diff -rNu arpwatch-2.1a11_orig/Makefile.in arpwatch-2.1a11/Makefile.in
--- arpwatch-2.1a11_orig/Makefile.in	2000-06-15 02:39:55.000000000 +0200
+++ arpwatch-2.1a11/Makefile.in	2003-11-01 13:01:15.000000000 +0100
@@ -32,6 +32,8 @@
 MANDEST = @mandir@
 # Pathname of directory to install database file
 ARPDIR = $(prefix)/arpwatch
+# Pathname of report script 
+REPORT_SCRIPT = $(ARPDIR)/arpwatch_report
 
 # VPATH
 srcdir = @srcdir@
@@ -45,7 +47,7 @@
 PROG = arpwatch
 CCOPT = @V_CCOPT@
 INCLS = -I. @V_INCLS@
-DEFS = -DDEBUG @DEFS@ -DARPDIR=\"$(ARPDIR)\" -DPATH_SENDMAIL=\"$(SENDMAIL)\"
+DEFS = -DDEBUG @DEFS@ -DARPDIR=\"$(ARPDIR)\" -DPATH_SENDMAIL=\"$(SENDMAIL)\" -DPATH_REPORT_SCRIPT=\"$(REPORT_SCRIPT)\"
 
 # Standard CFLAGS
 CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
diff -rNu arpwatch-2.1a11_orig/README-arpwatch_report arpwatch-2.1a11/README-arpwatch_report
--- arpwatch-2.1a11_orig/README-arpwatch_report	1970-01-01 01:00:00.000000000 +0100
+++ arpwatch-2.1a11/README-arpwatch_report	2003-11-05 11:12:16.000000000 +0100
@@ -0,0 +1,18 @@
+arpwatch_report - allows scripting for aprwatch
+(c) Collin R. Mulliner <collin@betaversion.net>
+
+arpwatch normally notifys root via email of any changes via sendmail.
+
+with arpwatch_report this has changed a little: arpwatch first trys to
+run the arpwatch_report program (which is any type of executable) located in
+the arpwatch directory (see arpwatch.8). arpwatch passes several parameters
+to aprwatch_report and dumps the content of the email, that should be mailed 
+to root, to stdin of arpwatch_report (see sample arpwatch_report script).
+If arpwatch_report can't run arpwatch falls back to sendmail.
+
+arpwatch_report (see sample script!) takes the following parameters:
+
+[interface] [ip] [new mac] [old mac] [old time] [new time] [arpwatch tag]
+
+example:
+de0 10.0.1.1 00:00:00:00:00:00 00:11:22:33:44:55 0 1432432 "new station"
diff -rNu arpwatch-2.1a11_orig/arpsnmp.c arpwatch-2.1a11/arpsnmp.c
--- arpwatch-2.1a11_orig/arpsnmp.c	1999-01-18 02:47:40.000000000 +0100
+++ arpwatch-2.1a11/arpsnmp.c	2003-11-01 13:01:15.000000000 +0100
@@ -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 *, u_char*);
 __dead	void usage(void) __attribute__((volatile));
 
 char *prog;
@@ -138,7 +138,7 @@
 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, register u_char *u)
 {
 	/* Watch for ethernet broadcast */
 	if (MEMCMP(e, zero, 6) == 0 || MEMCMP(e, allones, 6) == 0) {
@@ -153,7 +153,7 @@
 	}
 
 	/* 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, u));
 }
 
 /* Process an snmp file */
diff -rNu arpwatch-2.1a11_orig/arpwatch.8 arpwatch-2.1a11/arpwatch.8
--- arpwatch-2.1a11_orig/arpwatch.8	2000-10-08 22:31:28.000000000 +0200
+++ arpwatch-2.1a11/arpwatch.8	2003-11-05 10:45:17.000000000 +0100
@@ -153,6 +153,7 @@
 .nh
 .nf
 /usr/operator/arpwatch - default directory
+arpwatch_report - report script
 arp.dat - ethernet/ip address database
 ethercodes.dat - vendor ethernet block list
 .ad
diff -rNu arpwatch-2.1a11_orig/arpwatch.c arpwatch-2.1a11/arpwatch.c
--- arpwatch-2.1a11_orig/arpwatch.c	2000-10-14 04:07:35.000000000 +0200
+++ arpwatch-2.1a11/arpwatch.c	2003-11-01 13:01:15.000000000 +0100
@@ -331,7 +331,7 @@
 	switch (linktype) {
 
 	case DLT_EN10MB:
-		status = pcap_loop(pd, 0, process_ether, NULL);
+		status = pcap_loop(pd, 0, process_ether, interface);
 		break;
 
 	case DLT_FDDI:
@@ -400,7 +400,7 @@
 	/* Got a live one */
 	t = h->ts.tv_sec;
 	can_checkpoint = 0;
-	if (!ent_add(sia, sea, t, NULL))
+	if (!ent_add(sia, sea, t, NULL, u))
 		syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed",
 		    intoa(sia), e2str(sea), t);
 	can_checkpoint = 1;
@@ -549,7 +549,7 @@
 	/* Got a live one */
 	t = h->ts.tv_sec;
 	can_checkpoint = 0;
-	if (!ent_add(sia, sea, t, NULL))
+	if (!ent_add(sia, sea, t, NULL, u))
 		syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed",
 		    intoa(sia), e2str(sea), t);
 	can_checkpoint = 1;
diff -rNu arpwatch-2.1a11_orig/arpwatch_report arpwatch-2.1a11/arpwatch_report
--- arpwatch-2.1a11_orig/arpwatch_report	1970-01-01 01:00:00.000000000 +0100
+++ arpwatch-2.1a11/arpwatch_report	2003-11-01 13:08:56.000000000 +0100
@@ -0,0 +1,43 @@
+#!/usr/bin/perl
+
+# send reports to
+$watcher = "root";
+
+# DEBUG 
+#open FILE, ">> /var/log/arpwatch";
+
+# read arpwatch 'mail' output
+@arpwatch_mail = <STDIN>;
+
+# read parameters 
+ # interface
+ $if = $ARGV[0];
+ # ip address
+ $ip = $ARGV[1];
+ # new mac address
+ $mac_new = $ARGV[2];
+ # old mac address
+ $mac_old = $ARGV[3];
+ # new time stamp
+ $ts_new = $ARGV[4];
+ # old time stamp
+ $ts_old = $ARGV[5];
+ # arpwatch event title
+ $title = $ARGV[6];
+
+# DEBUG
+#print FILE "DEBUG [$if] title: $title ip: $ip MAC(old: $mac_old new: $mac_new) TIME(old: $ts_old new: $ts_new)\n";
+ 
+# handle interfaces
+if ($if eq "de0") {
+	open MAIL, "|/usr/sbin/sendmail -odi $watcher";
+	print MAIL @arpwatch_mail;
+	close MAIL;
+}
+else {
+	open MAIL, "|/usr/sbin/sendmail -odi $watcher";
+	print MAIL @arpwatch_mail;
+	close MAIL;
+}
+# DEBUG
+#close FILE;
diff -rNu arpwatch-2.1a11_orig/db.c arpwatch-2.1a11/db.c
--- arpwatch-2.1a11_orig/db.c	2000-10-01 01:39:58.000000000 +0200
+++ arpwatch-2.1a11/db.c	2003-11-01 13:01:15.000000000 +0100
@@ -86,7 +86,7 @@
 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, register u_char *u)
 {
 	register struct ainfo *ap;
 	register struct einfo *ep;
@@ -103,7 +103,7 @@
 		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, u);
 				check_hname(ap);
 			}
 			ep->t = t;
@@ -115,7 +115,7 @@
 	if (ap->ecount == 0) {
 		ap->ecount = 1;
 		ap->elist[0] = elist_alloc(a, e, t, h);
-		report("new station", a, e, NULL, &t, NULL);
+		report("new station", a, e, NULL, &t, NULL, u);
 		return (1);
 	}
 
@@ -135,7 +135,7 @@
 				dosyslog(LOG_INFO,
 				    "suppressed DECnet flip flop", a, e, e2);
 			else
-				report("flip flop", a, e, e2, &t, &t2);
+				report("flip flop", a, e, e2, &t, &t2, u);
 			ap->elist[1] = ap->elist[0];
 			ap->elist[0] = ep;
 			ep->t = t;
@@ -165,7 +165,7 @@
 	/* 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, u);
 	/* Make room at head of list */
 	alist_alloc(ap);
 	len = ap->ecount * sizeof(ap->elist[0]);
diff -rNu arpwatch-2.1a11_orig/db.h arpwatch-2.1a11/db.h
--- arpwatch-2.1a11_orig/db.h	1996-06-05 07:39:30.000000000 +0200
+++ arpwatch-2.1a11/db.h	2003-11-01 13:01:15.000000000 +0100
@@ -5,6 +5,6 @@
 #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 *, u_char *);
 int	ent_loop(ent_process);
 void	sorteinfo(void);
diff -rNu arpwatch-2.1a11_orig/ec.c arpwatch-2.1a11/ec.c
--- arpwatch-2.1a11_orig/ec.c	2000-10-14 00:49:16.000000000 +0200
+++ arpwatch-2.1a11/ec.c	2003-11-01 13:01:15.000000000 +0100
@@ -218,7 +218,7 @@
 {
 	static char str[32];
 
-	(void)sprintf(str, "%x:%x:%x:%x:%x:%x",
+	(void)sprintf(str, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
 	    e[0], e[1], e[2], e[3], e[4], e[5]);
 	return (str);
 }
diff -rNu arpwatch-2.1a11_orig/file.c arpwatch-2.1a11/file.c
--- arpwatch-2.1a11_orig/file.c	2000-10-14 00:29:43.000000000 +0200
+++ arpwatch-2.1a11/file.c	2003-11-01 13:01:15.000000000 +0100
@@ -130,7 +130,7 @@
 			}
 		}
 
-		if (!(*fn)(a, e, t, h))
+		if (!(*fn)(a, e, t, h, ""))
 			return(0);
 	}
 
diff -rNu arpwatch-2.1a11_orig/file.h arpwatch-2.1a11/file.h
--- arpwatch-2.1a11_orig/file.h	1999-01-18 02:46:04.000000000 +0100
+++ arpwatch-2.1a11/file.h	2003-11-01 13:01:15.000000000 +0100
@@ -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 *, u_char *);
 
 int file_loop(FILE *, file_process, const char *);
diff -rNu arpwatch-2.1a11_orig/report.c arpwatch-2.1a11/report.c
--- arpwatch-2.1a11_orig/report.c	2000-10-01 01:41:10.000000000 +0200
+++ arpwatch-2.1a11/report.c	2003-11-01 13:01:15.000000000 +0100
@@ -233,7 +233,7 @@
 
 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, register u_char* u)
 {
 	register char *cp, *hn;
 	register int fd, pid;
@@ -243,9 +243,15 @@
 	char *watcher = WATCHER;
 	char *watchee = WATCHEE;
 	char *sendmail = PATH_SENDMAIL;
+	char *script = PATH_REPORT_SCRIPT;
 	char *unknown = "<unknown>";
 	char buf[132];
 	static int init = 0;
+	char t1p_s[50];
+	char t2p_s[50];
+	char mac_old[30];
+	char mac_new[30];
+
 
 	/* No report until we're initialized */
 	if (initializing)
@@ -313,6 +319,7 @@
 	(void)fprintf(f, fmt, "hostname", hn);
 	(void)fprintf(f, fmt, "ip address", intoa(a));
 	(void)fprintf(f, fmt, "ethernet address", e2str(e1));
+	sprintf(mac_new, e2str(e1));
 	if ((cp = ec_find(e1)) == NULL)
 		cp = unknown;
 	(void)fprintf(f, fmt, "ethernet vendor", cp);
@@ -321,15 +328,23 @@
 		(void)fprintf(f, fmt, "dns cpu & os", buf);
 	}
 	if (e2) {
+		sprintf(mac_old, e2str(e2));
 		(void)fprintf(f, fmt, "old ethernet address", e2str(e2));
 		if ((cp = ec_find(e2)) == NULL)
 			cp = unknown;
 		(void)fprintf(f, fmt, "old ethernet vendor", cp);
 	}
-	if (t1p)
+	else sprintf(mac_old, "00:00:00:00:00:00");
+	if (t1p) {
+		sprintf(t1p_s, "%d", *t1p);
 		(void)fprintf(f, fmt, "timestamp", fmtdate(*t1p));
-	if (t2p)
+	}
+	else sprintf(t1p_s, "0");
+	if (t2p) {
+		sprintf(t2p_s, "%d", *t2p);
 		(void)fprintf(f, fmt, "previous timestamp", fmtdate(*t2p));
+	}
+	else sprintf(t2p_s, "0");
 	if (t1p && t2p && *t1p && *t2p)
 		(void)fprintf(f, fmt, "delta", fmtdelta(*t1p - *t2p));
 
@@ -345,6 +360,11 @@
 	}
 	/* XXX Need to freopen()? */
 	/* Always Deliver interactively (pause when child depth gets large) */
+	
+	/* first try to run the script */
+	execl(script, script, u, intoa(a), mac_new, mac_old, t1p_s, t2p_s, title, NULL);
+	syslog(LOG_ERR, "execl: %s: %m, falling back to sendmail", script);
+	/* run sendmail if script can't execute */
 	execl(sendmail, "sendmail", "-odi", watcher, NULL);
 	syslog(LOG_ERR, "execl: %s: %m", sendmail);
 	exit(1);
diff -rNu arpwatch-2.1a11_orig/report.h arpwatch-2.1a11/report.h
--- arpwatch-2.1a11_orig/report.h	1996-06-05 07:40:54.000000000 +0200
+++ arpwatch-2.1a11/report.h	2003-11-01 13:01:15.000000000 +0100
@@ -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 *i, u_char *u);
