diff -Naru arpwatch-2.1a15.orig/arpwatch.c arpwatch-2.1a15/arpwatch.c --- arpwatch-2.1a15.orig/arpwatch.c 2006-09-23 22:20:51.000000000 +0400 +++ arpwatch-2.1a15/arpwatch.c 2006-09-23 22:24:49.000000000 +0400 @@ -179,6 +179,8 @@ struct bpf_program code; char errbuf[PCAP_ERRBUF_SIZE]; char* username = NULL; + int restart = 0; + int restarting_loop = 0; char options[] = "d" "f:" @@ -191,6 +193,7 @@ "p" "a" "u:" + "R:" "Q" "z:" ; @@ -267,6 +270,10 @@ username = optarg; break; + case 'R': + restart = atoi(optarg); + break; + case 'Q': ++quiet; break; @@ -285,6 +292,12 @@ if (optind != argc) usage(); + if ( username && restart ) { + syslog(LOG_ERR, "Please, specify either -u or -R"); + (void)fprintf(stderr,"Please, specify either -u or -R. See arpwatch.8\n"); + exit(1); + } + if (rfilename != NULL) { net = 0; netmask = 0; @@ -334,6 +347,7 @@ syslog(LOG_ERR, "(using current working directory)"); } +label_restart: if (rfilename != NULL) { pd = pcap_open_offline(rfilename, errbuf); if (pd == NULL) { @@ -348,22 +362,30 @@ pd = pcap_open_live(interface, snaplen, !nopromisc, timeout, errbuf); if (pd == NULL) { syslog(LOG_ERR, "pcap open %s: %s", interface, errbuf); - exit(1); + if (restart) { + syslog(LOG_ERR, "restart in %d secs", restart); + } else { + exit(1); + } + sleep(restart); + goto label_restart; } #ifdef WORDS_BIGENDIAN swapped = 1; #endif } - if ( username ) { - dropprivileges( username ); - } else { - /* - * Revert to non-privileged user after opening sockets - * (not needed on most systems). - */ - setgid(getgid()); - setuid(getuid()); + if (!restarting_loop) { + if ( username && !restart ) { + dropprivileges( username ); + } else { + /* + * Revert to non-privileged user after opening sockets + * (not needed on most systems). + */ + setgid(getgid()); + setuid(getuid()); + } } /* Must be ethernet or fddi */ @@ -386,26 +408,30 @@ if (rfilename == NULL) syslog(LOG_INFO, "listening on %s", interface); - /* Read in database */ - initializing = 1; - if (!readdata()) - exit(1); - sorteinfo(); + if (!restarting_loop) { + /* Read in database */ + initializing = 1; + if (!readdata()) + exit(1); + sorteinfo(); + } #ifdef DEBUG if (debug > 2) { debugdump(); exit(0); } #endif - initializing = 0; + if (!restarting_loop) { + initializing = 0; - (void)setsignal(SIGINT, die); - (void)setsignal(SIGTERM, die); - (void)setsignal(SIGHUP, die); - if (rfilename == NULL) { - (void)setsignal(SIGQUIT, checkpoint); - (void)setsignal(SIGALRM, checkpoint); - (void)alarm(CHECKPOINT); + (void)setsignal(SIGINT, die); + (void)setsignal(SIGTERM, die); + (void)setsignal(SIGHUP, die); + if (rfilename == NULL) { + (void)setsignal(SIGQUIT, checkpoint); + (void)setsignal(SIGALRM, checkpoint); + (void)alarm(CHECKPOINT); + } } switch (linktype) { @@ -424,7 +450,15 @@ } if (status < 0) { syslog(LOG_ERR, "pcap_loop: %s", pcap_geterr(pd)); - exit(1); + if (restart && rfilename == NULL) { + syslog(LOG_ERR, "restart in %d secs", restart); + ++restarting_loop; + pcap_close(pd); + } else { + exit(1); + } + sleep(restart); + goto label_restart; } pcap_close(pd); if (!dump()) @@ -851,6 +885,7 @@ "[-p] " "[-a] " "[-u username] " + "[-R seconds ] " "[-Q ] " "[-z ignorenet/ignoremask] " "\n"