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;
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
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
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 }