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);