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