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