|
|
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) 1991, 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: * @(#)iso.c 8.2 (Berkeley) 11/15/93 ! 58: */ ! 59: ! 60: /*********************************************************** ! 61: Copyright IBM Corporation 1987 ! 62: ! 63: All Rights Reserved ! 64: ! 65: Permission to use, copy, modify, and distribute this software and its ! 66: documentation for any purpose and without fee is hereby granted, ! 67: provided that the above copyright notice appear in all copies and that ! 68: both that copyright notice and this permission notice appear in ! 69: supporting documentation, and that the name of IBM not be ! 70: used in advertising or publicity pertaining to distribution of the ! 71: software without specific, written prior permission. ! 72: ! 73: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 74: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 75: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 76: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 77: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 78: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 79: SOFTWARE. ! 80: ! 81: ******************************************************************/ ! 82: ! 83: /* ! 84: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison ! 85: */ ! 86: /* ! 87: * iso.c: miscellaneous routines to support the iso address family ! 88: */ ! 89: ! 90: #include <sys/param.h> ! 91: #include <sys/systm.h> ! 92: #include <sys/ioctl.h> ! 93: #include <sys/mbuf.h> ! 94: #include <sys/domain.h> ! 95: #include <sys/protosw.h> ! 96: #include <sys/socket.h> ! 97: #include <sys/socketvar.h> ! 98: #include <sys/errno.h> ! 99: #include <sys/malloc.h> ! 100: ! 101: #include <net/if.h> ! 102: #include <net/route.h> ! 103: ! 104: #include <netiso/iso.h> ! 105: #include <netiso/iso_var.h> ! 106: #include <netiso/iso_snpac.h> ! 107: #include <netiso/iso_pcb.h> ! 108: #include <netiso/clnp.h> ! 109: #include <netiso/argo_debug.h> ! 110: #if TUBA ! 111: #include <netiso/tuba_table.h> ! 112: #endif ! 113: ! 114: #if ISO ! 115: ! 116: int iso_interfaces = 0; /* number of external interfaces */ ! 117: extern struct ifnet loif; /* loopback interface */ ! 118: int ether_output(); ! 119: void llc_rtrequest(); ! 120: ! 121: /* ! 122: * FUNCTION: iso_addrmatch1 ! 123: * ! 124: * PURPOSE: decide if the two iso_addrs passed are equal ! 125: * ! 126: * RETURNS: true if the addrs match, false if they do not ! 127: * ! 128: * SIDE EFFECTS: ! 129: * ! 130: * NOTES: ! 131: */ ! 132: iso_addrmatch1(isoaa, isoab) ! 133: register struct iso_addr *isoaa, *isoab; /* addresses to check */ ! 134: { ! 135: u_int compare_len; ! 136: ! 137: IFDEBUG(D_ROUTE) ! 138: printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len, ! 139: isoab->isoa_len); ! 140: printf("a:\n"); ! 141: dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len); ! 142: printf("b:\n"); ! 143: dump_buf(isoab->isoa_genaddr, isoab->isoa_len); ! 144: ENDDEBUG ! 145: ! 146: if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) { ! 147: IFDEBUG(D_ROUTE) ! 148: printf("iso_addrmatch1: returning false because of lengths\n"); ! 149: ENDDEBUG ! 150: return 0; ! 151: } ! 152: ! 153: #ifdef notdef ! 154: /* TODO : generalize this to all afis with masks */ ! 155: if( isoaa->isoa_afi == AFI_37 ) { ! 156: /* must not compare 2 least significant digits, or for ! 157: * that matter, the DSP ! 158: */ ! 159: compare_len = ADDR37_IDI_LEN - 1; ! 160: } ! 161: #endif ! 162: ! 163: IFDEBUG(D_ROUTE) ! 164: int i; ! 165: char *a, *b; ! 166: ! 167: a = isoaa->isoa_genaddr; ! 168: b = isoab->isoa_genaddr; ! 169: ! 170: for (i=0; i<compare_len; i++) { ! 171: printf("<%x=%x>", a[i]&0xff, b[i]&0xff); ! 172: if (a[i] != b[i]) { ! 173: printf("\naddrs are not equal at byte %d\n", i); ! 174: return(0); ! 175: } ! 176: } ! 177: printf("\n"); ! 178: printf("addrs are equal\n"); ! 179: return (1); ! 180: ENDDEBUG ! 181: return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len)); ! 182: } ! 183: ! 184: /* ! 185: * FUNCTION: iso_addrmatch ! 186: * ! 187: * PURPOSE: decide if the two sockadrr_isos passed are equal ! 188: * ! 189: * RETURNS: true if the addrs match, false if they do not ! 190: * ! 191: * SIDE EFFECTS: ! 192: * ! 193: * NOTES: ! 194: */ ! 195: iso_addrmatch(sisoa, sisob) ! 196: struct sockaddr_iso *sisoa, *sisob; /* addresses to check */ ! 197: { ! 198: return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr)); ! 199: } ! 200: #ifdef notdef ! 201: /* ! 202: * FUNCTION: iso_netmatch ! 203: * ! 204: * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso ! 205: * as argument. ! 206: * ! 207: * RETURNS: true if same net, false if not ! 208: * ! 209: * SIDE EFFECTS: ! 210: * ! 211: * NOTES: ! 212: */ ! 213: iso_netmatch(sisoa, sisob) ! 214: struct sockaddr_iso *sisoa, *sisob; ! 215: { ! 216: u_char bufa[sizeof(struct sockaddr_iso)]; ! 217: u_char bufb[sizeof(struct sockaddr_iso)]; ! 218: register int lena, lenb; ! 219: ! 220: lena = iso_netof(&sisoa->siso_addr, bufa); ! 221: lenb = iso_netof(&sisob->siso_addr, bufb); ! 222: ! 223: IFDEBUG(D_ROUTE) ! 224: printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb); ! 225: printf("a:\n"); ! 226: dump_buf(bufa, lena); ! 227: printf("b:\n"); ! 228: dump_buf(bufb, lenb); ! 229: ENDDEBUG ! 230: ! 231: return ((lena == lenb) && (!bcmp(bufa, bufb, lena))); ! 232: } ! 233: #endif /* notdef */ ! 234: ! 235: /* ! 236: * FUNCTION: iso_hashchar ! 237: * ! 238: * PURPOSE: Hash all character in the buffer specified into ! 239: * a long. Return the long. ! 240: * ! 241: * RETURNS: The hash value. ! 242: * ! 243: * SIDE EFFECTS: ! 244: * ! 245: * NOTES: The hash is achieved by exclusive ORing 4 byte ! 246: * quantities. ! 247: */ ! 248: u_long ! 249: iso_hashchar(buf, len) ! 250: register caddr_t buf; /* buffer to pack from */ ! 251: register int len; /* length of buffer */ ! 252: { ! 253: register u_long h = 0; ! 254: register int i; ! 255: ! 256: for (i=0; i<len; i+=4) { ! 257: register u_long l = 0; ! 258: ! 259: if ((len - i) < 4) { ! 260: /* buffer not multiple of 4 */ ! 261: switch (len - i) { ! 262: case 3: ! 263: l |= buf[i+2] << 8; ! 264: case 2: ! 265: l |= buf[i+1] << 16; ! 266: case 1: ! 267: l |= buf[i] << 24; ! 268: break; ! 269: default: ! 270: printf("iso_hashchar: unexpected value x%x\n", len - i); ! 271: break; ! 272: } ! 273: } else { ! 274: l |= buf[i] << 24; ! 275: l |= buf[i+1] << 16; ! 276: l |= buf[i+2] << 8; ! 277: l |= buf[i+3]; ! 278: } ! 279: ! 280: h ^= l; ! 281: } ! 282: ! 283: h ^= (u_long) (len % 4); ! 284: ! 285: return(h); ! 286: } ! 287: #ifdef notdef ! 288: /* ! 289: * FUNCTION: iso_hash ! 290: * ! 291: * PURPOSE: Fill in fields of afhash structure based upon addr passed. ! 292: * ! 293: * RETURNS: none ! 294: * ! 295: * SIDE EFFECTS: ! 296: * ! 297: * NOTES: ! 298: */ ! 299: iso_hash(siso, hp) ! 300: struct sockaddr_iso *siso; /* address to perform hash on */ ! 301: struct afhash *hp; /* RETURN: hash info here */ ! 302: { ! 303: u_long buf[sizeof(struct sockaddr_iso)+1/4]; ! 304: register int bufsize; ! 305: ! 306: ! 307: bzero(buf, sizeof(buf)); ! 308: ! 309: bufsize = iso_netof(&siso->siso_addr, buf); ! 310: hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize); ! 311: ! 312: IFDEBUG(D_ROUTE) ! 313: printf("iso_hash: iso_netof: bufsize = %d\n", bufsize); ! 314: ENDDEBUG ! 315: ! 316: hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr, ! 317: siso->siso_addr.isoa_len); ! 318: ! 319: IFDEBUG(D_ROUTE) ! 320: printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n", ! 321: clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash, ! 322: hp->afh_hosthash); ! 323: ENDDEBUG ! 324: } ! 325: /* ! 326: * FUNCTION: iso_netof ! 327: * ! 328: * PURPOSE: Extract the network portion of the iso address. ! 329: * The network portion of the iso address varies depending ! 330: * on the type of address. The network portion of the ! 331: * address will include the IDP. The network portion is: ! 332: * ! 333: * TYPE DESC ! 334: * t37 The AFI and x.121 (IDI) ! 335: * osinet The AFI, orgid, snetid ! 336: * rfc986 The AFI, vers and network part of ! 337: * internet address. ! 338: * ! 339: * RETURNS: number of bytes placed into buf. ! 340: * ! 341: * SIDE EFFECTS: ! 342: * ! 343: * NOTES: Buf is assumed to be big enough ! 344: */ ! 345: iso_netof(isoa, buf) ! 346: struct iso_addr *isoa; /* address */ ! 347: caddr_t buf; /* RESULT: network portion of address here */ ! 348: { ! 349: u_int len = 1; /* length of afi */ ! 350: ! 351: switch (isoa->isoa_afi) { ! 352: case AFI_37: ! 353: /* ! 354: * Due to classic x.25 tunnel vision, there is no ! 355: * net portion of an x.121 address. For our purposes ! 356: * the AFI will do, so that all x.25 -type addresses ! 357: * map to the single x.25 SNPA. (Cannot have more than ! 358: * one, obviously). ! 359: */ ! 360: ! 361: break; ! 362: ! 363: /* case AFI_OSINET:*/ ! 364: case AFI_RFC986: { ! 365: u_short idi; /* value of idi */ ! 366: ! 367: /* osinet and rfc986 have idi in the same place */ ! 368: CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi); ! 369: ! 370: if (idi == IDI_OSINET) ! 371: /* ! 372: * Network portion of OSINET address can only be the IDI. Clearly, ! 373: * with one x25 interface, one could get to several orgids, and ! 374: * several snetids. ! 375: len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN + ! 376: OVLOSINET_SNETID_LEN); ! 377: */ ! 378: len += ADDROSINET_IDI_LEN; ! 379: else if (idi == IDI_RFC986) { ! 380: u_long inetaddr; ! 381: struct ovl_rfc986 *o986 = (struct ovl_rfc986 *)isoa; ! 382: ! 383: /* bump len to include idi and version (1 byte) */ ! 384: len += ADDRRFC986_IDI_LEN + 1; ! 385: ! 386: /* get inet addr long aligned */ ! 387: bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr)); ! 388: inetaddr = ntohl(inetaddr); /* convert to host byte order */ ! 389: ! 390: IFDEBUG(D_ROUTE) ! 391: printf("iso_netof: isoa "); ! 392: dump_buf(isoa, sizeof(*isoa)); ! 393: printf("iso_netof: inetaddr 0x%x ", inetaddr); ! 394: ENDDEBUG ! 395: ! 396: /* bump len by size of network portion of inet address */ ! 397: if (IN_CLASSA(inetaddr)) { ! 398: len += 4-IN_CLASSA_NSHIFT/8; ! 399: IFDEBUG(D_ROUTE) ! 400: printf("iso_netof: class A net len is now %d\n", len); ! 401: ENDDEBUG ! 402: } else if (IN_CLASSB(inetaddr)) { ! 403: len += 4-IN_CLASSB_NSHIFT/8; ! 404: IFDEBUG(D_ROUTE) ! 405: printf("iso_netof: class B net len is now %d\n", len); ! 406: ENDDEBUG ! 407: } else { ! 408: len += 4-IN_CLASSC_NSHIFT/8; ! 409: IFDEBUG(D_ROUTE) ! 410: printf("iso_netof: class C net len is now %d\n", len); ! 411: ENDDEBUG ! 412: } ! 413: } else ! 414: len = 0; ! 415: } break; ! 416: ! 417: default: ! 418: len = 0; ! 419: } ! 420: ! 421: bcopy((caddr_t)isoa, buf, len); ! 422: IFDEBUG(D_ROUTE) ! 423: printf("iso_netof: isoa "); ! 424: dump_buf(isoa, len); ! 425: printf("iso_netof: net "); ! 426: dump_buf(buf, len); ! 427: ENDDEBUG ! 428: return len; ! 429: } ! 430: #endif /* notdef */ ! 431: /* ! 432: * Generic iso control operations (ioctl's). ! 433: * Ifp is 0 if not an interface-specific ioctl. ! 434: */ ! 435: /* ARGSUSED */ ! 436: iso_control(so, cmd, data, ifp) ! 437: struct socket *so; ! 438: int cmd; ! 439: caddr_t data; ! 440: register struct ifnet *ifp; ! 441: { ! 442: register struct iso_ifreq *ifr = (struct iso_ifreq *)data; ! 443: register struct iso_ifaddr *ia = 0; ! 444: register struct ifaddr *ifa; ! 445: struct iso_ifaddr *oia; ! 446: struct iso_aliasreq *ifra = (struct iso_aliasreq *)data; ! 447: int error, hostIsNew, maskIsNew; ! 448: ! 449: /* ! 450: * Find address for this interface, if it exists. ! 451: */ ! 452: if (ifp) ! 453: for (ia = iso_ifaddr; ia; ia = ia->ia_next) ! 454: if (ia->ia_ifp == ifp) ! 455: break; ! 456: ! 457: switch (cmd) { ! 458: ! 459: case SIOCAIFADDR_ISO: ! 460: case SIOCDIFADDR_ISO: ! 461: if (ifra->ifra_addr.siso_family == AF_ISO) ! 462: for (oia = ia; ia; ia = ia->ia_next) { ! 463: if (ia->ia_ifp == ifp && ! 464: SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) ! 465: break; ! 466: } ! 467: if ((so->so_state & SS_PRIV) == 0) ! 468: return (EPERM); ! 469: if (ifp == 0) ! 470: panic("iso_control"); ! 471: if (ia == (struct iso_ifaddr *)0) { ! 472: struct iso_ifaddr *nia; ! 473: if (cmd == SIOCDIFADDR_ISO) ! 474: return (EADDRNOTAVAIL); ! 475: #if TUBA ! 476: /* XXXXXX can't be done in the proto init routines */ ! 477: if (tuba_tree == 0) ! 478: tuba_table_init(); ! 479: #endif ! 480: MALLOC(nia, struct iso_ifaddr *, sizeof(*nia), ! 481: M_IFADDR, M_WAITOK); ! 482: if (nia == (struct iso_ifaddr *)0) ! 483: return (ENOBUFS); ! 484: bzero((caddr_t)nia, sizeof(*nia)); ! 485: if (ia = iso_ifaddr) { ! 486: for ( ; ia->ia_next; ia = ia->ia_next) ! 487: ; ! 488: ia->ia_next = nia; ! 489: } else ! 490: iso_ifaddr = nia; ! 491: ia = nia; ! 492: if (ifa = ifp->if_addrlist) { ! 493: for ( ; ifa->ifa_next; ifa = ifa->ifa_next) ! 494: ; ! 495: ifa->ifa_next = (struct ifaddr *) ia; ! 496: } else ! 497: ifp->if_addrlist = (struct ifaddr *) ia; ! 498: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ! 499: ia->ia_ifa.ifa_dstaddr ! 500: = (struct sockaddr *)&ia->ia_dstaddr; ! 501: ia->ia_ifa.ifa_netmask ! 502: = (struct sockaddr *)&ia->ia_sockmask; ! 503: ia->ia_ifp = ifp; ! 504: if (ifp != &loif) ! 505: iso_interfaces++; ! 506: } ! 507: break; ! 508: ! 509: #define cmdbyte(x) (((x) >> 8) & 0xff) ! 510: default: ! 511: if (cmdbyte(cmd) == 'a') ! 512: return (snpac_ioctl(so, cmd, data)); ! 513: if (ia == (struct iso_ifaddr *)0) ! 514: return (EADDRNOTAVAIL); ! 515: break; ! 516: } ! 517: switch (cmd) { ! 518: ! 519: case SIOCGIFADDR_ISO: ! 520: ifr->ifr_Addr = ia->ia_addr; ! 521: break; ! 522: ! 523: case SIOCGIFDSTADDR_ISO: ! 524: if ((ifp->if_flags & IFF_POINTOPOINT) == 0) ! 525: return (EINVAL); ! 526: ifr->ifr_Addr = ia->ia_dstaddr; ! 527: break; ! 528: ! 529: case SIOCGIFNETMASK_ISO: ! 530: ifr->ifr_Addr = ia->ia_sockmask; ! 531: break; ! 532: ! 533: case SIOCAIFADDR_ISO: ! 534: maskIsNew = 0; hostIsNew = 1; error = 0; ! 535: if (ia->ia_addr.siso_family == AF_ISO) { ! 536: if (ifra->ifra_addr.siso_len == 0) { ! 537: ifra->ifra_addr = ia->ia_addr; ! 538: hostIsNew = 0; ! 539: } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) ! 540: hostIsNew = 0; ! 541: } ! 542: if (ifra->ifra_mask.siso_len) { ! 543: iso_ifscrub(ifp, ia); ! 544: ia->ia_sockmask = ifra->ifra_mask; ! 545: maskIsNew = 1; ! 546: } ! 547: if ((ifp->if_flags & IFF_POINTOPOINT) && ! 548: (ifra->ifra_dstaddr.siso_family == AF_ISO)) { ! 549: iso_ifscrub(ifp, ia); ! 550: ia->ia_dstaddr = ifra->ifra_dstaddr; ! 551: maskIsNew = 1; /* We lie; but the effect's the same */ ! 552: } ! 553: if (ifra->ifra_addr.siso_family == AF_ISO && ! 554: (hostIsNew || maskIsNew)) { ! 555: error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0); ! 556: } ! 557: if (ifra->ifra_snpaoffset) ! 558: ia->ia_snpaoffset = ifra->ifra_snpaoffset; ! 559: return (error); ! 560: ! 561: case SIOCDIFADDR_ISO: ! 562: iso_ifscrub(ifp, ia); ! 563: if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) ! 564: ifp->if_addrlist = ifa->ifa_next; ! 565: else { ! 566: while (ifa->ifa_next && ! 567: (ifa->ifa_next != (struct ifaddr *)ia)) ! 568: ifa = ifa->ifa_next; ! 569: if (ifa->ifa_next) ! 570: ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next; ! 571: else ! 572: printf("Couldn't unlink isoifaddr from ifp\n"); ! 573: } ! 574: oia = ia; ! 575: if (oia == (ia = iso_ifaddr)) { ! 576: iso_ifaddr = ia->ia_next; ! 577: } else { ! 578: while (ia->ia_next && (ia->ia_next != oia)) { ! 579: ia = ia->ia_next; ! 580: } ! 581: if (ia->ia_next) ! 582: ia->ia_next = oia->ia_next; ! 583: else ! 584: printf("Didn't unlink isoifadr from list\n"); ! 585: } ! 586: IFAFREE((&oia->ia_ifa)); ! 587: break; ! 588: ! 589: default: ! 590: if (ifp == 0 || ifp->if_ioctl == 0) ! 591: return (EOPNOTSUPP); ! 592: return ((*ifp->if_ioctl)(ifp, cmd, data)); ! 593: } ! 594: return (0); ! 595: } ! 596: ! 597: /* ! 598: * Delete any existing route for an interface. ! 599: */ ! 600: iso_ifscrub(ifp, ia) ! 601: register struct ifnet *ifp; ! 602: register struct iso_ifaddr *ia; ! 603: { ! 604: int nsellength = ia->ia_addr.siso_tlen; ! 605: if ((ia->ia_flags & IFA_ROUTE) == 0) ! 606: return; ! 607: ia->ia_addr.siso_tlen = 0; ! 608: if (ifp->if_flags & IFF_LOOPBACK) ! 609: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); ! 610: else if (ifp->if_flags & IFF_POINTOPOINT) ! 611: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); ! 612: else { ! 613: rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); ! 614: } ! 615: ia->ia_addr.siso_tlen = nsellength; ! 616: ia->ia_flags &= ~IFA_ROUTE; ! 617: } ! 618: ! 619: /* ! 620: * Initialize an interface's internet address ! 621: * and routing table entry. ! 622: */ ! 623: iso_ifinit(ifp, ia, siso, scrub) ! 624: register struct ifnet *ifp; ! 625: register struct iso_ifaddr *ia; ! 626: struct sockaddr_iso *siso; ! 627: { ! 628: struct sockaddr_iso oldaddr; ! 629: int s = splimp(), error, nsellength; ! 630: ! 631: oldaddr = ia->ia_addr; ! 632: ia->ia_addr = *siso; ! 633: /* ! 634: * Give the interface a chance to initialize ! 635: * if this is its first address, ! 636: * and to validate the address if necessary. ! 637: */ ! 638: if (ifp->if_ioctl && ! 639: (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { ! 640: splx(s); ! 641: ia->ia_addr = oldaddr; ! 642: return (error); ! 643: } ! 644: if (scrub) { ! 645: ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; ! 646: iso_ifscrub(ifp, ia); ! 647: ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ! 648: } ! 649: /* XXX -- The following is here temporarily out of laziness ! 650: in not changing every ethernet driver's if_ioctl routine */ ! 651: if (ifp->if_output == ether_output) { ! 652: ia->ia_ifa.ifa_rtrequest = llc_rtrequest; ! 653: ia->ia_ifa.ifa_flags |= RTF_CLONING; ! 654: } ! 655: /* ! 656: * Add route for the network. ! 657: */ ! 658: nsellength = ia->ia_addr.siso_tlen; ! 659: ia->ia_addr.siso_tlen = 0; ! 660: if (ifp->if_flags & IFF_LOOPBACK) { ! 661: ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; ! 662: error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); ! 663: } else if (ifp->if_flags & IFF_POINTOPOINT && ! 664: ia->ia_dstaddr.siso_family == AF_ISO) ! 665: error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); ! 666: else { ! 667: rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr, ! 668: ia->ia_ifa.ifa_netmask); ! 669: ia->ia_dstaddr.siso_nlen = ! 670: min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6)); ! 671: error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP); ! 672: } ! 673: ia->ia_addr.siso_tlen = nsellength; ! 674: ia->ia_flags |= IFA_ROUTE; ! 675: splx(s); ! 676: return (error); ! 677: } ! 678: #ifdef notdef ! 679: ! 680: struct ifaddr * ! 681: iso_ifwithidi(addr) ! 682: register struct sockaddr *addr; ! 683: { ! 684: register struct ifnet *ifp; ! 685: register struct ifaddr *ifa; ! 686: register u_int af = addr->sa_family; ! 687: ! 688: if (af != AF_ISO) ! 689: return (0); ! 690: IFDEBUG(D_ROUTE) ! 691: printf(">>> iso_ifwithidi addr\n"); ! 692: dump_isoaddr( (struct sockaddr_iso *)(addr)); ! 693: printf("\n"); ! 694: ENDDEBUG ! 695: for (ifp = ifnet; ifp; ifp = ifp->if_next) { ! 696: IFDEBUG(D_ROUTE) ! 697: printf("iso_ifwithidi ifnet %s\n", ifp->if_name); ! 698: ENDDEBUG ! 699: for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { ! 700: IFDEBUG(D_ROUTE) ! 701: printf("iso_ifwithidi address "); ! 702: dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr)); ! 703: ENDDEBUG ! 704: if (ifa->ifa_addr->sa_family != addr->sa_family) ! 705: continue; ! 706: ! 707: #define IFA_SIS(ifa)\ ! 708: ((struct sockaddr_iso *)((ifa)->ifa_addr)) ! 709: ! 710: IFDEBUG(D_ROUTE) ! 711: printf(" af same, args to iso_eqtype:\n"); ! 712: printf("0x%x ", IFA_SIS(ifa)->siso_addr); ! 713: printf(" 0x%x\n", ! 714: &(((struct sockaddr_iso *)addr)->siso_addr)); ! 715: ENDDEBUG ! 716: ! 717: if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr), ! 718: &(((struct sockaddr_iso *)addr)->siso_addr))) { ! 719: IFDEBUG(D_ROUTE) ! 720: printf("ifa_ifwithidi: ifa found\n"); ! 721: ENDDEBUG ! 722: return (ifa); ! 723: } ! 724: IFDEBUG(D_ROUTE) ! 725: printf(" iso_eqtype failed\n"); ! 726: ENDDEBUG ! 727: } ! 728: } ! 729: return ((struct ifaddr *)0); ! 730: } ! 731: ! 732: #endif /* notdef */ ! 733: /* ! 734: * FUNCTION: iso_ck_addr ! 735: * ! 736: * PURPOSE: return true if the iso_addr passed is ! 737: * within the legal size limit for an iso address. ! 738: * ! 739: * RETURNS: true or false ! 740: * ! 741: * SIDE EFFECTS: ! 742: * ! 743: */ ! 744: iso_ck_addr(isoa) ! 745: struct iso_addr *isoa; /* address to check */ ! 746: { ! 747: return (isoa->isoa_len <= 20); ! 748: ! 749: } ! 750: ! 751: #ifdef notdef ! 752: /* ! 753: * FUNCTION: iso_eqtype ! 754: * ! 755: * PURPOSE: Determine if two iso addresses are of the same type. ! 756: * This is flaky. Really we should consider all type 47 addrs to be the ! 757: * same - but there do exist different structures for 47 addrs. ! 758: * Gosip adds a 3rd. ! 759: * ! 760: * RETURNS: true if the addresses are the same type ! 761: * ! 762: * SIDE EFFECTS: ! 763: * ! 764: * NOTES: By type, I mean rfc986, t37, or osinet ! 765: * ! 766: * This will first compare afis. If they match, then ! 767: * if the addr is not t37, the idis must be compared. ! 768: */ ! 769: iso_eqtype(isoaa, isoab) ! 770: struct iso_addr *isoaa; /* first addr to check */ ! 771: struct iso_addr *isoab; /* other addr to check */ ! 772: { ! 773: if (isoaa->isoa_afi == isoab->isoa_afi) { ! 774: if (isoaa->isoa_afi == AFI_37) ! 775: return(1); ! 776: else ! 777: return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2)); ! 778: } ! 779: return(0); ! 780: } ! 781: #endif /* notdef */ ! 782: /* ! 783: * FUNCTION: iso_localifa() ! 784: * ! 785: * PURPOSE: Find an interface addresss having a given destination ! 786: * or at least matching the net. ! 787: * ! 788: * RETURNS: ptr to an interface address ! 789: * ! 790: * SIDE EFFECTS: ! 791: * ! 792: * NOTES: ! 793: */ ! 794: struct iso_ifaddr * ! 795: iso_localifa(siso) ! 796: register struct sockaddr_iso *siso; ! 797: { ! 798: register struct iso_ifaddr *ia; ! 799: register char *cp1, *cp2, *cp3; ! 800: register struct ifnet *ifp; ! 801: struct iso_ifaddr *ia_maybe = 0; ! 802: /* ! 803: * We make one pass looking for both net matches and an exact ! 804: * dst addr. ! 805: */ ! 806: for (ia = iso_ifaddr; ia; ia = ia->ia_next) { ! 807: if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0)) ! 808: continue; ! 809: if (ifp->if_flags & IFF_POINTOPOINT) { ! 810: if ((ia->ia_dstaddr.siso_family == AF_ISO) && ! 811: SAME_ISOADDR(&ia->ia_dstaddr, siso)) ! 812: return (ia); ! 813: else ! 814: if (SAME_ISOADDR(&ia->ia_addr, siso)) ! 815: ia_maybe = ia; ! 816: continue; ! 817: } ! 818: if (ia->ia_sockmask.siso_len) { ! 819: char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask; ! 820: cp1 = ia->ia_sockmask.siso_data; ! 821: cp2 = siso->siso_data; ! 822: cp3 = ia->ia_addr.siso_data; ! 823: while (cp1 < cplim) ! 824: if (*cp1++ & (*cp2++ ^ *cp3++)) ! 825: goto next; ! 826: ia_maybe = ia; ! 827: } ! 828: if (SAME_ISOADDR(&ia->ia_addr, siso)) ! 829: return ia; ! 830: next:; ! 831: } ! 832: return ia_maybe; ! 833: } ! 834: ! 835: #if TPCONS ! 836: #include <netiso/cons.h> ! 837: #endif /* TPCONS */ ! 838: /* ! 839: * FUNCTION: iso_nlctloutput ! 840: * ! 841: * PURPOSE: Set options at the network level ! 842: * ! 843: * RETURNS: E* ! 844: * ! 845: * SIDE EFFECTS: ! 846: * ! 847: * NOTES: This could embody some of the functions of ! 848: * rclnp_ctloutput and cons_ctloutput. ! 849: */ ! 850: iso_nlctloutput(cmd, optname, pcb, m) ! 851: int cmd; /* command:set or get */ ! 852: int optname; /* option of interest */ ! 853: caddr_t pcb; /* nl pcb */ ! 854: struct mbuf *m; /* data for set, buffer for get */ ! 855: { ! 856: struct isopcb *isop = (struct isopcb *)pcb; ! 857: int error = 0; /* return value */ ! 858: caddr_t data; /* data for option */ ! 859: int data_len; /* data's length */ ! 860: ! 861: IFDEBUG(D_ISO) ! 862: printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n", ! 863: cmd, optname, pcb, m); ! 864: ENDDEBUG ! 865: ! 866: if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT)) ! 867: return(EOPNOTSUPP); ! 868: ! 869: data = mtod(m, caddr_t); ! 870: data_len = (m)->m_len; ! 871: ! 872: IFDEBUG(D_ISO) ! 873: printf("iso_nlctloutput: data is:\n"); ! 874: dump_buf(data, data_len); ! 875: ENDDEBUG ! 876: ! 877: switch (optname) { ! 878: ! 879: #if TPCONS ! 880: case CONSOPT_X25CRUD: ! 881: if (cmd == PRCO_GETOPT) { ! 882: error = EOPNOTSUPP; ! 883: break; ! 884: } ! 885: ! 886: if (data_len > MAXX25CRUDLEN) { ! 887: error = EINVAL; ! 888: break; ! 889: } ! 890: ! 891: IFDEBUG(D_ISO) ! 892: printf("iso_nlctloutput: setting x25 crud\n"); ! 893: ENDDEBUG ! 894: ! 895: bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len); ! 896: isop->isop_x25crud_len = data_len; ! 897: break; ! 898: #endif /* TPCONS */ ! 899: ! 900: default: ! 901: error = EOPNOTSUPP; ! 902: } ! 903: if (cmd == PRCO_SETOPT) ! 904: m_freem(m); ! 905: return error; ! 906: } ! 907: #endif /* ISO */ ! 908: ! 909: #ifdef ARGO_DEBUG ! 910: ! 911: /* ! 912: * FUNCTION: dump_isoaddr ! 913: * ! 914: * PURPOSE: debugging ! 915: * ! 916: * RETURNS: nada ! 917: * ! 918: */ ! 919: dump_isoaddr(s) ! 920: struct sockaddr_iso *s; ! 921: { ! 922: char *clnp_saddr_isop(); ! 923: register int i; ! 924: ! 925: if( s->siso_family == AF_ISO) { ! 926: printf("ISO address: suffixlen %d, %s\n", ! 927: s->siso_tlen, clnp_saddr_isop(s)); ! 928: } else if( s->siso_family == AF_INET) { ! 929: /* hack */ ! 930: struct sockaddr_in *sin = (struct sockaddr_in *)s; ! 931: ! 932: printf("%d.%d.%d.%d: %d", ! 933: (sin->sin_addr.s_addr>>24)&0xff, ! 934: (sin->sin_addr.s_addr>>16)&0xff, ! 935: (sin->sin_addr.s_addr>>8)&0xff, ! 936: (sin->sin_addr.s_addr)&0xff, ! 937: sin->sin_port); ! 938: } ! 939: } ! 940: ! 941: #endif /* ARGO_DEBUG */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.