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*39936Ssklower * @(#)iso.c 7.7 (Berkeley) 01/17/90 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 4037469Ssklower #include "types.h" 4137469Ssklower #include "param.h" 4237469Ssklower #include "ioctl.h" 4337469Ssklower #include "mbuf.h" 4437469Ssklower #include "domain.h" 4537469Ssklower #include "protosw.h" 4637469Ssklower #include "socket.h" 4737469Ssklower #include "socketvar.h" 4837469Ssklower #include "user.h" 4937469Ssklower #include "errno.h" 5036384Ssklower 5136384Ssklower #include "../net/if.h" 5236384Ssklower #include "../net/route.h" 5336384Ssklower #include "../net/af.h" 5436384Ssklower 5537469Ssklower #include "iso.h" 5637469Ssklower #include "iso_var.h" 5737469Ssklower #include "iso_snpac.h" 5837469Ssklower #include "iso_pcb.h" 5937469Ssklower #include "clnp.h" 6037469Ssklower #include "argo_debug.h" 6136384Ssklower 6236384Ssklower #ifdef ISO 6337469Ssklower #include "argoxtwentyfive.h" 6436384Ssklower 6536384Ssklower int iso_interfaces = 0; /* number of external interfaces */ 6636384Ssklower extern struct ifnet loif; /* loopback interface */ 6736384Ssklower 6836384Ssklower 6936384Ssklower /* 7036384Ssklower * FUNCTION: iso_init 7136384Ssklower * 7236384Ssklower * PURPOSE: initialize the iso address family 7336384Ssklower * 7436384Ssklower * RETURNS: nothing 7536384Ssklower * 7636384Ssklower * SIDE EFFECTS: 1) zeros the maptab table. 7737469Ssklower * 2) initializes the routing table. 7836384Ssklower * 7936384Ssklower * NOTES: 8036384Ssklower */ 8137469Ssklower struct radix_node_head *iso_rnhead; 8236384Ssklower iso_init() 8336384Ssklower { 8437469Ssklower extern struct spna_cache iso_snpac[]; 8537469Ssklower extern u_int iso_snpac_size; 8637469Ssklower static iso_init_done; 8736384Ssklower 8837469Ssklower if (iso_init_done == 0) { 8937469Ssklower iso_init_done++; 9037469Ssklower bzero((caddr_t)iso_snpac, iso_snpac_size * sizeof(struct snpa_cache)); 9137469Ssklower rn_inithead(&iso_rnhead, 40, AF_ISO); 9237469Ssklower } 9336384Ssklower } 9436384Ssklower 9536384Ssklower /* 9636384Ssklower * FUNCTION: iso_addrmatch1 9736384Ssklower * 9836384Ssklower * PURPOSE: decide if the two iso_addrs passed are equal 9936384Ssklower * 10036384Ssklower * RETURNS: true if the addrs match, false if they do not 10136384Ssklower * 10236384Ssklower * SIDE EFFECTS: 10336384Ssklower * 10436384Ssklower * NOTES: 10536384Ssklower */ 10636384Ssklower iso_addrmatch1(isoaa, isoab) 10737469Ssklower register struct iso_addr *isoaa, *isoab; /* addresses to check */ 10836384Ssklower { 10937469Ssklower u_int compare_len; 11036384Ssklower 11136384Ssklower IFDEBUG(D_ROUTE) 11236384Ssklower printf("iso_addrmatch1: comparing lengths: %d to %d\n", isoaa->isoa_len, 11336384Ssklower isoab->isoa_len); 11436384Ssklower printf("a:\n"); 11537469Ssklower dump_buf(isoaa->isoa_genaddr, isoaa->isoa_len); 11636384Ssklower printf("b:\n"); 11737469Ssklower dump_buf(isoab->isoa_genaddr, isoab->isoa_len); 11836384Ssklower ENDDEBUG 11936384Ssklower 12036384Ssklower if ((compare_len = isoaa->isoa_len) != isoab->isoa_len) { 12136384Ssklower IFDEBUG(D_ROUTE) 12236384Ssklower printf("iso_addrmatch1: returning false because of lengths\n"); 12336384Ssklower ENDDEBUG 12436384Ssklower return 0; 12536384Ssklower } 12636384Ssklower 12737469Ssklower #ifdef notdef 12836384Ssklower /* TODO : generalize this to all afis with masks */ 12936384Ssklower if( isoaa->isoa_afi == AFI_37 ) { 13036384Ssklower /* must not compare 2 least significant digits, or for 13136384Ssklower * that matter, the DSP 13236384Ssklower */ 13336384Ssklower compare_len = ADDR37_IDI_LEN - 1; 13436384Ssklower } 13537469Ssklower #endif 13636384Ssklower 13736384Ssklower IFDEBUG(D_ROUTE) 13836384Ssklower int i; 13936384Ssklower char *a, *b; 14036384Ssklower 14137469Ssklower a = isoaa->isoa_genaddr; 14237469Ssklower b = isoab->isoa_genaddr; 14336384Ssklower 14436384Ssklower for (i=0; i<compare_len; i++) { 14536384Ssklower printf("<%x=%x>", a[i]&0xff, b[i]&0xff); 14636384Ssklower if (a[i] != b[i]) { 14736384Ssklower printf("\naddrs are not equal at byte %d\n", i); 14836384Ssklower return(0); 14936384Ssklower } 15036384Ssklower } 15136384Ssklower printf("\n"); 15236384Ssklower printf("addrs are equal\n"); 15336384Ssklower return (1); 15436384Ssklower ENDDEBUG 15537469Ssklower return (!bcmp(isoaa->isoa_genaddr, isoab->isoa_genaddr, compare_len)); 15636384Ssklower } 15736384Ssklower 15836384Ssklower /* 15936384Ssklower * FUNCTION: iso_addrmatch 16036384Ssklower * 16136384Ssklower * PURPOSE: decide if the two sockadrr_isos passed are equal 16236384Ssklower * 16336384Ssklower * RETURNS: true if the addrs match, false if they do not 16436384Ssklower * 16536384Ssklower * SIDE EFFECTS: 16636384Ssklower * 16736384Ssklower * NOTES: 16836384Ssklower */ 16936384Ssklower iso_addrmatch(sisoa, sisob) 17036384Ssklower struct sockaddr_iso *sisoa, *sisob; /* addresses to check */ 17136384Ssklower { 17236384Ssklower return(iso_addrmatch1(&sisoa->siso_addr, &sisob->siso_addr)); 17336384Ssklower } 17437469Ssklower #ifdef notdef 17536384Ssklower /* 17636384Ssklower * FUNCTION: iso_netmatch 17736384Ssklower * 17836384Ssklower * PURPOSE: similar to iso_addrmatch but takes sockaddr_iso 17936384Ssklower * as argument. 18036384Ssklower * 18136384Ssklower * RETURNS: true if same net, false if not 18236384Ssklower * 18336384Ssklower * SIDE EFFECTS: 18436384Ssklower * 18536384Ssklower * NOTES: 18636384Ssklower */ 18736384Ssklower iso_netmatch(sisoa, sisob) 18836384Ssklower struct sockaddr_iso *sisoa, *sisob; 18936384Ssklower { 19036384Ssklower u_char bufa[sizeof(struct sockaddr_iso)]; 19136384Ssklower u_char bufb[sizeof(struct sockaddr_iso)]; 19236384Ssklower register int lena, lenb; 19336384Ssklower 19436384Ssklower lena = iso_netof(&sisoa->siso_addr, bufa); 19536384Ssklower lenb = iso_netof(&sisob->siso_addr, bufb); 19636384Ssklower 19736384Ssklower IFDEBUG(D_ROUTE) 19836384Ssklower printf("iso_netmatch: comparing lengths: %d to %d\n", lena, lenb); 19936384Ssklower printf("a:\n"); 20036384Ssklower dump_buf(bufa, lena); 20136384Ssklower printf("b:\n"); 20236384Ssklower dump_buf(bufb, lenb); 20336384Ssklower ENDDEBUG 20436384Ssklower 20536384Ssklower return ((lena == lenb) && (!bcmp(bufa, bufb, lena))); 20636384Ssklower } 20737469Ssklower #endif notdef 20836384Ssklower 20936384Ssklower /* 21036384Ssklower * FUNCTION: iso_hashchar 21136384Ssklower * 21236384Ssklower * PURPOSE: Hash all character in the buffer specified into 21336384Ssklower * a long. Return the long. 21436384Ssklower * 21536384Ssklower * RETURNS: The hash value. 21636384Ssklower * 21736384Ssklower * SIDE EFFECTS: 21836384Ssklower * 21936384Ssklower * NOTES: The hash is achieved by exclusive ORing 4 byte 22036384Ssklower * quantities. 22136384Ssklower */ 22236384Ssklower u_long 22336384Ssklower iso_hashchar(buf, len) 22436384Ssklower register caddr_t buf; /* buffer to pack from */ 22536384Ssklower register int len; /* length of buffer */ 22636384Ssklower { 22736384Ssklower register u_long h = 0; 22836384Ssklower register int i; 22936384Ssklower 23036384Ssklower for (i=0; i<len; i+=4) { 23136384Ssklower register u_long l = 0; 23236384Ssklower 23336384Ssklower if ((len - i) < 4) { 23436384Ssklower /* buffer not multiple of 4 */ 23536384Ssklower switch (len - i) { 23636384Ssklower case 3: 23736384Ssklower l |= buf[i+2] << 8; 23836384Ssklower case 2: 23936384Ssklower l |= buf[i+1] << 16; 24036384Ssklower case 1: 24136384Ssklower l |= buf[i] << 24; 24236384Ssklower break; 24336384Ssklower default: 24436384Ssklower printf("iso_hashchar: unexpected value x%x\n", len - i); 24536384Ssklower break; 24636384Ssklower } 24736384Ssklower } else { 24836384Ssklower l |= buf[i] << 24; 24936384Ssklower l |= buf[i+1] << 16; 25036384Ssklower l |= buf[i+2] << 8; 25136384Ssklower l |= buf[i+3]; 25236384Ssklower } 25336384Ssklower 25436384Ssklower h ^= l; 25536384Ssklower } 25636384Ssklower 25736384Ssklower h ^= (u_long) (len % 4); 25836384Ssklower 25936384Ssklower return(h); 26036384Ssklower } 26137469Ssklower #ifdef notdef 26236384Ssklower /* 26336384Ssklower * FUNCTION: iso_hash 26436384Ssklower * 26536384Ssklower * PURPOSE: Fill in fields of afhash structure based upon addr passed. 26636384Ssklower * 26736384Ssklower * RETURNS: none 26836384Ssklower * 26936384Ssklower * SIDE EFFECTS: 27036384Ssklower * 27136384Ssklower * NOTES: 27236384Ssklower */ 27336384Ssklower iso_hash(siso, hp) 27436384Ssklower struct sockaddr_iso *siso; /* address to perform hash on */ 27536384Ssklower struct afhash *hp; /* RETURN: hash info here */ 27636384Ssklower { 27736384Ssklower u_long buf[sizeof(struct sockaddr_iso)+1/4]; 27836384Ssklower register int bufsize; 27936384Ssklower 28036384Ssklower 28136384Ssklower bzero(buf, sizeof(buf)); 28236384Ssklower 28336384Ssklower bufsize = iso_netof(&siso->siso_addr, buf); 28436384Ssklower hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize); 28536384Ssklower 28636384Ssklower IFDEBUG(D_ROUTE) 28736384Ssklower printf("iso_hash: iso_netof: bufsize = %d\n", bufsize); 28836384Ssklower ENDDEBUG 28936384Ssklower 29036384Ssklower hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr, 29136384Ssklower siso->siso_addr.isoa_len); 29236384Ssklower 29336384Ssklower IFDEBUG(D_ROUTE) 29436384Ssklower printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n", 29536384Ssklower clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash, 29636384Ssklower hp->afh_hosthash); 29736384Ssklower ENDDEBUG 29836384Ssklower } 29936384Ssklower /* 30036384Ssklower * FUNCTION: iso_netof 30136384Ssklower * 30236384Ssklower * PURPOSE: Extract the network portion of the iso address. 30336384Ssklower * The network portion of the iso address varies depending 30436384Ssklower * on the type of address. The network portion of the 30536384Ssklower * address will include the IDP. The network portion is: 30636384Ssklower * 30736384Ssklower * TYPE DESC 30836384Ssklower * t37 The AFI and x.121 (IDI) 30936384Ssklower * osinet The AFI, orgid, snetid 31036384Ssklower * rfc986 The AFI, vers and network part of 31136384Ssklower * internet address. 31236384Ssklower * 31336384Ssklower * RETURNS: number of bytes placed into buf. 31436384Ssklower * 31536384Ssklower * SIDE EFFECTS: 31636384Ssklower * 31736384Ssklower * NOTES: Buf is assumed to be big enough 31836384Ssklower */ 31936384Ssklower iso_netof(isoa, buf) 32036384Ssklower struct iso_addr *isoa; /* address */ 32136384Ssklower caddr_t buf; /* RESULT: network portion of address here */ 32236384Ssklower { 32336384Ssklower u_int len = 1; /* length of afi */ 32436384Ssklower 32536384Ssklower switch (isoa->isoa_afi) { 32636384Ssklower case AFI_37: 32736384Ssklower /* 32836384Ssklower * Due to classic x.25 tunnel vision, there is no 32936384Ssklower * net portion of an x.121 address. For our purposes 33036384Ssklower * the AFI will do, so that all x.25 -type addresses 33136384Ssklower * map to the single x.25 SNPA. (Cannot have more than 33236384Ssklower * one, obviously). 33336384Ssklower */ 33436384Ssklower 33536384Ssklower break; 33636384Ssklower 33736384Ssklower /* case AFI_OSINET:*/ 33836384Ssklower case AFI_RFC986: { 33936384Ssklower u_short idi; /* value of idi */ 34036384Ssklower 34136384Ssklower /* osinet and rfc986 have idi in the same place */ 34236384Ssklower CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi); 34336384Ssklower 34436384Ssklower if (idi == IDI_OSINET) 34536384Ssklower /* 34636384Ssklower * Network portion of OSINET address can only be the IDI. Clearly, 34736384Ssklower * with one x25 interface, one could get to several orgids, and 34836384Ssklower * several snetids. 34936384Ssklower len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN + 35036384Ssklower OVLOSINET_SNETID_LEN); 35136384Ssklower */ 35236384Ssklower len += ADDROSINET_IDI_LEN; 35336384Ssklower else if (idi == IDI_RFC986) { 35436384Ssklower u_long inetaddr; 35536384Ssklower struct ovl_rfc986 *o986 = (struct ovl_rfc986 *)isoa; 35636384Ssklower 35736384Ssklower /* bump len to include idi and version (1 byte) */ 35836384Ssklower len += ADDRRFC986_IDI_LEN + 1; 35936384Ssklower 36036384Ssklower /* get inet addr long aligned */ 36136384Ssklower bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr)); 36236384Ssklower inetaddr = ntohl(inetaddr); /* convert to host byte order */ 36336384Ssklower 36436384Ssklower IFDEBUG(D_ROUTE) 36536384Ssklower printf("iso_netof: isoa "); 36636384Ssklower dump_buf(isoa, sizeof(*isoa)); 36736384Ssklower printf("iso_netof: inetaddr 0x%x ", inetaddr); 36836384Ssklower ENDDEBUG 36936384Ssklower 37036384Ssklower /* bump len by size of network portion of inet address */ 37136384Ssklower if (IN_CLASSA(inetaddr)) { 37236384Ssklower len += 4-IN_CLASSA_NSHIFT/8; 37336384Ssklower IFDEBUG(D_ROUTE) 37436384Ssklower printf("iso_netof: class A net len is now %d\n", len); 37536384Ssklower ENDDEBUG 37636384Ssklower } else if (IN_CLASSB(inetaddr)) { 37736384Ssklower len += 4-IN_CLASSB_NSHIFT/8; 37836384Ssklower IFDEBUG(D_ROUTE) 37936384Ssklower printf("iso_netof: class B net len is now %d\n", len); 38036384Ssklower ENDDEBUG 38136384Ssklower } else { 38236384Ssklower len += 4-IN_CLASSC_NSHIFT/8; 38336384Ssklower IFDEBUG(D_ROUTE) 38436384Ssklower printf("iso_netof: class C net len is now %d\n", len); 38536384Ssklower ENDDEBUG 38636384Ssklower } 38736384Ssklower } else 38836384Ssklower len = 0; 38936384Ssklower } break; 39036384Ssklower 39136384Ssklower default: 39236384Ssklower len = 0; 39336384Ssklower } 39436384Ssklower 39536384Ssklower bcopy((caddr_t)isoa, buf, len); 39636384Ssklower IFDEBUG(D_ROUTE) 39736384Ssklower printf("in_netof: isoa "); 39836384Ssklower dump_buf(isoa, len); 39936384Ssklower printf("in_netof: net "); 40036384Ssklower dump_buf(buf, len); 40136384Ssklower ENDDEBUG 40236384Ssklower return len; 40336384Ssklower } 40437469Ssklower #endif notdef 40536384Ssklower /* 40637469Ssklower * Generic iso control operations (ioctl's). 40737469Ssklower * Ifp is 0 if not an interface-specific ioctl. 40836384Ssklower */ 40937469Ssklower /* ARGSUSED */ 41036384Ssklower iso_control(so, cmd, data, ifp) 41137469Ssklower struct socket *so; 41237469Ssklower int cmd; 41337469Ssklower caddr_t data; 41437469Ssklower register struct ifnet *ifp; 41536384Ssklower { 41637469Ssklower register struct iso_ifreq *ifr = (struct iso_ifreq *)data; 41737469Ssklower register struct iso_ifaddr *ia = 0; 41837469Ssklower register struct ifaddr *ifa; 41937469Ssklower struct iso_ifaddr *oia; 42037469Ssklower struct iso_aliasreq *ifra = (struct iso_aliasreq *)data; 42137469Ssklower int error, hostIsNew, maskIsNew; 42236384Ssklower 42337469Ssklower /* 42437469Ssklower * Find address for this interface, if it exists. 42537469Ssklower */ 42637469Ssklower if (ifp) 42737469Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) 42837469Ssklower if (ia->ia_ifp == ifp) 42937469Ssklower break; 43036384Ssklower 43136384Ssklower switch (cmd) { 43237469Ssklower 43337469Ssklower case SIOCAIFADDR_ISO: 43437469Ssklower case SIOCDIFADDR_ISO: 43537469Ssklower if (ifra->ifra_addr.siso_family == AF_ISO) 43637469Ssklower for (oia = ia; ia; ia = ia->ia_next) { 43737469Ssklower if (ia->ia_ifp == ifp && 43837469Ssklower SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) 43937469Ssklower break; 44037469Ssklower } 44137547Smckusick if (error = suser(u.u_cred, &u.u_acflag)) 44237547Smckusick return (error); 44336384Ssklower if (ifp == 0) 44437469Ssklower panic("iso_control"); 44537469Ssklower if (ia == (struct iso_ifaddr *)0) { 44637469Ssklower struct iso_ifaddr *nia; 44737469Ssklower if (cmd == SIOCDIFADDR_ISO) 44837469Ssklower return (EADDRNOTAVAIL); 44937469Ssklower MALLOC(nia, struct iso_ifaddr *, sizeof(*nia), 45037469Ssklower M_IFADDR, M_WAITOK); 45137469Ssklower if (nia == (struct iso_ifaddr *)0) 45237469Ssklower return (ENOBUFS); 45337469Ssklower bzero((caddr_t)nia, sizeof(*nia)); 45437469Ssklower if (ia = iso_ifaddr) { 45537469Ssklower for ( ; ia->ia_next; ia = ia->ia_next) 45637469Ssklower ; 45737469Ssklower ia->ia_next = nia; 45837469Ssklower } else 45937469Ssklower iso_ifaddr = nia; 46037469Ssklower ia = nia; 46137469Ssklower if (ifa = ifp->if_addrlist) { 46237469Ssklower for ( ; ifa->ifa_next; ifa = ifa->ifa_next) 46337469Ssklower ; 46437469Ssklower ifa->ifa_next = (struct ifaddr *) ia; 46537469Ssklower } else 46637469Ssklower ifp->if_addrlist = (struct ifaddr *) ia; 46737469Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 46837469Ssklower ia->ia_ifa.ifa_dstaddr 46937469Ssklower = (struct sockaddr *)&ia->ia_dstaddr; 47037469Ssklower ia->ia_ifa.ifa_netmask 47137469Ssklower = (struct sockaddr *)&ia->ia_sockmask; 47237469Ssklower ia->ia_ifp = ifp; 47337469Ssklower if (ifp != &loif) 47437469Ssklower iso_interfaces++; 47537469Ssklower } 47637469Ssklower break; 47736384Ssklower 47837469Ssklower #define cmdbyte(x) (((x) >> 8) & 0xff) 47937469Ssklower default: 48037469Ssklower if (cmdbyte(cmd) == 'a') 48137469Ssklower return (snpac_ioctl(cmd, data)); 48237469Ssklower if (ia == (struct iso_ifaddr *)0) 48337469Ssklower return (EADDRNOTAVAIL); 48437469Ssklower break; 48537469Ssklower } 48637469Ssklower switch (cmd) { 48736384Ssklower 48837469Ssklower case SIOCGIFADDR_ISO: 48937469Ssklower ifr->ifr_Addr = ia->ia_addr; 49037469Ssklower break; 49136384Ssklower 49237469Ssklower case SIOCGIFDSTADDR_ISO: 49337469Ssklower if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 49437469Ssklower return (EINVAL); 49537469Ssklower ifr->ifr_Addr = ia->ia_dstaddr; 49637469Ssklower break; 49736384Ssklower 49837469Ssklower case SIOCGIFNETMASK_ISO: 49937469Ssklower ifr->ifr_Addr = ia->ia_sockmask; 50037469Ssklower break; 50136384Ssklower 50237469Ssklower case SIOCAIFADDR_ISO: 50337469Ssklower maskIsNew = 0; hostIsNew = 1; error = u.u_error; 50437469Ssklower if (ia->ia_addr.siso_family == AF_ISO) { 50537469Ssklower if (ifra->ifra_addr.siso_len == 0) { 50637469Ssklower ifra->ifra_addr = ia->ia_addr; 50737469Ssklower hostIsNew = 0; 50837469Ssklower } else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr)) 50937469Ssklower hostIsNew = 0; 51037469Ssklower } 51137469Ssklower if (ifra->ifra_mask.siso_len) { 51237469Ssklower iso_ifscrub(ifp, ia); 51337469Ssklower ia->ia_sockmask = ifra->ifra_mask; 51437469Ssklower maskIsNew = 1; 51537469Ssklower } 51637469Ssklower if ((ifp->if_flags & IFF_POINTOPOINT) && 51737469Ssklower (ifra->ifra_dstaddr.siso_family == AF_ISO)) { 51837469Ssklower iso_ifscrub(ifp, ia); 51937469Ssklower ia->ia_dstaddr = ifra->ifra_dstaddr; 52037469Ssklower maskIsNew = 1; /* We lie; but the effect's the same */ 52137469Ssklower } 52237469Ssklower if (ifra->ifra_addr.siso_family == AF_ISO && 52337469Ssklower (hostIsNew || maskIsNew)) { 52437469Ssklower error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0); 52537469Ssklower } 52637469Ssklower if (ifra->ifra_snpaoffset) 52737469Ssklower ia->ia_snpaoffset = ifra->ifra_snpaoffset; 52837469Ssklower return (error); 52937469Ssklower 53037469Ssklower case SIOCDIFADDR_ISO: 53137469Ssklower iso_ifscrub(ifp, ia); 53237469Ssklower if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) 53337469Ssklower ifp->if_addrlist = ifa->ifa_next; 53437469Ssklower else { 53537469Ssklower while (ifa->ifa_next && 53637469Ssklower (ifa->ifa_next != (struct ifaddr *)ia)) 53737469Ssklower ifa = ifa->ifa_next; 53837469Ssklower if (ifa->ifa_next) 53937469Ssklower ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next; 54037469Ssklower else 54137469Ssklower printf("Couldn't unlink isoifaddr from ifp\n"); 54237469Ssklower } 54337469Ssklower oia = ia; 54437469Ssklower if (oia == (ia = iso_ifaddr)) { 54537469Ssklower iso_ifaddr = ia->ia_next; 54637469Ssklower } else { 54737469Ssklower while (ia->ia_next && (ia->ia_next != oia)) { 54837469Ssklower ia = ia->ia_next; 54936384Ssklower } 55037469Ssklower if (ia->ia_next) 55137469Ssklower ia->ia_next = oia->ia_next; 55237469Ssklower else 55337469Ssklower printf("Didn't unlink isoifadr from list\n"); 55436384Ssklower } 55537469Ssklower free((caddr_t)oia, M_IFADDR); 55637469Ssklower break; 55736384Ssklower 55836384Ssklower default: 55936384Ssklower if (ifp == 0 || ifp->if_ioctl == 0) 56036384Ssklower return (EOPNOTSUPP); 56136384Ssklower return ((*ifp->if_ioctl)(ifp, cmd, data)); 56236384Ssklower } 56337469Ssklower return (0); 56436384Ssklower } 56536384Ssklower 56637469Ssklower /* 56737469Ssklower * Delete any existing route for an interface. 56837469Ssklower */ 56937469Ssklower iso_ifscrub(ifp, ia) 57037469Ssklower register struct ifnet *ifp; 57137469Ssklower register struct iso_ifaddr *ia; 57237469Ssklower { 57337469Ssklower if ((ia->ia_flags & IFA_ROUTE) == 0) 57437469Ssklower return; 57537469Ssklower if (ifp->if_flags & IFF_LOOPBACK) 57637469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 57737469Ssklower else if (ifp->if_flags & IFF_POINTOPOINT) 57837469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 57937469Ssklower else { 58037469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); 58137469Ssklower } 58237469Ssklower ia->ia_flags &= ~IFA_ROUTE; 58337469Ssklower } 58437469Ssklower 58537469Ssklower /* 58637469Ssklower * Initialize an interface's internet address 58737469Ssklower * and routing table entry. 58837469Ssklower */ 58937469Ssklower iso_ifinit(ifp, ia, siso, scrub) 59037469Ssklower register struct ifnet *ifp; 59137469Ssklower register struct iso_ifaddr *ia; 59237469Ssklower struct sockaddr_iso *siso; 59337469Ssklower { 59437469Ssklower struct sockaddr_iso oldaddr; 59537469Ssklower int s = splimp(), error; 59637469Ssklower 59737469Ssklower oldaddr = ia->ia_addr; 59837469Ssklower ia->ia_addr = *siso; 59937469Ssklower /* 60037469Ssklower * Give the interface a chance to initialize 60137469Ssklower * if this is its first address, 60237469Ssklower * and to validate the address if necessary. 60337469Ssklower */ 60437469Ssklower if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) { 60537469Ssklower splx(s); 60637469Ssklower ia->ia_addr = oldaddr; 60737469Ssklower return (error); 60837469Ssklower } 60937469Ssklower if (scrub) { 61037469Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 61137469Ssklower iso_ifscrub(ifp, ia); 61237469Ssklower ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 61337469Ssklower } 61437469Ssklower /* 61537469Ssklower * Add route for the network. 61637469Ssklower */ 61737469Ssklower if (ifp->if_flags & IFF_LOOPBACK) { 61837469Ssklower ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; 61937469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 62037469Ssklower } else if (ifp->if_flags & IFF_POINTOPOINT && 62137469Ssklower ia->ia_dstaddr.siso_family == AF_ISO) 62237469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 62337469Ssklower else { 62437469Ssklower rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP); 62537469Ssklower } 62637469Ssklower ia->ia_flags |= IFA_ROUTE; 62737469Ssklower splx(s); 62837469Ssklower return (0); 62937469Ssklower } 63037469Ssklower #ifdef notdef 63137469Ssklower 63236384Ssklower struct ifaddr * 63336384Ssklower iso_ifwithidi(addr) 63436384Ssklower register struct sockaddr *addr; 63536384Ssklower { 63636384Ssklower register struct ifnet *ifp; 63736384Ssklower register struct ifaddr *ifa; 63836384Ssklower register u_int af = addr->sa_family; 63936384Ssklower 64036384Ssklower if (af != AF_ISO) 64136384Ssklower return (0); 64236384Ssklower IFDEBUG(D_ROUTE) 64336384Ssklower printf(">>> iso_ifwithidi addr\n"); 64436384Ssklower dump_isoaddr( (struct sockaddr_iso *)(addr)); 64536384Ssklower printf("\n"); 64636384Ssklower ENDDEBUG 64736384Ssklower for (ifp = ifnet; ifp; ifp = ifp->if_next) { 64836384Ssklower IFDEBUG(D_ROUTE) 64936384Ssklower printf("iso_ifwithidi ifnet %s\n", ifp->if_name); 65036384Ssklower ENDDEBUG 65136384Ssklower for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 65236384Ssklower IFDEBUG(D_ROUTE) 65336384Ssklower printf("iso_ifwithidi address "); 65437469Ssklower dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr)); 65536384Ssklower ENDDEBUG 65637469Ssklower if (ifa->ifa_addr->sa_family != addr->sa_family) 65736384Ssklower continue; 65836384Ssklower 65936384Ssklower #define IFA_SIS(ifa)\ 66037469Ssklower ((struct sockaddr_iso *)((ifa)->ifa_addr)) 66136384Ssklower 66236384Ssklower IFDEBUG(D_ROUTE) 66336384Ssklower printf(" af same, args to iso_eqtype:\n"); 66436384Ssklower printf("0x%x ", IFA_SIS(ifa)->siso_addr); 66536384Ssklower printf(" 0x%x\n", 66636384Ssklower &(((struct sockaddr_iso *)addr)->siso_addr)); 66736384Ssklower ENDDEBUG 66836384Ssklower 66936384Ssklower if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr), 67036384Ssklower &(((struct sockaddr_iso *)addr)->siso_addr))) { 67136384Ssklower IFDEBUG(D_ROUTE) 67236384Ssklower printf("ifa_ifwithidi: ifa found\n"); 67336384Ssklower ENDDEBUG 67436384Ssklower return (ifa); 67536384Ssklower } 67636384Ssklower IFDEBUG(D_ROUTE) 67736384Ssklower printf(" iso_eqtype failed\n"); 67836384Ssklower ENDDEBUG 67936384Ssklower } 68036384Ssklower } 68136384Ssklower return ((struct ifaddr *)0); 68236384Ssklower } 68336384Ssklower 68437469Ssklower #endif notdef 68536384Ssklower /* 68636384Ssklower * FUNCTION: iso_ck_addr 68736384Ssklower * 68836384Ssklower * PURPOSE: return true if the iso_addr passed is 68936384Ssklower * within the legal size limit for an iso address. 69036384Ssklower * 69136384Ssklower * RETURNS: true or false 69236384Ssklower * 69336384Ssklower * SIDE EFFECTS: 69436384Ssklower * 69536384Ssklower */ 69636384Ssklower iso_ck_addr(isoa) 69736384Ssklower struct iso_addr *isoa; /* address to check */ 69836384Ssklower { 69936384Ssklower return (isoa->isoa_len <= 20); 70036384Ssklower 70136384Ssklower } 70236384Ssklower 70337469Ssklower #ifdef notdef 70436384Ssklower /* 70536384Ssklower * FUNCTION: iso_eqtype 70636384Ssklower * 70736384Ssklower * PURPOSE: Determine if two iso addresses are of the same type. 70836384Ssklower * This is flaky. Really we should consider all type 47 addrs to be the 70936384Ssklower * same - but there do exist different structures for 47 addrs. 71036384Ssklower * Gosip adds a 3rd. 71136384Ssklower * 71236384Ssklower * RETURNS: true if the addresses are the same type 71336384Ssklower * 71436384Ssklower * SIDE EFFECTS: 71536384Ssklower * 71636384Ssklower * NOTES: By type, I mean rfc986, t37, or osinet 71736384Ssklower * 71836384Ssklower * This will first compare afis. If they match, then 71936384Ssklower * if the addr is not t37, the idis must be compared. 72036384Ssklower */ 72136384Ssklower iso_eqtype(isoaa, isoab) 72236384Ssklower struct iso_addr *isoaa; /* first addr to check */ 72336384Ssklower struct iso_addr *isoab; /* other addr to check */ 72436384Ssklower { 72536384Ssklower if (isoaa->isoa_afi == isoab->isoa_afi) { 72636384Ssklower if (isoaa->isoa_afi == AFI_37) 72736384Ssklower return(1); 72836384Ssklower else 72936384Ssklower return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2)); 73036384Ssklower } 73136384Ssklower return(0); 73236384Ssklower } 73337469Ssklower #endif notdef 73436384Ssklower /* 73537469Ssklower * FUNCTION: iso_localifa() 73636384Ssklower * 73737469Ssklower * PURPOSE: Find an interface addresss having a given destination 73837469Ssklower * or at least matching the net. 73936384Ssklower * 74036384Ssklower * RETURNS: ptr to an interface address 74136384Ssklower * 74236384Ssklower * SIDE EFFECTS: 74336384Ssklower * 74436384Ssklower * NOTES: 74536384Ssklower */ 74636384Ssklower struct iso_ifaddr * 74737469Ssklower iso_localifa(siso) 74837469Ssklower register struct sockaddr_iso *siso; 74936384Ssklower { 75036384Ssklower register struct iso_ifaddr *ia; 75137469Ssklower register char *cp1, *cp2, *cp3; 75237469Ssklower register struct ifnet *ifp; 75337469Ssklower struct iso_ifaddr *ia_maybe = 0; 75437469Ssklower /* 75537469Ssklower * We make one pass looking for both net matches and an exact 75637469Ssklower * dst addr. 75737469Ssklower */ 75837469Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) { 75937469Ssklower if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0)) 76037469Ssklower continue; 76137469Ssklower if (ifp->if_flags & IFF_POINTOPOINT) { 76237469Ssklower if ((ia->ia_dstaddr.siso_family == AF_ISO) && 76337469Ssklower SAME_ISOADDR(&ia->ia_dstaddr, siso)) 76437469Ssklower return (ia); 76537469Ssklower else 76637469Ssklower if (SAME_ISOADDR(&ia->ia_addr, siso)) 76737469Ssklower ia_maybe = ia; 76837469Ssklower continue; 76937469Ssklower } 77037469Ssklower if (ia->ia_sockmask.siso_len) { 77137469Ssklower char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask; 77237469Ssklower cp1 = ia->ia_sockmask.siso_data; 77337469Ssklower cp2 = siso->siso_data; 77437469Ssklower cp3 = ia->ia_addr.siso_data; 775*39936Ssklower while (cp1 < cplim) 77637469Ssklower if (*cp1++ & (*cp2++ ^ *cp3++)) 77737469Ssklower goto next; 77837469Ssklower ia_maybe = ia; 77937469Ssklower } 78037469Ssklower if (SAME_ISOADDR(&ia->ia_addr, siso)) 78137469Ssklower return ia; 78237469Ssklower next:; 78337469Ssklower } 78437469Ssklower return ia_maybe; 78536384Ssklower } 78636384Ssklower 78736384Ssklower #ifdef NARGOXTWENTYFIVE > 0 78836384Ssklower #include "cons.h" 78936384Ssklower #endif NARGOXTWENTYFIVE > 0 79036384Ssklower /* 79136384Ssklower * FUNCTION: iso_nlctloutput 79236384Ssklower * 79336384Ssklower * PURPOSE: Set options at the network level 79436384Ssklower * 79536384Ssklower * RETURNS: E* 79636384Ssklower * 79736384Ssklower * SIDE EFFECTS: 79836384Ssklower * 79936384Ssklower * NOTES: This could embody some of the functions of 80036384Ssklower * rclnp_ctloutput and cons_ctloutput. 80136384Ssklower */ 80236384Ssklower iso_nlctloutput(cmd, optname, pcb, m) 80336384Ssklower int cmd; /* command:set or get */ 80436384Ssklower int optname; /* option of interest */ 80536384Ssklower caddr_t pcb; /* nl pcb */ 80636384Ssklower struct mbuf *m; /* data for set, buffer for get */ 80736384Ssklower { 80836384Ssklower struct isopcb *isop = (struct isopcb *)pcb; 80936384Ssklower int error = 0; /* return value */ 81036384Ssklower caddr_t data; /* data for option */ 81136384Ssklower int data_len; /* data's length */ 81236384Ssklower 81336384Ssklower IFDEBUG(D_ISO) 81436384Ssklower printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n", 81536384Ssklower cmd, optname, pcb, m); 81636384Ssklower ENDDEBUG 81736384Ssklower 81836384Ssklower if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT)) 81936384Ssklower return(EOPNOTSUPP); 82036384Ssklower 82136384Ssklower data = mtod(m, caddr_t); 82236384Ssklower data_len = (m)->m_len; 82336384Ssklower 82436384Ssklower IFDEBUG(D_ISO) 82536384Ssklower printf("iso_nlctloutput: data is:\n"); 82636384Ssklower dump_buf(data, data_len); 82736384Ssklower ENDDEBUG 82836384Ssklower 82936384Ssklower switch (optname) { 83036384Ssklower 83136384Ssklower #ifdef NARGOXTWENTYFIVE > 0 83236384Ssklower case CONSOPT_X25CRUD: 83336384Ssklower if (cmd == PRCO_GETOPT) { 83436384Ssklower error = EOPNOTSUPP; 83536384Ssklower break; 83636384Ssklower } 83736384Ssklower 83836384Ssklower if (data_len > MAXX25CRUDLEN) { 83936384Ssklower error = EINVAL; 84036384Ssklower break; 84136384Ssklower } 84236384Ssklower 84336384Ssklower IFDEBUG(D_ISO) 84436384Ssklower printf("iso_nlctloutput: setting x25 crud\n"); 84536384Ssklower ENDDEBUG 84636384Ssklower 84737469Ssklower bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len); 84836384Ssklower isop->isop_x25crud_len = data_len; 84936384Ssklower break; 85036384Ssklower #endif NARGOXTWENTYFIVE > 0 85136384Ssklower 85236384Ssklower default: 85336384Ssklower error = EOPNOTSUPP; 85436384Ssklower } 85536384Ssklower 85636384Ssklower return error; 85736384Ssklower } 85836384Ssklower #endif ISO 85936384Ssklower 86036384Ssklower #ifdef ARGO_DEBUG 86136384Ssklower 86236384Ssklower /* 86336384Ssklower * FUNCTION: dump_isoaddr 86436384Ssklower * 86536384Ssklower * PURPOSE: debugging 86636384Ssklower * 86736384Ssklower * RETURNS: nada 86836384Ssklower * 86936384Ssklower */ 87036384Ssklower dump_isoaddr(s) 87136384Ssklower struct sockaddr_iso *s; 87236384Ssklower { 87337469Ssklower char *clnp_saddr_isop(); 87436384Ssklower register int i; 87536384Ssklower 87636384Ssklower if( s->siso_family == AF_ISO) { 87737469Ssklower printf("ISO address: suffixlen %d, %s\n", 87838841Ssklower s->siso_tlen, clnp_saddr_isop(s)); 87936384Ssklower } else if( s->siso_family == AF_INET) { 88036384Ssklower /* hack */ 88136384Ssklower struct sockaddr_in *sin = (struct sockaddr_in *)s; 88236384Ssklower 88336384Ssklower printf("%d.%d.%d.%d: %d", 88436384Ssklower (sin->sin_addr.s_addr>>24)&0xff, 88536384Ssklower (sin->sin_addr.s_addr>>16)&0xff, 88636384Ssklower (sin->sin_addr.s_addr>>8)&0xff, 88736384Ssklower (sin->sin_addr.s_addr)&0xff, 88836384Ssklower sin->sin_port); 88936384Ssklower } 89036384Ssklower } 89136384Ssklower 89236384Ssklower #endif ARGO_DEBUG 893