changeset 4300:82a8e37ab298 draft

Workaround NetBSD-7 sending an invalid bcast address in RTM_NEWADDR
author Roy Marples <roy@marples.name>
date Fri, 17 Aug 2018 17:29:30 +0100
parents ff2791d0bac1
children 79099257b0ce
files src/if-bsd.c
diffstat 1 files changed, 23 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/if-bsd.c	Fri Aug 17 17:21:40 2018 +0100
+++ b/src/if-bsd.c	Fri Aug 17 17:29:30 2018 +0100
@@ -1103,9 +1103,32 @@
 		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