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

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #include <stdlib.h>
  3. #if HAVE_STRING_H
  4. #include <string.h>
  5. #else
  6. #include <strings.h>
  7. #endif
  8. #include <net-snmp/net-snmp-includes.h>
  9. #include <net-snmp/agent/net-snmp-agent-includes.h>
  10. #include <net-snmp/agent/watcher.h>
  11. #include <net-snmp/agent/instance.h>
  12. #include <net-snmp/agent/scalar.h>
  13. #if HAVE_DMALLOC_H
  14. #include <dmalloc.h>
  15. #endif
  16. /** @defgroup watcher watcher: watch a specified variable and process
  17.  *   it as an instance or scalar object
  18.  *  @ingroup leaf
  19.  *  @{
  20.  */
  21. netsnmp_mib_handler *
  22. netsnmp_get_watcher_handler(void)
  23. {
  24.     netsnmp_mib_handler *ret = NULL;
  25.     
  26.     ret = netsnmp_create_handler("watcher",
  27.                                  netsnmp_watcher_helper_handler);
  28.     if (ret) {
  29.         ret->flags |= MIB_HANDLER_AUTO_NEXT;
  30.     }
  31.     return ret;
  32. }
  33. netsnmp_watcher_info *
  34. netsnmp_create_watcher_info(void *data, size_t size, u_char type, int flags)
  35. {
  36.     netsnmp_watcher_info *winfo = SNMP_MALLOC_TYPEDEF(netsnmp_watcher_info);
  37.     winfo->data      = data;
  38.     winfo->data_size = size;
  39.     winfo->max_size  = size; /* Probably wrong for non-fixed size data */
  40.     winfo->type      = type;
  41.     if (flags)
  42.         winfo->flags = flags;
  43.     else
  44.         winfo->flags = WATCHER_FIXED_SIZE;
  45.     return winfo;
  46. }
  47. int
  48. netsnmp_register_watched_instance(netsnmp_handler_registration *reginfo,
  49.                                   netsnmp_watcher_info         *watchinfo)
  50. {
  51.     netsnmp_mib_handler *whandler;
  52.     whandler         = netsnmp_get_watcher_handler();
  53.     whandler->myvoid = (void *)watchinfo;
  54.     netsnmp_inject_handler(reginfo, whandler);
  55.     return netsnmp_register_instance(reginfo);
  56. }
  57. int
  58. netsnmp_register_watched_scalar(netsnmp_handler_registration *reginfo,
  59.                                   netsnmp_watcher_info         *watchinfo)
  60. {
  61.     netsnmp_mib_handler *whandler;
  62.     whandler         = netsnmp_get_watcher_handler();
  63.     whandler->myvoid = (void *)watchinfo;
  64.     netsnmp_inject_handler(reginfo, whandler);
  65.     return netsnmp_register_scalar(reginfo);
  66. }
  67. int
  68. netsnmp_watcher_helper_handler(netsnmp_mib_handler *handler,
  69.                                netsnmp_handler_registration *reginfo,
  70.                                netsnmp_agent_request_info *reqinfo,
  71.                                netsnmp_request_info *requests)
  72. {
  73.     netsnmp_watcher_info *winfo = (netsnmp_watcher_info *) handler->myvoid;
  74.     u_char              *old_data;
  75.     int                  cmp;
  76.     DEBUGMSGTL(("helper:watcher", "Got request:  %dn", reqinfo->mode));
  77.     cmp = snmp_oid_compare(requests->requestvb->name,
  78.                            requests->requestvb->name_length,
  79.                            reginfo->rootoid, reginfo->rootoid_len);
  80.     DEBUGMSGTL(( "helper:watcher", "  oid:", cmp));
  81.     DEBUGMSGOID(("helper:watcher", requests->requestvb->name,
  82.                                    requests->requestvb->name_length));
  83.     DEBUGMSG((   "helper:watcher", "n"));
  84.     switch (reqinfo->mode) {
  85.         /*
  86.          * data requests 
  87.          */
  88.     case MODE_GET:
  89.         snmp_set_var_typed_value(requests->requestvb,
  90.                                  winfo->type,
  91.                                  winfo->data,
  92.                                  winfo->data_size);
  93.         break;
  94.         /*
  95.          * SET requests.  Should only get here if registered RWRITE 
  96.          */
  97.     case MODE_SET_RESERVE1:
  98.         if (requests->requestvb->type != winfo->type)
  99.             netsnmp_set_request_error(reqinfo, requests,
  100.                                       SNMP_ERR_WRONGTYPE);
  101.         if (((winfo->flags & WATCHER_MAX_SIZE) &&
  102.                requests->requestvb->val_len >  winfo->max_size) ||
  103.             ((winfo->flags & WATCHER_FIXED_SIZE) &&
  104.                requests->requestvb->val_len != winfo->data_size))
  105.              netsnmp_set_request_error(reqinfo, requests,
  106.                                       SNMP_ERR_WRONGLENGTH);
  107.         break;
  108.     case MODE_SET_RESERVE2:
  109.         /*
  110.          * store old info for undo later 
  111.          */
  112.         memdup(&old_data, (u_char *) winfo->data, winfo->data_size);
  113.         if (old_data == NULL) {
  114.             netsnmp_set_request_error(reqinfo, requests,
  115.                                       SNMP_ERR_RESOURCEUNAVAILABLE);
  116.             return SNMP_ERR_NOERROR;
  117.         }
  118.         netsnmp_request_add_list_data(requests,
  119.                                       netsnmp_create_data_list
  120.                                       ("watcher", old_data, free));
  121.         break;
  122.     case MODE_SET_FREE:
  123.         /*
  124.          * nothing to do 
  125.          */
  126.         break;
  127.     case MODE_SET_ACTION:
  128.         /*
  129.          * update current 
  130.          */
  131.         memcpy(winfo->data, (void *)requests->requestvb->val.string,
  132.                                     requests->requestvb->val_len);
  133.         break;
  134.     case MODE_SET_UNDO:
  135.         memcpy(winfo->data,
  136.                netsnmp_request_get_list_data(requests, "watcher"),
  137.                winfo->data_size);
  138.         break;
  139.     case MODE_SET_COMMIT:
  140.         winfo->data_size = requests->requestvb->val_len;
  141.         break;
  142.     }
  143.     /* next handler called automatically - 'AUTO_NEXT' */
  144.     return SNMP_ERR_NOERROR;
  145. }
  146.     /***************************
  147.      *
  148.      * A specialised form of the above, reporting
  149.      *   the sysUpTime indicated by a given timestamp
  150.      *
  151.      ***************************/
  152. netsnmp_mib_handler *
  153. netsnmp_get_watched_timestamp_handler(void)
  154. {
  155.     netsnmp_mib_handler *ret = NULL;
  156.     
  157.     ret = netsnmp_create_handler("watcher",
  158.                                  netsnmp_watched_timestamp_handler);
  159.     if (ret) {
  160.         ret->flags |= MIB_HANDLER_AUTO_NEXT;
  161.     }
  162.     return ret;
  163. }
  164. int
  165. netsnmp_register_watched_timestamp(netsnmp_handler_registration *reginfo,
  166.                                    marker_t timestamp)
  167. {
  168.     netsnmp_mib_handler *whandler;
  169.     whandler         = netsnmp_get_watched_timestamp_handler();
  170.     whandler->myvoid = (void *)timestamp;
  171.     netsnmp_inject_handler(reginfo, whandler);
  172.     return netsnmp_register_scalar(reginfo);   /* XXX - or instance? */
  173. }
  174. int
  175. netsnmp_watched_timestamp_handler(netsnmp_mib_handler *handler,
  176.                                netsnmp_handler_registration *reginfo,
  177.                                netsnmp_agent_request_info *reqinfo,
  178.                                netsnmp_request_info *requests)
  179. {
  180.     marker_t timestamp = (marker_t) handler->myvoid;
  181.     long     uptime;
  182.     int      cmp;
  183.     DEBUGMSGTL(("helper:watcher:timestamp",
  184.                                "Got request:  %dn", reqinfo->mode));
  185.     cmp = snmp_oid_compare(requests->requestvb->name,
  186.                            requests->requestvb->name_length,
  187.                            reginfo->rootoid, reginfo->rootoid_len);
  188.     DEBUGMSGTL(( "helper:watcher:timestamp", "  oid:", cmp));
  189.     DEBUGMSGOID(("helper:watcher:timestamp", requests->requestvb->name,
  190.                                    requests->requestvb->name_length));
  191.     DEBUGMSG((   "helper:watcher:timestamp", "n"));
  192.     switch (reqinfo->mode) {
  193.         /*
  194.          * data requests 
  195.          */
  196.     case MODE_GET:
  197.         uptime = netsnmp_marker_uptime( timestamp );
  198.         snmp_set_var_typed_value(requests->requestvb,
  199.                                  ASN_TIMETICKS,
  200.                                  (u_char *) &uptime,
  201.                                  sizeof(uptime));
  202.         break;
  203.         /*
  204.          * Timestamps are inherently Read-Only,
  205.          *  so don't need to support SET requests.
  206.          */
  207.     case MODE_SET_RESERVE1:
  208.         netsnmp_set_request_error(reqinfo, requests,
  209.                                   SNMP_ERR_NOTWRITABLE);
  210.         return SNMP_ERR_NOTWRITABLE;
  211.     }
  212.     /* next handler called automatically - 'AUTO_NEXT' */
  213.     return SNMP_ERR_NOERROR;
  214. }
  215.     /***************************
  216.      *
  217.      * Another specialised form of the above,
  218.      *   implementing a 'TestAndIncr' spinlock
  219.      *
  220.      ***************************/
  221. netsnmp_mib_handler *
  222. netsnmp_get_watched_spinlock_handler(void)
  223. {
  224.     netsnmp_mib_handler *ret = NULL;
  225.     
  226.     ret = netsnmp_create_handler("watcher",
  227.                                  netsnmp_watched_spinlock_handler);
  228.     if (ret) {
  229.         ret->flags |= MIB_HANDLER_AUTO_NEXT;
  230.     }
  231.     return ret;
  232. }
  233. int
  234. netsnmp_register_watched_spinlock(netsnmp_handler_registration *reginfo,
  235.                                    int *spinlock)
  236. {
  237.     netsnmp_mib_handler  *whandler;
  238.     netsnmp_watcher_info *winfo;
  239.     whandler         = netsnmp_get_watched_spinlock_handler();
  240.     whandler->myvoid = (void *)spinlock;
  241.     winfo            = netsnmp_create_watcher_info((void *)spinlock,
  242.            sizeof(int), ASN_INTEGER, WATCHER_FIXED_SIZE);
  243.     netsnmp_inject_handler(reginfo, whandler);
  244.     return netsnmp_register_watched_scalar(reginfo, winfo);
  245. }
  246. int
  247. netsnmp_watched_spinlock_handler(netsnmp_mib_handler *handler,
  248.                                netsnmp_handler_registration *reginfo,
  249.                                netsnmp_agent_request_info *reqinfo,
  250.                                netsnmp_request_info *requests)
  251. {
  252.     int     *spinlock = (int *) handler->myvoid;
  253.     netsnmp_request_info *request;
  254.     int      cmp;
  255.     DEBUGMSGTL(("helper:watcher:spinlock",
  256.                                "Got request:  %dn", reqinfo->mode));
  257.     cmp = snmp_oid_compare(requests->requestvb->name,
  258.                            requests->requestvb->name_length,
  259.                            reginfo->rootoid, reginfo->rootoid_len);
  260.     DEBUGMSGTL(( "helper:watcher:spinlock", "  oid:", cmp));
  261.     DEBUGMSGOID(("helper:watcher:spinlock", requests->requestvb->name,
  262.                                    requests->requestvb->name_length));
  263.     DEBUGMSG((   "helper:watcher:spinlock", "n"));
  264.     switch (reqinfo->mode) {
  265.         /*
  266.          * Ensure the assigned value matches the current one
  267.          */
  268.     case MODE_SET_RESERVE1:
  269.         for (request=requests; request; request=request->next) {
  270.             if (*request->requestvb->val.integer != *spinlock) {
  271.                 netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGVALUE);
  272.                 return SNMP_ERR_WRONGVALUE;
  273.             }
  274.         }
  275.         break;
  276.         /*
  277.          * Everything else worked, so increment the spinlock
  278.          */
  279.     case MODE_SET_COMMIT:
  280. (*spinlock)++;
  281. break;
  282.     }
  283.     /* next handler called automatically - 'AUTO_NEXT' */
  284.     return SNMP_ERR_NOERROR;
  285. }