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
1.2.11 written by Dimitri van Heesch,
© 1997-2001
[an error occurred while processing this directive]
[an error occurred while processing this directive]
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.