dnsmasq: stay close as possible to master branch
[tomato.git] / release / src-rt-6.x.4708 / router / snmp / snmplib / snmp-tc.c
blob9ecdec5be7bc7aa6fa3849e09e36bc2707a34658
1 /*
2 * Host Resources MIB - utility functions - hr_utils.c
4 */
7 #include <net-snmp/net-snmp-config.h>
8 #include <sys/types.h>
9 #if HAVE_NETINET_IN_H
10 #include <netinet/in.h>
11 #endif
12 #if HAVE_STDLIB_H
13 #include <stdlib.h>
14 #endif
15 #include <ctype.h>
16 #if HAVE_STRING_H
17 #include <string.h>
18 #endif
19 #if HAVE_STDLIB_H
20 #include <stdlib.h>
21 #endif
23 #if TIME_WITH_SYS_TIME
24 #ifdef WIN32
25 # include <sys/timeb.h>
26 #else
27 # include <sys/time.h>
28 #endif
29 # include <time.h>
30 #else
31 # if HAVE_SYS_TIME_H
32 # include <sys/time.h>
33 # else
34 # include <time.h>
35 # endif
36 #endif
38 #include <net-snmp/types.h>
39 #include <net-snmp/library/snmp-tc.h> /* for "internal" definitions */
40 #include <net-snmp/library/snmp_api.h>
42 u_char *
43 date_n_time(time_t * when, size_t * length)
45 struct tm *tm_p;
46 static u_char string[11];
49 * Null time
51 if (when == NULL || *when == 0 || *when == (time_t) - 1) {
52 string[0] = 0;
53 string[1] = 0;
54 string[2] = 1;
55 string[3] = 1;
56 string[4] = 0;
57 string[5] = 0;
58 string[6] = 0;
59 string[7] = 0;
60 *length = 8;
61 return string;
66 * Basic 'local' time handling
68 tm_p = localtime(when);
69 *(short *) string = htons(tm_p->tm_year + 1900);
70 string[2] = tm_p->tm_mon + 1;
71 string[3] = tm_p->tm_mday;
72 string[4] = tm_p->tm_hour;
73 string[5] = tm_p->tm_min;
74 string[6] = tm_p->tm_sec;
75 string[7] = 0;
76 *length = 8;
78 #ifndef cygwin
80 * Timezone offset
82 #if !defined(SYSV) && !defined(aix4) && !defined(aix5) && !defined(WIN32) && !defined(irix6)
83 #if !defined(__UCLIBC__)
84 # define timezone tm_p->tm_gmtoff
85 #else
86 // # define timezone tm_gmtoff
87 #endif
88 #endif
89 if (timezone > 0)
90 string[8] = '-';
91 else
92 string[8] = '+';
93 string[9] = abs(timezone) / 3600;
94 string[10] = (abs(timezone) - string[9] * 3600) / 60;
95 *length = 11;
96 #endif
98 #ifdef SYSV
100 * Daylight saving time
102 if (tm_p->tm_isdst > 0) {
104 * Assume add one hour
106 if (string[8] == '-')
107 --string[9];
108 else
109 ++string[9];
111 if (string[9] == 0)
112 string[8] = '+';
114 #endif
116 return string;
120 time_t
121 ctime_to_timet(char *string)
123 struct tm tm;
125 if (strlen(string) < 24)
126 return 0;
129 * Month
131 if (!strncmp(string + 4, "Jan", 3))
132 tm.tm_mon = 0;
133 else if (!strncmp(string + 4, "Feb", 3))
134 tm.tm_mon = 1;
135 else if (!strncmp(string + 4, "Mar", 3))
136 tm.tm_mon = 2;
137 else if (!strncmp(string + 4, "Apr", 3))
138 tm.tm_mon = 3;
139 else if (!strncmp(string + 4, "May", 3))
140 tm.tm_mon = 4;
141 else if (!strncmp(string + 4, "Jun", 3))
142 tm.tm_mon = 5;
143 else if (!strncmp(string + 4, "Jul", 3))
144 tm.tm_mon = 6;
145 else if (!strncmp(string + 4, "Aug", 3))
146 tm.tm_mon = 7;
147 else if (!strncmp(string + 4, "Sep", 3))
148 tm.tm_mon = 8;
149 else if (!strncmp(string + 4, "Oct", 3))
150 tm.tm_mon = 9;
151 else if (!strncmp(string + 4, "Nov", 3))
152 tm.tm_mon = 10;
153 else if (!strncmp(string + 4, "Dec", 3))
154 tm.tm_mon = 11;
155 else
156 return 0;
158 tm.tm_mday = atoi(string + 8);
159 tm.tm_hour = atoi(string + 11);
160 tm.tm_min = atoi(string + 14);
161 tm.tm_sec = atoi(string + 17);
162 tm.tm_year = atoi(string + 20) - 1900;
165 * Cope with timezone and DST
168 #ifdef SYSV
169 if (daylight)
170 tm.tm_isdst = 1;
172 tm.tm_sec -= timezone;
173 #endif
175 return (mktime(&tm));
179 * blatantly lifted from opensmp
181 char
182 check_rowstatus_transition(int oldValue, int newValue)
185 * From the SNMPv2-TC MIB:
186 * STATE
187 * +--------------+-----------+-------------+-------------
188 * | A | B | C | D
189 * | |status col.|status column|
190 * |status column | is | is |status column
191 * ACTION |does not exist| notReady | notInService| is active
192 * --------------+--------------+-----------+-------------+-------------
193 * set status |noError ->D|inconsist- |inconsistent-|inconsistent-
194 * column to | or | entValue| Value| Value
195 * createAndGo |inconsistent- | | |
196 * | Value| | |
197 * --------------+--------------+-----------+-------------+-------------
198 * set status |noError see 1|inconsist- |inconsistent-|inconsistent-
199 * column to | or | entValue| Value| Value
200 * createAndWait |wrongValue | | |
201 * --------------+--------------+-----------+-------------+-------------
202 * set status |inconsistent- |inconsist- |noError |noError
203 * column to | Value| entValue| |
204 * active | | | |
205 * | | or | |
206 * | | | |
207 * | |see 2 ->D|see 8 ->D| ->D
208 * --------------+--------------+-----------+-------------+-------------
209 * set status |inconsistent- |inconsist- |noError |noError ->C
210 * column to | Value| entValue| |
211 * notInService | | | |
212 * | | or | | or
213 * | | | |
214 * | |see 3 ->C| ->C|see 6
215 * --------------+--------------+-----------+-------------+-------------
216 * set status |noError |noError |noError |noError ->A
217 * column to | | | | or
218 * destroy | ->A| ->A| ->A|see 7
219 * --------------+--------------+-----------+-------------+-------------
220 * set any other |see 4 |noError |noError |see 5
221 * column to some| | | |
222 * value | | see 1| ->C| ->D
223 * --------------+--------------+-----------+-------------+-------------
225 * (1) goto B or C, depending on information available to the
226 * agent.
228 * (2) if other variable bindings included in the same PDU,
229 * provide values for all columns which are missing but
230 * required, and all columns have acceptable values, then
231 * return noError and goto D.
233 * (3) if other variable bindings included in the same PDU,
234 * provide legal values for all columns which are missing but
235 * required, then return noError and goto C.
237 * (4) at the discretion of the agent, the return value may be
238 * either:
240 * inconsistentName: because the agent does not choose to
241 * create such an instance when the corresponding
242 * RowStatus instance does not exist, or
244 * inconsistentValue: if the supplied value is
245 * inconsistent with the state of some other MIB object's
246 * value, or
248 * noError: because the agent chooses to create the
249 * instance.
251 * If noError is returned, then the instance of the status
252 * column must also be created, and the new state is B or C,
253 * depending on the information available to the agent. If
254 * inconsistentName or inconsistentValue is returned, the row
255 * remains in state A.
257 * (5) depending on the MIB definition for the column/table,
258 * either noError or inconsistentValue may be returned.
260 * (6) the return value can indicate one of the following
261 * errors:
263 * wrongValue: because the agent does not support
264 * notInService (e.g., an agent which does not support
265 * createAndWait), or
267 * inconsistentValue: because the agent is unable to take
268 * the row out of service at this time, perhaps because it
269 * is in use and cannot be de-activated.
271 * (7) the return value can indicate the following error:
273 * inconsistentValue: because the agent is unable to
274 * remove the row at this time, perhaps because it is in
275 * use and cannot be de-activated.
277 * (8) the transition to D can fail, e.g., if the values of the
278 * conceptual row are inconsistent, then the error code would
279 * be inconsistentValue.
281 * NOTE: Other processing of (this and other varbinds of) the
282 * set request may result in a response other than noError
283 * being returned, e.g., wrongValue, noCreation, etc.
286 switch (newValue) {
288 * these two end up being equivelent as far as checking the
291 * status goes, although the final states are based on the
294 * newValue.
296 case RS_ACTIVE:
297 case RS_NOTINSERVICE:
298 if (oldValue == RS_NOTINSERVICE || oldValue == RS_ACTIVE);
299 else
300 return SNMP_ERR_INCONSISTENTVALUE;
301 break;
303 case RS_NOTREADY:
305 * Illegal set value.
307 return SNMP_ERR_INCONSISTENTVALUE;
308 break;
310 case RS_CREATEANDGO:
311 if (oldValue != RS_NONEXISTENT)
313 * impossible, we already exist.
315 return SNMP_ERR_INCONSISTENTVALUE;
316 break;
318 case RS_CREATEANDWAIT:
319 if (oldValue != RS_NONEXISTENT)
321 * impossible, we already exist.
323 return SNMP_ERR_INCONSISTENTVALUE;
324 break;
326 case RS_DESTROY:
327 break;
329 default:
330 return SNMP_ERR_INCONSISTENTVALUE;
331 break;
334 return SNMP_ERR_NOERROR;
337 char
338 check_storage_transition(int oldValue, int newValue)
341 * From the SNMPv2-TC MIB:
343 * "Describes the memory realization of a conceptual row. A
344 * row which is volatile(2) is lost upon reboot. A row which
345 * is either nonVolatile(3), permanent(4) or readOnly(5), is
346 * backed up by stable storage. A row which is permanent(4)
347 * can be changed but not deleted. A row which is readOnly(5)
348 * cannot be changed nor deleted.
350 * If the value of an object with this syntax is either
351 * permanent(4) or readOnly(5), it cannot be written.
352 * Conversely, if the value is either other(1), volatile(2) or
353 * nonVolatile(3), it cannot be modified to be permanent(4) or
354 * readOnly(5). (All illegal modifications result in a
355 * 'wrongValue' error.)
357 * Every usage of this textual convention is required to
358 * specify the columnar objects which a permanent(4) row must
359 * at a minimum allow to be writable."
361 switch (oldValue) {
362 case SNMP_STORAGE_PERMANENT:
363 case SNMP_STORAGE_READONLY:
364 return SNMP_ERR_INCONSISTENTVALUE;
366 case SNMP_STORAGE_NONE:
367 case SNMP_STORAGE_OTHER:
368 case SNMP_STORAGE_VOLATILE:
369 case SNMP_STORAGE_NONVOLATILE:
370 if (newValue == SNMP_STORAGE_PERMANENT ||
371 newValue == SNMP_STORAGE_READONLY)
372 return SNMP_ERR_INCONSISTENTVALUE;
375 return SNMP_ERR_NOERROR;