|
|
1.1 ! root 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.