Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/arp Add an "auto" keyword to auto-determine the lin...
details: https://anonhg.NetBSD.org/src/rev/1c455326a067
branches: trunk
changeset: 324476:1c455326a067
user: christos <christos%NetBSD.org@localhost>
date: Fri Jul 06 00:50:05 2018 +0000
description:
Add an "auto" keyword to auto-determine the link address from the inet addr.
diffstat:
usr.sbin/arp/arp.8 | 12 +++++++-
usr.sbin/arp/arp.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 70 insertions(+), 10 deletions(-)
diffs (156 lines):
diff -r 8ab574fa7df8 -r 1c455326a067 usr.sbin/arp/arp.8
--- a/usr.sbin/arp/arp.8 Thu Jul 05 19:46:58 2018 +0000
+++ b/usr.sbin/arp/arp.8 Fri Jul 06 00:50:05 2018 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: arp.8,v 1.23 2013/07/08 04:31:12 apb Exp $
+.\" $NetBSD: arp.8,v 1.24 2018/07/06 00:50:05 christos Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)arp.8 8.2 (Berkeley) 4/27/95
.\"
-.Dd July 8, 2013
+.Dd July 5, 2018
.Dt ARP 8
.Os
.Sh NAME
@@ -132,11 +132,19 @@
responding to requests for
.Ar hostname
even though the host address is not its own.
+.Pp
If the word
.Cm proxy
is also given, the published entry will be a
.Dq proxy only
entry.
+In this case the
+.Ar ether_addr
+can be given as
+.Cm auto
+in which case the interfaces on this host will be examined,
+and if one of them is found to occupy the same subnet, its
+Ethernet address will be used.
.It Fl v
Display verbose information when adding or deleting
.Tn ARP
diff -r 8ab574fa7df8 -r 1c455326a067 usr.sbin/arp/arp.c
--- a/usr.sbin/arp/arp.c Thu Jul 05 19:46:58 2018 +0000
+++ b/usr.sbin/arp/arp.c Fri Jul 06 00:50:05 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arp.c,v 1.59 2018/06/08 04:24:12 nonaka Exp $ */
+/* $NetBSD: arp.c,v 1.60 2018/07/06 00:50:05 christos Exp $ */
/*
* Copyright (c) 1984, 1993
@@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)arp.c 8.3 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: arp.c,v 1.59 2018/06/08 04:24:12 nonaka Exp $");
+__RCSID("$NetBSD: arp.c,v 1.60 2018/07/06 00:50:05 christos Exp $");
#endif
#endif /* not lint */
@@ -84,14 +84,14 @@
static void delete(const char *, const char *);
static void sdl_print(const struct sockaddr_dl *);
static int getifname(u_int16_t, char *, size_t);
-static int atosdl(const char *s, struct sockaddr_dl *sdl);
+static int atosdl(const char *, struct sockaddr_dl *);
static int file(const char *);
static void get(const char *);
static int getinetaddr(const char *, struct in_addr *);
static int getsocket(void);
-static struct rt_msghdr *
- rtmsg(const int, const int, struct rt_msghdr *,
- const struct sockaddr_inarp *, const struct sockaddr_dl *);
+static int getetheraddr(struct in_addr, struct sockaddr_dl *);
+static struct rt_msghdr * rtmsg(const int, const int, struct rt_msghdr *,
+ const struct sockaddr_inarp *, const struct sockaddr_dl *);
static int set(int, char **);
static void usage(void) __dead;
@@ -278,7 +278,7 @@
if (getinetaddr(host, &sin_m.sin_addr) == -1)
return (1);
- if (atosdl(eaddr, &sdl_m))
+ if (!strcmp(eaddr, "auto") && atosdl(eaddr, &sdl_m))
warnx("invalid link-level address '%s'", eaddr);
doing_proxy = flags = export_only = expire_time = 0;
for (; argc-- > 0; argv++) {
@@ -309,6 +309,10 @@
}
}
+ if (doing_proxy && !strcmp(eaddr, "auto")) {
+ if (getetheraddr(sin_m.sin_addr, &sdl_m) == -1)
+ return 1;
+ }
tryagain:
rtm = rtmsg(s, RTM_GET, NULL, &sin_m, &sdl_m);
if (rtm == NULL) {
@@ -706,7 +710,7 @@
{
int i;
struct ifaddrs *addr;
- const struct sockaddr_dl *sdl = NULL;
+ const struct sockaddr_dl *sdl;
static struct ifaddrs* ifaddrs = NULL;
if (ifaddrs == NULL) {
@@ -729,3 +733,51 @@
return -1;
}
+
+static int
+getetheraddr(struct in_addr ipaddr, struct sockaddr_dl *sdl)
+{
+ struct ifaddrs *ifaddrs, *addr;
+ in_addr_t ina, mask;
+ char ifname[IFNAMSIZ];
+
+ if (getifaddrs(&ifaddrs) != 0) {
+ warn("getifaddrs");
+ return -1;
+ }
+
+ for (addr = ifaddrs; addr; addr = addr->ifa_next) {
+ if (addr->ifa_addr == NULL ||
+ addr->ifa_addr->sa_family != AF_INET)
+ continue;
+ if ((addr->ifa_flags & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|
+ IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP|IFF_BROADCAST))
+ continue;
+
+ mask = ((struct sockaddr_in *)(void *)addr->ifa_netmask)->sin_addr.s_addr;
+ ina = ((struct sockaddr_in *)(void *)addr->ifa_addr)->sin_addr.s_addr;
+ if ((ipaddr.s_addr & mask) != (ina & mask))
+ continue;
+ strlcpy(ifname, addr->ifa_name, sizeof(ifname));
+ break;
+ }
+ if (addr == NULL) {
+ warnx("No interface matched %s", inet_ntoa(ipaddr));
+ freeifaddrs(ifaddrs);
+ return -1;
+ }
+
+ for (addr = ifaddrs; addr; addr = addr->ifa_next) {
+ if (addr->ifa_addr == NULL ||
+ addr->ifa_addr->sa_family != AF_LINK)
+ continue;
+ if (strcmp(ifname, addr->ifa_name) != 0)
+ continue;
+ memcpy(sdl, addr->ifa_addr, sizeof(*sdl));
+ freeifaddrs(ifaddrs);
+ return 0;
+ }
+ warnx("No link address for interface %s", ifname);
+ freeifaddrs(ifaddrs);
+ return -1;
+}
Home |
Main Index |
Thread Index |
Old Index