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