move net addresses from interface to protocol layer;
[unix-history] / usr / src / sys / netinet / in.c
index 74108f6..8d49d62 100644 (file)
@@ -1,12 +1,12 @@
-/*     in.c    4.11    82/11/13        */
-
-#include "../h/param.h"
-#include "../h/mbuf.h"
-#include "../h/protosw.h"
-#include "../h/socket.h"
-#include "../h/socketvar.h"
-#include "../netinet/in.h"
-#include "../netinet/in_systm.h"
+/*     in.c    6.5     84/10/19        */
+
+#include "param.h"
+#include "mbuf.h"
+#include "protosw.h"
+#include "socket.h"
+#include "socketvar.h"
+#include "in.h"
+#include "in_systm.h"
 #include "../net/if.h"
 #include "../net/route.h"
 #include "../net/af.h"
 #include "../net/if.h"
 #include "../net/route.h"
 #include "../net/af.h"
@@ -25,7 +25,7 @@ inet_netmatch(sin1, sin2)
        struct sockaddr_in *sin1, *sin2;
 {
 
        struct sockaddr_in *sin1, *sin2;
 {
 
-       return (sin1->sin_addr.s_net == sin2->sin_addr.s_net);
+       return (in_netof(sin1->sin_addr) == in_netof(sin2->sin_addr));
 }
 
 /*
 }
 
 /*
@@ -38,9 +38,9 @@ if_makeaddr(net, host)
 {
        u_long addr;
 
 {
        u_long addr;
 
-       if (net < 128)
+       if (net < IN_CLASSA_MAX)
                addr = (net << IN_CLASSA_NSHIFT) | host;
                addr = (net << IN_CLASSA_NSHIFT) | host;
-       else if (net < 65536)
+       else if (net < IN_CLASSB_MAX)
                addr = (net << IN_CLASSB_NSHIFT) | host;
        else
                addr = (net << IN_CLASSC_NSHIFT) | host;
                addr = (net << IN_CLASSB_NSHIFT) | host;
        else
                addr = (net << IN_CLASSC_NSHIFT) | host;
@@ -55,13 +55,51 @@ in_netof(in)
        struct in_addr in;
 {
        register u_long i = ntohl(in.s_addr);
        struct in_addr in;
 {
        register u_long i = ntohl(in.s_addr);
+       register u_long net, subnet;
+       register struct ifnet *ifp;
 
 
-       if (IN_CLASSA(i))
-               return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
-       else if (IN_CLASSB(i))
-               return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
-       else
-               return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+       if (IN_CLASSA(i)) {
+               net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
+               if (IN_SUBNETA(i)) {
+                       subnet = (i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT;
+                       /* Fall through and check whether a subnet */
+               } else
+                       return (net);
+       } else if (IN_CLASSB(i)) {
+               net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
+               if (IN_SUBNETB(i)) {
+                       subnet = (i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT;
+                       /* Fall through and check whether a subnet */
+               } else
+                       return (net);
+       } else {
+               return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+       }
+
+       /*
+        * Check whether network is a subnet of a `local' network;
+        * if so, return subnet number.
+        */
+       for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+               if (ifp->if_addr.sa_family != AF_INET)
+                       continue;
+               if (ifp->if_flags & IFF_LOCAL) {
+                       if (ifp->if_net == net)
+                               return (subnet);
+                       if ((ifp->if_net >> SUBNETSHIFT) == net)
+                               return (subnet);
+                       /*
+                        * Hack for use in setting if_net initially.
+                        */
+                       if (ifp->if_net == 0) {
+                               register struct sockaddr_in *sin;
+                               sin = (struct sockaddr_in *) &ifp->if_addr;
+                               if (sin->sin_addr.s_addr == in.s_addr)
+                                       return (subnet);
+                       }
+               }
+       }
+       return (net);
 }
 
 /*
 }
 
 /*
@@ -71,13 +109,74 @@ in_lnaof(in)
        struct in_addr in;
 {
        register u_long i = ntohl(in.s_addr);
        struct in_addr in;
 {
        register u_long i = ntohl(in.s_addr);
+       register u_long net, host, subhost;
+       register struct ifnet *ifp;
+
+       if (IN_CLASSA(i)) {
+               if (IN_SUBNETA(i)) {
+                       net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
+                       host = i & IN_CLASSA_HOST;
+                       subhost = i & IN_CLASSA_SUBHOST;
+                       /* Fall through and check whether a subnet */
+               } else
+                       return (i & IN_CLASSA_HOST);
+       } else if (IN_CLASSB(i)) {
+               if (IN_SUBNETB(i)) {
+                       net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
+                       host = i & IN_CLASSB_HOST;
+                       subhost = i & IN_CLASSB_SUBHOST;
+                       /* Fall through and check whether a subnet */
+               } else
+                       return (i & IN_CLASSB_HOST);
+       } else {
+               return (i & IN_CLASSC_HOST);
+       }
+
+       /*
+        * Check whether network is a subnet of a `local' network;
+        * if so, use the modified interpretation of `host'.
+        */
+       for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+               if (ifp->if_addr.sa_family != AF_INET)
+                       continue;
+               if (ifp->if_flags & IFF_LOCAL) {
+                       if (ifp->if_net == net)
+                           return (subhost);
+                       if ((ifp->if_net >> SUBNETSHIFT) == net)
+                           return (subhost);
+               }
+       }
+       return (host);
+}
+
+/*
+ * Return 1 if an internet address is for a ``local'' host.
+ */
+in_localaddr(in)
+       struct in_addr in;
+{
+       register u_long i = ntohl(in.s_addr);
+       register u_long net;
+       register struct ifnet *ifp;
 
        if (IN_CLASSA(i))
 
        if (IN_CLASSA(i))
-               return ((i)&IN_CLASSA_HOST);
+               net = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
        else if (IN_CLASSB(i))
        else if (IN_CLASSB(i))
-               return ((i)&IN_CLASSB_HOST);
+               net = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
        else
        else
-               return ((i)&IN_CLASSC_HOST);
+               net = (i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT;
+
+       for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+               if (ifp->if_addr.sa_family != AF_INET)
+                       continue;
+               if (ifp->if_flags & IFF_LOCAL) {
+                       if (ifp->if_net == net)
+                               return (1);
+                       if ((ifp->if_net >> SUBNETSHIFT) == net)
+                               return (1);
+               }
+       }
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -95,7 +194,7 @@ if_rtinit(ifp, flags)
                return;
        bzero((caddr_t)&sin, sizeof (sin));
        sin.sin_family = AF_INET;
                return;
        bzero((caddr_t)&sin, sizeof (sin));
        sin.sin_family = AF_INET;
-       sin.sin_addr = if_makeaddr(ifp->if_net, 0);
+       sin.sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY);
        rtinit((struct sockaddr *)&sin, &ifp->if_addr, flags);
 }
 #endif
        rtinit((struct sockaddr *)&sin, &ifp->if_addr, flags);
 }
 #endif