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 (c) 1998 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <sys/utsname.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #include <netdb.h>
40 #include "snmp_msg.h"
41 #include "impl.h"
42 #include "asn1.h"
43 #include "snmp.h"
44 #include "error.h"
45
46
47 /********************************************************************/
48
pdu_type_string(u_char type)49 char *pdu_type_string(u_char type)
50 {
51 static char buffer[50];
52
53
54 switch(type)
55 {
56 case GET_REQ_MSG:
57 sprintf(buffer, "GET_REQ_MSG (0x%x)", type);
58 break;
59 case GETNEXT_REQ_MSG:
60 sprintf(buffer, "GETNEXT_REQ_MSG (0x%x)", type);
61 break;
62 case GET_RSP_MSG:
63 sprintf(buffer, "GET_RSP_MSG (0x%x)", type);
64 break;
65 case SET_REQ_MSG:
66 sprintf(buffer, "SET_REQ_MSG (0x%x)", type);
67 break;
68 case TRP_REQ_MSG:
69 sprintf(buffer, "TRP_MSG (0x%x)", type);
70 break;
71 default:
72 sprintf(buffer, "UNKNOWN! (0x%x)", type);
73 break;
74 }
75
76 return buffer;
77 }
78
79
80 /********************************************************************/
81
asn1_type_string(u_char type)82 char *asn1_type_string(u_char type)
83 {
84 static char buffer[50];
85
86
87 switch(type)
88 {
89 case ASN_INTEGER:
90 sprintf(buffer, "INTEGER (0x%x)", type);
91 break;
92 case COUNTER:
93 sprintf(buffer, "COUNTER (0x%x)", type);
94 break;
95 case GAUGE:
96 sprintf(buffer, "GAUGE (0x%x)", type);
97 break;
98 case TIMETICKS:
99 sprintf(buffer, "TIMETICKS (0x%x)", type);
100 break;
101 case ASN_OCTET_STR:
102 sprintf(buffer, "OCTET STRING (0x%x)", type);
103 break;
104 case IPADDRESS:
105 sprintf(buffer, "IP ADDRESS (0x%x)", type);
106 break;
107 case OPAQUE:
108 sprintf(buffer, "OPAQUE (0x%x)", type);
109 break;
110 case ASN_OBJECT_ID:
111 sprintf(buffer, "OBJECT IDENTIFIER (0x%x)", type);
112 break;
113 case ASN_NULL:
114 sprintf(buffer, "NULL (0x%x)", type);
115 break;
116 default:
117 sprintf(buffer, "UNKNOWN! (0x%x)", type);
118 break;
119 }
120
121 return buffer;
122 }
123
124
125 /********************************************************************/
126
error_status_string(int status)127 char *error_status_string(int status)
128 {
129 static char buffer[50];
130
131
132 switch(status)
133 {
134 case SNMP_ERR_NOERROR:
135 sprintf(buffer, "noError(%d)", status);
136 break;
137 case SNMP_ERR_TOOBIG:
138 sprintf(buffer, "tooBig(%d)", status);
139 break;
140 case SNMP_ERR_NOSUCHNAME:
141 sprintf(buffer, "noSuchName(%d)", status);
142 break;
143 case SNMP_ERR_BADVALUE:
144 sprintf(buffer, "badValue(%d)", status);
145 break;
146 case SNMP_ERR_READONLY:
147 sprintf(buffer, "readOnly(%d)", status);
148 break;
149 case SNMP_ERR_GENERR:
150 sprintf(buffer, "genErr(%d)", status);
151 break;
152 default:
153 sprintf(buffer, "UNKNOWN! (%d)", status);
154 break;
155 }
156
157 return buffer;
158 }
159
160
161 /********************************************************************/
162
generic_trap_string(int generic)163 char *generic_trap_string(int generic)
164 {
165 static char buffer[50];
166
167
168 switch(generic)
169 {
170 case SNMP_TRAP_COLDSTART:
171 sprintf(buffer, "coldStart(%d)", generic);
172 break;
173 case SNMP_TRAP_WARMSTART:
174 sprintf(buffer, "warmStart(%d)", generic);
175 break;
176 case SNMP_TRAP_LINKDOWN:
177 sprintf(buffer, "linkDown(%d)", generic);
178 break;
179 case SNMP_TRAP_LINKUP:
180 sprintf(buffer, "linkUp(%d)", generic);
181 break;
182 case SNMP_TRAP_AUTHFAIL:
183 sprintf(buffer, "authentificationFailure(%d)", generic);
184 break;
185 case SNMP_TRAP_EGPNEIGHBORLOSS:
186 sprintf(buffer, "egpNeighborLoss(%d)", generic);
187 break;
188 case SNMP_TRAP_ENTERPRISESPECIFIC:
189 sprintf(buffer, "enterpriseSpecific(%d)", generic);
190 break;
191 default:
192 sprintf(buffer, "UNKNOWN! (%d)", generic);
193 break;
194 }
195
196 return buffer;
197 }
198
199
200 /********************************************************************/
201
202 /* we should check if the buffer is not too small */
203
SSAOidString(Oid * oid)204 char *SSAOidString(Oid *oid)
205 {
206 static char buffer[1000];
207 int i;
208 int32_t len;
209
210
211 if(oid == NULL)
212 {
213 sprintf(buffer, "oid is NULL!");
214 return buffer;
215 }
216
217 sprintf(buffer, "");
218
219 if(oid->len == 0)
220 {
221 return buffer;
222 }
223
224 for(i = 0; i < oid->len - 1; i++) {
225 /* LINTED */
226 len = (int32_t)strlen(buffer);
227 sprintf(&(buffer[len]), "%lu.", oid->subids[i]);
228 }
229 /* LINTED */
230 len = (int32_t)strlen(buffer);
231 sprintf(&(buffer[len]), "%lu", oid->subids[oid->len - 1]);
232
233 return buffer;
234 }
235
236
237 /********************************************************************/
238
timeval_string(struct timeval * tv)239 char *timeval_string(struct timeval *tv)
240 {
241 static char buffer[50];
242
243
244 if(tv == NULL)
245 {
246 sprintf(buffer, "tv is NULL!");
247 return buffer;
248 }
249
250 sprintf(buffer, "%ld sec %ld usec", tv->tv_sec, tv->tv_usec);
251 return buffer;
252 }
253
254
255 /********************************************************************/
256
ip_address_string(IPAddress * ip_address)257 char *ip_address_string(IPAddress *ip_address)
258 {
259 static char buffer[50];
260 struct hostent *hp;
261
262
263 if(ip_address == NULL)
264 {
265 sprintf(buffer, "BUG: ip_address_string(): ip_address is NULL");
266 return buffer;
267 }
268
269 hp = gethostbyaddr((char *) &(ip_address->s_addr), 4, AF_INET);
270 if(hp)
271 {
272 sprintf(buffer, "%s", hp->h_name);
273 }
274 else
275 {
276 sprintf(buffer, "%s", inet_ntoa(*ip_address));
277 }
278
279 return buffer;
280 }
281
282
283 /********************************************************************/
284
address_string(Address * address)285 char *address_string(Address *address)
286 {
287 static char buffer[50];
288 struct hostent *hp;
289
290
291 if(address == NULL)
292 {
293 sprintf(buffer, "BUG: address_string(): address is NULL");
294 return buffer;
295 }
296
297 hp = gethostbyaddr((char *) &(address->sin_addr.s_addr), 4, AF_INET);
298 if(hp)
299 {
300 sprintf(buffer, "%s.%d", hp->h_name, address->sin_port);
301 }
302 else
303 {
304 sprintf(buffer, "%s.%d", inet_ntoa(address->sin_addr), address->sin_port);
305 }
306
307 return buffer;
308 }
309
310
311 /********************************************************************/
312
SSAStringCpy(String * string1,String * string2,char * error_label)313 int SSAStringCpy(String *string1, String *string2, char *error_label)
314 {
315 error_label[0] = '\0';
316
317 if(string1 == NULL)
318 {
319 sprintf(error_label, "BUG: SSAStringCpy(): string1 is NULL");
320 return -1;
321 }
322
323 if(string2 == NULL)
324 {
325 sprintf(error_label, "BUG: SSAStringCpy(): string2 is NULL");
326 return -1;
327 }
328
329 if(string1->chars)
330 {
331 sprintf(error_label, "BUG: SSAStringCpy(): string1->chars is not NULL");
332 return -1;
333 }
334
335 if(string1->len)
336 {
337 sprintf(error_label, "BUG: SSAStringCpy(): string1->len is not 0");
338 return -1;
339 }
340
341 if(string2->len == 0)
342 {
343 return 0;
344 }
345
346 string1->chars = (u_char *) malloc(string2->len);
347 if(string1->chars == NULL)
348 {
349 sprintf(error_label, ERR_MSG_ALLOC);
350 return -1;
351 }
352
353 memcpy(string1->chars, string2->chars, string2->len);
354 string1->len = string2->len;
355
356
357 return 0;
358 }
359
360
361 /********************************************************************/
362
SSAStringZero(String * string)363 void SSAStringZero(String *string)
364 {
365 if(string == NULL)
366 {
367 (void)fprintf(stderr, "BUG: SSAStringZero(): string is NULL");
368 return;
369 }
370
371 if(string->chars)
372 {
373 free(string->chars);
374 string->chars = NULL;
375 }
376 string->len = 0;
377
378
379 return;
380 }
381
382
383 /********************************************************************/
384
SSAStringInit(String * string,u_char * chars,int len,char * error_label)385 int SSAStringInit(String *string, u_char *chars, int len, char *error_label)
386 {
387 error_label[0] = '\0';
388
389 if(string == NULL)
390 {
391 sprintf(error_label, "BUG: SSAStringInit(): string is NULL");
392 return -1;
393 }
394
395 if(string->chars != NULL)
396 {
397 sprintf(error_label, "BUG: SSAStringInit(): string->chars is not NULL");
398 return -1;
399 }
400
401 if(string->len != 0)
402 {
403 sprintf(error_label, "BUG: SSAStringInit(): string->len is not 0");
404 return -1;
405 }
406
407 if(len != 0)
408 {
409 string->chars = (u_char *) malloc(len);
410 if(string->chars == NULL)
411 {
412 sprintf(error_label, ERR_MSG_ALLOC);
413 return -1;
414 }
415 memcpy(string->chars, chars, len);
416 string->len = len;
417 }
418
419
420 return 0;
421 }
422
423
424 /********************************************************************/
425
426 /*
427 * SSAOidCmp() returns:
428 *
429 * 0 if oid1 == oid2
430 * 1 if oid1 > oid2
431 * -1 if oid1 < oid2
432 */
433
SSAOidCmp(Oid * oid1,Oid * oid2)434 int SSAOidCmp(Oid *oid1, Oid *oid2)
435 {
436 int min;
437 int i;
438
439
440 if(oid1 == NULL)
441 {
442 (void)fprintf(stderr, "BUG: SSAOidCmp(): oid1 is NULL");
443 return -2;
444 }
445
446 if(oid2 == NULL)
447 {
448 (void)fprintf(stderr, "BUG: SSAOidCmp(): oid2 is NULL");
449 return -2;
450 }
451
452 min = MIN(oid1->len, oid2->len);
453
454 for(i = 0; i < min; i++)
455 {
456 if(oid1->subids[i] > oid2->subids[i])
457 {
458 return 1;
459 }
460
461 if(oid1->subids[i] < oid2->subids[i])
462 {
463 return -1;
464 }
465 }
466
467 if(oid1->len == oid2->len)
468 {
469 return 0;
470 }
471 else
472 if(oid1->len > oid2->len)
473 {
474 return 1;
475 }
476 else
477 {
478 return -1;
479 }
480 }
481
482
483 /********************************************************************/
484
SSAOidCpy(Oid * oid1,Oid * oid2,char * error_label)485 int SSAOidCpy(Oid *oid1, Oid *oid2, char *error_label)
486 {
487 error_label[0] = '\0';
488
489 if(oid1 == NULL) {
490 (void)sprintf(error_label, "BUG: SSAOidCpy(): oid1 is NULL");
491 return -1;
492 }
493
494 if(oid2 == NULL) {
495 (void)sprintf(error_label, "BUG: SSAOidCpy(): oid2 is NULL");
496 return -1;
497 }
498
499 if(oid2->len == 0) {
500 return 0;
501 }
502
503 if(oid1->subids) {
504 (void)sprintf(error_label, "BUG: SSAOidCpy(): oid1->subids is not NULL");
505 return -1;
506 }
507
508 if(oid1->len) {
509 (void)sprintf(error_label, "BUG: SSAOidCpy(): oid1->len is not 0");
510 return -1;
511 }
512
513
514 oid1->subids = (Subid *) malloc(oid2->len * (int32_t)sizeof(Subid));
515 if(oid1->subids == NULL) {
516 (void)sprintf(error_label, ERR_MSG_ALLOC);
517 return -1;
518 }
519
520 (void)memcpy(oid1->subids, oid2->subids, oid2->len * (int32_t)sizeof(Subid));
521 oid1->len = oid2->len;
522
523 return 0;
524 }
525
526
527 /********************************************************************/
528
SSAOidDup(Oid * oid,char * error_label)529 Oid *SSAOidDup(Oid *oid, char *error_label)
530 {
531 Oid *new = NULL;
532
533
534 error_label[0] = '\0';
535
536 if(oid == NULL)
537 {
538 sprintf(error_label, "BUG: SSAOidDup(): oid is NULL");
539 return NULL;
540 }
541
542 new = (Oid *) malloc(sizeof(Oid));
543 if(new == NULL)
544 {
545 sprintf(error_label, ERR_MSG_ALLOC);
546 return NULL;
547 }
548 memset(new, 0, sizeof(Oid));
549
550 if(SSAOidCpy(new, oid, error_label))
551 {
552 free(new);
553 return NULL;
554 }
555
556 return new;
557 }
558
559
560 /********************************************************************/
561
SSAOidNew()562 Oid *SSAOidNew()
563 {
564 Oid *oid = NULL;
565 oid = (Oid *) malloc(sizeof(Oid));
566 oid->subids = NULL;
567 oid->len = 0;
568 return (oid);
569 }
570
571 /********************************************************************/
572
SSAOidZero(Oid * oid)573 void SSAOidZero(Oid *oid)
574 {
575 if(oid == NULL)
576 {
577 (void)fprintf(stderr, "BUG: SSAOidZero(): oid is NULL");
578 return;
579 }
580
581 if(oid->subids)
582 {
583 free(oid->subids);
584 oid->subids = NULL;
585 }
586 oid->len = 0;
587 }
588
589
590 /********************************************************************/
591
SSAOidFree(Oid * oid)592 void SSAOidFree(Oid *oid)
593 {
594 if(oid == NULL) {
595 return;
596 }
597
598 SSAOidZero(oid);
599 free(oid);
600 }
601
602
603 /********************************************************************/
604
SSAOidInit(Oid * oid,Subid * subids,int len,char * error_label)605 int SSAOidInit(Oid *oid, Subid *subids, int len, char *error_label)
606 {
607 error_label[0] = '\0';
608
609 if(oid == NULL)
610 {
611 sprintf(error_label, "BUG: SSAOidInit(): oid is NULL");
612 return -1;
613 }
614
615 if(oid->subids != NULL)
616 {
617 sprintf(error_label, "BUG: SSAOidInit(): oid->subids is not NULL");
618 return -1;
619 }
620
621 if(oid->len != 0)
622 {
623 sprintf(error_label, "BUG: SSAOidInit(): oid->len is not 0");
624 return -1;
625 }
626
627 if(len != 0)
628 {
629 oid->subids = (Subid *) malloc(len * (int32_t)sizeof(Subid));
630 if(oid->subids == NULL)
631 {
632 sprintf(error_label, ERR_MSG_ALLOC);
633 return -1;
634 }
635 (void)memcpy(oid->subids, subids, len * (int32_t)sizeof(Subid));
636 oid->len = len;
637 }
638
639
640 return 0;
641 }
642
643
644 /********************************************************************/
645
get_my_ip_address(IPAddress * my_ip_address,char * error_label)646 int get_my_ip_address(IPAddress *my_ip_address, char *error_label)
647 {
648 struct utsname name;
649 struct hostent *hp;
650
651
652 error_label[0] = '\0';
653
654 if(uname(&name) == -1)
655 {
656 sprintf(error_label, ERR_MSG_UNAME,
657 errno_string());
658 return -1;
659 }
660
661 if((hp = gethostbyname(name.nodename)) == NULL)
662 {
663 sprintf(error_label, ERR_MSG_GETHOSTBYNAME,
664 name.nodename, h_errno_string());
665 return -1;
666 }
667
668 if(hp->h_length != 4)
669 {
670 sprintf(error_label, ERR_MSG_HOSTENT_BAD_IP_LENGTH,
671 hp->h_length);
672 return -1;
673 }
674
675 if(*hp->h_addr_list == NULL)
676 {
677 sprintf(error_label, ERR_MSG_HOSTENT_MISSING_IP_ADDRESS);
678 return -1;
679 }
680
681 memcpy(&my_ip_address->s_addr, *hp->h_addr_list, 4);
682
683
684 return 0;
685 }
686
687
688 /********************************************************************/
689
name_to_ip_address(char * name,IPAddress * ip_address,char * error_label)690 int name_to_ip_address(char *name, IPAddress *ip_address, char *error_label)
691 {
692 error_label[0] = '\0';
693
694
695 if(name == NULL)
696 {
697 sprintf(error_label, "BUG: name_to_ip_address(): name is NULL");
698 return -1;
699 }
700
701 if(ip_address == NULL)
702 {
703 sprintf(error_label, "BUG: name_to_ip_address(): ip_address is NULL");
704 return -1;
705 }
706
707 /* try to find the IP address from the name */
708 if(isdigit(name[0]))
709 {
710 if((int) (ip_address->s_addr = inet_addr(name)) == -1)
711 {
712 sprintf(error_label, ERR_MSG_BAD_IP_ADDRESS, name);
713 return -1;
714 }
715 }
716 else
717 {
718 struct hostent *hp;
719
720
721 hp = gethostbyname(name);
722 if(hp == NULL)
723 {
724 sprintf(error_label, ERR_MSG_BAD_HOSTNAME, name);
725 return -1;
726 }
727
728 if(hp->h_length != 4)
729 {
730 sprintf(error_label, ERR_MSG_HOSTENT_BAD_IP_LENGTH,
731 hp->h_length);
732 return -1;
733 }
734
735 if(*hp->h_addr_list == NULL)
736 {
737 sprintf(error_label, ERR_MSG_HOSTENT_MISSING_IP_ADDRESS);
738 return -1;
739 }
740
741 memcpy(&(ip_address->s_addr), *hp->h_addr_list, 4);
742 }
743
744
745 return 0;
746 }
747
SSAStringToChar(String str)748 char *SSAStringToChar(String str)
749 {
750 static char buffer[100];
751
752 buffer[0] = '\0';
753 memcpy(buffer,str.chars,str.len);
754 return buffer;
755 }
756
757 /* error return NULL, success return Oid ptr */
SSAOidStrToOid(char * name,char * error_label)758 Oid *SSAOidStrToOid (char *name, char *error_label)
759 {
760 Oid *name_oid;
761 Subid *subids;
762 int len = 0;
763 int i;
764 char *num_c;
765
766 for (i=0; name[i] != '\0'; i++) {
767 if (name[i] == '.')
768 len++;
769 else if (!isdigit(name[i])) {
770 (void)fprintf(stderr, "%s is not a valid oid name\n", name);
771 return(NULL);
772 }
773 }
774
775 if (!len ) {
776 (void)fprintf(stderr,"%s is not a valid oid name\n", name);
777 return (NULL); /* not a valid name */
778 }
779
780 len++;
781 subids = (Subid *) malloc(len * (int32_t)sizeof(Subid));
782 if (subids == NULL) {
783 (void)fprintf(stderr,"cannot malloc\n");
784 return (NULL) ;
785 }
786 if ((num_c = strtok(name, "."))== NULL) {
787 free(subids);
788 return (NULL);
789 }
790 i = 0;
791 /* LINTED */
792 subids[i] = (Subid) atol(num_c);
793 i++;
794 while (( num_c = strtok(NULL, ".")) != NULL ) {
795 /* LINTED */
796 subids[i] = (Subid) atol(num_c);
797 i++;
798 }
799
800 name_oid = SSAOidNew();
801 (void)SSAOidInit(name_oid, subids, len, error_label);
802 free(subids);
803 return(name_oid);
804 }
805
806