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