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