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/stash_cache.h> 00013 #include <net-snmp/agent/stash_to_next.h> 00014 00015 extern NetsnmpCacheLoad _netsnmp_stash_cache_load; 00016 extern NetsnmpCacheFree _netsnmp_stash_cache_free; 00017 00029 netsnmp_stash_cache_info * 00030 netsnmp_get_new_stash_cache(void) 00031 { 00032 netsnmp_stash_cache_info *cinfo; 00033 00034 cinfo = SNMP_MALLOC_TYPEDEF(netsnmp_stash_cache_info); 00035 cinfo->cache_length = 30; 00036 return cinfo; 00037 } 00038 00043 netsnmp_mib_handler * 00044 netsnmp_get_timed_bare_stash_cache_handler(int timeout, oid *rootoid, size_t rootoid_len) 00045 { 00046 netsnmp_mib_handler *handler; 00047 netsnmp_cache *cinfo; 00048 00049 cinfo = netsnmp_cache_create( timeout, _netsnmp_stash_cache_load, 00050 _netsnmp_stash_cache_free, rootoid, rootoid_len ); 00051 00052 if (!cinfo) 00053 return NULL; 00054 00055 handler = netsnmp_cache_handler_get( cinfo ); 00056 if (!handler) { 00057 free(cinfo); 00058 return NULL; 00059 } 00060 00061 handler->next = netsnmp_create_handler("stash_cache", netsnmp_stash_cache_helper); 00062 if (!handler->next) { 00063 netsnmp_handler_free(handler); 00064 free(cinfo); 00065 return NULL; 00066 } 00067 00068 handler->myvoid = cinfo; 00069 00070 return handler; 00071 } 00072 00077 netsnmp_mib_handler * 00078 netsnmp_get_bare_stash_cache_handler(void) 00079 { 00080 return netsnmp_get_timed_bare_stash_cache_handler( 30, NULL, 0 ); 00081 } 00082 00086 netsnmp_mib_handler * 00087 netsnmp_get_stash_cache_handler(void) 00088 { 00089 netsnmp_mib_handler *handler = netsnmp_get_bare_stash_cache_handler(); 00090 if (handler && handler->next) { 00091 handler->next->next = netsnmp_get_stash_to_next_handler(); 00092 } 00093 return handler; 00094 } 00095 00099 netsnmp_mib_handler * 00100 netsnmp_get_timed_stash_cache_handler(int timeout, oid *rootoid, size_t rootoid_len) 00101 { 00102 netsnmp_mib_handler *handler = 00103 netsnmp_get_timed_bare_stash_cache_handler(timeout, rootoid, rootoid_len); 00104 if (handler && handler->next) { 00105 handler->next->next = netsnmp_get_stash_to_next_handler(); 00106 } 00107 return handler; 00108 } 00109 00111 netsnmp_oid_stash_node ** 00112 netsnmp_extract_stash_cache(netsnmp_agent_request_info *reqinfo) 00113 { 00114 return netsnmp_agent_get_list_data(reqinfo, STASH_CACHE_NAME); 00115 } 00116 00117 00119 int 00120 netsnmp_stash_cache_helper(netsnmp_mib_handler *handler, 00121 netsnmp_handler_registration *reginfo, 00122 netsnmp_agent_request_info *reqinfo, 00123 netsnmp_request_info *requests) 00124 { 00125 netsnmp_cache *cache; 00126 netsnmp_stash_cache_info *cinfo; 00127 netsnmp_oid_stash_node *cnode; 00128 netsnmp_variable_list *cdata; 00129 netsnmp_request_info *request; 00130 00131 DEBUGMSGTL(("helper:stash_cache", "Got request\n")); 00132 00133 cache = netsnmp_cache_reqinfo_extract( reqinfo, reginfo->handlerName ); 00134 cinfo = (netsnmp_stash_cache_info *) cache->magic; 00135 00136 switch (reqinfo->mode) { 00137 00138 case MODE_GET: 00139 DEBUGMSGTL(("helper:stash_cache", "Processing GET request\n")); 00140 for(request = requests; request; request = request->next) { 00141 cdata = 00142 netsnmp_oid_stash_get_data(cinfo->cache, 00143 requests->requestvb->name, 00144 requests->requestvb->name_length); 00145 if (cdata && cdata->val.string && cdata->val_len) { 00146 DEBUGMSGTL(("helper:stash_cache", "Found cached GET varbind\n")); 00147 DEBUGMSGOID(("helper:stash_cache", cdata->name, cdata->name_length)); 00148 DEBUGMSG(("helper:stash_cache", "\n")); 00149 snmp_set_var_typed_value(request->requestvb, cdata->type, 00150 cdata->val.string, cdata->val_len); 00151 } 00152 } 00153 return SNMP_ERR_NOERROR; 00154 break; 00155 00156 case MODE_GETNEXT: 00157 DEBUGMSGTL(("helper:stash_cache", "Processing GETNEXT request\n")); 00158 for(request = requests; request; request = request->next) { 00159 cnode = 00160 netsnmp_oid_stash_getnext_node(cinfo->cache, 00161 requests->requestvb->name, 00162 requests->requestvb->name_length); 00163 if (cnode && cnode->thedata) { 00164 cdata = cnode->thedata; 00165 if (cdata->val.string && cdata->name && cdata->name_length) { 00166 DEBUGMSGTL(("helper:stash_cache", "Found cached GETNEXT varbind\n")); 00167 DEBUGMSGOID(("helper:stash_cache", cdata->name, cdata->name_length)); 00168 DEBUGMSG(("helper:stash_cache", "\n")); 00169 snmp_set_var_typed_value(request->requestvb, cdata->type, 00170 cdata->val.string, cdata->val_len); 00171 snmp_set_var_objid(request->requestvb, cdata->name, 00172 cdata->name_length); 00173 } 00174 } 00175 } 00176 return SNMP_ERR_NOERROR; 00177 break; 00178 00179 default: 00180 cinfo->cache_valid = 0; 00181 return netsnmp_call_next_handler(handler, reginfo, reqinfo, 00182 requests); 00183 } 00184 return SNMP_ERR_GENERR; /* should never get here */ 00185 } 00186 00189 int 00190 _netsnmp_stash_cache_load( netsnmp_cache *cache, void *magic ) 00191 { 00192 netsnmp_mib_handler *handler = cache->cache_hint->handler; 00193 netsnmp_handler_registration *reginfo = cache->cache_hint->reginfo; 00194 netsnmp_agent_request_info *reqinfo = cache->cache_hint->reqinfo; 00195 netsnmp_request_info *requests = cache->cache_hint->requests; 00196 netsnmp_stash_cache_info *cinfo = (netsnmp_stash_cache_info*) magic; 00197 int old_mode; 00198 int ret; 00199 00200 if (!cinfo) { 00201 cinfo = netsnmp_get_new_stash_cache(); 00202 cache->magic = cinfo; 00203 } 00204 00205 /* change modes to the GET_STASH mode */ 00206 old_mode = reqinfo->mode; 00207 reqinfo->mode = MODE_GET_STASH; 00208 netsnmp_agent_add_list_data(reqinfo, 00209 netsnmp_create_data_list(STASH_CACHE_NAME, 00210 &cinfo->cache, NULL)); 00211 00212 /* have the next handler fill stuff in and switch modes back */ 00213 ret = netsnmp_call_next_handler(handler->next, reginfo, reqinfo, requests); 00214 reqinfo->mode = old_mode; 00215 00216 return ret; 00217 } 00218 00219 void 00220 _netsnmp_stash_cache_free( netsnmp_cache *cache, void *magic ) 00221 { 00222 netsnmp_stash_cache_info *cinfo = (netsnmp_stash_cache_info*) magic; 00223 netsnmp_oid_stash_free(&cinfo->cache, 00224 (NetSNMPStashFreeNode *) snmp_free_var); 00225 return; 00226 } 00227 00232 void 00233 netsnmp_init_stash_cache_helper(void) 00234 { 00235 netsnmp_register_handler_by_name("stash_cache", 00236 netsnmp_get_stash_cache_handler()); 00237 }