in_pcblookup() is always called with *:0 for the remote side.
Remove the useless bits, shuffle the tests around and it's much
easier to audit.

Ok ?

Index: netinet/in_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.201
diff -u -p -r1.201 in_pcb.c
--- netinet/in_pcb.c    8 Apr 2016 14:34:21 -0000       1.201
+++ netinet/in_pcb.c    9 Apr 2016 09:42:07 -0000
@@ -415,14 +415,13 @@ in_pcbaddrisavail(struct inpcb *inp, str
                struct inpcb *t;
 
                if (so->so_euid) {
-                       t = in_pcblookup(table, &zeroin_addr, 0,
-                           &sin->sin_addr, lport, INPLOOKUP_WILDCARD,
-                           inp->inp_rtableid);
+                       t = in_pcblookup_local(table, &sin->sin_addr, lport,
+                           INPLOOKUP_WILDCARD, inp->inp_rtableid);
                        if (t && (so->so_euid != t->inp_socket->so_euid))
                                return (EADDRINUSE);
                }
-               t = in_pcblookup(table, &zeroin_addr, 0,
-                   &sin->sin_addr, lport, wild, inp->inp_rtableid);
+               t = in_pcblookup_local(table, &sin->sin_addr, lport,
+                   wild, inp->inp_rtableid);
                if (t && (reuseport & t->inp_socket->so_options) == 0)
                        return (EADDRINUSE);
        }
@@ -475,8 +474,8 @@ in_pcbpickport(u_int16_t *lport, void *l
                        candidate = lower;
                localport = htons(candidate);
        } while (in_baddynamic(localport, so->so_proto->pr_protocol) ||
-           in_pcblookup(table, &zeroin46_addr, 0,
-           laddr, localport, wild, inp->inp_rtableid));
+           in_pcblookup_local(table, laddr, localport, wild,
+           inp->inp_rtableid));
        *lport = localport;
 
        return (0);
@@ -734,14 +733,14 @@ in_rtchange(struct inpcb *inp, int errno
 }
 
 struct inpcb *
-in_pcblookup(struct inpcbtable *table, void *faddrp, u_int fport_arg,
-    void *laddrp, u_int lport_arg, int flags, u_int rdomain)
+in_pcblookup_local(struct inpcbtable *table, void *laddrp, u_int lport_arg,
+    int flags, u_int rdomain)
 {
        struct inpcb *inp, *match = NULL;
        int matchwild = 3, wildcard;
-       u_int16_t fport = fport_arg, lport = lport_arg;
-       struct in_addr faddr = *(struct in_addr *)faddrp;
+       u_int16_t lport = lport_arg;
        struct in_addr laddr = *(struct in_addr *)laddrp;
+       struct in6_addr *laddr6 = (struct in6_addr *)laddrp;
        struct inpcbhead *head;
 
        rdomain = rtable_l2(rdomain);   /* convert passed rtableid to rdomain */
@@ -753,60 +752,40 @@ in_pcblookup(struct inpcbtable *table, v
                        continue;
                wildcard = 0;
 #ifdef INET6
-               if (flags & INPLOOKUP_IPV6) {
-                       struct in6_addr *laddr6 = (struct in6_addr *)laddrp;
-                       struct in6_addr *faddr6 = (struct in6_addr *)faddrp;
-
-                       if (!(inp->inp_flags & INP_IPV6))
+               if (ISSET(flags, INPLOOKUP_IPV6)) {
+                       if (!ISSET(inp->inp_flags, INP_IPV6))
                                continue;
 
-                       if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) {
-                               if (IN6_IS_ADDR_UNSPECIFIED(laddr6))
-                                       wildcard++;
-                               else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, 
laddr6))
-                                       continue;
-                       } else {
-                               if (!IN6_IS_ADDR_UNSPECIFIED(laddr6))
-                                       wildcard++;
-                       }
+                       if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
+                               wildcard++;
 
-                       if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
-                               if (IN6_IS_ADDR_UNSPECIFIED(faddr6))
+                       if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr6)) {
+                               if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) ||
+                                   IN6_IS_ADDR_UNSPECIFIED(laddr6))
                                        wildcard++;
-                               else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6,
-                                   faddr6) || inp->inp_fport != fport)
+                               else
                                        continue;
-                       } else {
-                               if (!IN6_IS_ADDR_UNSPECIFIED(faddr6))
-                                       wildcard++;
                        }
+
                } else
 #endif /* INET6 */
                {
 #ifdef INET6
-                       if (inp->inp_flags & INP_IPV6)
+                       if (ISSET(inp->inp_flags, INP_IPV6))
                                continue;
 #endif /* INET6 */
 
-                       if (inp->inp_faddr.s_addr != INADDR_ANY) {
-                               if (faddr.s_addr == INADDR_ANY)
-                                       wildcard++;
-                               else if (inp->inp_faddr.s_addr != faddr.s_addr 
||
-                                   inp->inp_fport != fport)
-                                       continue;
-                       } else {
-                               if (faddr.s_addr != INADDR_ANY)
-                                       wildcard++;
-                       }
-                       if (inp->inp_laddr.s_addr != INADDR_ANY) {
-                               if (laddr.s_addr == INADDR_ANY)
+                       if (inp->inp_faddr.s_addr != INADDR_ANY)
+                               wildcard++;
+
+                       if (inp->inp_laddr.s_addr != laddr.s_addr) {
+                               if (inp->inp_laddr.s_addr == INADDR_ANY ||
+                                   laddr.s_addr == INADDR_ANY)
                                        wildcard++;
-                               else if (inp->inp_laddr.s_addr != laddr.s_addr)
+                               else
                                        continue;
-                       } else {
-                               if (laddr.s_addr != INADDR_ANY)
-                                       wildcard++;
                        }
+
                }
                if ((!wildcard || (flags & INPLOOKUP_WILDCARD)) &&
                    wildcard < matchwild) {
Index: netinet/in_pcb.h
===================================================================
RCS file: /cvs/src/sys/netinet/in_pcb.h,v
retrieving revision 1.97
diff -u -p -r1.97 in_pcb.h
--- netinet/in_pcb.h    5 Apr 2016 19:34:05 -0000       1.97
+++ netinet/in_pcb.h    9 Apr 2016 09:42:07 -0000
@@ -271,8 +271,7 @@ int  in6_setpeeraddr(struct inpcb *, str
 #endif /* INET6 */
 void    in_pcbinit(struct inpcbtable *, int);
 struct inpcb *
-        in_pcblookup(struct inpcbtable *, void *, u_int, void *,
-           u_int, int, u_int);
+        in_pcblookup_local(struct inpcbtable *, void *, u_int, int, u_int);
 void    in_pcbnotifyall(struct inpcbtable *, struct sockaddr *,
            u_int, int, void (*)(struct inpcb *, int));
 void    in_pcbrehash(struct inpcb *);
Index: netinet6/in6_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.91
diff -u -p -r1.91 in6_pcb.c
--- netinet6/in6_pcb.c  5 Apr 2016 21:21:41 -0000       1.91
+++ netinet6/in6_pcb.c  9 Apr 2016 09:42:08 -0000
@@ -217,16 +217,14 @@ in6_pcbaddrisavail(struct inpcb *inp, st
                struct inpcb *t;
 
                if (so->so_euid) {
-                       t = in_pcblookup(table,
-                           (struct in_addr *)&zeroin6_addr, 0,
+                       t = in_pcblookup_local(table,
                            (struct in_addr *)&sin6->sin6_addr, lport,
                            INPLOOKUP_WILDCARD | INPLOOKUP_IPV6,
                            inp->inp_rtableid);
                        if (t && (so->so_euid != t->inp_socket->so_euid))
                                return (EADDRINUSE);
                }
-               t = in_pcblookup(table,
-                   (struct in_addr *)&zeroin6_addr, 0,
+               t = in_pcblookup_local(table,
                    (struct in_addr *)&sin6->sin6_addr, lport,
                    wild, inp->inp_rtableid);
                if (t && (reuseport & t->inp_socket->so_options) == 0)

Reply via email to