net-snmp 5.7
|
00001 #include <net-snmp/net-snmp-config.h> 00002 00003 #include <net-snmp/net-snmp-includes.h> 00004 #include <net-snmp/agent/net-snmp-agent-includes.h> 00005 00006 #include <net-snmp/agent/old_api.h> 00007 00008 #if HAVE_STRING_H 00009 #include <string.h> 00010 #else 00011 #include <strings.h> 00012 #endif 00013 00014 #include <net-snmp/agent/agent_callbacks.h> 00015 00016 #include <stddef.h> 00017 00018 #define MIB_CLIENTS_ARE_EVIL 1 00019 00020 #ifdef HAVE_DMALLOC_H 00021 static void free_wrapper(void * p) 00022 { 00023 free(p); 00024 } 00025 #else 00026 #define free_wrapper free 00027 #endif 00028 00029 /* 00030 * don't use these! 00031 */ 00032 void set_current_agent_session(netsnmp_agent_session *asp); 00033 netsnmp_agent_session *netsnmp_get_current_agent_session(void); 00034 00048 netsnmp_mib_handler * 00049 get_old_api_handler(void) 00050 { 00051 return netsnmp_create_handler("old_api", netsnmp_old_api_helper); 00052 } 00053 00054 struct variable * 00055 netsnmp_duplicate_variable(struct variable *var) 00056 { 00057 struct variable *var2 = NULL; 00058 00059 if (var) { 00060 const int varsize = offsetof(struct variable, name) + var->namelen * sizeof(var->name[0]); 00061 var2 = malloc(varsize); 00062 if (var2) 00063 memcpy(var2, var, varsize); 00064 } 00065 return var2; 00066 } 00067 00072 int 00073 netsnmp_register_old_api(const char *moduleName, 00074 struct variable *var, 00075 size_t varsize, 00076 size_t numvars, 00077 const oid * mibloc, 00078 size_t mibloclen, 00079 int priority, 00080 int range_subid, 00081 oid range_ubound, 00082 netsnmp_session * ss, 00083 const char *context, int timeout, int flags) 00084 { 00085 00086 unsigned int i; 00087 00088 /* 00089 * register all subtree nodes 00090 */ 00091 for (i = 0; i < numvars; i++) { 00092 struct variable *vp; 00093 netsnmp_handler_registration *reginfo = 00094 SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration); 00095 if (reginfo == NULL) 00096 return SNMP_ERR_GENERR; 00097 00098 vp = netsnmp_duplicate_variable((struct variable *) 00099 ((char *) var + varsize * i)); 00100 00101 reginfo->handler = get_old_api_handler(); 00102 reginfo->handlerName = strdup(moduleName); 00103 reginfo->rootoid_len = (mibloclen + vp->namelen); 00104 reginfo->rootoid = 00105 (oid *) malloc(reginfo->rootoid_len * sizeof(oid)); 00106 if (reginfo->rootoid == NULL) 00107 return SNMP_ERR_GENERR; 00108 00109 memcpy(reginfo->rootoid, mibloc, mibloclen * sizeof(oid)); 00110 memcpy(reginfo->rootoid + mibloclen, vp->name, vp->namelen 00111 * sizeof(oid)); 00112 reginfo->handler->myvoid = (void *) vp; 00113 reginfo->handler->data_clone 00114 = (void *(*)(void *))netsnmp_duplicate_variable; 00115 reginfo->handler->data_free = free; 00116 00117 reginfo->priority = priority; 00118 reginfo->range_subid = range_subid; 00119 00120 reginfo->range_ubound = range_ubound; 00121 reginfo->timeout = timeout; 00122 reginfo->contextName = (context) ? strdup(context) : NULL; 00123 reginfo->modes = HANDLER_CAN_RWRITE; 00124 00125 /* 00126 * register ourselves in the mib tree 00127 */ 00128 if (netsnmp_register_handler(reginfo) != MIB_REGISTERED_OK) { 00130 SNMP_FREE(vp); 00131 } 00132 } 00133 return SNMPERR_SUCCESS; 00134 } 00135 00137 int 00138 netsnmp_register_mib_table_row(const char *moduleName, 00139 struct variable *var, 00140 size_t varsize, 00141 size_t numvars, 00142 oid * mibloc, 00143 size_t mibloclen, 00144 int priority, 00145 int var_subid, 00146 netsnmp_session * ss, 00147 const char *context, int timeout, int flags) 00148 { 00149 unsigned int i = 0, rc = 0; 00150 oid ubound = 0; 00151 00152 for (i = 0; i < numvars; i++) { 00153 struct variable *vr = 00154 (struct variable *) ((char *) var + (i * varsize)); 00155 netsnmp_handler_registration *r; 00156 if ( var_subid > (int)mibloclen ) { 00157 break; /* doesn't make sense */ 00158 } 00159 r = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration); 00160 00161 if (r == NULL) { 00162 /* 00163 * Unregister whatever we have registered so far, and 00164 * return an error. 00165 */ 00166 rc = MIB_REGISTRATION_FAILED; 00167 break; 00168 } 00169 memset(r, 0, sizeof(netsnmp_handler_registration)); 00170 00171 r->handler = get_old_api_handler(); 00172 r->handlerName = strdup(moduleName); 00173 00174 if (r->handlerName == NULL) { 00175 netsnmp_handler_registration_free(r); 00176 break; 00177 } 00178 00179 r->rootoid_len = mibloclen; 00180 r->rootoid = (oid *) malloc(r->rootoid_len * sizeof(oid)); 00181 00182 if (r->rootoid == NULL) { 00183 netsnmp_handler_registration_free(r); 00184 rc = MIB_REGISTRATION_FAILED; 00185 break; 00186 } 00187 memcpy(r->rootoid, mibloc, mibloclen * sizeof(oid)); 00188 memcpy((u_char *) (r->rootoid + (var_subid - vr->namelen)), vr->name, 00189 vr->namelen * sizeof(oid)); 00190 DEBUGMSGTL(("netsnmp_register_mib_table_row", "rootoid ")); 00191 DEBUGMSGOID(("netsnmp_register_mib_table_row", r->rootoid, 00192 r->rootoid_len)); 00193 DEBUGMSG(("netsnmp_register_mib_table_row", "(%d)\n", 00194 (var_subid - vr->namelen))); 00195 r->handler->myvoid = netsnmp_duplicate_variable(vr); 00196 r->handler->data_clone = (void *(*)(void *))netsnmp_duplicate_variable; 00197 r->handler->data_free = free; 00198 00199 if (r->handler->myvoid == NULL) { 00200 netsnmp_handler_registration_free(r); 00201 rc = MIB_REGISTRATION_FAILED; 00202 break; 00203 } 00204 00205 r->contextName = (context) ? strdup(context) : NULL; 00206 00207 if (context != NULL && r->contextName == NULL) { 00208 netsnmp_handler_registration_free(r); 00209 rc = MIB_REGISTRATION_FAILED; 00210 break; 00211 } 00212 00213 r->priority = priority; 00214 r->range_subid = 0; /* var_subid; */ 00215 r->range_ubound = 0; /* range_ubound; */ 00216 r->timeout = timeout; 00217 r->modes = HANDLER_CAN_RWRITE; 00218 00219 /* 00220 * Register this column and row 00221 */ 00222 if ((rc = 00223 netsnmp_register_handler_nocallback(r)) != 00224 MIB_REGISTERED_OK) { 00225 DEBUGMSGTL(("netsnmp_register_mib_table_row", 00226 "register failed %d\n", rc)); 00227 netsnmp_handler_registration_free(r); 00228 break; 00229 } 00230 00231 if (vr->namelen > 0) { 00232 if (vr->name[vr->namelen - 1] > ubound) { 00233 ubound = vr->name[vr->namelen - 1]; 00234 } 00235 } 00236 } 00237 00238 if (rc == MIB_REGISTERED_OK) { 00239 struct register_parameters reg_parms; 00240 00241 reg_parms.name = mibloc; 00242 reg_parms.namelen = mibloclen; 00243 reg_parms.priority = priority; 00244 reg_parms.flags = (u_char) flags; 00245 reg_parms.range_subid = var_subid; 00246 reg_parms.range_ubound = ubound; 00247 reg_parms.timeout = timeout; 00248 reg_parms.contextName = context; 00249 rc = snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, 00250 SNMPD_CALLBACK_REGISTER_OID, ®_parms); 00251 } 00252 00253 return rc; 00254 } 00255 00257 int 00258 netsnmp_old_api_helper(netsnmp_mib_handler *handler, 00259 netsnmp_handler_registration *reginfo, 00260 netsnmp_agent_request_info *reqinfo, 00261 netsnmp_request_info *requests) 00262 { 00263 00264 #if MIB_CLIENTS_ARE_EVIL 00265 oid save[MAX_OID_LEN]; 00266 size_t savelen = 0; 00267 #endif 00268 struct variable compat_var, *cvp = &compat_var; 00269 int exact = 1; 00270 int status; 00271 00272 struct variable *vp; 00273 netsnmp_old_api_cache *cacheptr; 00274 netsnmp_agent_session *oldasp = NULL; 00275 u_char *access = NULL; 00276 WriteMethod *write_method = NULL; 00277 size_t len; 00278 size_t tmp_len; 00279 oid tmp_name[MAX_OID_LEN]; 00280 00281 vp = (struct variable *) handler->myvoid; 00282 00283 /* 00284 * create old variable structure with right information 00285 */ 00286 memcpy(cvp->name, reginfo->rootoid, 00287 reginfo->rootoid_len * sizeof(oid)); 00288 cvp->namelen = reginfo->rootoid_len; 00289 cvp->type = vp->type; 00290 cvp->magic = vp->magic; 00291 cvp->acl = vp->acl; 00292 cvp->findVar = vp->findVar; 00293 00294 switch (reqinfo->mode) { 00295 case MODE_GETNEXT: 00296 case MODE_GETBULK: 00297 exact = 0; 00298 } 00299 00300 for (; requests; requests = requests->next) { 00301 00302 #if MIB_CLIENTS_ARE_EVIL 00303 savelen = requests->requestvb->name_length; 00304 memcpy(save, requests->requestvb->name, savelen * sizeof(oid)); 00305 #endif 00306 00307 switch (reqinfo->mode) { 00308 case MODE_GET: 00309 case MODE_GETNEXT: 00310 #ifndef NETSNMP_NO_WRITE_SUPPORT 00311 case MODE_SET_RESERVE1: 00312 #endif /* !NETSNMP_NO_WRITE_SUPPORT */ 00313 /* 00314 * Actually call the old mib-module function 00315 */ 00316 if (vp && vp->findVar) { 00317 memcpy(tmp_name, requests->requestvb->name, 00318 requests->requestvb->name_length*sizeof(oid)); 00319 tmp_len = requests->requestvb->name_length; 00320 access = (*(vp->findVar)) (cvp, tmp_name, &tmp_len, 00321 exact, &len, &write_method); 00322 snmp_set_var_objid( requests->requestvb, tmp_name, tmp_len ); 00323 } 00324 else 00325 access = NULL; 00326 00327 #ifdef WWW_FIX 00328 if (IS_DELEGATED(cvp->type)) { 00329 add_method = (AddVarMethod *) statP; 00330 requests->delayed = 1; 00331 have_delegated = 1; 00332 continue; /* WWW: This may not get to the right place */ 00333 } 00334 #endif 00335 00336 /* 00337 * WWW: end range checking 00338 */ 00339 if (access) { 00340 /* 00341 * result returned 00342 */ 00343 #ifndef NETSNMP_NO_WRITE_SUPPORT 00344 if (reqinfo->mode != MODE_SET_RESERVE1) 00345 #endif /* !NETSNMP_NO_WRITE_SUPPORT */ 00346 snmp_set_var_typed_value(requests->requestvb, 00347 cvp->type, access, len); 00348 } else { 00349 /* 00350 * no result returned 00351 */ 00352 #if MIB_CLIENTS_ARE_EVIL 00353 if (access == NULL) { 00354 if (netsnmp_oid_equals(requests->requestvb->name, 00355 requests->requestvb->name_length, 00356 save, savelen) != 0) { 00357 DEBUGMSGTL(("old_api", "evil_client: %s\n", 00358 reginfo->handlerName)); 00359 memcpy(requests->requestvb->name, save, 00360 savelen * sizeof(oid)); 00361 requests->requestvb->name_length = savelen; 00362 } 00363 } 00364 #endif 00365 } 00366 00367 /* 00368 * AAA: fall through for everything that is a set (see BBB) 00369 */ 00370 #ifndef NETSNMP_NO_WRITE_SUPPORT 00371 if (reqinfo->mode != MODE_SET_RESERVE1) 00372 #endif /* !NETSNMP_NO_WRITE_SUPPORT */ 00373 break; 00374 00375 cacheptr = SNMP_MALLOC_TYPEDEF(netsnmp_old_api_cache); 00376 if (!cacheptr) 00377 return netsnmp_set_request_error(reqinfo, requests, 00378 SNMP_ERR_RESOURCEUNAVAILABLE); 00379 cacheptr->data = access; 00380 cacheptr->write_method = write_method; 00381 write_method = NULL; 00382 netsnmp_request_add_list_data(requests, 00383 netsnmp_create_data_list 00384 (OLD_API_NAME, cacheptr, 00385 &free_wrapper)); 00386 /* 00387 * BBB: fall through for everything that is a set (see AAA) 00388 */ 00389 00390 default: 00391 /* 00392 * WWW: explicitly list the SET conditions 00393 */ 00394 /* 00395 * (the rest of the) SET contions 00396 */ 00397 cacheptr = 00398 (netsnmp_old_api_cache *) 00399 netsnmp_request_get_list_data(requests, OLD_API_NAME); 00400 00401 if (cacheptr == NULL || cacheptr->write_method == NULL) { 00402 /* 00403 * WWW: try to set ourselves if possible? 00404 */ 00405 return netsnmp_set_request_error(reqinfo, requests, 00406 SNMP_ERR_NOTWRITABLE); 00407 } 00408 00409 oldasp = netsnmp_get_current_agent_session(); 00410 set_current_agent_session(reqinfo->asp); 00411 status = 00412 (*(cacheptr->write_method)) (reqinfo->mode, 00413 requests->requestvb->val. 00414 string, 00415 requests->requestvb->type, 00416 requests->requestvb->val_len, 00417 cacheptr->data, 00418 requests->requestvb->name, 00419 requests->requestvb-> 00420 name_length); 00421 set_current_agent_session(oldasp); 00422 00423 if (status != SNMP_ERR_NOERROR) { 00424 netsnmp_set_request_error(reqinfo, requests, status); 00425 } 00426 00427 /* 00428 * clean up is done by the automatic freeing of the 00429 * cache stored in the request. 00430 */ 00431 00432 break; 00433 } 00434 } 00435 return SNMP_ERR_NOERROR; 00436 } 00437 00440 /* 00441 * don't use this! 00442 */ 00443 static netsnmp_agent_session *current_agent_session = NULL; 00444 netsnmp_agent_session * 00445 netsnmp_get_current_agent_session(void) 00446 { 00447 return current_agent_session; 00448 } 00449 00450 /* 00451 * don't use this! 00452 */ 00453 void 00454 set_current_agent_session(netsnmp_agent_session *asp) 00455 { 00456 current_agent_session = asp; 00457 }