new stats; change keepalives to use rcv_nxt instead of rcv_nxt-1
[unix-history] / usr / src / sys / netinet / in.c
index e40d7ed..b6e6f07 100644 (file)
@@ -1,9 +1,9 @@
 /*
 /*
- * Copyright (c) 1982 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.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)in.c        6.14 (Berkeley) %G%
+ *     @(#)in.c        7.3 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -155,7 +155,7 @@ in_localaddr(in)
                net = i & IN_CLASSC_NET;
 
        for (ia = in_ifaddr; ia; ia = ia->ia_next)
                net = i & IN_CLASSC_NET;
 
        for (ia = in_ifaddr; ia; ia = ia->ia_next)
-               if (net == subnetsarelocal ? ia->ia_net : ia->ia_subnet)
+               if (net == (subnetsarelocal ? ia->ia_net : ia->ia_subnet))
                        return (1);
        return (0);
 }
                        return (1);
        return (0);
 }
@@ -259,12 +259,25 @@ in_control(so, cmd, data, ifp)
                break;
 
        case SIOCSIFDSTADDR:
                break;
 
        case SIOCSIFDSTADDR:
+           {
+               struct sockaddr oldaddr;
+
                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
                        return (EINVAL);
                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
                        return (EINVAL);
+               oldaddr = ia->ia_dstaddr;
+               ia->ia_dstaddr = ifr->ifr_dstaddr;
                if (ifp->if_ioctl &&
                if (ifp->if_ioctl &&
-                   (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia)))
+                   (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) {
+                       ia->ia_dstaddr = oldaddr;
                        return (error);
                        return (error);
-               ia->ia_dstaddr = ifr->ifr_dstaddr;
+               }
+               if (ia->ia_flags & IFA_ROUTE) {
+                       rtinit(&oldaddr, &ia->ia_addr, (int)SIOCDELRT,
+                           RTF_HOST);
+                       rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
+                           RTF_HOST|RTF_UP);
+               }
+           }
                break;
 
        case SIOCSIFBRDADDR:
                break;
 
        case SIOCSIFBRDADDR:
@@ -304,10 +317,11 @@ in_ifinit(ifp, ia, sin)
        struct sockaddr_in *sin;
 {
        register u_long i = ntohl(sin->sin_addr.s_addr);
        struct sockaddr_in *sin;
 {
        register u_long i = ntohl(sin->sin_addr.s_addr);
-       struct sockaddr_in tmpaddr;
+       struct sockaddr oldaddr;
+       struct sockaddr_in netaddr;
        int s = splimp(), error;
 
        int s = splimp(), error;
 
-       tmpaddr = *(struct sockaddr_in *)&ia->ia_addr;
+       oldaddr = ia->ia_addr;
        ia->ia_addr = *(struct sockaddr *)sin;
 
        /*
        ia->ia_addr = *(struct sockaddr *)sin;
 
        /*
@@ -317,23 +331,27 @@ in_ifinit(ifp, ia, sin)
         */
        if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
                splx(s);
         */
        if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
                splx(s);
-               ia->ia_addr = *(struct sockaddr *)&tmpaddr;
+               ia->ia_addr = oldaddr;
                return (error);
        }
 
                return (error);
        }
 
-       bzero((caddr_t)&tmpaddr, sizeof (tmpaddr));
-       tmpaddr.sin_family = AF_INET;
        /*
         * Delete any previous route for an old address.
         */
        /*
         * Delete any previous route for an old address.
         */
+       bzero((caddr_t)&netaddr, sizeof (netaddr));
+       netaddr.sin_family = AF_INET;
        if (ia->ia_flags & IFA_ROUTE) {
        if (ia->ia_flags & IFA_ROUTE) {
-               if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
-                   tmpaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY);
-                   rtinit((struct sockaddr *)&tmpaddr, &ia->ia_addr, 
+               if (ifp->if_flags & IFF_LOOPBACK)
+                       rtinit(&oldaddr, &oldaddr, (int)SIOCDELRT, RTF_HOST);
+               else if (ifp->if_flags & IFF_POINTOPOINT)
+                       rtinit(&ia->ia_dstaddr, &oldaddr, (int)SIOCDELRT,
+                           RTF_HOST);
+               else {
+                       netaddr.sin_addr = in_makeaddr(ia->ia_subnet,
+                           INADDR_ANY);
+                       rtinit((struct sockaddr *)&netaddr, &oldaddr, 
                            (int)SIOCDELRT, 0);
                            (int)SIOCDELRT, 0);
-               } else
-                   rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr,
-                           (int)SIOCDELRT, RTF_HOST);
+               }
                ia->ia_flags &= ~IFA_ROUTE;
        }
        if (IN_CLASSA(i))
                ia->ia_flags &= ~IFA_ROUTE;
        }
        if (IN_CLASSA(i))
@@ -356,18 +374,22 @@ in_ifinit(ifp, ia, sin)
                ia->ia_netbroadcast.s_addr =
                    htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
        }
                ia->ia_netbroadcast.s_addr =
                    htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
        }
-       splx(s);
        /*
         * Add route for the network.
         */
        /*
         * Add route for the network.
         */
-       if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
-               tmpaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY);
-               rtinit((struct sockaddr *)&tmpaddr, &ia->ia_addr,
-                       (int)SIOCADDRT, RTF_UP);
-       } else
-               rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr,
-                       (int)SIOCADDRT, RTF_HOST|RTF_UP);
+       if (ifp->if_flags & IFF_LOOPBACK)
+               rtinit(&ia->ia_addr, &ia->ia_addr, (int)SIOCADDRT,
+                   RTF_HOST|RTF_UP);
+       else if (ifp->if_flags & IFF_POINTOPOINT)
+               rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
+                   RTF_HOST|RTF_UP);
+       else {
+               netaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY);
+               rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
+                   (int)SIOCADDRT, RTF_UP);
+       }
        ia->ia_flags |= IFA_ROUTE;
        ia->ia_flags |= IFA_ROUTE;
+       splx(s);
        return (0);
 }
 
        return (0);
 }
 
@@ -387,21 +409,30 @@ in_iaonnetof(net)
 }
 
 /*
 }
 
 /*
- * Return 1 if the address is a local broadcast address.
+ * Return 1 if the address might be a local broadcast address.
  */
 in_broadcast(in)
        struct in_addr in;
 {
        register struct in_ifaddr *ia;
  */
 in_broadcast(in)
        struct in_addr in;
 {
        register struct in_ifaddr *ia;
+       u_long t;
 
        /*
         * Look through the list of addresses for a match
         * with a broadcast address.
         */
        for (ia = in_ifaddr; ia; ia = ia->ia_next)
 
        /*
         * Look through the list of addresses for a match
         * with a broadcast address.
         */
        for (ia = in_ifaddr; ia; ia = ia->ia_next)
-           if (((struct sockaddr_in *)&ia->ia_broadaddr)->sin_addr.s_addr ==
-               in.s_addr && (ia->ia_ifp->if_flags & IFF_BROADCAST))
+           if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
+               if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == in.s_addr)
                     return (1);
                     return (1);
+               /*
+                * Check for old-style (host 0) broadcast.
+                */
+               if ((t = ntohl(in.s_addr)) == ia->ia_subnet || t == ia->ia_net)
+                   return (1);
+       }
+       if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY)
+               return (1);
        return (0);
 }
 #endif
        return (0);
 }
 #endif