Subject: Re: Bad things with NetBSD and IP
To: Mike Cheponis <mac@Wireless.Com>
From: Andrew Brown <atatat@atatdot.net>
List: current-users
Date: 04/13/2001 22:53:54
--C7zPtVaVf+AK4Oqc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

>>In FreeBSD, the arp cache is cleared by "arp -da".  Unless there is a great reason
>>to do otherwise, can we keep it like FreeBSD?
>
>that's two votes.  good feedback...okay, i'll go rewrite it.

here we go.  now "arp -a -d" (or -a -d or -da or -ad or -dan...) will
delete all arp entries.

-- 
|-----< "CODE WARRIOR" >-----|
codewarrior@daemon.org             * "ah!  i see you have the internet
twofsonet@graffiti.com (Andrew Brown)                that goes *ping*!"
andrew@crossbar.com       * "information is power -- share the wealth."

--C7zPtVaVf+AK4Oqc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="arp.patch"

Index: arp.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/arp/arp.8,v
retrieving revision 1.11
diff -u -r1.11 arp.8
--- arp.8	1999/03/22 18:43:48	1.11
+++ arp.8	2001/04/14 02:52:42
@@ -48,7 +48,8 @@
 .Fl a
 .Nm ""
 .Op Fl v
-.Fl d Ar hostname
+.Fl d 
+.Op Ar -a|hostname
 .Nm ""
 .Fl s Ar hostname ether_addr
 .Op Ar temp
@@ -79,7 +80,11 @@
 .Ar hostname
 with the
 .Fl d
-flag.
+flag.  If used with
+.Fl a
+instead of a
+.Ar hostname ,
+it will delete all arp entries.
 .It Fl n
 Show network addresses as numbers (normally
 .Nm
Index: arp.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/arp/arp.c,v
retrieving revision 1.29
diff -u -r1.29 arp.c
--- arp.c	2001/03/19 19:49:30	1.29
+++ arp.c	2001/04/14 02:52:43
@@ -85,6 +85,7 @@
 
 int	delete __P((const char *, const char *));
 void	dump __P((u_long));
+void	delete_all __P((void));
 void	sdl_print __P((const struct sockaddr_dl *));
 int	getifname __P((u_int16_t, char *));
 int	atosdl __P((const char *s, struct sockaddr_dl *sdl));
@@ -98,7 +99,7 @@
 void	usage __P((void));
 
 static int pid;
-static int nflag, vflag;
+static int aflag, nflag, vflag;
 static int s = -1;
 static int is = -1;
 
@@ -120,6 +121,8 @@
 	while ((ch = getopt(argc, argv, "andsfv")) != -1)
 		switch((char)ch) {
 		case 'a':
+			aflag = 1;
+			break;
 		case 'd':
 		case 's':
 		case 'f':
@@ -139,14 +142,21 @@
 	argc -= optind;
 	argv += optind;
 
+	if (!op && aflag)
+		op = 'a';
+
 	switch((char)op) {
 	case 'a':
 		dump(0);
 		break;
 	case 'd':
-		if (argc < 1 || argc > 2)
-			usage();
-		(void)delete(argv[0], argv[1]);
+		if (aflag)
+			delete_all();
+		else {
+			if (argc < 1 || argc > 2)
+				usage();
+			(void)delete(argv[0], argv[1]);
+		}
 		break;
 	case 's':
 		if (argc < 2 || argc > 5)
@@ -455,6 +465,45 @@
 				(void)printf("(weird)");
 		}
 		(void)printf("\n");
+	}
+}
+
+/*
+ * Delete the entire arp table
+ */
+void
+delete_all(void)
+{
+	int mib[6];
+	size_t needed;
+	char addr[sizeof("000.000.000.000\0")];
+	char *lim, *buf, *next;
+	struct rt_msghdr *rtm;
+	struct sockaddr_inarp *sin;
+	struct sockaddr_dl *sdl;
+
+	mib[0] = CTL_NET;
+	mib[1] = PF_ROUTE;
+	mib[2] = 0;
+	mib[3] = AF_INET;
+	mib[4] = NET_RT_FLAGS;
+	mib[5] = RTF_LLINFO;
+	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+		err(1, "route-sysctl-estimate");
+	if (needed == 0)
+		return;
+	if ((buf = malloc(needed)) == NULL)
+		err(1, "malloc");
+	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+		err(1, "actual retrieval of routing table");
+	lim = buf + needed;
+	for (next = buf; next < lim; next += rtm->rtm_msglen) {
+		rtm = (struct rt_msghdr *)next;
+		sin = (struct sockaddr_inarp *)(rtm + 1);
+		sdl = (struct sockaddr_dl *)
+		    (ROUNDUP(sin->sin_len) + (char *)sin);
+		snprintf(addr, sizeof(addr), "%s", inet_ntoa(sin->sin_addr));
+		delete(addr, NULL);
 	}
 }
 

--C7zPtVaVf+AK4Oqc--