00001 #include <config.h> 00002 00003 #include <sys/types.h> 00004 00005 #if HAVE_STRING_H 00006 #include <string.h> 00007 #endif 00008 00009 #include <mibincl.h> 00010 #include <data_list.h> 00011 #include <snmp_agent.h> 00012 #include <agent_registry.h> 00013 #include <agent_handler.h> 00014 /***********************************************************************/ 00015 /* New Handler based API */ 00016 /***********************************************************************/ 00017 00019 int 00020 register_handler(handler_registration *reginfo) { 00021 mib_handler *handler; 00022 DEBUGIF("handler::register") { 00023 DEBUGMSGTL(("handler::register", "Registering")); 00024 for(handler = reginfo->handler; handler; 00025 handler = handler->next) { 00026 DEBUGMSG(("handler::register"," %s", handler->handler_name)); 00027 } 00028 00029 DEBUGMSG(("handler::register", " at ")); 00030 if (reginfo->rootoid) { 00031 DEBUGMSGOID(("handler::register", reginfo->rootoid, 00032 reginfo->rootoid_len)); 00033 } else { 00034 DEBUGMSG(("handler::register", "[null]")); 00035 } 00036 DEBUGMSG(("handler::register", "\n")); 00037 } 00038 00039 /* don't let them register for absolutely nothing. Probably a mistake */ 00040 if (0 == reginfo->modes) { 00041 reginfo->modes = HANDLER_CAN_DEFAULT; 00042 } 00043 00044 return register_mib_context2(reginfo->handler->handler_name, 00045 NULL, 0, 0, 00046 reginfo->rootoid, reginfo->rootoid_len, 00047 reginfo->priority, 00048 reginfo->range_subid, reginfo->range_ubound, 00049 NULL, 00050 reginfo->contextName, 00051 reginfo->timeout, 00052 0, reginfo); 00053 } 00054 00059 int 00060 inject_handler(handler_registration *reginfo, mib_handler *handler) { 00061 DEBUGMSGTL(("handler:inject", "injecting %s before %s\n", \ 00062 handler->handler_name, reginfo->handler->handler_name)); 00063 handler->next = reginfo->handler; 00064 if (reginfo->handler) 00065 reginfo->handler->prev = handler; 00066 reginfo->handler = handler; 00067 return SNMPERR_SUCCESS; 00068 } 00069 00070 int call_handlers(handler_registration *reginfo, 00071 agent_request_info *reqinfo, 00072 request_info *requests) { 00073 NodeHandler *nh; 00074 int status; 00075 00076 if (reginfo == NULL || reqinfo == NULL || requests == NULL) { 00077 snmp_log(LOG_ERR, "call_handlers() called illegally"); 00078 return SNMP_ERR_GENERR; 00079 } 00080 00081 if (reginfo->handler == NULL) { 00082 snmp_log(LOG_ERR, "no handler specified."); 00083 return SNMP_ERR_GENERR; 00084 } 00085 00086 switch(reqinfo->mode) { 00087 case MODE_GET: 00088 case MODE_GETNEXT: 00089 if (!(reginfo->modes & HANDLER_CAN_GETANDGETNEXT)) 00090 return SNMP_ERR_NOERROR; /* legal */ 00091 break; 00092 00093 case MODE_SET_RESERVE1: 00094 case MODE_SET_RESERVE2: 00095 case MODE_SET_ACTION: 00096 case MODE_SET_COMMIT: 00097 case MODE_SET_FREE: 00098 case MODE_SET_UNDO: 00099 if (!(reginfo->modes & HANDLER_CAN_SET)) { 00100 for(; requests; requests = requests->next) { 00101 set_request_error(reqinfo, requests, SNMP_ERR_NOTWRITABLE); 00102 } 00103 return SNMP_ERR_NOERROR; 00104 } 00105 break; 00106 00107 case MODE_GETBULK: 00108 if (!(reginfo->modes & HANDLER_CAN_GETBULK)) 00109 return SNMP_ERR_NOERROR; /* XXXWWW: should never get 00110 here after we force a 00111 getbulk->getnext helper on 00112 them during registration 00113 process. */ 00114 break; 00115 00116 default: 00117 snmp_log(LOG_ERR, "unknown mode in call_handlers! bug!\n"); 00118 return SNMP_ERR_GENERR; 00119 } 00120 DEBUGMSGTL(("handler:calling", "calling main handler %s\n", 00121 reginfo->handler->handler_name)); 00122 00123 nh = reginfo->handler->access_method; 00124 if (!nh) { 00125 snmp_log(LOG_ERR, "no handler access method specified."); 00126 return SNMP_ERR_GENERR; 00127 } 00128 00129 /* XXX: define acceptable return statuses */ 00130 status = (*nh)(reginfo->handler, reginfo, reqinfo, requests); 00131 00132 return status; 00133 } 00134 00136 inline int call_handler(mib_handler *next_handler, 00137 handler_registration *reginfo, 00138 agent_request_info *reqinfo, 00139 request_info *requests) { 00140 NodeHandler *nh; 00141 int ret; 00142 00143 if (next_handler == NULL || reginfo == NULL || reqinfo == NULL || 00144 requests == NULL) { 00145 snmp_log(LOG_ERR, "call_next_handler() called illegally"); 00146 return SNMP_ERR_GENERR; 00147 } 00148 00149 nh = next_handler->access_method; 00150 if (!nh) { 00151 snmp_log(LOG_ERR, "no access method specified in handler %s.", 00152 next_handler->handler_name); 00153 return SNMP_ERR_GENERR; 00154 } 00155 00156 DEBUGMSGTL(("handler:calling", "calling handler %s\n", 00157 next_handler->handler_name)); 00158 00159 ret = (*nh)(next_handler, reginfo, reqinfo, requests); 00160 00161 DEBUGMSGTL(("handler:returned", "handler %s returned %d\n", 00162 next_handler->handler_name, ret)); 00163 00164 return ret; 00165 } 00166 00169 inline int call_next_handler(mib_handler *current, 00170 handler_registration *reginfo, 00171 agent_request_info *reqinfo, 00172 request_info *requests) { 00173 00174 if (current == NULL || reginfo == NULL || reqinfo == NULL || 00175 requests == NULL) { 00176 snmp_log(LOG_ERR, "call_next_handler() called illegally"); 00177 return SNMP_ERR_GENERR; 00178 } 00179 00180 return call_handler(current->next, reginfo, reqinfo, requests); 00181 } 00182 00184 mib_handler * 00185 create_handler(const char *name, NodeHandler *handler_access_method) { 00186 mib_handler *ret = SNMP_MALLOC_TYPEDEF(mib_handler); 00187 ret->handler_name = strdup(name); 00188 ret->access_method = handler_access_method; 00189 return ret; 00190 } 00191 00196 handler_registration * 00197 create_handler_registration(const char *name, 00198 NodeHandler *handler_access_method, 00199 oid *reg_oid, size_t reg_oid_len, 00200 int modes) { 00201 handler_registration *the_reg; 00202 the_reg = SNMP_MALLOC_TYPEDEF(handler_registration); 00203 if (!the_reg) 00204 return NULL; 00205 00206 if (modes) 00207 the_reg->modes = modes; 00208 else 00209 the_reg->modes = HANDLER_CAN_DEFAULT; 00210 00211 the_reg->handler = create_handler(name, handler_access_method); 00212 memdup(&the_reg->rootoid, reg_oid, reg_oid_len * sizeof(oid)); 00213 the_reg->rootoid_len = reg_oid_len; 00214 return the_reg; 00215 } 00216 00220 inline delegated_cache * 00221 create_delegated_cache(mib_handler *handler, 00222 handler_registration *reginfo, 00223 agent_request_info *reqinfo, 00224 request_info *requests, 00225 void *localinfo) { 00226 delegated_cache *ret; 00227 00228 ret = SNMP_MALLOC_TYPEDEF(delegated_cache); 00229 if (ret) { 00230 ret->transaction_id = reqinfo->asp->pdu->transid; 00231 ret->handler = handler; 00232 ret->reginfo = reginfo; 00233 ret->reqinfo = reqinfo; 00234 ret->requests = requests; 00235 ret->localinfo = localinfo; 00236 } 00237 return ret; 00238 } 00239 00243 inline delegated_cache * 00244 handler_check_cache(delegated_cache *dcache) 00245 { 00246 if (!dcache) 00247 return dcache; 00248 00249 if (check_transaction_id(dcache->transaction_id) == SNMPERR_SUCCESS) 00250 return dcache; 00251 00252 return NULL; 00253 } 00254 00256 void 00257 handler_mark_requests_as_delegated(request_info *requests, int isdelegated) 00258 { 00259 while(requests) { 00260 requests->delegated = isdelegated; 00261 requests = requests->next; 00262 } 00263 } 00264 00265 inline void 00266 request_add_list_data(request_info *request, data_list *node) 00267 { 00268 if (request) { 00269 if (request->parent_data) 00270 add_list_data(&request->parent_data, node); 00271 else 00272 request->parent_data = node; 00273 } 00274 } 00275 00276 inline void * 00277 request_get_list_data(request_info *request, const char *name) 00278 { 00279 if (request) 00280 return get_list_data(request->parent_data,name); 00281 return NULL; 00282 } 00283 00284 inline void 00285 free_request_data_set(request_info *request) 00286 { 00287 if (request) 00288 free_list_data(request->parent_data); 00289 } 00290 00291 inline void 00292 free_request_data_sets(request_info *request) 00293 { 00294 if (request) 00295 free_all_list_data(request->parent_data); 00296 } 00297 00299 mib_handler * 00300 find_handler_by_name(handler_registration *reginfo, char *name) 00301 { 00302 mib_handler *it; 00303 for(it = reginfo->handler; it; it = it->next) { 00304 if (strcmp(it->handler_name, name) == 0) { 00305 return it; 00306 } 00307 } 00308 return NULL; 00309 } 00310 00315 void * 00316 find_handler_data_by_name(handler_registration *reginfo, 00317 char *name) 00318 { 00319 mib_handler *it = find_handler_by_name(reginfo, name); 00320 if (it) 00321 return it->myvoid; 00322 return NULL; 00323 } 00324
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.