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)