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