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

SNMP编程

开发平台:

Unix_Linux

  1. /**************************************************************
  2.  * Copyright (C) 2001 Tali Rozin, Optical Access
  3.  *
  4.  *                     All Rights Reserved
  5.  *
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and that
  9.  * both that copyright notice and this permission notice appear in
  10.  * supporting documentation.
  11.  *
  12.  * TALI ROZIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  13.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  14.  * ALEX ROZIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  15.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  16.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  17.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  18.  * SOFTWARE.
  19.  ******************************************************************/
  20. #include <net-snmp/net-snmp-config.h>
  21. #if HAVE_STDLIB
  22. #include <stdlib.h>
  23. #endif
  24. #if TIME_WITH_SYS_TIME
  25. # ifdef WIN32
  26. #  include <sys/timeb.h>
  27. # else
  28. #  include <sys/time.h>
  29. # endif
  30. # include <time.h>
  31. #else
  32. # if HAVE_SYS_TIME_H
  33. #  include <sys/time.h>
  34. # else
  35. #  include <time.h>
  36. # endif
  37. #endif
  38. #if HAVE_UNISTD_H
  39. #include <unistd.h>
  40. #endif
  41. #include <net-snmp/net-snmp-includes.h>
  42. #include <net-snmp/agent/net-snmp-agent-includes.h>
  43. #include "util_funcs.h"
  44. #include "statistics.h"
  45.         /*
  46.          * Implementation headers 
  47.          */
  48. #include "agutil_api.h"
  49. #include "row_api.h"
  50.         /*
  51.          * File scope definitions section 
  52.          */
  53.         /*
  54.          * from MIB compilation 
  55.          */
  56. #define MIB_DESCR "EthStat"
  57. #define etherStatsEntryFirstIndexBegin 11
  58. #define IDetherStatsDroppedFrames        1
  59. #define IDetherStatsCreateTime           2
  60. #define IDetherStatsIndex                3
  61. #define IDetherStatsDataSource           4
  62. #define IDetherStatsDropEvents           5
  63. #define IDetherStatsOctets               6
  64. #define IDetherStatsPkts                 7
  65. #define IDetherStatsBroadcastPkts        8
  66. #define IDetherStatsMulticastPkts        9
  67. #define IDetherStatsCRCAlignErrors       10
  68. #define IDetherStatsUndersizePkts        11
  69. #define IDetherStatsOversizePkts         12
  70. #define IDetherStatsFragments            13
  71. #define IDetherStatsJabbers              14
  72. #define IDetherStatsCollisions           15
  73. #define IDetherStatsPkts64Octets         16
  74. #define IDetherStatsPkts65to127Octets    17
  75. #define IDetherStatsPkts128to255Octets   18
  76. #define IDetherStatsPkts256to511Octets   19
  77. #define IDetherStatsPkts512to1023Octets  20
  78. #define IDetherStatsPkts1024to1518Octets 21
  79. #define IDetherStatsOwner                22
  80. #define IDetherStatsStatus               23
  81. #define Leaf_etherStatsDataSource        2
  82. #define Leaf_etherStatsOwner             20
  83. #define Leaf_etherStatsStatus            21
  84. #define MIN_etherStatsIndex   1
  85. #define MAX_etherStatsIndex   65535
  86.      typedef struct {
  87.          VAR_OID_T
  88.              data_source;
  89.          u_long
  90.              etherStatsCreateTime;
  91.          ETH_STATS_T
  92.              eth;
  93.      } CRTL_ENTRY_T;
  94. /*
  95.  * Main section 
  96.  */
  97.      static TABLE_DEFINTION_T
  98.          StatCtrlTable;
  99.      static TABLE_DEFINTION_T *
  100.          table_ptr = &
  101.          StatCtrlTable;
  102. /*
  103.  * Control Table RowApi Callbacks 
  104.  */
  105.      int
  106.      stat_Create(RMON_ENTRY_T * eptr)
  107. {                               /* create the body: alloc it and set defaults */
  108.     CRTL_ENTRY_T   *body;
  109.     static VAR_OID_T data_src_if_index_1 =
  110.         { 11, {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1} };
  111.     eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
  112.     if (!eptr->body)
  113.         return -3;
  114.     body = (CRTL_ENTRY_T *) eptr->body;
  115.     /*
  116.      * set defaults 
  117.      */
  118.     memcpy(&body->data_source, &data_src_if_index_1, sizeof(VAR_OID_T));
  119.     body->data_source.objid[body->data_source.length - 1] =
  120.         eptr->ctrl_index;
  121.     eptr->owner = AGSTRDUP("Startup Mgmt");
  122.     memset(&body->eth, 0, sizeof(ETH_STATS_T));
  123.     return 0;
  124. }
  125. int
  126. stat_Validate(RMON_ENTRY_T * eptr)
  127. {
  128.     /*
  129.      * T.B.D. (system dependent) check valid inteface in body->data_source; 
  130.      */
  131.     return 0;
  132. }
  133. int
  134. stat_Activate(RMON_ENTRY_T * eptr)
  135. {
  136.     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
  137.     body->etherStatsCreateTime = AGUTIL_sys_up_time();
  138.     return 0;
  139. }
  140. int
  141. stat_Copy(RMON_ENTRY_T * eptr)
  142. {
  143.     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
  144.     CRTL_ENTRY_T   *clone = (CRTL_ENTRY_T *) eptr->tmp;
  145.     if (snmp_oid_compare
  146.         (clone->data_source.objid, clone->data_source.length,
  147.          body->data_source.objid, body->data_source.length)) {
  148.         memcpy(&body->data_source, &clone->data_source, sizeof(VAR_OID_T));
  149.     }
  150.     return 0;
  151. }
  152. int
  153. stat_Deactivate(RMON_ENTRY_T * eptr)
  154. {
  155.     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
  156.     memset(&body->eth, 0, sizeof(ETH_STATS_T));
  157.     return 0;
  158. }
  159. /***************************************************
  160.  * Function:var_etherStats2Entry 
  161.  * Purpose: Handles the request for etherStats2Entry variable instances
  162.  ***************************************************/
  163. u_char         *
  164. var_etherStats2Entry(struct variable * vp, oid * name, size_t * length,
  165.                      int exact, size_t * var_len,
  166.                      WriteMethod ** write_method)
  167. {
  168.     static long     long_return;
  169.     static CRTL_ENTRY_T theEntry;
  170.     RMON_ENTRY_T   *hdr;
  171.     *write_method = NULL;
  172.     hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
  173.                                      table_ptr,
  174.                                      &theEntry, sizeof(CRTL_ENTRY_T));
  175.     if (!hdr)
  176.         return NULL;
  177.     *var_len = sizeof(long);    /* default */
  178.     switch (vp->magic) {
  179.     case IDetherStatsDroppedFrames:
  180.         long_return = 0;
  181.         return (u_char *) & long_return;
  182.     case IDetherStatsCreateTime:
  183.         long_return = theEntry.etherStatsCreateTime;
  184.         return (u_char *) & long_return;
  185.     default:
  186.         ag_trace("%s: unknown vp->magic=%d", table_ptr->name,
  187.                  (int) vp->magic);
  188.         ERROR_MSG("");
  189.     };                          /* of switch by 'vp->magic'  */
  190.     return NULL;
  191. }
  192. /***************************************************
  193.  * Function:write_etherStatsEntry 
  194.  ***************************************************/
  195. static int
  196. write_etherStatsEntry(int action, u_char * var_val, u_char var_val_type,
  197.                       size_t var_val_len, u_char * statP,
  198.                       oid * name, size_t name_len)
  199. {
  200.     long            long_temp;
  201.     int             leaf_id, snmp_status;
  202.     static int      prev_action = COMMIT;
  203.     RMON_ENTRY_T   *hdr;
  204.     CRTL_ENTRY_T   *cloned_body;
  205.     CRTL_ENTRY_T   *body;
  206.     switch (action) {
  207.     case RESERVE1:
  208.     case FREE:
  209.     case UNDO:
  210.     case ACTION:
  211.     case COMMIT:
  212.     default:
  213.         snmp_status =
  214.             ROWAPI_do_another_action(name, etherStatsEntryFirstIndexBegin,
  215.                                      action, &prev_action, table_ptr,
  216.                                      sizeof(CRTL_ENTRY_T));
  217.         if (SNMP_ERR_NOERROR != snmp_status) {
  218.             ag_trace("failed action %d with %d", action, snmp_status);
  219.         }
  220.         break;
  221.     case RESERVE2:
  222.         /*
  223.          * get values from PDU, check them and save them in the cloned entry 
  224.          */
  225.         long_temp = name[etherStatsEntryFirstIndexBegin];
  226.         leaf_id = (int) name[etherStatsEntryFirstIndexBegin - 1];
  227.         hdr = ROWAPI_find(table_ptr, long_temp);        /* it MUST be OK */
  228.         cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
  229.         body = (CRTL_ENTRY_T *) hdr->body;
  230.         switch (leaf_id) {
  231.         case Leaf_etherStatsDataSource:
  232.             snmp_status = AGUTIL_get_oid_value(var_val, var_val_type,
  233.                                                var_val_len,
  234.                                                &cloned_body->data_source);
  235.             if (SNMP_ERR_NOERROR != snmp_status) {
  236.                 return snmp_status;
  237.             }
  238.             if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
  239.                 snmp_oid_compare(cloned_body->data_source.objid,
  240.                                  cloned_body->data_source.length,
  241.                                  body->data_source.objid,
  242.                                  body->data_source.length))
  243.                 return SNMP_ERR_BADVALUE;
  244.             break;
  245.             break;
  246.         case Leaf_etherStatsOwner:
  247.             if (hdr->new_owner)
  248.                 AGFREE(hdr->new_owner);
  249.             hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);;
  250.             if (!hdr->new_owner)
  251.                 return SNMP_ERR_TOOBIG;
  252.             snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
  253.                                                   var_val_len,
  254.                                                   MAX_OWNERSTRING,
  255.                                                   1, NULL, hdr->new_owner);
  256.             if (SNMP_ERR_NOERROR != snmp_status) {
  257.                 return snmp_status;
  258.             }
  259.             break;
  260.         case Leaf_etherStatsStatus:
  261.             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
  262.                                                var_val_len,
  263.                                                RMON1_ENTRY_VALID,
  264.                                                RMON1_ENTRY_INVALID,
  265.                                                &long_temp);
  266.             if (SNMP_ERR_NOERROR != snmp_status) {
  267.                 ag_trace("cannot browse etherStatsStatus");
  268.                 return snmp_status;
  269.             }
  270.             hdr->new_status = long_temp;
  271.             break;
  272.             break;
  273.         default:
  274.             ag_trace("%s:unknown leaf_id=%dn", table_ptr->name,
  275.                      (int) leaf_id);
  276.             return SNMP_ERR_NOSUCHNAME;
  277.         }                       /* of switch by 'leaf_id' */
  278.         break;
  279.     }                           /* of switch by 'action' */
  280.     prev_action = action;
  281.     return SNMP_ERR_NOERROR;
  282. }
  283. /***************************************************
  284.  * Function:var_etherStatsEntry 
  285.  * Purpose: Handles the request for etherStatsEntry variable instances
  286.  ***************************************************/
  287. u_char         *
  288. var_etherStatsEntry(struct variable * vp, oid * name, size_t * length,
  289.                     int exact, size_t * var_len,
  290.                     WriteMethod ** write_method)
  291. {
  292.     static long     long_return;
  293.     static CRTL_ENTRY_T theEntry;
  294.     RMON_ENTRY_T   *hdr;
  295.     *write_method = write_etherStatsEntry;
  296.     hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
  297.                                      table_ptr,
  298.                                      &theEntry, sizeof(CRTL_ENTRY_T));
  299.     if (!hdr)
  300.         return NULL;
  301.     if (RMON1_ENTRY_VALID == hdr->status)
  302.         SYSTEM_get_eth_statistics(&theEntry.data_source, &theEntry.eth);
  303.     *var_len = sizeof(long);
  304.     switch (vp->magic) {
  305.     case IDetherStatsIndex:
  306.         long_return = hdr->ctrl_index;
  307.         return (u_char *) & long_return;
  308.     case IDetherStatsDataSource:
  309.         *var_len = sizeof(oid) * theEntry.data_source.length;
  310.         return (unsigned char *) theEntry.data_source.objid;
  311.     case IDetherStatsDropEvents:
  312.         long_return = 0;        /* theEntry.eth.etherStatsDropEvents; */
  313.         return (u_char *) & long_return;
  314.     case IDetherStatsOctets:
  315.         long_return = theEntry.eth.octets;
  316.         return (u_char *) & long_return;
  317.     case IDetherStatsPkts:
  318.         long_return = theEntry.eth.packets;
  319.         return (u_char *) & long_return;
  320.     case IDetherStatsBroadcastPkts:
  321.         long_return = theEntry.eth.bcast_pkts;
  322.         return (u_char *) & long_return;
  323.     case IDetherStatsMulticastPkts:
  324.         long_return = theEntry.eth.mcast_pkts;
  325.         return (u_char *) & long_return;
  326.     case IDetherStatsCRCAlignErrors:
  327.         long_return = theEntry.eth.crc_align;
  328.         return (u_char *) & long_return;
  329.     case IDetherStatsUndersizePkts:
  330.         long_return = theEntry.eth.undersize;
  331.         return (u_char *) & long_return;
  332.     case IDetherStatsOversizePkts:
  333.         long_return = theEntry.eth.oversize;
  334.         return (u_char *) & long_return;
  335.     case IDetherStatsFragments:
  336.         long_return = theEntry.eth.fragments;
  337.         return (u_char *) & long_return;
  338.     case IDetherStatsJabbers:
  339.         long_return = theEntry.eth.jabbers;
  340.         return (u_char *) & long_return;
  341.     case IDetherStatsCollisions:
  342.         long_return = theEntry.eth.collisions;
  343.         return (u_char *) & long_return;
  344.     case IDetherStatsPkts64Octets:
  345.         long_return = theEntry.eth.pkts_64;
  346.         return (u_char *) & long_return;
  347.     case IDetherStatsPkts65to127Octets:
  348.         long_return = theEntry.eth.pkts_65_127;
  349.         return (u_char *) & long_return;
  350.     case IDetherStatsPkts128to255Octets:
  351.         long_return = theEntry.eth.pkts_128_255;
  352.         return (u_char *) & long_return;
  353.     case IDetherStatsPkts256to511Octets:
  354.         long_return = theEntry.eth.pkts_256_511;
  355.         return (u_char *) & long_return;
  356.     case IDetherStatsPkts512to1023Octets:
  357.         long_return = theEntry.eth.pkts_512_1023;
  358.         return (u_char *) & long_return;
  359.     case IDetherStatsPkts1024to1518Octets:
  360.         long_return = theEntry.eth.pkts_1024_1518;
  361.         return (u_char *) & long_return;
  362.     case IDetherStatsOwner:
  363.         if (hdr->owner) {
  364.             *var_len = strlen(hdr->owner);
  365.             return (unsigned char *) hdr->owner;
  366.         } else {
  367.             *var_len = 0;
  368.             return (unsigned char *) "";
  369.         }
  370.     case IDetherStatsStatus:
  371.         long_return = hdr->status;
  372.         return (u_char *) & long_return;
  373.     default:
  374.         ERROR_MSG("");
  375.     };                          /* of switch by 'vp->magic'  */
  376.     return NULL;
  377. }
  378. #if 1                           /* debug, but may be used for init. TBD: may be token snmpd.conf ? */
  379. int
  380. add_statistics_entry(int ctrl_index, int ifIndex)
  381. {
  382.     int             ierr;
  383.     ierr = ROWAPI_new(table_ptr, ctrl_index);
  384.     switch (ierr) {
  385.     case -1:
  386.         ag_trace("max. number exedesn");
  387.         break;
  388.     case -2:
  389.         ag_trace("malloc failed");
  390.         break;
  391.     case -3:
  392.         ag_trace("ClbkCreate failed");
  393.         break;
  394.     case 0:
  395.         break;
  396.     default:
  397.         ag_trace("Unknown code %d", ierr);
  398.         break;
  399.     }
  400.     if (!ierr) {
  401.         register RMON_ENTRY_T *eptr = ROWAPI_find(table_ptr, ctrl_index);
  402.         if (!eptr) {
  403.             ag_trace("cannot find it");
  404.             ierr = -4;
  405.         } else {
  406.             CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
  407.             body->data_source.objid[body->data_source.length - 1] =
  408.                 ifIndex;
  409.             eptr->new_status = RMON1_ENTRY_VALID;
  410.             ierr = ROWAPI_commit(table_ptr, ctrl_index);
  411.             if (ierr) {
  412.                 ag_trace("ROWAPI_commit returned %d", ierr);
  413.             }
  414.         }
  415.     }
  416.     return ierr;
  417. }
  418. #endif
  419. /***************************************************
  420.  * define Variables callbacks 
  421.  ***************************************************/
  422. oid             oidstatisticsVariablesOid[] = { 1, 3, 6, 1, 2, 1, 16, 1 };
  423. struct variable7 oidstatisticsVariables[] = {
  424.     {IDetherStatsIndex, ASN_INTEGER, RONLY, var_etherStatsEntry, 3,
  425.      {1, 1, 1}},
  426.     {IDetherStatsDataSource, ASN_OBJECT_ID, RWRITE, var_etherStatsEntry, 3,
  427.      {1, 1, 2}},
  428.     {IDetherStatsDropEvents, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  429.      {1, 1, 3}},
  430.     {IDetherStatsOctets, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  431.      {1, 1, 4}},
  432.     {IDetherStatsPkts, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  433.      {1, 1, 5}},
  434.     {IDetherStatsBroadcastPkts, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  435.      {1, 1, 6}},
  436.     {IDetherStatsMulticastPkts, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  437.      {1, 1, 7}},
  438.     {IDetherStatsCRCAlignErrors, ASN_COUNTER, RONLY, var_etherStatsEntry,
  439.      3, {1, 1, 8}},
  440.     {IDetherStatsUndersizePkts, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  441.      {1, 1, 9}},
  442.     {IDetherStatsOversizePkts, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  443.      {1, 1, 10}},
  444.     {IDetherStatsFragments, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  445.      {1, 1, 11}},
  446.     {IDetherStatsJabbers, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  447.      {1, 1, 12}},
  448.     {IDetherStatsCollisions, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  449.      {1, 1, 13}},
  450.     {IDetherStatsPkts64Octets, ASN_COUNTER, RONLY, var_etherStatsEntry, 3,
  451.      {1, 1, 14}},
  452.     {IDetherStatsPkts65to127Octets, ASN_COUNTER, RONLY,
  453.      var_etherStatsEntry, 3, {1, 1, 15}},
  454.     {IDetherStatsPkts128to255Octets, ASN_COUNTER, RONLY,
  455.      var_etherStatsEntry, 3, {1, 1, 16}},
  456.     {IDetherStatsPkts256to511Octets, ASN_COUNTER, RONLY,
  457.      var_etherStatsEntry, 3, {1, 1, 17}},
  458.     {IDetherStatsPkts512to1023Octets, ASN_COUNTER, RONLY,
  459.      var_etherStatsEntry, 3, {1, 1, 18}},
  460.     {IDetherStatsPkts1024to1518Octets, ASN_COUNTER, RONLY,
  461.      var_etherStatsEntry, 3, {1, 1, 19}},
  462.     {IDetherStatsOwner, ASN_OCTET_STR, RWRITE, var_etherStatsEntry, 3,
  463.      {1, 1, 20}},
  464.     {IDetherStatsStatus, ASN_INTEGER, RWRITE, var_etherStatsEntry, 3,
  465.      {1, 1, 21}},
  466.     {IDetherStatsDroppedFrames, ASN_COUNTER, RONLY, var_etherStats2Entry,
  467.      3, {4, 1, 1}},
  468.     {IDetherStatsCreateTime, ASN_TIMETICKS, RONLY, var_etherStats2Entry, 3,
  469.      {4, 1, 2}},
  470. };
  471. /***************************************************
  472.  * Function:init_statistics 
  473.  * Purpose: register statistics objects in the agent 
  474.  ***************************************************/
  475. void
  476. init_statistics(void)
  477. {
  478.     REGISTER_MIB(MIB_DESCR, oidstatisticsVariables, variable7,
  479.                  oidstatisticsVariablesOid);
  480.     ROWAPI_init_table(&StatCtrlTable, MIB_DESCR, 0, &stat_Create, NULL, /* &stat_Clone, */
  481.                       NULL,     /* &stat_Delete, */
  482.                       &stat_Validate,
  483.                       &stat_Activate, &stat_Deactivate, &stat_Copy);
  484. #if 0                           /* debug */
  485.     {
  486.         int             iii;
  487.         for (iii = 1; iii < 6; iii++) {
  488.             add_statistics_entry(iii, iii);
  489.         }
  490.         add_statistics_entry(10, 16);
  491.         add_statistics_entry(12, 11);
  492.     }
  493. #endif
  494. }
  495. /*
  496.  * end of file statistics.c 
  497.  */