diff -Naru arpwatch-2.1a15.orig/arpsnmp.c arpwatch-2.1a15/arpsnmp.c --- arpwatch-2.1a15.orig/arpsnmp.c 2006-09-22 19:44:44.000000000 +0400 +++ arpwatch-2.1a15/arpsnmp.c 2006-09-22 19:41:19.000000000 +0400 @@ -63,7 +63,7 @@ /* Forwards */ int main(int, char **); int readsnmp(char *); -int snmp_add(u_int32_t, u_char *, time_t, char *); +int snmp_add(u_int32_t, u_char *, time_t, char *, char *); __dead void usage(void) __attribute__((volatile)); char *prog; @@ -149,22 +149,24 @@ static time_t now; int -snmp_add(register u_int32_t a, register u_char *e, time_t t, register char *h) +snmp_add(register u_int32_t a, register u_char *e, time_t t, register char *h, + char *interface) { /* Watch for ethernet broadcast */ if (MEMCMP(e, zero, 6) == 0 || MEMCMP(e, allones, 6) == 0) { - dosyslog(LOG_INFO, "ethernet broadcast", a, e, NULL); + dosyslog(LOG_INFO, "ethernet broadcast", a, e, NULL, + interface); return (1); } /* Watch for some ip broadcast addresses */ if (a == 0 || a == 1) { - dosyslog(LOG_INFO, "ip broadcast", a, e, NULL); + dosyslog(LOG_INFO, "ip broadcast", a, e, NULL, interface); return (1); } /* Use current time (although it would be nice to subtract idle time) */ - return (ent_add(a, e, now, h)); + return (ent_add(a, e, now, h, interface)); } /* Process an snmp file */ diff -Naru arpwatch-2.1a15.orig/arpwatch.8 arpwatch-2.1a15/arpwatch.8 --- arpwatch-2.1a15.orig/arpwatch.8 2006-09-22 19:44:53.000000000 +0400 +++ arpwatch-2.1a15/arpwatch.8 2006-09-22 19:41:19.000000000 +0400 @@ -64,6 +64,11 @@ [ .B -p ] +.br +.ti +8 +[ +.B -a +] .ad .SH DESCRIPTION .B Arpwatch @@ -130,6 +135,17 @@ .B arpwatch. YMMV. (This feature comes from Debian). .LP +The +.B -a +flag tells +.B arpwatch +to report bogons about every IP address. By default, +.B arpwatch +reports bogons for IP addresses that are in the same subnet with the first IP +address of the default interface (unless +.B -N +is given). (This feature comes from Debian). +.LP Note that an empty .I arp.dat file must be created before the first time you run diff -Naru arpwatch-2.1a15.orig/arpwatch.c arpwatch-2.1a15/arpwatch.c --- arpwatch-2.1a15.orig/arpwatch.c 2006-09-22 19:44:53.000000000 +0400 +++ arpwatch-2.1a15/arpwatch.c 2006-09-22 19:41:19.000000000 +0400 @@ -142,6 +142,8 @@ int sanity_fddi(struct fddi_header *, struct ether_arp *, int); __dead void usage(void) __attribute__((volatile)); +static char *interface; + int main(int argc, char **argv) { @@ -151,7 +153,7 @@ register int fd; #endif register pcap_t *pd; - register char *interface, *rfilename; + register char *rfilename; struct bpf_program code; char errbuf[PCAP_ERRBUF_SIZE]; char options[] = @@ -163,6 +165,7 @@ "r:" "s:" "p" + "a" ; if (argv[0] == NULL) @@ -221,6 +224,10 @@ ++nopromisc; break; + case 'a': + ++allsubnets; + break; + default: usage(); } @@ -399,29 +406,31 @@ /* Watch for bogons */ if (isbogon(sia)) { - dosyslog(LOG_INFO, "bogon", sia, sea, sha); - return; + dosyslog(LOG_INFO, "bogon", sia, sea, sha, interface); + if (!allsubnets) return; } /* Watch for ethernet broadcast */ if (MEMCMP(sea, zero, 6) == 0 || MEMCMP(sea, allones, 6) == 0 || MEMCMP(sha, zero, 6) == 0 || MEMCMP(sha, allones, 6) == 0) { - dosyslog(LOG_INFO, "ethernet broadcast", sia, sea, sha); + dosyslog(LOG_INFO, "ethernet broadcast", sia, sea, sha, + interface); return; } /* Double check ethernet addresses */ if (MEMCMP(sea, sha, 6) != 0) { - dosyslog(LOG_INFO, "ethernet mismatch", sia, sea, sha); + dosyslog(LOG_INFO, "ethernet mismatch", sia, sea, sha, + interface); return; } /* Got a live one */ t = h->ts.tv_sec; can_checkpoint = 0; - if (!ent_add(sia, sea, t, NULL)) - syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed", - intoa(sia), e2str(sea), t); + if (!ent_add(sia, sea, t, NULL, interface)) + syslog(LOG_ERR, "ent_add(%s, %s, %ld, %s) failed", + intoa(sia), e2str(sea), t, interface); can_checkpoint = 1; } @@ -548,29 +557,31 @@ /* Watch for bogons */ if (isbogon(sia)) { - dosyslog(LOG_INFO, "bogon", sia, sea, sha); - return; + dosyslog(LOG_INFO, "bogon", sia, sea, sha, interface); + if (!allsubnets) return; } /* Watch for ethernet broadcast */ if (MEMCMP(sea, zero, 6) == 0 || MEMCMP(sea, allones, 6) == 0 || MEMCMP(sha, zero, 6) == 0 || MEMCMP(sha, allones, 6) == 0) { - dosyslog(LOG_INFO, "ethernet broadcast", sia, sea, sha); + dosyslog(LOG_INFO, "ethernet broadcast", sia, sea, sha, + interface); return; } /* Double check ethernet addresses */ if (MEMCMP(sea, sha, 6) != 0) { - dosyslog(LOG_INFO, "ethernet mismatch", sia, sea, sha); + dosyslog(LOG_INFO, "ethernet mismatch", sia, sea, sha, + interface); return; } /* Got a live one */ t = h->ts.tv_sec; can_checkpoint = 0; - if (!ent_add(sia, sea, t, NULL)) - syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed", - intoa(sia), e2str(sea), t); + if (!ent_add(sia, sea, t, NULL, interface)) + syslog(LOG_ERR, "ent_add(%s, %s, %ld, %s) failed", + intoa(sia), e2str(sea), t, interface); can_checkpoint = 1; } @@ -775,6 +786,7 @@ "[-r file] " "[-s sendmail_path] " "[-p] " + "[-a] " "\n" ; diff -Naru arpwatch-2.1a15.orig/db.c arpwatch-2.1a15/db.c --- arpwatch-2.1a15.orig/db.c 2000-10-01 03:39:58.000000000 +0400 +++ arpwatch-2.1a15/db.c 2006-09-22 19:43:35.000000000 +0400 @@ -64,6 +64,7 @@ u_char e[6]; /* ether address */ char h[34]; /* simple hostname */ time_t t; /* timestamp */ + char i[16]; /* interface */ }; /* Address info */ @@ -80,13 +81,14 @@ static void alist_alloc(struct ainfo *); int cmpeinfo(const void *, const void *); -static struct einfo *elist_alloc(u_int32_t, u_char *, time_t, char *); +static struct einfo *elist_alloc(u_int32_t, u_char *, time_t, char *, char *); static struct ainfo *ainfo_find(u_int32_t); static void check_hname(struct ainfo *); struct ainfo *newainfo(void); int -ent_add(register u_int32_t a, register u_char *e, time_t t, register char *h) +ent_add(register u_int32_t a, register u_char *e, time_t t, register char *h, + char *interface) { register struct ainfo *ap; register struct einfo *ep; @@ -103,7 +105,8 @@ ep = ap->elist[0]; if (MEMCMP(e, ep->e, 6) == 0) { if (t - ep->t > NEWACTIVITY_DELTA) { - report("new activity", a, e, NULL, &t, &ep->t); + report("new activity", a, e, NULL, &t, &ep->t, + interface); check_hname(ap); } ep->t = t; @@ -114,8 +117,8 @@ /* Check for a virgin ainfo record */ if (ap->ecount == 0) { ap->ecount = 1; - ap->elist[0] = elist_alloc(a, e, t, h); - report("new station", a, e, NULL, &t, NULL); + ap->elist[0] = elist_alloc(a, e, t, h, interface); + report("new station", a, e, NULL, &t, NULL, interface); return (1); } @@ -133,9 +136,11 @@ if (t - t2 < FLIPFLIP_DELTA && (isdecnet(e) || isdecnet(e2))) dosyslog(LOG_INFO, - "suppressed DECnet flip flop", a, e, e2); + "suppressed DECnet flip flop", a, e, e2, + interface); else - report("flip flop", a, e, e2, &t, &t2); + report("flip flop", a, e, e2, &t, &t2, + interface); ap->elist[1] = ap->elist[0]; ap->elist[0] = ep; ep->t = t; @@ -151,7 +156,7 @@ e2 = ap->elist[0]->e; t2 = ap->elist[0]->t; dosyslog(LOG_NOTICE, "reused old ethernet address", - a, e, e2); + a, e, e2, interface); /* Shift entries down */ len = i * sizeof(ap->elist[0]); BCOPY(&ap->elist[0], &ap->elist[1], len); @@ -165,12 +170,12 @@ /* New ether address */ e2 = ap->elist[0]->e; t2 = ap->elist[0]->t; - report("changed ethernet address", a, e, e2, &t, &t2); + report("changed ethernet address", a, e, e2, &t, &t2, interface); /* Make room at head of list */ alist_alloc(ap); len = ap->ecount * sizeof(ap->elist[0]); BCOPY(&ap->elist[0], &ap->elist[1], len); - ap->elist[0] = elist_alloc(a, e, t, h); + ap->elist[0] = elist_alloc(a, e, t, h, interface); ++ap->ecount; return (1); } @@ -227,7 +232,7 @@ for (ap = &ainfo_table[i]; ap != NULL; ap = ap->next) for (j = 0; j < ap->ecount; ++j) { ep = ap->elist[j]; - (*fn)(ap->a, ep->e, ep->t, ep->h); + (*fn)(ap->a, ep->e, ep->t, ep->h, ep->i); ++n; } return (n); @@ -259,7 +264,7 @@ /* Allocate and initialize a elist struct */ static struct einfo * elist_alloc(register u_int32_t a, register u_char *e, register time_t t, - register char *h) + register char *h, char *interface) { register struct einfo *ep; register u_int size; @@ -286,6 +291,8 @@ if (h != NULL && !isdigit((int)*h)) strcpy(ep->h, h); ep->t = t; + if (interface != NULL) + strncpy(ep->i, interface, 16); return (ep); } diff -Naru arpwatch-2.1a15.orig/db.h arpwatch-2.1a15/db.h --- arpwatch-2.1a15.orig/db.h 1996-06-05 09:39:30.000000000 +0400 +++ arpwatch-2.1a15/db.h 2006-09-22 19:41:19.000000000 +0400 @@ -1,10 +1,10 @@ /* @(#) $Header: db.h,v 1.8 96/06/04 22:39:29 leres Exp $ (LBL) */ -typedef void (*ent_process)(u_int32_t, u_char *, time_t, char *); +typedef void (*ent_process)(u_int32_t, u_char *, time_t, char *, char *); #ifdef DEBUG void debugdump(void); #endif -int ent_add(u_int32_t, u_char *, time_t, char *); +int ent_add(u_int32_t, u_char *, time_t, char *, char *); int ent_loop(ent_process); void sorteinfo(void); diff -Naru arpwatch-2.1a15.orig/file.c arpwatch-2.1a15/file.c --- arpwatch-2.1a15.orig/file.c 2000-10-14 02:29:43.000000000 +0400 +++ arpwatch-2.1a15/file.c 2006-09-22 19:41:19.000000000 +0400 @@ -69,6 +69,7 @@ u_int32_t a; register time_t t; register struct hostent *hp; + char *interface; char line[1024]; u_char e[6]; @@ -117,6 +118,7 @@ if (cp2 == NULL) { t = 0; h = NULL; + interface = NULL; } else { t = atoi(cp2); h = strchr(cp2, '\t'); @@ -126,11 +128,18 @@ while (*cp2 != '\n' && *cp2 != '\t' && *cp2 != '\0') ++cp2; + if (*cp2 == '\t') { + *cp2++ = '\0'; + while (*cp2 != '\n' && *cp2 != '\t' && + *cp2 != '\0') ++cp2; + } else { + interface = NULL; + } *cp2 = '\0'; } } - if (!(*fn)(a, e, t, h)) + if (!(*fn)(a, e, t, h, interface)) return(0); } diff -Naru arpwatch-2.1a15.orig/file.h arpwatch-2.1a15/file.h --- arpwatch-2.1a15.orig/file.h 1999-01-18 04:46:04.000000000 +0300 +++ arpwatch-2.1a15/file.h 2006-09-22 19:41:19.000000000 +0400 @@ -1,5 +1,5 @@ /* @(#) $Header: file.h,v 1.4 99/01/17 17:46:03 leres Exp $ (LBL) */ -typedef int (*file_process)(u_int32_t, u_char *, time_t, char *); +typedef int (*file_process)(u_int32_t, u_char *, time_t, char *, char *); int file_loop(FILE *, file_process, const char *); diff -Naru arpwatch-2.1a15.orig/report.c arpwatch-2.1a15/report.c --- arpwatch-2.1a15.orig/report.c 2006-09-22 19:44:44.000000000 +0400 +++ arpwatch-2.1a15/report.c 2006-09-22 19:41:19.000000000 +0400 @@ -233,7 +233,8 @@ void report(register char *title, register u_int32_t a, register u_char *e1, - register u_char *e2, register time_t *t1p, register time_t *t2p) + register u_char *e2, register time_t *t1p, register time_t *t2p, + char *interface) { extern char *path_sendmail; register char *cp, *hn; @@ -254,7 +255,7 @@ if (debug) { if (debug > 1) { - dosyslog(LOG_NOTICE, title, a, e1, e2); + dosyslog(LOG_NOTICE, title, a, e1, e2, interface); return; } f = stdout; @@ -271,7 +272,7 @@ } /* Syslog this event too */ - dosyslog(LOG_NOTICE, title, a, e1, e2); + dosyslog(LOG_NOTICE, title, a, e1, e2, interface); /* Update child depth */ ++cdepth; @@ -303,16 +304,19 @@ (void)fprintf(f, "From: %s\n", watchee); (void)fprintf(f, "To: %s\n", watcher); + if (interface == NULL) interface = ""; /* shouldn't happen */ hn = gethname(a); if (!isdigit(*hn)) - (void)fprintf(f, "Subject: %s (%s)\n", title, hn); + (void)fprintf(f, "Subject: %s (%s) %s\n", title, hn, + interface); else { - (void)fprintf(f, "Subject: %s\n", title); + (void)fprintf(f, "Subject: %s %s\n", title, interface); hn = unknown; } (void)putc('\n', f); (void)fprintf(f, fmt, "hostname", hn); (void)fprintf(f, fmt, "ip address", intoa(a)); + (void)fprintf(f, fmt, "interface", interface); (void)fprintf(f, fmt, "ethernet address", e2str(e1)); if ((cp = ec_find(e1)) == NULL) cp = unknown; diff -Naru arpwatch-2.1a15.orig/report.h arpwatch-2.1a15/report.h --- arpwatch-2.1a15.orig/report.h 1996-06-05 09:40:54.000000000 +0400 +++ arpwatch-2.1a15/report.h 2006-09-22 19:41:19.000000000 +0400 @@ -1,3 +1,3 @@ /* @(#) $Header: report.h,v 1.3 96/06/04 22:40:53 leres Exp $ (LBL) */ -void report(char *, u_int32_t, u_char *, u_char *, time_t *, time_t *); +void report(char *, u_int32_t, u_char *, u_char *, time_t *, time_t *, char *); diff -Naru arpwatch-2.1a15.orig/util.c arpwatch-2.1a15/util.c --- arpwatch-2.1a15.orig/util.c 2006-09-22 19:44:53.000000000 +0400 +++ arpwatch-2.1a15/util.c 2006-09-22 19:41:19.000000000 +0400 @@ -62,11 +62,12 @@ int debug = 0; int initializing = 1; /* true if initializing */ int nopromisc = 0; /* don't activate promisc mode by default */ +int allsubnets = 0; /* watch all attached subnets */ /* syslog() helper routine */ void dosyslog(register int p, register char *s, register u_int32_t a, - register u_char *ea, register u_char *ha) + register u_char *ea, register u_char *ha, char *interface) { char xbuf[64]; @@ -83,23 +84,21 @@ } if (debug) - fprintf(stderr, "%s: %s %s %s\n", prog, s, intoa(a), xbuf); + fprintf(stderr, "%s: %s %s %s %s\n", prog, s, intoa(a), + xbuf, interface); else - syslog(p, "%s %s %s", s, intoa(a), xbuf); + syslog(p, "%s %s %s %s", s, intoa(a), xbuf, interface); } static FILE *dumpf; void dumpone(register u_int32_t a, register u_char *e, register time_t t, - register char *h) + register char *h, char *interface) { - (void)fprintf(dumpf, "%s\t%s", e2str(e), intoa(a)); - if (t != 0 || h != NULL) - (void)fprintf(dumpf, "\t%u", (u_int32_t)t); - if (h != NULL && *h != '\0') - (void)fprintf(dumpf, "\t%s", h); - (void)putc('\n', dumpf); + (void)fprintf(dumpf, "%s\t%s\t%u\t%s\t%s\n", e2str(e), intoa(a), + (u_int32_t)t, ((h != NULL)?h:""), + ((interface != NULL)?interface:"")); } int diff -Naru arpwatch-2.1a15.orig/util.h arpwatch-2.1a15/util.h --- arpwatch-2.1a15.orig/util.h 2006-09-22 19:44:53.000000000 +0400 +++ arpwatch-2.1a15/util.h 2006-09-22 19:41:19.000000000 +0400 @@ -1,8 +1,8 @@ /* @(#) $Header: util.h,v 1.2 96/10/06 03:22:13 leres Exp $ (LBL) */ -void dosyslog(int, char *, u_int32_t, u_char *, u_char *); +void dosyslog(int, char *, u_int32_t, u_char *, u_char *, char *); int dump(void); -void dumpone(u_int32_t, u_char *, time_t, char *); +void dumpone(u_int32_t, u_char *, time_t, char *, char *); int readdata(void); char *savestr(const char *); @@ -18,3 +18,4 @@ extern int debug; extern int initializing; extern int nopromisc; +extern int allsubnets;