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