xref: /onnv-gate/usr/src/cmd/agents/snmp/snmplib/impl.c (revision 0:68f95e015346)
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