net-snmp 5.7
|
00001 #include <net-snmp/net-snmp-config.h> 00002 00003 #include <net-snmp/net-snmp-features.h> 00004 #include <net-snmp/net-snmp-includes.h> 00005 #include <net-snmp/agent/net-snmp-agent-includes.h> 00006 00007 netsnmp_feature_provide(stash_cache) 00008 netsnmp_feature_child_of(stash_cache, mib_helpers) 00009 #ifdef NETSNMP_FEATURE_REQUIRE_STASH_CACHE 00010 netsnmp_feature_require(oid_stash) 00011 netsnmp_feature_require(oid_stash_iterate) 00012 netsnmp_feature_require(oid_stash_get_data) 00013 #endif 00014 00015 #ifndef NETSNMP_FEATURE_REMOVE_STASH_CACHE 00016 #include <net-snmp/agent/stash_to_next.h> 00017 00018 #include <net-snmp/agent/stash_cache.h> 00019 00020 extern NetsnmpCacheLoad _netsnmp_stash_cache_load; 00021 extern NetsnmpCacheFree _netsnmp_stash_cache_free; 00022 00034 netsnmp_stash_cache_info * 00035 netsnmp_get_new_stash_cache(void) 00036 { 00037 netsnmp_stash_cache_info *cinfo; 00038 00039 cinfo = SNMP_MALLOC_TYPEDEF(netsnmp_stash_cache_info); 00040 if (cinfo != NULL) 00041 cinfo->cache_length = 30; 00042 return cinfo; 00043 } 00044 00049 netsnmp_mib_handler * 00050 netsnmp_get_timed_bare_stash_cache_handler(int timeout, oid *rootoid, size_t rootoid_len) 00051 { 00052 netsnmp_mib_handler *handler; 00053 netsnmp_cache *cinfo; 00054 00055 cinfo = netsnmp_cache_create( timeout, _netsnmp_stash_cache_load, 00056 _netsnmp_stash_cache_free, rootoid, rootoid_len ); 00057 00058 if (!cinfo) 00059 return NULL; 00060 00061 handler = netsnmp_cache_handler_get( cinfo ); 00062 if (!handler) { 00063 free(cinfo); 00064 return NULL; 00065 } 00066 00067 handler->next = netsnmp_create_handler("stash_cache", netsnmp_stash_cache_helper); 00068 if (!handler->next) { 00069 netsnmp_handler_free(handler); 00070 free(cinfo); 00071 return NULL; 00072 } 00073 00074 handler->myvoid = cinfo; 00075 netsnmp_cache_handler_owns_cache(handler); 00076 00077 return handler; 00078 } 00079 00084 netsnmp_mib_handler * 00085 netsnmp_get_bare_stash_cache_handler(void) 00086 { 00087 return netsnmp_get_timed_bare_stash_cache_handler( 30, NULL, 0 ); 00088 } 00089 00093 netsnmp_mib_handler * 00094 netsnmp_get_stash_cache_handler(void) 00095 { 00096 netsnmp_mib_handler *handler = netsnmp_get_bare_stash_cache_handler(); 00097 if (handler && handler->next) { 00098 handler->next->next = netsnmp_get_stash_to_next_handler(); 00099 } 00100 return handler; 00101 } 00102 00106 netsnmp_mib_handler * 00107 netsnmp_get_timed_stash_cache_handler(int timeout, oid *rootoid, size_t rootoid_len) 00108 { 00109 netsnmp_mib_handler *handler = 00110 netsnmp_get_timed_bare_stash_cache_handler(timeout, rootoid, rootoid_len); 00111 if (handler && handler->next) { 00112 handler->next->next = netsnmp_get_stash_to_next_handler(); 00113 } 00114 return handler; 00115 } 00116 00118 netsnmp_oid_stash_node ** 00119 netsnmp_extract_stash_cache(netsnmp_agent_request_info *reqinfo) 00120 { 00121 return (netsnmp_oid_stash_node**)netsnmp_agent_get_list_data(reqinfo, STASH_CACHE_NAME); 00122 } 00123 00124 00126 int 00127 netsnmp_stash_cache_helper(netsnmp_mib_handler *handler, 00128 netsnmp_handler_registration *reginfo, 00129 netsnmp_agent_request_info *reqinfo, 00130 netsnmp_request_info *requests) 00131 { 00132 netsnmp_cache *cache; 00133 netsnmp_stash_cache_info *cinfo; 00134 netsnmp_oid_stash_node *cnode; 00135 netsnmp_variable_list *cdata; 00136 netsnmp_request_info *request; 00137 00138 DEBUGMSGTL(("helper:stash_cache", "Got request\n")); 00139 00140 cache = netsnmp_cache_reqinfo_extract( reqinfo, reginfo->handlerName ); 00141 if (!cache) { 00142 DEBUGMSGTL(("helper:stash_cache", "No cache structure\n")); 00143 return SNMP_ERR_GENERR; 00144 } 00145 cinfo = (netsnmp_stash_cache_info *) cache->magic; 00146 00147 switch (reqinfo->mode) { 00148 00149 case MODE_GET: 00150 DEBUGMSGTL(("helper:stash_cache", "Processing GET request\n")); 00151 for(request = requests; request; request = request->next) { 00152 cdata = (netsnmp_variable_list*) 00153 netsnmp_oid_stash_get_data(cinfo->cache, 00154 requests->requestvb->name, 00155 requests->requestvb->name_length); 00156 if (cdata && cdata->val.string && cdata->val_len) { 00157 DEBUGMSGTL(("helper:stash_cache", "Found cached GET varbind\n")); 00158 DEBUGMSGOID(("helper:stash_cache", cdata->name, cdata->name_length)); 00159 DEBUGMSG(("helper:stash_cache", "\n")); 00160 snmp_set_var_typed_value(request->requestvb, cdata->type, 00161 cdata->val.string, cdata->val_len); 00162 } 00163 } 00164 break; 00165 00166 case MODE_GETNEXT: 00167 DEBUGMSGTL(("helper:stash_cache", "Processing GETNEXT request\n")); 00168 for(request = requests; request; request = request->next) { 00169 cnode = 00170 netsnmp_oid_stash_getnext_node(cinfo->cache, 00171 requests->requestvb->name, 00172 requests->requestvb->name_length); 00173 if (cnode && cnode->thedata) { 00174 cdata = (netsnmp_variable_list*)cnode->thedata; 00175 if (cdata->val.string && cdata->name && cdata->name_length) { 00176 DEBUGMSGTL(("helper:stash_cache", "Found cached GETNEXT varbind\n")); 00177 DEBUGMSGOID(("helper:stash_cache", cdata->name, cdata->name_length)); 00178 DEBUGMSG(("helper:stash_cache", "\n")); 00179 snmp_set_var_typed_value(request->requestvb, cdata->type, 00180 cdata->val.string, cdata->val_len); 00181 snmp_set_var_objid(request->requestvb, cdata->name, 00182 cdata->name_length); 00183 } 00184 } 00185 } 00186 break; 00187 00188 default: 00189 cinfo->cache_valid = 0; 00190 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00191 requests); 00192 } 00193 00194 return SNMP_ERR_NOERROR; 00195 } 00196 00199 int 00200 _netsnmp_stash_cache_load( netsnmp_cache *cache, void *magic ) 00201 { 00202 netsnmp_mib_handler *handler = cache->cache_hint->handler; 00203 netsnmp_handler_registration *reginfo = cache->cache_hint->reginfo; 00204 netsnmp_agent_request_info *reqinfo = cache->cache_hint->reqinfo; 00205 netsnmp_request_info *requests = cache->cache_hint->requests; 00206 netsnmp_stash_cache_info *cinfo = (netsnmp_stash_cache_info*) magic; 00207 int old_mode; 00208 int ret; 00209 00210 if (!cinfo) { 00211 cinfo = netsnmp_get_new_stash_cache(); 00212 cache->magic = cinfo; 00213 } 00214 00215 /* change modes to the GET_STASH mode */ 00216 old_mode = reqinfo->mode; 00217 reqinfo->mode = MODE_GET_STASH; 00218 netsnmp_agent_add_list_data(reqinfo, 00219 netsnmp_create_data_list(STASH_CACHE_NAME, 00220 &cinfo->cache, NULL)); 00221 00222 /* have the next handler fill stuff in and switch modes back */ 00223 ret = netsnmp_call_next_handler(handler->next, reginfo, reqinfo, requests); 00224 reqinfo->mode = old_mode; 00225 00226 return ret; 00227 } 00228 00229 void 00230 _netsnmp_stash_cache_free( netsnmp_cache *cache, void *magic ) 00231 { 00232 netsnmp_stash_cache_info *cinfo = (netsnmp_stash_cache_info*) magic; 00233 netsnmp_oid_stash_free(&cinfo->cache, 00234 (NetSNMPStashFreeNode *) snmp_free_var); 00235 return; 00236 } 00237 00242 void 00243 netsnmp_init_stash_cache_helper(void) 00244 { 00245 netsnmp_register_handler_by_name("stash_cache", 00246 netsnmp_get_stash_cache_handler()); 00247 } 00250 #else /* NETSNMP_FEATURE_REMOVE_STASH_CACHE */ 00251 netsnmp_feature_unused(stash_cache); 00252 #endif /* NETSNMP_FEATURE_REMOVE_STASH_CACHE */