BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / netinet / in_pcb.c
index e2f7f9f..a7211cc 100644 (file)
@@ -1,9 +1,20 @@
 /*
  * Copyright (c) 1982, 1986 Regents of the University of California.
 /*
  * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * All rights reserved.
  *
  *
- *     @(#)in_pcb.c    7.1 (Berkeley) %G%
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)in_pcb.c    7.7 (Berkeley) 6/29/88
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -106,7 +117,7 @@ noname:
  * then pick one.
  */
 in_pcbconnect(inp, nam)
  * then pick one.
  */
 in_pcbconnect(inp, nam)
-       struct inpcb *inp;
+       register struct inpcb *inp;
        struct mbuf *nam;
 {
        struct in_ifaddr *ia;
        struct mbuf *nam;
 {
        struct in_ifaddr *ia;
@@ -145,34 +156,39 @@ in_pcbconnect(inp, nam)
                 */
                ro = &inp->inp_route;
                if (ro->ro_rt &&
                 */
                ro = &inp->inp_route;
                if (ro->ro_rt &&
-                   satosin(&ro->ro_dst)->sin_addr.s_addr !=
-                   sin->sin_addr.s_addr) {
+                   (satosin(&ro->ro_dst)->sin_addr.s_addr !=
+                       sin->sin_addr.s_addr || 
+                   inp->inp_socket->so_options & SO_DONTROUTE)) {
                        RTFREE(ro->ro_rt);
                        ro->ro_rt = (struct rtentry *)0;
                }
                if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
                    (ro->ro_rt == (struct rtentry *)0 ||
                        RTFREE(ro->ro_rt);
                        ro->ro_rt = (struct rtentry *)0;
                }
                if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
                    (ro->ro_rt == (struct rtentry *)0 ||
-                   (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0)) {
+                   ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
                        /* No route yet, so try to acquire one */
                        ro->ro_dst.sa_family = AF_INET;
                        ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
                                sin->sin_addr;
                        rtalloc(ro);
                        /* No route yet, so try to acquire one */
                        ro->ro_dst.sa_family = AF_INET;
                        ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
                                sin->sin_addr;
                        rtalloc(ro);
-                       /*
-                        * If we found a route, use the address
-                        * corresponding to the outgoing interface
-                        * unless it is the loopback (in case a route
-                        * to our address on another net goes to loopback).
-                        */
-                       if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp) &&
-                           (ifp->if_flags & IFF_LOOPBACK) == 0)
-                               for (ia = in_ifaddr; ia; ia = ia->ia_next)
-                                       if (ia->ia_ifp == ifp)
-                                               break;
                }
                }
+               /*
+                * If we found a route, use the address
+                * corresponding to the outgoing interface
+                * unless it is the loopback (in case a route
+                * to our address on another net goes to loopback).
+                */
+               if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp) &&
+                   (ifp->if_flags & IFF_LOOPBACK) == 0)
+                       for (ia = in_ifaddr; ia; ia = ia->ia_next)
+                               if (ia->ia_ifp == ifp)
+                                       break;
                if (ia == 0) {
                if (ia == 0) {
+                       int fport = sin->sin_port;
+
+                       sin->sin_port = 0;
                        ia = (struct in_ifaddr *)
                            ifa_ifwithdstaddr((struct sockaddr *)sin);
                        ia = (struct in_ifaddr *)
                            ifa_ifwithdstaddr((struct sockaddr *)sin);
+                       sin->sin_port = fport;
                        if (ia == 0)
                                ia = in_iaonnetof(in_netof(sin->sin_addr));
                        if (ia == 0)
                        if (ia == 0)
                                ia = in_iaonnetof(in_netof(sin->sin_addr));
                        if (ia == 0)
@@ -228,7 +244,7 @@ in_setsockaddr(inp, nam)
        register struct inpcb *inp;
        struct mbuf *nam;
 {
        register struct inpcb *inp;
        struct mbuf *nam;
 {
-       register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+       register struct sockaddr_in *sin;
        
        nam->m_len = sizeof (*sin);
        sin = mtod(nam, struct sockaddr_in *);
        
        nam->m_len = sizeof (*sin);
        sin = mtod(nam, struct sockaddr_in *);
@@ -239,10 +255,10 @@ in_setsockaddr(inp, nam)
 }
 
 in_setpeeraddr(inp, nam)
 }
 
 in_setpeeraddr(inp, nam)
-       register struct inpcb *inp;
+       struct inpcb *inp;
        struct mbuf *nam;
 {
        struct mbuf *nam;
 {
-       register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+       register struct sockaddr_in *sin;
        
        nam->m_len = sizeof (*sin);
        sin = mtod(nam, struct sockaddr_in *);
        
        nam->m_len = sizeof (*sin);
        sin = mtod(nam, struct sockaddr_in *);