File arpwatch-no-flipflop.patch of Package arpwatch

Index: b/arpwatch.c
===================================================================
--- a/arpwatch.c
+++ b/arpwatch.c
@@ -146,7 +146,8 @@ struct nets {
 
 enum action {
 	ADD = 1,
-	SKIP
+	SKIP,
+	NOFLIP
 };
 
 /* Locals */
@@ -156,6 +157,9 @@ static int nets_size;
 static struct nets *skipnets;
 static int skipnets_ind;
 static int skipnets_size;
+static struct nets *noflipnets;
+static int noflipnets_ind;
+static int noflipnets_size;
 static const char *pidfile;
 
 extern int optind;
@@ -175,6 +179,7 @@ int	snmp_add(u_int32_t, u_char *, time_t
 int	sanity_ether(struct ether_header *, struct ether_arp *, int);
 int	sanity_fddi(struct fddi_header *, struct ether_arp *, int);
 int	toskip(u_int32_t);
+int	noflip(u_int32_t);
 void	usage(void) __attribute__((noreturn));
 
 void dropprivileges(const char* user)
@@ -266,7 +271,7 @@ main(int argc, char **argv)
 	interface = NULL;
 	rfilename = NULL;
 	pd = NULL;
-	while ((op = getopt(argc, argv, "CdD:Ff:i:n:NpP:qr:svw:W:x:zZu:")) != EOF)
+	while ((op = getopt(argc, argv, "CdD:Ff:i:n:o:NpP:qr:svw:W:x:zZu:")) != EOF)
 		switch (op) {
 
 		case 'C':
@@ -306,6 +311,11 @@ main(int argc, char **argv)
 			++nobogons;
 			break;
 
+		case 'o':
+			if (!addnet(NOFLIP, optarg))
+				usage();
+			break;
+
 		case 'p':
 			promisc = 0;
 			break;
@@ -870,6 +880,12 @@ addnet(enum action action, const char *s
 		ns = skipnets;
 		break;
 
+	case NOFLIP:
+		size = noflipnets_size;
+		ind = noflipnets_ind;
+		ns = noflipnets;
+		break;
+
 	default:
 		(void)fprintf(stderr, "%s: addnet: unknown action: %d\n",
 		    prog, action);
@@ -941,6 +957,10 @@ addnet(enum action action, const char *s
 		skipnets_size = size;
 		skipnets_ind = ind;
 		skipnets = ns;
+	} else if (action == NOFLIP) {
+		noflipnets_size = size;
+		noflipnets_ind = ind;
+		noflipnets = ns;
 	} else {
 		(void)fprintf(stderr, "%s: addnet: unknown action: %d\n",
 		    prog, action);
@@ -964,6 +984,18 @@ toskip(u_int32_t sia)
 }
 
 int
+noflip(u_int32_t sia)
+{
+	int i;
+	struct nets *np;
+	for (i = 0, np = noflipnets; i < noflipnets_ind; ++i, ++np)
+		if ((sia & np->netmask) == np->net)
+			return (1);
+
+	return (0);
+}
+
+int
 isbogon(u_int32_t sia)
 {
 	int i;
@@ -1020,6 +1052,6 @@ usage(void)
 	    "usage: %s [-CdFNpqsvzZ] [-D arpdir] [-f datafile]"
 	    " [-i interface]\n\t"
 	    " [-P pidfile] [-w watcher@email] [-W watchee@email]\n\t"
-	    " [-n net[/width]] [-x net[/width]] [-r file] [-u username]\n", prog);
+	    " [-n net[/width]] [-x net[/width]] [-o net[/width]] [-r file] [-u username]\n", prog);
 	exit(1);
 }
Index: b/db.c
===================================================================
--- a/db.c
+++ b/db.c
@@ -67,6 +67,8 @@ static const char rcsid[] =
 #define NEWACTIVITY_DELTA (6*30*24*60*60)	/* 6 months in seconds */
 #define FLIPFLIP_DELTA (24*60*60)		/* 24 hours in seconds */
 
+extern int noflip(u_int32_t);
+
 /* Ethernet info */
 struct einfo {
 	u_char e[6];		/* ether address */
@@ -199,8 +201,13 @@ ent_add(u_int32_t a, const u_char *e, ti
 				    dosyslog(LOG_INFO,
 					"suppressed DECnet flip flop",
 					a, e, e2);
-			} else if (!suppress)
-				report("flip flop", a, e, e2, &t, &t2);
+			} else if (!suppress) {
+				if (noflip(a)) {
+					if (0) /* enable for debugging */
+						dosyslog(LOG_INFO, "suppressed flip flop", a, e, e2);
+				} else
+					report("flip flop", a, e, e2, &t, &t2);
+			}
 			ap->elist[1] = ap->elist[0];
 			ap->elist[0] = ep;
 			ep->t = t;
Index: b/arpsnmp.c
===================================================================
--- a/arpsnmp.c
+++ b/arpsnmp.c
@@ -87,6 +87,11 @@ extern int optind;
 extern int opterr;
 extern char *optarg;
 
+int noflip(u_int32_t a)
+{
+	return 0;
+}
+
 int
 main(int argc, char **argv)
 {
openSUSE Build Service is sponsored by