scalar_group.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:6k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #include <stdlib.h>
  3. #if HAVE_STRING_H
  4. #include <string.h>
  5. #else
  6. #include <strings.h>
  7. #endif
  8. #include <net-snmp/net-snmp-includes.h>
  9. #include <net-snmp/agent/net-snmp-agent-includes.h>
  10. #include <net-snmp/agent/scalar_group.h>
  11. #include <net-snmp/agent/scalar.h>
  12. #include <net-snmp/agent/serialize.h>
  13. #include <net-snmp/agent/read_only.h>
  14. #if HAVE_DMALLOC_H
  15. #include <dmalloc.h>
  16. #endif
  17. /** @defgroup scalar_group_group scalar_group: process groups of scalars.
  18.  *  @ingroup leaf
  19.  *  @{
  20.  */
  21. netsnmp_mib_handler *
  22. netsnmp_get_scalar_group_handler(oid first, oid last)
  23. {
  24.     netsnmp_mib_handler  *ret    = NULL;
  25.     netsnmp_scalar_group *sgroup = NULL;
  26.     ret = netsnmp_create_handler("scalar_group",
  27.                                   netsnmp_scalar_group_helper_handler);
  28.     if (ret) {
  29.         sgroup = SNMP_MALLOC_TYPEDEF(netsnmp_scalar_group);
  30.         if (NULL == sgroup) {
  31.             netsnmp_handler_free(ret);
  32.             ret = NULL;
  33.         }
  34.         else {
  35.     sgroup->lbound = first;
  36.     sgroup->ubound = last;
  37.             ret->myvoid = (void *)sgroup;
  38. }
  39.     }
  40.     return ret;
  41. }
  42. int
  43. netsnmp_register_scalar_group(netsnmp_handler_registration *reginfo,
  44.                               oid first, oid last)
  45. {
  46.     netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler());
  47.     netsnmp_inject_handler(reginfo, netsnmp_get_scalar_handler());
  48.     netsnmp_inject_handler(reginfo, netsnmp_get_scalar_group_handler(first, last));
  49.     return netsnmp_register_serialize(reginfo);
  50. }
  51. int
  52. netsnmp_scalar_group_helper_handler(netsnmp_mib_handler *handler,
  53.                                 netsnmp_handler_registration *reginfo,
  54.                                 netsnmp_agent_request_info *reqinfo,
  55.                                 netsnmp_request_info *requests)
  56. {
  57.     netsnmp_variable_list *var = requests->requestvb;
  58.     netsnmp_scalar_group *sgroup = (netsnmp_scalar_group *)handler->myvoid;
  59.     int             ret, cmp;
  60.     int             namelen;
  61.     oid             subid, root_tmp[MAX_OID_LEN], *root_save;
  62.     DEBUGMSGTL(("helper:scalar_group", "Got request:n"));
  63.     namelen = SNMP_MIN(requests->requestvb->name_length,
  64.                        reginfo->rootoid_len);
  65.     cmp = snmp_oid_compare(requests->requestvb->name, namelen,
  66.                            reginfo->rootoid, reginfo->rootoid_len);
  67.     DEBUGMSGTL(( "helper:scalar_group", "  cmp=%d, oid:", cmp));
  68.     DEBUGMSGOID(("helper:scalar_group", var->name, var->name_length));
  69.     DEBUGMSG((   "helper:scalar_group", "n"));
  70.     /*
  71.      * copy root oid to root_tmp, set instance to 0. (subid set later on)
  72.      * save rootoid, since we'll replace it before calling next handler,
  73.      * and need to restore it afterwards.
  74.      */
  75.     memcpy(root_tmp, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid));
  76.     root_tmp[reginfo->rootoid_len + 1] = 0;
  77.     root_save = reginfo->rootoid;
  78.     ret = SNMP_ERR_NOCREATION;
  79.     switch (reqinfo->mode) {
  80.     /*
  81.      * The handling of "exact" requests is basically the same.
  82.      * The only difference between GET and SET requests is the
  83.      *     error/exception to return on failure.
  84.      */
  85.     case MODE_GET:
  86.         ret = SNMP_NOSUCHOBJECT;
  87.         /* Fallthrough */
  88.     case MODE_SET_RESERVE1:
  89.     case MODE_SET_RESERVE2:
  90.     case MODE_SET_ACTION:
  91.     case MODE_SET_COMMIT:
  92.     case MODE_SET_UNDO:
  93.     case MODE_SET_FREE:
  94.         if (cmp != 0 ||
  95.             requests->requestvb->name_length <= reginfo->rootoid_len) {
  96.     /*
  97.      * Common prefix doesn't match, or only *just* matches 
  98.      *  the registered root (so can't possibly match a scalar)
  99.      */
  100.             netsnmp_set_request_error(reqinfo, requests, ret);
  101.             return SNMP_ERR_NOERROR;
  102.         } else {
  103.     /*
  104.      * Otherwise,
  105.      *     extract the object subidentifier from the request, 
  106.      *     check this is (probably) valid, and then fudge the
  107.      *     registered 'rootoid' to match, before passing the
  108.      *     request off to the next handler ('scalar').
  109.      *
  110.      * Note that we don't bother checking instance subidentifiers
  111.      *     here.  That's left to the scalar helper.
  112.      */
  113.             subid = requests->requestvb->name[reginfo->rootoid_len];
  114.     if (subid < sgroup->lbound ||
  115.         subid > sgroup->ubound) {
  116.                 netsnmp_set_request_error(reqinfo, requests, ret);
  117.                 return SNMP_ERR_NOERROR;
  118.     }
  119.             root_tmp[reginfo->rootoid_len++] = subid;
  120.             reginfo->rootoid = root_tmp;
  121.             ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
  122.                                             requests);
  123.             reginfo->rootoid = root_save;
  124.             reginfo->rootoid_len--;
  125.             return ret;
  126.         }
  127.         break;
  128.     case MODE_GETNEXT:
  129. /*
  130.  * If we're being asked for something before (or exactly matches)
  131.  *     the registered root OID, then start with the first object.
  132.  * If we're being asked for something that exactly matches an object
  133.  *    OID, then that's what we pass down.
  134.  * Otherwise, we pass down the OID of the *next* object....
  135.  */
  136.         if (cmp < 0 ||
  137.             requests->requestvb->name_length <= reginfo->rootoid_len) {
  138.             subid  = sgroup->lbound;
  139.         } else if (requests->requestvb->name_length == reginfo->rootoid_len+1)
  140.             subid = requests->requestvb->name[reginfo->rootoid_len];
  141.         else
  142.             subid = requests->requestvb->name[reginfo->rootoid_len]+1;
  143. /*
  144.  * ... always assuming this is (potentially) valid, of course.
  145.  */
  146. if (subid > sgroup->ubound)
  147.             return SNMP_ERR_NOERROR;
  148.         
  149.         root_tmp[reginfo->rootoid_len++] = subid;
  150.         reginfo->rootoid = root_tmp;
  151.         ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
  152.                                             requests);
  153.         /*
  154.          * If we didn't get an answer (due to holes in the group)
  155.  *   set things up to retry again.
  156.          */
  157.         if (!requests->delegated &&
  158.             (requests->requestvb->type == ASN_NULL ||
  159.              requests->requestvb->type == SNMP_NOSUCHOBJECT ||
  160.              requests->requestvb->type == SNMP_NOSUCHINSTANCE)) {
  161.             snmp_set_var_objid(requests->requestvb,
  162.                                reginfo->rootoid, reginfo->rootoid_len);
  163.             requests->requestvb->name[reginfo->rootoid_len-1] = ++subid;
  164.             requests->requestvb->type = ASN_PRIV_RETRY;
  165.         }
  166.         reginfo->rootoid = root_save;
  167.         reginfo->rootoid_len--;
  168.         return ret;
  169.     }
  170.     /*
  171.      * got here only if illegal mode found 
  172.      */
  173.     return SNMP_ERR_GENERR;
  174. }
  175. /*
  176.  * @} 
  177.  */