summaryrefslogtreecommitdiffstats
path: root/src/if.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-08-20 22:59:47 +0100
committerRoy Marples <roy@marples.name>2019-08-20 22:59:47 +0100
commitc47c788594840e177f4409c084336e467ac651f9 (patch)
tree8d1fc415a46aa3ae35af17994662e8d72b9d653c /src/if.c
parentf6fad76175efa3e561b265b5a765b79c4acc2048 (diff)
downloaddhcpcd-c47c788594840e177f4409c084336e467ac651f9.tar.xz
Linux: Add support for ARPHRD_NONE
So apprently I've been doing this wrong for years - on glibc at least, getifaddrs(3) never reported a hardware address for AF_PACKET addresses. Infact, it reported nothing but useless stats in ifa_data. I view this as a bug because SIOCGIFHWADDR will get a sockaddr with a sa_family set correctly. getifaddrs should do the same. Anyway, if we have the ioctl and no address for the AF_PACKET "address", call upon the above ioctl to get the correct family for the interface. While here, replace if_nametoindex with an ioctl to save libc from doing it for us.
Diffstat (limited to 'src/if.c')
-rw-r--r--src/if.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/if.c b/src/if.c
index 857294ef..d9f5d19f 100644
--- a/src/if.c
+++ b/src/if.c
@@ -307,17 +307,16 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
struct if_spec spec;
#ifdef AF_LINK
const struct sockaddr_dl *sdl;
-#ifdef SIOCGIFPRIORITY
- struct ifreq ifr;
-#endif
#ifdef IFLR_ACTIVE
struct if_laddrreq iflr = { .flags = IFLR_PREFIX };
int link_fd;
#endif
-
#elif AF_PACKET
const struct sockaddr_ll *sll;
#endif
+#if defined(SIOCGIFPRIORITY) || defined(SIOCGIFHWADDR)
+ struct ifreq ifr;
+#endif
if ((ifs = malloc(sizeof(*ifs))) == NULL) {
logerr(__func__);
@@ -512,10 +511,18 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen);
#endif
}
-#ifdef __linux__
- /* PPP addresses on Linux don't have hardware addresses */
- else
- ifp->index = if_nametoindex(ifp->name);
+#ifdef SIOCGIFHWADDR
+ else {
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, ifa->ifa_name,
+ sizeof(ifr.ifr_name));
+ if (ioctl(ctx->pf_inet_fd, SIOCGIFHWADDR, &ifr) == -1)
+ logerr("%s: SIOCGIFHWADDR", ifa->ifa_name);
+ ifp->family = ifr.ifr_hwaddr.sa_family;
+ if (ioctl(ctx->pf_inet_fd, SIOCGIFINDEX, &ifr) == -1)
+ logerr("%s: SIOCGIFINDEX", ifa->ifa_name);
+ ifp->index = (unsigned int)ifr.ifr_ifindex;
+ }
#endif
/* Ensure hardware address is valid. */
@@ -528,9 +535,6 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
ctx->ifac == 0 && !if_hasconf(ctx, ifp->name))
active = IF_INACTIVE;
switch (ifp->family) {
-#ifdef ARPHRD_NETROM
- case ARPHRD_NETROM:
-#endif
case ARPHRD_IEEE1394:
case ARPHRD_INFINIBAND:
#ifdef ARPHRD_LOOPBACK
@@ -539,6 +543,9 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
#ifdef ARPHRD_PPP
case ARPHRD_PPP:
#endif
+#ifdef ARPHRD_NONE
+ case ARPHRD_NONE:
+#endif
/* We don't warn for supported families */
break;