and added files
[bcm963xx.git] / userapps / opensource / net-snmp / agent / helpers / multiplexer.c
1 #include <net-snmp/net-snmp-config.h>
2
3 #include <sys/types.h>
4
5 #include <net-snmp/net-snmp-includes.h>
6 #include <net-snmp/agent/net-snmp-agent-includes.h>
7
8 #include <net-snmp/agent/multiplexer.h>
9
10 #if HAVE_DMALLOC_H
11 #include <dmalloc.h>
12 #endif
13
14 /** @defgroup multiplexer multiplexer: splits mode requests into calls to different handlers.
15  *  @ingroup handler
16  * The multiplexer helper lets you split the calling chain depending
17  * on the calling mode (get vs getnext vs set).  Useful if you want
18  * different routines to handle different aspects of SNMP requests,
19  * which is very common for GET vs SET type actions.
20  *
21  * Functionally:
22  *
23  * -# GET requests call the get_method
24  * -# GETNEXT requests call the getnext_method, or if not present, the
25  *    get_method.
26  * -# GETBULK requests call the getbulk_method, or if not present, the
27  *    getnext_method, or if even that isn't present the get_method.
28  * -# SET requests call the set_method, or if not present return a
29  *    SNMP_ERR_NOTWRITABLE error.
30  *  @{
31  */
32
33 /** returns a multiplixer handler given a netsnmp_mib_handler_methods structure of subhandlers.
34  */
35 netsnmp_mib_handler *
36 netsnmp_get_multiplexer_handler(netsnmp_mib_handler_methods *req)
37 {
38     netsnmp_mib_handler *ret = NULL;
39
40     if (!req) {
41         snmp_log(LOG_INFO,
42                  "netsnmp_get_multiplexer_handler(NULL) called\n");
43         return NULL;
44     }
45
46     ret =
47         netsnmp_create_handler("multiplexer",
48                                netsnmp_multiplexer_helper_handler);
49     if (ret) {
50         ret->myvoid = (void *) req;
51     }
52     return ret;
53 }
54
55 /** implements the multiplexer helper */
56 int
57 netsnmp_multiplexer_helper_handler(netsnmp_mib_handler *handler,
58                                    netsnmp_handler_registration *reginfo,
59                                    netsnmp_agent_request_info *reqinfo,
60                                    netsnmp_request_info *requests)
61 {
62
63     netsnmp_mib_handler_methods *methods;
64
65     if (!handler->myvoid) {
66         snmp_log(LOG_INFO, "improperly registered multiplexer found\n");
67         return SNMP_ERR_GENERR;
68     }
69
70     methods = (netsnmp_mib_handler_methods *) handler->myvoid;
71
72     switch (reqinfo->mode) {
73     case MODE_GET:
74         handler = methods->get_handler;
75         if (!handler) {
76             netsnmp_set_all_requests_error(reqinfo, requests,
77                                            SNMP_NOSUCHOBJECT);
78         }
79         break;
80
81     case MODE_GETNEXT:
82         handler = methods->getnext_handler;
83         if (!handler)           /* fallback to get handler */
84             handler = methods->get_handler;
85         break;
86
87     case MODE_GETBULK:
88         /*
89          * XXX: this needs to do better getbulk -> getnext
90          * handling (probably via a separate helper) 
91          */
92         handler = methods->getbulk_handler;
93         if (!handler)           /* fallback to getnext handler */
94             handler = methods->getnext_handler;
95         if (!handler)           /* fallback to getnext handler */
96             handler = methods->get_handler;
97         break;
98
99     case MODE_SET_RESERVE1:
100     case MODE_SET_RESERVE2:
101     case MODE_SET_ACTION:
102     case MODE_SET_COMMIT:
103     case MODE_SET_FREE:
104     case MODE_SET_UNDO:
105         handler = methods->set_handler;
106         if (!handler) {
107             netsnmp_set_all_requests_error(reqinfo, requests,
108                                            SNMP_ERR_NOTWRITABLE);
109             return SNMP_ERR_NOERROR;
110         }
111         break;
112
113         /*
114          * XXX: process SETs specially, and possibly others 
115          */
116     default:
117         snmp_log(LOG_ERR, "unsupported mode for multiplexer: %d\n",
118                  reqinfo->mode);
119         return SNMP_ERR_GENERR;
120     }
121     if (!handler) {
122         snmp_log(LOG_ERR,
123                  "No handler enabled for mode %d in multiplexer\n",
124                  reqinfo->mode);
125         return SNMP_ERR_GENERR;
126     }
127     return netsnmp_call_handler(handler, reginfo, reqinfo, requests);
128 }