/************************************************************* /* /* Program dfcd /* /* Author: E. Pasqualucci /* /* It is an example of how to modify snmptrapd to /* receive and log snmp traps from kloe nodes. It works on /* the KLOE_SNMP_TRAP_PORT. /* Modified from the Carnegie Mellon University /* snmptrapd. /* /* Usage: /* /* dfcd [-P] [-d] /* /*************************************************************/ /* Standard include files */ #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <sys/time.h> #include <errno.h> #include <syslog.h> /* SNMP standard include files */ #include "snmp.h" #include "asn1.h" #include "snmp_impl.h" #include "snmp_api.h" #include "snmp_client.h" #include "party.h" #include "context.h" #include "view.h" #include "acl.h" /* Specific include files */ #include "dfcd_protos.h" #include "dfcd.h" #include "kloe_traps.h" /* Global variables */ extern int errno; int snmp_dump_packet = 0; int Print = 0; struct snmp_session *ss; char *dfcd_trap_description (int trap) { switch(trap){ case SNMP_TRAP_COLDSTART: return "Cold Start"; case SNMP_TRAP_WARMSTART: return "Warm Start"; case SNMP_TRAP_LINKDOWN: return "Link Down"; case SNMP_TRAP_LINKUP: return "Link Up"; case SNMP_TRAP_AUTHFAIL: return "Authentication Failure"; case SNMP_TRAP_EGPNEIGHBORLOSS: return "EGP Neighbor Loss"; case SNMP_TRAP_ENTERPRISESPECIFIC: return "Enterprise Specific"; case DFC_TRAP_KNODE_Q_AV: return "Kloe Node Queue Available"; case DFC_TRAP_KNODE_Q_UNAV: return "Kloe Node Queue Unanavailable"; default: return "Unknown Type"; } } char *uptime_string(register u_int timeticks, char *buf) { int seconds, minutes, hours, days; timeticks /= 100; days = timeticks / (60 * 60 * 24); timeticks %= (60 * 60 * 24); hours = timeticks / (60 * 60); timeticks %= (60 * 60); minutes = timeticks / 60; seconds = timeticks % 60; if (days == 0){ sprintf(buf, "%d:%02d:%02d", hours, minutes, seconds); } else if (days == 1) { sprintf(buf, "%d day, %d:%02d:%02d", days, hours, minutes, seconds); } else { sprintf(buf, "%d days, %d:%02d:%02d", days, hours, minutes, seconds); } return buf; } int dfcd_input (int op, struct snmp_session *session, int reqid, struct snmp_pdu *pdu, void *magic) { struct variable_list *vars; char buf[DFCD_MAXBUFLEN]; if (op == RECEIVED_MESSAGE && pdu->command == TRP_REQ_MSG) { if (Print) { printf("%s: %s Trap (%d) Uptime: %s\n", inet_ntoa(pdu->agent_addr.sin_addr), dfcd_trap_description(pdu->trap_type), pdu->specific_type, uptime_string(pdu->time, buf)); for(vars = pdu->variables; vars; vars = vars->next_variable) print_variable(vars->name, vars->name_length, vars); } #ifndef __Lynx__ else { syslog(LOG_WARNING, "%s: %s Trap (%d) Uptime: %s\n", inet_ntoa(pdu->agent_addr.sin_addr), dfcd_trap_description(pdu->trap_type), pdu->specific_type, uptime_string(pdu->time, buf)); } #endif } else if (op == TIMED_OUT) { printf("Timeout: This shouldn't happen!\n"); } } void init_syslog (void) { #ifndef __Lynx__ /* * These definitions handle 4.2 systems without additional syslog facilities. */ #ifndef LOG_CONS #define LOG_CONS 0 /* Don't bother if not defined... */ #endif #ifndef LOG_LOCAL0 #define LOG_LOCAL0 0 #endif /* * All messages will be logged to the local0 facility and will be sent to * the console if syslog doesn't work. */ openlog("snmptrapd", LOG_CONS, LOG_LOCAL0); syslog(LOG_INFO, "Starting snmptrapd"); #endif } void init_options (int argc, char **argv) { int arg; for(arg = 1; arg < argc; arg++) if (argv[arg][0] == '-') { switch(argv[arg][1]) { case 'd': snmp_dump_packet++; break; case 'p': Print++; break; default: printf("invalid option: -%c\n", argv[arg][1]); printf("Usage: dfcd [-p] [-d]\n"); break; } } } struct snmp_session *dfcd_init_snmp_trap_session (void) { struct snmp_session session, *dfcd_ss; bzero((char *)&session, sizeof(struct snmp_session)); session.peername = NULL; session.community = NULL; session.community_len = 0; session.retries = SNMP_DEFAULT_RETRIES; session.timeout = SNMP_DEFAULT_TIMEOUT; session.authenticator = NULL; session.callback = dfcd_input; session.callback_magic = NULL; session.local_port = SNMP_KLOE_TRAP_PORT; dfcd_ss = snmp_open(&session); return dfcd_ss; } void dfcd_init (int argc, char **argv) { init_syslog(); init_mib(); init_options (argc, argv); if ((ss = dfcd_init_snmp_trap_session()) == NULL) { printf("Couldn't open snmp\n"); exit(-1); } } int dfcd_main_loop (void) { int count, numfds, block; fd_set fdset; struct timeval timeout, *tvp; while (1) { numfds = 0; FD_ZERO(&fdset); block = 1; tvp = &timeout; timerclear(tvp); snmp_select_info(&numfds, &fdset, tvp, &block); if (block == 1) tvp = NULL; /* block without timeout */ #if defined (_HPUX_SOURCE) && defined (V9) count = select (numfds, (int *) &fdset, 0, 0, tvp); #else count = select (numfds, &fdset, 0, 0, tvp); #endif if (count > 0) snmp_read(&fdset); else switch(count) { case 0: snmp_timeout(); break; case -1: if (errno != EINTR) perror("select"); return -1; default: printf("select returned %d\n", count); return -1; } } } main (int argc, char **argv) { dfcd_init (argc, argv); return dfcd_main_loop(); }