On Mon, May 08, 2017 at 05:09:01PM +0200, Alexander Bluhm wrote: > Checking for IPv4 mapped addresses is a bit inconsistent in the > output path.
I should split the diff to make review easier. - Use the common switch(af) construct for af specific code in tcp_usrreq(PRU_CONNECT). - Do not access sockaddr_in before checking the address family. - Add a EAFNOSUPPORT default case. ok? bluhm Index: netinet/tcp_usrreq.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.147 diff -u -p -r1.147 tcp_usrreq.c --- netinet/tcp_usrreq.c 5 Apr 2017 13:35:18 -0000 1.147 +++ netinet/tcp_usrreq.c 12 May 2017 16:09:16 -0000 @@ -127,7 +127,6 @@ int tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct proc *p) { - struct sockaddr_in *sin; struct inpcb *inp; struct tcpcb *tp = NULL; int error = 0; @@ -221,33 +220,41 @@ tcp_usrreq(struct socket *so, int req, s * Send initial segment on connection. */ case PRU_CONNECT: - sin = mtod(nam, struct sockaddr_in *); - -#ifdef INET6 - if (sin->sin_family == AF_INET6) { - struct in6_addr *in6_addr = &mtod(nam, - struct sockaddr_in6 *)->sin6_addr; - - if (IN6_IS_ADDR_UNSPECIFIED(in6_addr) || - IN6_IS_ADDR_MULTICAST(in6_addr) || - IN6_IS_ADDR_V4MAPPED(in6_addr)) { + switch (mtod(nam, struct sockaddr *)->sa_family) { + case AF_INET: { + struct in_addr *addr = + &mtod(nam, struct sockaddr_in *)->sin_addr; + + if ((addr->s_addr == INADDR_ANY) || + (addr->s_addr == INADDR_BROADCAST) || + IN_MULTICAST(addr->s_addr) || + in_broadcast(*addr, inp->inp_rtableid)) { error = EINVAL; break; } - error = in6_pcbconnect(inp, nam); - } else if (sin->sin_family == AF_INET) -#endif /* INET6 */ - { - if ((sin->sin_addr.s_addr == INADDR_ANY) || - (sin->sin_addr.s_addr == INADDR_BROADCAST) || - IN_MULTICAST(sin->sin_addr.s_addr) || - in_broadcast(sin->sin_addr, inp->inp_rtableid)) { + error = in_pcbconnect(inp, nam); + break; + } +#ifdef INET6 + case AF_INET6: { + struct in6_addr *addr6 = + &mtod(nam, struct sockaddr_in6 *)->sin6_addr; + + if (IN6_IS_ADDR_UNSPECIFIED(addr6) || + IN6_IS_ADDR_MULTICAST(addr6) || + IN6_IS_ADDR_V4MAPPED(addr6)) { error = EINVAL; break; } - error = in_pcbconnect(inp, nam); + error = in6_pcbconnect(inp, nam); + break; + } +#endif /* INET6 */ + default: + error = EAFNOSUPPORT; + break; } if (error)