]>
Commit | Line | Data |
---|---|---|
85269fdf | 1 | /* |
2 | * SNMP PDU Encoding | |
3 | * | |
4 | * Complies with: | |
5 | * | |
6 | * RFC 1902: Structure of Management Information for SNMPv2 | |
7 | * | |
8 | */ | |
9 | ||
10 | /********************************************************************** | |
11 | * | |
12 | * Copyright 1997 by Carnegie Mellon University | |
26ac0430 | 13 | * |
85269fdf | 14 | * All Rights Reserved |
26ac0430 | 15 | * |
85269fdf | 16 | * Permission to use, copy, modify, and distribute this software and its |
17 | * documentation for any purpose and without fee is hereby granted, | |
18 | * provided that the above copyright notice appear in all copies and that | |
19 | * both that copyright notice and this permission notice appear in | |
20 | * supporting documentation, and that the name of CMU not be | |
21 | * used in advertising or publicity pertaining to distribution of the | |
22 | * software without specific, written prior permission. | |
26ac0430 | 23 | * |
85269fdf | 24 | * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
25 | * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
26 | * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
27 | * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
28 | * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
29 | * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
30 | * SOFTWARE. | |
26ac0430 | 31 | * |
85269fdf | 32 | * Author: Ryan Troll <ryan+@andrew.cmu.edu> |
26ac0430 | 33 | * |
85269fdf | 34 | **********************************************************************/ |
35 | ||
f7f3304a | 36 | #include "squid.h" |
85269fdf | 37 | |
38 | #include <stdio.h> | |
39 | ||
40 | #if HAVE_UNISTD_H | |
41 | #include <unistd.h> | |
42 | #endif | |
43 | #if HAVE_STDLIB_H | |
44 | #include <stdlib.h> | |
45 | #endif | |
46 | #if HAVE_SYS_TYPES_H | |
47 | #include <sys/types.h> | |
48 | #endif | |
49 | #if HAVE_CTYPE_H | |
50 | #include <ctype.h> | |
51 | #endif | |
52 | #if HAVE_GNUMALLOC_H | |
53 | #include <gnumalloc.h> | |
482aa790 | 54 | #elif HAVE_MALLOC_H |
85269fdf | 55 | #include <malloc.h> |
56 | #endif | |
57 | #if HAVE_MEMORY_H | |
58 | #include <memory.h> | |
59 | #endif | |
32d002cb | 60 | #if HAVE_STRING_H |
85269fdf | 61 | #include <string.h> |
62 | #endif | |
32d002cb | 63 | #if HAVE_STRINGS_H |
85269fdf | 64 | #include <strings.h> |
65 | #endif | |
66 | #if HAVE_BSTRING_H | |
67 | #include <bstring.h> | |
68 | #endif | |
69 | #if HAVE_SYS_SOCKET_H | |
70 | #include <sys/socket.h> | |
71 | #endif | |
72 | #if HAVE_NETINET_IN_H | |
73 | #include <netinet/in.h> | |
74 | #endif | |
75 | #if HAVE_ARPA_INET_H | |
76 | #include <arpa/inet.h> | |
77 | #endif | |
78 | #if HAVE_SYS_TIME_H | |
79 | #include <sys/time.h> | |
80 | #endif | |
81 | #if HAVE_NETDB_H | |
82 | #include <netdb.h> | |
83 | #endif | |
84 | ||
85269fdf | 85 | #include "asn1.h" |
602d9612 A |
86 | #include "snmp.h" |
87 | #include "snmp_api_error.h" | |
85269fdf | 88 | #include "snmp_error.h" |
85269fdf | 89 | #include "snmp_msg.h" |
602d9612 A |
90 | #include "snmp_pdu.h" |
91 | #include "snmp_vars.h" | |
85269fdf | 92 | |
93 | #include "util.h" | |
94 | ||
95 | /* #define DEBUG_PDU 1 */ | |
96 | /* #define DEBUG_PDU_DECODE 1 */ | |
97 | /* #define DEBUG_PDU_ENCODE 1 */ | |
98 | ||
43d4303e | 99 | #define ASN_PARSE_ERROR(x) { return(x); } |
85269fdf | 100 | |
101 | /**********************************************************************/ | |
102 | ||
103 | /* Create a PDU. | |
104 | */ | |
105 | ||
43d4303e | 106 | struct snmp_pdu * |
e1381638 | 107 | snmp_pdu_create(int command) { |
43d4303e | 108 | struct snmp_pdu *pdu; |
85269fdf | 109 | |
32d002cb | 110 | #if DEBUG_PDU |
43d4303e | 111 | snmplib_debug(8, "PDU: Creating\n"); |
85269fdf | 112 | #endif |
113 | ||
43d4303e | 114 | pdu = (struct snmp_pdu *) xmalloc(sizeof(struct snmp_pdu)); |
115 | if (pdu == NULL) { | |
26ac0430 AJ |
116 | snmp_set_api_error(SNMPERR_OS_ERR); |
117 | return (NULL); | |
43d4303e | 118 | } |
119 | memset((char *) pdu, '\0', sizeof(struct snmp_pdu)); | |
85269fdf | 120 | |
43d4303e | 121 | pdu->command = command; |
122 | pdu->errstat = SNMP_DEFAULT_ERRSTAT; | |
123 | pdu->errindex = SNMP_DEFAULT_ERRINDEX; | |
124 | pdu->address.sin_addr.s_addr = SNMP_DEFAULT_ADDRESS; | |
125 | pdu->enterprise = NULL; | |
126 | pdu->enterprise_length = 0; | |
127 | pdu->variables = NULL; | |
85269fdf | 128 | |
32d002cb | 129 | #if DEBUG_PDU |
43d4303e | 130 | snmplib_debug(8, "PDU: Created %x\n", (unsigned int) pdu); |
85269fdf | 131 | #endif |
132 | ||
43d4303e | 133 | return (pdu); |
85269fdf | 134 | } |
135 | ||
136 | /**********************************************************************/ | |
137 | ||
138 | /* Clone an existing PDU. | |
139 | */ | |
43d4303e | 140 | struct snmp_pdu * |
e1381638 | 141 | snmp_pdu_clone(struct snmp_pdu *Src) { |
43d4303e | 142 | struct snmp_pdu *Dest; |
85269fdf | 143 | |
32d002cb | 144 | #if DEBUG_PDU |
43d4303e | 145 | snmplib_debug(8, "PDU %x: Cloning\n", (unsigned int) Src); |
85269fdf | 146 | #endif |
147 | ||
43d4303e | 148 | Dest = (struct snmp_pdu *) xmalloc(sizeof(struct snmp_pdu)); |
149 | if (Dest == NULL) { | |
26ac0430 AJ |
150 | snmp_set_api_error(SNMPERR_OS_ERR); |
151 | return (NULL); | |
43d4303e | 152 | } |
41d00cd3 | 153 | memcpy((char *) Dest, (char *) Src, sizeof(struct snmp_pdu)); |
85269fdf | 154 | |
32d002cb | 155 | #if DEBUG_PDU |
43d4303e | 156 | snmplib_debug(8, "PDU %x: Created %x\n", (unsigned int) Src, (unsigned int) Dest); |
85269fdf | 157 | #endif |
43d4303e | 158 | return (Dest); |
85269fdf | 159 | } |
160 | ||
161 | /**********************************************************************/ | |
162 | ||
163 | /* | |
164 | * If there was an error in the input pdu, creates a clone of the pdu | |
165 | * that includes all the variables except the one marked by the errindex. | |
166 | * The command is set to the input command and the reqid, errstat, and | |
167 | * errindex are set to default values. | |
168 | * If the error status didn't indicate an error, the error index didn't | |
169 | * indicate a variable, the pdu wasn't a get response message, or there | |
170 | * would be no remaining variables, this function will return NULL. | |
171 | * If everything was successful, a pointer to the fixed cloned pdu will | |
172 | * be returned. | |
173 | */ | |
43d4303e | 174 | struct snmp_pdu * |
e1381638 | 175 | snmp_pdu_fix(struct snmp_pdu *pdu, int command) { |
43d4303e | 176 | return (snmp_fix_pdu(pdu, command)); |
85269fdf | 177 | } |
178 | ||
43d4303e | 179 | struct snmp_pdu * |
e1381638 | 180 | snmp_fix_pdu(struct snmp_pdu *pdu, int command) { |
43d4303e | 181 | struct variable_list *var, *newvar; |
182 | struct snmp_pdu *newpdu; | |
5c52f59a | 183 | int i; |
43d4303e | 184 | int copied = 0; |
85269fdf | 185 | |
32d002cb | 186 | #if DEBUG_PDU |
43d4303e | 187 | snmplib_debug(8, "PDU %x: Fixing. Err index is %d\n", |
26ac0430 | 188 | (unsigned int) pdu, (unsigned int) pdu->errindex); |
85269fdf | 189 | #endif |
190 | ||
43d4303e | 191 | if (pdu->command != SNMP_PDU_RESPONSE || |
26ac0430 AJ |
192 | pdu->errstat == SNMP_ERR_NOERROR || |
193 | pdu->errindex <= 0) { | |
194 | snmp_set_api_error(SNMPERR_UNABLE_TO_FIX); | |
195 | return (NULL); | |
85269fdf | 196 | } |
43d4303e | 197 | /* clone the pdu */ |
198 | newpdu = snmp_pdu_clone(pdu); | |
199 | if (newpdu == NULL) | |
26ac0430 | 200 | return (NULL); |
43d4303e | 201 | |
202 | newpdu->variables = 0; | |
203 | newpdu->command = command; | |
204 | newpdu->reqid = SNMP_DEFAULT_REQID; | |
205 | newpdu->errstat = SNMP_DEFAULT_ERRSTAT; | |
206 | newpdu->errindex = SNMP_DEFAULT_ERRINDEX; | |
85269fdf | 207 | |
43d4303e | 208 | /* Loop through the variables, removing whatever isn't necessary */ |
85269fdf | 209 | |
43d4303e | 210 | var = pdu->variables; |
5c52f59a | 211 | i = 1; |
85269fdf | 212 | |
43d4303e | 213 | /* skip first variable if necessary */ |
5c52f59a | 214 | if (pdu->errindex == i) { |
26ac0430 AJ |
215 | var = var->next_variable; |
216 | i++; | |
43d4303e | 217 | } |
218 | if (var != NULL) { | |
219 | ||
26ac0430 AJ |
220 | /* VAR is the first uncopied variable */ |
221 | ||
222 | /* Clone this variable */ | |
223 | newpdu->variables = snmp_var_clone(var); | |
224 | if (newpdu->variables == NULL) { | |
225 | snmp_pdu_free(newpdu); | |
226 | return (NULL); | |
227 | } | |
228 | copied++; | |
229 | ||
230 | newvar = newpdu->variables; | |
231 | ||
232 | /* VAR has been copied to NEWVAR. */ | |
233 | while (var->next_variable) { | |
234 | ||
235 | /* Skip the item that was bad */ | |
236 | if (++i == pdu->errindex) { | |
237 | var = var->next_variable; | |
238 | continue; | |
239 | } | |
240 | /* Copy this var */ | |
241 | newvar->next_variable = snmp_var_clone(var->next_variable); | |
242 | if (newvar->next_variable == NULL) { | |
243 | snmp_pdu_free(newpdu); | |
244 | return (NULL); | |
245 | } | |
246 | /* Move to the next one */ | |
247 | newvar = newvar->next_variable; | |
248 | var = var->next_variable; | |
249 | copied++; | |
250 | } | |
251 | newvar->next_variable = NULL; | |
43d4303e | 252 | } |
253 | /* If we didn't copy anything, free the new pdu. */ | |
5c52f59a | 254 | if (i < pdu->errindex || copied == 0) { |
26ac0430 AJ |
255 | snmp_free_pdu(newpdu); |
256 | snmp_set_api_error(SNMPERR_UNABLE_TO_FIX); | |
257 | return (NULL); | |
85269fdf | 258 | } |
32d002cb | 259 | #if DEBUG_PDU |
43d4303e | 260 | snmplib_debug(8, "PDU %x: Fixed PDU is %x\n", |
26ac0430 | 261 | (unsigned int) pdu, (unsigned int) newpdu); |
85269fdf | 262 | #endif |
43d4303e | 263 | return (newpdu); |
85269fdf | 264 | } |
265 | ||
85269fdf | 266 | /**********************************************************************/ |
267 | ||
468ae12b | 268 | void |
43d4303e | 269 | snmp_pdu_free(struct snmp_pdu *pdu) |
85269fdf | 270 | { |
43d4303e | 271 | snmp_free_pdu(pdu); |
85269fdf | 272 | } |
273 | ||
274 | /* | |
275 | * Frees the pdu and any xmalloc'd data associated with it. | |
276 | */ | |
468ae12b | 277 | void |
43d4303e | 278 | snmp_free_pdu(struct snmp_pdu *pdu) |
85269fdf | 279 | { |
43d4303e | 280 | struct variable_list *vp, *ovp; |
281 | ||
282 | vp = pdu->variables; | |
283 | while (vp) { | |
26ac0430 AJ |
284 | ovp = vp; |
285 | vp = vp->next_variable; | |
286 | snmp_var_free(ovp); | |
43d4303e | 287 | } |
288 | ||
289 | if (pdu->enterprise) | |
26ac0430 | 290 | xfree((char *) pdu->enterprise); |
43d4303e | 291 | xfree((char *) pdu); |
85269fdf | 292 | } |
293 | ||
294 | /**********************************************************************/ | |
295 | ||
296 | /* Encode this PDU into DestBuf. | |
297 | * | |
298 | * Returns a pointer to the next byte in the buffer (where the Variable | |
299 | * Bindings belong.) | |
300 | */ | |
301 | ||
302 | /* | |
303 | * RFC 1902: Structure of Management Information for SNMPv2 | |
304 | * | |
26ac0430 | 305 | * PDU ::= |
85269fdf | 306 | * SEQUENCE { |
307 | * request-id INTEGER32 | |
308 | * error-status INTEGER | |
309 | * error-index INTEGER | |
310 | * Variable Bindings | |
311 | * } | |
312 | * | |
313 | * BulkPDU ::= | |
314 | * SEQUENCE { | |
315 | * request-id INTEGER32 | |
316 | * non-repeaters INTEGER | |
317 | * max-repetitions INTEGER | |
318 | * Variable Bindings | |
319 | * } | |
320 | */ | |
321 | ||
322 | /* | |
323 | * RFC 1157: A Simple Network Management Protocol (SNMP) | |
324 | * | |
26ac0430 | 325 | * PDU ::= |
85269fdf | 326 | * SEQUENCE { |
327 | * request-id INTEGER | |
328 | * error-status INTEGER | |
329 | * error-index INTEGER | |
330 | * Variable Bindings | |
331 | * } | |
332 | * | |
333 | * TrapPDU ::= | |
334 | * SEQUENCE { | |
335 | * enterprise NetworkAddress | |
336 | * generic-trap INTEGER | |
337 | * specific-trap INTEGER | |
338 | * time-stamp TIMETICKS | |
339 | * Variable Bindings | |
340 | * } | |
341 | */ | |
342 | ||
43d4303e | 343 | u_char * |
344 | snmp_pdu_encode(u_char * DestBuf, int *DestBufLen, | |
26ac0430 | 345 | struct snmp_pdu *PDU) |
85269fdf | 346 | { |
43d4303e | 347 | u_char *bufp; |
85269fdf | 348 | |
32d002cb | 349 | #if DEBUG_PDU_ENCODE |
43d4303e | 350 | snmplib_debug(8, "PDU: Encoding %d\n", PDU->command); |
85269fdf | 351 | #endif |
352 | ||
43d4303e | 353 | /* ASN.1 Header */ |
354 | switch (PDU->command) { | |
85269fdf | 355 | |
26ac0430 | 356 | /**********************************************************************/ |
32d002cb | 357 | #if TRP_REQ_MSG |
43d4303e | 358 | case TRP_REQ_MSG: |
359 | ||
26ac0430 AJ |
360 | /* SNMPv1 Trap */ |
361 | ||
362 | /* enterprise */ | |
363 | bufp = asn_build_objid(DestBuf, DestBufLen, | |
364 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), | |
365 | (oid *) PDU->enterprise, PDU->enterprise_length); | |
366 | if (bufp == NULL) | |
367 | return (NULL); | |
368 | ||
369 | /* agent-addr */ | |
370 | bufp = asn_build_string(bufp, DestBufLen, | |
371 | (u_char) (SMI_IPADDRESS | ASN_PRIMITIVE), | |
372 | (u_char *) & PDU->agent_addr.sin_addr.s_addr, | |
373 | sizeof(PDU->agent_addr.sin_addr.s_addr)); | |
374 | if (bufp == NULL) | |
375 | return (NULL); | |
376 | ||
377 | /* generic trap */ | |
378 | bufp = asn_build_int(bufp, DestBufLen, | |
379 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
380 | (int *) &PDU->trap_type, sizeof(PDU->trap_type)); | |
381 | if (bufp == NULL) | |
382 | return (NULL); | |
383 | ||
384 | /* specific trap */ | |
385 | bufp = asn_build_int(bufp, DestBufLen, | |
386 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
387 | (int *) &PDU->specific_type, | |
388 | sizeof(PDU->specific_type)); | |
389 | if (bufp == NULL) | |
390 | return (NULL); | |
391 | ||
392 | /* timestamp */ | |
393 | bufp = asn_build_unsigned_int(bufp, DestBufLen, | |
394 | (u_char) (SMI_TIMETICKS | ASN_PRIMITIVE), | |
395 | &PDU->time, sizeof(PDU->time)); | |
396 | if (bufp == NULL) | |
397 | return (NULL); | |
398 | break; | |
a56db080 | 399 | #endif |
85269fdf | 400 | |
26ac0430 | 401 | /**********************************************************************/ |
85269fdf | 402 | |
43d4303e | 403 | case SNMP_PDU_GETBULK: |
404 | ||
26ac0430 AJ |
405 | /* SNMPv2 Bulk Request */ |
406 | ||
407 | /* request id */ | |
408 | bufp = asn_build_int(DestBuf, DestBufLen, | |
409 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
410 | &PDU->reqid, sizeof(PDU->reqid)); | |
411 | if (bufp == NULL) | |
412 | return (NULL); | |
413 | ||
414 | /* non-repeaters */ | |
415 | bufp = asn_build_int(bufp, DestBufLen, | |
416 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
417 | &PDU->non_repeaters, | |
418 | sizeof(PDU->non_repeaters)); | |
419 | if (bufp == NULL) | |
420 | return (NULL); | |
421 | ||
422 | /* max-repetitions */ | |
423 | bufp = asn_build_int(bufp, DestBufLen, | |
424 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
425 | &PDU->max_repetitions, | |
426 | sizeof(PDU->max_repetitions)); | |
427 | if (bufp == NULL) | |
428 | return (NULL); | |
429 | break; | |
430 | ||
431 | /**********************************************************************/ | |
85269fdf | 432 | |
43d4303e | 433 | default: |
85269fdf | 434 | |
26ac0430 | 435 | /* Normal PDU Encoding */ |
85269fdf | 436 | |
26ac0430 | 437 | /* request id */ |
32d002cb | 438 | #if DEBUG_PDU_ENCODE |
26ac0430 | 439 | snmplib_debug(8, "PDU: Request ID %d (0x%x)\n", PDU->reqid, DestBuf); |
85269fdf | 440 | #endif |
26ac0430 AJ |
441 | bufp = asn_build_int(DestBuf, DestBufLen, |
442 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
443 | &PDU->reqid, sizeof(PDU->reqid)); | |
444 | if (bufp == NULL) | |
445 | return (NULL); | |
85269fdf | 446 | |
26ac0430 | 447 | /* error status */ |
32d002cb | 448 | #if DEBUG_PDU_ENCODE |
26ac0430 | 449 | snmplib_debug(8, "PDU: Error Status %d (0x%x)\n", PDU->errstat, bufp); |
85269fdf | 450 | #endif |
26ac0430 AJ |
451 | bufp = asn_build_int(bufp, DestBufLen, |
452 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
453 | &PDU->errstat, sizeof(PDU->errstat)); | |
454 | if (bufp == NULL) | |
455 | return (NULL); | |
85269fdf | 456 | |
26ac0430 | 457 | /* error index */ |
32d002cb | 458 | #if DEBUG_PDU_ENCODE |
26ac0430 | 459 | snmplib_debug(8, "PDU: Error index %d (0x%x)\n", PDU->errindex, bufp); |
85269fdf | 460 | #endif |
26ac0430 AJ |
461 | bufp = asn_build_int(bufp, DestBufLen, |
462 | (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), | |
463 | &PDU->errindex, sizeof(PDU->errindex)); | |
464 | if (bufp == NULL) | |
465 | return (NULL); | |
466 | break; | |
43d4303e | 467 | } /* End of encoding */ |
468 | ||
469 | return (bufp); | |
85269fdf | 470 | } |
471 | ||
472 | /**********************************************************************/ | |
473 | ||
474 | /* Decodes PDU from Packet into PDU. | |
475 | * | |
476 | * Returns a pointer to the next byte of the packet, which is where the | |
477 | * Variable Bindings start. | |
478 | */ | |
43d4303e | 479 | u_char * |
480 | snmp_pdu_decode(u_char * Packet, /* data */ | |
26ac0430 AJ |
481 | int *Length, /* &length */ |
482 | struct snmp_pdu * PDU) | |
43d4303e | 483 | { /* pdu */ |
484 | u_char *bufp; | |
485 | u_char PDUType; | |
43d4303e | 486 | u_char ASNType; |
32d002cb | 487 | #if UNUSED_CODE |
a56db080 | 488 | int four; |
43d4303e | 489 | oid objid[MAX_NAME_LEN]; |
a56db080 | 490 | #endif |
43d4303e | 491 | |
492 | bufp = asn_parse_header(Packet, Length, &PDUType); | |
493 | if (bufp == NULL) | |
26ac0430 | 494 | ASN_PARSE_ERROR(NULL); |
85269fdf | 495 | |
32d002cb | 496 | #if DEBUG_PDU_DECODE |
43d4303e | 497 | snmplib_debug(8, "PDU Type: %d\n", PDUType); |
85269fdf | 498 | #endif |
499 | ||
43d4303e | 500 | PDU->command = PDUType; |
501 | switch (PDUType) { | |
502 | ||
32d002cb | 503 | #if TRP_REQ_MSG |
43d4303e | 504 | case TRP_REQ_MSG: |
505 | ||
26ac0430 AJ |
506 | /* SNMPv1 Trap Message */ |
507 | ||
508 | /* enterprise */ | |
509 | PDU->enterprise_length = MAX_NAME_LEN; | |
510 | bufp = asn_parse_objid(bufp, Length, | |
511 | &ASNType, objid, &PDU->enterprise_length); | |
512 | if (bufp == NULL) | |
513 | ASN_PARSE_ERROR(NULL); | |
514 | ||
515 | PDU->enterprise = (oid *) xmalloc(PDU->enterprise_length * sizeof(oid)); | |
516 | if (PDU->enterprise == NULL) { | |
517 | snmp_set_api_error(SNMPERR_OS_ERR); | |
518 | return (NULL); | |
519 | } | |
41d00cd3 | 520 | memcpy((char *) PDU->enterprise, (char *) objid, |
e34763f4 | 521 | PDU->enterprise_length * sizeof(oid)); |
26ac0430 AJ |
522 | |
523 | /* Agent-addr */ | |
524 | four = 4; | |
525 | bufp = asn_parse_string(bufp, Length, | |
526 | &ASNType, | |
527 | (u_char *) & PDU->agent_addr.sin_addr.s_addr, | |
528 | &four); | |
529 | if (bufp == NULL) | |
530 | ASN_PARSE_ERROR(NULL); | |
531 | ||
532 | /* Generic trap */ | |
533 | bufp = asn_parse_int(bufp, Length, | |
534 | &ASNType, | |
535 | (int *) &PDU->trap_type, | |
536 | sizeof(PDU->trap_type)); | |
537 | if (bufp == NULL) | |
538 | ASN_PARSE_ERROR(NULL); | |
539 | ||
540 | /* Specific Trap */ | |
541 | bufp = asn_parse_int(bufp, Length, | |
542 | &ASNType, | |
543 | (int *) &PDU->specific_type, | |
544 | sizeof(PDU->specific_type)); | |
545 | if (bufp == NULL) | |
546 | ASN_PARSE_ERROR(NULL); | |
547 | ||
548 | /* Timestamp */ | |
549 | bufp = asn_parse_unsigned_int(bufp, Length, | |
550 | &ASNType, | |
551 | &PDU->time, sizeof(PDU->time)); | |
552 | if (bufp == NULL) | |
553 | ASN_PARSE_ERROR(NULL); | |
554 | break; | |
a56db080 | 555 | #endif |
85269fdf | 556 | |
26ac0430 | 557 | /**********************************************************************/ |
85269fdf | 558 | |
43d4303e | 559 | case SNMP_PDU_GETBULK: |
85269fdf | 560 | |
26ac0430 | 561 | /* SNMPv2 Bulk Request */ |
a56db080 | 562 | |
26ac0430 AJ |
563 | /* request id */ |
564 | bufp = asn_parse_int(bufp, Length, | |
565 | &ASNType, | |
566 | &PDU->reqid, sizeof(PDU->reqid)); | |
567 | if (bufp == NULL) | |
568 | ASN_PARSE_ERROR(NULL); | |
569 | ||
570 | /* non-repeaters */ | |
571 | bufp = asn_parse_int(bufp, Length, | |
572 | &ASNType, | |
573 | &PDU->non_repeaters, sizeof(PDU->non_repeaters)); | |
574 | if (bufp == NULL) | |
575 | ASN_PARSE_ERROR(NULL); | |
576 | ||
577 | /* max-repetitions */ | |
578 | bufp = asn_parse_int(bufp, Length, | |
579 | &ASNType, | |
580 | &PDU->max_repetitions, sizeof(PDU->max_repetitions)); | |
581 | if (bufp == NULL) | |
582 | ASN_PARSE_ERROR(NULL); | |
583 | break; | |
584 | ||
585 | /**********************************************************************/ | |
85269fdf | 586 | |
43d4303e | 587 | default: |
85269fdf | 588 | |
26ac0430 | 589 | /* Normal PDU Encoding */ |
85269fdf | 590 | |
26ac0430 AJ |
591 | /* request id */ |
592 | bufp = asn_parse_int(bufp, Length, | |
593 | &ASNType, | |
594 | &PDU->reqid, sizeof(PDU->reqid)); | |
595 | if (bufp == NULL) | |
596 | ASN_PARSE_ERROR(NULL); | |
85269fdf | 597 | |
32d002cb | 598 | #if DEBUG_PDU_DECODE |
26ac0430 | 599 | snmplib_debug(8, "PDU Request ID: %d\n", PDU->reqid); |
85269fdf | 600 | #endif |
601 | ||
26ac0430 AJ |
602 | /* error status */ |
603 | bufp = asn_parse_int(bufp, Length, | |
604 | &ASNType, | |
605 | &PDU->errstat, sizeof(PDU->errstat)); | |
606 | if (bufp == NULL) | |
607 | ASN_PARSE_ERROR(NULL); | |
85269fdf | 608 | |
32d002cb | 609 | #if DEBUG_PDU_DECODE |
26ac0430 | 610 | snmplib_debug(8, "PDU Error Status: %d\n", PDU->errstat); |
85269fdf | 611 | #endif |
612 | ||
26ac0430 AJ |
613 | /* error index */ |
614 | bufp = asn_parse_int(bufp, Length, | |
615 | &ASNType, | |
616 | &PDU->errindex, sizeof(PDU->errindex)); | |
617 | if (bufp == NULL) | |
618 | ASN_PARSE_ERROR(NULL); | |
85269fdf | 619 | |
32d002cb | 620 | #if DEBUG_PDU_DECODE |
26ac0430 | 621 | snmplib_debug(8, "PDU Error Index: %d\n", PDU->errindex); |
85269fdf | 622 | #endif |
623 | ||
26ac0430 | 624 | break; |
43d4303e | 625 | } |
85269fdf | 626 | |
43d4303e | 627 | return (bufp); |
85269fdf | 628 | } |
629 | ||
85269fdf | 630 | /* |
631 | * Add a null variable with the requested name to the end of the list of | |
632 | * variables for this pdu. | |
633 | */ | |
468ae12b | 634 | void |
43d4303e | 635 | snmp_add_null_var(struct snmp_pdu *pdu, oid * name, int name_length) |
85269fdf | 636 | { |
43d4303e | 637 | struct variable_list *vars; |
638 | struct variable_list *ptr; | |
85269fdf | 639 | |
43d4303e | 640 | vars = snmp_var_new(name, name_length); |
641 | if (vars == NULL) { | |
26ac0430 AJ |
642 | perror("snmp_add_null_var:xmalloc"); |
643 | return; | |
43d4303e | 644 | } |
645 | if (pdu->variables == NULL) { | |
26ac0430 | 646 | pdu->variables = vars; |
43d4303e | 647 | } else { |
648 | ||
26ac0430 AJ |
649 | /* Insert at the end */ |
650 | for (ptr = pdu->variables; | |
651 | ptr->next_variable; | |
652 | ptr = ptr->next_variable) | |
653 | /*EXIT */ ; | |
654 | ptr->next_variable = vars; | |
43d4303e | 655 | } |
85269fdf | 656 | |
43d4303e | 657 | return; |
85269fdf | 658 | } |