1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdlib.h>
30 #include <sys/types.h>
31 #include <netinet/in.h>
32 #include <stdio.h>
33 #include <sys/socket.h>
34 #include <errno.h>
35 #include <syslog.h>
36 #include <string.h>
37 #include <arpa/inet.h>
38 #include <netdb.h>
39 #include <nlist.h>
40 #include <sys/uio.h>
41 #include "snmp_msg.h"
42 #include "impl.h"
43 #include "trace.h"
44 #include "asn1.h"
45 #include "snmp.h"
46 #include "pdu.h"
47 #include "error.h"
48
49 /***** LOCAL CONSTANTS *****/
50
51 /*It is practically feasible to have a packet up to around 9k bytes (less than 9.5k).*/
52 #define PACKET_LENGTH 9500 /* The SNMP recommendation is 1500! */
53 #define COMMUNITY_LENGTH 128
54
55
56 /***** LOCAL VARIABLES *****/
57
58 static char static_error_label[500] = "";
59
60
61 /***** LOCAL FUNCTIONS *****/
62
63 static void trace_packet(u_char *packet, int length);
64 static void trace_snmp_variable(SNMP_variable *variable);
65
66 static SNMP_pdu *snmp_pdu_decode(u_char *packet, int length, char *error_label);
67 static SNMP_variable *snmp_pdu_decode_variable(u_char **data, int *length, char *error_label);
68 static int snmp_pdu_encode(SNMP_pdu *pdu, u_char *packet, int *length, char *error_label);
69 static u_char *snmp_pdu_encode_variable(SNMP_variable *variable, u_char *data, int *length, char *error_label);
70
71 static void shift_array(u_char *begin, int length, int shift_amount);
72
73
74 /********************************************************************/
75
snmp_variable_new(char * error_label)76 SNMP_variable *snmp_variable_new(char *error_label)
77 {
78 SNMP_variable *new;
79
80
81 error_label[0] = '\0';
82
83 new = (SNMP_variable *) malloc(sizeof(SNMP_variable));
84 if(new == NULL)
85 {
86 sprintf(error_label, ERR_MSG_ALLOC);
87 return NULL;
88 }
89 memset(new, 0, sizeof(SNMP_variable));
90
91 return new;
92 }
93
94
95 /********************************************************************/
96
snmp_typed_variable_new(Oid * name,u_char type,SNMP_value * value,char * error_label)97 SNMP_variable *snmp_typed_variable_new(Oid *name, u_char type, SNMP_value *value, char *error_label)
98 {
99 SNMP_variable *new;
100
101
102 error_label[0] = '\0';
103
104 if(name == NULL)
105 {
106 sprintf(error_label, "BUG: snmp_typed_variable_new(): name is NULL");
107 return NULL;
108 }
109
110 if(value == NULL)
111 {
112 sprintf(error_label, "BUG: snmp_typed_variable_new(): value is NULL");
113 return NULL;
114 }
115
116 new = snmp_variable_new(error_label);
117 if(new == NULL)
118 {
119 return NULL;
120 }
121
122 /* name */
123 if(SSAOidCpy(&(new->name), name, error_label))
124 {
125 snmp_variable_free(new);
126 return NULL;
127 }
128
129 /* type */
130 new->type = type;
131
132 /* val, val_len */
133 switch(type)
134 {
135 case INTEGER:
136 case COUNTER:
137 case GAUGE:
138 case TIMETICKS:
139 new->val.integer = (int *) malloc(sizeof(int));
140 if(new->val.integer == NULL)
141 {
142 sprintf(error_label, ERR_MSG_ALLOC);
143 snmp_variable_free(new);
144 return NULL;
145 }
146
147 *(new->val.integer) = value->v_integer;
148
149 new->val_len = sizeof(int32_t);
150
151 break;
152
153 case IPADDRESS:
154 case OPAQUE:
155 case STRING:
156 new->val.string = (u_char *) malloc(value->v_string.len);
157 if(new->val.string == NULL)
158 {
159 sprintf(error_label, ERR_MSG_ALLOC);
160 snmp_variable_free(new);
161 return NULL;
162 }
163
164 memcpy(new->val.string,
165 value->v_string.chars,
166 value->v_string.len);
167
168 new->val_len = value->v_string.len;
169
170 break;
171
172 case OBJID:
173 new->val.objid = (Subid *) malloc(value->v_oid.len * sizeof(Subid));
174 if(new->val.objid == NULL)
175 {
176 sprintf(error_label, ERR_MSG_ALLOC);
177 snmp_variable_free(new);
178 return NULL;
179 }
180
181 /* Should * sizeof(Subid), yiru's fix*/
182 memcpy(new->val.objid,
183 value->v_oid.subids,
184 value->v_oid.len*sizeof(Subid));
185
186 new->val_len = value->v_oid.len * (int32_t)sizeof(Subid);
187
188 break;
189
190 default:
191 sprintf(error_label, "BUG: snmp_typed_variable_new(): unsupported type (0x%x)", type);
192 snmp_variable_free(new);
193 return NULL;
194 }
195
196
197 return new;
198 }
199
200
201 /********************************************************************/
202
snmp_typed_variable_append(SNMP_variable * list,Oid * name,u_char type,SNMP_value * value,char * error_label)203 SNMP_variable *snmp_typed_variable_append(SNMP_variable *list, Oid *name, u_char type, SNMP_value *value, char *error_label)
204 {
205 SNMP_variable *new;
206
207
208 error_label[0] = '\0';
209
210 new = snmp_typed_variable_new(name, type, value, error_label);
211 if(new == NULL)
212 {
213 snmp_variable_list_free(list);
214 return NULL;
215 }
216
217 if(list == NULL)
218 {
219 list = new;
220 }
221 else
222 {
223 SNMP_variable *last = NULL;
224 SNMP_variable *v;
225
226
227 for(v = list; v; v = v->next_variable)
228 {
229 last = v;
230 }
231
232 last->next_variable = new;
233 }
234
235
236 return list;
237 }
238
239
240 /********************************************************************/
241
snmp_pdu_new(char * error_label)242 SNMP_pdu *snmp_pdu_new(char *error_label)
243 {
244 SNMP_pdu *new;
245
246
247 error_label[0] = '\0';
248
249 new = (SNMP_pdu *) malloc(sizeof(SNMP_pdu));
250 if(new == NULL)
251 {
252 sprintf(error_label, ERR_MSG_ALLOC);
253 return NULL;
254 }
255 new->community = NULL;
256 new->enterprise.subids = NULL;
257 new->enterprise.len = 0;
258 new->first_variable = NULL;
259
260
261 new->version = 0;
262 new->type = 0;
263
264 new->request_id = 0;
265 new->error_status = 0;
266 new->error_index = 0;
267
268 new->ip_agent_addr.s_addr = 0;
269 new->generic = 0;
270 new->specific = 0;
271 new->time_stamp = 0;
272
273
274 return new;
275 }
276
277
278 /********************************************************************/
279
snmp_pdu_receive(int sd,Address * address,char * error_label)280 SNMP_pdu *snmp_pdu_receive(int sd, Address *address, char *error_label)
281 {
282 SNMP_pdu *pdu;
283 u_char * packet;
284 int length;
285 socklen_t address_length;
286 Address network_address;
287
288
289 error_label[0] = '\0';
290
291 packet = (u_char *) malloc (PACKET_LENGTH * sizeof (u_char));
292 if (packet == NULL) {
293 sprintf(error_label, ERR_MSG_ALLOC);
294 return NULL;
295 }
296 address_length = (socklen_t) sizeof(Address);
297 /* LINTED */
298 length = (int)recvfrom(sd, (char *) packet, PACKET_LENGTH, 0,
299 (struct sockaddr *) &network_address, &address_length);
300 if(length == -1)
301 {
302 sprintf(error_label, ERR_MSG_RECVFROM, errno_string());
303 free (packet);
304 return NULL;
305 }
306 address->sin_family = network_address.sin_family;
307 address->sin_addr.s_addr = network_address.sin_addr.s_addr;
308 address->sin_port = htons(network_address.sin_port);
309
310 if(trace_flags & TRACE_TRAFFIC)
311 {
312 trace("<< received %d bytes from %s\n\n",
313 length, address_string(address));
314 }
315
316 if(trace_flags & TRACE_PACKET)
317 {
318 trace_packet(packet, length);
319 }
320
321 pdu = snmp_pdu_decode(packet, length, error_label);
322 free (packet);
323 if(pdu == NULL)
324 {
325 return NULL;
326 }
327
328 if(trace_flags & TRACE_PDU)
329 {
330 trace_snmp_pdu(pdu);
331 }
332
333
334 return pdu;
335 }
336
337
338 /********************************************************************/
339
340 /* this function does not close sd and does not free pdu */
341
snmp_pdu_send(int sd,Address * address,SNMP_pdu * pdu,char * error_label)342 int snmp_pdu_send(int sd, Address *address, SNMP_pdu *pdu, char *error_label)
343 {
344 u_char *packet;
345 int length = PACKET_LENGTH;
346 int bytes;
347 Address network_address;
348
349
350 packet = (u_char *) malloc (PACKET_LENGTH * sizeof (u_char));
351 if (packet == NULL) {
352 sprintf(error_label, ERR_MSG_ALLOC);
353 return -1;
354 }
355 error_label[0] = '\0';
356
357 if(pdu == NULL)
358 {
359 sprintf(error_label, "BUG: snmp_pdu_send(): pdu is NULL");
360 return -1;
361 }
362
363 if(address == NULL)
364 {
365 sprintf(error_label, "BUG: snmp_pdu_send(): address is NULL");
366 free (packet);
367 return -1;
368 }
369
370 if(trace_flags & TRACE_PDU)
371 {
372 trace_snmp_pdu(pdu);
373 }
374
375 if(snmp_pdu_encode(pdu, packet, &length, error_label))
376 {
377 free (packet);
378 return -1;
379 }
380
381 if(trace_flags & TRACE_PACKET)
382 {
383 trace_packet(packet, length);
384 }
385
386 network_address.sin_family = AF_INET;
387 network_address.sin_addr.s_addr = address->sin_addr.s_addr;
388 network_address.sin_port = htons(address->sin_port);
389
390 /* LINTED */
391 bytes = (int)sendto(sd, (char *) packet, length, 0,
392 (struct sockaddr *) &network_address, sizeof(Address));
393 free (packet);
394 if(bytes == -1)
395 {
396 sprintf(error_label, ERR_MSG_SENDTO);
397 return -1;
398 }
399
400 if(trace_flags & TRACE_TRAFFIC)
401 {
402 trace(">> sent %d bytes to %s\n\n",
403 length, address_string(address));
404 }
405
406
407 return 0;
408 }
409
410
411 /********************************************************************/
412
snmp_pdu_free(SNMP_pdu * pdu)413 void snmp_pdu_free(SNMP_pdu *pdu)
414 {
415 if(pdu == NULL)
416 {
417 return;
418 }
419
420 if(pdu->community)
421 {
422 free(pdu->community);
423 }
424 if(pdu->enterprise.subids)
425 {
426 free(pdu->enterprise.subids);
427 }
428
429 snmp_variable_list_free(pdu->first_variable);
430
431 free(pdu);
432 }
433
434
435 /********************************************************************/
436
snmp_variable_list_free(SNMP_variable * variable_list)437 void snmp_variable_list_free(SNMP_variable *variable_list)
438 {
439 while(variable_list)
440 {
441 SNMP_variable *v;
442
443 v = variable_list->next_variable;
444 snmp_variable_free(variable_list);
445 variable_list = v;
446 }
447 }
448
449
450 /********************************************************************/
451
snmp_variable_free(SNMP_variable * variable)452 void snmp_variable_free(SNMP_variable *variable)
453 {
454 if(variable == NULL)
455 {
456 return;
457 }
458
459 if(variable->name.subids)
460 {
461 free(variable->name.subids);
462 }
463
464 if(variable->val.string)
465 {
466 free(variable->val.string);
467 }
468
469 free(variable);
470 }
471
472
473 /********************************************************************/
474
trace_packet(u_char * packet,int length)475 static void trace_packet(u_char *packet, int length)
476 {
477 int count;
478
479
480 trace("PACKET:\n");
481 trace("-------\n");
482 for(count = 0; count < length; count++)
483 {
484 trace("%02X ", packet[count]);
485 if((count % 16) == 15)
486 {
487 trace("\n");
488 }
489 }
490 trace("\n\n");
491 }
492
493
494 /********************************************************************/
495
trace_snmp_pdu(SNMP_pdu * pdu)496 void trace_snmp_pdu(SNMP_pdu *pdu)
497 {
498 SNMP_variable *variable;
499
500
501 trace("PDU:\n");
502 trace("----\n");
503 if(pdu == NULL)
504 {
505 trace("pdu is NULL!\n\n");
506 return;
507 }
508
509 trace("version: %d\n", pdu->version);
510 trace("community: %s\n", pdu->community? pdu->community: "NULL");
511
512 trace("type: %s\n", pdu_type_string(pdu->type));
513
514 switch(pdu->type)
515 {
516 case GET_REQ_MSG:
517 case GETNEXT_REQ_MSG:
518 case GET_RSP_MSG:
519 case SET_REQ_MSG:
520 trace("request id: %d\n", pdu->request_id);
521 trace("error status: %s\n",
522 error_status_string(pdu->error_status));
523 trace("error index: %d\n", pdu->error_index);
524 break;
525
526 case TRP_REQ_MSG:
527 trace("enterprise: %s\n",
528 SSAOidString(&(pdu->enterprise)));
529 trace("IP agent addr: %s\n",
530 ip_address_string(&(pdu->ip_agent_addr)));
531 trace("generic: %s\n",
532 generic_trap_string(pdu->generic));
533 trace("specific: %d\n", pdu->specific);
534 trace("time stamp: %d\n", pdu->time_stamp);
535 break;
536
537 default:
538 trace("\n");
539 return;
540 }
541
542 variable = pdu->first_variable;
543 while(variable)
544 {
545 trace("--------------------------------------------------\n");
546 trace_snmp_variable(variable);
547 variable = variable->next_variable;
548 }
549 trace("--------------------------------------------------\n\n");
550 }
551
552
553 /********************************************************************/
554
trace_snmp_variable(SNMP_variable * variable)555 static void trace_snmp_variable(SNMP_variable *variable)
556 {
557 Oid oid;
558 int i;
559
560
561 if(variable == NULL)
562 {
563 trace("variable is NULL\n");
564 }
565
566 /*
567 trace("variable 0x%x\n", variable);
568 trace("next 0x%x\n", variable->next_variable);
569 */
570 trace("name: %s\n", SSAOidString(&(variable->name)));
571 trace("type: %s\n", asn1_type_string(variable->type));
572 trace("length: %d\n", variable->val_len);
573 trace("value: ");
574 switch(variable->type)
575 {
576 case INTEGER:
577 case COUNTER:
578 case GAUGE:
579 case TIMETICKS:
580 trace("%d\n", *(variable->val.integer));
581 break;
582
583
584 case IPADDRESS:
585 if(variable->val_len != 4)
586 {
587 trace("val_len should be 4! (%d)\n", variable->val_len);
588 }
589 else
590 {
591 IPAddress ip_address;
592
593 ip_address.s_addr = *(variable->val.integer);
594 trace("%s\n", ip_address_string(&ip_address));
595 }
596 break;
597
598 case OBJID:
599 oid.subids = variable->val.objid;
600 oid.len = variable->val_len / (int32_t)sizeof(Subid);
601 trace("%s\n", SSAOidString(&oid));
602 break;
603
604 case STRING:
605 case OPAQUE:
606 case NULLOBJ:
607 default:
608 for(i = 0; i < variable->val_len; i++)
609 {
610 trace("%c", variable->val.string[i]);
611 }
612 trace(" ( ");
613 for(i = 0; i < variable->val_len; i++)
614 {
615 trace("%02x ", variable->val.string[i]);
616 }
617 trace(")\n");
618 break;
619 }
620 }
621
622
623 /********************************************************************/
624
625 /*
626 * Parses the packet and places the data into the pdu.
627 * If any errors are encountered, NULL is returned.
628 */
629
snmp_pdu_decode(u_char * packet,int packet_length,char * error_label)630 static SNMP_pdu *snmp_pdu_decode(u_char *packet, int packet_length, char *error_label)
631 {
632 u_char *data = packet;
633 int length = packet_length;
634 u_char type;
635 int len;
636 Subid subids[MAX_OID_LEN];
637 SNMP_pdu *pdu;
638 SNMP_variable *last_variable = NULL;
639 char community[COMMUNITY_LENGTH + 1];
640
641
642 error_label[0] = '\0';
643
644 pdu = snmp_pdu_new(error_label);
645 if(pdu == NULL)
646 {
647 return NULL;
648 }
649
650 /* header of message */
651 data = asn_parse_header(data, (uint32_t *)&length, &type, static_error_label);
652 if(data == NULL)
653 {
654 sprintf(error_label, "Decode the header of message failed: %s",
655 static_error_label);
656 snmp_pdu_free(pdu);
657 return NULL;
658 }
659 if(type != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
660 {
661 sprintf(error_label, "The message has a wrong header type (0x%x)", type);
662 snmp_pdu_free(pdu);
663 return NULL;
664 }
665
666 /* version */
667 data = asn_parse_int(data, (uint32_t *)&length, &type, (int32_t *) &pdu->version,
668 sizeof(pdu->version), static_error_label);
669 if(data == NULL)
670 {
671 sprintf(error_label, "Decode the version failed: %s",
672 static_error_label);
673 snmp_pdu_free(pdu);
674 return NULL;
675 }
676 if(pdu->version != SNMP_VERSION_1)
677 {
678 sprintf(error_label, "The message has a wrong version (%d)",
679 pdu->version);
680 snmp_pdu_free(pdu);
681 return NULL;
682 }
683
684 /* parse community */
685 len = COMMUNITY_LENGTH;
686 data = asn_parse_string(data, (uint32_t *)&length, &type, (u_char *) community,
687 (uint32_t *)&len, static_error_label);
688 if(data == NULL)
689 {
690 sprintf(error_label, "Decode the community failed: %s",
691 static_error_label);
692 snmp_pdu_free(pdu);
693 return NULL;
694 }
695 community[len] = '\0';
696 pdu->community = strdup(community);
697 if(pdu->community == NULL)
698 {
699 sprintf(error_label, ERR_MSG_ALLOC);
700 snmp_pdu_free(pdu);
701 return NULL;
702 }
703
704 /* header od pdu */
705 data = asn_parse_header(data, (uint32_t *)&length, &type, static_error_label);
706 if(data == NULL)
707 {
708 sprintf(error_label, "Decode the header of pdu failed: %s",
709 static_error_label);
710 snmp_pdu_free(pdu);
711 return NULL;
712 }
713 pdu->type = type;
714
715
716 switch(pdu->type)
717 {
718 case GET_REQ_MSG:
719 case GETNEXT_REQ_MSG:
720 case GET_RSP_MSG:
721 case SET_REQ_MSG:
722
723 /* request id */
724 data = asn_parse_int(data, (uint32_t *)&length, &type, (int32_t *) &pdu->request_id,
725 sizeof(pdu->request_id), static_error_label);
726 if(data == NULL)
727 {
728 sprintf(error_label, "Decode the request id failed: %s",
729 static_error_label);
730 snmp_pdu_free(pdu);
731 return NULL;
732 }
733
734 /* error status */
735 data = asn_parse_int(data, (uint32_t *)&length, &type, (int32_t *) &pdu->error_status,
736 sizeof(pdu->error_status), static_error_label);
737 if (data == NULL)
738 {
739 sprintf(error_label, "Decode the error status failed: %s",
740 static_error_label);
741 snmp_pdu_free(pdu);
742 return NULL;
743 }
744
745 /* error index */
746 data = asn_parse_int(data, (uint32_t *)&length, &type, (int32_t *)&pdu->error_index,
747 sizeof(pdu->error_index), static_error_label);
748 if (data == NULL)
749 {
750 sprintf(error_label, "Decode the error index failed: %s",
751 static_error_label);
752 snmp_pdu_free(pdu);
753 return NULL;
754 }
755
756 break;
757
758
759 case TRP_REQ_MSG:
760
761 /* enterprise */
762 pdu->enterprise.len = MAX_OID_LEN;
763 data = asn_parse_objid(data, (uint32_t *)&length, &type, subids,
764 &pdu->enterprise.len, static_error_label);
765 if(data == NULL)
766 {
767 sprintf(error_label, "Decode the enterprise failed: %s",
768 static_error_label);
769 snmp_pdu_free(pdu);
770 return NULL;
771 }
772 pdu->enterprise.subids = (Subid *) malloc(pdu->enterprise.len * sizeof(Subid));
773 if(pdu->enterprise.subids == NULL)
774 {
775 sprintf(error_label, ERR_MSG_ALLOC);
776 snmp_pdu_free(pdu);
777 return NULL;
778 }
779 memcpy(pdu->enterprise.subids, subids, pdu->enterprise.len * sizeof(Subid));
780
781 /* agent address */
782 len = 4;
783 data = asn_parse_string(data, (uint32_t *)&length, &type,
784 (u_char *)&pdu->ip_agent_addr.s_addr, (uint32_t *)&len, static_error_label);
785 if(data == NULL)
786 {
787 sprintf(error_label, "Decode the agent address failed: %s",
788 static_error_label);
789 snmp_pdu_free(pdu);
790 return NULL;
791 }
792
793 /* generic trap */
794 data = asn_parse_int(data, (uint32_t *)&length, &type, (int32_t *)&pdu->generic,
795 sizeof(pdu->generic), static_error_label);
796 if(data == NULL)
797 {
798 sprintf(error_label, "Decode the generic trap failed: %s",
799 static_error_label);
800 snmp_pdu_free(pdu);
801 return NULL;
802 }
803
804 /* specific trap */
805 data = asn_parse_int(data, (uint32_t *)&length, &type, (int32_t *)&pdu->specific,
806 sizeof(pdu->specific), static_error_label);
807 if(data == NULL)
808 {
809 sprintf(error_label, "Decode the specific trap failed: %s",
810 static_error_label);
811 snmp_pdu_free(pdu);
812 return NULL;
813 }
814
815 /* time stamp */
816 data = asn_parse_unsigned_int(data, (uint32_t *)&length, &type, (int32_t *)&pdu->time_stamp,
817 sizeof(pdu->time_stamp), static_error_label);
818 if(data == NULL)
819 {
820 sprintf(error_label, "Decode the time stamp failed: %s",
821 static_error_label);
822 snmp_pdu_free(pdu);
823 return NULL;
824 }
825
826 break;
827
828
829 default:
830 sprintf(error_label, "The type of the pdu is wrong (%d)", pdu->type);
831 snmp_pdu_free(pdu);
832 return NULL;
833 }
834
835
836 /* header of variables */
837 data = asn_parse_header(data, (uint32_t *)&length, &type, static_error_label);
838 if(data == NULL)
839 {
840 sprintf(error_label, "Decode the header of the variables failed: %s",
841 static_error_label);
842 snmp_pdu_free(pdu);
843 return NULL;
844 }
845 if(type != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
846 {
847 sprintf(error_label, "The header of the variables has a wrong type (%x)", type);
848 snmp_pdu_free(pdu);
849 return NULL;
850 }
851
852
853
854 while(length > 0)
855 {
856 SNMP_variable *variable;
857
858
859 variable = snmp_pdu_decode_variable(&data , &length, error_label);
860 if(variable == NULL)
861 {
862 snmp_pdu_free(pdu);
863 return NULL;
864 }
865
866 if(pdu->first_variable == NULL)
867 {
868 pdu->first_variable = variable;
869 }
870 else
871 {
872 last_variable->next_variable = variable;
873 }
874 last_variable = variable;
875
876 } /* while */
877
878
879 return pdu;
880 }
881
882
883 /********************************************************************/
884
snmp_pdu_decode_variable(u_char ** data,int * length,char * error_label)885 static SNMP_variable *snmp_pdu_decode_variable(u_char **data, int *length, char *error_label)
886 {
887 u_char *d = *data;
888 u_char *value_start;
889 int len = *length;
890 SNMP_variable *variable;
891 u_char type;
892 Subid subids[MAX_OID_LEN];
893
894
895 error_label[0] = '\0';
896
897 variable = snmp_variable_new(error_label);
898 if(variable == NULL)
899 {
900 return NULL;
901 }
902
903
904 /* header of variable */
905 d = asn_parse_header(d, (uint32_t *)&len, &type, static_error_label);
906 if(d == NULL)
907 {
908 sprintf(error_label, "Decode the header of a variable failed: %s",
909 static_error_label);
910 snmp_variable_free(variable);
911 return NULL;
912 }
913 if(type != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
914 {
915 sprintf(error_label, "The header of a variable has a wrong type (%x)", type);
916 snmp_variable_free(variable);
917 return NULL;
918 }
919
920
921 /* name */
922 variable->name.len = MAX_OID_LEN;
923 d = asn_parse_objid(d, (uint32_t *)&len, &type, subids, &(variable->name.len), static_error_label);
924 if(d == NULL)
925 {
926 sprintf(error_label, "Decode the name of a variable failed: %s",
927 static_error_label);
928 snmp_variable_free(variable);
929 return NULL;
930 }
931 if(type != (u_char) OBJID)
932 {
933 sprintf(error_label, "The name of a variable has wrong type (%x)", type);
934 snmp_variable_free(variable);
935 return NULL;
936 }
937 variable->name.subids = (Subid *) malloc(variable->name.len * sizeof(Subid));
938 if(variable->name.subids == NULL)
939 {
940 sprintf(error_label, ERR_MSG_ALLOC);
941 snmp_variable_free(variable);
942 return NULL;
943 }
944 memcpy(variable->name.subids, subids, variable->name.len * sizeof(Subid));
945
946
947 /* find out what type of object this is */
948 variable->val_len = len;
949 value_start = d;
950 d = asn_parse_header(d, (uint32_t *)&variable->val_len, &variable->type, static_error_label);
951 if(d == NULL)
952 {
953 sprintf(error_label, "Decode the type of a variable failed: %s",
954 static_error_label);
955 snmp_variable_free(variable);
956 return NULL;
957 }
958
959 switch(variable->type)
960 {
961 case INTEGER:
962 case COUNTER:
963 case GAUGE:
964 case TIMETICKS:
965 variable->val.integer = (int32_t *) malloc(sizeof(int32_t));
966 if(variable->val.integer == NULL)
967 {
968 sprintf(error_label, ERR_MSG_ALLOC);
969 snmp_variable_free(variable);
970 return NULL;
971 }
972 variable->val_len = sizeof(int32_t);
973 d = asn_parse_unsigned_int(value_start, (uint32_t *)&len, &variable->type,
974 (int32_t *)variable->val.integer, sizeof(int32_t), static_error_label);
975 if(d == NULL)
976 {
977 sprintf(error_label, "Decode a variable of type integer failed: %s",
978 static_error_label);
979 snmp_variable_free(variable);
980 return NULL;
981 }
982 break;
983
984 case STRING:
985 case IPADDRESS:
986 case OPAQUE:
987 variable->val.string = (u_char *) malloc(variable->val_len);
988 if(variable->val.string == NULL)
989 {
990 sprintf(error_label, ERR_MSG_ALLOC);
991 snmp_variable_free(variable);
992 return NULL;
993 }
994 d = asn_parse_string(value_start, (uint32_t *)&len, &variable->type,
995 variable->val.string, (uint32_t *)&variable->val_len, static_error_label);
996 if(d == NULL)
997 {
998 sprintf(error_label, "Decode a variable of type octet string failed: %s",
999 static_error_label);
1000 snmp_variable_free(variable);
1001 return NULL;
1002 }
1003 break;
1004
1005 case OBJID:
1006 variable->val_len = MAX_OID_LEN;
1007 d = asn_parse_objid(value_start, (uint32_t *)&len, &variable->type,
1008 subids, &variable->val_len, static_error_label);
1009 if(d == NULL)
1010 {
1011 sprintf(error_label, "Decode a variable of type object identifier failed: %s",
1012 static_error_label);
1013 snmp_variable_free(variable);
1014 return NULL;
1015 }
1016 variable->val_len = variable->val_len * (int32_t)sizeof(Subid);
1017 variable->val.objid = (Subid *) malloc(variable->val_len);
1018 if(variable->val.objid == NULL)
1019 {
1020 sprintf(error_label, ERR_MSG_ALLOC);
1021 snmp_variable_free(variable);
1022 return NULL;
1023 }
1024 memcpy(variable->val.objid, subids, variable->val_len);
1025 break;
1026
1027 case NULLOBJ:
1028 break;
1029
1030 default:
1031 sprintf(error_label, "A variable has a wrong type (%x)", variable->type);
1032 snmp_variable_free(variable);
1033 return NULL;
1034 }
1035
1036 /* LINTED */
1037 *length = *length - (uint32_t)(d - *data);
1038 *data = d;
1039
1040
1041 return variable;
1042 }
1043
1044
1045 /********************************************************************/
1046
1047 /*
1048 * Takes a pdu and serializes the ASN PDU into the area
1049 * pointed to by packet. length is the size of the data area available.
1050 * Returns the length of the completed packet in length. If any errors
1051 * occur, -1 is returned. If all goes well, 0 is returned.
1052 */
1053
snmp_pdu_encode(SNMP_pdu * pdu,u_char * packet,int * packet_length,char * error_label)1054 static int snmp_pdu_encode(SNMP_pdu *pdu, u_char *packet, int *packet_length, char *error_label)
1055 {
1056 u_char *buf;
1057 int buf_len;
1058 int len;
1059 SNMP_variable *variable;
1060 u_char *cp;
1061 int32_t total_length;
1062
1063
1064 buf = (u_char *) malloc (PACKET_LENGTH * sizeof (u_char));
1065 if (buf == NULL) {
1066 sprintf(error_label, ERR_MSG_ALLOC);
1067 return -1;
1068 }
1069 error_label[0] = '\0';
1070
1071 cp = packet;
1072 len = *packet_length;
1073
1074 /* encode the variables in packet */
1075 for(variable = pdu->first_variable; variable; variable = variable->next_variable)
1076 {
1077 cp = snmp_pdu_encode_variable(variable, cp, &len, error_label);
1078 if(cp == NULL) {
1079 free (buf);
1080 return -1;
1081 }
1082 }
1083 /* LINTED */
1084 total_length = (int32_t)(cp - packet); /* Better fit in 32 bits */
1085
1086 /* encode the header for the variables in buf */
1087 buf_len = PACKET_LENGTH;
1088 cp = asn_build_header(buf, (uint32_t *)&buf_len, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
1089 total_length, static_error_label);
1090 if(cp == NULL)
1091 {
1092 sprintf(error_label, "Encode the header of the variables failed: %s",
1093 static_error_label);
1094 free (buf);
1095 return -1;
1096 }
1097
1098 /* copy the encoded variables from packet to buf */
1099 memcpy(cp, packet, total_length);
1100 /* LINTED */
1101 total_length += (int32_t)(cp - buf);
1102
1103
1104 /* encode the pdu in packet */
1105 len = *packet_length;
1106 switch(pdu->type)
1107 {
1108 case GET_REQ_MSG:
1109 case GETNEXT_REQ_MSG:
1110 case GET_RSP_MSG:
1111 case SET_REQ_MSG:
1112
1113 /* request id */
1114 cp = asn_build_int(packet, (uint32_t *)&len, (u_char) INTEGER,
1115 (int32_t *) &pdu->request_id, sizeof(pdu->request_id),
1116 static_error_label);
1117 if(cp == NULL)
1118 {
1119 sprintf(error_label, "Encode the request id failed: %s",
1120 static_error_label);
1121 free (buf);
1122 return -1;
1123 }
1124
1125 /* error status */
1126 cp = asn_build_int(cp, (uint32_t *)&len, (u_char) INTEGER,
1127 (int32_t *) &pdu->error_status, sizeof(pdu->error_status),
1128 static_error_label);
1129 if(cp == NULL)
1130 {
1131 sprintf(error_label, "Encode the error status failed: %s",
1132 static_error_label);
1133 free (buf);
1134 return -1;
1135 }
1136
1137 /* error index */
1138 cp = asn_build_int(cp, (uint32_t *)&len, (u_char) INTEGER,
1139 (int32_t *) &pdu->error_index, sizeof(pdu->error_index),
1140 static_error_label);
1141 if(cp == NULL)
1142 {
1143 sprintf(error_label, "Encode the error index failed: %s",
1144 static_error_label);
1145 free (buf);
1146 return -1;
1147 }
1148
1149 break;
1150
1151
1152 case TRP_REQ_MSG:
1153
1154 /* enterprise */
1155 cp = asn_build_objid(packet, (uint32_t *)&len, (u_char) OBJID,
1156 (Subid *) pdu->enterprise.subids, pdu->enterprise.len,
1157 static_error_label);
1158 if(cp == NULL)
1159 {
1160 sprintf(error_label, "Encode the enterprise failed: %s",
1161 static_error_label);
1162 free (buf);
1163 return -1;
1164 }
1165
1166 /* agent-addr */
1167 cp = asn_build_string(cp, (uint32_t *)&len, (u_char) IPADDRESS,
1168 (u_char *) &pdu->ip_agent_addr.s_addr,
1169 sizeof(pdu->ip_agent_addr.s_addr),
1170 static_error_label);
1171 if(cp == NULL)
1172 {
1173 sprintf(error_label, "Encode the agent address failed: %s",
1174 static_error_label);
1175 free (buf);
1176 return -1;
1177 }
1178
1179 /* generic trap */
1180 cp = asn_build_int(cp, (uint32_t *)&len, (u_char) INTEGER,
1181 (int32_t *) &pdu->generic, sizeof(pdu->generic),
1182 static_error_label);
1183 if(cp == NULL)
1184 {
1185 sprintf(error_label, "Encode the generic trap failed: %s",
1186 static_error_label);
1187 free (buf);
1188 return -1;
1189 }
1190
1191 /* specific trap */
1192 cp = asn_build_int(cp, (uint32_t *)&len, (u_char) INTEGER,
1193 (int32_t *) &pdu->specific, sizeof(pdu->specific),
1194 static_error_label);
1195 if(cp == NULL)
1196 {
1197 sprintf(error_label, "Encode the specific trap failed: %s",
1198 static_error_label);
1199 free (buf);
1200 return -1;
1201 }
1202
1203 /* time stamp */
1204 cp = asn_build_unsigned_int(cp, (uint32_t *)&len, (u_char) TIMETICKS,
1205 (int32_t *) &pdu->time_stamp, sizeof(pdu->time_stamp),
1206 static_error_label);
1207 if(cp == NULL)
1208 {
1209 sprintf(error_label, "Encode the time stamp failed: %s",
1210 static_error_label);
1211 free (buf);
1212 return -1;
1213 }
1214
1215 break;
1216
1217
1218 default:
1219 sprintf(error_label, "The pdu has a wrong type (%x)", pdu->type);
1220 free (buf);
1221 return -1;
1222
1223 } /* switch */
1224
1225
1226 /* copy the encoded variables and their header from buf to packet */
1227 if(len < total_length)
1228 {
1229 sprintf(error_label, "The buffer is too small");
1230 free (buf);
1231 return -1;
1232 }
1233 memcpy(cp, buf, total_length);
1234 /* LINTED */
1235 total_length += (int32_t)(cp - packet);
1236
1237
1238 /* encode the header of the pdu in buf */
1239 len = PACKET_LENGTH;
1240 /* LINTED */
1241 cp = asn_build_header(buf, (uint32_t *)&len, (u_char)pdu->type,
1242 total_length, static_error_label);
1243 if(cp == NULL)
1244 {
1245 sprintf(error_label, "Encode the header of the pdu failed: %s",
1246 static_error_label);
1247 free (buf);
1248 return -1;
1249 }
1250
1251
1252 /* copy the pdu from packet to buf */
1253 if(len < total_length)
1254 {
1255 sprintf(error_label, "The buffer is too small");
1256 free (buf);
1257 return -1;
1258 }
1259 memcpy(cp, packet, total_length);
1260 /* LINTED */
1261 total_length += (int32_t)(cp - buf);
1262
1263 /* encode the message in packet */
1264 len = *packet_length;
1265
1266 if(pdu->community == NULL)
1267 {
1268 sprintf(error_label, "BUG: snmp_pdu_encode(): community is NULL");
1269 free (buf);
1270 return -1;
1271 }
1272
1273 cp = asn_build_header(packet, (uint32_t *)&len, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
1274 /* LINTED */
1275 total_length + (int32_t)strlen(pdu->community) + 5,
1276 static_error_label);
1277 if(cp == NULL)
1278 {
1279 sprintf(error_label, "Encode the header of the message failed: %s",
1280 static_error_label);
1281 free (buf);
1282 return -1;
1283 }
1284
1285 /* version */
1286 cp = asn_build_int(cp, (uint32_t *)&len, (u_char) INTEGER,
1287 (int32_t *) &pdu->version, sizeof(pdu->version),
1288 static_error_label);
1289 if(cp == NULL)
1290 {
1291 sprintf(error_label, "Encode the version failed: %s",
1292 static_error_label);
1293 free (buf);
1294 return -1;
1295 }
1296
1297 /* community */
1298 cp = asn_build_string(cp, (uint32_t *)&len, (u_char) STRING,
1299 /* LINTED */
1300 (u_char *) pdu->community, (int32_t)strlen(pdu->community),
1301 static_error_label);
1302 if(cp == NULL)
1303 {
1304 sprintf(error_label, "Encode the community failed: %s",
1305 static_error_label);
1306 free (buf);
1307 return -1;
1308 }
1309
1310
1311 /* copy the pdu and its header from buf to packet */
1312 if(len < total_length)
1313 {
1314 sprintf(error_label, "The buffer is too small");
1315 free (buf);
1316 return -1;
1317 }
1318
1319 memcpy(cp, buf, total_length);
1320 /* LINTED */
1321 total_length += (int32_t)(cp - packet);
1322 *packet_length = total_length;
1323
1324 free (buf);
1325 return 0;
1326 }
1327
1328
1329 /********************************************************************/
1330
snmp_pdu_encode_variable(SNMP_variable * variable,u_char * data,int * length,char * error_label)1331 static u_char *snmp_pdu_encode_variable(SNMP_variable *variable, u_char *data, int *length, char *error_label)
1332 {
1333 int dummy_len, header_len, header_shift;
1334 u_char *data_ptr;
1335
1336
1337 error_label[0] = '\0';
1338
1339 dummy_len = *length;
1340 data_ptr = data;
1341 data = asn_build_header(data, (uint32_t *)&dummy_len, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), 0,
1342 static_error_label);
1343 if(data == NULL) {
1344 sprintf(error_label, "Encode the header of a variable failed: %s",
1345 static_error_label);
1346 return NULL;
1347 }
1348
1349 /* LINTED */
1350 header_len = (int32_t)(data - data_ptr);
1351 *length = *length - header_len;
1352 data = asn_build_objid(data, (uint32_t *)length, (u_char) OBJID,
1353 variable->name.subids, variable->name.len, static_error_label);
1354 if(data == NULL)
1355 {
1356 sprintf(error_label, "Encode the name of a variable failed: %s",
1357 static_error_label);
1358 return NULL;
1359 }
1360
1361
1362 switch(variable->type)
1363 {
1364 case INTEGER:
1365 case GAUGE:
1366 case COUNTER:
1367 case TIMETICKS:
1368 if (variable->type == TIMETICKS)
1369 data = asn_build_unsigned_int(data, (uint32_t *)length, variable->type,
1370 (int32_t *) variable->val.integer, variable->val_len, static_error_label);
1371 else
1372 data = asn_build_int(data, (uint32_t *)length, variable->type,
1373 (int32_t *) variable->val.integer, variable->val_len, static_error_label);
1374 if(data == NULL)
1375 {
1376 sprintf(error_label, "Encode a variable of type integer failed: %s",
1377 static_error_label);
1378 return NULL;
1379 }
1380 break;
1381
1382 case STRING:
1383 case IPADDRESS:
1384 case OPAQUE:
1385 data = asn_build_string(data, (uint32_t *)length, variable->type,
1386 variable->val.string, variable->val_len, static_error_label);
1387 if(data == NULL)
1388 {
1389 sprintf(error_label, "Encode a variable of type octet string failed: %s",
1390 static_error_label);
1391 return NULL;
1392 }
1393 break;
1394
1395 case OBJID:
1396 data = asn_build_objid(data, (uint32_t *)length, variable->type, variable->val.objid,
1397 variable->val_len / (int32_t)sizeof(Subid), static_error_label);
1398 if(data == NULL)
1399 {
1400 sprintf(error_label, "Encode a variable of type object identifier failed: %s",
1401 static_error_label);
1402 return NULL;
1403 }
1404 break;
1405
1406 case NULLOBJ:
1407 data = asn_build_null(data, (uint32_t *)length, variable->type, static_error_label);
1408 if(data == NULL)
1409 {
1410 sprintf(error_label, "Encode a variable of type null failed: %s",
1411 static_error_label);
1412 return NULL;
1413 }
1414 break;
1415
1416 default:
1417 sprintf(error_label, "A variable has a wrong type (%x)", variable->type);
1418 return NULL;
1419 } /* switch */
1420
1421
1422 /* LINTED */
1423 dummy_len = (uint32_t)(data - data_ptr) - header_len;
1424 header_shift = 0;
1425 if(dummy_len >= 0x80)
1426 {
1427 header_shift++;
1428 if(dummy_len > 0xFF)
1429 {
1430 header_shift++;
1431 }
1432 }
1433
1434
1435 if(header_shift)
1436 {
1437 *length = *length - header_shift;
1438 if(*length < 0)
1439 {
1440 sprintf(error_label, "The buffer is too small");
1441 return NULL;
1442 }
1443
1444 shift_array(data_ptr + header_len, dummy_len, header_shift);
1445 data = data + header_shift;
1446 header_len = header_len + header_shift;
1447 }
1448
1449
1450 if(asn_build_header(data_ptr, (uint32_t *)&dummy_len, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR),
1451 dummy_len, static_error_label) == NULL)
1452 {
1453 sprintf(error_label, "Encode the header of a variable failed: %s",
1454 static_error_label);
1455 return NULL;
1456 }
1457
1458
1459 return data;
1460 }
1461
1462
1463 /********************************************************************/
1464
shift_array(u_char * begin,int length,int shift_amount)1465 static void shift_array(u_char *begin, int length, int shift_amount)
1466 {
1467 register u_char *old, *new;
1468
1469 if(shift_amount >= 0)
1470 {
1471 old = begin + length - 1;
1472 new = old + shift_amount;
1473
1474 while(length--)
1475 {
1476 *new-- = *old--;
1477 }
1478 }
1479 else
1480 {
1481 old = begin;
1482 new = begin + shift_amount;
1483
1484 while(length--)
1485 {
1486 *new++ = *old++;
1487 }
1488 }
1489 }
1490
1491
1492 /********************************************************************/
1493
snmp_pdu_dup(SNMP_pdu * pdu,char * error_label)1494 SNMP_pdu *snmp_pdu_dup(SNMP_pdu *pdu, char *error_label)
1495 {
1496 SNMP_pdu *new;
1497
1498
1499 error_label[0] = '\0';
1500
1501 new = snmp_pdu_new(error_label);
1502 if(new == NULL)
1503 {
1504 return NULL;
1505 }
1506
1507 new->version = pdu->version;
1508 new->community = strdup(pdu->community);
1509 if(new->community == NULL)
1510 {
1511 sprintf(error_label, ERR_MSG_ALLOC);
1512 snmp_pdu_free(new);
1513 return NULL;
1514 }
1515
1516 new->type = pdu->type;
1517
1518 new->request_id = pdu->request_id;
1519 new->error_status = pdu->error_status;
1520 new->error_index = pdu->error_index;
1521
1522 if(SSAOidCpy(&(new->enterprise), &(pdu->enterprise), error_label))
1523 {
1524 snmp_pdu_free(new);
1525 return NULL;
1526 }
1527
1528 memcpy(&(new->ip_agent_addr), &(pdu->ip_agent_addr), sizeof(IPAddress));
1529 new->generic = pdu->generic;
1530 new->specific = pdu->specific;
1531 new->time_stamp = pdu->time_stamp;
1532
1533
1534 return new;
1535 }
1536
1537
1538 /********************************************************************/
1539
1540 SNMP_variable *
snmp_variable_dup(SNMP_variable * variable,char * error_label)1541 snmp_variable_dup(SNMP_variable *variable, char *error_label)
1542 {
1543 SNMP_variable *new;
1544
1545
1546 error_label[0] = '\0';
1547
1548 new = snmp_variable_new(error_label);
1549 if (new == NULL) {
1550 return (NULL);
1551 }
1552
1553 if (SSAOidCpy(&(new->name), &(variable->name), error_label)) {
1554 snmp_variable_free(new);
1555 return (NULL);
1556 }
1557
1558 new->type = variable->type;
1559 if (variable->val_len > 0) {
1560 new->val.string = (uchar_t *)malloc(variable->val_len);
1561 if (new->val.string == NULL) {
1562 sprintf(error_label, ERR_MSG_ALLOC);
1563 snmp_variable_free(new);
1564 return (NULL);
1565 }
1566 memcpy(new->val.string, variable->val.string,
1567 variable->val_len);
1568 } else {
1569 new->val.string = NULL;
1570 }
1571
1572 new->val_len = variable->val_len;
1573
1574
1575 return (new);
1576 }
1577
1578
1579 /********************************************************************/
1580
snmp_pdu_append_null_variable(SNMP_pdu * pdu,Oid * name,char * error_label)1581 SNMP_variable *snmp_pdu_append_null_variable(SNMP_pdu *pdu, Oid *name, char *error_label)
1582 {
1583 SNMP_variable *new;
1584 SNMP_variable *current, *last;
1585
1586
1587 error_label[0] = '\0';
1588
1589 if(pdu == NULL)
1590 {
1591 sprintf(error_label, "BUG: snmp_pdu_append_null_variable(): pdu is NULL");
1592 return NULL;
1593 }
1594
1595 if(name == NULL)
1596 {
1597 sprintf(error_label, "BUG: snmp_pdu_append_null_variable(): pdu is NULL");
1598 return NULL;
1599 }
1600
1601 new = snmp_variable_new(error_label);
1602 if(new == NULL)
1603 {
1604 return NULL;
1605 }
1606
1607 if(SSAOidCpy(&(new->name), name, error_label))
1608 {
1609 snmp_variable_free(new);
1610 return NULL;
1611 }
1612
1613 new->type = NULLOBJ;
1614
1615 last = NULL;
1616 for(current = pdu->first_variable; current; current = current->next_variable)
1617 {
1618 last = current;
1619 }
1620
1621 if(last)
1622 {
1623 last->next_variable = new;
1624 }
1625 else
1626 {
1627 pdu->first_variable = new;
1628 }
1629
1630
1631 return new;
1632 }
1633
ssa_append_integer_variable(SNMP_variable * list,Oid * oid,int num,char * error_label,u_char asn1_type)1634 SNMP_variable *ssa_append_integer_variable(SNMP_variable *list, Oid *oid, int num,char *error_label,u_char asn1_type)
1635 {
1636 SNMP_value value;
1637
1638 value.v_integer = num;
1639 list = snmp_typed_variable_append(list,oid,asn1_type,&value,error_label);
1640 if(list == NULL){
1641 error("ssa_append_integer_variable failed: oid: %s, value: %d\n",
1642 SSAOidString(oid),num);
1643 }
1644 return(list);
1645 }
1646
1647 SNMP_variable *
ssa_append_string_variable(SNMP_variable * list,Oid * oid,String str,char * error_label)1648 ssa_append_string_variable(SNMP_variable *list, Oid *oid, String str,
1649 char *error_label)
1650 {
1651 SNMP_value value;
1652
1653 if (str.chars == NULL)
1654 return (NULL);
1655 value.v_string.chars = (uchar_t *)str.chars;
1656 value.v_string.len = str.len;
1657 list = snmp_typed_variable_append(list, oid, STRING, &value,
1658 error_label);
1659 if (list == NULL) {
1660 error("ssa_append_string_variable failed: oid: %s, \
1661 value: %s\n", SSAOidString(oid), str);
1662 }
1663 return (list);
1664 }
1665
ssa_append_oid_variable(SNMP_variable * list,Oid * oid,Oid name,char * error_label)1666 SNMP_variable *ssa_append_oid_variable(SNMP_variable *list, Oid *oid, Oid name, char *error_label)
1667 {
1668 SNMP_value value;
1669
1670 if(oid == NULL || name.subids == NULL || name.len == 0) return NULL;
1671 value.v_oid.subids = name.subids;
1672 value.v_oid.len = name.len;
1673 list = snmp_typed_variable_append(list,oid,OBJID,&value,error_label);
1674 if(list == NULL){
1675 error("ssa_append_oid_varaible(%s,%s) failed\n",
1676 SSAOidString(oid),SSAOidString(&name));
1677 }
1678 return(list);
1679 }
1680
1681
1682
1683
1684
1685
1686