nsCache.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:13k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #include <net-snmp/net-snmp-includes.h>
  3. #include <net-snmp/agent/net-snmp-agent-includes.h>
  4. #include <net-snmp/agent/scalar.h>
  5. #ifdef HAVE_STRING_H
  6. #include <string.h>
  7. #else
  8. #include <strings.h>
  9. #endif
  10. #include <net-snmp/agent/cache_handler.h>
  11. #include "agent/nsCache.h"
  12. #include "util_funcs.h"
  13. /*
  14.  * use unadvertised function to get cache head. You really should not
  15.  * do this, since the internal storage mechanism might change.
  16.  */
  17. extern netsnmp_cache *netsnmp_cache_get_head(void);
  18. /*
  19.  * OIDs for the cacheging control scalar objects
  20.  *
  21.  * Note that these we're registering the full object rather
  22.  *  than the (sole) valid instance in each case, in order
  23.  *  to handle requests for invalid instances properly.
  24.  */
  25. oid nsCacheTimeout_oid[]    = { 1, 3, 6, 1, 4, 1, 8072, 1, 5, 1};
  26. oid nsCacheEnabled_oid[]    = { 1, 3, 6, 1, 4, 1, 8072, 1, 5, 2};
  27. /*
  28.  * ... and for the cache table.
  29.  */
  30. #define  NSCACHE_TIMEOUT 2
  31. #define  NSCACHE_STATUS 3
  32. #define NSCACHE_STATUS_ENABLED  1
  33. #define NSCACHE_STATUS_DISABLED 2
  34. #define NSCACHE_STATUS_EMPTY    3
  35. #define NSCACHE_STATUS_ACTIVE   4
  36. #define NSCACHE_STATUS_EXPIRED  5
  37. oid nsCacheTable_oid[]      = { 1, 3, 6, 1, 4, 1, 8072, 1, 5, 3};
  38. void
  39. init_nsCache(void)
  40. {
  41.     netsnmp_table_registration_info *table_info;
  42.     netsnmp_iterator_info           *iinfo;
  43.     /*
  44.      * Register the scalar objects...
  45.      */
  46.     DEBUGMSGTL(("nsCacheScalars", "Initializingn"));
  47.     netsnmp_register_scalar(
  48.         netsnmp_create_handler_registration(
  49.             "nsCacheTimeout", handle_nsCacheTimeout,
  50.             nsCacheTimeout_oid, OID_LENGTH(nsCacheTimeout_oid),
  51.             HANDLER_CAN_RWRITE)
  52.         );
  53.     netsnmp_register_scalar(
  54.         netsnmp_create_handler_registration(
  55.             "nsCacheEnabled", handle_nsCacheEnabled,
  56.             nsCacheEnabled_oid, OID_LENGTH(nsCacheEnabled_oid),
  57.             HANDLER_CAN_RWRITE)
  58.         );
  59.     /*
  60.      * ... and the table.
  61.      * We need to define the column structure and indexing....
  62.      */
  63.     table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
  64.     if (!table_info) {
  65.         return;
  66.     }
  67.     netsnmp_table_helper_add_indexes(table_info, ASN_PRIV_IMPLIED_OBJECT_ID, 0);
  68.     table_info->min_column = NSCACHE_TIMEOUT;
  69.     table_info->max_column = NSCACHE_STATUS;
  70.     /*
  71.      * .... and the iteration information ....
  72.      */
  73.     iinfo      = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
  74.     if (!iinfo) {
  75.         return;
  76.     }
  77.     iinfo->get_first_data_point = get_first_cache_entry;
  78.     iinfo->get_next_data_point  = get_next_cache_entry;
  79.     iinfo->table_reginfo        = table_info;
  80.     /*
  81.      * .... and register the table with the agent.
  82.      */
  83.     netsnmp_register_table_iterator(
  84.         netsnmp_create_handler_registration(
  85.             "tzCacheTable", handle_nsCacheTable,
  86.             nsCacheTable_oid, OID_LENGTH(nsCacheTable_oid),
  87.             HANDLER_CAN_RWRITE),
  88.         iinfo);
  89. }
  90. /*
  91.  * nsCache scalar handling
  92.  */
  93. int
  94. handle_nsCacheTimeout(netsnmp_mib_handler *handler,
  95.                 netsnmp_handler_registration *reginfo,
  96.                 netsnmp_agent_request_info *reqinfo,
  97.                 netsnmp_request_info *requests)
  98. {
  99.     long cache_default_timeout =
  100.         netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
  101.                                NETSNMP_DS_AGENT_CACHE_TIMEOUT);
  102.     netsnmp_request_info *request=NULL;
  103.     switch (reqinfo->mode) {
  104.     case MODE_GET:
  105. for (request = requests; request; request=request->next) {
  106.     snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
  107.                                      (u_char*)&cache_default_timeout,
  108.                                         sizeof(cache_default_timeout));
  109. }
  110. break;
  111.     case MODE_SET_RESERVE1:
  112. for (request = requests; request; request=request->next) {
  113.             if ( request->status != 0 ) {
  114.                 return SNMP_ERR_NOERROR; /* Already got an error */
  115.             }
  116.             if ( request->requestvb->type != ASN_INTEGER ) {
  117.                 netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
  118.                 return SNMP_ERR_WRONGTYPE;
  119.             }
  120.             if ( *request->requestvb->val.integer < 0 ) {
  121.                 netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
  122.                 return SNMP_ERR_WRONGVALUE;
  123.             }
  124.         }
  125.         break;
  126.     case MODE_SET_COMMIT:
  127.         netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
  128.                            NETSNMP_DS_AGENT_CACHE_TIMEOUT,
  129.                            *requests->requestvb->val.integer);
  130.         break;
  131.     }
  132.     return SNMP_ERR_NOERROR;
  133. }
  134. int
  135. handle_nsCacheEnabled(netsnmp_mib_handler *handler,
  136.                 netsnmp_handler_registration *reginfo,
  137.                 netsnmp_agent_request_info *reqinfo,
  138.                 netsnmp_request_info *requests)
  139. {
  140.     long enabled;
  141.     netsnmp_request_info *request=NULL;
  142.     switch (reqinfo->mode) {
  143.     case MODE_GET:
  144. enabled =  (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
  145.                                            NETSNMP_DS_AGENT_NO_CACHING)
  146.                        ? NSCACHE_STATUS_ENABLED    /* Actually True/False */
  147.                        : NSCACHE_STATUS_DISABLED );
  148. for (request = requests; request; request=request->next) {
  149.     snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
  150.                                      (u_char*)&enabled, sizeof(enabled));
  151. }
  152. break;
  153.     case MODE_SET_RESERVE1:
  154. for (request = requests; request; request=request->next) {
  155.             if ( request->status != 0 ) {
  156.                 return SNMP_ERR_NOERROR; /* Already got an error */
  157.             }
  158.             if ( request->requestvb->type != ASN_INTEGER ) {
  159.                 netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
  160.                 return SNMP_ERR_WRONGTYPE;
  161.             }
  162.             if ((*request->requestvb->val.integer != NSCACHE_STATUS_ENABLED) &&
  163.                 (*request->requestvb->val.integer != NSCACHE_STATUS_DISABLED)) {
  164.                 netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
  165.                 return SNMP_ERR_WRONGVALUE;
  166.             }
  167.         }
  168.         break;
  169.     case MODE_SET_COMMIT:
  170.         enabled = *requests->requestvb->val.integer;
  171. if (enabled == NSCACHE_STATUS_DISABLED)
  172.     enabled = 0;
  173. netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
  174.                                NETSNMP_DS_AGENT_NO_CACHING, enabled);
  175.         break;
  176.     }
  177.     return SNMP_ERR_NOERROR;
  178. }
  179. /*
  180.  * nsCacheTable handling
  181.  */
  182. netsnmp_variable_list *
  183. get_first_cache_entry(void **loop_context, void **data_context,
  184.                       netsnmp_variable_list *index,
  185.                       netsnmp_iterator_info *data)
  186. {
  187.     netsnmp_cache  *cache_head = netsnmp_cache_get_head();
  188.     if ( !cache_head )
  189.         return NULL;
  190.     snmp_set_var_value(index, (u_char*)cache_head->rootoid,
  191.          sizeof(oid) * cache_head->rootoid_len);
  192.     *loop_context = (void*)cache_head;
  193.     *data_context = (void*)cache_head;
  194.     return index;
  195. }
  196. netsnmp_variable_list *
  197. get_next_cache_entry(void **loop_context, void **data_context,
  198.                       netsnmp_variable_list *index,
  199.                       netsnmp_iterator_info *data)
  200. {
  201.     netsnmp_cache *cache = (netsnmp_cache *)*loop_context;
  202.     cache = cache->next;
  203.     if ( !cache )
  204.         return NULL;
  205.     snmp_set_var_value(index, (u_char*)cache->rootoid,
  206.          sizeof(oid) * cache->rootoid_len);
  207.     *loop_context = (void*)cache;
  208.     *data_context = (void*)cache;
  209.     return index;
  210. }
  211. int
  212. handle_nsCacheTable(netsnmp_mib_handler *handler,
  213.                 netsnmp_handler_registration *reginfo,
  214.                 netsnmp_agent_request_info *reqinfo,
  215.                 netsnmp_request_info *requests)
  216. {
  217.     long status;
  218.     netsnmp_request_info       *request     = NULL;
  219.     netsnmp_table_request_info *table_info  = NULL;
  220.     netsnmp_cache              *cache_entry = NULL;
  221.     switch (reqinfo->mode) {
  222.     case MODE_GET:
  223.         for (request=requests; request; request=request->next) {
  224.             if (requests->processed != 0)
  225.                 continue;
  226.             cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
  227.             table_info  =                 netsnmp_extract_table_info(request);
  228.             switch (table_info->colnum) {
  229.             case NSCACHE_TIMEOUT:
  230.                 if (!cache_entry) {
  231.                     netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
  232.                     continue;
  233. }
  234. status = cache_entry->timeout;
  235.         snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
  236.                                          (u_char*)&status, sizeof(status));
  237.         break;
  238.             case NSCACHE_STATUS:
  239.                 if (!cache_entry) {
  240.                     netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
  241.                     continue;
  242. }
  243. status = (cache_entry->enabled ?
  244.                    (cache_entry->timestamp ?
  245.                              (!atime_ready(cache_entry->timestamp,
  246.                                           1000*cache_entry->timeout) ?
  247.                         NSCACHE_STATUS_ACTIVE:
  248.                         NSCACHE_STATUS_EXPIRED) :
  249.                       NSCACHE_STATUS_EMPTY) :
  250.                     NSCACHE_STATUS_DISABLED);
  251.         snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
  252.                                          (u_char*)&status, sizeof(status));
  253.         break;
  254.             default:
  255.                 netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  256.                 continue;
  257.     }
  258. }
  259. break;
  260.     case MODE_SET_RESERVE1:
  261.         for (request=requests; request; request=request->next) {
  262.             if (requests->processed != 0)
  263.                 continue;
  264.             if ( request->status != 0 ) {
  265.                 return SNMP_ERR_NOERROR; /* Already got an error */
  266.             }
  267.             cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
  268.             table_info  =                 netsnmp_extract_table_info(request);
  269.             switch (table_info->colnum) {
  270.             case NSCACHE_TIMEOUT:
  271.                 if (!cache_entry) {
  272.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
  273.                     return SNMP_ERR_NOCREATION;
  274. }
  275.                 if ( request->requestvb->type != ASN_INTEGER ) {
  276.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
  277.                     return SNMP_ERR_WRONGTYPE;
  278.                 }
  279.                 if (*request->requestvb->val.integer < 0 ) {
  280.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
  281.                     return SNMP_ERR_WRONGVALUE;
  282.                 }
  283.         break;
  284.             case NSCACHE_STATUS:
  285.                 if (!cache_entry) {
  286.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
  287.                     return SNMP_ERR_NOCREATION;
  288. }
  289.                 if ( request->requestvb->type != ASN_INTEGER ) {
  290.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
  291.                     return SNMP_ERR_WRONGTYPE;
  292.                 }
  293.                 status = *request->requestvb->val.integer;
  294.                 if (!((status == NSCACHE_STATUS_ENABLED  ) ||
  295.                       (status == NSCACHE_STATUS_DISABLED ) ||
  296.                       (status == NSCACHE_STATUS_EMPTY  ))) {
  297.                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
  298.                     return SNMP_ERR_WRONGVALUE;
  299.                 }
  300.         break;
  301.             default:
  302.                 netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
  303.                 return SNMP_ERR_NOCREATION; /* XXX - is this right ? */
  304.                 continue;
  305.     }
  306. }
  307. break;
  308.     case MODE_SET_COMMIT:
  309.         for (request=requests; request; request=request->next) {
  310.             if (requests->processed != 0)
  311.                 continue;
  312.             if ( request->status != 0 ) {
  313.                 return SNMP_ERR_NOERROR; /* Already got an error */
  314.             }
  315.             cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
  316.             if (!cache_entry) {
  317.                 netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED);
  318.                 return SNMP_ERR_COMMITFAILED; /* Shouldn't happen! */
  319.             }
  320.             table_info  =                 netsnmp_extract_table_info(request);
  321.             switch (table_info->colnum) {
  322.             case NSCACHE_TIMEOUT:
  323.                 cache_entry->timeout = *request->requestvb->val.integer;
  324.         break;
  325.             case NSCACHE_STATUS:
  326.                 switch (*request->requestvb->val.integer) {
  327.                     case NSCACHE_STATUS_ENABLED:
  328.                         cache_entry->enabled = 1;
  329.                         break;
  330.     case NSCACHE_STATUS_DISABLED:
  331.                         cache_entry->enabled = 0;
  332.                         break;
  333.     case NSCACHE_STATUS_EMPTY:
  334.                         cache_entry->free_cache(cache_entry, cache_entry->magic);
  335.                         free(cache_entry->timestamp);
  336.                         cache_entry->timestamp = NULL;
  337.                         break;
  338. }
  339.         break;
  340.     }
  341. }
  342. break;
  343.     }
  344.     return SNMP_ERR_NOERROR;
  345. }