]>
Commit | Line | Data |
---|---|---|
43d4303e | 1 | |
85269fdf | 2 | /* |
3 | * SNMP Variable Binding. Complies with: | |
4 | * | |
5 | * RFC 1905: Protocol Operations for SNMPv2 | |
6 | * | |
7 | */ | |
8 | ||
9 | /********************************************************************** | |
10 | * | |
11 | * Copyright 1997 by Carnegie Mellon University | |
26ac0430 | 12 | * |
85269fdf | 13 | * All Rights Reserved |
26ac0430 | 14 | * |
85269fdf | 15 | * Permission to use, copy, modify, and distribute this software and its |
16 | * documentation for any purpose and without fee is hereby granted, | |
17 | * provided that the above copyright notice appear in all copies and that | |
18 | * both that copyright notice and this permission notice appear in | |
19 | * supporting documentation, and that the name of CMU not be | |
20 | * used in advertising or publicity pertaining to distribution of the | |
21 | * software without specific, written prior permission. | |
26ac0430 | 22 | * |
85269fdf | 23 | * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
24 | * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
25 | * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
26 | * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
27 | * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
28 | * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
29 | * SOFTWARE. | |
26ac0430 | 30 | * |
85269fdf | 31 | * Author: Ryan Troll <ryan+@andrew.cmu.edu> |
26ac0430 | 32 | * |
85269fdf | 33 | **********************************************************************/ |
34 | ||
f7f3304a | 35 | #include "squid.h" |
85269fdf | 36 | |
37 | #include <stdio.h> | |
38 | ||
39 | #if HAVE_UNISTD_H | |
40 | #include <unistd.h> | |
41 | #endif | |
42 | #if HAVE_STDLIB_H | |
43 | #include <stdlib.h> | |
44 | #endif | |
45 | #if HAVE_SYS_TYPES_H | |
46 | #include <sys/types.h> | |
47 | #endif | |
48 | #if HAVE_CTYPE_H | |
49 | #include <ctype.h> | |
50 | #endif | |
51 | #if HAVE_GNUMALLOC_H | |
52 | #include <gnumalloc.h> | |
482aa790 | 53 | #elif HAVE_MALLOC_H |
85269fdf | 54 | #include <malloc.h> |
55 | #endif | |
56 | #if HAVE_MEMORY_H | |
57 | #include <memory.h> | |
58 | #endif | |
32d002cb | 59 | #if HAVE_STRING_H |
85269fdf | 60 | #include <string.h> |
61 | #endif | |
32d002cb | 62 | #if HAVE_STRINGS_H |
85269fdf | 63 | #include <strings.h> |
64 | #endif | |
65 | #if HAVE_BSTRING_H | |
66 | #include <bstring.h> | |
67 | #endif | |
68 | #if HAVE_SYS_SOCKET_H | |
69 | #include <sys/socket.h> | |
70 | #endif | |
71 | #if HAVE_NETINET_IN_H | |
72 | #include <netinet/in.h> | |
73 | #endif | |
74 | #if HAVE_ARPA_INET_H | |
75 | #include <arpa/inet.h> | |
76 | #endif | |
77 | #if HAVE_SYS_TIME_H | |
78 | #include <sys/time.h> | |
79 | #endif | |
80 | #if HAVE_NETDB_H | |
81 | #include <netdb.h> | |
82 | #endif | |
83 | ||
85269fdf | 84 | #include "asn1.h" |
602d9612 | 85 | #include "snmp.h" |
85269fdf | 86 | #include "snmp_vars.h" |
43d4303e | 87 | #if 0 |
85269fdf | 88 | #include "mibii.h" |
43d4303e | 89 | #endif |
85269fdf | 90 | #include "snmp_api_error.h" |
85269fdf | 91 | #include "snmp_msg.h" |
602d9612 | 92 | #include "snmp_pdu.h" |
85269fdf | 93 | |
94 | #include "util.h" | |
95 | ||
85269fdf | 96 | /* #define DEBUG_VARS 1 */ |
97 | /* #define DEBUG_VARS_MALLOC 1 */ | |
98 | /* #define DEBUG_VARS_DECODE 1 */ | |
99 | /* #define DEBUG_VARS_ENCODE 1 */ | |
100 | ||
85269fdf | 101 | /* Create a new variable_list structure representing oid Name of length Len. |
102 | * | |
103 | * Returns NULL upon error. | |
104 | */ | |
105 | ||
43d4303e | 106 | struct variable_list * |
e1381638 | 107 | snmp_var_new(oid * Name, int Len) { |
43d4303e | 108 | struct variable_list *New; |
85269fdf | 109 | |
32d002cb | 110 | #if DEBUG_VARS |
43d4303e | 111 | printf("VARS: Creating.\n"); |
85269fdf | 112 | #endif |
113 | ||
736eb6ad | 114 | New = xmalloc(sizeof(*New)); |
115 | /* XXX xmalloc never returns NULL */ | |
43d4303e | 116 | if (New == NULL) { |
26ac0430 AJ |
117 | snmp_set_api_error(SNMPERR_OS_ERR); |
118 | return (NULL); | |
43d4303e | 119 | } |
120 | memset(New, '\0', sizeof(struct variable_list)); | |
121 | /* New->next_variable = NULL; */ | |
85269fdf | 122 | |
43d4303e | 123 | New->type = ASN_NULL; |
124 | New->name_length = Len; | |
85269fdf | 125 | |
43d4303e | 126 | if (New->name_length == 0) { |
26ac0430 AJ |
127 | New->name = NULL; |
128 | return (New); | |
43d4303e | 129 | } |
130 | New->name = (oid *) xmalloc(Len * sizeof(oid)); | |
736eb6ad | 131 | /* XXX xmalloc never returns NULL */ |
43d4303e | 132 | if (New->name == NULL) { |
26ac0430 AJ |
133 | xfree(New); |
134 | snmp_set_api_error(SNMPERR_OS_ERR); | |
135 | return (NULL); | |
43d4303e | 136 | } |
32d002cb | 137 | #if DEBUG_VARS |
43d4303e | 138 | printf("VARS: Copying name, size (%d)\n", Len); |
85269fdf | 139 | #endif |
140 | ||
43d4303e | 141 | /* Only copy a name if it was specified. */ |
142 | if (Name) | |
41d00cd3 | 143 | memcpy((char *) New->name, (char *) Name, Len * sizeof(oid)); |
85269fdf | 144 | |
43d4303e | 145 | return (New); |
85269fdf | 146 | } |
147 | ||
736eb6ad | 148 | struct variable_list * |
e1381638 | 149 | snmp_var_new_integer(oid * Name, int Len, int ival, unsigned char type) { |
736eb6ad | 150 | variable_list *v = snmp_var_new(Name, Len); |
151 | v->val_len = sizeof(int); | |
152 | v->val.integer = xmalloc(sizeof(int)); | |
153 | v->type = type; | |
154 | *(v->val.integer) = ival; | |
155 | return v; | |
156 | } | |
157 | ||
85269fdf | 158 | /* Clone a variable list. |
159 | * | |
160 | * Returns NULL upon error. | |
161 | */ | |
162 | ||
43d4303e | 163 | struct variable_list * |
e1381638 | 164 | snmp_var_clone(struct variable_list *Src) { |
43d4303e | 165 | struct variable_list *Dest; |
85269fdf | 166 | |
32d002cb | 167 | #if DEBUG_VARS |
43d4303e | 168 | printf("VARS: Cloning.\n"); |
85269fdf | 169 | #endif |
170 | ||
43d4303e | 171 | Dest = (struct variable_list *) xmalloc(sizeof(struct variable_list)); |
172 | if (Dest == NULL) { | |
26ac0430 AJ |
173 | snmp_set_api_error(SNMPERR_OS_ERR); |
174 | return (NULL); | |
43d4303e | 175 | } |
32d002cb | 176 | #if DEBUG_VARS |
43d4303e | 177 | printf("VARS: Copying entire variable list. (Size %d)\n", |
26ac0430 | 178 | sizeof(struct variable_list)); |
85269fdf | 179 | #endif |
180 | ||
41d00cd3 | 181 | memcpy((char *) Dest, (char *) Src, sizeof(struct variable_list)); |
85269fdf | 182 | |
43d4303e | 183 | if (Src->name != NULL) { |
26ac0430 AJ |
184 | Dest->name = (oid *) xmalloc(Src->name_length * sizeof(oid)); |
185 | if (Dest->name == NULL) { | |
186 | snmp_set_api_error(SNMPERR_OS_ERR); | |
187 | xfree(Dest); | |
188 | return (NULL); | |
189 | } | |
32d002cb | 190 | #if DEBUG_VARS |
26ac0430 | 191 | printf("VARS: Copying name OID. (Size %d)\n", Src->name_length); |
43d4303e | 192 | #endif |
41d00cd3 | 193 | memcpy((char *) Dest->name, (char *) Src->name, |
e34763f4 | 194 | Src->name_length * sizeof(oid)); |
85269fdf | 195 | } |
43d4303e | 196 | /* CISCO Catalyst 2900 returns NULL strings as data of length 0. */ |
197 | if ((Src->val.string != NULL) && | |
26ac0430 AJ |
198 | (Src->val_len)) { |
199 | Dest->val.string = (u_char *) xmalloc(Src->val_len); | |
200 | if (Dest->val.string == NULL) { | |
201 | snmp_set_api_error(SNMPERR_OS_ERR); | |
202 | xfree(Dest->name); | |
203 | xfree(Dest); | |
204 | return (NULL); | |
205 | } | |
32d002cb | 206 | #if DEBUG_VARS |
26ac0430 | 207 | printf("VARS: Copying value (Size %d)\n", Src->val_len); |
85269fdf | 208 | #endif |
41d00cd3 | 209 | memcpy((char *) Dest->val.string, (char *) Src->val.string, Src->val_len); |
43d4303e | 210 | } |
32d002cb | 211 | #if DEBUG_VARS |
43d4303e | 212 | printf("VARS: Cloned %x.\n", (unsigned int) Dest); |
85269fdf | 213 | #endif |
32d002cb | 214 | #if DEBUG_VARS_MALLOC |
43d4303e | 215 | printf("VARS: Cloned (%x)\n", (unsigned int) Dest); |
216 | printf("VARS: Name is (%x)\n", (unsigned int) Dest->name); | |
85269fdf | 217 | #endif |
218 | ||
43d4303e | 219 | return (Dest); |
85269fdf | 220 | } |
221 | ||
222 | /* Free a variable_list. | |
223 | */ | |
736eb6ad | 224 | void |
43d4303e | 225 | snmp_var_free(struct variable_list *Ptr) |
85269fdf | 226 | { |
63f8db1a | 227 | if (Ptr->name) |
26ac0430 | 228 | xfree((char *) Ptr->name); |
85269fdf | 229 | |
63f8db1a | 230 | if (Ptr->val.string) |
26ac0430 | 231 | xfree((char *) Ptr->val.string); |
63f8db1a | 232 | else if (Ptr->val.integer) |
26ac0430 | 233 | xfree((char *) Ptr->val.integer); |
85269fdf | 234 | |
43d4303e | 235 | xfree(Ptr); |
85269fdf | 236 | } |
237 | ||
238 | /**********************************************************************/ | |
239 | ||
240 | /* Build a variable binding. | |
241 | * | |
242 | * RFC 1905: Protocol Operations for SNMPv2 | |
243 | * | |
26ac0430 | 244 | * VarBind ::= |
85269fdf | 245 | * SEQUENCE { |
246 | * name ObjectName | |
247 | * CHOICE { | |
248 | * value ObjectSyntax | |
249 | * unSpecified NULL | |
250 | * noSuchObject[0] NULL | |
251 | * noSuchInstance[1] NULL | |
252 | * endOfMibView[2] NULL | |
253 | * } | |
254 | * } | |
255 | */ | |
43d4303e | 256 | u_char * |
257 | snmp_var_EncodeVarBind(u_char * Buffer, int *BufLenP, | |
26ac0430 AJ |
258 | variable_list * VarList, |
259 | int Version) | |
85269fdf | 260 | { |
43d4303e | 261 | struct variable_list *Vars; |
262 | u_char *bufp; | |
263 | u_char *HeaderStart; | |
264 | u_char *HeaderEnd; | |
265 | int FakeArg = *BufLenP; | |
266 | ||
267 | bufp = Buffer; | |
268 | ||
269 | for (Vars = VarList; Vars; Vars = Vars->next_variable) { | |
270 | ||
26ac0430 AJ |
271 | /* Build the header for this variable |
272 | * | |
273 | * Use Maximum size. | |
274 | */ | |
275 | HeaderStart = bufp; | |
276 | HeaderEnd = asn_build_header(HeaderStart, BufLenP, | |
277 | (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), | |
278 | FakeArg); | |
279 | if (HeaderEnd == NULL) | |
280 | return (NULL); | |
281 | ||
282 | /* Now, let's put the Object Identifier into the buffer */ | |
283 | bufp = asn_build_objid(HeaderEnd, BufLenP, | |
284 | (u_char) (ASN_UNIVERSAL | | |
285 | ASN_PRIMITIVE | | |
286 | ASN_OBJECT_ID), | |
287 | Vars->name, Vars->name_length); | |
288 | if (bufp == NULL) | |
289 | return (NULL); | |
290 | ||
291 | /* Now put the data in */ | |
292 | switch (Vars->type) { | |
293 | ||
294 | case ASN_INTEGER: | |
295 | bufp = asn_build_int(bufp, | |
296 | BufLenP, Vars->type, | |
297 | (int *) Vars->val.integer, Vars->val_len); | |
298 | break; | |
299 | ||
300 | case SMI_COUNTER32: | |
301 | case SMI_GAUGE32: | |
302 | /* case SMI_UNSIGNED32: */ | |
303 | case SMI_TIMETICKS: | |
304 | bufp = asn_build_unsigned_int(bufp, BufLenP, | |
305 | Vars->type, | |
306 | (u_int *) Vars->val.integer, Vars->val_len); | |
307 | break; | |
308 | ||
309 | case ASN_OCTET_STR: | |
310 | case SMI_IPADDRESS: | |
311 | case SMI_OPAQUE: | |
312 | bufp = asn_build_string(bufp, BufLenP, Vars->type, | |
313 | Vars->val.string, Vars->val_len); | |
314 | break; | |
315 | ||
316 | case ASN_OBJECT_ID: | |
317 | bufp = asn_build_objid(bufp, BufLenP, Vars->type, | |
318 | (oid *) Vars->val.objid, Vars->val_len / sizeof(oid)); | |
319 | break; | |
320 | ||
321 | case SMI_NOSUCHINSTANCE: | |
322 | case SMI_NOSUCHOBJECT: | |
323 | case SMI_ENDOFMIBVIEW: | |
324 | if (Version == SNMP_VERSION_1) { | |
325 | /* SNMP Version 1 does not support these error codes. */ | |
326 | bufp = asn_build_null(bufp, BufLenP, SMI_NOSUCHOBJECT); | |
327 | } else { | |
328 | bufp = asn_build_exception(bufp, BufLenP, Vars->type); | |
329 | } | |
330 | break; | |
331 | ||
332 | case ASN_NULL: | |
333 | bufp = asn_build_null(bufp, BufLenP, Vars->type); | |
334 | break; | |
335 | ||
336 | case SMI_COUNTER64: | |
337 | snmplib_debug(2, "Unable to encode type SMI_COUNTER64!\n"); | |
338 | /* Fall through */ | |
339 | ||
340 | default: | |
341 | snmp_set_api_error(SNMPERR_UNSUPPORTED_TYPE); | |
342 | return (NULL); | |
343 | } | |
344 | ||
345 | /* ASSERT: bufp should now point to the next valid byte. */ | |
346 | if (bufp == NULL) | |
347 | return (NULL); | |
348 | ||
349 | /* Rebuild the header with the appropriate length */ | |
350 | HeaderEnd = asn_build_header(HeaderStart, &FakeArg, | |
351 | (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), | |
352 | (bufp - HeaderEnd)); | |
353 | ||
354 | /* Returns NULL */ | |
355 | if (HeaderEnd == NULL) | |
356 | return (NULL); | |
85269fdf | 357 | |
43d4303e | 358 | } |
85269fdf | 359 | |
43d4303e | 360 | /* or the end of the entire thing */ |
361 | return (bufp); | |
85269fdf | 362 | } |
363 | ||
85269fdf | 364 | /* Parse all Vars from the buffer */ |
43d4303e | 365 | u_char * |
366 | snmp_var_DecodeVarBind(u_char * Buffer, int *BufLen, | |
26ac0430 AJ |
367 | struct variable_list ** VarP, |
368 | int Version) | |
85269fdf | 369 | { |
63f8db1a | 370 | struct variable_list *Var = NULL, **VarLastP; |
43d4303e | 371 | u_char *bufp, *tmp; |
372 | u_char VarBindType; | |
373 | u_char *DataPtr; | |
374 | int DataLen; | |
375 | oid TmpBuf[MAX_NAME_LEN]; | |
2082bd1c | 376 | memset(TmpBuf, 0, MAX_NAME_LEN * sizeof(*TmpBuf)); |
85269fdf | 377 | |
43d4303e | 378 | int AllVarLen = *BufLen; |
379 | int ThisVarLen = 0; | |
85269fdf | 380 | |
43d4303e | 381 | VarLastP = VarP; |
32d002cb | 382 | #if DEBUG_VARS_DECODE |
43d4303e | 383 | printf("VARS: Decoding buffer of length %d\n", *BufLen); |
85269fdf | 384 | #endif |
385 | ||
43d4303e | 386 | /* Now parse the variables */ |
387 | bufp = asn_parse_header(Buffer, &AllVarLen, &VarBindType); | |
388 | if (bufp == NULL) | |
26ac0430 | 389 | return (NULL); |
85269fdf | 390 | |
43d4303e | 391 | if (VarBindType != (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR)) { |
26ac0430 AJ |
392 | snmp_set_api_error(SNMPERR_PDU_PARSE); |
393 | return (NULL); | |
85269fdf | 394 | } |
32d002cb | 395 | #if DEBUG_VARS_DECODE |
43d4303e | 396 | printf("VARS: All Variable length %d\n", AllVarLen); |
397 | #endif | |
398 | ||
63f8db1a | 399 | #define PARSE_ERROR { snmp_var_free(Var); return(NULL); } |
400 | ||
43d4303e | 401 | /* We know how long the variable list is. Parse it. */ |
402 | while ((int) AllVarLen > 0) { | |
403 | ||
26ac0430 AJ |
404 | /* Create a new variable */ |
405 | Var = snmp_var_new(NULL, MAX_NAME_LEN); | |
406 | if (Var == NULL) | |
407 | return (NULL); | |
408 | ||
409 | /* Parse the header to find out the length of this variable. */ | |
410 | ThisVarLen = AllVarLen; | |
411 | tmp = asn_parse_header(bufp, &ThisVarLen, &VarBindType); | |
412 | if (tmp == NULL) | |
413 | PARSE_ERROR; | |
414 | ||
415 | /* Now that we know the length , figure out how it relates to | |
416 | * the entire variable list | |
417 | */ | |
418 | AllVarLen = AllVarLen - (ThisVarLen + (tmp - bufp)); | |
419 | bufp = tmp; | |
420 | ||
421 | /* Is it valid? */ | |
422 | if (VarBindType != (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR)) { | |
423 | snmp_set_api_error(SNMPERR_PDU_PARSE); | |
424 | PARSE_ERROR; | |
425 | } | |
32d002cb | 426 | #if DEBUG_VARS_DECODE |
26ac0430 | 427 | printf("VARS: Header type 0x%x (%d bytes left)\n", VarBindType, ThisVarLen); |
85269fdf | 428 | #endif |
429 | ||
26ac0430 AJ |
430 | /* Parse the OBJID */ |
431 | bufp = asn_parse_objid(bufp, &ThisVarLen, &VarBindType, | |
432 | Var->name, &(Var->name_length)); | |
433 | if (bufp == NULL) | |
434 | PARSE_ERROR; | |
85269fdf | 435 | |
26ac0430 AJ |
436 | if (VarBindType != (u_char) (ASN_UNIVERSAL | |
437 | ASN_PRIMITIVE | | |
438 | ASN_OBJECT_ID)) { | |
439 | snmp_set_api_error(SNMPERR_PDU_PARSE); | |
440 | PARSE_ERROR; | |
441 | } | |
32d002cb | 442 | #if DEBUG_VARS_DECODE |
26ac0430 AJ |
443 | printf("VARS: Decoded OBJID (%d bytes). (%d bytes left)\n", |
444 | Var->name_length, ThisVarLen); | |
85269fdf | 445 | #endif |
446 | ||
26ac0430 AJ |
447 | /* Keep a pointer to this object */ |
448 | DataPtr = bufp; | |
449 | DataLen = ThisVarLen; | |
85269fdf | 450 | |
26ac0430 AJ |
451 | /* find out type of object */ |
452 | bufp = asn_parse_header(bufp, &ThisVarLen, &(Var->type)); | |
453 | if (bufp == NULL) | |
454 | PARSE_ERROR; | |
455 | ThisVarLen = DataLen; | |
85269fdf | 456 | |
32d002cb | 457 | #if DEBUG_VARS_DECODE |
26ac0430 | 458 | printf("VARS: Data type %d\n", Var->type); |
85269fdf | 459 | #endif |
460 | ||
26ac0430 | 461 | /* Parse the type */ |
85269fdf | 462 | |
26ac0430 | 463 | switch ((short) Var->type) { |
85269fdf | 464 | |
26ac0430 AJ |
465 | case ASN_INTEGER: |
466 | Var->val.integer = (int *) xmalloc(sizeof(int)); | |
467 | if (Var->val.integer == NULL) { | |
468 | snmp_set_api_error(SNMPERR_OS_ERR); | |
469 | PARSE_ERROR; | |
470 | } | |
471 | Var->val_len = sizeof(int); | |
472 | bufp = asn_parse_int(DataPtr, &ThisVarLen, | |
473 | &Var->type, (int *) Var->val.integer, | |
474 | Var->val_len); | |
32d002cb | 475 | #if DEBUG_VARS_DECODE |
26ac0430 AJ |
476 | printf("VARS: Decoded integer '%d' (%d bytes left)\n", |
477 | *(Var->val.integer), ThisVarLen); | |
478 | #endif | |
479 | break; | |
480 | ||
481 | case SMI_COUNTER32: | |
482 | case SMI_GAUGE32: | |
483 | /* case SMI_UNSIGNED32: */ | |
484 | case SMI_TIMETICKS: | |
485 | Var->val.integer = (int *) xmalloc(sizeof(u_int)); | |
486 | if (Var->val.integer == NULL) { | |
487 | snmp_set_api_error(SNMPERR_OS_ERR); | |
488 | PARSE_ERROR; | |
489 | } | |
490 | Var->val_len = sizeof(u_int); | |
491 | bufp = asn_parse_unsigned_int(DataPtr, &ThisVarLen, | |
492 | &Var->type, (u_int *) Var->val.integer, | |
493 | Var->val_len); | |
32d002cb | 494 | #if DEBUG_VARS_DECODE |
26ac0430 AJ |
495 | printf("VARS: Decoded timeticks '%d' (%d bytes left)\n", |
496 | *(Var->val.integer), ThisVarLen); | |
497 | #endif | |
498 | break; | |
499 | ||
500 | case ASN_OCTET_STR: | |
501 | case SMI_IPADDRESS: | |
502 | case SMI_OPAQUE: | |
503 | Var->val_len = *&ThisVarLen; /* String is this at most */ | |
504 | Var->val.string = (u_char *) xmalloc((unsigned) Var->val_len); | |
505 | if (Var->val.string == NULL) { | |
506 | snmp_set_api_error(SNMPERR_OS_ERR); | |
507 | PARSE_ERROR; | |
508 | } | |
509 | bufp = asn_parse_string(DataPtr, &ThisVarLen, | |
510 | &Var->type, Var->val.string, | |
511 | &Var->val_len); | |
32d002cb | 512 | #if DEBUG_VARS_DECODE |
26ac0430 AJ |
513 | printf("VARS: Decoded string '%s' (length %d) (%d bytes left)\n", |
514 | (Var->val.string), Var->val_len, ThisVarLen); | |
515 | #endif | |
516 | break; | |
517 | ||
518 | case ASN_OBJECT_ID: | |
519 | Var->val_len = MAX_NAME_LEN; | |
520 | bufp = asn_parse_objid(DataPtr, &ThisVarLen, | |
521 | &Var->type, TmpBuf, &Var->val_len); | |
522 | Var->val_len *= sizeof(oid); | |
523 | Var->val.objid = (oid *) xmalloc((unsigned) Var->val_len); | |
524 | if (Var->val.integer == NULL) { | |
525 | snmp_set_api_error(SNMPERR_OS_ERR); | |
526 | PARSE_ERROR; | |
527 | } | |
528 | /* Only copy if we successfully decoded something */ | |
529 | if (bufp) { | |
41d00cd3 | 530 | memcpy((char *) Var->val.objid, (char *) TmpBuf, Var->val_len); |
26ac0430 | 531 | } |
32d002cb | 532 | #if DEBUG_VARS_DECODE |
26ac0430 AJ |
533 | printf("VARS: Decoded OBJID (length %d) (%d bytes left)\n", |
534 | Var->val_len, ThisVarLen); | |
43d4303e | 535 | #endif |
26ac0430 | 536 | break; |
85269fdf | 537 | |
26ac0430 AJ |
538 | case ASN_NULL: |
539 | case SMI_NOSUCHINSTANCE: | |
540 | case SMI_NOSUCHOBJECT: | |
541 | case SMI_ENDOFMIBVIEW: | |
542 | break; | |
43d4303e | 543 | |
26ac0430 AJ |
544 | case SMI_COUNTER64: |
545 | snmplib_debug(2, "Unable to parse type SMI_COUNTER64!\n"); | |
546 | snmp_set_api_error(SNMPERR_UNSUPPORTED_TYPE); | |
547 | PARSE_ERROR; | |
43d4303e | 548 | |
26ac0430 AJ |
549 | default: |
550 | snmplib_debug(2, "bad type returned (%x)\n", Var->type); | |
551 | snmp_set_api_error(SNMPERR_PDU_PARSE); | |
552 | PARSE_ERROR; | |
553 | } /* End of var type switch */ | |
43d4303e | 554 | |
26ac0430 AJ |
555 | if (bufp == NULL) |
556 | PARSE_ERROR; | |
85269fdf | 557 | |
32d002cb | 558 | #if DEBUG_VARS_DECODE |
26ac0430 | 559 | printf("VARS: Adding to list.\n"); |
85269fdf | 560 | #endif |
26ac0430 AJ |
561 | /* Add variable to the list */ |
562 | *VarLastP = Var; | |
563 | VarLastP = &(Var->next_variable); | |
43d4303e | 564 | } |
63f8db1a | 565 | #undef PARSE_ERROR |
85269fdf | 566 | |
43d4303e | 567 | return (bufp); |
85269fdf | 568 | } |