diff options
Diffstat (limited to 'usr.sbin/arp/arp.c')
| -rw-r--r-- | usr.sbin/arp/arp.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c index 9a19d792f788..8b2cc6f09740 100644 --- a/usr.sbin/arp/arp.c +++ b/usr.sbin/arp/arp.c @@ -67,7 +67,6 @@ static char const sccsid[] = "@(#)from: arp.c 8.2 (Berkeley) 1/2/94"; #include <arpa/inet.h> #include <ctype.h> -#include <err.h> #include <errno.h> #include <netdb.h> #include <nlist.h> @@ -94,7 +93,6 @@ static int get(char *host); static int file(char *name); static struct rt_msghdr *rtmsg(int cmd, struct sockaddr_in *dst, struct sockaddr_dl *sdl); -static int get_ether_addr(in_addr_t ipaddr, struct ether_addr *hwaddr); static int set_rtsock(struct sockaddr_in *dst, struct sockaddr_dl *sdl_m, char *host); @@ -156,7 +154,8 @@ main(int argc, char *argv[]) if (!func) func = F_GET; if (opts.rifname) { - if (func != F_GET && !(func == F_DELETE && opts.aflag)) + if (func != F_GET && func != F_SET && func != F_REPLACE && + !(func == F_DELETE && opts.aflag)) xo_errx(1, "-i not applicable to this operation"); if ((opts.rifindex = if_nametoindex(opts.rifname)) == 0) { if (errno == ENXIO) @@ -181,7 +180,8 @@ main(int argc, char *argv[]) xo_close_list("arp-cache"); xo_close_container("arp"); - xo_finish(); + if (xo_finish() < 0) + xo_err(1, "stdout"); } else { if (argc != 1) usage(); @@ -218,7 +218,7 @@ main(int argc, char *argv[]) if (ifnameindex != NULL) if_freenameindex(ifnameindex); - return (rtn); + exit(rtn); } /* @@ -285,7 +285,6 @@ getaddr(char *host) return (&reply); } -int valid_type(int type); /* * Returns true if the type is a valid one for ARP. */ @@ -369,11 +368,14 @@ set(int argc, char **argv) } ea = (struct ether_addr *)LLADDR(&sdl_m); if ((opts.flags & RTF_ANNOUNCE) && !strcmp(eaddr, "auto")) { - if (!get_ether_addr(dst->sin_addr.s_addr, ea)) { + uint32_t ifindex; + if (!get_ifinfo(dst->sin_addr.s_addr, ea, &ifindex)) { xo_warnx("no interface found for %s", - inet_ntoa(dst->sin_addr)); + inet_ntoa(dst->sin_addr)); return (1); } + if (opts.rifindex == 0) + opts.rifindex = ifindex; sdl_m.sdl_alen = ETHER_ADDR_LEN; } else { struct ether_addr *ea1 = ether_aton(eaddr); @@ -387,7 +389,7 @@ set(int argc, char **argv) } } #ifndef WITHOUT_NETLINK - return (set_nl(0, dst, &sdl_m, host)); + return (set_nl(dst, &sdl_m, host)); #else return (set_rtsock(dst, &sdl_m, host)); #endif @@ -458,7 +460,8 @@ get(char *host) xo_close_list("arp-cache"); xo_close_container("arp"); - xo_finish(); + if (xo_finish() < 0) + xo_err(1, "stdout"); return (found == 0); } @@ -533,7 +536,7 @@ delete(char *host) #ifdef WITHOUT_NETLINK return (delete_rtsock(host)); #else - return (delete_nl(0, host)); + return (delete_nl(host)); #endif } @@ -735,7 +738,7 @@ nuke_entries(uint32_t ifindex, struct in_addr addr) static void usage(void) { - fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", + xo_error("%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]", @@ -830,11 +833,11 @@ doit: } /* - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. + * get_ifinfo - get the hardware address and if_index of an interface + * on the same subnet as ipaddr. */ -static int -get_ether_addr(in_addr_t ipaddr, struct ether_addr *hwaddr) +int +get_ifinfo(in_addr_t ipaddr, struct ether_addr *hwaddr, uint32_t *pifindex) { struct ifaddrs *ifa, *ifd, *ifas = NULL; in_addr_t ina, mask; @@ -873,7 +876,13 @@ get_ether_addr(in_addr_t ipaddr, struct ether_addr *hwaddr) } if (ifa == NULL) goto done; - + if (pifindex != NULL) + *pifindex = if_nametoindex(ifa->ifa_name); + if (hwaddr == NULL) { + /* ether addr is not required */ + retval = ETHER_ADDR_LEN; + goto done; + } /* * Now scan through again looking for a link-level address * for this interface. |
