header_complex.c
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:13k
源码类别:

SNMP编程

开发平台:

C/C++

  1. /* header complex:  More complex storage and data sorting for mib modules */
  2. #include <config.h>
  3. #include <sys/types.h>
  4. #if HAVE_STDLIB_H
  5. #include <stdlib.h>
  6. #endif
  7. #if HAVE_STRING_H
  8. #include <string.h>
  9. #else
  10. #include <strings.h>
  11. #endif
  12. #include "mibincl.h"
  13. #include "header_complex.h"
  14. int
  15. header_complex_generate_varoid(struct variable_list *var) {
  16.   int i;
  17.   
  18.   if (var->name == NULL) {
  19.     /* assume cached value is correct */
  20.     switch(var->type) {
  21.       case ASN_INTEGER:
  22.       case ASN_COUNTER:
  23.       case ASN_GAUGE:
  24.       case ASN_TIMETICKS:
  25.         var->name_length = 1;
  26.         var->name = (oid *) malloc(sizeof(oid));
  27.         if (var->name == NULL)
  28.             return SNMPERR_GENERR;
  29.         var->name[0] = *(var->val.integer);
  30.         break;
  31.       case ASN_OPAQUE:
  32.       case ASN_OCTET_STR:
  33.         var->name_length = var->val_len+1;
  34.         var->name = (oid *) malloc(sizeof(oid) * (var->val_len + 1));
  35.         if (var->name == NULL)
  36.             return SNMPERR_GENERR;
  37.         var->name[0] = var->val_len;
  38.         for(i=0; i < var->val_len; i++)
  39.           var->name[i+1] = var->val.string[i];
  40.         break;
  41.       
  42.       default:
  43.         DEBUGMSGTL(("header_complex_generate_varoid",
  44.                     "invalid asn type: %dn", var->type));
  45.         return SNMPERR_GENERR;
  46.     }
  47.   }
  48.   if (var->name_length > MAX_OID_LEN) {
  49.     DEBUGMSGTL(("header_complex_generate_varoid",
  50.                 "Something terribly wrong, namelen = %dn", var->name_length));
  51.     return SNMPERR_GENERR;
  52.   }
  53.   return SNMPERR_SUCCESS;
  54. }
  55. /* header_complex_parse_oid(): parses an index to the usmTable to
  56.    break it down into a engineID component and a name component.
  57.    The results are stored in the data pointer, as a varbindlist:
  58.    returns 1 if an error is encountered, or 0 if successful.
  59. */
  60. static int _header_complex_parse_oid(oid *oidIndex, size_t oidLen,
  61.                          struct variable_list *data);
  62. int
  63. header_complex_parse_oid(oid *oidIndex, size_t oidLen,
  64.                          struct variable_list *data)
  65. {
  66.     int rc;
  67.     memset(data, 0, sizeof(*data));
  68.     rc = _header_complex_parse_oid(oidIndex, oidLen, data);
  69.     if (rc == SNMPERR_GENERR)
  70.         snmp_free_varbind(data);
  71.     return (rc);
  72. }
  73. static int _header_complex_parse_oid(oid *oidIndex, size_t oidLen,
  74.                          struct variable_list *data)
  75. {
  76.   struct variable_list *var = data;
  77.   int i, itmp;
  78.   
  79.   while(var && oidLen > 0) {
  80.     switch(var->type) {
  81.       case ASN_INTEGER:
  82.       case ASN_COUNTER:
  83.       case ASN_GAUGE:
  84.       case ASN_TIMETICKS:
  85.         var->val.integer = (long *) calloc(1,sizeof(long));
  86.         if (var->val.string == NULL)
  87.             return SNMPERR_GENERR;
  88.         *var->val.integer = (long) *oidIndex++;
  89.         var->val_len = sizeof(long);
  90.         oidLen--;
  91.         DEBUGMSGTL(("header_complex_parse_oid",
  92.                     "Parsed int(%d): %dn", var->type, *var->val.integer));
  93.         break;
  94.       case ASN_OPAQUE:
  95.       case ASN_OCTET_STR:
  96.         itmp = (long) *oidIndex++;
  97.         oidLen--;
  98.         if (itmp > oidLen)
  99.           return SNMPERR_GENERR;
  100.           
  101.         if (itmp == 0)
  102.           break;        /* zero length strings shouldn't malloc */
  103.         
  104.         /* malloc by size+1 to allow a null to be appended. */
  105.         var->val_len = itmp;
  106.         var->val.string = (u_char *) calloc(1,itmp+1);
  107.         if (var->val.string == NULL)
  108.             return SNMPERR_GENERR;
  109.         for(i = 0; i < itmp; i++)
  110.           var->val.string[i] = (u_char) *oidIndex++;
  111.         var->val.string[itmp] = '';
  112.         oidLen -= itmp;
  113.         DEBUGMSGTL(("header_complex_parse_oid",
  114.                     "Parsed str(%d): %sn", var->type, var->val.string));
  115.         break;
  116.       default:
  117.         DEBUGMSGTL(("header_complex_parse_oid",
  118.                     "invalid asn type: %dn", var->type));
  119.         return SNMPERR_GENERR;
  120.     }
  121.     var = var->next_variable;
  122.   }
  123.   if (var != NULL || oidLen > 0)
  124.     return SNMPERR_GENERR;
  125.   return SNMPERR_SUCCESS;
  126. }
  127. void
  128. header_complex_generate_oid(oid *name, /* out */
  129.                             size_t *length, /* out */
  130.                             oid *prefix,
  131.                             size_t prefix_len,
  132.                             struct variable_list *data) {
  133.   oid *oidptr;
  134.   struct variable_list *var;
  135.   
  136.   if (prefix) {
  137.     memcpy(name, prefix, prefix_len * sizeof(oid));
  138.     oidptr = (name + (prefix_len));
  139.     *length = prefix_len;
  140.   } else {
  141.     oidptr = name;
  142.     *length = 0;
  143.   }
  144.     
  145.   for(var = data; var != NULL; var = var->next_variable) {
  146.     header_complex_generate_varoid(var);
  147.     memcpy(oidptr, var->name, sizeof(oid) * var->name_length);
  148.     oidptr = oidptr + var->name_length;
  149.     *length += var->name_length;
  150.   }
  151.   
  152.   DEBUGMSGTL(("header_complex_generate_oid", "generated: "));
  153.   DEBUGMSGOID(("header_complex_generate_oid", name, *length));
  154.   DEBUGMSG(("header_complex_generate_oid", "n"));
  155. }
  156. void *
  157. header_complex(struct header_complex_index *datalist,
  158.                struct variable *vp,
  159.        oid *name,
  160.        size_t *length,
  161.        int exact,
  162.        size_t *var_len,
  163.        WriteMethod **write_method) {
  164.   struct header_complex_index *nptr, *found = NULL;
  165.   oid indexOid[MAX_OID_LEN];
  166.   size_t len;
  167.   int result;
  168.   
  169.   /* set up some nice defaults for the user */
  170.   if (write_method)
  171.     *write_method = NULL;
  172.   if (var_len)
  173.     *var_len = sizeof (long);
  174.   for(nptr = datalist; nptr != NULL && found == NULL; nptr = nptr->next) {
  175.     memcpy(indexOid, vp->name, vp->namelen * sizeof(oid));
  176.     memcpy(indexOid + vp->namelen, nptr->name,
  177.            nptr->namelen * sizeof(oid));
  178.     len = vp->namelen + nptr->namelen;
  179.     result = snmp_oid_compare(name, *length, indexOid, len);
  180.     DEBUGMSGTL(("header_complex", "Checking: "));
  181.     DEBUGMSGOID(("header_complex", indexOid, len));
  182.     DEBUGMSG(("header_complex", "n"));
  183.     if (exact) {
  184.       if (result == 0) {
  185.         found = nptr;
  186.       }
  187.     } else {
  188.       if (result == 0) {
  189.         /* found an exact match.  Need the next one for !exact */
  190.         if (nptr->next)
  191.           found = nptr->next;
  192.       } else if (result == -1) {
  193.         found = nptr;
  194.       }
  195.     }
  196.   }
  197.   if (found) {
  198.       memcpy(name, vp->name, vp->namelen * sizeof(oid));
  199.       memcpy(name + vp->namelen, found->name,
  200.              found->namelen * sizeof(oid));
  201.       *length = vp->namelen + found->namelen;
  202.       return found->data;
  203.   }
  204.     
  205.   return NULL;
  206. }
  207. struct header_complex_index *
  208. header_complex_add_data(struct header_complex_index **thedata,
  209.                         struct variable_list *var, void *data) {
  210.   struct header_complex_index *hciptrn, *hciptrp, *ourself;
  211.   oid newoid[MAX_OID_LEN];
  212.   size_t newoid_len;
  213. /*  struct variable_list *vp, *vp2;*/
  214.   if (thedata == NULL || var == NULL || data == NULL)
  215.     return NULL;
  216.   
  217.   header_complex_generate_oid(newoid, &newoid_len, NULL, 0, var);
  218.   for(hciptrn = *thedata, hciptrp = NULL;
  219.       hciptrn != NULL;
  220.       hciptrp = hciptrn, hciptrn = hciptrn->next)
  221.       /* XXX: check for == and error (overlapping table entries) */
  222.     if (snmp_oid_compare(hciptrn->name, hciptrn->namelen, newoid, newoid_len)
  223.         > 0)
  224.       break;
  225.   
  226.   /* nptr should now point to the spot that we need to add ourselves
  227.      in front of, and pptr should be our new 'prev'. */
  228.   /* create ourselves */
  229.   ourself = (struct header_complex_index *)
  230.       SNMP_MALLOC_STRUCT(header_complex_index);
  231.   /* change our pointers */
  232.   ourself->prev = hciptrp;
  233.   ourself->next = hciptrn;
  234.     
  235.   if (ourself->next)
  236.     ourself->next->prev = ourself;
  237.   if (ourself->prev)
  238.     ourself->prev->next = ourself;
  239.   ourself->data = data;
  240.   ourself->name = snmp_duplicate_objid(newoid, newoid_len);
  241.   ourself->namelen = newoid_len;
  242.   /* free the variable list, but not the enclosed data!  it's not ours! */
  243.   snmp_free_varbind(var);
  244.   /* rewind to the head of the list and return it (since the new head
  245.      could be us, we need to notify the above routine who the head now is. */
  246.   for(hciptrp = ourself; hciptrp->prev != NULL; hciptrp = hciptrp->prev);
  247.   *thedata = hciptrp;
  248.   DEBUGMSGTL(("header_complex_add_data", "adding something...n"));
  249.   return hciptrp;
  250. }
  251. /* extracts an entry from the storage space (removing it from future
  252.    accesses) and returns the data stored there
  253.    Modifies "thetop" pointer as needed (and if present) if were
  254.    extracting the first node.
  255. */
  256. void *
  257. header_complex_extract_entry(struct header_complex_index **thetop,
  258.                              struct header_complex_index *thespot) {
  259.   struct header_complex_index *hciptrp, *hciptrn;
  260.   void *retdata = thespot->data;
  261.   if (thespot == NULL) {
  262.     DEBUGMSGTL(("header_complex_extract_entry",
  263.                 "Null pointer asked to be extractedn"));
  264.     return NULL;
  265.   }
  266.   
  267.   hciptrp = thespot->prev;
  268.   hciptrn = thespot->next;
  269.   if (hciptrp)
  270.     hciptrp->next = hciptrn;
  271.   else if (thetop)
  272.     *thetop = hciptrn;
  273.   if (hciptrn)
  274.     hciptrn->prev = hciptrp;
  275.   if (thespot->name)
  276.       free(thespot->name);
  277.   free(thespot);
  278.   return retdata;
  279. }
  280. /* wipe out a single entry */
  281. void
  282. header_complex_free_entry(struct header_complex_index *theentry,
  283.                           HeaderComplexCleaner *cleaner) {
  284.   void *data;
  285.   data = header_complex_extract_entry(NULL, theentry);
  286.   (*cleaner)(data);
  287. }
  288. /* completely wipe out all entries in our data store */
  289. void
  290. header_complex_free_all(struct header_complex_index *thestuff,
  291.                          HeaderComplexCleaner *cleaner) {
  292.   struct header_complex_index *hciptr, *hciptrn;  
  293.   for(hciptr = thestuff; hciptr != NULL; hciptr = hciptrn) {
  294.     hciptrn = hciptr->next; /* need to extract this before deleting it */
  295.     header_complex_free_entry(hciptr, cleaner);
  296.   }
  297. }
  298. struct header_complex_index *
  299. header_complex_find_entry(struct header_complex_index *thestuff,
  300.                           void *theentry) {
  301.   struct header_complex_index *hciptr;  
  302.   for(hciptr = thestuff; hciptr != NULL && hciptr->data != theentry;
  303.       hciptr = hciptr->next);
  304.   return hciptr;
  305. }
  306. #ifdef TESTING
  307. void
  308. header_complex_dump(struct header_complex_index *thestuff) {
  309.   struct header_complex_index *hciptr;
  310.   oid oidsave[MAX_OID_LEN];
  311.   size_t len;
  312.   
  313.   for(hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
  314.     DEBUGMSGTL(("header_complex_dump", "var:  "));
  315.     header_complex_generate_oid(oidsave, &len, NULL, 0, hciptr->);
  316.     DEBUGMSGOID(("header_complex_dump", oidsave, len));
  317.     DEBUGMSG(("header_complex_dump", "n"));
  318.   }
  319. }
  320. main() {
  321.   oid oidsave[MAX_OID_LEN];
  322.   int len = MAX_OID_LEN, len2;
  323.   struct variable_list *vars;
  324.   long ltmp = 4242, ltmp2=88, ltmp3 = 1, ltmp4 = 4200;
  325.   oid ourprefix[] = { 1,2,3,4};
  326.   oid testparse[] = { 4,116,101,115,116,4200};
  327.   int ret;
  328.   
  329.   char *string="wes", *string2 = "dawn", *string3 = "test";
  330.   struct header_complex_index *thestorage = NULL;
  331.   debug_register_tokens("header_complex");
  332.   snmp_set_do_debugging(1);
  333.   
  334.   vars = NULL;
  335.   len2 = sizeof(ltmp);
  336.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) &ltmp, len2);
  337.   header_complex_add_data(&thestorage, vars, ourprefix);
  338.   vars = NULL;
  339.   len2 = strlen(string);
  340.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string, len2);
  341.   header_complex_add_data(&thestorage, vars, ourprefix);
  342.   vars = NULL;
  343.   len2 = sizeof(ltmp2);
  344.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) &ltmp2, len2);
  345.   header_complex_add_data(&thestorage, vars, ourprefix);
  346.   vars = NULL;
  347.   len2 = strlen(string2);
  348.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string2, len2);
  349.   header_complex_add_data(&thestorage, vars, ourprefix);
  350.   vars = NULL;
  351.   len2 = sizeof(ltmp3);
  352.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) &ltmp3, len2);
  353.   header_complex_add_data(&thestorage, vars, ourprefix);
  354.   vars = NULL;
  355.   len2 = strlen(string3);
  356.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string3, len2);
  357.   len2 = sizeof(ltmp4);
  358.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) &ltmp4, len2);
  359.   header_complex_add_data(&thestorage, vars, ourprefix);
  360.   header_complex_dump(thestorage);
  361.   vars = NULL;
  362.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);
  363.   snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, NULL, 0);
  364.   ret = header_complex_parse_oid(testparse, sizeof(testparse)/sizeof(oid), vars);
  365.   DEBUGMSGTL(("header_complex_test", "parse returned %d...n", ret));
  366. }
  367. #endif