Re: ia_sockmask.sin_family is not set correctly

Ido <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
On 2026-06-18, Claudio Jeker wrote:
> In BSD the netmask was normally all 0xff apart from the sa_len.
> This comes from the time where all netmasks were shared amongst all
> address families.
> 
> In general the sa_family value of the address should be used for the
> netmask sockaddr. Also be aware that on some systems the returned buffer
> may be shorter than the AF specific sockaddr struct.
> 
> So if you really want cross platform then you need to handle that in
> userland. It may still make sense to improve the exported values by
> getifaddrs(3).

Thanks for the explanation and for taking the time to look into this.

> Your diff is certainly not complete. There are a fair amount of other
> places where ia_sockmask is adjusted that would also need such a fix.

The updated diff below covers all the assignments of ia_sockmask, apart from
the one in if_pppx.c which already sets the sin_family field correctly.

However, I suspect it might actually be sufficient to set it only in the two
	if (ai == NULL) {
	}
blocks, in in_ioctl_set_ifaddr() and in_ioctl_change_ifaddr() where we allocate
a new in_ifaddr. I'll follow up with an alternative diff that does just that.

---
Ido

diff --git sys/netinet/in.c sys/netinet/in.c
index 4edd8573071..7199345e3f7 100644
--- sys/netinet/in.c
+++ sys/netinet/in.c
@@ -345,6 +345,7 @@ in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
 			error = EINVAL;
 			break;
 		}
+		ia->ia_sockmask.sin_family = AF_INET;
 		ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
 		    sin->sin_addr.s_addr;
 		break;
@@ -390,7 +391,9 @@ in_ioctl_set_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp)
 		ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
 		ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
 		ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
+		ia->ia_sockmask.sin_family = AF_INET;
 		ia->ia_sockmask.sin_len = 8;
+
 		if (ifp->if_flags & IFF_BROADCAST) {
 			ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
 			ia->ia_broadaddr.sin_family = AF_INET;
@@ -484,6 +487,7 @@ in_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp)
 			ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
 			ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
 			ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
+			ia->ia_sockmask.sin_family = AF_INET;
 			ia->ia_sockmask.sin_len = 8;
 			if (ifp->if_flags & IFF_BROADCAST) {
 				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
@@ -503,6 +507,7 @@ in_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp)
 		}
 		if (masksin != NULL) {
 			in_ifscrub(ifp, ia);
+			ia->ia_sockmask.sin_family = AF_INET;
 			ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
 			    masksin->sin_addr.s_addr;
 			needinit = 1;
@@ -668,6 +673,7 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
 			ia->ia_netmask = IN_CLASSB_NET;
 		else
 			ia->ia_netmask = IN_CLASSC_NET;
+		ia->ia_sockmask.sin_family = AF_INET;
 		ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask;
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.