blob: d3c0295991fb6ae5b28376bec746101ba97bf26f [file] [log] [blame]
/*
*Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
*
*All right reserved
*
*File Name: expValueTable.c
*File Description: expValueTable MIB operation.
*
*Current Version:1.0
*Author:JianShun Tong
*Date:2004.8.20
*/
/*
* This file was generated by mib2c and is intended for use as
* a mib module for the ucd-snmp snmpd agent.
*/
/*
* This should always be included first before anything else
*/
#include <net-snmp/net-snmp-config.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdio.h>
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
/*
* minimal include directives
*/
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "header_complex.h"
#include "expExpressionTable.h"
#include "expValueTable.h"
#include "expObjectTable.h"
/*
* expValueTable_variables_oid:
* this is the top level oid that we want to register under. This
* is essentially a prefix, with the suffix appearing in the
* variable below.
*/
oid expValueTable_variables_oid[] =
{ 1, 3, 6, 1, 2, 1, 90, 1, 3, 1 };
struct s_node {
unsigned data;
struct s_node *next;
};
typedef struct s_node nodelink;
nodelink *operater = NULL;
nodelink *operand = NULL;
/*
* variable2 expObjectTable_variables:
*/
struct variable2 expValueTable_variables[] = {
/*
* magic number , variable type , ro/rw , callback fn , L, oidsuffix
*/
#define EXPVALUECOUNTER32VAL 2
{EXPVALUECOUNTER32VAL, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 2}},
#define EXPVALUEUNSIGNED32VAL 3
{EXPVALUEUNSIGNED32VAL, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 3}},
#define EXPVALUETIMETICKSVAL 4
{EXPVALUETIMETICKSVAL, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 4}},
#define EXPVALUEINTEGER32VAL 5
{EXPVALUEINTEGER32VAL, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 5}},
#define EXPVALUEIPADDRESSVAL 6
{EXPVALUEIPADDRESSVAL, ASN_IPADDRESS, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 6}},
#define EXPVALUEOCTETSTRINGVAL 7
{EXPVALUEOCTETSTRINGVAL, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 7}},
#define EXPVALUEOIDVAL 8
{EXPVALUEOIDVAL, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 8}},
#define EXPVALUECOUNTER64VAL 9
{EXPVALUECOUNTER64VAL, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_expValueTable, 2, {1, 9}}
};
/*
* global storage of our data, saved in and configured by header_complex()
*/
extern struct header_complex_index *expExpressionTableStorage;
extern struct header_complex_index *expObjectTableStorage;
struct header_complex_index *expValueTableStorage = NULL;
struct snmp_session session;
/*
* init_expValueTable():
* Initialization routine. This is called when the agent starts up.
* At a minimum, registration of your variables should take place here.
*/
void
init_expValueTable(void)
{
DEBUGMSGTL(("expValueTable", "initializing... "));
/*
* register ourselves with the agent to handle our mib tree
*/
REGISTER_MIB("expValueTable",
expValueTable_variables, variable2,
expValueTable_variables_oid);
init_snmp("snmpapp");
/*
* Initialize a "session" that defines who we're going to talk to
*/
snmp_sess_init(&session); /* set up defaults */
session.peername = strdup("localhost");
DEBUGMSGTL(("expValueTable", "done.\n"));
}
struct expValueTable_data *
create_expValueTable_data(void)
{
struct expValueTable_data *StorageNew;
StorageNew = SNMP_MALLOC_STRUCT(expValueTable_data);
/*
* fill in default row values here into StorageNew
*/
/*
* fill in values for all tables (even if not
* appropriate), since its easier to do here than anywhere
* else
*/
StorageNew->expExpressionOwner = strdup("");
StorageNew->expExpressionName = strdup("");
StorageNew->expValueInstance = calloc(1, sizeof(oid) * sizeof(2)); /* 0.0.0 */
StorageNew->expValueInstanceLen = 3;
return StorageNew;
}
/*
* mteTriggerTable_add(): adds a structure node to our data set
*/
int
expValueTable_add(struct expExpressionTable_data *expression_data,
char *owner, size_t owner_len, char *name,
size_t name_len, oid * index, size_t index_len)
{
netsnmp_variable_list *vars = NULL;
struct expValueTable_data *thedata, *StorageTmp;
struct header_complex_index *hcindex;
int founded = 0;
thedata = create_expValueTable_data();
thedata->expValueCounter32Val = 0;
thedata->expExpressionOwner = owner;
thedata->expExpressionOwnerLen = owner_len;
thedata->expExpressionName = name;
thedata->expExpressionNameLen = name_len;
thedata->expValueInstance = index;
thedata->expValueInstanceLen = index_len;
thedata->expression_data = expression_data;
DEBUGMSGTL(("expValueTable", "adding data... "));
/*
* add the index variables to the varbind list, which is
* used by header_complex to index the data
*/
snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionOwner, thedata->expExpressionOwnerLen); /* expExpressionOwner */
snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionName, thedata->expExpressionNameLen); /* expExpressionName */
snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OBJECT_ID,
(u_char *) thedata->expValueInstance,
thedata->expValueInstanceLen * sizeof(oid));
for (hcindex = expValueTableStorage; hcindex != NULL;
hcindex = hcindex->next) {
StorageTmp = (struct expValueTable_data *) hcindex->data;
if (!strcmp
(StorageTmp->expExpressionOwner, thedata->expExpressionOwner)
&& (StorageTmp->expExpressionOwnerLen ==
thedata->expExpressionOwnerLen)
&& !strcmp(StorageTmp->expExpressionName,
thedata->expExpressionName)
&& (StorageTmp->expExpressionNameLen ==
thedata->expExpressionNameLen)
&& !snmp_oid_compare(StorageTmp->expValueInstance,
StorageTmp->expValueInstanceLen,
thedata->expValueInstance,
thedata->expValueInstanceLen)) {
founded = 1;
break;
}
}
if (!founded) {
header_complex_add_data(&expValueTableStorage, vars, thedata);
DEBUGMSGTL(("expValueTable", "registered an entry\n"));
} else {
SNMP_FREE(thedata);
DEBUGMSGTL(("expValueTable",
"already have an entry, dont registe\n"));
}
DEBUGMSGTL(("expValueTable", "done.\n"));
return SNMPERR_SUCCESS;
}
unsigned long
Evaluate_Expression(struct expValueTable_data *vtable_data)
{
struct header_complex_index *hcindex;
struct expObjectTable_data *objstorage, *objfound;
struct expValueTable_data *valstorage;
valstorage = vtable_data;
char *expression;
char *result, *resultbak;
char *temp, *tempbak;
char intchar[10];
int dollar1, dollar2;
int i = 0, j, k, l;
long value;
unsigned long result_u_long;
temp = malloc(100);
result = malloc(100);
tempbak = temp;
memset(result, 0, 100);
*result = '\0';
resultbak = result;
expression = vtable_data->expression_data->expExpression;
while (*expression != '\0') {
if (*expression == '$') {
objfound = NULL;
i++;
for (j = 1; j < 100; j++) {
if ((*(expression + j) == '+') ||
(*(expression + j) == '-') ||
(*(expression + j) == '*') ||
(*(expression + j) == '/') ||
(*(expression + j) == '(') ||
(*(expression + j) == ')') ||
*(expression + j) == '\0') {
break;
}
}
sprintf(temp, "%.*s", j - 1, expression + 1);
l = atoi(temp);
expression = expression + j;
/*
* here use snmpget to get value
*/
for (hcindex = expObjectTableStorage; hcindex != NULL;
hcindex = hcindex->next) {
objstorage = (struct expObjectTable_data *) hcindex->data;
if (!strcmp
(objstorage->expExpressionOwner,
valstorage->expExpressionOwner)
&& (objstorage->expExpressionOwnerLen ==
valstorage->expExpressionOwnerLen)
&& !strcmp(objstorage->expExpressionName,
valstorage->expExpressionName)
&& (objstorage->expExpressionNameLen ==
valstorage->expExpressionNameLen)
&& (l == objstorage->expObjectIndex)) {
objfound = objstorage;
break;
}
}
if (!objfound) {
/* have err */
return 0;
}
struct snmp_session *ss;
struct snmp_pdu *pdu;
struct snmp_pdu *response;
oid anOID[MAX_OID_LEN];
size_t anOID_len;
memcpy(anOID, objfound->expObjectID,
objfound->expObjectIDLen * sizeof(oid));
anOID_len = objfound->expObjectIDLen;
if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_TRUE) {
anOID_len =
anOID_len + valstorage->expValueInstanceLen - 2;
memcpy(anOID + objfound->expObjectIDLen,
valstorage->expValueInstance + 2,
(valstorage->expValueInstanceLen -
2) * sizeof(oid));
}
struct variable_list *vars;
int status;
int count = 1;
/*
* Initialize the SNMP library
*/
/*
* Initialize a "session" that defines who we're going to talk to
*/
session.version = vtable_data->expression_data->pdu_version;
/*
* set the SNMPv1 community name used for authentication
*/
session.community =
vtable_data->expression_data->pdu_community;
session.community_len =
vtable_data->expression_data->pdu_community_len;
/*
* Open the session
*/
SOCK_STARTUP;
ss = snmp_open(&session); /* establish the session */
if (!ss) {
/* err */
exit(2);
}
pdu = snmp_pdu_create(SNMP_MSG_GET);
snmp_add_null_var(pdu, anOID, anOID_len);
/*
* Send the Request out.
*/
status = snmp_synch_response(ss, pdu, &response);
/*
* Process the response.
*/
if (status == STAT_SUCCESS
&& response->errstat == SNMP_ERR_NOERROR) {
/*
* SUCCESS: Print the result variables
*/
vars = response->variables;
value = *(vars->val.integer);
sprintf(intchar, "%u", value);
for (k = 1; k <= strlen(intchar); k++) {
*result = intchar[k - 1];
result++;
}
} else {
/*
* FAILURE: print what went wrong!
*/
if (status == STAT_SUCCESS)
fprintf(stderr, "Error in packet\nReason: %s\n",
snmp_errstring(response->errstat));
else
snmp_sess_perror("snmpget", ss);
}
/*
* Clean up:
* 1) free the response.
* 2) close the session.
*/
if (response)
snmp_free_pdu(response);
snmp_close(ss);
SOCK_CLEANUP;
} else {
*result = *expression;
result++;
expression++;
}
}
result_u_long = get_result(resultbak);
free(tempbak);
free(resultbak);
return result_u_long;
}
void
expValueTable_clean(void *data)
{
struct expValueTable_data *cleanme =
(struct expValueTable_data *) data;
SNMP_FREE(cleanme->expValueInstance);
SNMP_FREE(cleanme->expValueIpAddressVal);
SNMP_FREE(cleanme->expValueOctetStringVal);
SNMP_FREE(cleanme->expValueOidVal);
SNMP_FREE(cleanme);
}
void
build_valuetable()
{
struct expExpressionTable_data *expstorage;
struct expObjectTable_data *objstorage, *objfound = NULL;
struct header_complex_index *hcindex, *object_hcindex;
char *owner;
size_t owner_len;
char *name;
size_t name_len;
char *expression;
oid *index;
int i = 0, j, l;
DEBUGMSGTL(("expValueTable", "building valuetable... \n"));
for (hcindex = expExpressionTableStorage; hcindex != NULL;
hcindex = hcindex->next) {
expstorage = (struct expExpressionTable_data *) hcindex->data;
if (expstorage->expExpressionEntryStatus == RS_ACTIVE) {
expression = expstorage->expExpression;
while (*expression != '\0') {
if (*expression == '$') {
i++;
for (j = 1; j < 100; j++) {
if ((*(expression + j) == '+') ||
(*(expression + j) == '-') ||
(*(expression + j) == '*') ||
(*(expression + j) == '/') ||
(*(expression + j) == '(') ||
(*(expression + j) == ')') ||
*(expression + j) == '\0') {
break;
}
}
{
char temp[100];
sprintf(temp, "%.*s", j - 1, expression + 1);
l = atoi(temp);
}
for (object_hcindex = expObjectTableStorage;
object_hcindex != NULL;
object_hcindex = object_hcindex->next) {
objstorage =
(struct expObjectTable_data *) object_hcindex->
data;
if (!strcmp
(objstorage->expExpressionOwner,
expstorage->expExpressionOwner)
&& (objstorage->expExpressionOwnerLen ==
expstorage->expExpressionOwnerLen)
&& !strcmp(objstorage->expExpressionName,
expstorage->expExpressionName)
&& (objstorage->expExpressionNameLen ==
expstorage->expExpressionNameLen)
&& (l == objstorage->expObjectIndex)) {
if (objfound == NULL) {
objfound = objstorage;
}
if (objstorage->expObjectIDWildcard ==
EXPOBJCETIDWILDCARD_TRUE)
objfound = objstorage;
}
}
expression = expression + j;
} else {
expression++;
}
};
}
if (!objfound) {
continue;
}
if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_FALSE) {
index = calloc(1, MAX_OID_LEN);
*index = 0;
*(index + 1) = 0;
*(index + 2) = 0;
expValueTable_add(expstorage, objfound->expExpressionOwner,
objfound->expExpressionOwnerLen,
objfound->expExpressionName,
objfound->expExpressionNameLen, index, 3);
} else {
oid *targetOID;
size_t taggetOID_len;
targetOID = objfound->expObjectID;
struct snmp_pdu *pdu;
struct snmp_pdu *response;
oid *next_OID;
size_t next_OID_len;
taggetOID_len = objfound->expObjectIDLen;
struct variable_list *vars;
int status;
int count = 1;
struct snmp_session *ss;
/*
* Initialize the SNMP library
*/
/*
* set the SNMP version number
*/
session.version = expstorage->pdu_version;
/*
* set the SNMPv1 community name used for authentication
*/
session.community = expstorage->pdu_community;
session.community_len = expstorage->pdu_community_len;
/*
* Open the session
*/
SOCK_STARTUP;
ss = snmp_open(&session); /* establish the session */
if (!ss) {
snmp_perror("ack");
snmp_log(LOG_ERR, "something horrible happened!!!\n");
exit(2);
}
next_OID = targetOID;
next_OID_len = taggetOID_len;
do {
index = calloc(1, MAX_OID_LEN);
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
snmp_add_null_var(pdu, next_OID, next_OID_len);
/*
* Send the Request out.
*/
status = snmp_synch_response(ss, pdu, &response);
/*
* Process the response.
*/
if (status == STAT_SUCCESS
&& response->errstat == SNMP_ERR_NOERROR) {
/*
* SUCCESS: Print the result variables
*/
if (((response->variables->type >= SNMP_NOSUCHOBJECT &&
response->variables->type <= SNMP_ENDOFMIBVIEW)
|| snmp_oid_compare(targetOID, taggetOID_len,
response->variables->name,
taggetOID_len) != 0)) {
break;
}
/* add to expValueTable */
*index = 0;
*(index + 1) = 0;
memcpy(index + 2,
response->variables->name + taggetOID_len,
(response->variables->name_length -
taggetOID_len) * sizeof(oid));
expValueTable_add(expstorage,
objfound->expExpressionOwner,
objfound->expExpressionOwnerLen,
objfound->expExpressionName,
objfound->expExpressionNameLen,
index,
response->variables->name_length -
taggetOID_len + 2);
next_OID = response->variables->name;
next_OID_len = response->variables->name_length;
} else {
/*
* FAILURE: print what went wrong!
*/
if (status == STAT_SUCCESS)
fprintf(stderr, "Error in packet\nReason: %s\n",
snmp_errstring(response->errstat));
else
snmp_sess_perror("snmpget", ss);
}
} while (TRUE);
}
}
}
/*
* var_expValueTable():
*/
unsigned char *
var_expValueTable(struct variable *vp,
oid * name,
size_t *length,
int exact, size_t *var_len, WriteMethod ** write_method)
{
static netsnmp_variable_list *vars;
size_t newlen =
*length - (sizeof(expValueTable_variables_oid) / sizeof(oid) +
3 - 1);
struct expValueTable_data *StorageTmp = NULL;
unsigned int counter32;
DEBUGMSGTL(("expValueTable", "var_expValueTable: Entering... \n"));
/*
* before we build valuetable we must free any other valutable if exist
*/
header_complex_free_all(expValueTableStorage, expValueTable_clean);
expValueTableStorage = NULL;
build_valuetable();
/*
* this assumes you have registered all your data properly
*/
if ((StorageTmp =
header_complex(expValueTableStorage, vp, name, length, exact,
var_len, write_method)) == NULL)
return NULL;
/*
* this is where we do the value assignments for the mib results.
*/
switch (vp->magic) {
/*
* we only support counter32val
*/
case EXPVALUECOUNTER32VAL:
StorageTmp->expValueCounter32Val = Evaluate_Expression(StorageTmp);
*var_len = sizeof(StorageTmp->expValueCounter32Val);
return (u_char *) & StorageTmp->expValueCounter32Val;
case EXPVALUEUNSIGNED32VAL:
/* var_len = sizeof(StorageTmp->expValueUnsigned32Val); */
/* return (u_char *) & StorageTmp->expValueUnsigned32Val; */
return NULL;
case EXPVALUETIMETICKSVAL:
/* var_len = sizeof(StorageTmp->expValueTimeTicksVal); */
/* return (u_char *) & StorageTmp->expValueTimeTicksVal; */
return NULL;
case EXPVALUEINTEGER32VAL:
/* var_len = sizeof(StorageTmp->expValueInteger32Val); */
/* return (u_char *) & StorageTmp->expValueInteger32Val; */
return NULL;
case EXPVALUEIPADDRESSVAL:
/* var_len = sizeof(StorageTmp->expValueIpAddressVal); */
/* return (u_char *) & StorageTmp->expValueIpAddressVal; */
return NULL;
case EXPVALUEOCTETSTRINGVAL:
/* var_len = sizeof(StorageTmp->expValueOctetStringVal); */
/* return (u_char *) & StorageTmp->expValueOctetStringVal; */
return NULL;
case EXPVALUEOIDVAL:
/* var_len = StorageTmp->expValueOidValLen; */
/* return (u_char *) & StorageTmp->expValueOidVal; */
return NULL;
case EXPVALUECOUNTER64VAL:
/* var_len = sizeof(StorageTmp->expValueCounter64Val); */
/* return (u_char *) & StorageTmp->expValueCounter64Val; */
return NULL;
default:
ERROR_MSG("");
}
}
void
push(nodelink ** stack, unsigned long value)
{
nodelink *newnode;
newnode = (nodelink *) malloc(sizeof(nodelink));
if (!newnode) {
printf("\nMemory allocation failure!");
return;
}
newnode->data = value;
newnode->next = *stack;
*stack = newnode;
}
unsigned long
pop(nodelink ** stack)
{
unsigned long value;
nodelink *top;
top = *stack;
*stack = (*stack)->next;
value = top->data;
free(top);
return value;
}
int
priority(char operater)
{
switch (operater) {
case '*':
case '/':
return 4;
case '+':
case '-':
return 3;
case ')':
return 2;
case '(':
return 1;
default:
return 0;
}
}
unsigned long
calculate(int operater, unsigned long a, unsigned long b)
{
switch (operater) {
case '+':
return (a + b);
case '-':
return (a - b);
case '*':
return (a * b);
case '/':
if (operater == '/' && b == 0) {
printf("\nDivision mustn\'t be 0!");
exit(0);
} else
return (a / b);
}
}
unsigned long
get_operand(char *p, int *length)
{
char c[13];
int i = 0, k = 1;
unsigned long result = 0;
while (*p <= 57 && *p >= 48)
c[i++] = *(p++);
*length += --i;
for (; i >= 0; i--) {
result += (c[i] - 48) * k;
k *= 10;
}
return result;
}
int
operator_class(char c)
{
if (c <= 57 && c >= 48)
return 1;
if (c == 42 || c == 43 || c == 45 || c == 47)
return 2;
if (c == 41)
return 3;
if (c == 40)
return 4;
return 0;
}
unsigned long
get_result(char *expr)
{
int position = 0;
unsigned long op = 0, a = 0, b = 0, result = 0;
char *expression;
expression = expr;
while (*(expression + position) != '\0'
&& *(expression + position) != '\n') {
switch (operator_class(*(expression + position))) {
case 1:
push(&operand, get_operand(expression + position, &position));
break;
case 2:
if (operater != NULL)
while (operater != NULL
&& priority(*(expression + position)) <=
priority(operater->data)) {
a = pop(&operand);
b = pop(&operand);
op = pop(&operater);
push(&operand, calculate(op, b, a));
}
push(&operater, *(expression + position));
break;
case 3:
while (operater != NULL && operater->data != '(') {
a = pop(&operand);
b = pop(&operand);
op = pop(&operater);
push(&operand, calculate(op, b, a));
}
if (operater->data == '(')
pop(&operater);
break;
case 4:
push(&operater, '(');
break;
default:
printf("\nInvalid character in expression:");
a = 0;
while (*(expression + (int) a) != '\n'
&& *(expression + (int) a) != '\0') {
if (a != position)
printf("%c", *(expression + (int) a));
else
printf("<%c>", *(expression + (int) a));
a++;
}
exit(0);
} /* end switch */
position++;
}
while (operater != NULL) {
op = pop(&operater);
a = pop(&operand);
b = pop(&operand);
push(&operand, calculate(op, b, a));
}
result = pop(&operand);
return result;
}