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

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #if HAVE_STRING_H
  3. #include <string.h>
  4. #else
  5. #include <strings.h>
  6. #endif
  7. #include <net-snmp/net-snmp-includes.h>
  8. #include <net-snmp/agent/net-snmp-agent-includes.h>
  9. #include <net-snmp/agent/old_api.h>
  10. #include <net-snmp/agent/agent_callbacks.h>
  11. #if HAVE_DMALLOC_H
  12. #include <dmalloc.h>
  13. #endif
  14. #define MIB_CLIENTS_ARE_EVIL 1
  15. /*
  16.  * don't use these! 
  17.  */
  18. void            set_current_agent_session(netsnmp_agent_session *asp);
  19. netsnmp_agent_session *netsnmp_get_current_agent_session(void);
  20. /** @defgroup old_api old_api: Calls mib module code written in the old style of code.
  21.  *  @ingroup handler
  22.  *  This is a backwards compatilibity module that allows code written
  23.  *  in the old API to be run under the new handler based architecture.
  24.  *  Use it by calling netsnmp_register_old_api().
  25.  *  @{
  26.  */
  27. /** returns a old_api handler that should be the final calling
  28.  * handler.  Don't use this function.  Use the netsnmp_register_old_api()
  29.  * function instead.
  30.  */
  31. netsnmp_mib_handler *
  32. get_old_api_handler(void)
  33. {
  34.     return netsnmp_create_handler("old_api", netsnmp_old_api_helper);
  35. }
  36. /** Registers an old API set into the mib tree.  Functionally this
  37.  * mimics the old register_mib_context() function (and in fact the new
  38.  * register_mib_context() function merely calls this new old_api one).
  39.  */
  40. int
  41. netsnmp_register_old_api(const char *moduleName,
  42.                          struct variable *var,
  43.                          size_t varsize,
  44.                          size_t numvars,
  45.                          oid * mibloc,
  46.                          size_t mibloclen,
  47.                          int priority,
  48.                          int range_subid,
  49.                          oid range_ubound,
  50.                          netsnmp_session * ss,
  51.                          const char *context, int timeout, int flags)
  52. {
  53.     unsigned int    i;
  54.     /*
  55.      * register all subtree nodes 
  56.      */
  57.     for (i = 0; i < numvars; i++) {
  58.         struct variable *vp;
  59.         netsnmp_handler_registration *reginfo =
  60.             SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
  61.         memdup((void *) &vp,
  62.                (void *) (struct variable *) ((char *) var + varsize * i),
  63.                varsize);
  64.         reginfo->handler = get_old_api_handler();
  65.         reginfo->handlerName = strdup(moduleName);
  66.         reginfo->rootoid_len = (mibloclen + vp->namelen);
  67.         reginfo->rootoid =
  68.             (oid *) malloc(reginfo->rootoid_len * sizeof(oid));
  69.         memcpy(reginfo->rootoid, mibloc, mibloclen * sizeof(oid));
  70.         memcpy(reginfo->rootoid + mibloclen, vp->name, vp->namelen
  71.                * sizeof(oid));
  72.         reginfo->handler->myvoid = (void *) vp;
  73.         reginfo->priority = priority;
  74.         reginfo->range_subid = range_subid;
  75.         reginfo->range_ubound = range_ubound;
  76.         reginfo->timeout = timeout;
  77.         reginfo->contextName = (context) ? strdup(context) : NULL;
  78.         reginfo->modes = HANDLER_CAN_RWRITE;
  79.         /*
  80.          * register ourselves in the mib tree 
  81.          */
  82.         if (netsnmp_register_handler(reginfo) != MIB_REGISTERED_OK) {
  83.             /** netsnmp_handler_registration_free(reginfo); already freed */
  84.             SNMP_FREE(vp);
  85.         }
  86.     }
  87.     return SNMPERR_SUCCESS;
  88. }
  89. /** registers a row within a mib table */
  90. int
  91. netsnmp_register_mib_table_row(const char *moduleName,
  92.                                struct variable *var,
  93.                                size_t varsize,
  94.                                size_t numvars,
  95.                                oid * mibloc,
  96.                                size_t mibloclen,
  97.                                int priority,
  98.                                int var_subid,
  99.                                netsnmp_session * ss,
  100.                                const char *context, int timeout, int flags)
  101. {
  102.     unsigned int    i = 0, rc = 0;
  103.     oid             ubound = 0;
  104.     for (i = 0; i < numvars; i++) {
  105.         struct variable *vr =
  106.             (struct variable *) ((char *) var + (i * varsize));
  107.         netsnmp_handler_registration *r;
  108.         if ( var_subid > (int)mibloclen ) {
  109.             break;    /* doesn't make sense */
  110.         }
  111.         r = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
  112.         if (r == NULL) {
  113.             /*
  114.              * Unregister whatever we have registered so far, and
  115.              * return an error.  
  116.              */
  117.             rc = MIB_REGISTRATION_FAILED;
  118.             break;
  119.         }
  120.         memset(r, 0, sizeof(netsnmp_handler_registration));
  121.         r->handler = get_old_api_handler();
  122.         r->handlerName = strdup(moduleName);
  123.         if (r->handlerName == NULL) {
  124.             netsnmp_handler_registration_free(r);
  125.             break;
  126.         }
  127.         r->rootoid_len = mibloclen;
  128.         r->rootoid = (oid *) malloc(r->rootoid_len * sizeof(oid));
  129.         if (r->rootoid == NULL) {
  130.             netsnmp_handler_registration_free(r);
  131.             rc = MIB_REGISTRATION_FAILED;
  132.             break;
  133.         }
  134.         memcpy(r->rootoid, mibloc, mibloclen * sizeof(oid));
  135.         memcpy((u_char *) (r->rootoid + (var_subid - vr->namelen)), vr->name,
  136.                vr->namelen * sizeof(oid));
  137.         DEBUGMSGTL(("netsnmp_register_mib_table_row", "rootoid "));
  138.         DEBUGMSGOID(("netsnmp_register_mib_table_row", r->rootoid,
  139.                      r->rootoid_len));
  140.         DEBUGMSG(("netsnmp_register_mib_table_row", "(%d)n",
  141.                      (var_subid - vr->namelen)));
  142.         r->handler->myvoid = (void *) malloc(varsize);
  143.         if (r->handler->myvoid == NULL) {
  144.             netsnmp_handler_registration_free(r);
  145.             rc = MIB_REGISTRATION_FAILED;
  146.             break;
  147.         }
  148.         memcpy((char *) r->handler->myvoid, vr, varsize);
  149.         r->contextName = (context) ? strdup(context) : NULL;
  150.         if (context != NULL && r->contextName == NULL) {
  151.             netsnmp_handler_registration_free(r);
  152.             rc = MIB_REGISTRATION_FAILED;
  153.             break;
  154.         }
  155.         r->priority = priority;
  156.         r->range_subid = 0;     /* var_subid; */
  157.         r->range_ubound = 0;    /* range_ubound; */
  158.         r->timeout = timeout;
  159.         r->modes = HANDLER_CAN_RWRITE;
  160.         /*
  161.          * Register this column and row  
  162.          */
  163.         if ((rc =
  164.              netsnmp_register_handler_nocallback(r)) !=
  165.             MIB_REGISTERED_OK) {
  166.             DEBUGMSGTL(("netsnmp_register_mib_table_row",
  167.                         "register failed %dn", rc));
  168.             netsnmp_handler_registration_free(r);
  169.             break;
  170.         }
  171.         if (vr->namelen > 0) {
  172.             if (vr->name[vr->namelen - 1] > ubound) {
  173.                 ubound = vr->name[vr->namelen - 1];
  174.             }
  175.         }
  176.     }
  177.     if (rc == MIB_REGISTERED_OK) {
  178.         struct register_parameters reg_parms;
  179.         reg_parms.name = mibloc;
  180.         reg_parms.namelen = mibloclen;
  181.         reg_parms.priority = priority;
  182.         reg_parms.flags = (u_char) flags;
  183.         reg_parms.range_subid = var_subid;
  184.         reg_parms.range_ubound = ubound;
  185.         reg_parms.timeout = timeout;
  186.         reg_parms.contextName = context;
  187.         rc = snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
  188.                                  SNMPD_CALLBACK_REGISTER_OID, &reg_parms);
  189.     }
  190.     return rc;
  191. }
  192. /** implements the old_api handler */
  193. int
  194. netsnmp_old_api_helper(netsnmp_mib_handler *handler,
  195.                        netsnmp_handler_registration *reginfo,
  196.                        netsnmp_agent_request_info *reqinfo,
  197.                        netsnmp_request_info *requests)
  198. {
  199. #if MIB_CLIENTS_ARE_EVIL
  200.     oid             save[MAX_OID_LEN];
  201.     size_t          savelen = 0;
  202. #endif
  203.     struct variable compat_var, *cvp = &compat_var;
  204.     int             exact = 1;
  205.     int             status;
  206.     struct variable *vp;
  207.     WriteMethod    *write_method = NULL;
  208.     size_t          len;
  209.     u_char         *access = NULL;
  210.     netsnmp_old_api_cache *cacheptr;
  211.     netsnmp_agent_session *oldasp = NULL;
  212.     vp = (struct variable *) handler->myvoid;
  213.     /*
  214.      * create old variable structure with right information 
  215.      */
  216.     memcpy(cvp->name, reginfo->rootoid,
  217.            reginfo->rootoid_len * sizeof(oid));
  218.     cvp->namelen = reginfo->rootoid_len;
  219.     cvp->type = vp->type;
  220.     cvp->magic = vp->magic;
  221.     cvp->acl = vp->acl;
  222.     cvp->findVar = vp->findVar;
  223.     switch (reqinfo->mode) {
  224.     case MODE_GETNEXT:
  225.     case MODE_GETBULK:
  226.         exact = 0;
  227.     }
  228.     for (; requests; requests = requests->next) {
  229. #if MIB_CLIENTS_ARE_EVIL
  230.         savelen = requests->requestvb->name_length;
  231.         memcpy(save, requests->requestvb->name, savelen * sizeof(oid));
  232. #endif
  233.         switch (reqinfo->mode) {
  234.         case MODE_GET:
  235.         case MODE_GETNEXT:
  236.         case MODE_SET_RESERVE1:
  237.             /*
  238.              * Actually call the old mib-module function 
  239.              */
  240.             if (vp && vp->findVar)
  241.                 access = (*(vp->findVar)) (cvp, requests->requestvb->name,
  242.                                            &(requests->requestvb->
  243.                                              name_length), exact, &len,
  244.                                            &write_method);
  245.             else
  246.                 access = NULL;
  247. #ifdef WWW_FIX
  248.             if (IS_DELEGATED(cvp->type)) {
  249.                 add_method = (AddVarMethod *) statP;
  250.                 requests->delayed = 1;
  251.                 have_delegated = 1;
  252.                 continue;       /* WWW: This may not get to the right place */
  253.             }
  254. #endif
  255.             /*
  256.              * WWW: end range checking 
  257.              */
  258.             if (access) {
  259.                 /*
  260.                  * result returned 
  261.                  */
  262.                 if (reqinfo->mode != MODE_SET_RESERVE1)
  263.                     snmp_set_var_typed_value(requests->requestvb,
  264.                                              cvp->type, access, len);
  265.             } else {
  266.                 /*
  267.                  * no result returned 
  268.                  */
  269. #if MIB_CLIENTS_ARE_EVIL
  270.                 if (access == NULL) {
  271.                     if (netsnmp_oid_equals(requests->requestvb->name,
  272.                                          requests->requestvb->name_length,
  273.                                          save, savelen) != 0) {
  274.                         DEBUGMSGTL(("old_api", "evil_client: %sn",
  275.                                     reginfo->handlerName));
  276.                         memcpy(requests->requestvb->name, save,
  277.                                savelen * sizeof(oid));
  278.                         requests->requestvb->name_length = savelen;
  279.                     }
  280.                 }
  281. #endif
  282.             }
  283.             /*
  284.              * AAA: fall through for everything that is a set (see BBB) 
  285.              */
  286.             if (reqinfo->mode != MODE_SET_RESERVE1)
  287.                 break;
  288.             cacheptr = SNMP_MALLOC_TYPEDEF(netsnmp_old_api_cache);
  289.             if (!cacheptr)
  290.                 return netsnmp_set_request_error(reqinfo, requests,
  291.                                                  SNMP_ERR_RESOURCEUNAVAILABLE);
  292.             cacheptr->data = access;
  293.             cacheptr->write_method = write_method;
  294.             write_method = NULL;
  295.             netsnmp_request_add_list_data(requests,
  296.                                           netsnmp_create_data_list
  297.                                           (OLD_API_NAME, cacheptr, free));
  298.             /*
  299.              * BBB: fall through for everything that is a set (see AAA) 
  300.              */
  301.         default:
  302.             /*
  303.              * WWW: explicitly list the SET conditions 
  304.              */
  305.             /*
  306.              * (the rest of the) SET contions 
  307.              */
  308.             cacheptr =
  309.                 (netsnmp_old_api_cache *)
  310.                 netsnmp_request_get_list_data(requests, OLD_API_NAME);
  311.             if (cacheptr == NULL || cacheptr->write_method == NULL) {
  312.                 /*
  313.                  * WWW: try to set ourselves if possible? 
  314.                  */
  315.                 return netsnmp_set_request_error(reqinfo, requests,
  316.                                                  SNMP_ERR_NOTWRITABLE);
  317.             }
  318.             oldasp = netsnmp_get_current_agent_session();
  319.             set_current_agent_session(reqinfo->asp);
  320.             status =
  321.                 (*(cacheptr->write_method)) (reqinfo->mode,
  322.                                              requests->requestvb->val.
  323.                                              string,
  324.                                              requests->requestvb->type,
  325.                                              requests->requestvb->val_len,
  326.                                              cacheptr->data,
  327.                                              requests->requestvb->name,
  328.                                              requests->requestvb->
  329.                                              name_length);
  330.             set_current_agent_session(oldasp);
  331.             if (status != SNMP_ERR_NOERROR) {
  332.                 netsnmp_set_request_error(reqinfo, requests, status);
  333.             }
  334.             /*
  335.              * clean up is done by the automatic freeing of the
  336.              * cache stored in the request. 
  337.              */
  338.             break;
  339.         }
  340.     }
  341.     return SNMP_ERR_NOERROR;
  342. }
  343. /** @} */
  344. /*
  345.  * don't use this! 
  346.  */
  347. static netsnmp_agent_session *current_agent_session = NULL;
  348. netsnmp_agent_session *
  349. netsnmp_get_current_agent_session()
  350. {
  351.     return current_agent_session;
  352. }
  353. /*
  354.  * don't use this! 
  355.  */
  356. void
  357. set_current_agent_session(netsnmp_agent_session *asp)
  358. {
  359.     current_agent_session = asp;
  360. }