summaryrefslogtreecommitdiff
path: root/agent/helpers/multiplexer.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/helpers/multiplexer.c')
-rw-r--r--agent/helpers/multiplexer.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/agent/helpers/multiplexer.c b/agent/helpers/multiplexer.c
new file mode 100644
index 0000000..2a7a664
--- /dev/null
+++ b/agent/helpers/multiplexer.c
@@ -0,0 +1,119 @@
+#include <net-snmp/net-snmp-config.h>
+
+#include <sys/types.h>
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include <net-snmp/agent/multiplexer.h>
+
+/** @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 */
+ case MODE_GETNEXT:
+ handler = methods->getnext_handler;
+ if (handler)
+ break;
+ /* Deliberate fallthrough to use Get handler */
+ 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);
+}
+/** @} */
+