/* * Copyright (c) 1996, 1997, 1999, 2004 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char copyright[] = "Copyright (c) 1996, 1997, 1999, 2004\n\ The Regents of the University of California. All rights reserved.\n"; static const char rcsid[] = "@(#) $Header: /usr/src/local/sbin/arpwatch/RCS/arpsnmp.c,v 1.9 2004/01/22 22:25:11 leres Exp $ (LBL)"; #endif /* * arpsnmp - keep track of ethernet/ip address pairings, report changes */ #include #include /* concession to AIX */ #include #include #ifdef HAVE_MEMORY_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #include #include #include #include #include #include #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #include "arpwatch.h" #include "db.h" #include "ec.h" #include "file.h" #include "machdep.h" #include "util.h" #include "addresses.h" /* Forwards */ int main(int, char **); int readsnmp(char *); int snmp_add(u_int32_t, u_char *, time_t, char *); __dead void usage(void) __attribute__((volatile)); char *prog; extern int optind; extern int opterr; extern char *optarg; int main(int argc, char **argv) { register char *cp; register int op, i; char errbuf[256]; if ((cp = strrchr(argv[0], '/')) != NULL) prog = cp + 1; else prog = argv[0]; if (abort_on_misalignment(errbuf) < 0) { (void)fprintf(stderr, "%s: %s\n", prog, errbuf); exit(1); } opterr = 0; while ((op = getopt(argc, argv, "df:e:s:")) != EOF) switch (op) { case 'd': ++debug; #ifndef DEBUG (void)fprintf(stderr, "%s: Warning: Not compiled with -DDEBUG\n", prog); #endif break; case 'f': arpfile = optarg; break; case 'e': if ( optarg ) { watcher = strdup(optarg); } else { (void)fprintf(stderr, "%s: Need recipient username/e-mail address after -e\n", prog); usage(); } break; case 's': if ( optarg ) { watchee = strdup(optarg); } else { (void)fprintf(stderr, "%s: Need sender username/e-mail address after -s\n", prog); usage(); } break; default: usage(); } if (optind == argc) usage(); openlog(prog, 0, LOG_DAEMON); /* Read in database */ initializing = 1; /* XXX todo: file locking */ if (!readdata()) exit(1); sorteinfo(); #ifdef DEBUG if (debug > 2) { debugdump(); exit(0); } #endif initializing = 0; /* Suck files in then exit */ for (i = optind; i < argc; ++i) (void)readsnmp(argv[i]); if (!dump()) exit(1); exit(0); } static time_t now; int snmp_add(register u_int32_t a, register u_char *e, time_t t, register char *h) { /* Watch for ethernet broadcast */ if (MEMCMP(e, zero, 6) == 0 || MEMCMP(e, allones, 6) == 0) { dosyslog(LOG_INFO, "ethernet broadcast", a, e, NULL); return (1); } /* Watch for some ip broadcast addresses */ if (a == 0 || a == 1) { dosyslog(LOG_INFO, "ip broadcast", a, e, NULL); return (1); } /* Use current time (although it would be nice to subtract idle time) */ return (ent_add(a, e, now, h)); } /* Process an snmp file */ int readsnmp(register char *file) { register FILE *f; if (debug > 2) (void)fprintf(stderr, "%s: reading %s\n", prog, file); if ((f = fopen(file, "r")) == NULL) { syslog(LOG_ERR, "fopen(%s): %m", file); return(0); } now = time(NULL); if (!file_loop(f, snmp_add, file)) { (void)fclose(f); return(0); } (void)fclose(f); return(1); } __dead void usage(void) { extern char version[]; (void)fprintf(stderr, "Version %s\n", version); (void)fprintf(stderr, "usage: %s [-d] [-f datafile] [-e username] [-s username] file [...]\n", prog); exit(1); }