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

Defined functions

ns_control defined in line 63; never used
ns_hash defined in line 34; never used
ns_iaonnetof defined in line 268; never used
ns_ifinit defined in line 171; used 1 times
ns_netmatch defined in line 52; never used

Defined variables

ns_ifaddr defined in line 32; used 4 times
Last modified: 1988-04-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3724
Valid CSS Valid XHTML 1.0 Strict