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