From: Roy Marples Date: Wed, 24 Jun 2020 19:53:20 +0000 (+0100) Subject: Linux: restore fix when no address is returned by getifaddrs(3) X-Git-Tag: v9.1.3~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a71bb4136183dda7a06828b7d4b515fe25d953f;p=thirdparty%2Fdhcpcd.git Linux: restore fix when no address is returned by getifaddrs(3) Suck sucky sucky, but it fixes PPP links again. --- diff --git a/src/if.c b/src/if.c index f867cd59..d711542a 100644 --- a/src/if.c +++ b/src/if.c @@ -386,6 +386,39 @@ if_valid_hwaddr(const uint8_t *hwaddr, size_t hwlen) return false; } +#if defined(AF_PACKET) && !defined(AF_LINK) +static unsigned int +if_check_arphrd(struct interface *ifp, unsigned int active, bool if_noconf) +{ + + switch(ifp->hwtype) { + case ARPHRD_ETHER: /* FALLTHROUGH */ + case ARPHRD_IEEE1394: /* FALLTHROUGH */ + case ARPHRD_INFINIBAND: /* FALLTHROUGH */ + case ARPHRD_NONE: /* FALLTHROUGH */ + break; + case ARPHRD_LOOPBACK: + case ARPHRD_PPP: + if (if_noconf) { + logdebugx("%s: ignoring due to interface type and" + " no config", + ifp->name); + active = IF_INACTIVE; + } + break; + default: + if (if_noconf) + active = IF_INACTIVE; + if (active) + logwarnx("%s: unsupported interface type 0x%.2x", + ifp->name, ifp->hwtype); + break; + } + + return active; +} +#endif + struct if_head * if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs, int argc, char * const *argv) @@ -597,34 +630,27 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs, ifp->hwlen = sll->sll_halen; if (ifp->hwlen != 0) memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen); - - switch(ifp->hwtype) { - case ARPHRD_ETHER: /* FALLTHROUGH */ - case ARPHRD_IEEE1394: /* FALLTHROUGH */ - case ARPHRD_INFINIBAND: /* FALLTHROUGH */ - case ARPHRD_NONE: /* FALLTHROUGH */ - break; - case ARPHRD_LOOPBACK: - case ARPHRD_PPP: - if (if_noconf) { - logdebugx("%s: ignoring due to" - " interface type and" - " no config", - ifp->name); - active = IF_INACTIVE; - } - break; - default: - if (if_noconf) - active = IF_INACTIVE; - if (active) - logwarnx("%s: unsupported" - " interface type 0x%.2x", - ifp->name, ifp->hwtype); - break; - } + active = if_check_arphrd(ifp, active, if_noconf); #endif } +#ifdef __linux__ + else { + struct ifreq ifr = { .ifr_flags = 0 }; + + /* This is a huge bug in getifaddrs(3) as there + * is no reason why this can't be returned in + * ifa_addr. */ + 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->hwtype = 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; + if_check_arphrd(ifp, active, if_noconf); + } +#endif if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) { /* Handle any platform init for the interface */