diff options
author | yar <yar@FreeBSD.org> | 2003-07-18 13:48:06 +0000 |
---|---|---|
committer | yar <yar@FreeBSD.org> | 2003-07-18 13:48:06 +0000 |
commit | e91a5a8a8f295a31c3bad24a88490ac45ee6ef57 (patch) | |
tree | 990070cc266c21f1a4d42ecf42c07d8826669c32 /usr.sbin/arp/arp.c | |
parent | 522acafcec81cffcf59023810c4d1aaf993e9523 (diff) | |
download | FreeBSD-src-e91a5a8a8f295a31c3bad24a88490ac45ee6ef57.zip FreeBSD-src-e91a5a8a8f295a31c3bad24a88490ac45ee6ef57.tar.gz |
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 <marck at rinet.ru>
Discussed on: -net
MFC after: 2 weeks
Diffstat (limited to 'usr.sbin/arp/arp.c')
-rw-r--r-- | usr.sbin/arp/arp.c | 29 |
1 files changed, 25 insertions, 4 deletions
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]", |