Logo
Home page Net-SNMP

Archive Search:

Require all words?

Site Search:
Google
Main Page | Modules | Data Structures | File List | Data Fields | Related Pages | Examples

agent_handler.c

00001 /* Portions of this file are subject to the following copyright(s).  See
00002  * the Net-SNMP's COPYING file for more details and other copyrights
00003  * that may apply:
00004  */
00005 /*
00006  * Portions of this file are copyrighted by:
00007  * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
00008  * Use is subject to license terms specified in the COPYING file
00009  * distributed with the Net-SNMP package.
00010  */
00011 #include <net-snmp/net-snmp-config.h>
00012 
00013 #include <sys/types.h>
00014 
00015 #if HAVE_STRING_H
00016 #include <string.h>
00017 #endif
00018 
00019 #include <net-snmp/net-snmp-includes.h>
00020 #include <net-snmp/agent/net-snmp-agent-includes.h>
00021 
00022 #include <net-snmp/agent/bulk_to_next.h>
00023 
00024 
00025 static netsnmp_mib_handler *_clone_handler(netsnmp_mib_handler *it);
00026 
00027 /***********************************************************************/
00028 /*
00029  * New Handler based API 
00030  */
00031 /***********************************************************************/
00104 netsnmp_mib_handler *
00105 netsnmp_create_handler(const char *name,
00106                        Netsnmp_Node_Handler * handler_access_method)
00107 {
00108     netsnmp_mib_handler *ret = SNMP_MALLOC_TYPEDEF(netsnmp_mib_handler);
00109     if (ret) {
00110         ret->access_method = handler_access_method;
00111         if (NULL != name) {
00112             ret->handler_name = strdup(name);
00113             if (NULL == ret->handler_name)
00114                 SNMP_FREE(ret);
00115         }
00116     }
00117     return ret;
00118 }
00119 
00162 netsnmp_handler_registration *
00163 netsnmp_handler_registration_create(const char *name,
00164                                     netsnmp_mib_handler *handler,
00165                                     oid * reg_oid, size_t reg_oid_len,
00166                                     int modes)
00167 {
00168     netsnmp_handler_registration *the_reg;
00169     the_reg = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
00170     if (!the_reg)
00171         return NULL;
00172 
00173     if (modes)
00174         the_reg->modes = modes;
00175     else
00176         the_reg->modes = HANDLER_CAN_DEFAULT;
00177 
00178     the_reg->handler = handler;
00179     the_reg->priority = DEFAULT_MIB_PRIORITY;
00180     if (name)
00181         the_reg->handlerName = strdup(name);
00182     memdup((u_char **) & the_reg->rootoid, (const u_char *) reg_oid,
00183            reg_oid_len * sizeof(oid));
00184     the_reg->rootoid_len = reg_oid_len;
00185     return the_reg;
00186 }
00187 
00188 netsnmp_handler_registration *
00189 netsnmp_create_handler_registration(const char *name,
00190                                     Netsnmp_Node_Handler *
00191                                     handler_access_method, oid * reg_oid,
00192                                     size_t reg_oid_len, int modes)
00193 {
00194     return
00195         netsnmp_handler_registration_create(name,
00196                                             netsnmp_create_handler(name, handler_access_method),
00197                                             reg_oid, reg_oid_len, modes);
00198 }
00199 
00201 int
00202 netsnmp_register_handler(netsnmp_handler_registration *reginfo)
00203 {
00204     netsnmp_mib_handler *handler;
00205     if (reginfo == NULL) {
00206         snmp_log(LOG_ERR, "netsnmp_register_handler() called illegally\n");
00207         netsnmp_assert(reginfo != NULL);
00208         return SNMP_ERR_GENERR;
00209     }
00210 
00211     DEBUGIF("handler::register") {
00212         DEBUGMSGTL(("handler::register", "Registering %s (", reginfo->handlerName));
00213         for (handler = reginfo->handler; handler; handler = handler->next) {
00214             DEBUGMSG(("handler::register", "::%s", handler->handler_name));
00215         }
00216 
00217         DEBUGMSG(("handler::register", ") at "));
00218         if (reginfo->rootoid && reginfo->range_subid) {
00219             DEBUGMSGOIDRANGE(("handler::register", reginfo->rootoid,
00220                               reginfo->rootoid_len, reginfo->range_subid,
00221                               reginfo->range_ubound));
00222         } else if (reginfo->rootoid) {
00223             DEBUGMSGOID(("handler::register", reginfo->rootoid,
00224                          reginfo->rootoid_len));
00225         } else {
00226             DEBUGMSG(("handler::register", "[null]"));
00227         }
00228         DEBUGMSG(("handler::register", "\n"));
00229     }
00230 
00231     /*
00232      * don't let them register for absolutely nothing.  Probably a mistake 
00233      */
00234     if (0 == reginfo->modes) {
00235         reginfo->modes = HANDLER_CAN_DEFAULT;
00236         snmp_log(LOG_WARNING, "no registration modes specified for %s. "
00237                  "Defaulting to 0x%x\n", reginfo->handlerName, reginfo->modes);
00238     }
00239 
00240     /*
00241      * for handlers that can't GETBULK, force a conversion handler on them 
00242      */
00243     if (!(reginfo->modes & HANDLER_CAN_GETBULK)) {
00244         netsnmp_inject_handler(reginfo,
00245                                netsnmp_get_bulk_to_next_handler());
00246     }
00247 
00248     return netsnmp_register_mib(reginfo->handlerName,
00249                                 NULL, 0, 0,
00250                                 reginfo->rootoid, reginfo->rootoid_len,
00251                                 reginfo->priority,
00252                                 reginfo->range_subid,
00253                                 reginfo->range_ubound, NULL,
00254                                 reginfo->contextName, reginfo->timeout, 0,
00255                                 reginfo, 1);
00256 }
00257 
00259 int
00260 netsnmp_unregister_handler(netsnmp_handler_registration *reginfo)
00261 {
00262     return unregister_mib_context(reginfo->rootoid, reginfo->rootoid_len,
00263                                   reginfo->priority,
00264                                   reginfo->range_subid, reginfo->range_ubound,
00265                                   reginfo->contextName);
00266 }
00267 
00269 int
00270 netsnmp_register_handler_nocallback(netsnmp_handler_registration *reginfo)
00271 {
00272     netsnmp_mib_handler *handler;
00273     if (reginfo == NULL) {
00274         snmp_log(LOG_ERR, "netsnmp_register_handler_nocallback() called illegally\n");
00275         netsnmp_assert(reginfo != NULL);
00276         return SNMP_ERR_GENERR;
00277     }
00278     DEBUGIF("handler::register") {
00279         DEBUGMSGTL(("handler::register",
00280                     "Registering (with no callback) "));
00281         for (handler = reginfo->handler; handler; handler = handler->next) {
00282             DEBUGMSG(("handler::register", "::%s", handler->handler_name));
00283         }
00284 
00285         DEBUGMSG(("handler::register", " at "));
00286         if (reginfo->rootoid && reginfo->range_subid) {
00287             DEBUGMSGOIDRANGE(("handler::register", reginfo->rootoid,
00288                               reginfo->rootoid_len, reginfo->range_subid,
00289                               reginfo->range_ubound));
00290         } else if (reginfo->rootoid) {
00291             DEBUGMSGOID(("handler::register", reginfo->rootoid,
00292                          reginfo->rootoid_len));
00293         } else {
00294             DEBUGMSG(("handler::register", "[null]"));
00295         }
00296         DEBUGMSG(("handler::register", "\n"));
00297     }
00298 
00299     /*
00300      * don't let them register for absolutely nothing.  Probably a mistake 
00301      */
00302     if (0 == reginfo->modes) {
00303         reginfo->modes = HANDLER_CAN_DEFAULT;
00304     }
00305 
00306     return netsnmp_register_mib(reginfo->handler->handler_name,
00307                                 NULL, 0, 0,
00308                                 reginfo->rootoid, reginfo->rootoid_len,
00309                                 reginfo->priority,
00310                                 reginfo->range_subid,
00311                                 reginfo->range_ubound, NULL,
00312                                 reginfo->contextName, reginfo->timeout, 0,
00313                                 reginfo, 0);
00314 }
00315 
00321 int
00322 netsnmp_inject_handler_before(netsnmp_handler_registration *reginfo,
00323                               netsnmp_mib_handler *handler,
00324                               const char *before_what)
00325 {
00326     netsnmp_mib_handler *handler2 = handler;
00327 
00328     if (handler == NULL || reginfo == NULL) {
00329         snmp_log(LOG_ERR, "netsnmp_inject_handler() called illegally\n");
00330         netsnmp_assert(reginfo != NULL);
00331         netsnmp_assert(handler != NULL);
00332         return SNMP_ERR_GENERR;
00333     }
00334     while (handler2->next) {
00335         handler2 = handler2->next;  /* Find the end of a handler sub-chain */
00336     }
00337     if (reginfo->handler == NULL) {
00338         DEBUGMSGTL(("handler:inject", "injecting %s\n", handler->handler_name));
00339     }
00340     else {
00341         DEBUGMSGTL(("handler:inject", "injecting %s before %s\n",
00342                     handler->handler_name, reginfo->handler->handler_name));
00343     }
00344     if (before_what) {
00345         netsnmp_mib_handler *nexth, *prevh = NULL;
00346         if (reginfo->handler == NULL) {
00347             snmp_log(LOG_ERR, "no handler to inject before\n");
00348             return SNMP_ERR_GENERR;
00349         }
00350         for(nexth = reginfo->handler; nexth;
00351             prevh = nexth, nexth = nexth->next) {
00352             if (strcmp(nexth->handler_name, before_what) == 0)
00353                 break;
00354         }
00355         if (!nexth)
00356             return SNMP_ERR_GENERR;
00357         if (prevh) {
00358             /* after prevh and before nexth */
00359             prevh->next = handler;
00360             handler2->next = nexth;
00361             handler->prev = prevh;
00362             nexth->prev = handler2;
00363             return SNMPERR_SUCCESS;
00364         }
00365         /* else we're first, which is what we do next anyway so fall through */
00366     }
00367     handler2->next = reginfo->handler;
00368     if (reginfo->handler)
00369         reginfo->handler->prev = handler2;
00370     reginfo->handler = handler;
00371     return SNMPERR_SUCCESS;
00372 }
00373 
00378 int
00379 netsnmp_inject_handler(netsnmp_handler_registration *reginfo,
00380                        netsnmp_mib_handler *handler)
00381 {
00382     return netsnmp_inject_handler_before(reginfo, handler, NULL);
00383 }
00384 
00386 NETSNMP_INLINE int
00387 netsnmp_call_handler(netsnmp_mib_handler *next_handler,
00388                      netsnmp_handler_registration *reginfo,
00389                      netsnmp_agent_request_info *reqinfo,
00390                      netsnmp_request_info *requests)
00391 {
00392     Netsnmp_Node_Handler *nh;
00393     int             ret;
00394 
00395     if (next_handler == NULL || reginfo == NULL || reqinfo == NULL ||
00396         requests == NULL) {
00397         snmp_log(LOG_ERR, "netsnmp_call_handler() called illegally\n");
00398         netsnmp_assert(next_handler != NULL);
00399         netsnmp_assert(reqinfo != NULL);
00400         netsnmp_assert(reginfo != NULL);
00401         netsnmp_assert(requests != NULL);
00402         return SNMP_ERR_GENERR;
00403     }
00404 
00405     do {
00406     nh = next_handler->access_method;
00407     if (!nh) {
00408         if (next_handler->next) {
00409             snmp_log(LOG_ERR, "no access method specified in handler %s.",
00410                      next_handler->handler_name);
00411             return SNMP_ERR_GENERR;
00412         }
00413         /*
00414          * The final handler registration in the chain may well not need
00415          * to include a handler routine, if the processing of this object
00416          * is handled completely by the agent toolkit helpers.
00417          */
00418         return SNMP_ERR_NOERROR;
00419     }
00420 
00421     DEBUGMSGTL(("handler:calling", "calling handler %s for mode %s\n",
00422                 next_handler->handler_name,
00423                 se_find_label_in_slist("agent_mode", reqinfo->mode)));
00424 
00425     /*
00426      * XXX: define acceptable return statuses 
00427      */
00428     ret = (*nh) (next_handler, reginfo, reqinfo, requests);
00429 
00430     DEBUGMSGTL(("handler:returned", "handler %s returned %d\n",
00431                 next_handler->handler_name, ret));
00432 
00433     if (! (next_handler->flags & MIB_HANDLER_AUTO_NEXT))
00434         break;
00435 
00436     /*
00437      * did handler signal that it didn't want auto next this time around?
00438      */
00439     if(next_handler->flags & MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE) {
00440         next_handler->flags &= ~MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
00441         break;
00442     }
00443 
00444     next_handler = next_handler->next;
00445 
00446     } while(next_handler);
00447 
00448     return ret;
00449 }
00450 
00454 int
00455 netsnmp_call_handlers(netsnmp_handler_registration *reginfo,
00456                       netsnmp_agent_request_info *reqinfo,
00457                       netsnmp_request_info *requests)
00458 {
00459     netsnmp_request_info *request;
00460     int             status;
00461 
00462     if (reginfo == NULL || reqinfo == NULL || requests == NULL) {
00463         snmp_log(LOG_ERR, "netsnmp_call_handlers() called illegally\n");
00464         netsnmp_assert(reqinfo != NULL);
00465         netsnmp_assert(reginfo != NULL);
00466         netsnmp_assert(requests != NULL);
00467         return SNMP_ERR_GENERR;
00468     }
00469 
00470     if (reginfo->handler == NULL) {
00471         snmp_log(LOG_ERR, "no handler specified.");
00472         return SNMP_ERR_GENERR;
00473     }
00474 
00475     switch (reqinfo->mode) {
00476     case MODE_GETBULK:
00477     case MODE_GET:
00478     case MODE_GETNEXT:
00479         if (!(reginfo->modes & HANDLER_CAN_GETANDGETNEXT))
00480             return SNMP_ERR_NOERROR;    /* legal */
00481         break;
00482 
00483     case MODE_SET_RESERVE1:
00484     case MODE_SET_RESERVE2:
00485     case MODE_SET_ACTION:
00486     case MODE_SET_COMMIT:
00487     case MODE_SET_FREE:
00488     case MODE_SET_UNDO:
00489         if (!(reginfo->modes & HANDLER_CAN_SET)) {
00490             for (; requests; requests = requests->next) {
00491                 netsnmp_set_request_error(reqinfo, requests,
00492                                           SNMP_ERR_NOTWRITABLE);
00493             }
00494             return SNMP_ERR_NOERROR;
00495         }
00496         break;
00497 
00498     default:
00499         snmp_log(LOG_ERR, "unknown mode in netsnmp_call_handlers! bug!\n");
00500         return SNMP_ERR_GENERR;
00501     }
00502     DEBUGMSGTL(("handler:calling", "main handler %s\n",
00503                 reginfo->handler->handler_name));
00504 
00505     for (request = requests ; request; request = request->next) {
00506         request->processed = 0;
00507     }
00508 
00509     status = netsnmp_call_handler(reginfo->handler, reginfo, reqinfo, requests);
00510 
00511     return status;
00512 }
00513 
00516 NETSNMP_INLINE int
00517 netsnmp_call_next_handler(netsnmp_mib_handler *current,
00518                           netsnmp_handler_registration *reginfo,
00519                           netsnmp_agent_request_info *reqinfo,
00520                           netsnmp_request_info *requests)
00521 {
00522 
00523     if (current == NULL || reginfo == NULL || reqinfo == NULL ||
00524         requests == NULL) {
00525         snmp_log(LOG_ERR, "netsnmp_call_next_handler() called illegally\n");
00526         netsnmp_assert(current != NULL);
00527         netsnmp_assert(reginfo != NULL);
00528         netsnmp_assert(reqinfo != NULL);
00529         netsnmp_assert(requests != NULL);
00530         return SNMP_ERR_GENERR;
00531     }
00532 
00533     return netsnmp_call_handler(current->next, reginfo, reqinfo, requests);
00534 }
00535 
00538 NETSNMP_INLINE int
00539 netsnmp_call_next_handler_one_request(netsnmp_mib_handler *current,
00540                                       netsnmp_handler_registration *reginfo,
00541                                       netsnmp_agent_request_info *reqinfo,
00542                                       netsnmp_request_info *requests)
00543 {
00544     netsnmp_request_info *request;
00545     int ret;
00546     
00547     if (!requests) {
00548         snmp_log(LOG_ERR, "netsnmp_call_next_handler_ONE_REQUEST() called illegally\n");
00549         netsnmp_assert(requests != NULL);
00550         return SNMP_ERR_GENERR;
00551     }
00552 
00553     request = requests->next;
00554     requests->next = NULL;
00555     ret = netsnmp_call_handler(current->next, reginfo, reqinfo, requests);
00556     requests->next = request;
00557     return ret;
00558 }
00559 
00561 void
00562 netsnmp_handler_free(netsnmp_mib_handler *handler)
00563 {
00564     if (handler != NULL) {
00565         if (handler->next != NULL) {
00567             netsnmp_assert(handler != handler->next); /* bugs caught: 1 */
00568             netsnmp_handler_free(handler->next);
00569             handler->next = NULL;
00570         }
00575         SNMP_FREE(handler->handler_name);
00576         SNMP_FREE(handler);
00577     }
00578 }
00579 
00583 netsnmp_mib_handler *
00584 netsnmp_handler_dup(netsnmp_mib_handler *handler)
00585 {
00586     netsnmp_mib_handler *h = NULL;
00587 
00588     if (handler == NULL) {
00589         return NULL;
00590     }
00591 
00592     h = _clone_handler(handler);
00593 
00594     if (h != NULL) {
00595         h->myvoid = handler->myvoid;
00596 
00597         if (handler->next != NULL) {
00598             h->next = netsnmp_handler_dup(handler->next);
00599             if (h->next == NULL) {
00600                 netsnmp_handler_free(h);
00601                 return NULL;
00602             }
00603             h->next->prev = h;
00604         }
00605         h->prev = NULL;
00606         return h;
00607     }
00608     return NULL;
00609 }
00610 
00612 void
00613 netsnmp_handler_registration_free(netsnmp_handler_registration *reginfo)
00614 {
00615     if (reginfo != NULL) {
00616         netsnmp_handler_free(reginfo->handler);
00617         SNMP_FREE(reginfo->handlerName);
00618         SNMP_FREE(reginfo->contextName);
00619         SNMP_FREE(reginfo->rootoid);
00620         SNMP_FREE(reginfo);
00621     }
00622 }
00623 
00625 netsnmp_handler_registration *
00626 netsnmp_handler_registration_dup(netsnmp_handler_registration *reginfo)
00627 {
00628     netsnmp_handler_registration *r = NULL;
00629 
00630     if (reginfo == NULL) {
00631         return NULL;
00632     }
00633 
00634 
00635     r = (netsnmp_handler_registration *) calloc(1,
00636                                                 sizeof
00637                                                 (netsnmp_handler_registration));
00638 
00639     if (r != NULL) {
00640         r->modes = reginfo->modes;
00641         r->priority = reginfo->priority;
00642         r->range_subid = reginfo->range_subid;
00643         r->timeout = reginfo->timeout;
00644         r->range_ubound = reginfo->range_ubound;
00645         r->rootoid_len = reginfo->rootoid_len;
00646 
00647         if (reginfo->handlerName != NULL) {
00648             r->handlerName = strdup(reginfo->handlerName);
00649             if (r->handlerName == NULL) {
00650                 netsnmp_handler_registration_free(r);
00651                 return NULL;
00652             }
00653         }
00654 
00655         if (reginfo->contextName != NULL) {
00656             r->contextName = strdup(reginfo->contextName);
00657             if (r->contextName == NULL) {
00658                 netsnmp_handler_registration_free(r);
00659                 return NULL;
00660             }
00661         }
00662 
00663         if (reginfo->rootoid != NULL) {
00664             memdup((u_char **) & (r->rootoid),
00665                    (const u_char *) reginfo->rootoid,
00666                    reginfo->rootoid_len * sizeof(oid));
00667             if (r->rootoid == NULL) {
00668                 netsnmp_handler_registration_free(r);
00669                 return NULL;
00670             }
00671         }
00672 
00673         r->handler = netsnmp_handler_dup(reginfo->handler);
00674         if (r->handler == NULL) {
00675             netsnmp_handler_registration_free(r);
00676             return NULL;
00677         }
00678         return r;
00679     }
00680 
00681     return NULL;
00682 }
00683 
00687 NETSNMP_INLINE netsnmp_delegated_cache *
00688 netsnmp_create_delegated_cache(netsnmp_mib_handler *handler,
00689                                netsnmp_handler_registration *reginfo,
00690                                netsnmp_agent_request_info *reqinfo,
00691                                netsnmp_request_info *requests,
00692                                void *localinfo)
00693 {
00694     netsnmp_delegated_cache *ret;
00695 
00696     ret = SNMP_MALLOC_TYPEDEF(netsnmp_delegated_cache);
00697     if (ret) {
00698         ret->transaction_id = reqinfo->asp->pdu->transid;
00699         ret->handler = handler;
00700         ret->reginfo = reginfo;
00701         ret->reqinfo = reqinfo;
00702         ret->requests = requests;
00703         ret->localinfo = localinfo;
00704     }
00705     return ret;
00706 }
00707 
00711 NETSNMP_INLINE netsnmp_delegated_cache *
00712 netsnmp_handler_check_cache(netsnmp_delegated_cache *dcache)
00713 {
00714     if (!dcache)
00715         return dcache;
00716 
00717     if (netsnmp_check_transaction_id(dcache->transaction_id) ==
00718         SNMPERR_SUCCESS)
00719         return dcache;
00720 
00721     return NULL;
00722 }
00723 
00725 NETSNMP_INLINE void
00726 netsnmp_free_delegated_cache(netsnmp_delegated_cache *dcache)
00727 {
00728     /*
00729      * right now, no extra data is there that needs to be freed 
00730      */
00731     if (dcache)
00732         SNMP_FREE(dcache);
00733 
00734     return;
00735 }
00736 
00737 
00739 void
00740 netsnmp_handler_mark_requests_as_delegated(netsnmp_request_info *requests,
00741                                            int isdelegated)
00742 {
00743     while (requests) {
00744         requests->delegated = isdelegated;
00745         requests = requests->next;
00746     }
00747 }
00748 
00759 NETSNMP_INLINE void
00760 netsnmp_request_add_list_data(netsnmp_request_info *request,
00761                               netsnmp_data_list *node)
00762 {
00763     if (request) {
00764         if (request->parent_data)
00765             netsnmp_add_list_data(&request->parent_data, node);
00766         else
00767             request->parent_data = node;
00768     }
00769 }
00770 
00780 NETSNMP_INLINE int
00781 netsnmp_request_remove_list_data(netsnmp_request_info *request,
00782                                  const char *name)
00783 {
00784     if ((NULL == request) || (NULL ==request->parent_data))
00785         return 1;
00786 
00787     return netsnmp_remove_list_node(&request->parent_data, name);
00788 }
00789 
00801 NETSNMP_INLINE void    *
00802 netsnmp_request_get_list_data(netsnmp_request_info *request,
00803                               const char *name)
00804 {
00805     if (request)
00806         return netsnmp_get_list_data(request->parent_data, name);
00807     return NULL;
00808 }
00809 
00811 NETSNMP_INLINE void
00812 netsnmp_free_request_data_set(netsnmp_request_info *request)
00813 {
00814     if (request)
00815         netsnmp_free_list_data(request->parent_data);
00816 }
00817 
00819 NETSNMP_INLINE void
00820 netsnmp_free_request_data_sets(netsnmp_request_info *request)
00821 {
00822     if (request && request->parent_data) {
00823         netsnmp_free_all_list_data(request->parent_data);
00824         request->parent_data = NULL;
00825     }
00826 }
00827 
00829 netsnmp_mib_handler *
00830 netsnmp_find_handler_by_name(netsnmp_handler_registration *reginfo,
00831                              const char *name)
00832 {
00833     netsnmp_mib_handler *it;
00834     for (it = reginfo->handler; it; it = it->next) {
00835         if (strcmp(it->handler_name, name) == 0) {
00836             return it;
00837         }
00838     }
00839     return NULL;
00840 }
00841 
00846 void           *
00847 netsnmp_find_handler_data_by_name(netsnmp_handler_registration *reginfo,
00848                                   const char *name)
00849 {
00850     netsnmp_mib_handler *it = netsnmp_find_handler_by_name(reginfo, name);
00851     if (it)
00852         return it->myvoid;
00853     return NULL;
00854 }
00855 
00859 static netsnmp_mib_handler *
00860 _clone_handler(netsnmp_mib_handler *it)
00861 {
00862     netsnmp_mib_handler *dup;
00863 
00864     if(NULL == it)
00865         return NULL;
00866 
00867     dup = netsnmp_create_handler(it->handler_name, it->access_method);
00868     if(NULL != dup)
00869         dup->flags = it->flags;
00870 
00871     return dup;
00872 }
00873 
00874 static netsnmp_data_list *handler_reg = NULL;
00875 
00876 void
00877 handler_free_callback(void *free)
00878 {
00879     netsnmp_handler_free((netsnmp_mib_handler *)free);
00880 }
00881 
00884 void
00885 netsnmp_register_handler_by_name(const char *name,
00886                                  netsnmp_mib_handler *handler)
00887 {
00888     netsnmp_add_list_data(&handler_reg,
00889                           netsnmp_create_data_list(name, (void *) handler,
00890                                                    handler_free_callback));
00891     DEBUGMSGTL(("handler_registry", "registering helper %s\n", name));
00892 }
00893 
00896 void
00897 netsnmp_clear_handler_list(void)
00898 {
00899     DEBUGMSGTL(("agent_handler", "netsnmp_clear_handler_list() called\n"));
00900     netsnmp_free_all_list_data(handler_reg);
00901     handler_reg = NULL;
00902 }
00903 
00908 void
00909 netsnmp_inject_handler_into_subtree(netsnmp_subtree *tp, const char *name,
00910                                     netsnmp_mib_handler *handler,
00911                                     const char *before_what)
00912 {
00913     netsnmp_subtree *tptr;
00914     netsnmp_mib_handler *mh;
00915 
00916     for (tptr = tp; tptr != NULL; tptr = tptr->next) {
00917         /*  if (tptr->children) { 
00918               netsnmp_inject_handler_into_subtree(tptr->children,name,handler);
00919             }   */
00920         if (strcmp(tptr->label_a, name) == 0) {
00921             DEBUGMSGTL(("injectHandler", "injecting handler %s into %s\n",
00922                         handler->handler_name, tptr->label_a));
00923             netsnmp_inject_handler_before(tptr->reginfo, _clone_handler(handler),
00924                                           before_what);
00925         } else if (tptr->reginfo != NULL &&
00926                    tptr->reginfo->handlerName != NULL &&
00927                    strcmp(tptr->reginfo->handlerName, name) == 0) {
00928             DEBUGMSGTL(("injectHandler", "injecting handler into %s/%s\n",
00929                         tptr->label_a, tptr->reginfo->handlerName));
00930             netsnmp_inject_handler_before(tptr->reginfo, _clone_handler(handler),
00931                                           before_what);
00932         } else {
00933             for (mh = tptr->reginfo->handler; mh != NULL; mh = mh->next) {
00934                 if (mh->handler_name && strcmp(mh->handler_name, name) == 0) {
00935                     DEBUGMSGTL(("injectHandler", "injecting handler into %s\n",
00936                                 tptr->label_a));
00937                     netsnmp_inject_handler_before(tptr->reginfo,
00938                                                   _clone_handler(handler),
00939                                                   before_what);
00940                     break;
00941                 } else {
00942                     DEBUGMSGTL(("yyyinjectHandler",
00943                                 "not injecting handler into %s\n",
00944                                 mh->handler_name));
00945                 }
00946             }
00947         }
00948     }
00949 }
00950 
00951 static int      doneit = 0;
00955 void
00956 parse_injectHandler_conf(const char *token, char *cptr)
00957 {
00958     char            handler_to_insert[256], reg_name[256];
00959     subtree_context_cache *stc;
00960     netsnmp_mib_handler *handler;
00961 
00962     /*
00963      * XXXWWW: ensure instead that handler isn't inserted twice 
00964      */
00965     if (doneit)                 /* we only do this once without restart the agent */
00966         return;
00967 
00968     cptr = copy_nword(cptr, handler_to_insert, sizeof(handler_to_insert));
00969     handler = netsnmp_get_list_data(handler_reg, handler_to_insert);
00970     if (!handler) {
00971         config_perror("no such \"%s\" handler registered.");
00972         return;
00973     }
00974 
00975     if (!cptr) {
00976         config_perror("no INTONAME specified.  Can't do insertion.");
00977         return;
00978     }
00979     cptr = copy_nword(cptr, reg_name, sizeof(reg_name));
00980 
00981     for (stc = get_top_context_cache(); stc; stc = stc->next) {
00982         DEBUGMSGTL(("injectHandler", "Checking context tree %s (before=%s)\n",
00983                     stc->context_name, (cptr)?cptr:"null"));
00984         netsnmp_inject_handler_into_subtree(stc->first_subtree, reg_name,
00985                                             handler, cptr);
00986     }
00987 }
00988 
00993 static int
00994 handler_mark_doneit(int majorID, int minorID,
00995                     void *serverarg, void *clientarg)
00996 {
00997     doneit = 1;
00998     return 0;
00999 }
01000 
01004 void
01005 netsnmp_init_handler_conf(void)
01006 {
01007     snmpd_register_config_handler("injectHandler",
01008                                   parse_injectHandler_conf,
01009                                   NULL, "injectHandler NAME INTONAME [BEFORE_OTHER_NAME]");
01010     snmp_register_callback(SNMP_CALLBACK_LIBRARY,
01011                            SNMP_CALLBACK_POST_READ_CONFIG,
01012                            handler_mark_doneit, NULL);
01013 
01014     se_add_pair_to_slist("agent_mode", strdup("GET"), MODE_GET);
01015     se_add_pair_to_slist("agent_mode", strdup("GETNEXT"), MODE_GETNEXT);
01016     se_add_pair_to_slist("agent_mode", strdup("GETBULK"), MODE_GETBULK);
01017     se_add_pair_to_slist("agent_mode", strdup("SET_BEGIN"),
01018                          MODE_SET_BEGIN);
01019     se_add_pair_to_slist("agent_mode", strdup("SET_RESERVE1"),
01020                          MODE_SET_RESERVE1);
01021     se_add_pair_to_slist("agent_mode", strdup("SET_RESERVE2"),
01022                          MODE_SET_RESERVE2);
01023     se_add_pair_to_slist("agent_mode", strdup("SET_ACTION"),
01024                          MODE_SET_ACTION);
01025     se_add_pair_to_slist("agent_mode", strdup("SET_COMMIT"),
01026                          MODE_SET_COMMIT);
01027     se_add_pair_to_slist("agent_mode", strdup("SET_FREE"), MODE_SET_FREE);
01028     se_add_pair_to_slist("agent_mode", strdup("SET_UNDO"), MODE_SET_UNDO);
01029 
01030     se_add_pair_to_slist("babystep_mode", strdup("pre-request"),
01031                          MODE_BSTEP_PRE_REQUEST);
01032     se_add_pair_to_slist("babystep_mode", strdup("object_lookup"),
01033                          MODE_BSTEP_OBJECT_LOOKUP);
01034     se_add_pair_to_slist("babystep_mode", strdup("check_value"),
01035                          MODE_BSTEP_CHECK_VALUE);
01036     se_add_pair_to_slist("babystep_mode", strdup("row_create"),
01037                          MODE_BSTEP_ROW_CREATE);
01038     se_add_pair_to_slist("babystep_mode", strdup("undo_setup"),
01039                          MODE_BSTEP_UNDO_SETUP);
01040     se_add_pair_to_slist("babystep_mode", strdup("set_value"),
01041                          MODE_BSTEP_SET_VALUE);
01042     se_add_pair_to_slist("babystep_mode", strdup("check_consistency"),
01043                          MODE_BSTEP_CHECK_CONSISTENCY);
01044     se_add_pair_to_slist("babystep_mode", strdup("undo_set"),
01045                          MODE_BSTEP_UNDO_SET);
01046     se_add_pair_to_slist("babystep_mode", strdup("commit"),
01047                          MODE_BSTEP_COMMIT);
01048     se_add_pair_to_slist("babystep_mode", strdup("undo_commit"),
01049                          MODE_BSTEP_UNDO_COMMIT);
01050     se_add_pair_to_slist("babystep_mode", strdup("irreversible_commit"),
01051                          MODE_BSTEP_IRREVERSIBLE_COMMIT);
01052     se_add_pair_to_slist("babystep_mode", strdup("undo_cleanup"),
01053                          MODE_BSTEP_UNDO_CLEANUP);
01054     se_add_pair_to_slist("babystep_mode", strdup("post_request"),
01055                          MODE_BSTEP_POST_REQUEST);
01056     se_add_pair_to_slist("babystep_mode", strdup("original"), 0xffff);
01057 
01058     /*
01059      * xxx-rks: hmmm.. will this work for modes which are or'd together?
01060      *          I'm betting not...
01061      */
01062     se_add_pair_to_slist("handler_can_mode", strdup("GET/GETNEXT"),
01063                          HANDLER_CAN_GETANDGETNEXT);
01064     se_add_pair_to_slist("handler_can_mode", strdup("SET"),
01065                          HANDLER_CAN_SET);
01066     se_add_pair_to_slist("handler_can_mode", strdup("GETBULK"),
01067                          HANDLER_CAN_GETBULK);
01068     se_add_pair_to_slist("handler_can_mode", strdup("BABY_STEP"),
01069                          HANDLER_CAN_BABY_STEP);
01070 }
01071 

Generated on Fri Dec 30 13:47:43 2005 for net-snmp by  doxygen 1.3.9.1

Valid CSS!


Last modified: Thursday, 01-Mar-2007 16:20:06 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.