136389Ssklower /*********************************************************** 236389Ssklower Copyright IBM Corporation 1987 336389Ssklower 436389Ssklower All Rights Reserved 536389Ssklower 636389Ssklower Permission to use, copy, modify, and distribute this software and its 736389Ssklower documentation for any purpose and without fee is hereby granted, 836389Ssklower provided that the above copyright notice appear in all copies and that 936389Ssklower both that copyright notice and this permission notice appear in 1036389Ssklower supporting documentation, and that the name of IBM not be 1136389Ssklower used in advertising or publicity pertaining to distribution of the 1236389Ssklower software without specific, written prior permission. 1336389Ssklower 1436389Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 1536389Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 1636389Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 1736389Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 1836389Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 1936389Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 2036389Ssklower SOFTWARE. 2136389Ssklower 2236389Ssklower ******************************************************************/ 2336389Ssklower 2436389Ssklower /* 2536389Ssklower * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison 2636389Ssklower */ 2736389Ssklower /* 2836389Ssklower * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $ 2936389Ssklower * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $ 30*38477Ssklower * @(#)iso_pcb.c 7.4 (Berkeley) 07/19/89 3136389Ssklower * 3236389Ssklower * Iso address family net-layer(s) pcb stuff. NEH 1/29/87 3336389Ssklower */ 34*38477Ssklower 3536389Ssklower #ifndef lint 3636389Ssklower static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $"; 3736389Ssklower #endif 3836389Ssklower 3936389Ssklower #ifdef ISO 4036389Ssklower 4136389Ssklower #include "param.h" 4236389Ssklower #include "systm.h" 4336389Ssklower #include "user.h" 4436389Ssklower #include "mbuf.h" 4537469Ssklower #include "socket.h" 4637469Ssklower #include "socketvar.h" 4737469Ssklower #include "argo_debug.h" 4837469Ssklower #include "iso.h" 4937469Ssklower #include "clnp.h" 5036389Ssklower #include "../netinet/in_systm.h" 5136389Ssklower #include "../net/if.h" 5236389Ssklower #include "../net/route.h" 5337469Ssklower #include "iso_pcb.h" 5437469Ssklower #include "iso_var.h" 5536389Ssklower #include "protosw.h" 5636389Ssklower 5736389Ssklower #define PCBNULL (struct isopcb *)0 5836389Ssklower struct iso_addr zeroiso_addr = { 5936389Ssklower 0 6036389Ssklower }; 6136389Ssklower 6236389Ssklower 6336389Ssklower /* 6436389Ssklower * FUNCTION: iso_pcballoc 6536389Ssklower * 6636389Ssklower * PURPOSE: creates an isopcb structure in an mbuf, 6736389Ssklower * with socket (so), and 6836389Ssklower * puts it in the queue with head (head) 6936389Ssklower * 7036389Ssklower * RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf 7136389Ssklower */ 7236389Ssklower int 7336389Ssklower iso_pcballoc(so, head) 7436389Ssklower struct socket *so; 7536389Ssklower struct isopcb *head; 7636389Ssklower { 7736389Ssklower register struct isopcb *isop; 7836389Ssklower 7936389Ssklower IFDEBUG(D_ISO) 8036389Ssklower printf("iso_pcballoc(so 0x%x)\n", so); 8136389Ssklower ENDDEBUG 8237469Ssklower MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT); 8337469Ssklower if (isop == NULL) 8436389Ssklower return ENOBUFS; 8537469Ssklower bzero((caddr_t)isop, sizeof(*isop)); 8636389Ssklower isop->isop_head = head; 8736389Ssklower isop->isop_socket = so; 8836389Ssklower insque(isop, head); 8936389Ssklower so->so_pcb = (caddr_t)isop; 9036389Ssklower return 0; 9136389Ssklower } 9236389Ssklower 9336389Ssklower /* 9436389Ssklower * FUNCTION: iso_pcbbind 9536389Ssklower * 9636389Ssklower * PURPOSE: binds the address given in *(nam) to the socket 9736389Ssklower * specified by the isopcb in *(isop) 9836389Ssklower * If the given address is zero, it makes sure the 9936389Ssklower * address isn't already in use and if it's got a network 10036389Ssklower * portion, we look for an interface with that network 10136389Ssklower * address. If the address given is zero, we allocate 10236389Ssklower * a port and stuff it in the (nam) structure. 10336389Ssklower * 10436389Ssklower * RETURNS: errno E* or 0 if ok. 10536389Ssklower * 10636389Ssklower * SIDE EFFECTS: increments head->isop_lport if it allocates a port # 10736389Ssklower * 10836389Ssklower * NOTES: 10936389Ssklower */ 11037469Ssklower #define satosiso(sa) ((struct sockaddr_iso *)(sa)) 11136389Ssklower int 11236389Ssklower iso_pcbbind(isop, nam) 11336389Ssklower register struct isopcb *isop; 11436389Ssklower struct mbuf *nam; 11536389Ssklower { 11636389Ssklower register struct isopcb *head = isop->isop_head; 11736389Ssklower register struct sockaddr_iso *siso; 11837469Ssklower struct iso_ifaddr *ia; 11937469Ssklower union { 12037469Ssklower char data[2]; 12137469Ssklower u_short s; 12237469Ssklower } suf; 12336389Ssklower 12436389Ssklower IFDEBUG(D_ISO) 12536389Ssklower printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam); 12636389Ssklower ENDDEBUG 12737469Ssklower suf.s = 0; 12836389Ssklower if (iso_ifaddr == 0) /* any interfaces attached? */ 12936389Ssklower return EADDRNOTAVAIL; 13037469Ssklower if (isop->isop_laddr) /* already bound */ 13136389Ssklower return EADDRINUSE; 13237469Ssklower if(nam == (struct mbuf *)0) { 13337469Ssklower isop->isop_laddr = &isop->isop_sladdr; 13437469Ssklower isop->isop_sladdr.siso_tsuffixlen = 2; 13537469Ssklower isop->isop_sladdr.siso_nlen = 0; 13637469Ssklower isop->isop_sladdr.siso_family = AF_ISO; 13737469Ssklower isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso); 13836389Ssklower goto noname; 13937469Ssklower } 14036389Ssklower siso = mtod(nam, struct sockaddr_iso *); 14136389Ssklower IFDEBUG(D_ISO) 14236389Ssklower printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); 14336389Ssklower printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr)); 14436389Ssklower ENDDEBUG 14536389Ssklower /* 14636389Ssklower * We would like sort of length check but since some OSI addrs 14736389Ssklower * do not have fixed length, we can't really do much. 14836389Ssklower * The ONLY thing we can say is that an osi addr has to have 14936389Ssklower * at LEAST an afi and one more byte and had better fit into 15036389Ssklower * a struct iso_addr. 15136389Ssklower * However, in fact the size of the whole thing is a struct 15236389Ssklower * sockaddr_iso, so probably this is what we should check for. 15336389Ssklower */ 15437469Ssklower if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) { 15536389Ssklower return ENAMETOOLONG; 15636389Ssklower } 15737469Ssklower if (siso->siso_tsuffixlen) { 15837469Ssklower register char *cp = TSEL(siso); 15937469Ssklower suf.data[0] = cp[0]; 16037469Ssklower suf.data[1] = cp[1]; 16137469Ssklower } 16237469Ssklower if (siso->siso_nlen) { 16336389Ssklower /* non-zero net addr- better match one of our interfaces */ 16436389Ssklower IFDEBUG(D_ISO) 16536389Ssklower printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); 16636389Ssklower ENDDEBUG 16737469Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) 16837469Ssklower if (SAME_ISOADDR(siso, &ia->ia_addr)) 16937469Ssklower break; 17037469Ssklower if (ia == 0) 17136389Ssklower return EADDRNOTAVAIL; 17236389Ssklower } 17337469Ssklower if (siso->siso_len <= sizeof (isop->isop_sladdr)) { 17437469Ssklower isop->isop_laddr = &isop->isop_sladdr; 17537469Ssklower } else { 17637469Ssklower if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0) 17737469Ssklower return ENOBUFS; 17837469Ssklower isop->isop_laddr = mtod(nam, struct sockaddr_iso *); 17937469Ssklower } 18037469Ssklower bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len); 18137469Ssklower if (suf.s) { 18237469Ssklower if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tsuffixlen <= 2) && 18337469Ssklower (u.u_uid != 0)) 18436389Ssklower return EACCES; 18536389Ssklower if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && 18637469Ssklower iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)) 18736389Ssklower return EADDRINUSE; 18837469Ssklower } else { 18937469Ssklower register char *cp; 19036389Ssklower noname: 19137469Ssklower cp = TSEL(isop->isop_laddr); 19236389Ssklower IFDEBUG(D_ISO) 19336389Ssklower printf("iso_pcbbind noname\n"); 19436389Ssklower ENDDEBUG 19536389Ssklower do { 19636389Ssklower if (head->isop_lport++ < ISO_PORT_RESERVED || 19736389Ssklower head->isop_lport > ISO_PORT_USERRESERVED) 19836389Ssklower head->isop_lport = ISO_PORT_RESERVED; 19937469Ssklower suf.s = head->isop_lport; 20037469Ssklower cp[0] = suf.data[0]; 20137469Ssklower cp[1] = suf.data[1]; 20237469Ssklower } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)); 20337469Ssklower } 20436389Ssklower IFDEBUG(D_ISO) 20536389Ssklower printf("iso_pcbbind returns 0, suf 0x%x\n", suf); 20636389Ssklower ENDDEBUG 20736389Ssklower return 0; 20836389Ssklower } 20936389Ssklower /* 21036389Ssklower * FUNCTION: iso_pcbconnect 21136389Ssklower * 21236389Ssklower * PURPOSE: Make the isopcb (isop) look like it's connected. 21336389Ssklower * In other words, give it the peer address given in 21436389Ssklower * the mbuf * (nam). Make sure such a combination 21536389Ssklower * of local, peer addresses doesn't already exist 21636389Ssklower * for this protocol. Internet mentality prevails here, 21736389Ssklower * wherein a src,dst pair uniquely identifies a connection. 21836389Ssklower * Both net address and port must be specified in argument 21936389Ssklower * (nam). 22036389Ssklower * If we don't have a local address for this socket yet, 22136389Ssklower * we pick one by calling iso_pcbbind(). 22236389Ssklower * 22336389Ssklower * RETURNS: errno E* or 0 if ok. 22436389Ssklower * 22536389Ssklower * SIDE EFFECTS: Looks up a route, which may cause one to be left 22636389Ssklower * in the isopcb. 22736389Ssklower * 22836389Ssklower * NOTES: 22936389Ssklower */ 23036389Ssklower int 23136389Ssklower iso_pcbconnect(isop, nam) 23237469Ssklower register struct isopcb *isop; 23336389Ssklower struct mbuf *nam; 23436389Ssklower { 23536389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 23637469Ssklower int local_zero, error = 0; 23737469Ssklower struct iso_ifaddr *ia; 23836389Ssklower 23936389Ssklower IFDEBUG(D_ISO) 24037469Ssklower printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x", 24137469Ssklower isop, isop->isop_socket, nam); 24237469Ssklower printf("nam->m_len 0x%x), addr:\n", nam->m_len); 24336389Ssklower dump_isoaddr(siso); 24436389Ssklower ENDDEBUG 24537469Ssklower if (nam->m_len < siso->siso_len) 24637469Ssklower return EINVAL; 24736389Ssklower if (siso->siso_family != AF_ISO) 24836389Ssklower return EAFNOSUPPORT; 249*38477Ssklower if (siso->siso_nlen == 0) { 250*38477Ssklower if (ia = iso_ifaddr) { 251*38477Ssklower int nlen = ia->ia_addr.siso_nlen; 252*38477Ssklower ovbcopy(TSEL(siso), nlen + TSEL(siso), 253*38477Ssklower siso->siso_tsuffixlen + siso->siso_ssuffixlen); 254*38477Ssklower bcopy((caddr_t)&ia->ia_addr.siso_addr, 255*38477Ssklower (caddr_t)&siso->siso_addr, nlen + 1); 256*38477Ssklower /* includes siso->siso_nlen = nlen; */ 257*38477Ssklower } else 258*38477Ssklower return EADDRNOTAVAIL; 259*38477Ssklower } 26037469Ssklower /* 26137469Ssklower * Local zero means either not bound, or bound to a TSEL, but no 26237469Ssklower * particular local interface. So, if we want to send somebody 26337469Ssklower * we need to choose a return address. 26436389Ssklower */ 26537469Ssklower local_zero = 26637469Ssklower ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0)); 26736389Ssklower if (local_zero) { 26837469Ssklower int flags; 26936389Ssklower 27036389Ssklower IFDEBUG(D_ISO) 27136389Ssklower printf("iso_pcbconnect localzero 1\n"); 27236389Ssklower ENDDEBUG 27336389Ssklower /* 27436389Ssklower * If route is known or can be allocated now, 27536389Ssklower * our src addr is taken from the i/f, else punt. 27636389Ssklower */ 27737469Ssklower flags = isop->isop_socket->so_options & SO_DONTROUTE; 27837469Ssklower if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags, 27937469Ssklower (struct sockaddr **)0, &ia)) 28037469Ssklower return error; 28136389Ssklower IFDEBUG(D_ISO) 28237469Ssklower printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x", 28337469Ssklower isop->isop_route.ro_rt); 28437469Ssklower printf(" ia 0x%x\n", ia); 28536389Ssklower ENDDEBUG 28636389Ssklower } 28736389Ssklower IFDEBUG(D_ISO) 28836389Ssklower printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", 28936389Ssklower isop, isop->isop_socket); 29036389Ssklower ENDDEBUG 29136389Ssklower if (local_zero) { 29237469Ssklower int nlen, tlen, totlen; caddr_t oldtsel, newtsel; 29337469Ssklower siso = isop->isop_laddr; 29437469Ssklower if (siso == 0 || siso->siso_tsuffixlen == 0) 29536389Ssklower (void)iso_pcbbind(isop, (struct mbuf *)0); 29637469Ssklower /* 29737469Ssklower * Here we have problem of squezeing in a definite network address 29837469Ssklower * into an existing sockaddr_iso, which in fact may not have room 29937469Ssklower * for it. This gets messy. 30037469Ssklower */ 30137469Ssklower siso = isop->isop_laddr; 30237469Ssklower oldtsel = TSEL(siso); 30337469Ssklower tlen = siso->siso_tsuffixlen; 30437469Ssklower nlen = ia->ia_addr.siso_nlen; 30537469Ssklower totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]); 30637469Ssklower if ((siso == &isop->isop_sladdr) && 30737469Ssklower (totlen > sizeof(isop->isop_sladdr))) { 30837469Ssklower struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); 30937469Ssklower if (m == 0) 31037469Ssklower return ENOBUFS; 31137469Ssklower m->m_len = totlen; 31237469Ssklower isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *); 31337469Ssklower } 31437469Ssklower siso->siso_nlen = ia->ia_addr.siso_nlen; 31537469Ssklower newtsel = TSEL(siso); 31637469Ssklower ovbcopy(oldtsel, newtsel, tlen); 31737469Ssklower bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen); 31837469Ssklower siso->siso_tsuffixlen = tlen; 31937469Ssklower siso->siso_family = AF_ISO; 32037469Ssklower siso->siso_len = totlen; 32137469Ssklower siso = mtod(nam, struct sockaddr_iso *); 32236389Ssklower } 32336389Ssklower IFDEBUG(D_ISO) 32436389Ssklower printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", 32536389Ssklower isop, isop->isop_socket); 32636389Ssklower ENDDEBUG 32737469Ssklower /* 32837469Ssklower * If we had to allocate space to a previous big foreign address, 32937469Ssklower * and for some reason we didn't free it, we reuse it knowing 33037469Ssklower * that is going to be big enough, as sockaddrs are delivered in 33137469Ssklower * 128 byte mbufs. 33237469Ssklower * If the foreign address is small enough, we use default space; 33337469Ssklower * otherwise, we grab an mbuf to copy into. 33437469Ssklower */ 33537469Ssklower if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) { 33637469Ssklower if (siso->siso_len <= sizeof(isop->isop_sfaddr)) 33737469Ssklower isop->isop_faddr = &isop->isop_sfaddr; 33837469Ssklower else { 33937469Ssklower struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); 34037469Ssklower if (m == 0) 34137469Ssklower return ENOBUFS; 34237469Ssklower isop->isop_faddr = mtod(m, struct sockaddr_iso *); 34337469Ssklower } 34437469Ssklower } 34537469Ssklower bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len); 34636389Ssklower IFDEBUG(D_ISO) 34736389Ssklower printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", 34836389Ssklower isop, isop->isop_socket); 34936389Ssklower printf("iso_pcbconnect connected to addr:\n"); 35037469Ssklower dump_isoaddr(isop->isop_faddr); 35136389Ssklower printf("iso_pcbconnect end: src addr:\n"); 35237469Ssklower dump_isoaddr(isop->isop_laddr); 35336389Ssklower ENDDEBUG 35436389Ssklower return 0; 35536389Ssklower } 35636389Ssklower 35736389Ssklower /* 35836389Ssklower * FUNCTION: iso_pcbdisconnect() 35936389Ssklower * 36036389Ssklower * PURPOSE: washes away the peer address info so the socket 36136389Ssklower * appears to be disconnected. 36236389Ssklower * If there's no file descriptor associated with the socket 36336389Ssklower * it detaches the pcb. 36436389Ssklower * 36536389Ssklower * RETURNS: Nada. 36636389Ssklower * 36736389Ssklower * SIDE EFFECTS: May detach the pcb. 36836389Ssklower * 36936389Ssklower * NOTES: 37036389Ssklower */ 37136389Ssklower void 37236389Ssklower iso_pcbdisconnect(isop) 37336389Ssklower struct isopcb *isop; 37436389Ssklower { 37536389Ssklower void iso_pcbdetach(); 37636389Ssklower 37736389Ssklower IFDEBUG(D_ISO) 37836389Ssklower printf("iso_pcbdisconnect(isop 0x%x)\n", isop); 37936389Ssklower ENDDEBUG 38037469Ssklower /* 38137469Ssklower * Preserver binding infnormation if already bound. 38237469Ssklower */ 38337469Ssklower if (isop->isop_laddr && isop->isop_laddr->siso_nlen) 38437469Ssklower isop->isop_laddr->siso_nlen = 0; 38537469Ssklower if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr) 38637469Ssklower m_freem(dtom(isop->isop_faddr)); 38737469Ssklower isop->isop_faddr = 0; 38836389Ssklower if (isop->isop_socket->so_state & SS_NOFDREF) 38936389Ssklower iso_pcbdetach(isop); 39036389Ssklower } 39136389Ssklower 39236389Ssklower /* 39336389Ssklower * FUNCTION: iso_pcbdetach 39436389Ssklower * 39536389Ssklower * PURPOSE: detach the pcb at *(isop) from it's socket and free 39636389Ssklower * the mbufs associated with the pcb.. 39736389Ssklower * Dequeues (isop) from its head. 39836389Ssklower * 39936389Ssklower * RETURNS: Nada. 40036389Ssklower * 40136389Ssklower * SIDE EFFECTS: 40236389Ssklower * 40336389Ssklower * NOTES: 40436389Ssklower */ 40536389Ssklower void 40636389Ssklower iso_pcbdetach(isop) 40736389Ssklower struct isopcb *isop; 40836389Ssklower { 40936389Ssklower struct socket *so = isop->isop_socket; 41036389Ssklower 41136389Ssklower IFDEBUG(D_ISO) 41236389Ssklower printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 41336389Ssklower isop, isop->isop_socket, so); 41436389Ssklower ENDDEBUG 41536389Ssklower if (so ) { /* in the x.25 domain, we sometimes have no socket */ 41636389Ssklower so->so_pcb = 0; 41736389Ssklower sofree(so); 41836389Ssklower } 41936389Ssklower IFDEBUG(D_ISO) 42036389Ssklower printf("iso_pcbdetach 2 \n"); 42136389Ssklower ENDDEBUG 42236389Ssklower if (isop->isop_options) 42336389Ssklower (void)m_free(isop->isop_options); 42436389Ssklower IFDEBUG(D_ISO) 42536389Ssklower printf("iso_pcbdetach 3 \n"); 42636389Ssklower ENDDEBUG 42736389Ssklower if (isop->isop_route.ro_rt) 42836389Ssklower rtfree(isop->isop_route.ro_rt); 42936389Ssklower IFDEBUG(D_ISO) 43036389Ssklower printf("iso_pcbdetach 3.1\n"); 43136389Ssklower ENDDEBUG 43236389Ssklower if (isop->isop_clnpcache != NULL) { 43336389Ssklower struct clnp_cache *clcp = 43436389Ssklower mtod(isop->isop_clnpcache, struct clnp_cache *); 43536389Ssklower IFDEBUG(D_ISO) 43636389Ssklower printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", 43736389Ssklower clcp, clcp->clc_hdr); 43836389Ssklower ENDDEBUG 43936389Ssklower if (clcp->clc_hdr != NULL) 44036389Ssklower m_free(clcp->clc_hdr); 44136389Ssklower IFDEBUG(D_ISO) 44236389Ssklower printf("iso_pcbdetach 3.3: freeing cache x%x\n", 44336389Ssklower isop->isop_clnpcache); 44436389Ssklower ENDDEBUG 44536389Ssklower m_free(isop->isop_clnpcache); 44636389Ssklower } 44736389Ssklower IFDEBUG(D_ISO) 44836389Ssklower printf("iso_pcbdetach 4 \n"); 44936389Ssklower ENDDEBUG 45036389Ssklower remque(isop); 45136389Ssklower IFDEBUG(D_ISO) 45236389Ssklower printf("iso_pcbdetach 5 \n"); 45336389Ssklower ENDDEBUG 45437469Ssklower if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr)) 45537469Ssklower m_freem(dtom(isop->isop_laddr)); 45637469Ssklower free((caddr_t)isop, M_IFADDR); 45736389Ssklower } 45836389Ssklower 45936389Ssklower #ifdef notdef 46036389Ssklower /* NEEDED? */ 46136389Ssklower void 46236389Ssklower iso_setsockaddr(isop, nam) 46336389Ssklower register struct isopcb *isop; 46436389Ssklower struct mbuf *nam; 46536389Ssklower { 46636389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 46736389Ssklower 46836389Ssklower nam->m_len = sizeof (*siso); 46936389Ssklower siso = mtod(nam, struct sockaddr_iso *); 47036389Ssklower bzero((caddr_t)siso, sizeof (*siso)); 47136389Ssklower siso->siso_family = AF_ISO; 47236389Ssklower siso->siso_tsuffix = isop->isop_lport; 47336389Ssklower siso->siso_addr = isop->isop_laddr.siso_addr; 47436389Ssklower } 47536389Ssklower 47636389Ssklower /* NEEDED? */ 47736389Ssklower void 47836389Ssklower iso_setpeeraddr(isop, nam) 47936389Ssklower register struct isopcb *isop; 48036389Ssklower struct mbuf *nam; 48136389Ssklower { 48236389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 48336389Ssklower 48436389Ssklower nam->m_len = sizeof (*siso); 48536389Ssklower siso = mtod(nam, struct sockaddr_iso *); 48636389Ssklower bzero((caddr_t)siso, sizeof (*siso)); 48736389Ssklower siso->siso_family = AF_ISO; 48836389Ssklower siso->siso_tsuffix = isop->isop_fport; 48936389Ssklower siso->siso_addr = isop->isop_faddr.siso_addr; 49036389Ssklower } 49136389Ssklower #endif notdef 49236389Ssklower 49336389Ssklower /* 49436389Ssklower * FUNCTION: iso_pcbnotify 49536389Ssklower * 49636389Ssklower * PURPOSE: notify all connections in this protocol's queue (head) 49736389Ssklower * that have peer address (dst) of the problem (errno) 49836389Ssklower * by calling (notify) on the connections' isopcbs. 49936389Ssklower * 50036389Ssklower * RETURNS: Rien. 50136389Ssklower * 50236389Ssklower * SIDE EFFECTS: 50336389Ssklower * 50436389Ssklower * NOTES: (notify) is called at splimp! 50536389Ssklower */ 50636389Ssklower void 50736389Ssklower iso_pcbnotify(head, dst, errno, notify) 50836389Ssklower struct isopcb *head; 50936389Ssklower register struct iso_addr *dst; 51036389Ssklower int errno, (*notify)(); 51136389Ssklower { 51236389Ssklower register struct isopcb *isop, *oisop; 51336389Ssklower int s = splimp(); 51436389Ssklower 51536389Ssklower IFDEBUG(D_ISO) 51636389Ssklower printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); 51736389Ssklower ENDDEBUG 51836389Ssklower for (isop = head->isop_next; isop != head;) { 51937469Ssklower if (!iso_addrmatch1(&(isop->isop_faddr->siso_addr), dst) || 52036389Ssklower isop->isop_socket == 0) { 52136389Ssklower IFDEBUG(D_ISO) 52236389Ssklower printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , 52336389Ssklower isop, isop->isop_socket); 52436389Ssklower printf("addrmatch cmp'd with (0x%x):\n", 52537469Ssklower &(isop->isop_faddr->siso_addr)); 52637469Ssklower dump_isoaddr(isop->isop_faddr); 52736389Ssklower ENDDEBUG 52836389Ssklower isop = isop->isop_next; 52936389Ssklower continue; 53036389Ssklower } 53136389Ssklower if (errno) 53236389Ssklower isop->isop_socket->so_error = errno; 53336389Ssklower oisop = isop; 53436389Ssklower isop = isop->isop_next; 53536389Ssklower if (notify) 53636389Ssklower (*notify)(oisop); 53736389Ssklower } 53836389Ssklower splx(s); 53936389Ssklower IFDEBUG(D_ISO) 54036389Ssklower printf("END OF iso_pcbnotify\n" ); 54136389Ssklower ENDDEBUG 54236389Ssklower } 54336389Ssklower 54436389Ssklower 54536389Ssklower /* 54636389Ssklower * FUNCTION: iso_pcblookup 54736389Ssklower * 54836389Ssklower * PURPOSE: looks for a given combination of (faddr), (fport), 54936389Ssklower * (lport), (laddr) in the queue named by (head). 55036389Ssklower * Argument (flags) is ignored. 55136389Ssklower * 55236389Ssklower * RETURNS: ptr to the isopcb if it finds a connection matching 55336389Ssklower * these arguments, o.w. returns zero. 55436389Ssklower * 55536389Ssklower * SIDE EFFECTS: 55636389Ssklower * 55736389Ssklower * NOTES: 55836389Ssklower */ 55936389Ssklower struct isopcb * 56037469Ssklower iso_pcblookup(head, fportlen, fport, laddr) 56136389Ssklower struct isopcb *head; 56237469Ssklower register struct sockaddr_iso *laddr; 56337469Ssklower caddr_t fport; 56437469Ssklower int fportlen; 56536389Ssklower { 56636389Ssklower register struct isopcb *isop; 56737469Ssklower register caddr_t lp = TSEL(laddr); 56837469Ssklower unsigned int llen = laddr->siso_tsuffixlen; 56936389Ssklower 57036389Ssklower IFDEBUG(D_ISO) 57137469Ssklower printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", 57237469Ssklower head, laddr, fport); 57336389Ssklower ENDDEBUG 57436389Ssklower for (isop = head->isop_next; isop != head; isop = isop->isop_next) { 57537469Ssklower if (isop->isop_laddr == 0 || isop->isop_laddr == laddr) 57636389Ssklower continue; 57737469Ssklower if (isop->isop_laddr->siso_tsuffixlen != llen) 57836389Ssklower continue; 57937469Ssklower if (bcmp(lp, TSEL(isop->isop_laddr), llen)) 58037469Ssklower continue; 58137469Ssklower if (fportlen && isop->isop_faddr && 58237469Ssklower bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen)) 58337469Ssklower continue; 58436389Ssklower /* PHASE2 58536389Ssklower * addrmatch1 should be iso_addrmatch(a, b, mask) 58636389Ssklower * where mask is taken from isop->isop_laddrmask (new field) 58736389Ssklower * isop_lnetmask will also be available in isop 58836389Ssklower if (laddr != &zeroiso_addr && 58936389Ssklower !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) 59036389Ssklower continue; 59137469Ssklower */ 59237469Ssklower if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr))) 59337469Ssklower continue; 59436389Ssklower return (isop); 59536389Ssklower } 59636389Ssklower return (struct isopcb *)0; 59736389Ssklower } 59836389Ssklower #endif ISO 599