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

SNMP编程

开发平台:

C/C++

  1. /*
  2.  * agent_registry.c
  3.  *
  4.  * Maintain a registry of MIB subtrees, together
  5.  *   with related information regarding mibmodule, sessions, etc
  6.  */
  7. #define IN_SNMP_VARS_C
  8. #include <config.h>
  9. #if HAVE_STRING_H
  10. #include <string.h>
  11. #endif
  12. #if HAVE_STDLIB_H
  13. #include <stdlib.h>
  14. #endif
  15. #include <sys/types.h>
  16. #include <stdio.h>
  17. #include <fcntl.h>
  18. #if HAVE_WINSOCK_H
  19. #include <ip/socket.h>
  20. #endif
  21. #if TIME_WITH_SYS_TIME
  22. # ifdef WIN32
  23. #  include <sys/timeb.h>
  24. # else
  25. #  include <time.h>
  26. # endif
  27. # include <time.h>
  28. #else
  29. # if HAVE_SYS_TIME_H
  30. #  include <sys/time.h>
  31. # else
  32. #  include <time.h>
  33. # endif
  34. #endif
  35. #ifdef OS_VXWORKS
  36. #include <sys/times.h>
  37. #endif
  38. #if HAVE_DMALLOC_H
  39. #include <dmalloc.h>
  40. #endif
  41. #include "mibgroup/mibincl.h"
  42. #include "snmp_client.h"
  43. #include "default_store.h"
  44. #include "ds_agent.h"
  45. #include "callback.h"
  46. #include "agent_callbacks.h"
  47. #include "agent_registry.h"
  48. #include "snmp_alarm.h"
  49. #include "snmpd.h"
  50. #include "mibgroup/struct.h"
  51. #include "mib_module_includes.h"
  52. #ifdef USING_AGENTX_SUBAGENT_MODULE
  53. #include "agentx/subagent.h"
  54. #include "agentx/client.h"
  55. #endif
  56. #include <boot/convert.h>
  57. #include <bspfuncs.h>
  58. #include <libsys/misc.h>
  59. struct snmp_index {
  60.     struct variable_list varbind; /* or pointer to var_list ? */
  61.     struct snmp_session *session; /* NULL implies unused  ? */
  62.     struct snmp_index *next_oid;
  63.     struct snmp_index *prev_oid;
  64.     struct snmp_index *next_idx;
  65. } *snmp_index_head = NULL; 
  66. struct subtree *subtrees;
  67.  
  68. int tree_compare(const struct subtree *ap, const struct subtree *bp)
  69. {
  70.   return snmp_oid_compare(ap->name,ap->namelen,bp->name,bp->namelen);
  71. }
  72. BOOL ReadObjidFromSubtree (char *str, oid name[], int *name_len)
  73. {
  74. struct subtree *sp;
  75. /*The label in subtree may be NULL, skip these subtrees*/
  76. if (strlen(str) < 3)
  77. return FALSE;
  78. for (sp = subtrees; sp != NULL; sp = sp->next)
  79. {
  80. if (!strcmp (str, sp->label))
  81. {
  82. *name_len = sp->namelen;
  83. memcpy (name, sp->name, *name_len*sizeof (oid));
  84. return TRUE;
  85. }
  86. }
  87. return FALSE;
  88. }
  89. /*
  90.  *  Split the subtree into two at the specified point,
  91.  *    returning the new (second) subtree
  92.  */
  93. struct subtree *
  94. split_subtree(struct subtree *current, oid name[], int name_len )
  95. {
  96.     struct subtree *new_sub, *ptr;
  97.     int i;
  98.     char *cp;
  99.     if ( snmp_oid_compare(name, name_len,
  100.   current->end, current->end_len) > 0 )
  101. return NULL; /* Split comes after the end of this subtree */
  102.      new_sub = (struct subtree *)malloc(sizeof(struct subtree));
  103.      if ( new_sub == NULL )
  104. return NULL;
  105.     memcpy(new_sub, current, sizeof(struct subtree));
  106. /* Set up the point of division */
  107.     memcpy(current->end,   name, name_len*sizeof(oid));
  108.     memcpy(new_sub->start, name, name_len*sizeof(oid));
  109.     current->end_len   = (unsigned char)name_len;
  110.     new_sub->start_len = (unsigned char)name_len;
  111. /*
  112.  * Split the variables between the two new subtrees
  113.  */
  114.     i = current->variables_len;
  115.     current->variables_len = 0;
  116.     for ( ; i > 0 ; i-- ) {
  117. /* Note that the variable "name" field omits
  118.    the prefix common to the whole registration,
  119.    hence the strange comparison here */
  120. if ( snmp_oid_compare( new_sub->variables[0].name,
  121.        new_sub->variables[0].namelen,
  122.        name     + current->namelen, 
  123.        name_len - current->namelen ) >= 0 )
  124.     break; /* All following variables belong to the second subtree */
  125. current->variables_len++;
  126. new_sub->variables_len--;
  127. cp = (char *)new_sub->variables;
  128. new_sub->variables = (struct variable *)(cp + new_sub->variables_width);
  129.     }
  130. /* Delegated trees should retain their variables regardless */
  131.     if ( current->variables_len > 0 &&
  132. IS_DELEGATED((u_char)current->variables[0].type)) {
  133. new_sub->variables_len = 1;
  134. new_sub->variables     = current->variables;
  135.     }
  136. /* Propogate this split down through any children */
  137.     if ( current->children )
  138. {
  139. new_sub->children = split_subtree(current->children, name, name_len);
  140. if (new_sub->children == NULL)
  141. {
  142.   free (new_sub);
  143.   return NULL;
  144. }
  145. }
  146. /* Retain the correct linking of the list */
  147.     for ( ptr = current ; ptr != NULL ; ptr=ptr->children )
  148.           ptr->next = new_sub;
  149.     for ( ptr = new_sub ; ptr != NULL ; ptr=ptr->children )
  150.           ptr->prev = current;
  151.     for ( ptr = new_sub->next ; ptr != NULL ; ptr=ptr->children )
  152.           ptr->prev = new_sub;
  153.     return new_sub;
  154. }
  155. int
  156. load_subtree( struct subtree *new_sub )
  157. {
  158.     struct subtree *tree1, *tree2, *new2;
  159.     struct subtree *prev, *next;
  160.     int res;
  161.     if ( new_sub == NULL )
  162. return MIB_REGISTERED_OK; /* Degenerate case */
  163. /*
  164.  * Find the subtree that contains the start of 
  165.  *  the new subtree (if any)...
  166.  */
  167.     tree1 = find_subtree( new_sub->start, new_sub->start_len, NULL );
  168. /*
  169.  * ...and the subtree that follows the new one
  170.  * (NULL implies this is the final region covered)
  171.  */  
  172.     if ( tree1 == NULL )
  173.         tree2 = find_subtree_next( new_sub->start, new_sub->start_len, NULL );
  174.     else
  175. tree2 = tree1->next;
  176. /*
  177.  * Handle new subtrees that start in virgin territory.
  178.  */
  179.     if ( tree1 == NULL ) {
  180. new2 = NULL;
  181. /* Is there any overlap with later subtrees ? */
  182. if ( tree2 && snmp_oid_compare( new_sub->end, new_sub->end_len,
  183. tree2->start, tree2->start_len ) > 0 )
  184.     new2 = split_subtree( new_sub, tree2->start, tree2->start_len );
  185. /*
  186.  * Link the new subtree (less any overlapping region)
  187.  *  with the list of existing registrations
  188.  */
  189. if ( tree2 ) {
  190.     new_sub->prev = tree2->prev;
  191.     tree2->prev       = new_sub;
  192. }
  193. else
  194.     new_sub->prev = find_subtree_previous( new_sub->start, new_sub->start_len, NULL );
  195. if ( new_sub->prev )
  196.     new_sub->prev->next = new_sub;
  197. else
  198.     subtrees = new_sub;
  199. new_sub->next     = tree2;
  200. /*
  201.  * If there was any overlap,
  202.  *  recurse to merge in the overlapping region
  203.  *  (including anything that may follow the overlap)
  204.  */
  205. if ( new2 )
  206.     return load_subtree( new2 );
  207.     }
  208.     else {
  209. /*
  210.  *  If the new subtree starts *within* an existing registration
  211.  *    (rather than at the same point as it), then split the
  212.  *    existing subtree at this point.
  213.  */
  214. if ( snmp_oid_compare( new_sub->start, new_sub->start_len, 
  215.        tree1->start,   tree1->start_len) != 0 )
  216.     tree1 = split_subtree( tree1, new_sub->start, new_sub->start_len);
  217.     if ( tree1 == NULL )
  218. return MIB_REGISTRATION_FAILED;
  219. /*  Now consider the end of this existing subtree:
  220.  * If it matches the new subtree precisely,
  221.  *   simply merge the new one into the list of children
  222.  * If it includes the whole of the new subtree,
  223.  *   split it at the appropriate point, and merge again
  224.  *
  225.  * If the new subtree extends beyond this existing region,
  226.  *   split it, and recurse to merge the two parts.
  227.  */
  228.  switch ( snmp_oid_compare( new_sub->end, new_sub->end_len, 
  229.     tree1->end,   tree1->end_len))  {
  230. case -1: /* Existing subtree contains new one */
  231. (void) split_subtree( tree1,
  232. new_sub->end, new_sub->end_len);
  233. /* Fall Through */
  234. case  0: /* The two trees match precisely */
  235. /*
  236.  * Note: This is the only point where the original
  237.  *  registration OID ("name") is used
  238.  */
  239. prev = NULL;
  240. next = tree1;
  241. while ( next && next->namelen > new_sub->namelen ) {
  242. prev = next;
  243. next = next->children;
  244. }
  245. while ( next && next->namelen == new_sub->namelen &&
  246. next->priority < new_sub->priority ) {
  247. prev = next;
  248. next = next->children;
  249. }
  250. if ( next && next->namelen  == new_sub->namelen &&
  251. next->priority == new_sub->priority )
  252.    return MIB_DUPLICATE_REGISTRATION;
  253. if ( prev ) {
  254.     new_sub->children = next;
  255.     prev->children    = new_sub;
  256.     new_sub->prev = prev->prev;
  257.     new_sub->next = prev->next;
  258. }
  259. else {
  260.     new_sub->children = next;
  261.     new_sub->prev = next->prev;
  262.     new_sub->next = next->next;
  263.     for ( next = new_sub->next ;
  264.        next != NULL ;
  265.   next = next->children )
  266. next->prev = new_sub;
  267.     for ( prev = new_sub->prev ;
  268.        prev != NULL ;
  269.   prev = prev->children )
  270. prev->next = new_sub;
  271. }
  272. break;
  273. case  1: /* New subtree contains the existing one */
  274.      new2 = split_subtree( new_sub,
  275. tree1->end, tree1->end_len);
  276. res = load_subtree( new_sub );
  277. if ( res != MIB_REGISTERED_OK )
  278.     return res;
  279. return load_subtree( new2 );
  280.  }
  281.     }
  282.     return 0;
  283. }
  284. extern void *sys_staticmem_alloc(size_t size);
  285. int
  286. register_mib_range(const char *moduleName,
  287.      struct variable *var,
  288.      size_t varsize,
  289.      size_t numvars,
  290.      oid *mibloc,
  291.      size_t mibloclen,
  292.      int priority,
  293.      int range_subid,
  294.      oid range_ubound,
  295.      struct snmp_session *ss)
  296. {
  297.   struct subtree *subtree, *sub2;
  298.   int res, i;
  299.   struct register_parameters reg_parms;
  300. #if 0
  301.   unsigned char short_company_name[30];
  302.   /*add by huanghuan 2001.9.5 to change bdcom enterprise to digitalchina enterprise*/
  303.   memset (short_company_name, 0, sizeof(short_company_name));
  304.   if (eprom_extend() && !get_extend_info_string(INFO_SHORT_COMPANY_NAME, short_company_name))
  305.   {
  306.    if (stricmp(short_company_name, DIGITAL_CHINA_SHORT_VENDOR_NAME) == 0)
  307.    {
  308.    if ((mibloc[0] == 1) && (mibloc[1] == 3) && (mibloc[2] == 6) && (mibloc[3] == 1)
  309.    && (mibloc[4] == 4) && (mibloc[5] == 1) && (mibloc[6] == 3320))
  310.    mibloc[6] = 6339;
  311.    }
  312.    else if (stricmp(short_company_name, LEGEND_SHORT_VENDOR_NAME) == 0)
  313.    {
  314.    if ((mibloc[0] == 1) && (mibloc[1] == 3) && (mibloc[2] == 6) && (mibloc[3] == 1)
  315.    && (mibloc[4] == 4) && (mibloc[5] == 1) && (mibloc[6] == 3320))
  316.    mibloc[6] = LEGEND_ENTERPRISE_NUMBER;
  317.    }
  318.   }
  319.   #endif
  320.    subtree = (struct subtree *) malloc(sizeof(struct subtree));
  321.    if ( subtree == NULL )
  322.     return MIB_REGISTRATION_FAILED;
  323.   memset(subtree, 0, sizeof(struct subtree));
  324.   DEBUGMSGTL(("register_mib", "registering "%s" at ", moduleName));
  325.   DEBUGMSGOID(("register_mib", mibloc, mibloclen));
  326.   DEBUGMSG(("register_mib","n"));
  327.     
  328. /*
  329.  * Create the new subtree node being registered
  330.  */
  331.   memcpy(subtree->name, mibloc, mibloclen*sizeof(oid));
  332.   subtree->namelen = (u_char) mibloclen;
  333.   memcpy(subtree->start, mibloc, mibloclen*sizeof(oid));
  334.   subtree->start_len = (u_char) mibloclen;
  335.   memcpy(subtree->end, mibloc, mibloclen*sizeof(oid));
  336.   subtree->end[ mibloclen-1 ]++; /* XXX - or use 'variables' info ? */
  337.   subtree->end_len = (u_char) mibloclen;
  338.   memcpy(subtree->label, moduleName, strlen(moduleName)+1);
  339.   if ( var ) {
  340.     subtree->variables = 
  341. #if SYS_VOS_STATICMEM
  342.     sys_staticmem_alloc(varsize*numvars);
  343. #else
  344.     malloc(varsize*numvars);
  345. #endif
  346.     memcpy(subtree->variables, var, numvars*varsize);
  347.     subtree->variables_len = numvars;
  348.     subtree->variables_width = varsize;
  349.   }
  350.   subtree->priority = (unsigned char)priority;
  351.   subtree->session = ss;
  352.   res = load_subtree(subtree);
  353. /*
  354.  * If registering a range,
  355.  *   use the first subtree as a template
  356.  *   for the rest of the range
  357.  */
  358.   if (( res == MIB_REGISTERED_OK ) && ( range_subid != 0 )) {
  359.     for ( i = mibloc[range_subid-1] +1 ; i < (int)range_ubound ; i++ ) {
  360.   sub2 = (struct subtree *) malloc(sizeof(struct subtree));
  361.  
  362. if ( sub2 == NULL ) {
  363.     unregister_mib_range( mibloc, mibloclen, priority,
  364.   range_subid, range_ubound);
  365.     return MIB_REGISTRATION_FAILED;
  366. }
  367. memcpy( sub2, subtree, sizeof(struct subtree));
  368. sub2->start[range_subid-1] = i;
  369. sub2->end[  range_subid-1] = i; /* XXX - ???? */
  370. res = load_subtree(sub2);
  371. if ( res != MIB_REGISTERED_OK ) {
  372.     unregister_mib_range( mibloc, mibloclen, priority,
  373.   range_subid, range_ubound);
  374.     return MIB_REGISTRATION_FAILED;
  375. }
  376.     }
  377.   }
  378.   reg_parms.name = mibloc;
  379.   reg_parms.namelen = mibloclen;
  380.   reg_parms.priority = priority;
  381.   reg_parms.range_subid  = range_subid;
  382.   reg_parms.range_ubound = range_ubound;
  383.   snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_REGISTER_OID,
  384.                       &reg_parms);
  385.   return res;
  386. }
  387. int
  388. register_mib_priority(const char *moduleName,
  389.      struct variable *var,
  390.      size_t varsize,
  391.      size_t numvars,
  392.      oid *mibloc,
  393.      size_t mibloclen,
  394.      int priority)
  395. {
  396.   return register_mib_range( moduleName, var, varsize, numvars,
  397. mibloc, mibloclen, priority, 0, 0, NULL );
  398. }
  399. int
  400. register_mib(const char *moduleName,
  401.      struct variable *var,
  402.      size_t varsize,
  403.      size_t numvars,
  404.      oid *mibloc,
  405.      size_t mibloclen)
  406. {
  407. SNMP_ENTERPRISE_MODIFY(mibloc,mibloclen);
  408. return register_mib_priority( moduleName, var, varsize, numvars,
  409. mibloc, mibloclen, DEFAULT_MIB_PRIORITY );
  410. }
  411. void
  412. unload_subtree( struct subtree *sub, struct subtree *prev)
  413. {
  414.     struct subtree *ptr;
  415.     if ( prev != NULL ) { /* non-leading entries are easy */
  416. prev->children = sub->children;
  417. return;
  418.     }
  419. /* otherwise, we need to amend our neighbours as well */
  420.     if ( sub->children == NULL) { /* just remove this node completely */
  421. for (ptr = sub->prev ; ptr ; ptr=ptr->children )
  422.     ptr->next = sub->next;
  423. for (ptr = sub->next ; ptr ; ptr=ptr->children )
  424.     ptr->prev = sub->prev;
  425. return;
  426.     }
  427.     else {
  428. for (ptr = sub->prev ; ptr ; ptr=ptr->children )
  429.     ptr->next = sub->children;
  430. for (ptr = sub->next ; ptr ; ptr=ptr->children )
  431.     ptr->prev = sub->children;
  432. return;
  433.     }
  434. }
  435. int
  436. unregister_mib_range( oid *name, size_t len, int priority,
  437.       int range_subid, oid range_ubound)
  438. {
  439.   struct subtree *list, *myptr;
  440.   struct subtree *prev, *child;             /* loop through children */
  441.   struct register_parameters reg_parms;
  442.   list = find_subtree( name, len, subtrees );
  443.   if ( list == NULL )
  444. return MIB_NO_SUCH_REGISTRATION;
  445.   for ( child=list, prev=NULL;  child != NULL;
  446.   prev=child, child=child->children ) {
  447.       if (( snmp_oid_compare( child->name, child->namelen, name, len) == 0 )
  448.   && ( child->priority == priority ))
  449. break; /* found it */
  450.   }
  451.   if ( child == NULL )
  452. return MIB_NO_SUCH_REGISTRATION;
  453.   unload_subtree( child, prev );
  454.   myptr = child; /* remember this for later */
  455. /*
  456.  *  Now handle any occurances in the following subtrees,
  457.  * as a result of splitting this range.  Due to the
  458.  * nature of the way such splits work, the first
  459.  *  subtree 'slice' that doesn't refer to the given
  460.  * name marks the end of the original region.
  461.  *
  462.  *  This should also serve to register ranges.
  463.  */
  464.   for ( list = myptr->next ; list != NULL ; list=list->next ) {
  465.    for ( child=list, prev=NULL;  child != NULL;
  466.         prev=child, child=child->children ) {
  467.     if (( snmp_oid_compare( child->name, child->namelen,
  468. name, len) == 0 )
  469. && ( child->priority == priority )) {
  470.     unload_subtree( child, prev );
  471.     free_subtree( child );
  472.     break;
  473.     }
  474. }
  475. if ( child == NULL ) /* Didn't find the given name */
  476.     break;
  477.   }
  478.   free_subtree( myptr );
  479.   
  480.   reg_parms.name = name;
  481.   reg_parms.namelen = len;
  482.   reg_parms.priority = priority;
  483.   reg_parms.range_subid  = range_subid;
  484.   reg_parms.range_ubound = range_ubound;
  485.   snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREGISTER_OID,
  486.                       &reg_parms);
  487.   return MIB_UNREGISTERED_OK;
  488. }
  489. int
  490. unregister_mib_priority(oid *name, size_t len, int priority)
  491. {
  492.   return unregister_mib_range( name, len, priority, 0, 0 );
  493. }
  494. int
  495. unregister_mib(oid *name,
  496.        size_t len)
  497. {
  498.   return unregister_mib_priority( name, len, DEFAULT_MIB_PRIORITY );
  499. }
  500. void
  501. unregister_mibs_by_session (struct snmp_session *ss)
  502. {
  503.   struct subtree *list, *list2;
  504.   struct subtree *child, *prev, *next_child;
  505.   for( list = subtrees; list != NULL; list = list2) {
  506.     list2 = list->next;
  507.     for ( child=list, prev=NULL;  child != NULL; child=next_child ) {
  508.       next_child = child->children;
  509.       if (( (ss->flags & SNMP_FLAGS_SUBSESSION) && child->session == ss ) ||
  510.           (!(ss->flags & SNMP_FLAGS_SUBSESSION) &&
  511.                                       child->session->subsession == ss )) {
  512.               unload_subtree( child, prev );
  513.               free_subtree( child );
  514.       }
  515.       else
  516.           prev = child;
  517.     }
  518.   }
  519. }
  520. struct subtree *
  521. free_subtree(struct subtree *st)
  522. {
  523.   struct subtree *ret = NULL;
  524.   if ((snmp_oid_compare(st->name, st->namelen, st->start, st->start_len) == 0)
  525.        && (st->variables != NULL))
  526.     free(st->variables);
  527.   if (st->next != NULL)
  528.     ret = st->next;
  529.  
  530.   free(st);
  531.  
  532.   return ret;
  533. }
  534. /* in_a_view: determines if a given snmp_pdu is allowed to see a
  535.    given name/namelen OID pointer
  536.    name         IN - name of var, OUT - name matched
  537.    nameLen      IN -number of sub-ids in name, OUT - subid-is in matched name
  538.    pi           IN - relevant auth info re PDU 
  539.    cvp          IN - relevant auth info re mib module
  540. */
  541. int
  542. in_a_view(oid   *name,      /* IN - name of var, OUT - name matched */
  543.           size_t   *namelen,   /* IN -number of sub-ids in name*/
  544.           struct snmp_pdu *pdu,       /* IN - relevant auth info re PDU */
  545.           int            type)      /* IN - variable type being checked */
  546. {
  547.   struct view_parameters view_parms;
  548.   view_parms.pdu = pdu;
  549.   view_parms.name = name;
  550.   if (namelen)
  551.       view_parms.namelen = *namelen;
  552.   else
  553.       view_parms.namelen = 0;
  554.   view_parms.errorcode = 0;
  555.   if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
  556.     return 0; /* Enable bypassing of view-based access control */
  557.   /* check for v1 and counter64s, since snmpv1 doesn't support it */
  558.   if (pdu->version == SNMP_VERSION_1 && type == ASN_COUNTER64)
  559.      return 5;
  560.   switch (pdu->version) {
  561.   case SNMP_VERSION_1:
  562.   case SNMP_VERSION_2c:
  563.   case SNMP_VERSION_3:
  564.     snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
  565.                         &view_parms);
  566.     return view_parms.errorcode;
  567.   }
  568.   return 1;
  569. }
  570. /* in_a_view: determines if a given snmp_pdu is ever going to be allowed to do
  571.    anynthing or if it's not going to ever be authenticated. */
  572. int
  573. snmp_check_access(struct snmp_pdu *pdu)      /* IN - pdu being checked */
  574. {
  575.   struct view_parameters view_parms;
  576.   view_parms.pdu = pdu;
  577.   view_parms.name = 0;
  578.   view_parms.namelen = 0;
  579.   view_parms.errorcode = 0;
  580.   if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
  581.     return 0; /* Enable bypassing of view-based access control */
  582.   switch (pdu->version) {
  583.   case SNMP_VERSION_1:
  584.   case SNMP_VERSION_2c:
  585.   case SNMP_VERSION_3:
  586.     snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
  587.                         SNMPD_CALLBACK_ACM_CHECK_INITIAL,
  588.                         &view_parms);
  589.     return view_parms.errorcode;
  590.   }
  591.   return 1;
  592. }
  593. /* lexicographical compare two object identifiers.
  594.  * Returns -1 if name1 < name2,
  595.  *          0 if name1 = name2, or name1 matches name2 for length of name2
  596.  *          1 if name1 > name2
  597.  *
  598.  * Note: snmp_oid_compare checks len2 before last return.
  599.  */
  600. int
  601. compare_tree(const oid *in_name1,
  602.      size_t len1, 
  603.      const oid *in_name2, 
  604.      size_t len2)
  605. {
  606.     register int len, res;
  607.     register const oid * name1 = in_name1;
  608.     register const oid * name2 = in_name2;
  609.     /* len = minimum of len1 and len2 */
  610.     if (len1 < len2)
  611. len = len1;
  612.     else
  613. len = len2;
  614.     /* find first non-matching OID */
  615.     while(len-- > 0){
  616. res = *(name1++) - *(name2++);
  617. if (res < 0)
  618.     return -1;
  619. if (res > 0)
  620.     return 1;
  621.     }
  622.     /* both OIDs equal up to length of shorter OID */
  623.     if (len1 < len2)
  624. return -1;
  625.     /* name1 matches name2 for length of name2, or they are equal */
  626.     return 0;
  627. }
  628. struct subtree *find_subtree_previous(oid *name,
  629.      size_t len,
  630.      struct subtree *subtree)
  631. {
  632.   struct subtree *myptr, *previous = NULL;
  633.   if ( subtree )
  634. myptr = subtree;
  635.   else
  636. myptr = subtrees; /* look through everything */
  637.   for( ; myptr != NULL; previous = myptr, myptr = myptr->next) {
  638.     if (snmp_oid_compare(name, len, myptr->start, myptr->start_len) < 0)
  639.       return previous;
  640.   }
  641.   return previous;
  642. }
  643. struct subtree *find_subtree_next(oid *name, 
  644.   size_t len,
  645.   struct subtree *subtree)
  646. {
  647.   struct subtree *myptr;
  648.   myptr = find_subtree_previous(name, len, subtree);
  649.   if ( myptr != NULL ) {
  650.      myptr = myptr->next;
  651.      while ( myptr && (myptr->variables == NULL || myptr->variables_len == 0) )
  652.          myptr = myptr->next;
  653.      return myptr;
  654.   }
  655.   else if (subtree && snmp_oid_compare(name, len, subtree->start, subtree->start_len) < 0)
  656.      return subtree;
  657.   else
  658.      return NULL;
  659. }
  660. struct subtree *find_subtree(oid *name,
  661.      size_t len,
  662.      struct subtree *subtree)
  663. {
  664.   struct subtree *myptr;
  665.   myptr = find_subtree_previous(name, len, subtree);
  666.   if (myptr && snmp_oid_compare(name, len, myptr->end, myptr->end_len) < 0)
  667. return myptr;
  668.   return NULL;
  669. }
  670. struct snmp_session *get_session_for_oid( oid *name, size_t len)
  671. {
  672.    struct subtree *myptr;
  673.    myptr = find_subtree_previous(name, len, subtrees);
  674.    while ( myptr && myptr->variables == NULL )
  675.         myptr = myptr->next;
  676.    if ( myptr == NULL )
  677.         return NULL;
  678.    else
  679.         return myptr->session;
  680. }
  681. static struct subtree root_subtrees[] = {
  682.    { { 0 }, 1 }, /* ccitt */
  683.    { { 1 }, 1 }, /*  iso  */
  684.    { { 2 }, 1 } /* joint-ccitt-iso */
  685. };
  686. #include "snmp/snmpreg.h"    
  687. extern struct snmp_list *SnmpMibList;
  688. extern long    subtrees_enable;/*** sun define 2000.07.27 ***/
  689. void setup_tree (void)
  690. {
  691. #ifdef USING_AGENTX_SUBAGENT_MODULE
  692.   int role;
  693.   role = ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE);
  694.   ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
  695. #endif
  696.   struct snmp_list *snmpreglist;
  697.   register_mib("ccitt", NULL, 0, 0,
  698. root_subtrees[0].name,  root_subtrees[0].namelen);
  699.   register_mib("iso", NULL, 0, 0,
  700. root_subtrees[1].name,  root_subtrees[1].namelen);
  701.   register_mib("joint-ccitt-iso", NULL, 0, 0,
  702. root_subtrees[2].name,  root_subtrees[2].namelen);
  703.   /* Support for 'static' subtrees (subtrees_old) has now been dropped */
  704.   /* No longer necessary to sort the mib tree - this is inherent in
  705.      the construction of the subtree structure */
  706.   /* Go through the 'static' subtrees (subtrees_old),
  707. and link them into the global subtree structure */
  708.    subtrees_enable = TRUE;/*** yang mod 2005.08.28 ***/
  709. for(snmpreglist=SnmpMibList;snmpreglist!=NULL;snmpreglist = snmpreglist->next){
  710. (*snmpreglist->init_mib)();
  711. }
  712.   /* No longer necessary to sort the mib tree - this is inherent in
  713.      the construction of the subtree structure */
  714. #ifdef USING_AGENTX_SUBAGENT_MODULE
  715.   ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, role);
  716. #endif
  717. }
  718. /*
  719.  * Initial support for index allocation
  720.  */
  721. extern struct snmp_session *main_session;
  722. char *
  723. register_string_index( oid *name, size_t name_len, char *cp )
  724. {
  725.     struct variable_list varbind, *res;
  726.     
  727.     memset( &varbind, 0, sizeof(struct variable_list));
  728.     varbind.type = ASN_OCTET_STR;
  729.     snmp_set_var_objid( &varbind, name, name_len );
  730.     if ( cp != ANY_STRING_INDEX ) {
  731.         snmp_set_var_value( &varbind, (u_char *)cp, strlen(cp) );
  732. res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
  733.     }
  734.     else
  735. res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
  736.     if ( res == NULL )
  737. return NULL;
  738.     else
  739. return (char *)res->val.string;
  740. }
  741. int
  742. register_int_index( oid *name, size_t name_len, int val )
  743. {
  744.     struct variable_list varbind, *res;
  745.     
  746.     memset( &varbind, 0, sizeof(struct variable_list));
  747.     varbind.type = ASN_INTEGER;
  748.     snmp_set_var_objid( &varbind, name, name_len );
  749.     varbind.val.string = varbind.buf;
  750.     if ( val != ANY_INTEGER_INDEX ) {
  751.         varbind.val_len = sizeof(long);
  752.         *varbind.val.integer = val;
  753. res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
  754.     }
  755.     else
  756. res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
  757.     if ( res == NULL )
  758. return -1;
  759.     else
  760. return *res->val.integer;
  761. }
  762. struct variable_list *
  763. register_oid_index( oid *name, size_t name_len,
  764.     oid *value, size_t value_len )
  765. {
  766.     struct variable_list varbind;
  767.     
  768.     memset( &varbind, 0, sizeof(struct variable_list));
  769.     varbind.type = ASN_OBJECT_ID;
  770.     snmp_set_var_objid( &varbind, name, name_len );
  771.     if ( value != ANY_OID_INDEX ) {
  772.         snmp_set_var_value( &varbind, (u_char*)value, value_len*sizeof(oid) );
  773. return( register_index( &varbind, ALLOCATE_THIS_INDEX, main_session ));
  774.     }
  775.     else
  776. return( register_index( &varbind, ALLOCATE_ANY_INDEX, main_session ));
  777. }
  778. struct variable_list*
  779. register_index(struct variable_list *varbind, int flags, struct snmp_session *ss )
  780. {
  781.     struct snmp_index *new_index, *idxptr, *idxptr2;
  782.     struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
  783.     int res, res2, i;
  784. #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
  785.     if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
  786. return( agentx_register_index( ss, varbind, flags ));
  787. #endif
  788. /* Look for the requested OID entry */
  789.     prev_oid_ptr = NULL;
  790.     prev_idx_ptr = NULL;
  791.     res  = 1;
  792.     res2 = 1;
  793.     for( idxptr = snmp_index_head ; idxptr != NULL;
  794.  prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
  795. if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
  796. idxptr->varbind.name,
  797. idxptr->varbind.name_length)) <= 0 )
  798. break;
  799.     }
  800. /*  Found the OID - now look at the registered indices */
  801.     if ( res == 0 && idxptr ) {
  802. if ( varbind->type != idxptr->varbind.type )
  803.     return NULL; /* wrong type */
  804. /*
  805.  * If we've been asked for an arbitrary new value,
  806.  * then find the end of the list.
  807.  * If we've been asked for any arbitrary value,
  808.  * then look for an unused entry, and use that.
  809.  *      If there aren't any, continue as for new.
  810.  * Otherwise, locate the given value in the (sorted)
  811.  * list of already allocated values
  812.  */
  813. if ( flags & ALLOCATE_ANY_INDEX ) {
  814.             for(idxptr2 = idxptr ; idxptr2 != NULL;
  815.  prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
  816. if ( flags == ALLOCATE_ANY_INDEX && idxptr2->session == NULL ) {
  817.     idxptr2->session = ss ;
  818.     return &idxptr2->varbind;
  819. }
  820.     }
  821. }
  822. else {
  823.             for(idxptr2 = idxptr ; idxptr2 != NULL;
  824.  prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
  825.         switch ( varbind->type ) {
  826.     case ASN_INTEGER:
  827. res2 = (*varbind->val.integer - *idxptr2->varbind.val.integer);
  828. break;
  829.     case ASN_OCTET_STR:
  830. i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len);
  831. res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i);
  832. break;
  833.     case ASN_OBJECT_ID:
  834. res2 = snmp_oid_compare(varbind->val.objid, varbind->val_len/sizeof(oid),
  835. idxptr2->varbind.val.objid,
  836. idxptr2->varbind.val_len/sizeof(oid));
  837. break;
  838.     default:
  839.      return NULL; /* wrong type */
  840.         }
  841.         if ( res2 <= 0 )
  842.     break;
  843.     }
  844.     if ( res2 == 0 )
  845. return NULL; /* duplicate value */
  846. }
  847.     }
  848. /*
  849.  * OK - we've now located where the new entry needs to
  850.  * be fitted into the index registry tree
  851.  * To recap:
  852.  * 'prev_oid_ptr' points to the head of the OID index
  853.  *     list prior to this one.  If this is null, then
  854.  *     it means that this is the first OID in the list.
  855.  * 'idxptr' points either to the head of this OID list,
  856.  *     or the next OID (if this is a new OID request)
  857.  *     These can be distinguished by the value of 'res'.
  858.  *
  859.  * 'prev_idx_ptr' points to the index entry that sorts
  860.  *     immediately prior to the requested value (if any).
  861.  *     If an arbitrary value is required, then this will
  862.  *     point to the last allocated index.
  863.  *     If this pointer is null, then either this is a new
  864.  *     OID request, or the requested value is the first
  865.  *     in the list.
  866.  * 'idxptr2' points to the next sorted index (if any)
  867.  *     but is not actually needed any more.
  868.  *
  869.  *  Clear?  Good!
  870.  * I hope you've been paying attention.
  871.  *     There'll be a test later :-)
  872.  */
  873. /*
  874.  * We proceed by creating the new entry
  875.  *    (by copying the entry provided)
  876.  */
  877. new_index = (struct snmp_index *)malloc( sizeof( struct snmp_index ));
  878. if (new_index == NULL)
  879.     return NULL;
  880. if (snmp_clone_var( varbind, &new_index->varbind ) != 0 ) {
  881.     free( new_index );
  882.     return NULL;
  883. }
  884. new_index->session = ss;
  885. if ( varbind->type == ASN_OCTET_STR && flags == ALLOCATE_THIS_INDEX )
  886.     new_index->varbind.val.string[new_index->varbind.val_len] = 0;
  887. /*
  888.  * If we've been given a value, then we can use that, but
  889.  *    otherwise, we need to create a new value for this entry.
  890.  * Note that ANY_INDEX and NEW_INDEX are both covered by this
  891.  *   test (since NEW_INDEX & ANY_INDEX = ANY_INDEX, remember?)
  892.  */
  893. if ( flags & ALLOCATE_ANY_INDEX ) {
  894.     if ( prev_idx_ptr ) {
  895. if ( snmp_clone_var( &prev_idx_ptr->varbind, &new_index->varbind ) != 0 ) {
  896.     free( new_index );
  897.     return NULL;
  898. }
  899.     }
  900.     else
  901. new_index->varbind.val.string = new_index->varbind.buf;
  902.     switch ( varbind->type ) {
  903. case ASN_INTEGER:
  904.     if ( prev_idx_ptr ) {
  905. (*new_index->varbind.val.integer)++; 
  906.     }
  907.     else
  908. *(new_index->varbind.val.integer) = 1;
  909.     new_index->varbind.val_len = sizeof(long);
  910.     break;
  911. case ASN_OCTET_STR:
  912.     if ( prev_idx_ptr ) {
  913. i =  new_index->varbind.val_len-1;
  914. while ( new_index->varbind.buf[ i ] == 'z' ) {
  915.     new_index->varbind.buf[ i ] = 'a';
  916.     i--;
  917.     if ( i < 0 ) {
  918. i =  new_index->varbind.val_len;
  919.         new_index->varbind.buf[ i ] = 'a';
  920.         new_index->varbind.buf[ i+1 ] = 0;
  921.     }
  922. }
  923. new_index->varbind.buf[ i ]++;
  924.     }
  925.     else
  926.         strcpy((char *)new_index->varbind.buf, "aaaa");
  927.     new_index->varbind.val_len = strlen((char *)new_index->varbind.buf);
  928.     break;
  929. case ASN_OBJECT_ID:
  930.     if ( prev_idx_ptr ) {
  931. i =  prev_idx_ptr->varbind.val_len/sizeof(oid) -1;
  932. while ( new_index->varbind.val.objid[ i ] == 255 ) {
  933.     new_index->varbind.val.objid[ i ] = 1;
  934.     i--;
  935.     if ( i == 0 && new_index->varbind.val.objid[0] == 2 ) {
  936.         new_index->varbind.val.objid[ 0 ] = 1;
  937. i =  new_index->varbind.val_len/sizeof(oid);
  938.         new_index->varbind.val.objid[ i ] = 0;
  939. new_index->varbind.val_len += sizeof(oid);
  940.     }
  941. }
  942. new_index->varbind.val.objid[ i ]++;
  943.     }
  944.     else {
  945. /* If the requested OID name is small enough,
  946.  *   append another OID (1) and use this as the
  947.  *   default starting value for new indexes.
  948.  */
  949.         if ( (varbind->name_length+1) * sizeof(oid) <= 40 ) {
  950.     for ( i = 0 ; i < (int)varbind->name_length ; i++ )
  951.         new_index->varbind.val.objid[i] = varbind->name[i];
  952.     new_index->varbind.val.objid[varbind->name_length] = 1;
  953.     new_index->varbind.val_len =
  954. (varbind->name_length+1) * sizeof(oid);
  955.         }
  956.         else {
  957.     /* Otherwise use '.1.1.1.1...' */
  958.     i = 40/sizeof(oid);
  959.     if ( i > 4 )
  960. i = 4;
  961.     new_index->varbind.val_len = i * (sizeof(oid));
  962.     for (i-- ; i>=0 ; i-- )
  963.         new_index->varbind.val.objid[i] = 1;
  964.         }
  965.     }
  966.     break;
  967. default:
  968.     free( new_index );
  969.     return NULL; /* Index type not supported */
  970.     }
  971. }
  972. /*
  973.  * Right - we've set up the new entry.
  974.  * All that remains is to link it into the tree.
  975.  * There are a number of possible cases here,
  976.  *   so watch carefully.
  977.  */
  978. if ( prev_idx_ptr ) {
  979.     new_index->next_idx = prev_idx_ptr->next_idx;
  980.     new_index->next_oid = prev_idx_ptr->next_oid;
  981.     prev_idx_ptr->next_idx = new_index;
  982. }
  983. else {
  984.     if ( res == 0 && idxptr ) {
  985.         new_index->next_idx = idxptr;
  986.         new_index->next_oid = idxptr->next_oid;
  987.     }
  988.     else {
  989.         new_index->next_idx = NULL;
  990.         new_index->next_oid = idxptr;
  991.     }
  992.     if ( prev_oid_ptr ) {
  993. while ( prev_oid_ptr ) {
  994.     prev_oid_ptr->next_oid = new_index;
  995.     prev_oid_ptr = prev_oid_ptr->next_idx;
  996. }
  997.     }
  998.     else
  999.         snmp_index_head = new_index;
  1000. }
  1001.     return &new_index->varbind;
  1002. }
  1003. /*
  1004.  * Release an allocated index,
  1005.  *   to allow it to be used elsewhere
  1006.  */
  1007. int
  1008. release_index(struct variable_list *varbind)
  1009. {
  1010.     return( unregister_index( varbind, TRUE, NULL ));
  1011. }
  1012. /*
  1013.  * Completely remove an allocated index,
  1014.  *   due to errors in the registration process.
  1015.  */
  1016. int
  1017. remove_index(struct variable_list *varbind, struct snmp_session *ss)
  1018. {
  1019.     return( unregister_index( varbind, FALSE, ss ));
  1020. }
  1021. void
  1022. unregister_index_by_session(struct snmp_session *ss)
  1023. {
  1024.     struct snmp_index *idxptr, *idxptr2;
  1025.     for(idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid)
  1026. for(idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx)
  1027.     if ( idxptr2->session == ss )
  1028. idxptr2->session = NULL;
  1029. }
  1030. int
  1031. unregister_index(struct variable_list *varbind, int remember, struct snmp_session *ss)
  1032. {
  1033.     struct snmp_index *idxptr, *idxptr2;
  1034.     struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
  1035.     int res, res2, i;
  1036. #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
  1037.     if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
  1038. return( agentx_unregister_index( ss, varbind ));
  1039. #endif
  1040. /* Look for the requested OID entry */
  1041.     prev_oid_ptr = NULL;
  1042.     prev_idx_ptr = NULL;
  1043.     res  = 1;
  1044.     res2 = 1;
  1045.     for( idxptr = snmp_index_head ; idxptr != NULL;
  1046.  prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
  1047. if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
  1048. idxptr->varbind.name,
  1049. idxptr->varbind.name_length)) <= 0 )
  1050. break;
  1051.     }
  1052.     if ( res != 0 )
  1053. return INDEX_ERR_NOT_ALLOCATED;
  1054.     if ( varbind->type != idxptr->varbind.type )
  1055. return INDEX_ERR_WRONG_TYPE;
  1056.     for(idxptr2 = idxptr ; idxptr2 != NULL;
  1057. prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
  1058. i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len);
  1059. res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i);
  1060. if ( res2 <= 0 )
  1061.     break;
  1062.     }
  1063.     if ( res2 != 0 )
  1064. return INDEX_ERR_NOT_ALLOCATED;
  1065.     if ( ss != idxptr2->session )
  1066. return INDEX_ERR_WRONG_SESSION;
  1067. /*
  1068.  *  If this is a "normal" index unregistration,
  1069.  * mark the index entry as unused, but leave
  1070.  * it in situ.  This allows differentiation
  1071.  * between ANY_INDEX and NEW_INDEX
  1072.  */
  1073.     if ( remember ) {
  1074. idxptr2->session = NULL; /* Unused index */
  1075. return SNMP_ERR_NOERROR;
  1076.     }
  1077. /*
  1078.  *  If this is a failed attempt to register a
  1079.  * number of indexes, the successful ones
  1080.  * must be removed completely.
  1081.  */
  1082.     if ( prev_idx_ptr ) {
  1083. prev_idx_ptr->next_idx = idxptr2->next_idx;
  1084.     }
  1085.     else if ( prev_oid_ptr ) {
  1086. if ( idxptr2->next_idx ) /* Use p_idx_ptr as a temp variable */
  1087.     prev_idx_ptr = idxptr2->next_idx;
  1088. else
  1089.     prev_idx_ptr = idxptr2->next_oid;
  1090. while ( prev_oid_ptr ) {
  1091.     prev_oid_ptr->next_oid = prev_idx_ptr;
  1092.     prev_oid_ptr = prev_oid_ptr->next_idx;
  1093. }
  1094.     }
  1095.     else {
  1096. if ( idxptr2->next_idx )
  1097.     snmp_index_head = idxptr2->next_idx;
  1098. else
  1099.     snmp_index_head = idxptr2->next_oid;
  1100.     }
  1101.     snmp_free_var( (struct variable_list *)idxptr2 );
  1102.     return SNMP_ERR_NOERROR;
  1103. }
  1104. void dump_registry( void )
  1105. {
  1106.     struct subtree *myptr, *myptr2;
  1107.     struct snmp_index *idxptr, *idxptr2;
  1108.     char start_oid[SPRINT_MAX_LEN];
  1109.     char end_oid[SPRINT_MAX_LEN];
  1110.     for( myptr = subtrees ; myptr != NULL; myptr = myptr->next) {
  1111. sprint_objid(start_oid, myptr->start, myptr->start_len);
  1112. sprint_objid(end_oid, myptr->end, myptr->end_len);
  1113. printf("%c %s - %s %cn",
  1114. ( myptr->variables ? ' ' : '(' ),
  1115.   start_oid, end_oid,
  1116. ( myptr->variables ? ' ' : ')' ));
  1117. for( myptr2 = myptr ; myptr2 != NULL; myptr2 = myptr2->children) {
  1118.     if ( myptr2->label && myptr2->label[0] )
  1119. printf("t%sn", myptr2->label);
  1120. }
  1121.     }
  1122.     if ( snmp_index_head )
  1123. printf("nIndex Allocations:n");
  1124.     for( idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid) {
  1125. sprint_objid(start_oid, idxptr->varbind.name, idxptr->varbind.name_length);
  1126. printf("%s indexes:n", start_oid);
  1127.         for( idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx) {
  1128.     switch( idxptr2->varbind.type ) {
  1129. case ASN_INTEGER:
  1130.     printf("    %c %ld %cn",
  1131. ( idxptr2->session ? ' ' : '(' ),
  1132.   *idxptr2->varbind.val.integer,
  1133. ( idxptr2->session ? ' ' : ')' ));
  1134.     break;
  1135. case ASN_OCTET_STR:
  1136.     printf("    %c %s %cn",
  1137. ( idxptr2->session ? ' ' : '(' ),
  1138.   idxptr2->varbind.val.string,
  1139. ( idxptr2->session ? ' ' : ')' ));
  1140.     break;
  1141. case ASN_OBJECT_ID:
  1142.     sprint_objid(end_oid, idxptr2->varbind.val.objid,
  1143. idxptr2->varbind.val_len/sizeof(oid));
  1144.     printf("    %c %s %cn",
  1145. ( idxptr2->session ? ' ' : '(' ),
  1146.   end_oid,
  1147. ( idxptr2->session ? ' ' : ')' ));
  1148.     break;
  1149. default:
  1150.     printf("unsupported type (%d)n",
  1151. idxptr2->varbind.type);
  1152.     }
  1153. }
  1154.     }
  1155. }
  1156. #ifdef TESTING
  1157. struct variable_list varbind;
  1158. struct snmp_session main_sess, *main_session=&main_sess;
  1159. void
  1160. test_string_register( int n, char *cp )
  1161. {
  1162.     varbind.name[4] = n;
  1163.     if (register_string_index(varbind.name, varbind.name_length, cp) == NULL)
  1164. printf("allocating %s failedn", cp);
  1165. }
  1166. void
  1167. test_int_register( int n, int val )
  1168. {
  1169.     varbind.name[4] = n;
  1170.     if (register_int_index( varbind.name, varbind.name_length, val ) == -1 )
  1171. printf("allocating %d/%d failedn", n, val);
  1172. }
  1173. void
  1174. test_oid_register( int n, int subid )
  1175. {
  1176.     struct variable_list *res;
  1177.     varbind.name[4] = n;
  1178.     if ( subid != -1 ) {
  1179.         varbind.val.objid[5] = subid;
  1180. res = register_oid_index(varbind.name, varbind.name_length,
  1181.     varbind.val.objid,
  1182.     varbind.val_len/sizeof(oid) );
  1183.     }
  1184.     else
  1185. res = register_oid_index(varbind.name, varbind.name_length, NULL, 0);
  1186.     if (res == NULL )
  1187. printf("allocating %d/%d failedn", n, subid);
  1188. }
  1189. void
  1190. main( int argc, char argv[] )
  1191. {
  1192.     oid name[] = { 1, 2, 3, 4, 0 };
  1193.     int i;
  1194.     
  1195.     memset( &varbind, 0, sizeof(struct variable_list));
  1196.     snmp_set_var_objid( &varbind, name, 5 );
  1197.     varbind.type = ASN_OCTET_STR;
  1198. /*
  1199.  * Test index structure linking:
  1200.  * a) sorted by OID
  1201.  */
  1202.     test_string_register( 20, "empty OID" );
  1203.     test_string_register( 10, "first OID" );
  1204.     test_string_register( 40, "last OID" );
  1205.     test_string_register( 30, "middle OID" );
  1206. /*
  1207.  * b) sorted by index value
  1208.  */
  1209.     test_string_register( 25, "eee: empty IDX" );
  1210.     test_string_register( 25, "aaa: first IDX" );
  1211.     test_string_register( 25, "zzz: last IDX" );
  1212.     test_string_register( 25, "mmm: middle IDX" );
  1213.     printf("This next one should fail....n");
  1214.     test_string_register( 25, "eee: empty IDX" ); /* duplicate */
  1215.     printf("donen");
  1216. /*
  1217.  * c) test initial index linking
  1218.  */
  1219.     test_string_register( 5, "eee: empty initial IDX" );
  1220.     test_string_register( 5, "aaa: replace initial IDX" );
  1221. /*
  1222.  * Did it all work?
  1223.  */
  1224.     dump_registry();
  1225.     unregister_index_by_session( main_session );
  1226. /*
  1227.  *  Now test index allocation
  1228.  * a) integer values
  1229.  */
  1230.     test_int_register( 110, -1 ); /* empty */
  1231.     test_int_register( 110, -1 ); /* append */
  1232.     test_int_register( 110, 10 ); /* append exact */
  1233.     printf("This next one should fail....n");
  1234.     test_int_register( 110, 10 ); /* exact duplicate */
  1235.     printf("donen");
  1236.     test_int_register( 110, -1 ); /* append */
  1237.     test_int_register( 110,  5 ); /* insert exact */
  1238. /*
  1239.  * b) string values
  1240.  */
  1241.     test_string_register( 120, NULL ); /* empty */
  1242.     test_string_register( 120, NULL ); /* append */
  1243.     test_string_register( 120, "aaaz" );
  1244.     test_string_register( 120, NULL ); /* minor rollover */
  1245.     test_string_register( 120, "zzzz" );
  1246.     test_string_register( 120, NULL ); /* major rollover */
  1247. /*
  1248.  * c) OID values
  1249.  */
  1250.     
  1251.     test_oid_register( 130, -1 ); /* empty */
  1252.     test_oid_register( 130, -1 ); /* append */
  1253.     varbind.val_len = varbind.name_length*sizeof(oid);
  1254.     memcpy( varbind.buf, varbind.name, varbind.val_len);
  1255.     varbind.val.objid = (oid*) varbind.buf;
  1256.     varbind.val_len += sizeof(oid);
  1257.     test_oid_register( 130, 255 ); /* append exact */
  1258.     test_oid_register( 130, -1 ); /* minor rollover */
  1259.     test_oid_register( 130, 100 ); /* insert exact */
  1260.     printf("This next one should fail....n");
  1261.     test_oid_register( 130, 100 ); /* exact duplicate */
  1262.     printf("donen");
  1263.     varbind.val.objid = (oid*)varbind.buf;
  1264.     for ( i=0; i<6; i++ )
  1265. varbind.val.objid[i]=255;
  1266.     varbind.val.objid[0]=1;
  1267.     test_oid_register( 130, 255 ); /* set up rollover  */
  1268.     test_oid_register( 130, -1 ); /* medium rollover */
  1269.     for ( i=0; i<6; i++ )
  1270. varbind.val.objid[i]=255;
  1271.     varbind.val.objid[0]=2;
  1272.     test_oid_register( 130, 255 ); /* set up rollover  */
  1273.     test_oid_register( 130, -1 ); /* major rollover */
  1274. /*
  1275.  * Did it all work?
  1276.  */
  1277.     dump_registry();
  1278. /*
  1279.  * Test the various "invalid" requests
  1280.  * (unsupported types, mis-matched types, etc)
  1281.  */
  1282.     printf("The rest of these should fail....n");
  1283.     test_oid_register( 110, -1 );
  1284.     test_oid_register( 110, 100 );
  1285.     test_oid_register( 120, -1 );
  1286.     test_oid_register( 120, 100 );
  1287.     test_string_register( 110, NULL );
  1288.     test_string_register( 110, "aaaa" );
  1289.     test_string_register( 130, NULL );
  1290.     test_string_register( 130, "aaaa" );
  1291.     test_int_register( 120, -1 );
  1292.     test_int_register( 120,  1 );
  1293.     test_int_register( 130, -1 );
  1294.     test_int_register( 130,  1 );
  1295.     printf("done - this dump should be the same as beforen");
  1296.     dump_registry();
  1297. }
  1298. #endif