diff options
| author | Roy Marples <roy@marples.name> | 2020-06-24 20:53:20 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-06-24 20:53:20 +0100 |
| commit | 5a71bb4136183dda7a06828b7d4b515fe25d953f (patch) | |
| tree | 557df68bb78477b140cc2858afcab835bb20a702 /src/if.c | |
| parent | 449ed1897e27251f0c09cd6729aed93462f32d42 (diff) | |
| download | dhcpcd-5a71bb4136183dda7a06828b7d4b515fe25d953f.tar.xz | |
Linux: restore fix when no address is returned by getifaddrs(3)
Suck sucky sucky, but it fixes PPP links again.
Diffstat (limited to 'src/if.c')
| -rw-r--r-- | src/if.c | 78 |
1 files changed, 52 insertions, 26 deletions
@@ -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 */ |
