1 #include <net-snmp/net-snmp-config.h>
9 #include <net-snmp/net-snmp-includes.h>
10 #include <net-snmp/agent/net-snmp-agent-includes.h>
12 #include <net-snmp/agent/old_api.h>
13 #include <net-snmp/agent/agent_callbacks.h>
19 #define MIB_CLIENTS_ARE_EVIL 1
24 void set_current_agent_session(netsnmp_agent_session *asp);
25 netsnmp_agent_session *netsnmp_get_current_agent_session(void);
27 /** @defgroup old_api old_api: Calls mib module code written in the old style of code.
29 * This is a backwards compatilibity module that allows code written
30 * in the old API to be run under the new handler based architecture.
31 * Use it by calling netsnmp_register_old_api().
35 /** returns a old_api handler that should be the final calling
36 * handler. Don't use this function. Use the netsnmp_register_old_api()
40 get_old_api_handler(void)
42 return netsnmp_create_handler("old_api", netsnmp_old_api_helper);
46 /** Registers an old API set into the mib tree. Functionally this
47 * mimics the old register_mib_context() function (and in fact the new
48 * register_mib_context() function merely calls this new old_api one).
51 netsnmp_register_old_api(const char *moduleName,
61 const char *context, int timeout, int flags)
64 netsnmp_old_api_info *old_info =
65 SNMP_MALLOC_TYPEDEF(netsnmp_old_api_info);
69 old_info->varsize = varsize;
70 old_info->numvars = numvars;
72 old_info->flags = flags;
75 * register all subtree nodes
77 for (i = 0; i < numvars; i++) {
79 netsnmp_handler_registration *reginfo =
80 SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
83 (void *) (struct variable *) ((char *) var + varsize * i),
86 reginfo->handler = get_old_api_handler();
87 reginfo->handlerName = strdup(moduleName);
88 reginfo->rootoid_len = (mibloclen + vp->namelen);
90 (oid *) malloc(reginfo->rootoid_len * sizeof(oid));
92 memcpy(reginfo->rootoid, mibloc, mibloclen * sizeof(oid));
93 memcpy(reginfo->rootoid + mibloclen, vp->name, vp->namelen
95 reginfo->handler->myvoid = (void *) vp;
97 reginfo->priority = priority;
98 reginfo->range_subid = range_subid;
100 reginfo->range_ubound = range_ubound;
101 reginfo->timeout = timeout;
102 reginfo->contextName = (context) ? strdup(context) : NULL;
103 reginfo->modes = HANDLER_CAN_RWRITE;
106 * register ourselves in the mib tree
108 if (netsnmp_register_handler(reginfo) != MIB_REGISTERED_OK) {
109 netsnmp_handler_registration_free(reginfo);
114 return SNMPERR_SUCCESS;
117 /** registers a row within a mib table */
119 netsnmp_register_mib_table_row(const char *moduleName,
120 struct variable *var,
127 netsnmp_session * ss,
128 const char *context, int timeout, int flags)
130 unsigned int i = 0, rc = 0;
133 for (i = 0; i < numvars; i++) {
134 struct variable *vr =
135 (struct variable *) ((char *) var + (i * varsize));
136 netsnmp_handler_registration *r =
137 SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
141 * Unregister whatever we have registered so far, and
144 rc = MIB_REGISTRATION_FAILED;
147 memset(r, 0, sizeof(netsnmp_handler_registration));
149 r->handler = get_old_api_handler();
150 r->handlerName = strdup(moduleName);
152 if (r->handlerName == NULL) {
153 netsnmp_handler_registration_free(r);
157 r->rootoid_len = mibloclen;
158 r->rootoid = (oid *) malloc(r->rootoid_len * sizeof(oid));
160 if (r->rootoid == NULL) {
161 netsnmp_handler_registration_free(r);
162 rc = MIB_REGISTRATION_FAILED;
165 memcpy(r->rootoid, mibloc, mibloclen * sizeof(oid));
166 memcpy((u_char *) (r->rootoid + (var_subid - 1)), vr->name,
167 vr->namelen * sizeof(oid));
168 DEBUGMSGTL(("netsnmp_register_mib_table_row", "rootoid "));
169 DEBUGMSGOID(("netsnmp_register_mib_table_row", r->rootoid,
171 DEBUGMSG(("netsnmp_register_mib_table_row", "\n"));
172 r->handler->myvoid = (void *) malloc(varsize);
174 if (r->handler->myvoid == NULL) {
175 netsnmp_handler_registration_free(r);
176 rc = MIB_REGISTRATION_FAILED;
179 memcpy((char *) r->handler->myvoid, vr, varsize);
181 r->contextName = (context) ? strdup(context) : NULL;
183 if (context != NULL && r->contextName == NULL) {
184 netsnmp_handler_registration_free(r);
185 rc = MIB_REGISTRATION_FAILED;
189 r->priority = priority;
190 r->range_subid = 0; /* var_subid; */
191 r->range_ubound = 0; /* range_ubound; */
192 r->timeout = timeout;
193 r->modes = HANDLER_CAN_RWRITE;
196 * Register this column and row
199 netsnmp_register_handler_nocallback(r)) !=
201 DEBUGMSGTL(("netsnmp_register_mib_table_row",
202 "register failed %d\n", rc));
203 netsnmp_handler_registration_free(r);
207 if (vr->namelen > 0) {
208 if (vr->name[vr->namelen - 1] > ubound) {
209 ubound = vr->name[vr->namelen - 1];
214 if (rc == MIB_REGISTERED_OK) {
215 struct register_parameters reg_parms;
217 reg_parms.name = mibloc;
218 reg_parms.namelen = mibloclen;
219 reg_parms.priority = priority;
220 reg_parms.flags = (u_char) flags;
221 reg_parms.range_subid = var_subid;
222 reg_parms.range_ubound = ubound;
223 reg_parms.timeout = timeout;
224 rc = snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
225 SNMPD_CALLBACK_REGISTER_OID, ®_parms);
231 /** implements the old_api handler */
233 netsnmp_old_api_helper(netsnmp_mib_handler *handler,
234 netsnmp_handler_registration *reginfo,
235 netsnmp_agent_request_info *reqinfo,
236 netsnmp_request_info *requests)
239 #if MIB_CLIENTS_ARE_EVIL
240 oid save[MAX_OID_LEN];
243 struct variable compat_var, *cvp = &compat_var;
248 WriteMethod *write_method = NULL;
250 u_char *access = NULL;
251 netsnmp_old_api_cache *cacheptr;
252 netsnmp_agent_session *oldasp = NULL;
254 vp = (struct variable *) handler->myvoid;
257 * create old variable structure with right information
259 memcpy(cvp->name, reginfo->rootoid,
260 reginfo->rootoid_len * sizeof(oid));
261 cvp->namelen = reginfo->rootoid_len;
262 cvp->type = vp->type;
263 cvp->magic = vp->magic;
265 cvp->findVar = vp->findVar;
267 switch (reqinfo->mode) {
273 for (; requests; requests = requests->next) {
275 #if MIB_CLIENTS_ARE_EVIL
276 savelen = requests->requestvb->name_length;
277 memcpy(save, requests->requestvb->name, savelen * sizeof(oid));
280 switch (reqinfo->mode) {
283 case MODE_SET_RESERVE1:
285 * Actually call the old mib-module function
287 if (vp && vp->findVar)
288 access = (*(vp->findVar)) (cvp, requests->requestvb->name,
289 &(requests->requestvb->
290 name_length), exact, &len,
296 if (IS_DELEGATED(cvp->type)) {
297 add_method = (AddVarMethod *) statP;
298 requests->delayed = 1;
300 continue; /* WWW: This may not get to the right place */
305 * WWW: end range checking
311 if (reqinfo->mode != MODE_SET_RESERVE1)
312 snmp_set_var_typed_value(requests->requestvb,
313 cvp->type, access, len);
318 #if MIB_CLIENTS_ARE_EVIL
319 if (access == NULL) {
320 if (netsnmp_oid_equals(requests->requestvb->name,
321 requests->requestvb->name_length,
322 save, savelen) != 0) {
323 DEBUGMSGTL(("old_api", "evil_client: %s\n",
324 reginfo->handlerName));
325 memcpy(requests->requestvb->name, save,
326 savelen * sizeof(oid));
327 requests->requestvb->name_length = savelen;
334 * AAA: fall through for everything that is a set (see BBB)
336 if (reqinfo->mode != MODE_SET_RESERVE1)
339 cacheptr = SNMP_MALLOC_TYPEDEF(netsnmp_old_api_cache);
341 return netsnmp_set_request_error(reqinfo, requests,
342 SNMP_ERR_RESOURCEUNAVAILABLE);
343 cacheptr->data = access;
344 cacheptr->write_method = write_method;
345 netsnmp_request_add_list_data(requests,
346 netsnmp_create_data_list
347 (OLD_API_NAME, cacheptr, free));
349 * BBB: fall through for everything that is a set (see AAA)
354 * WWW: explicitly list the SET conditions
357 * (the rest of the) SET contions
360 (netsnmp_old_api_cache *)
361 netsnmp_request_get_list_data(requests, OLD_API_NAME);
363 if (cacheptr == NULL || cacheptr->write_method == NULL) {
365 * WWW: try to set ourselves if possible?
367 return netsnmp_set_request_error(reqinfo, requests,
368 SNMP_ERR_NOTWRITABLE);
371 oldasp = netsnmp_get_current_agent_session();
372 set_current_agent_session(reqinfo->asp);
374 (*(cacheptr->write_method)) (reqinfo->mode,
375 requests->requestvb->val.
377 requests->requestvb->type,
378 requests->requestvb->val_len,
380 requests->requestvb->name,
381 requests->requestvb->
383 set_current_agent_session(oldasp);
385 if (status != SNMP_ERR_NOERROR) {
386 netsnmp_set_request_error(reqinfo, requests, status);
390 * clean up is done by the automatic freeing of the
391 * cache stored in the request.
397 return SNMP_ERR_NOERROR;
405 static netsnmp_agent_session *current_agent_session = NULL;
406 netsnmp_agent_session *
407 netsnmp_get_current_agent_session()
409 return current_agent_session;
416 set_current_agent_session(netsnmp_agent_session *asp)
418 current_agent_session = asp;