xref: /onnv-gate/usr/src/cmd/agents/snmp/snmplib/trap.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 2005 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 <unistd.h>
31 #include <sys/types.h>
32 #include <netinet/in.h>
33 #include <stdio.h>
34 #include <sys/socket.h>
35 #include <errno.h>
36 #include <syslog.h>
37 #include <string.h>
38 #include <arpa/inet.h>
39 #include <netdb.h>
40 #include <nlist.h>
41 #include "snmp_msg.h"
42 #include "impl.h"
43 #include "trace.h"
44 #include "snmp.h"
45 #include "pdu.h"
46 #include "request.h"
47 #include "trap.h"
48 #include "error.h"
49 
50 
51 /***** GLOBAL VARIABLES *****/
52 
53 char *trap_community = NULL;
54 
55 Subid sun_subids[] = { 1, 3, 6, 1, 4, 1, 42, 2, 1, 1 };
56 Oid sun_oid = { sun_subids, 10 };
57 
58 
59 /***** LOCAL TYPES *****/
60 
61 typedef struct _Trap_Destinator {
62 	struct _Trap_Destinator	*next_trap_destinator;
63 	char			*name;
64 	IPAddress		ip_address;
65 } Trap_Destinator;
66 
67 
68 /***** LOCAL VARIABLES *****/
69 
70 static Oid *default_enterprise = NULL;
71 
72 static Trap_Destinator *first_trap_destinator = NULL;
73 
74 
75 /********************************************************************/
76 
trap_init(Oid * enterprise,char * error_label)77 int trap_init(Oid *enterprise, char *error_label)
78 {
79 	error_label[0] = '\0';
80 
81 	if(enterprise == NULL)
82 	{
83 		sprintf(error_label, "BUG: trap_init(): enterprise is NULL");
84 		return -1;
85 	}
86 
87 	SSAOidFree(default_enterprise);
88 	default_enterprise = NULL;
89 
90 	default_enterprise = SSAOidDup(enterprise, error_label);
91 	if(default_enterprise == NULL)
92 	{
93 		return -1;
94 	}
95 
96 	return 0;
97 }
98 
99 
100 /********************************************************************/
101 
trap_send(IPAddress * ip_address,Oid * enterprise,int generic,int specific,SNMP_variable * variables,char * error_label)102 int trap_send(IPAddress *ip_address, Oid *enterprise, int generic, int specific, SNMP_variable *variables, char *error_label)
103 {
104 	static int my_ip_address_initialized = False;
105 	static IPAddress my_ip_address;
106 	struct sockaddr_in me;
107 	int sd;
108 	Address address;
109 	SNMP_pdu *pdu;
110 	SNMP_variable *last_variable = NULL;
111 	SNMP_variable *new_variable;
112 
113 
114 	error_label[0] = '\0';
115 
116 	if(my_ip_address_initialized == False)
117 	{
118 		if(get_my_ip_address(&my_ip_address, error_label))
119 		{
120 			return -1;
121 		}
122 
123 		my_ip_address_initialized = True;
124 	}
125 
126 	pdu = snmp_pdu_new(error_label);
127 	if(pdu == NULL)
128 	{
129 		return -1;
130 	}
131 
132 	/* version, community */
133 	pdu->version = SNMP_VERSION_1;
134 	if(trap_community == NULL)
135 	{
136 		pdu->community = strdup("public");
137 	}
138 	else
139 	{
140 		pdu->community = strdup(trap_community);
141 	}
142 	if(pdu->community == NULL)
143 	{
144 		sprintf(error_label, ERR_MSG_ALLOC);
145 		snmp_pdu_free(pdu);
146 		return -1;
147 	}
148 
149 	/* type */
150 	pdu->type = TRP_REQ_MSG;
151 
152 	/* enterprise */
153 	if(enterprise == NULL)
154 	{
155 		if(default_enterprise)
156 		{
157 			enterprise = default_enterprise;
158 		}
159 		else
160 		{
161 			enterprise = &sun_oid;
162 		}
163 	}
164 	if(SSAOidCpy(&(pdu->enterprise), enterprise, error_label))
165 	{
166 		snmp_pdu_free(pdu);
167 		return -1;
168 	}
169 
170 	/* agent_addr */
171 	pdu->ip_agent_addr.s_addr = my_ip_address.s_addr;
172 
173 	/* generic, specific */
174 	pdu->generic = generic;
175 	pdu->specific = specific;
176 
177 	/* time_stamp */
178 	pdu->time_stamp = request_sysUpTime(error_label, NULL);
179 
180 	/* first_variable */
181 	while(variables)
182 	{
183 		new_variable = snmp_variable_dup(variables, error_label);
184 		if(new_variable == NULL)
185 		{
186 			snmp_pdu_free(pdu);
187 			return -1;
188 		}
189 
190 		if(last_variable)
191 		{
192 			last_variable->next_variable = new_variable;
193 		}
194 		else
195 		{
196 			pdu->first_variable = new_variable;
197 		}
198 		last_variable = new_variable;
199 
200 		variables = variables->next_variable;
201 	}
202 
203 
204 	/* sd */
205 	sd = socket(AF_INET, SOCK_DGRAM, 0);
206 	if(sd < 0)
207 	{
208 		sprintf(error_label, ERR_MSG_SOCKET, errno_string());
209 		snmp_pdu_free(pdu);
210 		return -1;
211 	}
212 	me.sin_family = AF_INET;
213 	me.sin_addr.s_addr = INADDR_ANY;
214 	me.sin_port = htons(0);
215 	if(bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0)
216 	{
217 		sprintf(error_label, ERR_MSG_BIND, errno_string());
218 		snmp_pdu_free(pdu);
219 		(void)close(sd);
220 		return -1;
221 	}
222 
223 
224 	/* address */
225 	address.sin_family = AF_INET;
226 	address.sin_addr.s_addr = ip_address->s_addr;
227 	address.sin_port = SNMP_TRAP_PORT;
228 
229 	if(snmp_pdu_send(sd, &address, pdu, error_label))
230 	{
231 		snmp_pdu_free(pdu);
232 		(void)close(sd);
233 		return -1;
234 	}
235 	snmp_pdu_free(pdu);
236 	(void)close(sd);
237 
238 
239 	return 0;
240 }
241 /**********************************************************************/
242 
trap_send_raw(IPAddress * ip_address,IPAddress my_ip_addr,char * community,int i_flag,Oid * enterprise,int generic,int specific,int trap_port,uint32_t time_stamp,SNMP_variable * variables,char * error_label)243 int trap_send_raw(IPAddress *ip_address, IPAddress my_ip_addr,
244 	char* community,int i_flag,Oid *enterprise,int generic,
245 	int specific,int trap_port,uint32_t time_stamp,
246 	SNMP_variable *variables,char *error_label)
247 {
248 	static int my_ip_address_initialized = False;
249 	static IPAddress my_ip_address;
250 	struct sockaddr_in me;
251 	int sd;
252 	Address address;
253 	SNMP_pdu *pdu;
254 	SNMP_variable *last_variable = NULL;
255 	SNMP_variable *new_variable;
256 
257 
258 	error_label[0] = '\0';
259 
260 	if (!i_flag) {
261 		if(my_ip_address_initialized == False)
262 		{
263 			if(get_my_ip_address(&my_ip_address, error_label))
264 			{
265 				return -1;
266 			}
267 
268 			my_ip_address_initialized = True;
269 		}
270 	}
271 
272 	pdu = snmp_pdu_new(error_label);
273 	if(pdu == NULL)
274 	{
275 		return -1;
276 	}
277 
278 	/* version, community */
279 	pdu->version = SNMP_VERSION_1;
280 
281 	if(community == NULL)
282 	{
283 		pdu->community = strdup("public");
284 	}
285 	else
286 	{
287 		pdu->community = strdup(community);
288 	}
289 	if(pdu->community == NULL)
290 	{
291 		sprintf(error_label, ERR_MSG_ALLOC);
292 		snmp_pdu_free(pdu);
293 		return -1;
294 	}
295 
296 	/* type */
297 	pdu->type = TRP_REQ_MSG;
298 
299 	/* enterprise */
300 	if(enterprise == NULL)
301 	{
302 		if(default_enterprise)
303 		{
304 			enterprise = default_enterprise;
305 		}
306 		else
307 		{
308 			enterprise = &sun_oid;
309 		}
310 	}
311 	if(SSAOidCpy(&(pdu->enterprise), enterprise, error_label))
312 	{
313 		snmp_pdu_free(pdu);
314 		return -1;
315 	}
316 
317  	/* agent_addr */
318 	if (!i_flag) {
319 		pdu->ip_agent_addr.s_addr = my_ip_address.s_addr;
320 	}
321 	else {
322 		pdu->ip_agent_addr.s_addr = my_ip_addr.s_addr;
323 	}
324 
325 	/* generic, specific */
326 
327 	pdu->generic = generic;
328 	pdu->specific = specific;
329 
330 	/* time_stamp */
331 	if (time_stamp == -1U)
332 		pdu->time_stamp = request_sysUpTime(error_label, community); /* default */
333 	else
334 		pdu->time_stamp = time_stamp;
335 
336 	/* first_variable */
337 	while(variables)
338 	{
339 		new_variable = snmp_variable_dup(variables, error_label);
340 		if(new_variable == NULL)
341 		{
342 			snmp_pdu_free(pdu);
343 			return -1;
344 		}
345 
346 		if(last_variable)
347 		{
348 			last_variable->next_variable = new_variable;
349 		}
350 		else
351 		{
352 			pdu->first_variable = new_variable;
353 		}
354 		last_variable = new_variable;
355 
356 		variables = variables->next_variable;
357 	}
358 
359 
360 	/* sd */
361 	sd = socket(AF_INET, SOCK_DGRAM, 0);
362 	if(sd < 0)
363 	{
364 		sprintf(error_label, ERR_MSG_SOCKET, errno_string());
365 		snmp_pdu_free(pdu);
366 		return -1;
367 	}
368 	me.sin_family = AF_INET;
369 	me.sin_addr.s_addr = INADDR_ANY;
370 	me.sin_port = htons(0);
371 	if(bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0)
372 	{
373 		sprintf(error_label, ERR_MSG_BIND, errno_string());
374 		snmp_pdu_free(pdu);
375 		(void)close(sd);
376 		return -1;
377 	}
378 
379 
380 	/* address */
381 	address.sin_family = AF_INET;
382 	address.sin_addr.s_addr = ip_address->s_addr;
383 	if (trap_port == -1)
384 		address.sin_port = SNMP_TRAP_PORT; /* default */
385 	else
386 		/* LINTED */
387 		address.sin_port = (short)trap_port;
388 
389 	if(snmp_pdu_send(sd, &address, pdu, error_label))
390 	{
391 		snmp_pdu_free(pdu);
392 		(void)close(sd);
393 		return -1;
394 	}
395 	snmp_pdu_free(pdu);
396 	(void)close(sd);
397 
398 
399 	return 0;
400 }
401 
402 /**********************************************************************/
trap_send_with_more_para(IPAddress * ip_address,IPAddress my_ip_addr,char * community,int i_flag,Oid * enterprise,int generic,int specific,int trap_port,uint32_t time_stamp,SNMP_variable * variables,char * error_label)403 int trap_send_with_more_para(IPAddress *ip_address,
404 							 IPAddress my_ip_addr,
405 							 char *community,
406 							 int i_flag,
407 							 Oid *enterprise,
408 							 int generic,
409 							 int specific,
410 							 int trap_port,
411 							 uint32_t time_stamp,
412 							 SNMP_variable *variables,
413 							 char *error_label)
414 {
415  return(trap_send_raw(ip_address,my_ip_addr,community,i_flag,enterprise,generic,
416 	specific,trap_port,time_stamp, variables,error_label));
417 }
418 
419 
420 
421 /********************************************************************/
422 
423 /*
424  *	returns 0 if OK
425  *		1 if error
426  *		-1 if fatal error
427  */
428 
trap_destinator_add(char * name,char * error_label)429 int trap_destinator_add(char *name, char *error_label)
430 {
431 	IPAddress ip_address;
432 	Trap_Destinator *new;
433 	Trap_Destinator *d;
434 
435 
436 	error_label[0] = '\0';
437 
438 	if(name == NULL)
439 	{
440 		sprintf(error_label, "BUG: trap_destinator_add(): name is NULL");
441 		return -1;
442 	}
443 
444 	if(name_to_ip_address(name, &ip_address, error_label))
445 	{
446 		return 1;
447 	}
448 
449 	/* check if this trap destinator does not already exist */
450 	for(d = first_trap_destinator; d; d = d->next_trap_destinator)
451 	{
452 		if(ip_address.s_addr == d->ip_address.s_addr)
453 		{
454 			sprintf(error_label, ERR_MSG_TRAP_DEST_DUP,
455 				name);
456 			return 1;
457 		}
458 	}
459 
460 
461 	/* allocate, initialize and link the new trap destinator */
462 	new = (Trap_Destinator *) malloc(sizeof(Trap_Destinator));
463 	if(new == NULL)
464 	{
465 		sprintf(error_label, ERR_MSG_ALLOC);
466 		return -1;
467 	}
468 	new->next_trap_destinator = NULL;
469 	new->name = NULL;
470 
471 	new->name = strdup(name);
472 	if(new->name == NULL)
473 	{
474 		sprintf(error_label, ERR_MSG_ALLOC);
475 		free(new);
476 		return -1;
477 	}
478 
479 	new->ip_address.s_addr = ip_address.s_addr;
480 
481 	new->next_trap_destinator = first_trap_destinator;
482 	first_trap_destinator = new;
483 
484 
485 	return 0;
486 }
487 
488 
489 /********************************************************************/
490 
delete_trap_destinator_list()491 void delete_trap_destinator_list()
492 {
493 	Trap_Destinator *next;
494 
495 
496 	while(first_trap_destinator)
497 	{
498 		next = first_trap_destinator->next_trap_destinator;
499 
500 		if(first_trap_destinator->name)
501 		{
502 			free(first_trap_destinator->name);
503 		}
504 
505 		free(first_trap_destinator);
506 
507 		first_trap_destinator = next;
508 	}
509 
510 	first_trap_destinator = NULL;
511 }
512 
513 
514 /********************************************************************/
515 
trace_trap_destinators()516 void trace_trap_destinators()
517 {
518 	Trap_Destinator *d;
519 
520 
521 	trace("TRAP RECIPIENTS:\n");
522 	trace("-----------------\n");
523 	for(d = first_trap_destinator; d; d = d->next_trap_destinator)
524 	{
525 		trace("%-30s %-20s\n",
526 			d->name,
527 			inet_ntoa(d->ip_address));
528 	}
529 	trace("\n");
530 }
531 
532 
533 /********************************************************************/
534 /* ARGSUSED */
trap_send_to_all_destinators7(int i_flag,Oid * enterprise,int generic,int specific,uint32_t time_stamp,SNMP_variable * variables,char * error_label)535 int trap_send_to_all_destinators7( int i_flag, Oid *enterprise, int generic,
536                                    int specific, uint32_t time_stamp,
537                                    SNMP_variable *variables, char *error_label)
538 {
539         Trap_Destinator *d;
540         IPAddress my_ip_addr;
541 
542 	(void)memset(&my_ip_addr, 0, sizeof(IPAddress));
543 
544         error_label[0] = '\0';
545 
546         for(d = first_trap_destinator; d; d = d->next_trap_destinator)
547         {
548                 if(trap_send_with_more_para(&(d->ip_address), my_ip_addr, NULL, 0,enterprise, generic, specific, SNMP_TRAP_PORT,time_stamp,variables, error_label))
549                 {
550                         return -1;
551                 }
552         }
553 
554         return 0;
555 }
556 
557 
558 
trap_send_to_all_destinators(Oid * enterprise,int generic,int specific,SNMP_variable * variables,char * error_label)559 int trap_send_to_all_destinators(Oid *enterprise, int generic, int specific, SNMP_variable *variables, char *error_label)
560 {
561 	Trap_Destinator *d;
562 
563 
564 	error_label[0] = '\0';
565 
566 	for(d = first_trap_destinator; d; d = d->next_trap_destinator)
567 	{
568 		if(trap_send(&(d->ip_address), enterprise, generic, specific, variables, error_label))
569 		{
570 			return -1;
571 		}
572 	}
573 
574 	return 0;
575 }
576 
577