summaryrefslogtreecommitdiffstats
path: root/src/if.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-06-24 20:53:20 +0100
committerRoy Marples <roy@marples.name>2020-06-24 20:53:20 +0100
commit5a71bb4136183dda7a06828b7d4b515fe25d953f (patch)
tree557df68bb78477b140cc2858afcab835bb20a702 /src/if.c
parent449ed1897e27251f0c09cd6729aed93462f32d42 (diff)
downloaddhcpcd-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.c78
1 files changed, 52 insertions, 26 deletions
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 */