changeset 5389:188a969d672e draft

Linux: restore fix when no address is returned by getifaddrs(3) Suck sucky sucky, but it fixes PPP links again.
author Roy Marples <roy@marples.name>
date Wed, 24 Jun 2020 20:53:20 +0100
parents 9bb47d579f62
children 3c3341010852
files src/if.c
diffstat 1 files changed, 52 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/if.c	Tue Jun 23 11:31:25 2020 +0100
+++ b/src/if.c	Wed Jun 24 20:53:20 2020 +0100
@@ -386,6 +386,39 @@
 	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 @@
 			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 */