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