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