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