diff options
| author | Roy Marples <roy@marples.name> | 2019-08-20 22:59:47 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2019-08-20 22:59:47 +0100 |
| commit | c47c788594840e177f4409c084336e467ac651f9 (patch) | |
| tree | 8d1fc415a46aa3ae35af17994662e8d72b9d653c /src/if.c | |
| parent | f6fad76175efa3e561b265b5a765b79c4acc2048 (diff) | |
| download | dhcpcd-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.c | 29 |
1 files changed, 18 insertions, 11 deletions
@@ -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; |
