00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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 const 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 the_reg->rootoid = snmp_duplicate_objid(reg_oid, reg_oid_len);
00183 the_reg->rootoid_len = reg_oid_len;
00184 return the_reg;
00185 }
00186
00187 netsnmp_handler_registration *
00188 netsnmp_create_handler_registration(const char *name,
00189 Netsnmp_Node_Handler *
00190 handler_access_method, const oid * reg_oid,
00191 size_t reg_oid_len, int modes)
00192 {
00193 netsnmp_handler_registration *rv = NULL;
00194 netsnmp_mib_handler *handler =
00195 netsnmp_create_handler(name, handler_access_method);
00196 if (handler) {
00197 rv = netsnmp_handler_registration_create(
00198 name, handler, reg_oid, reg_oid_len, modes);
00199 if (!rv)
00200 netsnmp_handler_free(handler);
00201 }
00202 return rv;
00203 }
00204
00206 int
00207 netsnmp_register_handler(netsnmp_handler_registration *reginfo)
00208 {
00209 netsnmp_mib_handler *handler;
00210 int flags = 0;
00211
00212 if (reginfo == NULL) {
00213 snmp_log(LOG_ERR, "netsnmp_register_handler() called illegally\n");
00214 netsnmp_assert(reginfo != NULL);
00215 return SNMP_ERR_GENERR;
00216 }
00217
00218 DEBUGIF("handler::register") {
00219 DEBUGMSGTL(("handler::register", "Registering %s (", reginfo->handlerName));
00220 for (handler = reginfo->handler; handler; handler = handler->next) {
00221 DEBUGMSG(("handler::register", "::%s", handler->handler_name));
00222 }
00223
00224 DEBUGMSG(("handler::register", ") at "));
00225 if (reginfo->rootoid && reginfo->range_subid) {
00226 DEBUGMSGOIDRANGE(("handler::register", reginfo->rootoid,
00227 reginfo->rootoid_len, reginfo->range_subid,
00228 reginfo->range_ubound));
00229 } else if (reginfo->rootoid) {
00230 DEBUGMSGOID(("handler::register", reginfo->rootoid,
00231 reginfo->rootoid_len));
00232 } else {
00233 DEBUGMSG(("handler::register", "[null]"));
00234 }
00235 DEBUGMSG(("handler::register", "\n"));
00236 }
00237
00238
00239
00240
00241 if (0 == reginfo->modes) {
00242 reginfo->modes = HANDLER_CAN_DEFAULT;
00243 snmp_log(LOG_WARNING, "no registration modes specified for %s. "
00244 "Defaulting to 0x%x\n", reginfo->handlerName, reginfo->modes);
00245 }
00246
00247
00248
00249
00250 if (!(reginfo->modes & HANDLER_CAN_GETBULK)) {
00251 netsnmp_inject_handler(reginfo,
00252 netsnmp_get_bulk_to_next_handler());
00253 }
00254
00255 for (handler = reginfo->handler; handler; handler = handler->next) {
00256 if (handler->flags & MIB_HANDLER_INSTANCE)
00257 flags = FULLY_QUALIFIED_INSTANCE;
00258 }
00259
00260 return netsnmp_register_mib(reginfo->handlerName,
00261 NULL, 0, 0,
00262 reginfo->rootoid, reginfo->rootoid_len,
00263 reginfo->priority,
00264 reginfo->range_subid,
00265 reginfo->range_ubound, NULL,
00266 reginfo->contextName, reginfo->timeout, flags,
00267 reginfo, 1);
00268 }
00269
00271 int
00272 netsnmp_unregister_handler(netsnmp_handler_registration *reginfo)
00273 {
00274 return unregister_mib_context(reginfo->rootoid, reginfo->rootoid_len,
00275 reginfo->priority,
00276 reginfo->range_subid, reginfo->range_ubound,
00277 reginfo->contextName);
00278 }
00279
00281 int
00282 netsnmp_register_handler_nocallback(netsnmp_handler_registration *reginfo)
00283 {
00284 netsnmp_mib_handler *handler;
00285 if (reginfo == NULL) {
00286 snmp_log(LOG_ERR, "netsnmp_register_handler_nocallback() called illegally\n");
00287 netsnmp_assert(reginfo != NULL);
00288 return SNMP_ERR_GENERR;
00289 }
00290 DEBUGIF("handler::register") {
00291 DEBUGMSGTL(("handler::register",
00292 "Registering (with no callback) "));
00293 for (handler = reginfo->handler; handler; handler = handler->next) {
00294 DEBUGMSG(("handler::register", "::%s", handler->handler_name));
00295 }
00296
00297 DEBUGMSG(("handler::register", " at "));
00298 if (reginfo->rootoid && reginfo->range_subid) {
00299 DEBUGMSGOIDRANGE(("handler::register", reginfo->rootoid,
00300 reginfo->rootoid_len, reginfo->range_subid,
00301 reginfo->range_ubound));
00302 } else if (reginfo->rootoid) {
00303 DEBUGMSGOID(("handler::register", reginfo->rootoid,
00304 reginfo->rootoid_len));
00305 } else {
00306 DEBUGMSG(("handler::register", "[null]"));
00307 }
00308 DEBUGMSG(("handler::register", "\n"));
00309 }
00310
00311
00312
00313
00314 if (0 == reginfo->modes) {
00315 reginfo->modes = HANDLER_CAN_DEFAULT;
00316 }
00317
00318 return netsnmp_register_mib(reginfo->handler->handler_name,
00319 NULL, 0, 0,
00320 reginfo->rootoid, reginfo->rootoid_len,
00321 reginfo->priority,
00322 reginfo->range_subid,
00323 reginfo->range_ubound, NULL,
00324 reginfo->contextName, reginfo->timeout, 0,
00325 reginfo, 0);
00326 }
00327
00333 int
00334 netsnmp_inject_handler_before(netsnmp_handler_registration *reginfo,
00335 netsnmp_mib_handler *handler,
00336 const char *before_what)
00337 {
00338 netsnmp_mib_handler *handler2 = handler;
00339
00340 if (handler == NULL || reginfo == NULL) {
00341 snmp_log(LOG_ERR, "netsnmp_inject_handler() called illegally\n");
00342 netsnmp_assert(reginfo != NULL);
00343 netsnmp_assert(handler != NULL);
00344 return SNMP_ERR_GENERR;
00345 }
00346 while (handler2->next) {
00347 handler2 = handler2->next;
00348 }
00349 if (reginfo->handler == NULL) {
00350 DEBUGMSGTL(("handler:inject", "injecting %s\n", handler->handler_name));
00351 }
00352 else {
00353 DEBUGMSGTL(("handler:inject", "injecting %s before %s\n",
00354 handler->handler_name, reginfo->handler->handler_name));
00355 }
00356 if (before_what) {
00357 netsnmp_mib_handler *nexth, *prevh = NULL;
00358 if (reginfo->handler == NULL) {
00359 snmp_log(LOG_ERR, "no handler to inject before\n");
00360 return SNMP_ERR_GENERR;
00361 }
00362 for(nexth = reginfo->handler; nexth;
00363 prevh = nexth, nexth = nexth->next) {
00364 if (strcmp(nexth->handler_name, before_what) == 0)
00365 break;
00366 }
00367 if (!nexth)
00368 return SNMP_ERR_GENERR;
00369 if (prevh) {
00370
00371 prevh->next = handler;
00372 handler2->next = nexth;
00373 handler->prev = prevh;
00374 nexth->prev = handler2;
00375 return SNMPERR_SUCCESS;
00376 }
00377
00378 }
00379 handler2->next = reginfo->handler;
00380 if (reginfo->handler)
00381 reginfo->handler->prev = handler2;
00382 reginfo->handler = handler;
00383 return SNMPERR_SUCCESS;
00384 }
00385
00390 int
00391 netsnmp_inject_handler(netsnmp_handler_registration *reginfo,
00392 netsnmp_mib_handler *handler)
00393 {
00394 return netsnmp_inject_handler_before(reginfo, handler, NULL);
00395 }
00396
00398 NETSNMP_INLINE int
00399 netsnmp_call_handler(netsnmp_mib_handler *next_handler,
00400 netsnmp_handler_registration *reginfo,
00401 netsnmp_agent_request_info *reqinfo,
00402 netsnmp_request_info *requests)
00403 {
00404 Netsnmp_Node_Handler *nh;
00405 int ret;
00406
00407 if (next_handler == NULL || reginfo == NULL || reqinfo == NULL ||
00408 requests == NULL) {
00409 snmp_log(LOG_ERR, "netsnmp_call_handler() called illegally\n");
00410 netsnmp_assert(next_handler != NULL);
00411 netsnmp_assert(reqinfo != NULL);
00412 netsnmp_assert(reginfo != NULL);
00413 netsnmp_assert(requests != NULL);
00414 return SNMP_ERR_GENERR;
00415 }
00416
00417 do {
00418 nh = next_handler->access_method;
00419 if (!nh) {
00420 if (next_handler->next) {
00421 snmp_log(LOG_ERR, "no access method specified in handler %s.",
00422 next_handler->handler_name);
00423 return SNMP_ERR_GENERR;
00424 }
00425
00426
00427
00428
00429
00430 return SNMP_ERR_NOERROR;
00431 }
00432
00433 DEBUGMSGTL(("handler:calling", "calling handler %s for mode %s\n",
00434 next_handler->handler_name,
00435 se_find_label_in_slist("agent_mode", reqinfo->mode)));
00436
00437
00438
00439
00440 ret = (*nh) (next_handler, reginfo, reqinfo, requests);
00441
00442 DEBUGMSGTL(("handler:returned", "handler %s returned %d\n",
00443 next_handler->handler_name, ret));
00444
00445 if (! (next_handler->flags & MIB_HANDLER_AUTO_NEXT))
00446 break;
00447
00448
00449
00450
00451 if(next_handler->flags & MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE) {
00452 next_handler->flags &= ~MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
00453 break;
00454 }
00455
00456 next_handler = next_handler->next;
00457
00458 } while(next_handler);
00459
00460 return ret;
00461 }
00462
00466 int
00467 netsnmp_call_handlers(netsnmp_handler_registration *reginfo,
00468 netsnmp_agent_request_info *reqinfo,
00469 netsnmp_request_info *requests)
00470 {
00471 netsnmp_request_info *request;
00472 int status;
00473
00474 if (reginfo == NULL || reqinfo == NULL || requests == NULL) {
00475 snmp_log(LOG_ERR, "netsnmp_call_handlers() called illegally\n");
00476 netsnmp_assert(reqinfo != NULL);
00477 netsnmp_assert(reginfo != NULL);
00478 netsnmp_assert(requests != NULL);
00479 return SNMP_ERR_GENERR;
00480 }
00481
00482 if (reginfo->handler == NULL) {
00483 snmp_log(LOG_ERR, "no handler specified.");
00484 return SNMP_ERR_GENERR;
00485 }
00486
00487 switch (reqinfo->mode) {
00488 case MODE_GETBULK:
00489 case MODE_GET:
00490 case MODE_GETNEXT:
00491 if (!(reginfo->modes & HANDLER_CAN_GETANDGETNEXT))
00492 return SNMP_ERR_NOERROR;
00493 break;
00494
00495 case MODE_SET_RESERVE1:
00496 case MODE_SET_RESERVE2:
00497 case MODE_SET_ACTION:
00498 case MODE_SET_COMMIT:
00499 case MODE_SET_FREE:
00500 case MODE_SET_UNDO:
00501 if (!(reginfo->modes & HANDLER_CAN_SET)) {
00502 for (; requests; requests = requests->next) {
00503 netsnmp_set_request_error(reqinfo, requests,
00504 SNMP_ERR_NOTWRITABLE);
00505 }
00506 return SNMP_ERR_NOERROR;
00507 }
00508 break;
00509
00510 default:
00511 snmp_log(LOG_ERR, "unknown mode in netsnmp_call_handlers! bug!\n");
00512 return SNMP_ERR_GENERR;
00513 }
00514 DEBUGMSGTL(("handler:calling", "main handler %s\n",
00515 reginfo->handler->handler_name));
00516
00517 for (request = requests ; request; request = request->next) {
00518 request->processed = 0;
00519 }
00520
00521 status = netsnmp_call_handler(reginfo->handler, reginfo, reqinfo, requests);
00522
00523 return status;
00524 }
00525
00528 NETSNMP_INLINE int
00529 netsnmp_call_next_handler(netsnmp_mib_handler *current,
00530 netsnmp_handler_registration *reginfo,
00531 netsnmp_agent_request_info *reqinfo,
00532 netsnmp_request_info *requests)
00533 {
00534
00535 if (current == NULL || reginfo == NULL || reqinfo == NULL ||
00536 requests == NULL) {
00537 snmp_log(LOG_ERR, "netsnmp_call_next_handler() called illegally\n");
00538 netsnmp_assert(current != NULL);
00539 netsnmp_assert(reginfo != NULL);
00540 netsnmp_assert(reqinfo != NULL);
00541 netsnmp_assert(requests != NULL);
00542 return SNMP_ERR_GENERR;
00543 }
00544
00545 return netsnmp_call_handler(current->next, reginfo, reqinfo, requests);
00546 }
00547
00550 NETSNMP_INLINE int
00551 netsnmp_call_next_handler_one_request(netsnmp_mib_handler *current,
00552 netsnmp_handler_registration *reginfo,
00553 netsnmp_agent_request_info *reqinfo,
00554 netsnmp_request_info *requests)
00555 {
00556 netsnmp_request_info *request;
00557 int ret;
00558
00559 if (!requests) {
00560 snmp_log(LOG_ERR, "netsnmp_call_next_handler_ONE_REQUEST() called illegally\n");
00561 netsnmp_assert(requests != NULL);
00562 return SNMP_ERR_GENERR;
00563 }
00564
00565 request = requests->next;
00566 requests->next = NULL;
00567 ret = netsnmp_call_handler(current->next, reginfo, reqinfo, requests);
00568 requests->next = request;
00569 return ret;
00570 }
00571
00573 void
00574 netsnmp_handler_free(netsnmp_mib_handler *handler)
00575 {
00576 if (handler != NULL) {
00577 if (handler->next != NULL) {
00579 netsnmp_assert(handler != handler->next);
00580 netsnmp_handler_free(handler->next);
00581 handler->next = NULL;
00582 }
00587 if ((handler->myvoid != NULL) && (handler->data_free != NULL))
00588 {
00589 handler->data_free(handler->myvoid);
00590 }
00591 SNMP_FREE(handler->handler_name);
00592 SNMP_FREE(handler);
00593 }
00594 }
00595
00599 netsnmp_mib_handler *
00600 netsnmp_handler_dup(netsnmp_mib_handler *handler)
00601 {
00602 netsnmp_mib_handler *h = NULL;
00603
00604 if (handler == NULL) {
00605 return NULL;
00606 }
00607
00608 h = _clone_handler(handler);
00609
00610 if (h != NULL) {
00611 h->myvoid = handler->myvoid;
00612 h->data_free = handler->data_free;
00613
00614 if (handler->next != NULL) {
00615 h->next = netsnmp_handler_dup(handler->next);
00616 if (h->next == NULL) {
00617 netsnmp_handler_free(h);
00618 return NULL;
00619 }
00620 h->next->prev = h;
00621 }
00622 h->prev = NULL;
00623 return h;
00624 }
00625 return NULL;
00626 }
00627
00629 void
00630 netsnmp_handler_registration_free(netsnmp_handler_registration *reginfo)
00631 {
00632 if (reginfo != NULL) {
00633 netsnmp_handler_free(reginfo->handler);
00634 SNMP_FREE(reginfo->handlerName);
00635 SNMP_FREE(reginfo->contextName);
00636 SNMP_FREE(reginfo->rootoid);
00637 reginfo->rootoid_len = 0;
00638 SNMP_FREE(reginfo);
00639 }
00640 }
00641
00643 netsnmp_handler_registration *
00644 netsnmp_handler_registration_dup(netsnmp_handler_registration *reginfo)
00645 {
00646 netsnmp_handler_registration *r = NULL;
00647
00648 if (reginfo == NULL) {
00649 return NULL;
00650 }
00651
00652
00653 r = (netsnmp_handler_registration *) calloc(1,
00654 sizeof
00655 (netsnmp_handler_registration));
00656
00657 if (r != NULL) {
00658 r->modes = reginfo->modes;
00659 r->priority = reginfo->priority;
00660 r->range_subid = reginfo->range_subid;
00661 r->timeout = reginfo->timeout;
00662 r->range_ubound = reginfo->range_ubound;
00663 r->rootoid_len = reginfo->rootoid_len;
00664
00665 if (reginfo->handlerName != NULL) {
00666 r->handlerName = strdup(reginfo->handlerName);
00667 if (r->handlerName == NULL) {
00668 netsnmp_handler_registration_free(r);
00669 return NULL;
00670 }
00671 }
00672
00673 if (reginfo->contextName != NULL) {
00674 r->contextName = strdup(reginfo->contextName);
00675 if (r->contextName == NULL) {
00676 netsnmp_handler_registration_free(r);
00677 return NULL;
00678 }
00679 }
00680
00681 if (reginfo->rootoid != NULL) {
00682 r->rootoid =
00683 snmp_duplicate_objid(reginfo->rootoid, reginfo->rootoid_len);
00684 if (r->rootoid == NULL) {
00685 netsnmp_handler_registration_free(r);
00686 return NULL;
00687 }
00688 }
00689
00690 r->handler = netsnmp_handler_dup(reginfo->handler);
00691 if (r->handler == NULL) {
00692 netsnmp_handler_registration_free(r);
00693 return NULL;
00694 }
00695 return r;
00696 }
00697
00698 return NULL;
00699 }
00700
00704 NETSNMP_INLINE netsnmp_delegated_cache *
00705 netsnmp_create_delegated_cache(netsnmp_mib_handler *handler,
00706 netsnmp_handler_registration *reginfo,
00707 netsnmp_agent_request_info *reqinfo,
00708 netsnmp_request_info *requests,
00709 void *localinfo)
00710 {
00711 netsnmp_delegated_cache *ret;
00712
00713 ret = SNMP_MALLOC_TYPEDEF(netsnmp_delegated_cache);
00714 if (ret) {
00715 ret->transaction_id = reqinfo->asp->pdu->transid;
00716 ret->handler = handler;
00717 ret->reginfo = reginfo;
00718 ret->reqinfo = reqinfo;
00719 ret->requests = requests;
00720 ret->localinfo = localinfo;
00721 }
00722 return ret;
00723 }
00724
00728 NETSNMP_INLINE netsnmp_delegated_cache *
00729 netsnmp_handler_check_cache(netsnmp_delegated_cache *dcache)
00730 {
00731 if (!dcache)
00732 return dcache;
00733
00734 if (netsnmp_check_transaction_id(dcache->transaction_id) ==
00735 SNMPERR_SUCCESS)
00736 return dcache;
00737
00738 return NULL;
00739 }
00740
00742 NETSNMP_INLINE void
00743 netsnmp_free_delegated_cache(netsnmp_delegated_cache *dcache)
00744 {
00745
00746
00747
00748 if (dcache)
00749 SNMP_FREE(dcache);
00750
00751 return;
00752 }
00753
00754
00756 void
00757 netsnmp_handler_mark_requests_as_delegated(netsnmp_request_info *requests,
00758 int isdelegated)
00759 {
00760 while (requests) {
00761 requests->delegated = isdelegated;
00762 requests = requests->next;
00763 }
00764 }
00765
00776 NETSNMP_INLINE void
00777 netsnmp_request_add_list_data(netsnmp_request_info *request,
00778 netsnmp_data_list *node)
00779 {
00780 if (request) {
00781 if (request->parent_data)
00782 netsnmp_add_list_data(&request->parent_data, node);
00783 else
00784 request->parent_data = node;
00785 }
00786 }
00787
00797 NETSNMP_INLINE int
00798 netsnmp_request_remove_list_data(netsnmp_request_info *request,
00799 const char *name)
00800 {
00801 if ((NULL == request) || (NULL ==request->parent_data))
00802 return 1;
00803
00804 return netsnmp_remove_list_node(&request->parent_data, name);
00805 }
00806
00818 void *
00819 netsnmp_request_get_list_data(netsnmp_request_info *request,
00820 const char *name)
00821 {
00822 if (request)
00823 return netsnmp_get_list_data(request->parent_data, name);
00824 return NULL;
00825 }
00826
00828 NETSNMP_INLINE void
00829 netsnmp_free_request_data_set(netsnmp_request_info *request)
00830 {
00831 if (request)
00832 netsnmp_free_list_data(request->parent_data);
00833 }
00834
00836 NETSNMP_INLINE void
00837 netsnmp_free_request_data_sets(netsnmp_request_info *request)
00838 {
00839 if (request && request->parent_data) {
00840 netsnmp_free_all_list_data(request->parent_data);
00841 request->parent_data = NULL;
00842 }
00843 }
00844
00846 netsnmp_mib_handler *
00847 netsnmp_find_handler_by_name(netsnmp_handler_registration *reginfo,
00848 const char *name)
00849 {
00850 netsnmp_mib_handler *it;
00851 for (it = reginfo->handler; it; it = it->next) {
00852 if (strcmp(it->handler_name, name) == 0) {
00853 return it;
00854 }
00855 }
00856 return NULL;
00857 }
00858
00863 void *
00864 netsnmp_find_handler_data_by_name(netsnmp_handler_registration *reginfo,
00865 const char *name)
00866 {
00867 netsnmp_mib_handler *it = netsnmp_find_handler_by_name(reginfo, name);
00868 if (it)
00869 return it->myvoid;
00870 return NULL;
00871 }
00872
00876 static netsnmp_mib_handler *
00877 _clone_handler(netsnmp_mib_handler *it)
00878 {
00879 netsnmp_mib_handler *dup;
00880
00881 if(NULL == it)
00882 return NULL;
00883
00884 dup = netsnmp_create_handler(it->handler_name, it->access_method);
00885 if(NULL != dup)
00886 dup->flags = it->flags;
00887
00888 return dup;
00889 }
00890
00891 static netsnmp_data_list *handler_reg = NULL;
00892
00893 void
00894 handler_free_callback(void *free)
00895 {
00896 netsnmp_handler_free((netsnmp_mib_handler *)free);
00897 }
00898
00901 void
00902 netsnmp_register_handler_by_name(const char *name,
00903 netsnmp_mib_handler *handler)
00904 {
00905 netsnmp_add_list_data(&handler_reg,
00906 netsnmp_create_data_list(name, (void *) handler,
00907 handler_free_callback));
00908 DEBUGMSGTL(("handler_registry", "registering helper %s\n", name));
00909 }
00910
00913 void
00914 netsnmp_clear_handler_list(void)
00915 {
00916 DEBUGMSGTL(("agent_handler", "netsnmp_clear_handler_list() called\n"));
00917 netsnmp_free_all_list_data(handler_reg);
00918 handler_reg = NULL;
00919 }
00920
00925 void
00926 netsnmp_inject_handler_into_subtree(netsnmp_subtree *tp, const char *name,
00927 netsnmp_mib_handler *handler,
00928 const char *before_what)
00929 {
00930 netsnmp_subtree *tptr;
00931 netsnmp_mib_handler *mh;
00932
00933 for (tptr = tp; tptr != NULL; tptr = tptr->next) {
00934
00935
00936
00937 if (strcmp(tptr->label_a, name) == 0) {
00938 DEBUGMSGTL(("injectHandler", "injecting handler %s into %s\n",
00939 handler->handler_name, tptr->label_a));
00940 netsnmp_inject_handler_before(tptr->reginfo, _clone_handler(handler),
00941 before_what);
00942 } else if (tptr->reginfo != NULL &&
00943 tptr->reginfo->handlerName != NULL &&
00944 strcmp(tptr->reginfo->handlerName, name) == 0) {
00945 DEBUGMSGTL(("injectHandler", "injecting handler into %s/%s\n",
00946 tptr->label_a, tptr->reginfo->handlerName));
00947 netsnmp_inject_handler_before(tptr->reginfo, _clone_handler(handler),
00948 before_what);
00949 } else {
00950 for (mh = tptr->reginfo->handler; mh != NULL; mh = mh->next) {
00951 if (mh->handler_name && strcmp(mh->handler_name, name) == 0) {
00952 DEBUGMSGTL(("injectHandler", "injecting handler into %s\n",
00953 tptr->label_a));
00954 netsnmp_inject_handler_before(tptr->reginfo,
00955 _clone_handler(handler),
00956 before_what);
00957 break;
00958 } else {
00959 DEBUGMSGTL(("yyyinjectHandler",
00960 "not injecting handler into %s\n",
00961 mh->handler_name));
00962 }
00963 }
00964 }
00965 }
00966 }
00967
00968 static int doneit = 0;
00972 void
00973 parse_injectHandler_conf(const char *token, char *cptr)
00974 {
00975 char handler_to_insert[256], reg_name[256];
00976 subtree_context_cache *stc;
00977 netsnmp_mib_handler *handler;
00978
00979
00980
00981
00982 if (doneit)
00983 return;
00984
00985 cptr = copy_nword(cptr, handler_to_insert, sizeof(handler_to_insert));
00986 handler = netsnmp_get_list_data(handler_reg, handler_to_insert);
00987 if (!handler) {
00988 netsnmp_config_error("no \"%s\" handler registered.",
00989 handler_to_insert);
00990 return;
00991 }
00992
00993 if (!cptr) {
00994 config_perror("no INTONAME specified. Can't do insertion.");
00995 return;
00996 }
00997 cptr = copy_nword(cptr, reg_name, sizeof(reg_name));
00998
00999 for (stc = get_top_context_cache(); stc; stc = stc->next) {
01000 DEBUGMSGTL(("injectHandler", "Checking context tree %s (before=%s)\n",
01001 stc->context_name, (cptr)?cptr:"null"));
01002 netsnmp_inject_handler_into_subtree(stc->first_subtree, reg_name,
01003 handler, cptr);
01004 }
01005 }
01006
01011 static int
01012 handler_mark_doneit(int majorID, int minorID,
01013 void *serverarg, void *clientarg)
01014 {
01015 doneit = 1;
01016 return 0;
01017 }
01018
01022 void
01023 netsnmp_init_handler_conf(void)
01024 {
01025 snmpd_register_config_handler("injectHandler",
01026 parse_injectHandler_conf,
01027 NULL, "injectHandler NAME INTONAME [BEFORE_OTHER_NAME]");
01028 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
01029 SNMP_CALLBACK_POST_READ_CONFIG,
01030 handler_mark_doneit, NULL);
01031
01032 se_add_pair_to_slist("agent_mode", strdup("GET"), MODE_GET);
01033 se_add_pair_to_slist("agent_mode", strdup("GETNEXT"), MODE_GETNEXT);
01034 se_add_pair_to_slist("agent_mode", strdup("GETBULK"), MODE_GETBULK);
01035 se_add_pair_to_slist("agent_mode", strdup("SET_BEGIN"),
01036 MODE_SET_BEGIN);
01037 se_add_pair_to_slist("agent_mode", strdup("SET_RESERVE1"),
01038 MODE_SET_RESERVE1);
01039 se_add_pair_to_slist("agent_mode", strdup("SET_RESERVE2"),
01040 MODE_SET_RESERVE2);
01041 se_add_pair_to_slist("agent_mode", strdup("SET_ACTION"),
01042 MODE_SET_ACTION);
01043 se_add_pair_to_slist("agent_mode", strdup("SET_COMMIT"),
01044 MODE_SET_COMMIT);
01045 se_add_pair_to_slist("agent_mode", strdup("SET_FREE"), MODE_SET_FREE);
01046 se_add_pair_to_slist("agent_mode", strdup("SET_UNDO"), MODE_SET_UNDO);
01047
01048 se_add_pair_to_slist("babystep_mode", strdup("pre-request"),
01049 MODE_BSTEP_PRE_REQUEST);
01050 se_add_pair_to_slist("babystep_mode", strdup("object_lookup"),
01051 MODE_BSTEP_OBJECT_LOOKUP);
01052 se_add_pair_to_slist("babystep_mode", strdup("check_value"),
01053 MODE_BSTEP_CHECK_VALUE);
01054 se_add_pair_to_slist("babystep_mode", strdup("row_create"),
01055 MODE_BSTEP_ROW_CREATE);
01056 se_add_pair_to_slist("babystep_mode", strdup("undo_setup"),
01057 MODE_BSTEP_UNDO_SETUP);
01058 se_add_pair_to_slist("babystep_mode", strdup("set_value"),
01059 MODE_BSTEP_SET_VALUE);
01060 se_add_pair_to_slist("babystep_mode", strdup("check_consistency"),
01061 MODE_BSTEP_CHECK_CONSISTENCY);
01062 se_add_pair_to_slist("babystep_mode", strdup("undo_set"),
01063 MODE_BSTEP_UNDO_SET);
01064 se_add_pair_to_slist("babystep_mode", strdup("commit"),
01065 MODE_BSTEP_COMMIT);
01066 se_add_pair_to_slist("babystep_mode", strdup("undo_commit"),
01067 MODE_BSTEP_UNDO_COMMIT);
01068 se_add_pair_to_slist("babystep_mode", strdup("irreversible_commit"),
01069 MODE_BSTEP_IRREVERSIBLE_COMMIT);
01070 se_add_pair_to_slist("babystep_mode", strdup("undo_cleanup"),
01071 MODE_BSTEP_UNDO_CLEANUP);
01072 se_add_pair_to_slist("babystep_mode", strdup("post_request"),
01073 MODE_BSTEP_POST_REQUEST);
01074 se_add_pair_to_slist("babystep_mode", strdup("original"), 0xffff);
01075
01076
01077
01078
01079
01080 se_add_pair_to_slist("handler_can_mode", strdup("GET/GETNEXT"),
01081 HANDLER_CAN_GETANDGETNEXT);
01082 se_add_pair_to_slist("handler_can_mode", strdup("SET"),
01083 HANDLER_CAN_SET);
01084 se_add_pair_to_slist("handler_can_mode", strdup("GETBULK"),
01085 HANDLER_CAN_GETBULK);
01086 se_add_pair_to_slist("handler_can_mode", strdup("BABY_STEP"),
01087 HANDLER_CAN_BABY_STEP);
01088 }
01089