2 * Simple Network Management Protocol (RFC 1067).
5 /**********************************************************************
6 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
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
25 ******************************************************************/
27 #include <net-snmp/net-snmp-config.h>
34 #include "fp4/cmdmacro.h"
42 #include <sys/types.h>
49 #include <netinet/in.h>
51 #ifdef HAVE_SYS_SELECT_H
52 #include <sys/select.h>
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>
78 xdump(const u_char
* cp
, size_t length
, const char *prefix
)
83 buffer
= (char *) malloc(strlen(prefix
) + 80);
86 "xdump: malloc failed. packet-dump skipped\n");
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
]);
100 for (; col
< 16; col
++) { /* pad end of buffer with zeros */
106 for (col
= 0; ((count
+ col
) < (int) length
) && col
< 16; col
++) {
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
);
115 snmp_log(LOG_DEBUG
, "\n");
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
132 snmp_parse_var_op(u_char
* data
,
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
)
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");
151 DEBUGDUMPHEADER("recv", "Name");
153 asn_parse_objid(data
, &var_op_len
, &var_op_type
, var_name
,
157 ERROR_MSG("No OID for variable");
161 (u_char
) (ASN_UNIVERSAL
| ASN_PRIMITIVE
| ASN_OBJECT_ID
))
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
);
169 ERROR_MSG("No header for value");
173 * XXX no check for type!
175 *var_val_len
= var_op_len
;
177 *listlength
-= (int) (data
- var_op_start
);
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
194 snmp_build_var_op(u_char
* data
,
196 size_t * var_name_len
,
199 u_char
* var_val
, size_t * listlength
)
201 size_t dummyLen
, headerLen
;
204 dummyLen
= *listlength
;
207 data
= asn_build_sequence(data
, &dummyLen
,
208 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
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
,
228 ERROR_MSG("Can't build OID for variable");
231 DEBUGDUMPHEADER("send", "Value");
232 switch (var_val_type
) {
234 data
= asn_build_int(data
, listlength
, var_val_type
,
235 (long *) var_val
, var_val_len
);
241 data
= asn_build_unsigned_int(data
, listlength
, var_val_type
,
242 (u_long
*) var_val
, var_val_len
);
244 #ifdef OPAQUE_SPECIAL_TYPES
245 case ASN_OPAQUE_COUNTER64
:
249 data
= asn_build_unsigned_int64(data
, listlength
, var_val_type
,
250 (struct counter64
*) var_val
,
257 data
= asn_build_string(data
, listlength
, var_val_type
,
258 var_val
, var_val_len
);
261 data
= asn_build_objid(data
, listlength
, var_val_type
,
262 (oid
*) var_val
, var_val_len
/ sizeof(oid
));
265 data
= asn_build_null(data
, listlength
, var_val_type
);
268 data
= asn_build_bitstring(data
, listlength
, var_val_type
,
269 var_val
, var_val_len
);
271 case SNMP_NOSUCHOBJECT
:
272 case SNMP_NOSUCHINSTANCE
:
273 case SNMP_ENDOFMIBVIEW
:
274 data
= asn_build_null(data
, listlength
, var_val_type
);
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
);
281 case ASN_OPAQUE_DOUBLE
:
282 data
= asn_build_double(data
, listlength
, var_val_type
,
283 (double *) var_val
, var_val_len
);
286 data
= asn_build_signed_int64(data
, listlength
, var_val_type
,
287 (struct counter64
*) var_val
,
290 #endif /* OPAQUE_SPECIAL_TYPES */
292 ERROR_MSG("wrong type");
297 ERROR_MSG("Can't build value");
300 dummyLen
= (data
- dataPtr
) - headerLen
;
302 asn_build_sequence(dataPtr
, &dummyLen
,
303 (u_char
) (ASN_SEQUENCE
| ASN_CONSTRUCTOR
),
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
,
314 u_char
* var_val
, size_t var_val_len
)
316 size_t start_offset
= *offset
;
322 DEBUGDUMPHEADER("send", "Value");
324 switch (var_val_type
) {
326 rc
= asn_realloc_rbuild_int(pkt
, pkt_len
, offset
, allow_realloc
,
327 var_val_type
, (long *) var_val
,
335 rc
= asn_realloc_rbuild_unsigned_int(pkt
, pkt_len
, offset
,
336 allow_realloc
, var_val_type
,
341 #ifdef OPAQUE_SPECIAL_TYPES
342 case ASN_OPAQUE_COUNTER64
:
346 rc
= asn_realloc_rbuild_unsigned_int64(pkt
, pkt_len
, offset
,
347 allow_realloc
, var_val_type
,
349 var_val
, var_val_len
);
356 rc
= asn_realloc_rbuild_string(pkt
, pkt_len
, offset
, allow_realloc
,
357 var_val_type
, var_val
, var_val_len
);
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
));
367 rc
= asn_realloc_rbuild_null(pkt
, pkt_len
, offset
, allow_realloc
,
372 rc
= asn_realloc_rbuild_bitstring(pkt
, pkt_len
, offset
,
373 allow_realloc
, var_val_type
,
374 var_val
, var_val_len
);
377 case SNMP_NOSUCHOBJECT
:
378 case SNMP_NOSUCHINSTANCE
:
379 case SNMP_ENDOFMIBVIEW
:
380 rc
= asn_realloc_rbuild_null(pkt
, pkt_len
, offset
, allow_realloc
,
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
,
391 case ASN_OPAQUE_DOUBLE
:
392 rc
= asn_realloc_rbuild_double(pkt
, pkt_len
, offset
, allow_realloc
,
393 var_val_type
, (double *) var_val
,
398 rc
= asn_realloc_rbuild_signed_int64(pkt
, pkt_len
, offset
,
399 allow_realloc
, var_val_type
,
400 (struct counter64
*) var_val
,
403 #endif /* OPAQUE_SPECIAL_TYPES */
405 ERROR_MSG("wrong type");
411 ERROR_MSG("Can't build value");
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
,
426 ERROR_MSG("Can't build OID for variable");
431 * Build the sequence header.
434 rc
= asn_realloc_rbuild_sequence(pkt
, pkt_len
, offset
, allow_realloc
,
435 (u_char
) (ASN_SEQUENCE
|
437 *offset
- start_offset
);
441 #endif /* USE_REVERSE_ASNENCODING */