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 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 * don't let them register for absolutely nothing. Probably a mistake 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 * for handlers that can't GETBULK, force a conversion handler on them 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 * don't let them register for absolutely nothing. Probably a mistake 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; /* Find the end of a handler sub-chain */ 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 /* after prevh and before nexth */ 00371 prevh->next = handler; 00372 handler2->next = nexth; 00373 handler->prev = prevh; 00374 nexth->prev = handler2; 00375 return SNMPERR_SUCCESS; 00376 } 00377 /* else we're first, which is what we do next anyway so fall through */ 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 * The final handler registration in the chain may well not need 00427 * to include a handler routine, if the processing of this object 00428 * is handled completely by the agent toolkit helpers. 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 * XXX: define acceptable return statuses 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 * did handler signal that it didn't want auto next this time around? 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; /* legal */ 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); /* bugs caught: 1 */ 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 * right now, no extra data is there that needs to be freed 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 /* if (tptr->children) { 00935 netsnmp_inject_handler_into_subtree(tptr->children,name,handler); 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 * XXXWWW: ensure instead that handler isn't inserted twice 00981 */ 00982 if (doneit) /* we only do this once without restart the agent */ 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 * xxx-rks: hmmm.. will this work for modes which are or'd together? 01078 * I'm betting not... 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
Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.