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");