From nobody@FreeBSD.org  Sun Oct  4 10:49:05 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 4BC3B106568B
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  4 Oct 2009 10:49:05 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 2F6258FC0C
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  4 Oct 2009 10:49:05 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n94An5pT006729
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 4 Oct 2009 10:49:05 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n94An4BT006728;
	Sun, 4 Oct 2009 10:49:04 GMT
	(envelope-from nobody)
Message-Id: <200910041049.n94An4BT006728@www.freebsd.org>
Date: Sun, 4 Oct 2009 10:49:04 GMT
From: Gleb Kurtsou <gk@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] add arp option to remove static entries listed in file 
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         139346
>Category:       bin
>Synopsis:       [patch] arp(8) add option to remove static entries listed in file
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-net
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 04 10:50:01 UTC 2009
>Closed-Date:    
>Last-Modified:  Wed Oct  7 17:50:01 UTC 2009
>Originator:     Gleb Kurtsou
>Release:        
>Organization:
>Environment:
FreeBSD tops 9.0-CURRENT FreeBSD 9.0-CURRENT #7 r197735+8fb35f6: Sat Oct  3 21:22:17 EEST 2009     root@tops:/usr/obj/usr/freebsd-src/local/sys/TOPS  amd64
>Description:
Add 'arp -d -f file' option to remove static entries listed in file.
Basically it reverts 'arp -f file'

Was discussed in this thread: http://lists.freebsd.org/pipermail/svn-src-head/2009-August/009923.html
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c
index 8a3410f..11d1df6 100644
--- a/usr.sbin/arp/arp.c
+++ b/usr.sbin/arp/arp.c
@@ -101,7 +101,7 @@ static int valid_type(int type);
 static int nflag;	/* no reverse dns lookups */
 static char *rifname;
 
-static int	expire_time, flags, doing_proxy, proxy_only;
+static int	expire_time, flags, func, doing_proxy, proxy_only;
 
 /* which function we're supposed to do */
 #define F_GET		1
@@ -109,23 +109,28 @@ static int	expire_time, flags, doing_proxy, proxy_only;
 #define F_FILESET	3
 #define F_REPLACE	4
 #define F_DELETE	5
+#define F_FILEDELETE	6
 
 #define SETFUNC(f)	{ if (func) usage(); func = (f); }
 
 int
 main(int argc, char *argv[])
 {
-	int ch, func = 0;
+	int ch;
 	int rtn = 0;
 	int aflag = 0;	/* do it for all entries */
 
+	func = 0;
 	while ((ch = getopt(argc, argv, "andfsSi:")) != -1)
 		switch(ch) {
 		case 'a':
 			aflag = 1;
 			break;
 		case 'd':
-			SETFUNC(F_DELETE);
+			if (func == F_FILESET)
+				func = F_FILEDELETE;
+			else 
+				SETFUNC(F_DELETE);
 			break;
 		case 'n':
 			nflag = 1;
@@ -137,7 +142,10 @@ main(int argc, char *argv[])
 			SETFUNC(F_SET);
 			break;
 		case 'f' :
-			SETFUNC(F_FILESET);
+			if (func == F_DELETE)
+				func = F_FILEDELETE;
+			else
+				SETFUNC(F_FILESET);
 			break;
 		case 'i':
 			rifname = optarg;
@@ -197,6 +205,7 @@ main(int argc, char *argv[])
 		}
 		break;
 	case F_FILESET:
+	case F_FILEDELETE:
 		if (argc != 1)
 			usage();
 		rtn = file(argv[0]);
@@ -213,7 +222,7 @@ static int
 file(char *name)
 {
 	FILE *fp;
-	int i, retval;
+	int i, j, retval;
 	char line[100], arg[5][50], *args[5], *p;
 
 	if ((fp = fopen(name, "r")) == NULL)
@@ -237,8 +246,23 @@ file(char *name)
 			retval = 1;
 			continue;
 		}
-		if (set(i, args))
-			retval = 1;
+		switch (func) {
+		case F_FILESET:
+			if (set(i, args))
+				retval = 1;
+			break;
+		case F_FILEDELETE:
+			for (j = 2; j < i; j++)
+				if (strncmp(args[j], "pub", 3) == 0) {
+					j = 0;
+					break;
+				}
+			if (delete(args[0], j == 0 ? SIN_PROXY : 0))
+				retval = 1;
+			break;
+		default:
+			usage();
+		}
 	}
 	fclose(fp);
 	return (retval);
@@ -650,11 +674,12 @@ nuke_entry(struct sockaddr_dl *sdl __unused,
 static void
 usage(void)
 {
-	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
 		"usage: arp [-n] [-i interface] hostname",
 		"       arp [-n] [-i interface] -a",
 		"       arp -d hostname [pub]",
 		"       arp -d [-i interface] -a",
+		"       arp -d -f filename",
 		"       arp -s hostname ether_addr [temp] [reject | blackhole] [pub [only]]",
 		"       arp -S hostname ether_addr [temp] [reject | blackhole] [pub [only]]",
 		"       arp -f filename");


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: gavin 
Responsible-Changed-When: Sun Oct 4 17:38:34 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer(s).  To submitter:  Could you also please 
provide a patch to update the man page?  Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=139346 

From: Gleb Kurtsou <gleb.kurtsou@gmail.com>
To: gavin@FreeBSD.org, bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/139346: [patch] arp(8) add option to remove static entries
 listed in file
Date: Wed, 7 Oct 2009 20:40:53 +0300

 --zhXaljGHf11kAtnf
 Content-Type: text/plain; charset=utf-8
 Content-Disposition: inline
 
 Updated patch attached: includes man page update.
 
 --zhXaljGHf11kAtnf
 Content-Type: text/plain; charset=utf-8
 Content-Disposition: attachment; filename="arp-df-2.path.txt"
 
 diff --git a/usr.sbin/arp/arp.8 b/usr.sbin/arp/arp.8
 index d7306d3..683ec42 100644
 --- a/usr.sbin/arp/arp.8
 +++ b/usr.sbin/arp/arp.8
 @@ -51,6 +51,8 @@
  .Op Fl i Ar interface
  .Fl a
  .Nm
 +.Fl d Fl f Ar filename
 +.Nm
  .Fl s Ar hostname ether_addr
  .Op Cm temp
  .Op Cm blackhole No \&| Cm reject
 @@ -99,7 +101,9 @@ Alternatively, the
  .Fl d
  flag may be combined with the
  .Fl a
 -flag to delete all entries.
 +flag to delete all entries or with
 +.Fl f
 +flag to delete all entries listed in file.
  .It Fl i Ar interface
  Limit the operation scope to the
  .Tn ARP
 @@ -174,6 +178,11 @@ Cause the file
  to be read and multiple entries to be set in the
  .Tn ARP
  tables.
 +Combining with
 +.Fl d
 +flag may be used to delete entries from the
 +.Tn ARP
 +tables.
  Entries
  in the file should be of the form
  .Pp
 diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c
 index 8a3410f..11d1df6 100644
 --- a/usr.sbin/arp/arp.c
 +++ b/usr.sbin/arp/arp.c
 @@ -101,7 +101,7 @@ static int valid_type(int type);
  static int nflag;	/* no reverse dns lookups */
  static char *rifname;
  
 -static int	expire_time, flags, doing_proxy, proxy_only;
 +static int	expire_time, flags, func, doing_proxy, proxy_only;
  
  /* which function we're supposed to do */
  #define F_GET		1
 @@ -109,23 +109,28 @@ static int	expire_time, flags, doing_proxy, proxy_only;
  #define F_FILESET	3
  #define F_REPLACE	4
  #define F_DELETE	5
 +#define F_FILEDELETE	6
  
  #define SETFUNC(f)	{ if (func) usage(); func = (f); }
  
  int
  main(int argc, char *argv[])
  {
 -	int ch, func = 0;
 +	int ch;
  	int rtn = 0;
  	int aflag = 0;	/* do it for all entries */
  
 +	func = 0;
  	while ((ch = getopt(argc, argv, "andfsSi:")) != -1)
  		switch(ch) {
  		case 'a':
  			aflag = 1;
  			break;
  		case 'd':
 -			SETFUNC(F_DELETE);
 +			if (func == F_FILESET)
 +				func = F_FILEDELETE;
 +			else 
 +				SETFUNC(F_DELETE);
  			break;
  		case 'n':
  			nflag = 1;
 @@ -137,7 +142,10 @@ main(int argc, char *argv[])
  			SETFUNC(F_SET);
  			break;
  		case 'f' :
 -			SETFUNC(F_FILESET);
 +			if (func == F_DELETE)
 +				func = F_FILEDELETE;
 +			else
 +				SETFUNC(F_FILESET);
  			break;
  		case 'i':
  			rifname = optarg;
 @@ -197,6 +205,7 @@ main(int argc, char *argv[])
  		}
  		break;
  	case F_FILESET:
 +	case F_FILEDELETE:
  		if (argc != 1)
  			usage();
  		rtn = file(argv[0]);
 @@ -213,7 +222,7 @@ static int
  file(char *name)
  {
  	FILE *fp;
 -	int i, retval;
 +	int i, j, retval;
  	char line[100], arg[5][50], *args[5], *p;
  
  	if ((fp = fopen(name, "r")) == NULL)
 @@ -237,8 +246,23 @@ file(char *name)
  			retval = 1;
  			continue;
  		}
 -		if (set(i, args))
 -			retval = 1;
 +		switch (func) {
 +		case F_FILESET:
 +			if (set(i, args))
 +				retval = 1;
 +			break;
 +		case F_FILEDELETE:
 +			for (j = 2; j < i; j++)
 +				if (strncmp(args[j], "pub", 3) == 0) {
 +					j = 0;
 +					break;
 +				}
 +			if (delete(args[0], j == 0 ? SIN_PROXY : 0))
 +				retval = 1;
 +			break;
 +		default:
 +			usage();
 +		}
  	}
  	fclose(fp);
  	return (retval);
 @@ -650,11 +674,12 @@ nuke_entry(struct sockaddr_dl *sdl __unused,
  static void
  usage(void)
  {
 -	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
 +	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
  		"usage: arp [-n] [-i interface] hostname",
  		"       arp [-n] [-i interface] -a",
  		"       arp -d hostname [pub]",
  		"       arp -d [-i interface] -a",
 +		"       arp -d -f filename",
  		"       arp -s hostname ether_addr [temp] [reject | blackhole] [pub [only]]",
  		"       arp -S hostname ether_addr [temp] [reject | blackhole] [pub [only]]",
  		"       arp -f filename");
 
 --zhXaljGHf11kAtnf--
>Unformatted:
