summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2018-08-17 17:29:30 +0100
committerRoy Marples <roy@marples.name>2018-08-17 17:29:30 +0100
commit979edac94001df12f2a29182192cdb1757b6f547 (patch)
tree7011bf5fac4614f891e6341c47cf57ce8d8dfc17
parentb4a256853454a132a198caf39442db189e7752b1 (diff)
downloaddhcpcd-979edac94001df12f2a29182192cdb1757b6f547.tar.xz
Workaround NetBSD-7 sending an invalid bcast address in RTM_NEWADDR
-rw-r--r--src/if-bsd.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/if-bsd.c b/src/if-bsd.c
index c3c95ba6..477dfd6b 100644
--- a/src/if-bsd.c
+++ b/src/if-bsd.c
@@ -1103,9 +1103,32 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
sin = (const void *)rti_info[RTAX_NETMASK];
mask.s_addr = sin != NULL && sin->sin_family == AF_INET ?
sin->sin_addr.s_addr : INADDR_ANY;
+
+#if defined(__NetBSD_Version__) && __NetBSD_Version__ < 800000000
+ /* NetBSD-7 and older send an invalid broadcast address.
+ * So we need to query the actual address to get
+ * the right one. */
+ {
+ struct in_aliasreq ifra;
+
+ memset(&ifra, 0, sizeof(ifra));
+ strlcpy(ifra.ifra_name, ifp->name,
+ sizeof(ifra.ifra_name));
+ ifra.ifra_addr.sin_family = AF_INET;
+ ifra.ifra_addr.sin_len = sizeof(ifra.ifra_addr);
+ ifra.ifra_addr.sin_addr = addr;
+ if (ioctl(ctx->pf_inet_fd, SIOCGIFALIAS, &ifra) == -1) {
+ if (errno != EADDRNOTAVAIL)
+ logerr("%s: SIOCGIFALIAS", __func__);
+ break;
+ }
+ bcast = ifra.ifra_broadaddr.sin_addr;
+ }
+#else
sin = (const void *)rti_info[RTAX_BRD];
bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ?
sin->sin_addr.s_addr : INADDR_ANY;
+#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
/* FreeBSD sends RTM_DELADDR for each assigned address