fix outgoing QOS prios
[tomato.git] / release / src / router / snmp / snmplib / snmp.c
blobdcb4ef86e5b5f64c50b8af2c657a5d8736158f48
1 /*
2 * Simple Network Management Protocol (RFC 1067).
4 */
5 /**********************************************************************
6 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
8 All Rights Reserved
10 Permission to use, copy, modify, and distribute this software and its
11 documentation for any purpose and without fee is hereby granted,
12 provided that the above copyright notice appear in all copies and that
13 both that copyright notice and this permission notice appear in
14 supporting documentation, and that the name of CMU not be
15 used in advertising or publicity pertaining to distribution of the
16 software without specific, written prior permission.
18 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24 SOFTWARE.
25 ******************************************************************/
27 #include <net-snmp/net-snmp-config.h>
28 #include <ctype.h>
30 #ifdef KINETICS
31 #include "gw.h"
32 #include "ab.h"
33 #include "inet.h"
34 #include "fp4/cmdmacro.h"
35 #include "fp4/pbuf.h"
36 #include "glob.h"
37 #endif
39 #include <stdio.h>
40 #include <stdlib.h>
42 #include <sys/types.h>
43 #ifdef HAVE_STRING_H
44 #include <string.h>
45 #else
46 #include <strings.h>
47 #endif
48 #if HAVE_NETINET_IN_H
49 #include <netinet/in.h>
50 #endif
51 #ifdef HAVE_SYS_SELECT_H
52 #include <sys/select.h>
53 #endif
54 #if HAVE_WINSOCK_H
55 #include <winsock.h>
56 #endif
57 #ifndef NULL
58 #define NULL 0
59 #endif
61 #if HAVE_DMALLOC_H
62 #include <dmalloc.h>
63 #endif
65 #ifdef vms
66 #include <in.h>
67 #endif
69 #include <net-snmp/types.h>
70 #include <net-snmp/output_api.h>
72 #include <net-snmp/library/asn1.h>
73 #include <net-snmp/library/snmp.h> /* for "internal" definitions */
74 #include <net-snmp/library/snmp_api.h>
75 #include <net-snmp/library/mib.h>
77 void
78 xdump(const u_char * cp, size_t length, const char *prefix)
80 int col, count;
81 char *buffer;
83 buffer = (char *) malloc(strlen(prefix) + 80);
84 if (!buffer) {
85 snmp_log(LOG_NOTICE,
86 "xdump: malloc failed. packet-dump skipped\n");
87 return;
90 count = 0;
91 while (count < (int) length) {
92 strcpy(buffer, prefix);
93 sprintf(buffer + strlen(buffer), "%.4d: ", count);
95 for (col = 0; ((count + col) < (int) length) && col < 16; col++) {
96 sprintf(buffer + strlen(buffer), "%02X ", cp[count + col]);
97 if (col % 4 == 3)
98 strcat(buffer, " ");
100 for (; col < 16; col++) { /* pad end of buffer with zeros */
101 strcat(buffer, " ");
102 if (col % 4 == 3)
103 strcat(buffer, " ");
105 strcat(buffer, " ");
106 for (col = 0; ((count + col) < (int) length) && col < 16; col++) {
107 buffer[col + 60] =
108 isprint(cp[count + col]) ? cp[count + col] : '.';
110 buffer[col + 60] = '\n';
111 buffer[col + 60 + 1] = 0;
112 snmp_log(LOG_DEBUG, "%s", buffer);
113 count += col;
115 snmp_log(LOG_DEBUG, "\n");
116 free(buffer);
118 } /* end xdump() */
121 * u_char * snmp_parse_var_op(
122 * u_char *data IN - pointer to the start of object
123 * oid *var_name OUT - object id of variable
124 * int *var_name_len IN/OUT - length of variable name
125 * u_char *var_val_type OUT - type of variable (int or octet string) (one byte)
126 * int *var_val_len OUT - length of variable
127 * u_char **var_val OUT - pointer to ASN1 encoded value of variable
128 * int *listlength IN/OUT - number of valid bytes left in var_op_list
131 u_char *
132 snmp_parse_var_op(u_char * data,
133 oid * var_name,
134 size_t * var_name_len,
135 u_char * var_val_type,
136 size_t * var_val_len,
137 u_char ** var_val, size_t * listlength)
139 u_char var_op_type;
140 size_t var_op_len = *listlength;
141 u_char *var_op_start = data;
143 data = asn_parse_sequence(data, &var_op_len, &var_op_type,
144 (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op");
145 if (data == NULL) {
147 * msg detail is set
149 return NULL;
151 DEBUGDUMPHEADER("recv", "Name");
152 data =
153 asn_parse_objid(data, &var_op_len, &var_op_type, var_name,
154 var_name_len);
155 DEBUGINDENTLESS();
156 if (data == NULL) {
157 ERROR_MSG("No OID for variable");
158 return NULL;
160 if (var_op_type !=
161 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID))
162 return NULL;
163 *var_val = data; /* save pointer to this object */
165 * find out what type of object this is
167 data = asn_parse_header(data, &var_op_len, var_val_type);
168 if (data == NULL) {
169 ERROR_MSG("No header for value");
170 return NULL;
173 * XXX no check for type!
175 *var_val_len = var_op_len;
176 data += var_op_len;
177 *listlength -= (int) (data - var_op_start);
178 return data;
182 * u_char * snmp_build_var_op(
183 * u_char *data IN - pointer to the beginning of the output buffer
184 * oid *var_name IN - object id of variable
185 * int *var_name_len IN - length of object id
186 * u_char var_val_type IN - type of variable
187 * int var_val_len IN - length of variable
188 * u_char *var_val IN - value of variable
189 * int *listlength IN/OUT - number of valid bytes left in
190 * output buffer
193 u_char *
194 snmp_build_var_op(u_char * data,
195 oid * var_name,
196 size_t * var_name_len,
197 u_char var_val_type,
198 size_t var_val_len,
199 u_char * var_val, size_t * listlength)
201 size_t dummyLen, headerLen;
202 u_char *dataPtr;
204 dummyLen = *listlength;
205 dataPtr = data;
206 #if 0
207 data = asn_build_sequence(data, &dummyLen,
208 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
210 if (data == NULL) {
211 return NULL;
213 #endif
214 if (dummyLen < 4)
215 return NULL;
216 data += 4;
217 dummyLen -= 4;
219 headerLen = data - dataPtr;
220 *listlength -= headerLen;
221 DEBUGDUMPHEADER("send", "Name");
222 data = asn_build_objid(data, listlength,
223 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
224 ASN_OBJECT_ID), var_name,
225 *var_name_len);
226 DEBUGINDENTLESS();
227 if (data == NULL) {
228 ERROR_MSG("Can't build OID for variable");
229 return NULL;
231 DEBUGDUMPHEADER("send", "Value");
232 switch (var_val_type) {
233 case ASN_INTEGER:
234 data = asn_build_int(data, listlength, var_val_type,
235 (long *) var_val, var_val_len);
236 break;
237 case ASN_GAUGE:
238 case ASN_COUNTER:
239 case ASN_TIMETICKS:
240 case ASN_UINTEGER:
241 data = asn_build_unsigned_int(data, listlength, var_val_type,
242 (u_long *) var_val, var_val_len);
243 break;
244 #ifdef OPAQUE_SPECIAL_TYPES
245 case ASN_OPAQUE_COUNTER64:
246 case ASN_OPAQUE_U64:
247 #endif
248 case ASN_COUNTER64:
249 data = asn_build_unsigned_int64(data, listlength, var_val_type,
250 (struct counter64 *) var_val,
251 var_val_len);
252 break;
253 case ASN_OCTET_STR:
254 case ASN_IPADDRESS:
255 case ASN_OPAQUE:
256 case ASN_NSAP:
257 data = asn_build_string(data, listlength, var_val_type,
258 var_val, var_val_len);
259 break;
260 case ASN_OBJECT_ID:
261 data = asn_build_objid(data, listlength, var_val_type,
262 (oid *) var_val, var_val_len / sizeof(oid));
263 break;
264 case ASN_NULL:
265 data = asn_build_null(data, listlength, var_val_type);
266 break;
267 case ASN_BIT_STR:
268 data = asn_build_bitstring(data, listlength, var_val_type,
269 var_val, var_val_len);
270 break;
271 case SNMP_NOSUCHOBJECT:
272 case SNMP_NOSUCHINSTANCE:
273 case SNMP_ENDOFMIBVIEW:
274 data = asn_build_null(data, listlength, var_val_type);
275 break;
276 #ifdef OPAQUE_SPECIAL_TYPES
277 case ASN_OPAQUE_FLOAT:
278 data = asn_build_float(data, listlength, var_val_type,
279 (float *) var_val, var_val_len);
280 break;
281 case ASN_OPAQUE_DOUBLE:
282 data = asn_build_double(data, listlength, var_val_type,
283 (double *) var_val, var_val_len);
284 break;
285 case ASN_OPAQUE_I64:
286 data = asn_build_signed_int64(data, listlength, var_val_type,
287 (struct counter64 *) var_val,
288 var_val_len);
289 break;
290 #endif /* OPAQUE_SPECIAL_TYPES */
291 default:
292 ERROR_MSG("wrong type");
293 return NULL;
295 DEBUGINDENTLESS();
296 if (data == NULL) {
297 ERROR_MSG("Can't build value");
298 return NULL;
300 dummyLen = (data - dataPtr) - headerLen;
302 asn_build_sequence(dataPtr, &dummyLen,
303 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
304 dummyLen);
305 return data;
308 #ifdef USE_REVERSE_ASNENCODING
310 snmp_realloc_rbuild_var_op(u_char ** pkt, size_t * pkt_len,
311 size_t * offset, int allow_realloc,
312 const oid * var_name, size_t * var_name_len,
313 u_char var_val_type,
314 u_char * var_val, size_t var_val_len)
316 size_t start_offset = *offset;
317 int rc = 0;
320 * Encode the value.
322 DEBUGDUMPHEADER("send", "Value");
324 switch (var_val_type) {
325 case ASN_INTEGER:
326 rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc,
327 var_val_type, (long *) var_val,
328 var_val_len);
329 break;
331 case ASN_GAUGE:
332 case ASN_COUNTER:
333 case ASN_TIMETICKS:
334 case ASN_UINTEGER:
335 rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset,
336 allow_realloc, var_val_type,
337 (u_long *) var_val,
338 var_val_len);
339 break;
341 #ifdef OPAQUE_SPECIAL_TYPES
342 case ASN_OPAQUE_COUNTER64:
343 case ASN_OPAQUE_U64:
344 #endif
345 case ASN_COUNTER64:
346 rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset,
347 allow_realloc, var_val_type,
348 (struct counter64 *)
349 var_val, var_val_len);
350 break;
352 case ASN_OCTET_STR:
353 case ASN_IPADDRESS:
354 case ASN_OPAQUE:
355 case ASN_NSAP:
356 rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc,
357 var_val_type, var_val, var_val_len);
358 break;
360 case ASN_OBJECT_ID:
361 rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
362 var_val_type, (oid *) var_val,
363 var_val_len / sizeof(oid));
364 break;
366 case ASN_NULL:
367 rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
368 var_val_type);
369 break;
371 case ASN_BIT_STR:
372 rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset,
373 allow_realloc, var_val_type,
374 var_val, var_val_len);
375 break;
377 case SNMP_NOSUCHOBJECT:
378 case SNMP_NOSUCHINSTANCE:
379 case SNMP_ENDOFMIBVIEW:
380 rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc,
381 var_val_type);
382 break;
384 #ifdef OPAQUE_SPECIAL_TYPES
385 case ASN_OPAQUE_FLOAT:
386 rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc,
387 var_val_type, (float *) var_val,
388 var_val_len);
389 break;
391 case ASN_OPAQUE_DOUBLE:
392 rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc,
393 var_val_type, (double *) var_val,
394 var_val_len);
395 break;
397 case ASN_OPAQUE_I64:
398 rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset,
399 allow_realloc, var_val_type,
400 (struct counter64 *) var_val,
401 var_val_len);
402 break;
403 #endif /* OPAQUE_SPECIAL_TYPES */
404 default:
405 ERROR_MSG("wrong type");
406 return 0;
408 DEBUGINDENTLESS();
410 if (rc == 0) {
411 ERROR_MSG("Can't build value");
412 return 0;
416 * Build the OID.
419 DEBUGDUMPHEADER("send", "Name");
420 rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc,
421 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
422 ASN_OBJECT_ID), var_name,
423 *var_name_len);
424 DEBUGINDENTLESS();
425 if (rc == 0) {
426 ERROR_MSG("Can't build OID for variable");
427 return 0;
431 * Build the sequence header.
434 rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc,
435 (u_char) (ASN_SEQUENCE |
436 ASN_CONSTRUCTOR),
437 *offset - start_offset);
438 return rc;
441 #endif /* USE_REVERSE_ASNENCODING */