#include #include #include #include #include /** @defgroup multiplexer multiplexer * Splits mode requests into calls to different handlers. * @ingroup utilities * The multiplexer helper lets you split the calling chain depending * on the calling mode (get vs getnext vs set). Useful if you want * different routines to handle different aspects of SNMP requests, * which is very common for GET vs SET type actions. * * Functionally: * * -# GET requests call the get_method * -# GETNEXT requests call the getnext_method, or if not present, the * get_method. * -# GETBULK requests call the getbulk_method, or if not present, the * getnext_method, or if even that isn't present the get_method. * -# SET requests call the set_method, or if not present return a * SNMP_ERR_NOTWRITABLE error. * @{ */ /** returns a multiplixer handler given a netsnmp_mib_handler_methods structure of subhandlers. */ netsnmp_mib_handler * netsnmp_get_multiplexer_handler(netsnmp_mib_handler_methods *req) { netsnmp_mib_handler *ret = NULL; if (!req) { snmp_log(LOG_INFO, "netsnmp_get_multiplexer_handler(NULL) called\n"); return NULL; } ret = netsnmp_create_handler("multiplexer", netsnmp_multiplexer_helper_handler); if (ret) { ret->myvoid = (void *) req; } return ret; } /** implements the multiplexer helper */ int netsnmp_multiplexer_helper_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_mib_handler_methods *methods; if (!handler->myvoid) { snmp_log(LOG_INFO, "improperly registered multiplexer found\n"); return SNMP_ERR_GENERR; } methods = (netsnmp_mib_handler_methods *) handler->myvoid; switch (reqinfo->mode) { case MODE_GETBULK: handler = methods->getbulk_handler; if (handler) break; /* Deliberate fallthrough to use GetNext handler */ /* FALL THROUGH */ case MODE_GETNEXT: handler = methods->getnext_handler; if (handler) break; /* Deliberate fallthrough to use Get handler */ /* FALL THROUGH */ case MODE_GET: handler = methods->get_handler; if (!handler) { netsnmp_request_set_error_all(requests, SNMP_NOSUCHOBJECT); } break; #ifndef NETSNMP_NO_WRITE_SUPPORT case MODE_SET_RESERVE1: case MODE_SET_RESERVE2: case MODE_SET_ACTION: case MODE_SET_COMMIT: case MODE_SET_FREE: case MODE_SET_UNDO: handler = methods->set_handler; if (!handler) { netsnmp_request_set_error_all(requests, SNMP_ERR_NOTWRITABLE); return SNMP_ERR_NOERROR; } break; /* * XXX: process SETs specially, and possibly others */ #endif /* NETSNMP_NO_WRITE_SUPPORT */ default: snmp_log(LOG_ERR, "unsupported mode for multiplexer: %d\n", reqinfo->mode); return SNMP_ERR_GENERR; } if (!handler) { snmp_log(LOG_ERR, "No handler enabled for mode %d in multiplexer\n", reqinfo->mode); return SNMP_ERR_GENERR; } return netsnmp_call_handler(handler, reginfo, reqinfo, requests); } /** @} */