|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1984, 1985, 1986, 1987, 1993 ! 24: * The Regents of the University of California. All rights reserved. ! 25: * ! 26: * Redistribution and use in source and binary forms, with or without ! 27: * modification, are permitted provided that the following conditions ! 28: * are met: ! 29: * 1. Redistributions of source code must retain the above copyright ! 30: * notice, this list of conditions and the following disclaimer. ! 31: * 2. Redistributions in binary form must reproduce the above copyright ! 32: * notice, this list of conditions and the following disclaimer in the ! 33: * documentation and/or other materials provided with the distribution. ! 34: * 3. All advertising materials mentioning features or use of this software ! 35: * must display the following acknowledgement: ! 36: * This product includes software developed by the University of ! 37: * California, Berkeley and its contributors. ! 38: * 4. Neither the name of the University nor the names of its contributors ! 39: * may be used to endorse or promote products derived from this software ! 40: * without specific prior written permission. ! 41: * ! 42: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 43: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 44: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 45: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 46: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 47: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 48: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 49: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 50: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 51: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 52: * SUCH DAMAGE. ! 53: * ! 54: * @(#)ns.c 8.2 (Berkeley) 11/15/93 ! 55: */ ! 56: ! 57: #include <sys/param.h> ! 58: #include <sys/mbuf.h> ! 59: #include <sys/ioctl.h> ! 60: #include <sys/protosw.h> ! 61: #include <sys/errno.h> ! 62: #include <sys/socket.h> ! 63: #include <sys/socketvar.h> ! 64: ! 65: #include <net/if.h> ! 66: #include <net/route.h> ! 67: ! 68: #include <netns/ns.h> ! 69: #include <netns/ns_if.h> ! 70: ! 71: #ifdef NS ! 72: ! 73: struct ns_ifaddr *ns_ifaddr; ! 74: int ns_interfaces; ! 75: extern struct sockaddr_ns ns_netmask, ns_hostmask; ! 76: ! 77: /* ! 78: * Generic internet control operations (ioctl's). ! 79: */ ! 80: /* ARGSUSED */ ! 81: ns_control(so, cmd, data, ifp) ! 82: struct socket *so; ! 83: int cmd; ! 84: caddr_t data; ! 85: register struct ifnet *ifp; ! 86: { ! 87: register struct ifreq *ifr = (struct ifreq *)data; ! 88: register struct ns_aliasreq *ifra = (struct ns_aliasreq *)data; ! 89: register struct ns_ifaddr *ia; ! 90: struct ifaddr *ifa; ! 91: struct ns_ifaddr *oia; ! 92: int error, dstIsNew, hostIsNew; ! 93: ! 94: /* ! 95: * Find address for this interface, if it exists. ! 96: */ ! 97: if (ifp == 0) ! 98: return (EADDRNOTAVAIL); ! 99: for (ia = ns_ifaddr; ia; ia = ia->ia_next) ! 100: if (ia->ia_ifp == ifp) ! 101: break; ! 102: ! 103: switch (cmd) { ! 104: ! 105: case SIOCGIFADDR: ! 106: if (ia == (struct ns_ifaddr *)0) ! 107: return (EADDRNOTAVAIL); ! 108: *(struct sockaddr_ns *)&ifr->ifr_addr = ia->ia_addr; ! 109: return (0); ! 110: ! 111: ! 112: case SIOCGIFBRDADDR: ! 113: if (ia == (struct ns_ifaddr *)0) ! 114: return (EADDRNOTAVAIL); ! 115: if ((ifp->if_flags & IFF_BROADCAST) == 0) ! 116: return (EINVAL); ! 117: *(struct sockaddr_ns *)&ifr->ifr_dstaddr = ia->ia_broadaddr; ! 118: return (0); ! 119: ! 120: case SIOCGIFDSTADDR: ! 121: if (ia == (struct ns_ifaddr *)0) ! 122: return (EADDRNOTAVAIL); ! 123: if ((ifp->if_flags & IFF_POINTOPOINT) == 0) ! 124: return (EINVAL); ! 125: *(struct sockaddr_ns *)&ifr->ifr_dstaddr = ia->ia_dstaddr; ! 126: return (0); ! 127: } ! 128: ! 129: if ((so->so_state & SS_PRIV) == 0) ! 130: return (EPERM); ! 131: ! 132: switch (cmd) { ! 133: case SIOCAIFADDR: ! 134: case SIOCDIFADDR: ! 135: if (ifra->ifra_addr.sns_family == AF_NS) ! 136: for (oia = ia; ia; ia = ia->ia_next) { ! 137: if (ia->ia_ifp == ifp && ! 138: ns_neteq(ia->ia_addr.sns_addr, ! 139: ifra->ifra_addr.sns_addr)) ! 140: break; ! 141: } ! 142: if (cmd == SIOCDIFADDR && ia == 0) ! 143: return (EADDRNOTAVAIL); ! 144: /* FALLTHROUGH */ ! 145: ! 146: case SIOCSIFADDR: ! 147: case SIOCSIFDSTADDR: ! 148: if (ia == (struct ns_ifaddr *)0) { ! 149: // oia = (struct ns_ifaddr *) ! 150: // malloc(sizeof *ia, M_IFADDR, M_WAITOK); ! 151: MALLOC(oia, struct ns_ifaddr *, sizeof *ia, M_IFADDR, M_WAITOK); ! 152: if (oia == (struct ns_ifaddr *)NULL) ! 153: return (ENOBUFS); ! 154: bzero((caddr_t)oia, sizeof(*oia)); ! 155: if (ia = ns_ifaddr) { ! 156: for ( ; ia->ia_next; ia = ia->ia_next) ! 157: ; ! 158: ia->ia_next = oia; ! 159: } else ! 160: ns_ifaddr = oia; ! 161: ia = oia; ! 162: if (ifa = ifp->if_addrlist) { ! 163: for ( ; ifa->ifa_next; ifa = ifa->ifa_next) ! 164: ; ! 165: ifa->ifa_next = (struct ifaddr *) ia; ! 166: } else ! 167: ifp->if_addrlist = (struct ifaddr *) ia; ! 168: ia->ia_ifp = ifp; ! 169: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ! 170: ! 171: ia->ia_ifa.ifa_netmask = ! 172: (struct sockaddr *)&ns_netmask; ! 173: ! 174: ia->ia_ifa.ifa_dstaddr = ! 175: (struct sockaddr *)&ia->ia_dstaddr; ! 176: if (ifp->if_flags & IFF_BROADCAST) { ! 177: ia->ia_broadaddr.sns_family = AF_NS; ! 178: ia->ia_broadaddr.sns_len = sizeof(ia->ia_addr); ! 179: ia->ia_broadaddr.sns_addr.x_host = ns_broadhost; ! 180: } ! 181: ns_interfaces++; ! 182: } ! 183: } ! 184: ! 185: switch (cmd) { ! 186: int error; ! 187: ! 188: case SIOCSIFDSTADDR: ! 189: if ((ifp->if_flags & IFF_POINTOPOINT) == 0) ! 190: return (EINVAL); ! 191: if (ia->ia_flags & IFA_ROUTE) { ! 192: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); ! 193: ia->ia_flags &= ~IFA_ROUTE; ! 194: } ! 195: if (ifp->if_ioctl) { ! 196: error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia); ! 197: if (error) ! 198: return (error); ! 199: } ! 200: *(struct sockaddr *)&ia->ia_dstaddr = ifr->ifr_dstaddr; ! 201: return (0); ! 202: ! 203: case SIOCSIFADDR: ! 204: return (ns_ifinit(ifp, ia, ! 205: (struct sockaddr_ns *)&ifr->ifr_addr, 1)); ! 206: ! 207: case SIOCDIFADDR: ! 208: ns_ifscrub(ifp, ia); ! 209: if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) ! 210: ifp->if_addrlist = ifa->ifa_next; ! 211: else { ! 212: while (ifa->ifa_next && ! 213: (ifa->ifa_next != (struct ifaddr *)ia)) ! 214: ifa = ifa->ifa_next; ! 215: if (ifa->ifa_next) ! 216: ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next; ! 217: else ! 218: printf("Couldn't unlink nsifaddr from ifp\n"); ! 219: } ! 220: oia = ia; ! 221: if (oia == (ia = ns_ifaddr)) { ! 222: ns_ifaddr = ia->ia_next; ! 223: } else { ! 224: while (ia->ia_next && (ia->ia_next != oia)) { ! 225: ia = ia->ia_next; ! 226: } ! 227: if (ia->ia_next) ! 228: ia->ia_next = oia->ia_next; ! 229: else ! 230: printf("Didn't unlink nsifadr from list\n"); ! 231: } ! 232: IFAFREE((&oia->ia_ifa)); ! 233: if (0 == --ns_interfaces) { ! 234: /* ! 235: * We reset to virginity and start all over again ! 236: */ ! 237: ns_thishost = ns_zerohost; ! 238: } ! 239: return (0); ! 240: ! 241: case SIOCAIFADDR: ! 242: dstIsNew = 0; hostIsNew = 1; ! 243: if (ia->ia_addr.sns_family == AF_NS) { ! 244: if (ifra->ifra_addr.sns_len == 0) { ! 245: ifra->ifra_addr = ia->ia_addr; ! 246: hostIsNew = 0; ! 247: } else if (ns_neteq(ifra->ifra_addr.sns_addr, ! 248: ia->ia_addr.sns_addr)) ! 249: hostIsNew = 0; ! 250: } ! 251: if ((ifp->if_flags & IFF_POINTOPOINT) && ! 252: (ifra->ifra_dstaddr.sns_family == AF_NS)) { ! 253: if (hostIsNew == 0) ! 254: ns_ifscrub(ifp, ia); ! 255: ia->ia_dstaddr = ifra->ifra_dstaddr; ! 256: dstIsNew = 1; ! 257: } ! 258: if (ifra->ifra_addr.sns_family == AF_NS && ! 259: (hostIsNew || dstIsNew)) ! 260: error = ns_ifinit(ifp, ia, &ifra->ifra_addr, 0); ! 261: return (error); ! 262: ! 263: default: ! 264: if (ifp->if_ioctl == 0) ! 265: return (EOPNOTSUPP); ! 266: return ((*ifp->if_ioctl)(ifp, cmd, data)); ! 267: } ! 268: } ! 269: ! 270: /* ! 271: * Delete any previous route for an old address. ! 272: */ ! 273: ns_ifscrub(ifp, ia) ! 274: register struct ifnet *ifp; ! 275: register struct ns_ifaddr *ia; ! 276: { ! 277: if (ia->ia_flags & IFA_ROUTE) { ! 278: if (ifp->if_flags & IFF_POINTOPOINT) { ! 279: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); ! 280: } else ! 281: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); ! 282: ia->ia_flags &= ~IFA_ROUTE; ! 283: } ! 284: } ! 285: /* ! 286: * Initialize an interface's internet address ! 287: * and routing table entry. ! 288: */ ! 289: ns_ifinit(ifp, ia, sns, scrub) ! 290: register struct ifnet *ifp; ! 291: register struct ns_ifaddr *ia; ! 292: register struct sockaddr_ns *sns; ! 293: { ! 294: struct sockaddr_ns oldaddr; ! 295: register union ns_host *h = &ia->ia_addr.sns_addr.x_host; ! 296: int s = splimp(), error; ! 297: ! 298: /* ! 299: * Set up new addresses. ! 300: */ ! 301: oldaddr = ia->ia_addr; ! 302: ia->ia_addr = *sns; ! 303: /* ! 304: * The convention we shall adopt for naming is that ! 305: * a supplied address of zero means that "we don't care". ! 306: * if there is a single interface, use the address of that ! 307: * interface as our 6 byte host address. ! 308: * if there are multiple interfaces, use any address already ! 309: * used. ! 310: * ! 311: * Give the interface a chance to initialize ! 312: * if this is its first address, ! 313: * and to validate the address if necessary. ! 314: */ ! 315: if (ns_hosteqnh(ns_thishost, ns_zerohost)) { ! 316: if (ifp->if_ioctl && ! 317: (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) { ! 318: ia->ia_addr = oldaddr; ! 319: splx(s); ! 320: return (error); ! 321: } ! 322: ns_thishost = *h; ! 323: } else if (ns_hosteqnh(sns->sns_addr.x_host, ns_zerohost) ! 324: || ns_hosteqnh(sns->sns_addr.x_host, ns_thishost)) { ! 325: *h = ns_thishost; ! 326: if (ifp->if_ioctl && ! 327: (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) { ! 328: ia->ia_addr = oldaddr; ! 329: splx(s); ! 330: return (error); ! 331: } ! 332: if (!ns_hosteqnh(ns_thishost,*h)) { ! 333: ia->ia_addr = oldaddr; ! 334: splx(s); ! 335: return (EINVAL); ! 336: } ! 337: } else { ! 338: ia->ia_addr = oldaddr; ! 339: splx(s); ! 340: return (EINVAL); ! 341: } ! 342: ia->ia_ifa.ifa_metric = ifp->if_metric; ! 343: /* ! 344: * Add route for the network. ! 345: */ ! 346: if (scrub) { ! 347: ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; ! 348: ns_ifscrub(ifp, ia); ! 349: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ! 350: } ! 351: if (ifp->if_flags & IFF_POINTOPOINT) ! 352: rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); ! 353: else { ! 354: ia->ia_broadaddr.sns_addr.x_net = ia->ia_addr.sns_addr.x_net; ! 355: rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP); ! 356: } ! 357: ia->ia_flags |= IFA_ROUTE; ! 358: return (0); ! 359: } ! 360: ! 361: /* ! 362: * Return address info for specified internet network. ! 363: */ ! 364: struct ns_ifaddr * ! 365: ns_iaonnetof(dst) ! 366: register struct ns_addr *dst; ! 367: { ! 368: register struct ns_ifaddr *ia; ! 369: register struct ns_addr *compare; ! 370: register struct ifnet *ifp; ! 371: struct ns_ifaddr *ia_maybe = 0; ! 372: union ns_net net = dst->x_net; ! 373: ! 374: for (ia = ns_ifaddr; ia; ia = ia->ia_next) { ! 375: if (ifp = ia->ia_ifp) { ! 376: if (ifp->if_flags & IFF_POINTOPOINT) { ! 377: compare = &satons_addr(ia->ia_dstaddr); ! 378: if (ns_hosteq(*dst, *compare)) ! 379: return (ia); ! 380: if (ns_neteqnn(net, ia->ia_addr.sns_addr.x_net)) ! 381: ia_maybe = ia; ! 382: } else { ! 383: if (ns_neteqnn(net, ia->ia_addr.sns_addr.x_net)) ! 384: return (ia); ! 385: } ! 386: } ! 387: } ! 388: return (ia_maybe); ! 389: } ! 390: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.