BSD 4_4 release
[unix-history] / usr / src / sys / netinet / in.c
index a43bd5d..cee7e8a 100644 (file)
@@ -1,10 +1,36 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1991 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)in.c        7.31 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)in.c        8.1 (Berkeley) 6/10/93
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
+#include <netinet/if_ether.h>
 
 #ifdef INET
 
 #ifdef INET
-/*
- * Formulate an Internet address from network + host.
- */
-struct in_addr
-in_makeaddr(net, host)
-       u_long net, host;
-{
-       register struct in_ifaddr *ia;
-       register u_long mask;
-       u_long addr;
-
-       if (IN_CLASSA(net))
-               mask = IN_CLASSA_HOST;
-       else if (IN_CLASSB(net))
-               mask = IN_CLASSB_HOST;
-       else
-               mask = IN_CLASSC_HOST;
-       for (ia = in_ifaddr; ia; ia = ia->ia_next)
-               if ((ia->ia_netmask & net) == ia->ia_net) {
-                       mask = ~ia->ia_subnetmask;
-                       break;
-               }
-       addr = htonl(net | (host & mask));
-       return (*(struct in_addr *)&addr);
-}
-
 /*
  * Return the network number from an internet address.
  */
 /*
  * Return the network number from an internet address.
  */
@@ -81,53 +82,6 @@ in_netof(in)
        return (net);
 }
 
        return (net);
 }
 
-/*
- * Compute and save network mask as sockaddr from an internet address.
- */
-in_sockmaskof(in, sockmask)
-       struct in_addr in;
-       register struct sockaddr_in *sockmask;
-{
-       register u_long net;
-       register u_long mask;
-    {
-       register u_long i = ntohl(in.s_addr);
-
-       if (i == 0)
-               net = 0, mask = 0;
-       else if (IN_CLASSA(i))
-               net = i & IN_CLASSA_NET, mask = IN_CLASSA_NET;
-       else if (IN_CLASSB(i))
-               net = i & IN_CLASSB_NET, mask = IN_CLASSB_NET;
-       else if (IN_CLASSC(i))
-               net = i & IN_CLASSC_NET, mask = IN_CLASSC_NET;
-       else
-               net = i, mask = -1;
-    }
-    {
-       register struct in_ifaddr *ia;
-       /*
-        * Check whether network is a subnet;
-        * if so, return subnet number.
-        */
-       for (ia = in_ifaddr; ia; ia = ia->ia_next)
-               if (net == ia->ia_net)
-                       mask =  ia->ia_subnetmask;
-    }
-    {
-       register char *cpbase = (char *)&(sockmask->sin_addr);
-       register char *cp = (char *)(1 + &(sockmask->sin_addr));
-
-       sockmask->sin_addr.s_addr = htonl(mask);
-       sockmask->sin_len = 0;
-       while (--cp >= cpbase)
-               if (*cp) {
-                       sockmask->sin_len = 1 + cp - (caddr_t)sockmask;
-                       break;
-               }
-    }
-}
-
 #ifndef SUBNETSARELOCAL
 #define        SUBNETSARELOCAL 1
 #endif
 #ifndef SUBNETSARELOCAL
 #define        SUBNETSARELOCAL 1
 #endif
@@ -423,6 +377,7 @@ in_control(so, cmd, data, ifp)
 /*
  * Delete any existing route for an interface.
  */
 /*
  * Delete any existing route for an interface.
  */
+void
 in_ifscrub(ifp, ia)
        register struct ifnet *ifp;
        register struct in_ifaddr *ia;
 in_ifscrub(ifp, ia)
        register struct ifnet *ifp;
        register struct in_ifaddr *ia;
@@ -450,7 +405,6 @@ in_ifinit(ifp, ia, sin, scrub)
        register u_long i = ntohl(sin->sin_addr.s_addr);
        struct sockaddr_in oldaddr;
        int s = splimp(), flags = RTF_UP, error, ether_output();
        register u_long i = ntohl(sin->sin_addr.s_addr);
        struct sockaddr_in oldaddr;
        int s = splimp(), flags = RTF_UP, error, ether_output();
-       void arp_rtrequest();
 
        oldaddr = ia->ia_addr;
        ia->ia_addr = *sin;
 
        oldaddr = ia->ia_addr;
        ia->ia_addr = *sin;
@@ -481,14 +435,18 @@ in_ifinit(ifp, ia, sin, scrub)
                ia->ia_netmask = IN_CLASSB_NET;
        else
                ia->ia_netmask = IN_CLASSC_NET;
                ia->ia_netmask = IN_CLASSB_NET;
        else
                ia->ia_netmask = IN_CLASSC_NET;
-       ia->ia_net = i & ia->ia_netmask;
        /*
        /*
-        * The subnet mask includes at least the standard network part,
-        * but may already have been set to a larger value.
+        * The subnet mask usually includes at least the standard network part,
+        * but may may be smaller in the case of supernetting.
+        * If it is set, we believe it.
         */
         */
-       ia->ia_subnetmask |= ia->ia_netmask;
+       if (ia->ia_subnetmask == 0) {
+               ia->ia_subnetmask = ia->ia_netmask;
+               ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
+       } else
+               ia->ia_netmask &= ia->ia_subnetmask;
+       ia->ia_net = i & ia->ia_netmask;
        ia->ia_subnet = i & ia->ia_subnetmask;
        ia->ia_subnet = i & ia->ia_subnetmask;
-       ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
        in_socktrim(&ia->ia_sockmask);
        /*
         * Add route for the network.
        in_socktrim(&ia->ia_sockmask);
        /*
         * Add route for the network.
@@ -553,7 +511,7 @@ in_broadcast(in, ifp)
                      */
                     t == ia->ia_subnet || t == ia->ia_net))
                            return 1;
                      */
                     t == ia->ia_subnet || t == ia->ia_net))
                            return 1;
-       return 0;
+       return (0);
 #undef ia
 }
 /*
 #undef ia
 }
 /*