From e91a5a8a8f295a31c3bad24a88490ac45ee6ef57 Mon Sep 17 00:00:00 2001 From: yar Date: Fri, 18 Jul 2003 13:48:06 +0000 Subject: Implement a new option: -i, which will allow to limit the scope of operation to the ARP entries on a particular interface. It should be useful on machines with numerous network interfaces, e.g., on inter-VLAN routers. PR: bin/54151 Submitted by: Dmitry Morozovsky Discussed on: -net MFC after: 2 weeks --- usr.sbin/arp/arp.8 | 8 ++++++++ usr.sbin/arp/arp.c | 29 +++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) (limited to 'usr.sbin/arp') diff --git a/usr.sbin/arp/arp.8 b/usr.sbin/arp/arp.8 index 89aa7a5..7067338 100644 --- a/usr.sbin/arp/arp.8 +++ b/usr.sbin/arp/arp.8 @@ -41,9 +41,11 @@ .Sh SYNOPSIS .Nm .Op Fl n +.Op Fl i Ar interface .Ar hostname .Nm .Op Fl n +.Op Fl i Ar interface .Fl a .Nm .Fl d Ar hostname @@ -99,6 +101,12 @@ Alternatively, the flag may be combined with the .Fl a flag to delete all entries. +.It Fl i Ar interface +Limit the operation scope to the +.Tn ARP +entries on +.Ar interface . +Applicable to the display operations only. .It Fl n Show network addresses as numbers (normally .Nm diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c index e0bdf11..89d1d1d 100644 --- a/usr.sbin/arp/arp.c +++ b/usr.sbin/arp/arp.c @@ -104,6 +104,7 @@ static pid_t pid; static int nflag; /* no reverse dns lookups */ static int aflag; /* do it for all entries */ static int s = -1; +static char *rifname; struct sockaddr_in so_mask; struct sockaddr_inarp blank_sin, sin_m; @@ -132,7 +133,7 @@ main(int argc, char *argv[]) int rtn = 0; pid = getpid(); - while ((ch = getopt(argc, argv, "andfsS")) != -1) + while ((ch = getopt(argc, argv, "andfsSi:")) != -1) switch((char)ch) { case 'a': aflag = 1; @@ -152,6 +153,9 @@ main(int argc, char *argv[]) case 'f' : SETFUNC(F_FILESET); break; + case 'i': + rifname = optarg; + break; case '?': default: usage(); @@ -171,6 +175,16 @@ main(int argc, char *argv[]) if (!func) func = F_GET; + if (rifname) { + if (func != F_GET) + errx(1, "-i not applicable to this operation"); + if (if_nametoindex(rifname) == 0) { + if (errno == ENXIO) + errx(1, "interface %s does not exist", rifname); + else + err(1, "if_nametoindex(%s)", rifname); + } + } switch (func) { case F_GET: if (aflag) { @@ -376,8 +390,11 @@ get(char *host) } search(addr->sin_addr.s_addr, print_entry); if (found_entry == 0) { - printf("%s (%s) -- no entry\n", + printf("%s (%s) -- no entry", host, inet_ntoa(addr->sin_addr)); + if (rifname) + printf(" on %s", rifname); + printf("\n"); return(1); } return(0); @@ -459,6 +476,7 @@ search(u_long addr, void (*action)(struct sockaddr_dl *sdl, struct rt_msghdr *rtm; struct sockaddr_inarp *sin2; struct sockaddr_dl *sdl; + char ifname[IF_NAMESIZE]; mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -477,6 +495,9 @@ search(u_long addr, void (*action)(struct sockaddr_dl *sdl, rtm = (struct rt_msghdr *)next; sin2 = (struct sockaddr_inarp *)(rtm + 1); (char *)sdl = (char *)sin2 + ROUNDUP(sin2->sin_len); + if (rifname && if_indextoname(sdl->sdl_index, ifname) && + strcmp(ifname, rifname)) + continue; if (addr) { if (addr != sin2->sin_addr.s_addr) continue; @@ -593,8 +614,8 @@ void usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", - "usage: arp [-n] hostname", - " arp [-n] -a", + "usage: arp [-n] [-i interface] hostname", + " arp [-n] [-i interface] -a", " arp -d hostname [pub]", " arp -d -a", " arp -s hostname ether_addr [temp] [pub]", -- cgit v1.1