1: /*
   2:  * Copyright (c) 1984, 1985, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)ns.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "param.h"
  10: #include "mbuf.h"
  11: #include "ioctl.h"
  12: #include "protosw.h"
  13: #include "socket.h"
  14: #include "socketvar.h"
  15: #include "uio.h"
  16: #include "dir.h"
  17: #include "user.h"
  18: 
  19: 
  20: #include "../net/if.h"
  21: #include "../net/route.h"
  22: #include "../net/af.h"
  23: 
  24: #include "ns.h"
  25: #include "ns_if.h"
  26: 
  27: #ifdef NS
  28: 
  29: struct ns_ifaddr *ns_ifaddr;
  30: 
  31: ns_hash(sns, hp)
  32:     register struct sockaddr_ns *sns;
  33:     struct afhash *hp;
  34: {
  35:     register long hash = 0;
  36:     register u_short *s =  sns->sns_addr.x_host.s_host;
  37:     union {
  38:         union ns_net    net_e;
  39:         long        long_e;
  40:     } net;
  41: 
  42:     net.net_e = sns->sns_addr.x_net;
  43:     hp->afh_nethash = net.long_e;
  44:     hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s;
  45:     hp->afh_hosthash =  hash;
  46: }
  47: 
  48: 
  49: ns_netmatch(sns1, sns2)
  50:     struct sockaddr_ns *sns1, *sns2;
  51: {
  52: 
  53:     return (ns_neteq(sns1->sns_addr, sns2->sns_addr));
  54: }
  55: 
  56: /*
  57:  * Generic internet control operations (ioctl's).
  58:  */
  59: /* ARGSUSED */
  60: ns_control(so, cmd, data, ifp)
  61:     struct socket *so;
  62:     int cmd;
  63:     caddr_t data;
  64:     register struct ifnet *ifp;
  65: {
  66:     register struct ifreq *ifr = (struct ifreq *)data;
  67:     register struct ns_ifaddr *ia;
  68:     struct ifaddr *ifa;
  69:     struct mbuf *m;
  70: 
  71:     /*
  72: 	 * Find address for this interface, if it exists.
  73: 	 */
  74:     if (ifp == 0)
  75:         return (EADDRNOTAVAIL);
  76:     for (ia = ns_ifaddr; ia; ia = ia->ia_next)
  77:         if (ia->ia_ifp == ifp)
  78:             break;
  79: 
  80:     switch (cmd) {
  81: 
  82:     case SIOCGIFADDR:
  83:         if (ia == (struct ns_ifaddr *)0)
  84:             return (EADDRNOTAVAIL);
  85:         ifr->ifr_addr = ia->ia_addr;
  86:         return (0);
  87: 
  88: 
  89:     case SIOCGIFBRDADDR:
  90:         if (ia == (struct ns_ifaddr *)0)
  91:             return (EADDRNOTAVAIL);
  92:         if ((ifp->if_flags & IFF_BROADCAST) == 0)
  93:             return (EINVAL);
  94:         ifr->ifr_dstaddr = ia->ia_broadaddr;
  95:         return (0);
  96: 
  97:     case SIOCGIFDSTADDR:
  98:         if (ia == (struct ns_ifaddr *)0)
  99:             return (EADDRNOTAVAIL);
 100:         if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
 101:             return (EINVAL);
 102:         ifr->ifr_dstaddr = ia->ia_dstaddr;
 103:         return (0);
 104:     }
 105: 
 106:     if (!suser())
 107:         return (u.u_error);
 108: 
 109:     switch (cmd) {
 110: 
 111:     case SIOCSIFADDR:
 112:     case SIOCSIFDSTADDR:
 113:         if (ia == (struct ns_ifaddr *)0) {
 114:             m = m_getclr(M_WAIT, MT_IFADDR);
 115:             if (m == (struct mbuf *)NULL)
 116:                 return (ENOBUFS);
 117:             if (ia = ns_ifaddr) {
 118:                 for ( ; ia->ia_next; ia = ia->ia_next)
 119:                     ;
 120:                 ia->ia_next = mtod(m, struct ns_ifaddr *);
 121:             } else
 122:                 ns_ifaddr = mtod(m, struct ns_ifaddr *);
 123:             ia = mtod(m, struct ns_ifaddr *);
 124:             if (ifa = ifp->if_addrlist) {
 125:                 for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
 126:                     ;
 127:                 ifa->ifa_next = (struct ifaddr *) ia;
 128:             } else
 129:                 ifp->if_addrlist = (struct ifaddr *) ia;
 130:             ia->ia_ifp = ifp;
 131:             IA_SNS(ia)->sns_family = AF_NS;
 132:         }
 133:     }
 134: 
 135:     switch (cmd) {
 136: 
 137:     case SIOCSIFDSTADDR:
 138:         if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
 139:             return (EINVAL);
 140:         if (ia->ia_flags & IFA_ROUTE) {
 141:             rtinit(&ia->ia_dstaddr, &ia->ia_addr,
 142:                 (int)SIOCDELRT, RTF_HOST);
 143:             ia->ia_flags &= ~IFA_ROUTE;
 144:         }
 145:         if (ifp->if_ioctl) {
 146:             int error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia);
 147:             if (error)
 148:                 return (error);
 149:         }
 150:         ia->ia_dstaddr = ifr->ifr_dstaddr;
 151:         return (0);
 152: 
 153:     case SIOCSIFADDR:
 154:         return
 155:             (ns_ifinit(ifp, ia, (struct sockaddr_ns *)&ifr->ifr_addr));
 156: 
 157:     default:
 158:         if (ifp->if_ioctl == 0)
 159:             return (EOPNOTSUPP);
 160:         return ((*ifp->if_ioctl)(ifp, cmd, data));
 161:     }
 162: }
 163: 
 164: /*
 165:  * Initialize an interface's internet address
 166:  * and routing table entry.
 167:  */
 168: ns_ifinit(ifp, ia, sns)
 169:     register struct ifnet *ifp;
 170:     register struct ns_ifaddr *ia;
 171:     struct sockaddr_ns *sns;
 172: {
 173:     struct sockaddr_ns netaddr;
 174:     register union ns_host *h = &(IA_SNS(ia)->sns_addr.x_host);
 175:     int s = splimp(), error;
 176: 
 177:     /*
 178: 	 * The convention we shall adopt for naming is that
 179: 	 * a supplied address of zero means that "we don't care".
 180: 	 * if there is a single interface, use the address of that
 181: 	 * interface as our 6 byte host address.
 182: 	 * if there are multiple interfaces, use any address already
 183: 	 * used.
 184: 	 *
 185: 	 * If we have gotten into trouble and want to reset back to
 186: 	 * virginity, we recognize a request of the broadcast address.
 187: 	 */
 188:     if (ns_hosteqnh(sns->sns_addr.x_host, ns_broadhost)) {
 189:         ns_thishost = ns_zerohost;
 190:         splx(s);
 191:         return (0);
 192:     }
 193: 
 194:     /*
 195: 	 * Delete any previous route for an old address.
 196: 	 */
 197:     bzero((caddr_t)&netaddr, sizeof (netaddr));
 198:     netaddr.sns_family = AF_NS;
 199:     netaddr.sns_addr.x_host = ns_broadhost;
 200:     netaddr.sns_addr.x_net = ia->ia_net;
 201:     if (ia->ia_flags & IFA_ROUTE) {
 202:         if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
 203:             rtinit((struct sockaddr *)&netaddr, &ia->ia_addr,
 204:                     (int)SIOCDELRT, 0);
 205:         } else
 206:             rtinit(&ia->ia_dstaddr, &ia->ia_addr,
 207:                     (int)SIOCDELRT, RTF_HOST);
 208:     }
 209: 
 210:     /*
 211: 	 * Set up new addresses.
 212: 	 */
 213:     ia->ia_addr = *(struct sockaddr *)sns;
 214:     ia->ia_net = sns->sns_addr.x_net;
 215:     netaddr.sns_addr.x_net = ia->ia_net;
 216:     if (ifp->if_flags & IFF_BROADCAST) {
 217:         ia->ia_broadaddr = * (struct sockaddr *) &netaddr;
 218:     }
 219: 
 220:     /*
 221: 	 * Give the interface a chance to initialize
 222: 	 * if this is its first address,
 223: 	 * and to validate the address if necessary.
 224: 	 */
 225:     if (ns_hosteqnh(ns_thishost, ns_zerohost)) {
 226:         if (ifp->if_ioctl &&
 227:              (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
 228:             splx(s);
 229:             return (error);
 230:         }
 231:         ns_thishost = *h;
 232:     } else if (ns_hosteqnh(sns->sns_addr.x_host, ns_zerohost)
 233:         || ns_hosteqnh(sns->sns_addr.x_host, ns_thishost)) {
 234:         *h = ns_thishost;
 235:         if (ifp->if_ioctl &&
 236:              (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
 237:             splx(s);
 238:             return (error);
 239:         }
 240:         if (!ns_hosteqnh(ns_thishost,*h)) {
 241:             splx(s);
 242:             return (EINVAL);
 243:         }
 244:     } else {
 245:         splx(s);
 246:         return (EINVAL);
 247:     }
 248: 
 249:     /*
 250: 	 * Add route for the network.
 251: 	 */
 252:     if (ifp->if_flags & IFF_POINTOPOINT)
 253:         rtinit(&ia->ia_dstaddr, &ia->ia_addr, (int)SIOCADDRT,
 254:             RTF_HOST|RTF_UP);
 255:     else
 256:         rtinit(&ia->ia_broadaddr, &ia->ia_addr, (int)SIOCADDRT,
 257:             RTF_UP);
 258:     ia->ia_flags |= IFA_ROUTE;
 259:     return (0);
 260: }
 261: 
 262: /*
 263:  * Return address info for specified internet network.
 264:  */
 265: struct ns_ifaddr *
 266: ns_iaonnetof(dst)
 267:     register struct ns_addr *dst;
 268: {
 269:     register struct ns_ifaddr *ia;
 270:     register struct ns_addr *compare;
 271:     register struct ifnet *ifp;
 272:     struct ns_ifaddr *ia_maybe = 0;
 273:     union ns_net net = dst->x_net;
 274: 
 275:     for (ia = ns_ifaddr; ia; ia = ia->ia_next) {
 276:         if (ifp = ia->ia_ifp) {
 277:             if (ifp->if_flags & IFF_POINTOPOINT) {
 278:                 compare = &satons_addr(ia->ia_dstaddr);
 279:                 if (ns_hosteq(*dst, *compare))
 280:                     return (ia);
 281:                 if (ns_neteqnn(net, ia->ia_net))
 282:                     ia_maybe = ia;
 283:             } else {
 284:                 if (ns_neteqnn(net, ia->ia_net))
 285:                     return (ia);
 286:             }
 287:         }
 288:     }
 289:     return (ia_maybe);
 290: }
 291: #endif

Defined functions

ns_hash defined in line 31; used 2 times
ns_ifinit defined in line 168; used 1 times
ns_netmatch defined in line 49; used 2 times

Defined variables

ns_ifaddr defined in line 29; used 4 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1498
Valid CSS Valid XHTML 1.0 Strict