fix to subnet routing (for initial calculation of if_net's)
authorMike Karels <karels@ucbvax.Berkeley.EDU>
Wed, 25 Apr 1984 08:28:24 +0000 (00:28 -0800)
committerMike Karels <karels@ucbvax.Berkeley.EDU>
Wed, 25 Apr 1984 08:28:24 +0000 (00:28 -0800)
SCCS-vsn: sys/netinet/in.c 6.3

usr/src/sys/netinet/in.c

index 837f551..a7885b0 100644 (file)
@@ -1,4 +1,4 @@
-/*     in.c    6.2     84/04/12        */
+/*     in.c    6.3     84/04/24        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
@@ -55,23 +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 net;
+       register u_long net, subnet;
+       register struct ifnet *ifp;
 
        if (IN_CLASSA(i)) {
 
        if (IN_CLASSA(i)) {
-               net = ((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
-               if (in_localnet(net) && IN_SUBNETA(i))
-                       return (((i)&IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT);
-               else
+               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)) {
                        return (net);
        } else if (IN_CLASSB(i)) {
-               net = ((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
-               if (in_localnet(net) && IN_SUBNETB(i))
-                       return (((i)&IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT);
-               else
+               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 (net);
        } else {
-               return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+               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);
 }
 
 /*
 }
 
 /*
@@ -81,44 +109,44 @@ 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_CLASSA(i)) {
-               if (IN_SUBNETA(i) &&
-                   in_localnet(((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT))
-                       return ((i)&IN_CLASSA_SUBHOST);
-               else
-                       return ((i)&IN_CLASSA_HOST);
+               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)) {
        } else if (IN_CLASSB(i)) {
-               if (IN_SUBNETB(i) &&
-                   in_localnet(((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT) )
-                       return ((i)&IN_CLASSB_SUBHOST);
-               else
-                       return ((i)&IN_CLASSB_HOST);
+               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 {
        } else {
-               return ((i)&IN_CLASSC_HOST);
+               return (i & IN_CLASSC_HOST);
        }
        }
-}
-
-/*
- * Return true if the network is a ``local'' net
- * (one for which we can interpret the host part).
- */
-in_localnet(net)
-       register int net;
-{
-       register struct ifnet *ifp;
 
 
+       /*
+        * 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)
        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);
+                           return (subhost);
                        if ((ifp->if_net >> SUBNETSHIFT) == net)
                        if ((ifp->if_net >> SUBNETSHIFT) == net)
-                               return (1);
+                           return (subhost);
                }
        }
                }
        }
-       return (0);
+       return (host);
 }
 
 /*
 }
 
 /*