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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Host Resources MIB - utility functions - hr_utils.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #include <sys/types.h>
  7. #if HAVE_NETINET_IN_H
  8. #include <netinet/in.h>
  9. #endif
  10. #if HAVE_STDLIB_H
  11. #include <stdlib.h>
  12. #endif
  13. #include <ctype.h>
  14. #if HAVE_STRING_H
  15. #include <string.h>
  16. #endif
  17. #if HAVE_STDLIB_H
  18. #include <stdlib.h>
  19. #endif
  20. #if TIME_WITH_SYS_TIME
  21. #ifdef WIN32
  22. # include <sys/timeb.h>
  23. #else
  24. # include <sys/time.h>
  25. #endif
  26. # include <time.h>
  27. #else
  28. # if HAVE_SYS_TIME_H
  29. #  include <sys/time.h>
  30. # else
  31. #  include <time.h>
  32. # endif
  33. #endif
  34. #include <net-snmp/types.h>
  35. #include <net-snmp/library/snmp-tc.h>   /* for "internal" definitions */
  36. #include <net-snmp/library/snmp_api.h>
  37. /*
  38.   DateAndTime ::= TEXTUAL-CONVENTION
  39.     DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
  40.     STATUS       current
  41.     DESCRIPTION
  42.             "A date-time specification.
  43.             field  octets  contents                  range
  44.             -----  ------  --------                  -----
  45.               1      1-2   year*                     0..65536
  46.               2       3    month                     1..12
  47.               3       4    day                       1..31
  48.               4       5    hour                      0..23
  49.               5       6    minutes                   0..59
  50.               6       7    seconds                   0..60
  51.                            (use 60 for leap-second)
  52.               7       8    deci-seconds              0..9
  53.               8       9    direction from UTC        '+' / '-'
  54.               9      10    hours from UTC*           0..13
  55.              10      11    minutes from UTC          0..59
  56.             * Notes:
  57.             - the value of year is in network-byte order
  58.             - daylight saving time in New Zealand is +13
  59.             For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
  60.             displayed as:
  61.                              1992-5-26,13:30:15.0,-4:0
  62.             Note that if only local time is known, then timezone
  63.             information (fields 8-10) is not present."
  64.     SYNTAX       OCTET STRING (SIZE (8 | 11))
  65. */
  66. int
  67. netsnmp_dateandtime_set_buf_from_vars(u_char *buf, size_t *bufsize,
  68.                                       u_short year, u_char month, u_char day,
  69.                                       u_char hour, u_char minutes,
  70.                                       u_char seconds, u_char deci_seconds,
  71.                                       int utc_offset_direction,
  72.                                       u_char utc_offset_hours,
  73.                                       u_char utc_offset_minutes)
  74. {
  75.     u_short tmp_year = htons(year);
  76.     /*
  77.      * if we have a utc offset, need 11 bytes. Otherwise we
  78.      * just need 8 bytes.
  79.      */
  80.     if(utc_offset_direction) {
  81.         if(*bufsize < 11)
  82.             return SNMPERR_RANGE;
  83.         /*
  84.          * set utc offset data
  85.          */
  86.         buf[8] = (utc_offset_direction < 0) ? '-' : '+';
  87.         buf[9] = utc_offset_hours;
  88.         buf[10] = utc_offset_minutes;
  89.         *bufsize = 11;
  90.     }
  91.     else if(*bufsize < 8)
  92.         return SNMPERR_RANGE;
  93.     else
  94.         *bufsize = 8;
  95.     /*
  96.      * set basic date/time data
  97.      */
  98.     memcpy(buf, &tmp_year, sizeof(tmp_year));
  99.     buf[2] = month;
  100.     buf[3] = day;
  101.     buf[4] = hour;
  102.     buf[5] = minutes;
  103.     buf[6] = seconds;
  104.     buf[7] = deci_seconds;
  105.     return SNMPERR_SUCCESS;
  106. }
  107. u_char         *
  108. date_n_time(time_t * when, size_t * length)
  109. {
  110.     struct tm      *tm_p;
  111.     static u_char   string[11];
  112.     unsigned short yauron;
  113.     /*
  114.      * Null time
  115.      */
  116.     if (when == NULL || *when == 0 || *when == (time_t) - 1) {
  117.         string[0] = 0;
  118.         string[1] = 0;
  119.         string[2] = 1;
  120.         string[3] = 1;
  121.         string[4] = 0;
  122.         string[5] = 0;
  123.         string[6] = 0;
  124.         string[7] = 0;
  125.         *length = 8;
  126.         return string;
  127.     }
  128.     /*
  129.      * Basic 'local' time handling
  130.      */
  131.     tm_p = localtime(when);
  132.     yauron = tm_p->tm_year + 1900;
  133.     string[0] = (u_char)(yauron >> 8);
  134.     string[1] = (u_char)yauron;
  135.     string[2] = tm_p->tm_mon + 1;
  136.     string[3] = tm_p->tm_mday;
  137.     string[4] = tm_p->tm_hour;
  138.     string[5] = tm_p->tm_min;
  139.     string[6] = tm_p->tm_sec;
  140.     string[7] = 0;
  141.     *length = 8;
  142. #ifndef cygwin
  143.     /*
  144.      * Timezone offset
  145.      */
  146.     {
  147. #ifdef STRUCT_TM_HAS_TM_GMTOFF
  148.     const int tzoffset = tm_p->tm_gmtoff;
  149. #else
  150.     const int tzoffset = timezone;
  151. #endif
  152.     if (tzoffset > 0)
  153.         string[8] = '-';
  154.     else
  155.         string[8] = '+';
  156.     string[9] = abs(tzoffset) / 3600;
  157.     string[10] = (abs(tzoffset) - string[9] * 3600) / 60;
  158.     *length = 11;
  159.     }
  160. #endif
  161. #ifdef SYSV
  162.     /*
  163.      * Daylight saving time
  164.      */
  165.     if (tm_p->tm_isdst > 0) {
  166.         /*
  167.          * Assume add one hour 
  168.          */
  169.         if (string[8] == '-')
  170.             --string[9];
  171.         else
  172.             ++string[9];
  173.         if (string[9] == 0)
  174.             string[8] = '+';
  175.     }
  176. #endif
  177.     return string;
  178. }
  179. time_t
  180. ctime_to_timet(char *str)
  181. {
  182.     struct tm       tm;
  183.     if (strlen(str) < 24)
  184.         return 0;
  185.     /*
  186.      * Month 
  187.      */
  188.     if (!strncmp(str + 4, "Jan", 3))
  189.         tm.tm_mon = 0;
  190.     else if (!strncmp(str + 4, "Feb", 3))
  191.         tm.tm_mon = 1;
  192.     else if (!strncmp(str + 4, "Mar", 3))
  193.         tm.tm_mon = 2;
  194.     else if (!strncmp(str + 4, "Apr", 3))
  195.         tm.tm_mon = 3;
  196.     else if (!strncmp(str + 4, "May", 3))
  197.         tm.tm_mon = 4;
  198.     else if (!strncmp(str + 4, "Jun", 3))
  199.         tm.tm_mon = 5;
  200.     else if (!strncmp(str + 4, "Jul", 3))
  201.         tm.tm_mon = 6;
  202.     else if (!strncmp(str + 4, "Aug", 3))
  203.         tm.tm_mon = 7;
  204.     else if (!strncmp(str + 4, "Sep", 3))
  205.         tm.tm_mon = 8;
  206.     else if (!strncmp(str + 4, "Oct", 3))
  207.         tm.tm_mon = 9;
  208.     else if (!strncmp(str + 4, "Nov", 3))
  209.         tm.tm_mon = 10;
  210.     else if (!strncmp(str + 4, "Dec", 3))
  211.         tm.tm_mon = 11;
  212.     else
  213.         return 0;
  214.     tm.tm_mday = atoi(str + 8);
  215.     tm.tm_hour = atoi(str + 11);
  216.     tm.tm_min = atoi(str + 14);
  217.     tm.tm_sec = atoi(str + 17);
  218.     tm.tm_year = atoi(str + 20) - 1900;
  219.     /*
  220.      *  Cope with timezone and DST
  221.      */
  222. #ifdef SYSV
  223.     if (daylight)
  224.         tm.tm_isdst = 1;
  225.     tm.tm_sec -= timezone;
  226. #endif
  227.     return (mktime(&tm));
  228. }
  229. /*
  230.  * blatantly lifted from opensmp 
  231.  */
  232. char
  233. check_rowstatus_transition(int oldValue, int newValue)
  234. {
  235.     /*
  236.      * From the SNMPv2-TC MIB:
  237.      *                                          STATE
  238.      *               +--------------+-----------+-------------+-------------
  239.      *               |      A       |     B     |      C      |      D
  240.      *               |              |status col.|status column|
  241.      *               |status column |    is     |      is     |status column
  242.      *     ACTION    |does not exist|  notReady | notInService|  is active
  243.      * --------------+--------------+-----------+-------------+-------------
  244.      * set status    |noError    ->D|inconsist- |inconsistent-|inconsistent-
  245.      * column to     |       or     |   entValue|        Value|        Value
  246.      * createAndGo   |inconsistent- |           |             |
  247.      *               |         Value|           |             |
  248.      * --------------+--------------+-----------+-------------+-------------
  249.      * set status    |noError  see 1|inconsist- |inconsistent-|inconsistent-
  250.      * column to     |       or     |   entValue|        Value|        Value
  251.      * createAndWait |wrongValue    |           |             |
  252.      * --------------+--------------+-----------+-------------+-------------
  253.      * set status    |inconsistent- |inconsist- |noError      |noError
  254.      * column to     |         Value|   entValue|             |
  255.      * active        |              |           |             |
  256.      *               |              |     or    |             |
  257.      *               |              |           |             |
  258.      *               |              |see 2   ->D|see 8     ->D|          ->D
  259.      * --------------+--------------+-----------+-------------+-------------
  260.      * set status    |inconsistent- |inconsist- |noError      |noError   ->C
  261.      * column to     |         Value|   entValue|             |
  262.      * notInService  |              |           |             |
  263.      *               |              |     or    |             |      or
  264.      *               |              |           |             |
  265.      *               |              |see 3   ->C|          ->C|see 6
  266.      * --------------+--------------+-----------+-------------+-------------
  267.      * set status    |noError       |noError    |noError      |noError   ->A
  268.      * column to     |              |           |             |      or
  269.      * destroy       |           ->A|        ->A|          ->A|see 7
  270.      * --------------+--------------+-----------+-------------+-------------
  271.      * set any other |see 4         |noError    |noError      |see 5
  272.      * column to some|              |           |             |
  273.      * value         |              |      see 1|          ->C|          ->D
  274.      * --------------+--------------+-----------+-------------+-------------
  275.      
  276.      *             (1) goto B or C, depending on information available to the
  277.      *             agent.
  278.      
  279.      *             (2) if other variable bindings included in the same PDU,
  280.      *             provide values for all columns which are missing but
  281.      *             required, and all columns have acceptable values, then
  282.      *             return noError and goto D.
  283.      
  284.      *             (3) if other variable bindings included in the same PDU,
  285.      *             provide legal values for all columns which are missing but
  286.      *             required, then return noError and goto C.
  287.      
  288.      *             (4) at the discretion of the agent, the return value may be
  289.      *             either:
  290.      
  291.      *                  inconsistentName:  because the agent does not choose to
  292.      *                  create such an instance when the corresponding
  293.      *                  RowStatus instance does not exist, or
  294.      
  295.      *                  inconsistentValue:  if the supplied value is
  296.      *                  inconsistent with the state of some other MIB object's
  297.      *                  value, or
  298.      
  299.      *                  noError: because the agent chooses to create the
  300.      *                  instance.
  301.      
  302.      *             If noError is returned, then the instance of the status
  303.      *             column must also be created, and the new state is B or C,
  304.      *             depending on the information available to the agent.  If
  305.      *             inconsistentName or inconsistentValue is returned, the row
  306.      *             remains in state A.
  307.      
  308.      *             (5) depending on the MIB definition for the column/table,
  309.      *             either noError or inconsistentValue may be returned.
  310.      
  311.      *             (6) the return value can indicate one of the following
  312.      *             errors:
  313.      
  314.      *                  wrongValue: because the agent does not support
  315.      *                  notInService (e.g., an agent which does not support
  316.      *                  createAndWait), or
  317.      
  318.      *                  inconsistentValue: because the agent is unable to take
  319.      *                  the row out of service at this time, perhaps because it
  320.      *                  is in use and cannot be de-activated.
  321.      
  322.      *             (7) the return value can indicate the following error:
  323.      
  324.      *                  inconsistentValue: because the agent is unable to
  325.      *                  remove the row at this time, perhaps because it is in
  326.      *                  use and cannot be de-activated.
  327.      
  328.      *             (8) the transition to D can fail, e.g., if the values of the
  329.      *             conceptual row are inconsistent, then the error code would
  330.      *             be inconsistentValue.
  331.      
  332.      *             NOTE: Other processing of (this and other varbinds of) the
  333.      *             set request may result in a response other than noError
  334.      *             being returned, e.g., wrongValue, noCreation, etc.
  335.      */
  336.     switch (newValue) {
  337.         /*
  338.          * these two end up being equivelent as far as checking the 
  339.          */
  340.         /*
  341.          * status goes, although the final states are based on the 
  342.          */
  343.         /*
  344.          * newValue. 
  345.          */
  346.     case RS_ACTIVE:
  347.     case RS_NOTINSERVICE:
  348.         if (oldValue == RS_NOTINSERVICE || oldValue == RS_ACTIVE);
  349.         else
  350.             return SNMP_ERR_INCONSISTENTVALUE;
  351.         break;
  352.     case RS_NOTREADY:
  353.         /*
  354.          * Illegal set value. 
  355.          */
  356.         return SNMP_ERR_INCONSISTENTVALUE;
  357.         break;
  358.     case RS_CREATEANDGO:
  359.         if (oldValue != RS_NONEXISTENT)
  360.             /*
  361.              * impossible, we already exist. 
  362.              */
  363.             return SNMP_ERR_INCONSISTENTVALUE;
  364.         break;
  365.     case RS_CREATEANDWAIT:
  366.         if (oldValue != RS_NONEXISTENT)
  367.             /*
  368.              * impossible, we already exist. 
  369.              */
  370.             return SNMP_ERR_INCONSISTENTVALUE;
  371.         break;
  372.     case RS_DESTROY:
  373.         break;
  374.     default:
  375.         return SNMP_ERR_INCONSISTENTVALUE;
  376.         break;
  377.     }
  378.     return SNMP_ERR_NOERROR;
  379. }
  380. char
  381. check_storage_transition(int oldValue, int newValue)
  382. {
  383.     /*
  384.      * From the SNMPv2-TC MIB:
  385.      
  386.      *             "Describes the memory realization of a conceptual row.  A
  387.      *             row which is volatile(2) is lost upon reboot.  A row which
  388.      *             is either nonVolatile(3), permanent(4) or readOnly(5), is
  389.      *             backed up by stable storage.  A row which is permanent(4)
  390.      *             can be changed but not deleted.  A row which is readOnly(5)
  391.      *             cannot be changed nor deleted.
  392.      
  393.      *             If the value of an object with this syntax is either
  394.      *             permanent(4) or readOnly(5), it cannot be written.
  395.      *             Conversely, if the value is either other(1), volatile(2) or
  396.      *             nonVolatile(3), it cannot be modified to be permanent(4) or
  397.      *             readOnly(5).  (All illegal modifications result in a
  398.      *             'wrongValue' error.)
  399.      
  400.      *             Every usage of this textual convention is required to
  401.      *             specify the columnar objects which a permanent(4) row must
  402.      *             at a minimum allow to be writable."
  403.      */
  404.     switch (oldValue) {
  405.     case SNMP_STORAGE_PERMANENT:
  406.     case SNMP_STORAGE_READONLY:
  407.         return SNMP_ERR_INCONSISTENTVALUE;
  408.     case SNMP_STORAGE_NONE:
  409.     case SNMP_STORAGE_OTHER:
  410.     case SNMP_STORAGE_VOLATILE:
  411.     case SNMP_STORAGE_NONVOLATILE:
  412.         if (newValue == SNMP_STORAGE_PERMANENT ||
  413.             newValue == SNMP_STORAGE_READONLY)
  414.             return SNMP_ERR_INCONSISTENTVALUE;
  415.     }
  416.     return SNMP_ERR_NOERROR;
  417. }