136384Ssklower /*********************************************************** 236384Ssklower Copyright IBM Corporation 1987 336384Ssklower 436384Ssklower All Rights Reserved 536384Ssklower 636384Ssklower Permission to use, copy, modify, and distribute this software and its 736384Ssklower documentation for any purpose and without fee is hereby granted, 836384Ssklower provided that the above copyright notice appear in all copies and that 936384Ssklower both that copyright notice and this permission notice appear in 1036384Ssklower supporting documentation, and that the name of IBM not be 1136384Ssklower used in advertising or publicity pertaining to distribution of the 1236384Ssklower software without specific, written prior permission. 1336384Ssklower 1436384Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 1536384Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 1636384Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 1736384Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 1836384Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 1936384Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 2036384Ssklower SOFTWARE. 2136384Ssklower 2236384Ssklower ******************************************************************/ 2336384Ssklower 2436384Ssklower /* 2536384Ssklower * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison 2636384Ssklower */ 2736384Ssklower /* 2836384Ssklower * $Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $ 2936384Ssklower * $Source: /usr/argo/sys/netiso/RCS/iso.c,v $ 30*37469Ssklower * @(#)iso.c 7.2 (Berkeley) 04/22/89 3136384Ssklower * 3236384Ssklower * iso.c: miscellaneous routines to support the iso address family 3336384Ssklower */ 3436384Ssklower 3536384Ssklower #ifndef lint 3636384Ssklower static char *rcsid = "$Header: iso.c,v 4.11 88/09/19 14:58:35 root Exp $"; 3736384Ssklower #endif 3836384Ssklower 3936384Ssklower 40*37469Ssklower #include "types.h" 41*37469Ssklower #include "param.h" 42*37469Ssklower #include "ioctl.h" 43*37469Ssklower #include "mbuf.h" 44*37469Ssklower #include "domain.h" 45*37469Ssklower #include "protosw.h" 46*37469Ssklower #include "socket.h" 47*37469Ssklower #include "socketvar.h" 48*37469Ssklower #include "uio.h" 49*37469Ssklower #include "dir.h" 50*37469Ssklower #include "user.h" 51*37469Ssklower #include "errno.h" 5236384Ssklower 5336384Ssklower #include "../net/if.h" 5436384Ssklower #include "../net/route.h" 5536384Ssklower #include "../net/af.h" 5636384Ssklower 57*37469Ssklower #include "iso.h" 58*37469Ssklower #include "iso_var.h" 59*37469Ssklower #include "iso_snpac.h" 60*37469Ssklower #include "iso_pcb.h" 61*37469Ssklower #include "clnp.h" 62*37469Ssklower #include "argo_debug.h" 6336384Ssklower 6436384Ssklower #ifdef ISO 65*37469Ssklower #include "argoxtwentyfive.h" 6636384Ssklower 6736384Ssklower int iso_interfaces = 0; /* number of external interfaces */ 6836384Ssklower extern struct ifnet loif; /* loopback interface */ 6936384Ssklower 7036384Ssklower 7136384Ssklower /* 7236384Ssklower * FUNCTION: iso_init 7336384Ssklower * 7436384Ssklower * PURPOSE: initialize the iso address family 7536384Ssklower * 7636384Ssklower * RETURNS: nothing 7736384Ssklower * 7836384Ssklower * SIDE EFFECTS: 1) zeros the maptab table. 79*37469Ssklower * 2) initializes the routing table. 8036384Ssklower * 8136384Ssklower * NOTES: 8236384Ssklower */ 83*37469Ssklower struct radix_node_head *iso_rnhead; 8436384Ssklower iso_init() 8536384Ssklower { 86*37469Ssklower extern struct spna_cache iso_snpac[]; 87*37469Ssklower extern u_int iso_snpac_size; 88*37469Ssklower static iso_init_done; 8936384Ssklower 90*37469Ssklower if (iso_init_done == 0) { 91*37469Ssklower iso_init_done++; 92*37469Ssklower bzero((caddr_t)iso_snpac, iso_snpac_size * sizeof(struct snpa_cache)); 93*37469Ssklower rn_inithead(&iso_rnhead, 40, AF_ISO); 94*37469Ssklower } 9536384Ssklower } 9636384Ssklower 9736384Ssklower /* 9836384Ssklower * FUNCTION: iso_addrmatch1 9936384Ssklower * 10036384Ssklower * PURPOSE: decide if the two iso_addrs passed are equal 10136384Ssklower * 10236384Ssklower * RETURNS: true if the addrs match, false if they do not 10336384Ssklower * 10436384Ssklower * SIDE EFFECTS: 10536384Ssklower * 10636384Ssklower * NOTES: 10736384Ssklower */ 10836384Ssklower iso_addrmatch1(isoaa, isoab) 109*37469Ssklower register struct iso_addr *isoaa, *isoab; /* addresses to check */ 11036384Ssklower { 111*37469Ssklower u_int compare_len; 11236384Ssklower 11336384Ssklower IFDEBUG(D_ROUTE) 11436384Ssklower printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len, 11536384Ssklower isoab->isoa_len); 11636384Ssklower printf("a:\n"); 117*37469Ssklower dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len); 11836384Ssklower printf("b:\n"); 119*37469Ssklower dump_buf(isoab->isoa_genaddr, isoab->isoa_len); 12036384Ssklower ENDDEBUG 12136384Ssklower 12236384Ssklower if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) { 12336384Ssklower IFDEBUG(D_ROUTE) 12436384Ssklower printf("iso_addrmatch1: returning false because of lengths\n"); 12536384Ssklower ENDDEBUG 12636384Ssklower return 0; 12736384Ssklower } 12836384Ssklower 129*37469Ssklower #ifdef notdef 13036384Ssklower /* TODO : generalize this to all afis with masks */ 13136384Ssklower if( isoaa->isoa_afi == AFI_37 ) { 13236384Ssklower /* must not compare 2 least significant digits, or for 13336384Ssklower * that matter, the DSP 13436384Ssklower */ 13536384Ssklower compare_len = ADDR37_IDI_LEN - 1; 13636384Ssklower } 137*37469Ssklower #endif 13836384Ssklower 13936384Ssklower IFDEBUG(D_ROUTE) 14036384Ssklower int i; 14136384Ssklower char *a, *b; 14236384Ssklower 143*37469Ssklower a = isoaa->isoa_genaddr; 144*37469Ssklower b = isoab->isoa_genaddr; 14536384Ssklower 14636384Ssklower for (i=0; i<compare_len; i++) { 14736384Ssklower printf("<%x=%x>", a[i]&0xff, b[i]&0xff); 14836384Ssklower if (a[i] != b[i]) { 14936384Ssklower printf("\naddrs are not equal at byte %d\n", i); 15036384Ssklower return(0); 15136384Ssklower } 15236384Ssklower } 15336384Ssklower printf("\n"); 15436384Ssklower printf("addrs are equal\n"); 15536384Ssklower return (1); 15636384Ssklower ENDDEBUG 157*37469Ssklower return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len)); 15836384Ssklower } 15936384Ssklower 16036384Ssklower /* 16136384Ssklower * FUNCTION: iso_addrmatch 16236384Ssklower * 16336384Ssklower * PURPOSE: decide if the two sockadrr_isos passed are equal 16436384Ssklower * 16536384Ssklower * RETURNS: true if the addrs match, false if they do not 16636384Ssklower * 16736384Ssklower * SIDE EFFECTS: 16836384Ssklower * 16936384Ssklower * NOTES: 17036384Ssklower */ 17136384Ssklower iso_addrmatch(sisoa, sisob) 17236384Ssklower struct sockaddr_iso *sisoa, *sisob; /* addresses to check */ 17336384Ssklower { 17436384Ssklower return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr)); 17536384Ssklower } 176*37469Ssklower #ifdef notdef 17736384Ssklower /* 17836384Ssklower * FUNCTION: iso_netmatch 17936384Ssklower * 18036384Ssklower * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso 18136384Ssklower * as argument. 18236384Ssklower * 18336384Ssklower * RETURNS: true if same net, false if not 18436384Ssklower * 18536384Ssklower * SIDE EFFECTS: 18636384Ssklower * 18736384Ssklower * NOTES: 18836384Ssklower */ 18936384Ssklower iso_netmatch(sisoa, sisob) 19036384Ssklower struct sockaddr_iso *sisoa, *sisob; 19136384Ssklower { 19236384Ssklower u_char bufa[sizeof(struct sockaddr_iso)]; 19336384Ssklower u_char bufb[sizeof(struct sockaddr_iso)]; 19436384Ssklower register int lena, lenb; 19536384Ssklower 19636384Ssklower lena = iso_netof(&sisoa->siso_addr, bufa); 19736384Ssklower lenb = iso_netof(&sisob->siso_addr, bufb); 19836384Ssklower 19936384Ssklower IFDEBUG(D_ROUTE) 20036384Ssklower printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb); 20136384Ssklower printf("a:\n"); 20236384Ssklower dump_buf(bufa, lena); 20336384Ssklower printf("b:\n"); 20436384Ssklower dump_buf(bufb, lenb); 20536384Ssklower ENDDEBUG 20636384Ssklower 20736384Ssklower return ((lena == lenb) && (!bcmp(bufa, bufb, lena))); 20836384Ssklower } 209*37469Ssklower #endif notdef 21036384Ssklower 21136384Ssklower /* 21236384Ssklower * FUNCTION: iso_hashchar 21336384Ssklower * 21436384Ssklower * PURPOSE: Hash all character in the buffer specified into 21536384Ssklower * a long. Return the long. 21636384Ssklower * 21736384Ssklower * RETURNS: The hash value. 21836384Ssklower * 21936384Ssklower * SIDE EFFECTS: 22036384Ssklower * 22136384Ssklower * NOTES: The hash is achieved by exclusive ORing 4 byte 22236384Ssklower * quantities. 22336384Ssklower */ 22436384Ssklower u_long 22536384Ssklower iso_hashchar(buf, len) 22636384Ssklower register caddr_t buf; /* buffer to pack from */ 22736384Ssklower register int len; /* length of buffer */ 22836384Ssklower { 22936384Ssklower register u_long h = 0; 23036384Ssklower register int i; 23136384Ssklower 23236384Ssklower for (i=0; i<len; i+=4) { 23336384Ssklower register u_long l = 0; 23436384Ssklower 23536384Ssklower if ((len - i) < 4) { 23636384Ssklower /* buffer not multiple of 4 */ 23736384Ssklower switch (len - i) { 23836384Ssklower case 3: 23936384Ssklower l |= buf[i+2] << 8; 24036384Ssklower case 2: 24136384Ssklower l |= buf[i+1] << 16; 24236384Ssklower case 1: 24336384Ssklower l |= buf[i] << 24; 24436384Ssklower break; 24536384Ssklower default: 24636384Ssklower printf("iso_hashchar: unexpected value x%x\n", len - i); 24736384Ssklower break; 24836384Ssklower } 24936384Ssklower } else { 25036384Ssklower l |= buf[i] << 24; 25136384Ssklower l |= buf[i+1] << 16; 25236384Ssklower l |= buf[i+2] << 8; 25336384Ssklower l |= buf[i+3]; 25436384Ssklower } 25536384Ssklower 25636384Ssklower h ^= l; 25736384Ssklower } 25836384Ssklower 25936384Ssklower h ^= (u_long) (len % 4); 26036384Ssklower 26136384Ssklower return(h); 26236384Ssklower } 263*37469Ssklower #ifdef notdef 26436384Ssklower /* 26536384Ssklower * FUNCTION: iso_hash 26636384Ssklower * 26736384Ssklower * PURPOSE: Fill in fields of afhash structure based upon addr passed. 26836384Ssklower * 26936384Ssklower * RETURNS: none 27036384Ssklower * 27136384Ssklower * SIDE EFFECTS: 27236384Ssklower * 27336384Ssklower * NOTES: 27436384Ssklower */ 27536384Ssklower iso_hash(siso, hp) 27636384Ssklower struct sockaddr_iso *siso; /* address to perform hash on */ 27736384Ssklower struct afhash *hp; /* RETURN: hash info here */ 27836384Ssklower { 27936384Ssklower u_long buf[sizeof(struct sockaddr_iso)+1/4]; 28036384Ssklower register int bufsize; 28136384Ssklower 28236384Ssklower 28336384Ssklower bzero(buf, sizeof(buf)); 28436384Ssklower 28536384Ssklower bufsize = iso_netof(&siso->siso_addr, buf); 28636384Ssklower hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize); 28736384Ssklower 28836384Ssklower IFDEBUG(D_ROUTE) 28936384Ssklower printf("iso_hash: iso_netof: bufsize = %d\n", bufsize); 29036384Ssklower ENDDEBUG 29136384Ssklower 29236384Ssklower hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr, 29336384Ssklower siso->siso_addr.isoa_len); 29436384Ssklower 29536384Ssklower IFDEBUG(D_ROUTE) 29636384Ssklower printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n", 29736384Ssklower clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash, 29836384Ssklower hp->afh_hosthash); 29936384Ssklower ENDDEBUG 30036384Ssklower } 30136384Ssklower /* 30236384Ssklower * FUNCTION: iso_netof 30336384Ssklower * 30436384Ssklower * PURPOSE: Extract the network portion of the iso address. 30536384Ssklower * The network portion of the iso address varies depending 30636384Ssklower * on the type of address. The network portion of the 30736384Ssklower * address will include the IDP. The network portion is: 30836384Ssklower * 30936384Ssklower * TYPE DESC 31036384Ssklower * t37 The AFI and x.121 (IDI) 31136384Ssklower * osinet The AFI, orgid, snetid 31236384Ssklower * rfc986 The AFI, vers and network part of 31336384Ssklower * internet address. 31436384Ssklower * 31536384Ssklower * RETURNS: number of bytes placed into buf. 31636384Ssklower * 31736384Ssklower * SIDE EFFECTS: 31836384Ssklower * 31936384Ssklower * NOTES: Buf is assumed to be big enough 32036384Ssklower */ 32136384Ssklower iso_netof(isoa, buf) 32236384Ssklower struct iso_addr *isoa; /* address */ 32336384Ssklower caddr_t buf; /* RESULT: network portion of address here */ 32436384Ssklower { 32536384Ssklower u_int len = 1; /* length of afi */ 32636384Ssklower 32736384Ssklower switch (isoa->isoa_afi) { 32836384Ssklower case AFI_37: 32936384Ssklower /* 33036384Ssklower * Due to classic x.25 tunnel vision, there is no 33136384Ssklower * net portion of an x.121 address. For our purposes 33236384Ssklower * the AFI will do, so that all x.25 -type addresses 33336384Ssklower * map to the single x.25 SNPA. (Cannot have more than 33436384Ssklower * one, obviously). 33536384Ssklower */ 33636384Ssklower 33736384Ssklower break; 33836384Ssklower 33936384Ssklower /* case AFI_OSINET:*/ 34036384Ssklower case AFI_RFC986: { 34136384Ssklower u_short idi; /* value of idi */ 34236384Ssklower 34336384Ssklower /* osinet and rfc986 have idi in the same place */ 34436384Ssklower CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi); 34536384Ssklower 34636384Ssklower if (idi == IDI_OSINET) 34736384Ssklower /* 34836384Ssklower * Network portion of OSINET address can only be the IDI. Clearly, 34936384Ssklower * with one x25 interface, one could get to several orgids, and 35036384Ssklower * several snetids. 35136384Ssklower len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN + 35236384Ssklower OVLOSINET_SNETID_LEN); 35336384Ssklower */ 35436384Ssklower len += ADDROSINET_IDI_LEN; 35536384Ssklower else if (idi == IDI_RFC986) { 35636384Ssklower u_long inetaddr; 35736384Ssklower struct ovl_rfc986 *o986 = (struct ovl_rfc986 *)isoa; 35836384Ssklower 35936384Ssklower /* bump len to include idi and version (1 byte) */ 36036384Ssklower len += ADDRRFC986_IDI_LEN + 1; 36136384Ssklower 36236384Ssklower /* get inet addr long aligned */ 36336384Ssklower bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr)); 36436384Ssklower inetaddr = ntohl(inetaddr); /* convert to host byte order */ 36536384Ssklower 36636384Ssklower IFDEBUG(D_ROUTE) 36736384Ssklower printf("iso_netof: isoa "); 36836384Ssklower dump_buf(isoa, sizeof(*isoa)); 36936384Ssklower printf("iso_netof: inetaddr 0x%x ", inetaddr); 37036384Ssklower ENDDEBUG 37136384Ssklower 37236384Ssklower /* bump len by size of network portion of inet address */ 37336384Ssklower if (IN_CLASSA(inetaddr)) { 37436384Ssklower len += 4-IN_CLASSA_NSHIFT/8; 37536384Ssklower IFDEBUG(D_ROUTE) 37636384Ssklower printf("iso_netof: class A net len is now %d\n", len); 37736384Ssklower ENDDEBUG 37836384Ssklower } else if (IN_CLASSB(inetaddr)) { 37936384Ssklower len += 4-IN_CLASSB_NSHIFT/8; 38036384Ssklower IFDEBUG(D_ROUTE) 38136384Ssklower printf("iso_netof: class B net len is now %d\n", len); 38236384Ssklower ENDDEBUG 38336384Ssklower } else { 38436384Ssklower len += 4-IN_CLASSC_NSHIFT/8; 38536384Ssklower IFDEBUG(D_ROUTE) 38636384Ssklower printf("iso_netof: class C net len is now %d\n", len); 38736384Ssklower ENDDEBUG 38836384Ssklower } 38936384Ssklower } else 39036384Ssklower len = 0; 39136384Ssklower } break; 39236384Ssklower 39336384Ssklower default: 39436384Ssklower len = 0; 39536384Ssklower } 39636384Ssklower 39736384Ssklower bcopy((caddr_t)isoa, buf, len); 39836384Ssklower IFDEBUG(D_ROUTE) 39936384Ssklower printf("in_netof: isoa "); 40036384Ssklower dump_buf(isoa, len); 40136384Ssklower printf("in_netof: net "); 40236384Ssklower dump_buf(buf, len); 40336384Ssklower ENDDEBUG 40436384Ssklower return len; 40536384Ssklower } 406*37469Ssklower #endif notdef 40736384Ssklower /* 408*37469Ssklower * Generic iso control operations (ioctl's). 409*37469Ssklower * Ifp is 0 if not an interface-specific ioctl. 41036384Ssklower */ 411*37469Ssklower /* ARGSUSED */ 41236384Ssklower iso_control(so, cmd, data, ifp) 413*37469Ssklower struct socket *so; 414*37469Ssklower int cmd; 415*37469Ssklower caddr_t data; 416*37469Ssklower register struct ifnet *ifp; 41736384Ssklower { 418*37469Ssklower register struct iso_ifreq *ifr = (struct iso_ifreq *)data; 419*37469Ssklower register struct iso_ifaddr *ia = 0; 420*37469Ssklower register struct ifaddr *ifa; 421*37469Ssklower struct iso_ifaddr *oia; 422*37469Ssklower struct iso_aliasreq *ifra = (struct iso_aliasreq *)data; 423*37469Ssklower int error, hostIsNew, maskIsNew; 42436384Ssklower 425*37469Ssklower /* 426*37469Ssklower * Find address for this interface, if it exists. 427*37469Ssklower */ 428*37469Ssklower if (ifp) 429*37469Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) 430*37469Ssklower if (ia->ia_ifp == ifp) 431*37469Ssklower break; 43236384Ssklower 43336384Ssklower switch (cmd) { 434*37469Ssklower 435*37469Ssklower case SIOCAIFADDR_ISO: 436*37469Ssklower case SIOCDIFADDR_ISO: 437*37469Ssklower if (ifra->ifra_addr.siso_family == AF_ISO) 438*37469Ssklower for (oia = ia; ia; ia = ia->ia_next) { 439*37469Ssklower if (ia->ia_ifp == ifp && 440*37469Ssklower SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) 441*37469Ssklower break; 442*37469Ssklower } 44336384Ssklower if (!suser()) 44436384Ssklower return (u.u_error); 44536384Ssklower if (ifp == 0) 446*37469Ssklower panic("iso_control"); 447*37469Ssklower if (ia == (struct iso_ifaddr *)0) { 448*37469Ssklower struct iso_ifaddr *nia; 449*37469Ssklower if (cmd == SIOCDIFADDR_ISO) 450*37469Ssklower return (EADDRNOTAVAIL); 451*37469Ssklower MALLOC(nia, struct iso_ifaddr *, sizeof(*nia), 452*37469Ssklower M_IFADDR, M_WAITOK); 453*37469Ssklower if (nia == (struct iso_ifaddr *)0) 454*37469Ssklower return (ENOBUFS); 455*37469Ssklower bzero((caddr_t)nia, sizeof(*nia)); 456*37469Ssklower if (ia = iso_ifaddr) { 457*37469Ssklower for ( ; ia->ia_next; ia = ia->ia_next) 458*37469Ssklower ; 459*37469Ssklower ia->ia_next = nia; 460*37469Ssklower } else 461*37469Ssklower iso_ifaddr = nia; 462*37469Ssklower ia = nia; 463*37469Ssklower if (ifa = ifp->if_addrlist) { 464*37469Ssklower for ( ; ifa->ifa_next; ifa = ifa->ifa_next) 465*37469Ssklower ; 466*37469Ssklower ifa->ifa_next = (struct ifaddr *) ia; 467*37469Ssklower } else 468*37469Ssklower ifp->if_addrlist = (struct ifaddr *) ia; 469*37469Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 470*37469Ssklower ia->ia_ifa.ifa_dstaddr 471*37469Ssklower = (struct sockaddr *)&ia->ia_dstaddr; 472*37469Ssklower ia->ia_ifa.ifa_netmask 473*37469Ssklower = (struct sockaddr *)&ia->ia_sockmask; 474*37469Ssklower ia->ia_ifp = ifp; 475*37469Ssklower if (ifp != &loif) 476*37469Ssklower iso_interfaces++; 477*37469Ssklower } 478*37469Ssklower break; 47936384Ssklower 480*37469Ssklower #define cmdbyte(x) (((x) >> 8) & 0xff) 481*37469Ssklower default: 482*37469Ssklower if (cmdbyte(cmd) == 'a') 483*37469Ssklower return (snpac_ioctl(cmd, data)); 484*37469Ssklower if (ia == (struct iso_ifaddr *)0) 485*37469Ssklower return (EADDRNOTAVAIL); 486*37469Ssklower break; 487*37469Ssklower } 488*37469Ssklower switch (cmd) { 48936384Ssklower 490*37469Ssklower case SIOCGIFADDR_ISO: 491*37469Ssklower ifr->ifr_Addr = ia->ia_addr; 492*37469Ssklower break; 49336384Ssklower 494*37469Ssklower case SIOCGIFDSTADDR_ISO: 495*37469Ssklower if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 496*37469Ssklower return (EINVAL); 497*37469Ssklower ifr->ifr_Addr = ia->ia_dstaddr; 498*37469Ssklower break; 49936384Ssklower 500*37469Ssklower case SIOCGIFNETMASK_ISO: 501*37469Ssklower ifr->ifr_Addr = ia->ia_sockmask; 502*37469Ssklower break; 50336384Ssklower 504*37469Ssklower case SIOCAIFADDR_ISO: 505*37469Ssklower maskIsNew = 0; hostIsNew = 1; error = u.u_error; 506*37469Ssklower if (ia->ia_addr.siso_family == AF_ISO) { 507*37469Ssklower if (ifra->ifra_addr.siso_len == 0) { 508*37469Ssklower ifra->ifra_addr = ia->ia_addr; 509*37469Ssklower hostIsNew = 0; 510*37469Ssklower } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) 511*37469Ssklower hostIsNew = 0; 512*37469Ssklower } 513*37469Ssklower if (ifra->ifra_mask.siso_len) { 514*37469Ssklower iso_ifscrub(ifp, ia); 515*37469Ssklower ia->ia_sockmask = ifra->ifra_mask; 516*37469Ssklower maskIsNew = 1; 517*37469Ssklower } 518*37469Ssklower if ((ifp->if_flags & IFF_POINTOPOINT) && 519*37469Ssklower (ifra->ifra_dstaddr.siso_family == AF_ISO)) { 520*37469Ssklower iso_ifscrub(ifp, ia); 521*37469Ssklower ia->ia_dstaddr = ifra->ifra_dstaddr; 522*37469Ssklower maskIsNew = 1; /* We lie; but the effect's the same */ 523*37469Ssklower } 524*37469Ssklower if (ifra->ifra_addr.siso_family == AF_ISO && 525*37469Ssklower (hostIsNew || maskIsNew)) { 526*37469Ssklower error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0); 527*37469Ssklower } 528*37469Ssklower if (ifra->ifra_snpaoffset) 529*37469Ssklower ia->ia_snpaoffset = ifra->ifra_snpaoffset; 530*37469Ssklower return (error); 531*37469Ssklower 532*37469Ssklower case SIOCDIFADDR_ISO: 533*37469Ssklower iso_ifscrub(ifp, ia); 534*37469Ssklower if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) 535*37469Ssklower ifp->if_addrlist = ifa->ifa_next; 536*37469Ssklower else { 537*37469Ssklower while (ifa->ifa_next && 538*37469Ssklower (ifa->ifa_next != (struct ifaddr *)ia)) 539*37469Ssklower ifa = ifa->ifa_next; 540*37469Ssklower if (ifa->ifa_next) 541*37469Ssklower ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next; 542*37469Ssklower else 543*37469Ssklower printf("Couldn't unlink isoifaddr from ifp\n"); 544*37469Ssklower } 545*37469Ssklower oia = ia; 546*37469Ssklower if (oia == (ia = iso_ifaddr)) { 547*37469Ssklower iso_ifaddr = ia->ia_next; 548*37469Ssklower } else { 549*37469Ssklower while (ia->ia_next && (ia->ia_next != oia)) { 550*37469Ssklower ia = ia->ia_next; 55136384Ssklower } 552*37469Ssklower if (ia->ia_next) 553*37469Ssklower ia->ia_next = oia->ia_next; 554*37469Ssklower else 555*37469Ssklower printf("Didn't unlink isoifadr from list\n"); 55636384Ssklower } 557*37469Ssklower free((caddr_t)oia, M_IFADDR); 558*37469Ssklower break; 55936384Ssklower 56036384Ssklower default: 56136384Ssklower if (ifp == 0 || ifp->if_ioctl == 0) 56236384Ssklower return (EOPNOTSUPP); 56336384Ssklower return ((*ifp->if_ioctl)(ifp, cmd, data)); 56436384Ssklower } 565*37469Ssklower return (0); 56636384Ssklower } 56736384Ssklower 568*37469Ssklower /* 569*37469Ssklower * Delete any existing route for an interface. 570*37469Ssklower */ 571*37469Ssklower iso_ifscrub(ifp, ia) 572*37469Ssklower register struct ifnet *ifp; 573*37469Ssklower register struct iso_ifaddr *ia; 574*37469Ssklower { 575*37469Ssklower if ((ia->ia_flags & IFA_ROUTE) == 0) 576*37469Ssklower return; 577*37469Ssklower if (ifp->if_flags & IFF_LOOPBACK) 578*37469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 579*37469Ssklower else if (ifp->if_flags & IFF_POINTOPOINT) 580*37469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 581*37469Ssklower else { 582*37469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); 583*37469Ssklower } 584*37469Ssklower ia->ia_flags &= ~IFA_ROUTE; 585*37469Ssklower } 586*37469Ssklower 587*37469Ssklower /* 588*37469Ssklower * Initialize an interface's internet address 589*37469Ssklower * and routing table entry. 590*37469Ssklower */ 591*37469Ssklower iso_ifinit(ifp, ia, siso, scrub) 592*37469Ssklower register struct ifnet *ifp; 593*37469Ssklower register struct iso_ifaddr *ia; 594*37469Ssklower struct sockaddr_iso *siso; 595*37469Ssklower { 596*37469Ssklower struct sockaddr_iso oldaddr; 597*37469Ssklower int s = splimp(), error; 598*37469Ssklower 599*37469Ssklower oldaddr = ia->ia_addr; 600*37469Ssklower ia->ia_addr = *siso; 601*37469Ssklower /* 602*37469Ssklower * Give the interface a chance to initialize 603*37469Ssklower * if this is its first address, 604*37469Ssklower * and to validate the address if necessary. 605*37469Ssklower */ 606*37469Ssklower if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) { 607*37469Ssklower splx(s); 608*37469Ssklower ia->ia_addr = oldaddr; 609*37469Ssklower return (error); 610*37469Ssklower } 611*37469Ssklower if (scrub) { 612*37469Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 613*37469Ssklower iso_ifscrub(ifp, ia); 614*37469Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 615*37469Ssklower } 616*37469Ssklower /* 617*37469Ssklower * Add route for the network. 618*37469Ssklower */ 619*37469Ssklower if (ifp->if_flags & IFF_LOOPBACK) { 620*37469Ssklower ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; 621*37469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 622*37469Ssklower } else if (ifp->if_flags & IFF_POINTOPOINT && 623*37469Ssklower ia->ia_dstaddr.siso_family == AF_ISO) 624*37469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 625*37469Ssklower else { 626*37469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP); 627*37469Ssklower } 628*37469Ssklower ia->ia_flags |= IFA_ROUTE; 629*37469Ssklower splx(s); 630*37469Ssklower return (0); 631*37469Ssklower } 632*37469Ssklower #ifdef notdef 633*37469Ssklower 63436384Ssklower struct ifaddr * 63536384Ssklower iso_ifwithidi(addr) 63636384Ssklower register struct sockaddr *addr; 63736384Ssklower { 63836384Ssklower register struct ifnet *ifp; 63936384Ssklower register struct ifaddr *ifa; 64036384Ssklower register u_int af = addr->sa_family; 64136384Ssklower 64236384Ssklower if (af != AF_ISO) 64336384Ssklower return (0); 64436384Ssklower IFDEBUG(D_ROUTE) 64536384Ssklower printf(">>> iso_ifwithidi addr\n"); 64636384Ssklower dump_isoaddr( (struct sockaddr_iso *)(addr)); 64736384Ssklower printf("\n"); 64836384Ssklower ENDDEBUG 64936384Ssklower for (ifp = ifnet; ifp; ifp = ifp->if_next) { 65036384Ssklower IFDEBUG(D_ROUTE) 65136384Ssklower printf("iso_ifwithidi ifnet %s\n", ifp->if_name); 65236384Ssklower ENDDEBUG 65336384Ssklower for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 65436384Ssklower IFDEBUG(D_ROUTE) 65536384Ssklower printf("iso_ifwithidi address "); 656*37469Ssklower dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr)); 65736384Ssklower ENDDEBUG 658*37469Ssklower if (ifa->ifa_addr->sa_family != addr->sa_family) 65936384Ssklower continue; 66036384Ssklower 66136384Ssklower #define IFA_SIS(ifa)\ 662*37469Ssklower ((struct sockaddr_iso *)((ifa)->ifa_addr)) 66336384Ssklower 66436384Ssklower IFDEBUG(D_ROUTE) 66536384Ssklower printf(" af same, args to iso_eqtype:\n"); 66636384Ssklower printf("0x%x ", IFA_SIS(ifa)->siso_addr); 66736384Ssklower printf(" 0x%x\n", 66836384Ssklower &(((struct sockaddr_iso *)addr)->siso_addr)); 66936384Ssklower ENDDEBUG 67036384Ssklower 67136384Ssklower if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr), 67236384Ssklower &(((struct sockaddr_iso *)addr)->siso_addr))) { 67336384Ssklower IFDEBUG(D_ROUTE) 67436384Ssklower printf("ifa_ifwithidi: ifa found\n"); 67536384Ssklower ENDDEBUG 67636384Ssklower return (ifa); 67736384Ssklower } 67836384Ssklower IFDEBUG(D_ROUTE) 67936384Ssklower printf(" iso_eqtype failed\n"); 68036384Ssklower ENDDEBUG 68136384Ssklower } 68236384Ssklower } 68336384Ssklower return ((struct ifaddr *)0); 68436384Ssklower } 68536384Ssklower 686*37469Ssklower #endif notdef 68736384Ssklower /* 68836384Ssklower * FUNCTION: iso_ck_addr 68936384Ssklower * 69036384Ssklower * PURPOSE: return true if the iso_addr passed is 69136384Ssklower * within the legal size limit for an iso address. 69236384Ssklower * 69336384Ssklower * RETURNS: true or false 69436384Ssklower * 69536384Ssklower * SIDE EFFECTS: 69636384Ssklower * 69736384Ssklower */ 69836384Ssklower iso_ck_addr(isoa) 69936384Ssklower struct iso_addr *isoa; /* address to check */ 70036384Ssklower { 70136384Ssklower return (isoa->isoa_len <= 20); 70236384Ssklower 70336384Ssklower } 70436384Ssklower 705*37469Ssklower #ifdef notdef 70636384Ssklower /* 70736384Ssklower * FUNCTION: iso_eqtype 70836384Ssklower * 70936384Ssklower * PURPOSE: Determine if two iso addresses are of the same type. 71036384Ssklower * This is flaky. Really we should consider all type 47 addrs to be the 71136384Ssklower * same - but there do exist different structures for 47 addrs. 71236384Ssklower * Gosip adds a 3rd. 71336384Ssklower * 71436384Ssklower * RETURNS: true if the addresses are the same type 71536384Ssklower * 71636384Ssklower * SIDE EFFECTS: 71736384Ssklower * 71836384Ssklower * NOTES: By type, I mean rfc986, t37, or osinet 71936384Ssklower * 72036384Ssklower * This will first compare afis. If they match, then 72136384Ssklower * if the addr is not t37, the idis must be compared. 72236384Ssklower */ 72336384Ssklower iso_eqtype(isoaa, isoab) 72436384Ssklower struct iso_addr *isoaa; /* first addr to check */ 72536384Ssklower struct iso_addr *isoab; /* other addr to check */ 72636384Ssklower { 72736384Ssklower if (isoaa->isoa_afi == isoab->isoa_afi) { 72836384Ssklower if (isoaa->isoa_afi == AFI_37) 72936384Ssklower return(1); 73036384Ssklower else 73136384Ssklower return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2)); 73236384Ssklower } 73336384Ssklower return(0); 73436384Ssklower } 735*37469Ssklower #endif notdef 73636384Ssklower /* 737*37469Ssklower * FUNCTION: iso_localifa() 73836384Ssklower * 739*37469Ssklower * PURPOSE: Find an interface addresss having a given destination 740*37469Ssklower * or at least matching the net. 74136384Ssklower * 74236384Ssklower * RETURNS: ptr to an interface address 74336384Ssklower * 74436384Ssklower * SIDE EFFECTS: 74536384Ssklower * 74636384Ssklower * NOTES: 74736384Ssklower */ 74836384Ssklower struct iso_ifaddr * 749*37469Ssklower iso_localifa(siso) 750*37469Ssklower register struct sockaddr_iso *siso; 75136384Ssklower { 75236384Ssklower register struct iso_ifaddr *ia; 753*37469Ssklower register char *cp1, *cp2, *cp3; 754*37469Ssklower register struct ifnet *ifp; 755*37469Ssklower struct iso_ifaddr *ia_maybe = 0; 756*37469Ssklower /* 757*37469Ssklower * We make one pass looking for both net matches and an exact 758*37469Ssklower * dst addr. 759*37469Ssklower */ 760*37469Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) { 761*37469Ssklower if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0)) 762*37469Ssklower continue; 763*37469Ssklower if (ifp->if_flags & IFF_POINTOPOINT) { 764*37469Ssklower if ((ia->ia_dstaddr.siso_family == AF_ISO) && 765*37469Ssklower SAME_ISOADDR(&ia->ia_dstaddr, siso)) 766*37469Ssklower return (ia); 767*37469Ssklower else 768*37469Ssklower if (SAME_ISOADDR(&ia->ia_addr, siso)) 769*37469Ssklower ia_maybe = ia; 770*37469Ssklower continue; 771*37469Ssklower } 772*37469Ssklower if (ia->ia_sockmask.siso_len) { 773*37469Ssklower char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask; 774*37469Ssklower cp1 = ia->ia_sockmask.siso_data; 775*37469Ssklower cp2 = siso->siso_data; 776*37469Ssklower cp3 = ia->ia_addr.siso_data; 777*37469Ssklower while (cp2 < cplim) 778*37469Ssklower if (*cp1++ & (*cp2++ ^ *cp3++)) 779*37469Ssklower goto next; 780*37469Ssklower ia_maybe = ia; 781*37469Ssklower } 782*37469Ssklower if (SAME_ISOADDR(&ia->ia_addr, siso)) 783*37469Ssklower return ia; 784*37469Ssklower next:; 785*37469Ssklower } 786*37469Ssklower return ia_maybe; 78736384Ssklower } 78836384Ssklower 78936384Ssklower #ifdef NARGOXTWENTYFIVE > 0 79036384Ssklower #include "cons.h" 79136384Ssklower #endif NARGOXTWENTYFIVE > 0 79236384Ssklower /* 79336384Ssklower * FUNCTION: iso_nlctloutput 79436384Ssklower * 79536384Ssklower * PURPOSE: Set options at the network level 79636384Ssklower * 79736384Ssklower * RETURNS: E* 79836384Ssklower * 79936384Ssklower * SIDE EFFECTS: 80036384Ssklower * 80136384Ssklower * NOTES: This could embody some of the functions of 80236384Ssklower * rclnp_ctloutput and cons_ctloutput. 80336384Ssklower */ 80436384Ssklower iso_nlctloutput(cmd, optname, pcb, m) 80536384Ssklower int cmd; /* command:set or get */ 80636384Ssklower int optname; /* option of interest */ 80736384Ssklower caddr_t pcb; /* nl pcb */ 80836384Ssklower struct mbuf *m; /* data for set, buffer for get */ 80936384Ssklower { 81036384Ssklower struct isopcb *isop = (struct isopcb *)pcb; 81136384Ssklower int error = 0; /* return value */ 81236384Ssklower caddr_t data; /* data for option */ 81336384Ssklower int data_len; /* data's length */ 81436384Ssklower 81536384Ssklower IFDEBUG(D_ISO) 81636384Ssklower printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n", 81736384Ssklower cmd, optname, pcb, m); 81836384Ssklower ENDDEBUG 81936384Ssklower 82036384Ssklower if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT)) 82136384Ssklower return(EOPNOTSUPP); 82236384Ssklower 82336384Ssklower data = mtod(m, caddr_t); 82436384Ssklower data_len = (m)->m_len; 82536384Ssklower 82636384Ssklower IFDEBUG(D_ISO) 82736384Ssklower printf("iso_nlctloutput: data is:\n"); 82836384Ssklower dump_buf(data, data_len); 82936384Ssklower ENDDEBUG 83036384Ssklower 83136384Ssklower switch (optname) { 83236384Ssklower 83336384Ssklower #ifdef NARGOXTWENTYFIVE > 0 83436384Ssklower case CONSOPT_X25CRUD: 83536384Ssklower if (cmd == PRCO_GETOPT) { 83636384Ssklower error = EOPNOTSUPP; 83736384Ssklower break; 83836384Ssklower } 83936384Ssklower 84036384Ssklower if (data_len > MAXX25CRUDLEN) { 84136384Ssklower error = EINVAL; 84236384Ssklower break; 84336384Ssklower } 84436384Ssklower 84536384Ssklower IFDEBUG(D_ISO) 84636384Ssklower printf("iso_nlctloutput: setting x25 crud\n"); 84736384Ssklower ENDDEBUG 84836384Ssklower 849*37469Ssklower bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len); 85036384Ssklower isop->isop_x25crud_len = data_len; 85136384Ssklower break; 85236384Ssklower #endif NARGOXTWENTYFIVE > 0 85336384Ssklower 85436384Ssklower default: 85536384Ssklower error = EOPNOTSUPP; 85636384Ssklower } 85736384Ssklower 85836384Ssklower return error; 85936384Ssklower } 86036384Ssklower 86136384Ssklower /* 86236384Ssklower * FUNCTION: iso_routeifp 86336384Ssklower * 86436384Ssklower * PURPOSE: Route on a sockaddr and return ifp 86536384Ssklower * 86636384Ssklower * RETURNS: ifp of outgoing interface, or null 86736384Ssklower * 86836384Ssklower * SIDE EFFECTS: 86936384Ssklower * 87036384Ssklower * NOTES: 87136384Ssklower */ 872*37469Ssklower struct iso_ifaddr * 873*37469Ssklower iso_routeifa(dst) 87436384Ssklower struct sockaddr *dst; /* destination to route to */ 87536384Ssklower { 876*37469Ssklower struct rtentry *rt; 877*37469Ssklower struct ifaddr *ifa = 0; 878*37469Ssklower struct ifnet *ifp = 0; 87936384Ssklower 88036384Ssklower 88136384Ssklower IFDEBUG(D_ROUTE) 88236384Ssklower printf("iso_routeifp: dst:"); 883*37469Ssklower dump_isoaddr((struct sockaddr_iso *)dst); 88436384Ssklower ENDDEBUG 88536384Ssklower 886*37469Ssklower rt = rtalloc1(dst, 0); 88736384Ssklower 888*37469Ssklower if (rt) { 889*37469Ssklower ifa = rt->rt_ifa; 890*37469Ssklower ifp = rt->rt_ifp; 891*37469Ssklower RTFREE(rt); 89236384Ssklower } 89336384Ssklower 89436384Ssklower IFDEBUG(D_ROUTE) 895*37469Ssklower printf("iso_routeifp: ifa x%x", ifa); 89636384Ssklower if (ifp) 89736384Ssklower printf(" (%s%d)\n", ifp->if_name, ifp->if_unit); 89836384Ssklower else 89936384Ssklower printf("\n"); 90036384Ssklower ENDDEBUG 90136384Ssklower 902*37469Ssklower return((struct iso_ifaddr *)ifa); 90336384Ssklower } 90436384Ssklower #endif ISO 90536384Ssklower 90636384Ssklower #ifdef ARGO_DEBUG 90736384Ssklower 90836384Ssklower /* 90936384Ssklower * FUNCTION: dump_isoaddr 91036384Ssklower * 91136384Ssklower * PURPOSE: debugging 91236384Ssklower * 91336384Ssklower * RETURNS: nada 91436384Ssklower * 91536384Ssklower */ 91636384Ssklower dump_isoaddr(s) 91736384Ssklower struct sockaddr_iso *s; 91836384Ssklower { 919*37469Ssklower char *clnp_saddr_isop(); 92036384Ssklower register int i; 92136384Ssklower 92236384Ssklower if( s->siso_family == AF_ISO) { 923*37469Ssklower printf("ISO address: suffixlen %d, %s\n", 924*37469Ssklower s->siso_tsuffixlen, clnp_saddr_isop(s)); 92536384Ssklower } else if( s->siso_family == AF_INET) { 92636384Ssklower /* hack */ 92736384Ssklower struct sockaddr_in *sin = (struct sockaddr_in *)s; 92836384Ssklower 92936384Ssklower printf("%d.%d.%d.%d: %d", 93036384Ssklower (sin->sin_addr.s_addr>>24)&0xff, 93136384Ssklower (sin->sin_addr.s_addr>>16)&0xff, 93236384Ssklower (sin->sin_addr.s_addr>>8)&0xff, 93336384Ssklower (sin->sin_addr.s_addr)&0xff, 93436384Ssklower sin->sin_port); 93536384Ssklower } 93636384Ssklower } 93736384Ssklower 93836384Ssklower #endif ARGO_DEBUG 939