BSD 4_3 release
[unix-history] / usr / src / sys / netns / ns.c
index cf0c2e5..674b15c 100644 (file)
@@ -1,9 +1,9 @@
 /*
 /*
- * Copyright (c) 1982 Regents of the University of California.
+ * Copyright (c) 1984, 1985, 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.
  *
- *     @(#)ns.c        6.4 (Berkeley) %G%
+ *     @(#)ns.c        7.1 (Berkeley) 6/5/86
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -34,8 +34,13 @@ ns_hash(sns, hp)
 {
        register long hash = 0;
        register u_short *s =  sns->sns_addr.x_host.s_host;
 {
        register long hash = 0;
        register u_short *s =  sns->sns_addr.x_host.s_host;
+       union {
+               union ns_net    net_e;
+               long            long_e;
+       } net;
 
 
-       hp->afh_nethash = ns_netof(sns->sns_addr);
+       net.net_e = sns->sns_addr.x_net;
+       hp->afh_nethash = net.long_e;
        hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
        hp->afh_hosthash =  hash;
 }
        hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
        hp->afh_hosthash =  hash;
 }
@@ -45,7 +50,7 @@ ns_netmatch(sns1, sns2)
        struct sockaddr_ns *sns1, *sns2;
 {
 
        struct sockaddr_ns *sns1, *sns2;
 {
 
-       return (ns_netof(sns1->sns_addr) == ns_netof(sns2->sns_addr));
+       return (ns_neteq(sns1->sns_addr, sns2->sns_addr));
 }
 
 /*
 }
 
 /*
@@ -66,7 +71,7 @@ ns_control(so, cmd, data, ifp)
        /*
         * Find address for this interface, if it exists.
         */
        /*
         * Find address for this interface, if it exists.
         */
-       if (ifp==0)
+       if (ifp == 0)
                return (EADDRNOTAVAIL);
        for (ia = ns_ifaddr; ia; ia = ia->ia_next)
                if (ia->ia_ifp == ifp)
                return (EADDRNOTAVAIL);
        for (ia = ns_ifaddr; ia; ia = ia->ia_next)
                if (ia->ia_ifp == ifp)
@@ -103,10 +108,8 @@ ns_control(so, cmd, data, ifp)
 
        switch (cmd) {
 
 
        switch (cmd) {
 
-       case SIOCSIFDSTADDR:
-               return (EOPNOTSUPP);
-
        case SIOCSIFADDR:
        case SIOCSIFADDR:
+       case SIOCSIFDSTADDR:
                if (ia == (struct ns_ifaddr *)0) {
                        m = m_getclr(M_WAIT, MT_IFADDR);
                        if (m == (struct mbuf *)NULL)
                if (ia == (struct ns_ifaddr *)0) {
                        m = m_getclr(M_WAIT, MT_IFADDR);
                        if (m == (struct mbuf *)NULL)
@@ -127,6 +130,27 @@ ns_control(so, cmd, data, ifp)
                        ia->ia_ifp = ifp;
                        IA_SNS(ia)->sns_family = AF_NS;
                }
                        ia->ia_ifp = ifp;
                        IA_SNS(ia)->sns_family = AF_NS;
                }
+       }
+
+       switch (cmd) {
+
+       case SIOCSIFDSTADDR:
+               if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
+                       return (EINVAL);
+               if (ia->ia_flags & IFA_ROUTE) {
+                       rtinit(&ia->ia_dstaddr, &ia->ia_addr,
+                               (int)SIOCDELRT, RTF_HOST);
+                       ia->ia_flags &= ~IFA_ROUTE;
+               }
+               if (ifp->if_ioctl) {
+                       int error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia);
+                       if (error)
+                               return (error);
+               }
+               ia->ia_dstaddr = ifr->ifr_dstaddr;
+               return (0);
+
+       case SIOCSIFADDR:
                return
                    (ns_ifinit(ifp, ia, (struct sockaddr_ns *)&ifr->ifr_addr));
 
                return
                    (ns_ifinit(ifp, ia, (struct sockaddr_ns *)&ifr->ifr_addr));
 
@@ -164,22 +188,23 @@ ns_ifinit(ifp, ia, sns)
        if (ns_hosteqnh(sns->sns_addr.x_host, ns_broadhost)) {
                ns_thishost = ns_zerohost;
                splx(s);
        if (ns_hosteqnh(sns->sns_addr.x_host, ns_broadhost)) {
                ns_thishost = ns_zerohost;
                splx(s);
-               return(EINVAL);
+               return (0);
        }
 
        /*
         * Delete any previous route for an old address.
         */
        }
 
        /*
         * Delete any previous route for an old address.
         */
-
        bzero((caddr_t)&netaddr, sizeof (netaddr));
        netaddr.sns_family = AF_NS;
        netaddr.sns_addr.x_host = ns_broadhost;
        netaddr.sns_addr.x_net = ia->ia_net;
        if (ia->ia_flags & IFA_ROUTE) {
                if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
        bzero((caddr_t)&netaddr, sizeof (netaddr));
        netaddr.sns_family = AF_NS;
        netaddr.sns_addr.x_host = ns_broadhost;
        netaddr.sns_addr.x_net = ia->ia_net;
        if (ia->ia_flags & IFA_ROUTE) {
                if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
-                   rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, -1);
+                   rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
+                                   (int)SIOCDELRT, 0);
                } else
                } else
-                   rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr, -1);
+                   rtinit(&ia->ia_dstaddr, &ia->ia_addr,
+                                   (int)SIOCDELRT, RTF_HOST);
        }
 
        /*
        }
 
        /*
@@ -191,25 +216,12 @@ ns_ifinit(ifp, ia, sns)
        if (ifp->if_flags & IFF_BROADCAST) {
                ia->ia_broadaddr = * (struct sockaddr *) &netaddr;
        }
        if (ifp->if_flags & IFF_BROADCAST) {
                ia->ia_broadaddr = * (struct sockaddr *) &netaddr;
        }
-       /*
-        * Point to point links are a little touchier --
-        * We have to have an address of our own first,
-        * and will use the supplied address as that of the other end.
-        */
-       if (ifp->if_flags & IFF_POINTOPOINT) {
-               struct sockaddr_ns *sns2 = IA_SNS(ia);
-               if (ns_hosteqnh(ns_zerohost,ns_thishost))
-                       return(EINVAL);
-               ia->ia_dstaddr = ia->ia_addr;
-               sns2->sns_addr.x_host = ns_thishost;
-               sns->sns_addr.x_host = ns_thishost;
-       }
+
        /*
         * Give the interface a chance to initialize
         * if this is its first address,
         * and to validate the address if necessary.
         */
        /*
         * Give the interface a chance to initialize
         * if this is its first address,
         * and to validate the address if necessary.
         */
-
        if (ns_hosteqnh(ns_thishost, ns_zerohost)) {
                if (ifp->if_ioctl &&
                     (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
        if (ns_hosteqnh(ns_thishost, ns_zerohost)) {
                if (ifp->if_ioctl &&
                     (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
@@ -225,39 +237,55 @@ ns_ifinit(ifp, ia, sns)
                        splx(s);
                        return (error);
                }
                        splx(s);
                        return (error);
                }
-               if(!ns_hosteqnh(ns_thishost,*h)) {
+               if (!ns_hosteqnh(ns_thishost,*h)) {
                        splx(s);
                        return (EINVAL);
                }
        } else {
                splx(s);
                        splx(s);
                        return (EINVAL);
                }
        } else {
                splx(s);
-               return(EINVAL);
+               return (EINVAL);
        }
        }
+
        /*
         * Add route for the network.
         */
        /*
         * Add route for the network.
         */
-       if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
-               rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, RTF_UP);
-       } else
-               rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr,
+       if (ifp->if_flags & IFF_POINTOPOINT)
+               rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
                        RTF_HOST|RTF_UP);
                        RTF_HOST|RTF_UP);
+       else
+               rtinit(&ia->ia_broadaddr, &ia->ia_addr, (int)SIOCADDRT,
+                       RTF_UP);
        ia->ia_flags |= IFA_ROUTE;
        ia->ia_flags |= IFA_ROUTE;
-       return(0);
+       return (0);
 }
 
 /*
  * Return address info for specified internet network.
  */
 struct ns_ifaddr *
 }
 
 /*
  * Return address info for specified internet network.
  */
 struct ns_ifaddr *
-ns_iaonnetof(net)
-       union ns_net net;
+ns_iaonnetof(dst)
+       register struct ns_addr *dst;
 {
        register struct ns_ifaddr *ia;
 {
        register struct ns_ifaddr *ia;
+       register struct ns_addr *compare;
+       register struct ifnet *ifp;
+       struct ns_ifaddr *ia_maybe = 0;
+       union ns_net net = dst->x_net;
 
 
-#define        NtoL(x) (*(long *)(&(x)))
-       for (ia = ns_ifaddr; ia; ia = ia->ia_next)
-               if (NtoL(ia->ia_net) == NtoL(net))
-                       return (ia);
-       return ((struct ns_ifaddr *)0);
+       for (ia = ns_ifaddr; ia; ia = ia->ia_next) {
+               if (ifp = ia->ia_ifp) {
+                       if (ifp->if_flags & IFF_POINTOPOINT) {
+                               compare = &satons_addr(ia->ia_dstaddr);
+                               if (ns_hosteq(*dst, *compare))
+                                       return (ia);
+                               if (ns_neteqnn(net, ia->ia_net))
+                                       ia_maybe = ia;
+                       } else {
+                               if (ns_neteqnn(net, ia->ia_net))
+                                       return (ia);
+                       }
+               }
+       }
+       return (ia_maybe);
 }
 #endif
 }
 #endif