1 /*
2  *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
3  *
4  *All right reserved
5  *
6  *File Name: expValueTable.c
7  *File Description: expValueTable MIB operation.
8  *
9  *Current Version:1.0
10  *Author:JianShun Tong
11  *Date:2004.8.20
12  */
13 
14 
15 /*
16  * This file was generated by mib2c and is intended for use as
17  * a mib module for the ucd-snmp snmpd agent.
18  */
19 
20 
21 /*
22  * This should always be included first before anything else
23  */
24 #include <net-snmp/net-snmp-config.h>
25 #include <ctype.h>
26 #if HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 
30 #include <stdio.h>
31 
32 #if HAVE_STRING_H
33 #include <string.h>
34 #else
35 #include <strings.h>
36 #endif
37 #ifdef HAVE_LIMITS_H
38 #include <limits.h>
39 #endif
40 
41 
42 /*
43  * minimal include directives
44  */
45 #include <net-snmp/net-snmp-includes.h>
46 #include <net-snmp/agent/net-snmp-agent-includes.h>
47 #include "utilities/iquery.h"
48 #include "header_complex.h"
49 #include "expExpressionTable.h"
50 #include "expValueTable.h"
51 #include "expObjectTable.h"
52 
53 
54 /*
55  * expValueTable_variables_oid:
56  *   this is the top level oid that we want to register under.  This
57  *   is essentially a prefix, with the suffix appearing in the
58  *   variable below.
59  */
60 
61 static const oid expValueTable_variables_oid[] = {
62     1, 3, 6, 1, 2, 1, 90, 1, 3, 1
63 };
64 
65 struct s_node {
66     unsigned        data;
67     struct s_node  *next;
68 };
69 typedef struct s_node nodelink;
70 static FindVarMethod var_expValueTable;
71 
72 /*
73  * variable2 expObjectTable_variables:
74  */
75 
76 static const struct variable2 expValueTable_variables[] = {
77     /*
78      * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix
79      */
80 #define	EXPVALUECOUNTER32VAL 2
81     {EXPVALUECOUNTER32VAL,  ASN_COUNTER,  NETSNMP_OLDAPI_RONLY,
82      var_expValueTable, 2, {1, 2}},
83 #define	EXPVALUEUNSIGNED32VAL 3
84     {EXPVALUEUNSIGNED32VAL, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
85      var_expValueTable, 2, {1, 3}},
86 #define	EXPVALUETIMETICKSVAL 4
87     {EXPVALUETIMETICKSVAL,  ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
88      var_expValueTable, 2, {1, 4}},
89 #define	EXPVALUEINTEGER32VAL 5
90     {EXPVALUEINTEGER32VAL,  ASN_INTEGER,  NETSNMP_OLDAPI_RONLY,
91      var_expValueTable, 2, {1, 5}},
92 #define	EXPVALUEIPADDRESSVAL 6
93     {EXPVALUEIPADDRESSVAL, ASN_IPADDRESS, NETSNMP_OLDAPI_RONLY,
94      var_expValueTable, 2, {1, 6}},
95 #define	EXPVALUEOCTETSTRINGVAL 7
96     {EXPVALUEOCTETSTRINGVAL, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
97      var_expValueTable, 2, {1, 7}},
98 #define	EXPVALUEOIDVAL  8
99     {EXPVALUEOIDVAL,       ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
100      var_expValueTable, 2, {1, 8}},
101 #define	EXPVALUECOUNTER64VAL  9
102     {EXPVALUECOUNTER64VAL, ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
103      var_expValueTable, 2, {1, 9}}
104 };
105 
106 
107 static struct header_complex_index *expValueTableStorage = NULL;
108 
109 /*
110  * init_expValueTable():
111  *   Initialization routine.  This is called when the agent starts up.
112  *   At a minimum, registration of your variables should take place here.
113  */
114 void
init_expValueTable(void)115 init_expValueTable(void)
116 {
117     DEBUGMSGTL(("expValueTable", "initializing...  "));
118 
119 
120     /*
121      * register ourselves with the agent to handle our mib tree
122      */
123     REGISTER_MIB("expValueTable",
124                  expValueTable_variables, variable2,
125                  expValueTable_variables_oid);
126 
127     DEBUGMSGTL(("expValueTable", "done.\n"));
128 }
129 
130 static int
expValueTable_set(struct expExpressionTable_data * expression_data,const char * owner,size_t owner_len,const char * name,size_t name_len,oid * index,size_t index_len)131 expValueTable_set(struct expExpressionTable_data *expression_data,
132                   const char *owner, size_t owner_len, const char *name,
133                   size_t name_len, oid *index, size_t index_len)
134 {
135     netsnmp_variable_list *vars = NULL;
136     struct expValueTable_data *thedata;
137     struct header_complex_index *hcindex;
138     int             found = 0;
139 
140     for (hcindex = expValueTableStorage; hcindex; hcindex = hcindex->next) {
141         thedata = hcindex->data;
142         if (strcmp(thedata->expExpressionOwner, owner) == 0 &&
143             thedata->expExpressionOwnerLen == owner_len &&
144             strcmp(thedata->expExpressionName, name) == 0 &&
145             thedata->expExpressionNameLen == name_len) {
146             found = 1;
147             break;
148         }
149 
150     }
151 
152     if (found) {
153         if (snmp_oid_compare(thedata->expValueInstance,
154                              thedata->expValueInstanceLen, index,
155                              index_len) != 0) {
156             SNMP_FREE(thedata->expValueInstance);
157             thedata->expValueInstance = netsnmp_memdup(index, index_len);
158             thedata->expValueInstanceLen = index_len;
159         } else {
160             SNMP_FREE(index);
161         }
162     } else if ((thedata = calloc(1, sizeof(*thedata)))) {
163         thedata->expExpressionOwner = owner;
164         thedata->expExpressionOwnerLen = owner_len;
165         thedata->expExpressionName = name;
166         thedata->expExpressionNameLen = name_len;
167         thedata->expValueInstance = index;
168         thedata->expValueInstanceLen = index_len;
169         thedata->expression_data = expression_data;
170 
171         snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR,
172                                   (const char *) thedata->expExpressionOwner,
173                                   thedata->expExpressionOwnerLen);
174         snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR,
175                                   (const char *) thedata->expExpressionName,
176                                   thedata->expExpressionNameLen);
177         snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OBJECT_ID,
178                                   (u_char *) thedata->expValueInstance,
179                                   thedata->expValueInstanceLen * sizeof(oid));
180 
181         header_complex_add_data(&expValueTableStorage, vars, thedata);
182     } else {
183         return SNMPERR_GENERR;
184     }
185 
186     thedata->set = 1;
187 
188     return SNMPERR_SUCCESS;
189 }
190 
push(nodelink ** stack,unsigned long value)191 static void push(nodelink ** stack, unsigned long value)
192 {
193     nodelink           *newnode;
194     newnode = (nodelink *) malloc(sizeof(nodelink));
195     if (!newnode) {
196         printf("\nMemory allocation failure!");
197         return;
198     }
199     newnode->data = value;
200     newnode->next = *stack;
201     *stack = newnode;
202 }
203 
pop(nodelink ** stack)204 static unsigned long pop(nodelink **stack)
205 {
206     unsigned long   value;
207     nodelink       *top;
208 
209     if (!*stack)
210         return 0;
211 
212     top = *stack;
213     *stack = (*stack)->next;
214     value = top->data;
215     free(top);
216     return value;
217 }
218 
priority(char operator)219 static int priority(char operator)
220 {
221     switch (operator) {
222     case '*':
223     case '/':
224         return 4;
225     case '+':
226     case '-':
227         return 3;
228     case ')':
229         return 2;
230     case '(':
231         return 1;
232     default:
233         return 0;
234     }
235 }
236 
calculate(int operator,unsigned long a,unsigned long b)237 static unsigned long calculate(int operator, unsigned long a, unsigned long b)
238 {
239     switch (operator) {
240     case '+':
241         return (a + b);
242     case '-':
243         return (a - b);
244     case '*':
245         return (a * b);
246     case '/':
247         if (operator == '/' && b == 0) {
248             snmp_log(LOG_ERR, "Division by zero attempted\n");
249             return 0;
250         } else
251             return (a / b);
252     }
253     return 0;
254 }
255 
get_operand(const char * p,int * length)256 static unsigned long get_operand(const char *p, int *length)
257 {
258     char            c[13];
259     int             i = 0, k = 1;
260     unsigned long   result = 0;
261 
262     while (isdigit((unsigned char) *p))
263         c[i++] = *(p++);
264     *length += --i;
265     for (; i >= 0; i--) {
266         result += (c[i] - 48) * k;
267         k *= 10;
268     }
269     return result;
270 }
271 
272 enum operator_class {
273     c_other	= 0,
274     c_digit	= 1,
275     c_binop	= 2,
276     c_rpar	= 3,
277     c_lpar	= 4,
278 };
279 
operator_class(char c)280 static int operator_class(char c)
281 {
282     if (isdigit((unsigned char) c))
283         return c_digit;
284     else if (c == '*' || c == '+' || c == '-' || c == '/')
285         return c_binop;
286     else if (c == ')')
287         return c_rpar;
288     else if (c == '(')
289         return c_lpar;
290     else
291         return c_other;
292 }
293 
eval(nodelink ** operator,nodelink ** operand,char new_op)294 static void eval(nodelink **operator, nodelink **operand, char new_op)
295 {
296     unsigned long a, b, op, c;
297 
298     DEBUGMSG(("expValueTable", "eval: operator %c; new_op %c\n",
299               *operator ? (*operator)->data : '?', new_op));
300 
301     while (*operator != NULL &&
302            priority(new_op) <= priority((*operator)->data)) {
303         b = pop(operand);
304         op = pop(operator);
305         if (op) {
306             a = pop(operand);
307             c = calculate(op, a, b);
308             DEBUGMSG(("expValueTable", "eval: %ld %c %ld -> %ld\n", a, (char)op,
309                       b, c));
310             push(operand, c);
311         } else {
312             DEBUGMSG(("expValueTable", "eval: returning %ld\n", b));
313             push(operand, b);
314             break;
315         }
316     }
317 
318 }
319 
get_result(const char * expr)320 static unsigned long get_result(const char *expr)
321 {
322     int             position = 0;
323     unsigned long   a, result = 0;
324     const char     *expression;
325     nodelink       *operator = NULL;
326     nodelink       *operand = NULL;
327 
328     expression = expr;
329     while (*(expression + position) != '\0'
330            && *(expression + position) != '\n') {
331         switch (operator_class(*(expression + position))) {
332         case c_digit:
333             push(&operand, get_operand(expression + position, &position));
334             break;
335         case c_binop:
336             eval(&operator, &operand, *(expression + position));
337             push(&operator, *(expression + position));
338             break;
339         case c_rpar:
340             eval(&operator, &operand, ')');
341             if (operator->data == '(')
342                 pop(&operator);
343             break;
344         case c_lpar:
345             push(&operator, '(');
346             break;
347         default:
348             printf("\nInvalid character in expression:");
349             a = 0;
350             while (*(expression + (int) a) != '\n'
351                    && *(expression + (int) a) != '\0') {
352                 if (a != position)
353                     printf("%c", *(expression + (int) a));
354                 else
355                     printf("<%c>", *(expression + (int) a));
356                 a++;
357             }
358             return 0;
359         }                       /* end switch */
360         position++;
361     }
362     eval(&operator, &operand, ')');
363     result = pop(&operand);
364     DEBUGMSG(("expValueTable", "%s: %s -> %ld\n", __func__, expr, result));
365     return result;
366 }
367 
iquery(struct variable_list ** vars,char * secName,int snmp_version,const oid * name,int name_len)368 static int iquery(struct variable_list **vars, char *secName, int snmp_version,
369                   const oid *name, int name_len)
370 {
371     struct snmp_session *ss;
372     struct snmp_pdu *pdu;
373     struct snmp_pdu *response;
374     struct variable_list *v;
375     int status, rc = SNMP_ERR_GENERR;
376 
377     ss = netsnmp_query_get_default_session();
378     if (!ss) {
379         snmp_log(LOG_ERR, "%s: default SNMP session not available\n", __func__);
380         goto out;
381     }
382 
383     ss->retries = 0;
384 
385     pdu = snmp_pdu_create(SNMP_MSG_GET);
386     if (!pdu) {
387         snmp_log(LOG_ERR, "%s: failed to create an SNMP PDU\n", __func__);
388         goto out;
389     }
390 
391     if (snmp_add_null_var(pdu, name, name_len) == NULL) {
392         snmp_log(LOG_ERR, "%s: appending a variable to a PDU failed\n",
393                  __func__);
394         goto free_pdu;
395     }
396 
397     DEBUGMSGTL(("expValueTable", "%s: querying OID ", __func__));
398     DEBUGMSGOID(("expValueTable", name, name_len));
399     DEBUGMSG(("expValueTable", "\n"));
400 
401     status = snmp_synch_response(ss, pdu, &response);
402 
403     DEBUGMSGTL(("expValueTable", "%s: SNMP response status %d; rc %ld\n",
404                 __func__, status, response ? response->errstat : -1));
405 
406     if (status != STAT_SUCCESS)
407         goto free_pdu;
408 
409     rc = response->errstat;
410     *vars = snmp_clone_varbind(response->variables);
411     if (*vars == NULL)
412         goto free_response;
413 
414     for (v = *vars; v; v = v->next_variable) {
415         DEBUGMSGTL(("expValueTable", "%s: response variable type %d; oid ",
416                     __func__, v->type));
417         DEBUGMSGOID(("expValueTable", v->name, v->name_length));
418         if (v->type == ASN_INTEGER)
419             DEBUGMSG(("expValueTable", "; value %ld\n", *v->val.integer));
420         DEBUGMSG(("expValueTable", "\n"));
421     }
422 
423     rc = SNMPERR_SUCCESS;
424 
425 free_response:
426     if (response)
427         snmp_free_pdu(response);
428 
429 free_pdu:
430     /* if (pdu) snmp_free_pdu(pdu); -- triggers a use-after-free */
431 
432 out:
433     return rc;
434 }
435 
Evaluate_Expression(struct expValueTable_data * vtable_data)436 static unsigned long Evaluate_Expression(struct expValueTable_data *vtable_data)
437 {
438     struct header_complex_index *hcindex;
439     struct expObjectTable_data *objstorage, *objfound;
440     struct expValueTable_data *const valstorage = vtable_data;
441     const char     *expression;
442     char           *result, *resultbak;
443     char           *temp, *tempbak;
444     int             i = 0, j, l;
445     unsigned long   result_u_long = 0;
446     static int      level;
447 
448     temp = malloc(100);
449     result = malloc(100);
450     tempbak = temp;
451     memset(result, 0, 100);
452     *result = '\0';
453     resultbak = result;
454 
455     level++;
456 
457     if (level > 1) {
458         snmp_log(LOG_ERR, "%s: detected recursion\n", __func__);
459         goto out;
460     }
461 
462     expression = vtable_data->expression_data->expExpression;
463 
464     DEBUGMSGTL(("expValueTable", "%s(%s.%s): evaluating %s\n", __func__,
465                 valstorage->expExpressionOwner, valstorage->expExpressionName,
466                 expression));
467 
468     while (*expression != '\0') {
469         if (*expression == '$') {
470             objfound = NULL;
471             i++;
472             for (j = 1; j < 100; j++) {
473                 if ((*(expression + j) == '+') ||
474                     (*(expression + j) == '-') ||
475                     (*(expression + j) == '*') ||
476                     (*(expression + j) == '/') ||
477                     (*(expression + j) == '(') ||
478                     (*(expression + j) == ')') ||
479                     *(expression + j) == '\0') {
480                     break;
481                 }
482             }
483             sprintf(temp, "%.*s", j - 1, expression + 1);
484             l = atoi(temp);
485             expression = expression + j;
486             /*
487              *   here use snmpget to get value
488              */
489             for (hcindex = expObjectTableStorage; hcindex != NULL;
490                  hcindex = hcindex->next) {
491                 objstorage = (struct expObjectTable_data *) hcindex->data;
492                 if (!strcmp
493                     (objstorage->expExpressionOwner,
494                      valstorage->expExpressionOwner)
495                     && (objstorage->expExpressionOwnerLen ==
496                         valstorage->expExpressionOwnerLen)
497                     && !strcmp(objstorage->expExpressionName,
498                                valstorage->expExpressionName)
499                     && (objstorage->expExpressionNameLen ==
500                         valstorage->expExpressionNameLen)
501                     && (l == objstorage->expObjectIndex)) {
502                     objfound = objstorage;
503                     break;
504                 }
505             }
506 
507             if (!objfound) {
508                 snmp_log(LOG_ERR, "%s: lookup of expression %s.%s failed\n",
509                          __func__, valstorage->expExpressionOwner,
510                          valstorage->expExpressionName);
511                 goto out;
512             }
513 
514             DEBUGMSGTL(("expValueTable", "%s: Found OID ", __func__));
515             DEBUGMSGOID(("expValueTable", objfound->expObjectID,
516                          objfound->expObjectIDLen));
517             DEBUGMSG(("expValueTable", "%s\n",
518                       objfound->expObjectIDWildcard ==
519                       EXPOBJCETIDWILDCARD_TRUE ? "(wildcard)" : ""));
520 
521             oid             anOID[MAX_OID_LEN];
522             size_t          anOID_len;
523 
524             memcpy(anOID, objfound->expObjectID,
525                    objfound->expObjectIDLen * sizeof(oid));
526             anOID_len = objfound->expObjectIDLen;
527             if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_TRUE) {
528                 anOID_len =
529                     anOID_len + valstorage->expValueInstanceLen - 2;
530                 memcpy(anOID + objfound->expObjectIDLen,
531                        valstorage->expValueInstance + 2,
532                        (valstorage->expValueInstanceLen -
533                         2) * sizeof(oid));
534             }
535 
536             struct variable_list *vars;
537             int             rc;
538 
539             rc = iquery(&vars,
540                         (char *)vtable_data->expression_data->pdu_community,
541                         vtable_data->expression_data->pdu_version,
542                         anOID, anOID_len);
543             if (rc != SNMP_ERR_NOERROR)
544                 snmp_log(LOG_ERR, "Error in packet: %s\n", snmp_errstring(rc));
545             sprintf(result, "%lu", rc == SNMP_ERR_NOERROR ?
546                     *(vars->val.integer) : 0);
547             result += strlen(result);
548         } else {
549             *result++ = *expression++;
550         }
551     }
552     result_u_long = get_result(resultbak);
553     DEBUGMSGTL(("expValueTable", "%s(%s.%s): evaluated %s into %ld\n", __func__,
554                 valstorage->expExpressionOwner, valstorage->expExpressionName,
555                 resultbak, result_u_long));
556 
557 out:
558     free(tempbak);
559     free(resultbak);
560     level--;
561     return result_u_long;
562 }
563 
expValueTable_clean(void * data)564 static void expValueTable_clean(void *data)
565 {
566     struct expValueTable_data *cleanme = data;
567 
568     SNMP_FREE(cleanme->expValueInstance);
569     SNMP_FREE(cleanme);
570 }
571 
build_valuetable(void)572 static void build_valuetable(void)
573 {
574     struct expExpressionTable_data *expstorage;
575     struct expObjectTable_data *objstorage, *objfound = NULL;
576     struct header_complex_index *hcindex, *object_hcindex;
577     const char     *expression;
578     oid            *index;
579     int             i = 0, j, l;
580 
581     DEBUGMSGTL(("expValueTable", "building valuetable...  \n"));
582 
583     for (hcindex = expExpressionTableStorage; hcindex != NULL;
584          hcindex = hcindex->next) {
585         expstorage = (struct expExpressionTable_data *) hcindex->data;
586         if (expstorage->expExpressionEntryStatus == RS_ACTIVE) {
587             expression = expstorage->expExpression;
588             while (*expression != '\0') {
589                 if (*expression == '$') {
590                     i++;
591                     for (j = 1; j < 100; j++) {
592                         if ((*(expression + j) == '+') ||
593                             (*(expression + j) == '-') ||
594                             (*(expression + j) == '*') ||
595                             (*(expression + j) == '/') ||
596                             (*(expression + j) == '(') ||
597                             (*(expression + j) == ')') ||
598                             *(expression + j) == '\0') {
599                             break;
600                         }
601                     }
602                     {
603                         char temp[100];
604 
605                         sprintf(temp, "%.*s", j - 1, expression + 1);
606                         l = atoi(temp);
607                     }
608                     for (object_hcindex = expObjectTableStorage;
609                          object_hcindex != NULL;
610                          object_hcindex = object_hcindex->next) {
611                         objstorage =
612                             (struct expObjectTable_data *) object_hcindex->
613                             data;
614                         if (!strcmp
615                             (objstorage->expExpressionOwner,
616                              expstorage->expExpressionOwner)
617                             && (objstorage->expExpressionOwnerLen ==
618                                 expstorage->expExpressionOwnerLen)
619                             && !strcmp(objstorage->expExpressionName,
620                                        expstorage->expExpressionName)
621                             && (objstorage->expExpressionNameLen ==
622                                 expstorage->expExpressionNameLen)
623                             && (l == objstorage->expObjectIndex)) {
624                             if (objfound == NULL) {
625                                 objfound = objstorage;
626                             }
627                             if (objstorage->expObjectIDWildcard ==
628                                 EXPOBJCETIDWILDCARD_TRUE)
629                                 objfound = objstorage;
630                         }
631                     }
632                     expression = expression + j;
633                 } else {
634                     expression++;
635                 }
636             };
637         }
638 
639         if (!objfound) {
640             continue;
641         }
642         if (objfound->expObjectIDWildcard == EXPOBJCETIDWILDCARD_FALSE) {
643             index = calloc(1, MAX_OID_LEN);
644             *index = 0;
645             *(index + 1) = 0;
646             *(index + 2) = 0;
647             expValueTable_set(expstorage, objfound->expExpressionOwner,
648                               objfound->expExpressionOwnerLen,
649                               objfound->expExpressionName,
650                               objfound->expExpressionNameLen, index, 3);
651         } else {
652             oid            *targetOID = objfound->expObjectID;
653             size_t          taggetOID_len = objfound->expObjectIDLen;
654             oid            *next_OID;
655             size_t          next_OID_len;
656             struct variable_list *vars;
657             int             rc;
658 
659             next_OID = targetOID;
660             next_OID_len = taggetOID_len;
661             do {
662                 index = calloc(1, MAX_OID_LEN);
663 
664                 rc = iquery(&vars, (char *)expstorage->pdu_community,
665                             expstorage->pdu_version, next_OID, next_OID_len);
666                 if (rc == SNMP_ERR_NOERROR) {
667                     if (((vars->type >= SNMP_NOSUCHOBJECT &&
668                           vars->type <= SNMP_ENDOFMIBVIEW)
669                          || snmp_oid_compare(targetOID, taggetOID_len,
670                                              vars->name,
671                                              taggetOID_len) != 0)) {
672                         break;
673                     }
674                     /* add to expValueTable */
675 
676                     *index = 0;
677                     *(index + 1) = 0;
678                     memcpy(index + 2, vars->name + taggetOID_len,
679                            (vars->name_length - taggetOID_len) * sizeof(oid));
680                     expValueTable_set(expstorage,
681                                       objfound->expExpressionOwner,
682                                       objfound->expExpressionOwnerLen,
683                                       objfound->expExpressionName,
684                                       objfound->expExpressionNameLen,
685                                       index,
686                                       vars->name_length -
687                                       taggetOID_len + 2);
688 
689                     next_OID = vars->name;
690                     next_OID_len = vars->name_length;
691                 } else {
692                     snmp_log(LOG_ERR, "Error in packet: %s\n",
693                              snmp_errstring(rc));
694                 }
695             } while (TRUE);
696         }
697     }
698 }
699 
var_expValueTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)700 static unsigned char *var_expValueTable(struct variable *vp, oid * name,
701                                         size_t *length, int exact,
702                                         size_t *var_len,
703                                         WriteMethod ** write_method)
704 {
705     struct expValueTable_data *StorageTmp = NULL;
706 
707     DEBUGMSGTL(("expValueTable", "var_expValueTable: Entering...  \n"));
708 
709     struct header_complex_index *hciptr, *hciptrn;
710 
711     for (hciptr = expValueTableStorage; hciptr; hciptr = hciptr->next) {
712         StorageTmp = hciptr->data;
713         StorageTmp->set = 0;
714     }
715 
716     build_valuetable();
717 
718     for (hciptr = expValueTableStorage; hciptr; hciptr = hciptrn) {
719         hciptrn = hciptr->next;
720         StorageTmp = hciptr->data;
721         if (!StorageTmp->set)
722             header_complex_free_entry(hciptr, expValueTable_clean);
723     }
724 
725     /*
726      * this assumes you have registered all your data properly
727      */
728     if ((StorageTmp =
729          header_complex(expValueTableStorage, vp, name, length, exact,
730                         var_len, write_method)) == NULL) {
731         DEBUGMSGTL(("expValueTable", "%s: entry not found.\n", __func__));
732         return NULL;
733     }
734 
735     DEBUGMSGTL(("expValueTable", "%s: vp->magic = %d.\n", __func__, vp->magic));
736 
737 
738     /*
739      * this is where we do the value assignments for the mib results.
740      */
741     switch (vp->magic) {
742         /*
743          *   we only support counter32val
744          */
745 
746     case EXPVALUECOUNTER32VAL:
747         StorageTmp->expValueCounter32Val = Evaluate_Expression(StorageTmp);
748         *var_len = sizeof(StorageTmp->expValueCounter32Val);
749         return (u_char *) & StorageTmp->expValueCounter32Val;
750 
751     case EXPVALUEUNSIGNED32VAL:
752         /* var_len = sizeof(StorageTmp->expValueUnsigned32Val); */
753         /* return (u_char *) & StorageTmp->expValueUnsigned32Val;         */
754         return NULL;
755 
756     case EXPVALUETIMETICKSVAL:
757         /* var_len = sizeof(StorageTmp->expValueTimeTicksVal); */
758         /* return (u_char *) & StorageTmp->expValueTimeTicksVal; */
759         return NULL;
760 
761     case EXPVALUEINTEGER32VAL:
762         /* var_len = sizeof(StorageTmp->expValueInteger32Val); */
763         /* return (u_char *) & StorageTmp->expValueInteger32Val; */
764         return NULL;
765 
766     case EXPVALUEIPADDRESSVAL:
767         /* var_len = sizeof(StorageTmp->expValueIpAddressVal); */
768         /* return (u_char *) & StorageTmp->expValueIpAddressVal; */
769         return NULL;
770 
771     case EXPVALUEOCTETSTRINGVAL:
772         /* var_len = sizeof(StorageTmp->expValueOctetStringVal); */
773         /* return (u_char *) & StorageTmp->expValueOctetStringVal;        */
774         return NULL;
775 
776     case EXPVALUEOIDVAL:
777         /* var_len = StorageTmp->expValueOidValLen; */
778         /* return (u_char *) & StorageTmp->expValueOidVal; */
779         return NULL;
780 
781     case EXPVALUECOUNTER64VAL:
782         /* var_len = sizeof(StorageTmp->expValueCounter64Val); */
783         /* return (u_char *) & StorageTmp->expValueCounter64Val; */
784         return NULL;
785     default:
786         ERROR_MSG("");
787 	return NULL;
788     }
789 }
790