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