2
* snmptrap.c - send snmp traps to a network entity.
5
/******************************************************************
6
Copyright 1989, 1991, 1992 by Carnegie Mellon University
10
Permission to use, copy, modify, and distribute this software and its
11
documentation for any purpose and without fee is hereby granted,
12
provided that the above copyright notice appear in all copies and that
13
both that copyright notice and this permission notice appear in
14
supporting documentation, and that the name of CMU not be
15
used in advertising or publicity pertaining to distribution of the
16
software without specific, written prior permission.
18
CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20
CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25
******************************************************************/
26
#include <net-snmp/net-snmp-config.h>
39
#include <sys/types.h>
41
# include <netinet/in.h>
43
#if TIME_WITH_SYS_TIME
45
# include <sys/timeb.h>
47
# include <sys/time.h>
52
# include <sys/time.h>
58
#include <sys/select.h>
65
#include <sys/socket.h>
71
#include <arpa/inet.h>
74
#include <net-snmp/net-snmp-includes.h>
76
oid objid_enterprise[] = { 1, 3, 6, 1, 4, 1, 3, 1, 1 };
77
oid objid_sysdescr[] = { 1, 3, 6, 1, 2, 1, 1, 1, 0 };
78
oid objid_sysuptime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
79
oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
85
fprintf(stderr, "USAGE: %s ", inform ? "snmpinform" : "snmptrap");
86
snmp_parse_args_usage(stderr);
87
fprintf(stderr, " TRAP-PARAMETERS\n\n");
88
snmp_parse_args_descriptions(stderr);
90
" -C APPOPTS\t\tSet various application specific behaviour:\n");
91
fprintf(stderr, "\t\t\t i: send an INFORM instead of a TRAP\n");
93
"\n -v 1 TRAP-PARAMETERS:\n\t enterprise-oid agent trap-type specific-type uptime [OID TYPE VALUE]...\n");
94
fprintf(stderr, " or\n");
96
" -v 2 TRAP-PARAMETERS:\n\t uptime trapoid [OID TYPE VALUE] ...\n");
100
snmp_input(int operation,
101
netsnmp_session * session,
102
int reqid, netsnmp_pdu *pdu, void *magic)
108
parse_address(char *address)
111
struct sockaddr_in saddr;
114
if ((addr = inet_addr(address)) != -1)
116
hp = gethostbyname(address);
118
fprintf(stderr, "unknown host: %s\n", address);
121
memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
122
return saddr.sin_addr.s_addr;
128
optProc(int argc, char *const *argv, int opt)
139
"Unknown flag passed to -C: %c\n", optarg[-1]);
148
main(int argc, char *argv[])
150
netsnmp_session session, *ss;
151
netsnmp_pdu *pdu, *response;
152
in_addr_t *pdu_in_addr_t;
153
oid name[MAX_OID_LEN];
157
char *trap = NULL, *specific = NULL, *description =
162
prognam = strrchr(argv[0], '/');
168
putenv(strdup("POSIXLY_CORRECT=1"));
170
if (strcmp(prognam, "snmpinform") == 0)
172
switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
184
session.callback = snmp_input;
185
session.callback_magic = NULL;
186
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DEFAULT_PORT,
189
if (session.version == SNMP_VERSION_3 && !inform) {
191
* for traps, we use ourselves as the authoritative engine
192
* which is really stupid since command line apps don't have a
193
* notion of a persistent engine. Hence, our boots and time
194
* values are probably always really wacked with respect to what
195
* a manager would like to see.
197
* The following should be enough to:
199
* 1) prevent the library from doing discovery for engineid & time.
200
* 2) use our engineid instead of the remote engineid for
201
* authoritative & privacy related operations.
202
* 3) The remote engine must be configured with users for our engineID.
208
* setup the engineID based on IP addr. Need a different
209
* algorthim here. This will cause problems with agents on the
210
* same machine sending traps.
212
setup_engineID(NULL, NULL);
215
* pick our own engineID
217
if (session.securityEngineIDLen == 0 ||
218
session.securityEngineID == NULL) {
219
session.securityEngineID =
220
snmpv3_generate_engineID(&session.securityEngineIDLen);
222
if (session.contextEngineIDLen == 0 ||
223
session.contextEngineID == NULL) {
224
session.contextEngineID =
225
snmpv3_generate_engineID(&session.contextEngineIDLen);
229
* set boots and time, which will cause problems if this
230
* machine ever reboots and a remote trap receiver has cached our
231
* boots and time... I'll cause a not-in-time-window report to
232
* be sent back to this machine.
234
if (session.engineBoots == 0)
235
session.engineBoots = 1;
236
if (session.engineTime == 0) /* not really correct, */
237
session.engineTime = get_uptime(); /* but it'll work. Sort of. */
240
ss = snmp_open(&session);
243
* diagnose snmp_open errors with the input netsnmp_session pointer
245
snmp_sess_perror("snmptrap", &session);
250
if (session.version == SNMP_VERSION_1) {
252
fprintf(stderr, "Cannot send INFORM as SNMPv1 PDU\n");
255
pdu = snmp_pdu_create(SNMP_MSG_TRAP);
256
pdu_in_addr_t = (in_addr_t *) pdu->agent_addr;
258
fprintf(stderr, "No enterprise oid\n");
263
if (argv[arg][0] == 0) {
264
pdu->enterprise = (oid *) malloc(sizeof(objid_enterprise));
265
memcpy(pdu->enterprise, objid_enterprise,
266
sizeof(objid_enterprise));
267
pdu->enterprise_length =
268
sizeof(objid_enterprise) / sizeof(oid);
270
name_length = MAX_OID_LEN;
271
if (!snmp_parse_oid(argv[arg], name, &name_length)) {
272
snmp_perror(argv[arg]);
277
pdu->enterprise = (oid *) malloc(name_length * sizeof(oid));
278
memcpy(pdu->enterprise, name, name_length * sizeof(oid));
279
pdu->enterprise_length = name_length;
282
fprintf(stderr, "Missing agent parameter\n");
288
if (agent != NULL && strlen(agent) != 0) {
289
*pdu_in_addr_t = parse_address(agent);
291
*pdu_in_addr_t = get_myaddr();
294
fprintf(stderr, "Missing generic-trap parameter\n");
300
pdu->trap_type = atoi(trap);
302
fprintf(stderr, "Missing specific-trap parameter\n");
307
specific = argv[arg];
308
pdu->specific_type = atoi(specific);
310
fprintf(stderr, "Missing uptime parameter\n");
315
description = argv[arg];
316
if (description == NULL || *description == 0)
317
pdu->time = get_uptime();
319
pdu->time = atol(description);
324
pdu = snmp_pdu_create(inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2);
326
fprintf(stderr, "Missing up-time parameter\n");
333
sysuptime = get_uptime();
334
sprintf(csysuptime, "%ld", sysuptime);
337
snmp_add_var(pdu, objid_sysuptime,
338
sizeof(objid_sysuptime) / sizeof(oid), 't', trap);
340
fprintf(stderr, "Missing trap-oid parameter\n");
346
(pdu, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid),
347
'o', argv[arg]) != 0) {
348
snmp_perror(argv[arg]);
358
fprintf(stderr, "%s: Missing type/value for variable\n",
363
name_length = MAX_OID_LEN;
364
if (!snmp_parse_oid(argv[arg - 3], name, &name_length)) {
365
snmp_perror(argv[arg - 3]);
370
(pdu, name, name_length, argv[arg - 2][0],
371
argv[arg - 1]) != 0) {
372
snmp_perror(argv[arg - 3]);
379
status = snmp_synch_response(ss, pdu, &response);
381
status = snmp_send(ss, pdu) == 0;
383
snmp_sess_perror(inform ? "snmpinform" : "snmptrap", ss);
388
snmp_free_pdu(response);