snmp-tc.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:14k
- /*
- * Host Resources MIB - utility functions - hr_utils.c
- *
- */
- #include <net-snmp/net-snmp-config.h>
- #include <sys/types.h>
- #if HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #include <ctype.h>
- #if HAVE_STRING_H
- #include <string.h>
- #endif
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if TIME_WITH_SYS_TIME
- #ifdef WIN32
- # include <sys/timeb.h>
- #else
- # include <sys/time.h>
- #endif
- # include <time.h>
- #else
- # if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
- #endif
- #include <net-snmp/types.h>
- #include <net-snmp/library/snmp-tc.h> /* for "internal" definitions */
- #include <net-snmp/library/snmp_api.h>
- /*
- DateAndTime ::= TEXTUAL-CONVENTION
- DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
- STATUS current
- DESCRIPTION
- "A date-time specification.
- field octets contents range
- ----- ------ -------- -----
- 1 1-2 year* 0..65536
- 2 3 month 1..12
- 3 4 day 1..31
- 4 5 hour 0..23
- 5 6 minutes 0..59
- 6 7 seconds 0..60
- (use 60 for leap-second)
- 7 8 deci-seconds 0..9
- 8 9 direction from UTC '+' / '-'
- 9 10 hours from UTC* 0..13
- 10 11 minutes from UTC 0..59
- * Notes:
- - the value of year is in network-byte order
- - daylight saving time in New Zealand is +13
- For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
- displayed as:
- 1992-5-26,13:30:15.0,-4:0
- Note that if only local time is known, then timezone
- information (fields 8-10) is not present."
- SYNTAX OCTET STRING (SIZE (8 | 11))
- */
- int
- netsnmp_dateandtime_set_buf_from_vars(u_char *buf, size_t *bufsize,
- u_short year, u_char month, u_char day,
- u_char hour, u_char minutes,
- u_char seconds, u_char deci_seconds,
- int utc_offset_direction,
- u_char utc_offset_hours,
- u_char utc_offset_minutes)
- {
- u_short tmp_year = htons(year);
- /*
- * if we have a utc offset, need 11 bytes. Otherwise we
- * just need 8 bytes.
- */
- if(utc_offset_direction) {
- if(*bufsize < 11)
- return SNMPERR_RANGE;
- /*
- * set utc offset data
- */
- buf[8] = (utc_offset_direction < 0) ? '-' : '+';
- buf[9] = utc_offset_hours;
- buf[10] = utc_offset_minutes;
- *bufsize = 11;
- }
- else if(*bufsize < 8)
- return SNMPERR_RANGE;
- else
- *bufsize = 8;
- /*
- * set basic date/time data
- */
- memcpy(buf, &tmp_year, sizeof(tmp_year));
- buf[2] = month;
- buf[3] = day;
- buf[4] = hour;
- buf[5] = minutes;
- buf[6] = seconds;
- buf[7] = deci_seconds;
- return SNMPERR_SUCCESS;
- }
- u_char *
- date_n_time(time_t * when, size_t * length)
- {
- struct tm *tm_p;
- static u_char string[11];
- unsigned short yauron;
- /*
- * Null time
- */
- if (when == NULL || *when == 0 || *when == (time_t) - 1) {
- string[0] = 0;
- string[1] = 0;
- string[2] = 1;
- string[3] = 1;
- string[4] = 0;
- string[5] = 0;
- string[6] = 0;
- string[7] = 0;
- *length = 8;
- return string;
- }
- /*
- * Basic 'local' time handling
- */
- tm_p = localtime(when);
- yauron = tm_p->tm_year + 1900;
- string[0] = (u_char)(yauron >> 8);
- string[1] = (u_char)yauron;
- string[2] = tm_p->tm_mon + 1;
- string[3] = tm_p->tm_mday;
- string[4] = tm_p->tm_hour;
- string[5] = tm_p->tm_min;
- string[6] = tm_p->tm_sec;
- string[7] = 0;
- *length = 8;
- #ifndef cygwin
- /*
- * Timezone offset
- */
- {
- #ifdef STRUCT_TM_HAS_TM_GMTOFF
- const int tzoffset = tm_p->tm_gmtoff;
- #else
- const int tzoffset = timezone;
- #endif
- if (tzoffset > 0)
- string[8] = '-';
- else
- string[8] = '+';
- string[9] = abs(tzoffset) / 3600;
- string[10] = (abs(tzoffset) - string[9] * 3600) / 60;
- *length = 11;
- }
- #endif
- #ifdef SYSV
- /*
- * Daylight saving time
- */
- if (tm_p->tm_isdst > 0) {
- /*
- * Assume add one hour
- */
- if (string[8] == '-')
- --string[9];
- else
- ++string[9];
- if (string[9] == 0)
- string[8] = '+';
- }
- #endif
- return string;
- }
- time_t
- ctime_to_timet(char *str)
- {
- struct tm tm;
- if (strlen(str) < 24)
- return 0;
- /*
- * Month
- */
- if (!strncmp(str + 4, "Jan", 3))
- tm.tm_mon = 0;
- else if (!strncmp(str + 4, "Feb", 3))
- tm.tm_mon = 1;
- else if (!strncmp(str + 4, "Mar", 3))
- tm.tm_mon = 2;
- else if (!strncmp(str + 4, "Apr", 3))
- tm.tm_mon = 3;
- else if (!strncmp(str + 4, "May", 3))
- tm.tm_mon = 4;
- else if (!strncmp(str + 4, "Jun", 3))
- tm.tm_mon = 5;
- else if (!strncmp(str + 4, "Jul", 3))
- tm.tm_mon = 6;
- else if (!strncmp(str + 4, "Aug", 3))
- tm.tm_mon = 7;
- else if (!strncmp(str + 4, "Sep", 3))
- tm.tm_mon = 8;
- else if (!strncmp(str + 4, "Oct", 3))
- tm.tm_mon = 9;
- else if (!strncmp(str + 4, "Nov", 3))
- tm.tm_mon = 10;
- else if (!strncmp(str + 4, "Dec", 3))
- tm.tm_mon = 11;
- else
- return 0;
- tm.tm_mday = atoi(str + 8);
- tm.tm_hour = atoi(str + 11);
- tm.tm_min = atoi(str + 14);
- tm.tm_sec = atoi(str + 17);
- tm.tm_year = atoi(str + 20) - 1900;
- /*
- * Cope with timezone and DST
- */
- #ifdef SYSV
- if (daylight)
- tm.tm_isdst = 1;
- tm.tm_sec -= timezone;
- #endif
- return (mktime(&tm));
- }
- /*
- * blatantly lifted from opensmp
- */
- char
- check_rowstatus_transition(int oldValue, int newValue)
- {
- /*
- * From the SNMPv2-TC MIB:
- * STATE
- * +--------------+-----------+-------------+-------------
- * | A | B | C | D
- * | |status col.|status column|
- * |status column | is | is |status column
- * ACTION |does not exist| notReady | notInService| is active
- * --------------+--------------+-----------+-------------+-------------
- * set status |noError ->D|inconsist- |inconsistent-|inconsistent-
- * column to | or | entValue| Value| Value
- * createAndGo |inconsistent- | | |
- * | Value| | |
- * --------------+--------------+-----------+-------------+-------------
- * set status |noError see 1|inconsist- |inconsistent-|inconsistent-
- * column to | or | entValue| Value| Value
- * createAndWait |wrongValue | | |
- * --------------+--------------+-----------+-------------+-------------
- * set status |inconsistent- |inconsist- |noError |noError
- * column to | Value| entValue| |
- * active | | | |
- * | | or | |
- * | | | |
- * | |see 2 ->D|see 8 ->D| ->D
- * --------------+--------------+-----------+-------------+-------------
- * set status |inconsistent- |inconsist- |noError |noError ->C
- * column to | Value| entValue| |
- * notInService | | | |
- * | | or | | or
- * | | | |
- * | |see 3 ->C| ->C|see 6
- * --------------+--------------+-----------+-------------+-------------
- * set status |noError |noError |noError |noError ->A
- * column to | | | | or
- * destroy | ->A| ->A| ->A|see 7
- * --------------+--------------+-----------+-------------+-------------
- * set any other |see 4 |noError |noError |see 5
- * column to some| | | |
- * value | | see 1| ->C| ->D
- * --------------+--------------+-----------+-------------+-------------
-
- * (1) goto B or C, depending on information available to the
- * agent.
-
- * (2) if other variable bindings included in the same PDU,
- * provide values for all columns which are missing but
- * required, and all columns have acceptable values, then
- * return noError and goto D.
-
- * (3) if other variable bindings included in the same PDU,
- * provide legal values for all columns which are missing but
- * required, then return noError and goto C.
-
- * (4) at the discretion of the agent, the return value may be
- * either:
-
- * inconsistentName: because the agent does not choose to
- * create such an instance when the corresponding
- * RowStatus instance does not exist, or
-
- * inconsistentValue: if the supplied value is
- * inconsistent with the state of some other MIB object's
- * value, or
-
- * noError: because the agent chooses to create the
- * instance.
-
- * If noError is returned, then the instance of the status
- * column must also be created, and the new state is B or C,
- * depending on the information available to the agent. If
- * inconsistentName or inconsistentValue is returned, the row
- * remains in state A.
-
- * (5) depending on the MIB definition for the column/table,
- * either noError or inconsistentValue may be returned.
-
- * (6) the return value can indicate one of the following
- * errors:
-
- * wrongValue: because the agent does not support
- * notInService (e.g., an agent which does not support
- * createAndWait), or
-
- * inconsistentValue: because the agent is unable to take
- * the row out of service at this time, perhaps because it
- * is in use and cannot be de-activated.
-
- * (7) the return value can indicate the following error:
-
- * inconsistentValue: because the agent is unable to
- * remove the row at this time, perhaps because it is in
- * use and cannot be de-activated.
-
- * (8) the transition to D can fail, e.g., if the values of the
- * conceptual row are inconsistent, then the error code would
- * be inconsistentValue.
-
- * NOTE: Other processing of (this and other varbinds of) the
- * set request may result in a response other than noError
- * being returned, e.g., wrongValue, noCreation, etc.
- */
- switch (newValue) {
- /*
- * these two end up being equivelent as far as checking the
- */
- /*
- * status goes, although the final states are based on the
- */
- /*
- * newValue.
- */
- case RS_ACTIVE:
- case RS_NOTINSERVICE:
- if (oldValue == RS_NOTINSERVICE || oldValue == RS_ACTIVE);
- else
- return SNMP_ERR_INCONSISTENTVALUE;
- break;
- case RS_NOTREADY:
- /*
- * Illegal set value.
- */
- return SNMP_ERR_INCONSISTENTVALUE;
- break;
- case RS_CREATEANDGO:
- if (oldValue != RS_NONEXISTENT)
- /*
- * impossible, we already exist.
- */
- return SNMP_ERR_INCONSISTENTVALUE;
- break;
- case RS_CREATEANDWAIT:
- if (oldValue != RS_NONEXISTENT)
- /*
- * impossible, we already exist.
- */
- return SNMP_ERR_INCONSISTENTVALUE;
- break;
- case RS_DESTROY:
- break;
- default:
- return SNMP_ERR_INCONSISTENTVALUE;
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- char
- check_storage_transition(int oldValue, int newValue)
- {
- /*
- * From the SNMPv2-TC MIB:
-
- * "Describes the memory realization of a conceptual row. A
- * row which is volatile(2) is lost upon reboot. A row which
- * is either nonVolatile(3), permanent(4) or readOnly(5), is
- * backed up by stable storage. A row which is permanent(4)
- * can be changed but not deleted. A row which is readOnly(5)
- * cannot be changed nor deleted.
-
- * If the value of an object with this syntax is either
- * permanent(4) or readOnly(5), it cannot be written.
- * Conversely, if the value is either other(1), volatile(2) or
- * nonVolatile(3), it cannot be modified to be permanent(4) or
- * readOnly(5). (All illegal modifications result in a
- * 'wrongValue' error.)
-
- * Every usage of this textual convention is required to
- * specify the columnar objects which a permanent(4) row must
- * at a minimum allow to be writable."
- */
- switch (oldValue) {
- case SNMP_STORAGE_PERMANENT:
- case SNMP_STORAGE_READONLY:
- return SNMP_ERR_INCONSISTENTVALUE;
- case SNMP_STORAGE_NONE:
- case SNMP_STORAGE_OTHER:
- case SNMP_STORAGE_VOLATILE:
- case SNMP_STORAGE_NONVOLATILE:
- if (newValue == SNMP_STORAGE_PERMANENT ||
- newValue == SNMP_STORAGE_READONLY)
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- return SNMP_ERR_NOERROR;
- }