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*39934Ssklower * @(#)iso_pcb.c 7.6 (Berkeley) 01/17/90 3136389Ssklower * 3236389Ssklower * Iso address family net-layer(s) pcb stuff. NEH 1/29/87 3336389Ssklower */ 3438477Ssklower 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; 13438841Ssklower isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso); 13538841Ssklower isop->isop_sladdr.siso_family = AF_ISO; 13638841Ssklower isop->isop_sladdr.siso_tlen = 2; 13737469Ssklower isop->isop_sladdr.siso_nlen = 0; 13838841Ssklower isop->isop_sladdr.siso_slen = 0; 13938841Ssklower isop->isop_sladdr.siso_plen = 0; 14036389Ssklower goto noname; 14137469Ssklower } 14236389Ssklower siso = mtod(nam, struct sockaddr_iso *); 14336389Ssklower IFDEBUG(D_ISO) 14436389Ssklower printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); 14536389Ssklower printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr)); 14636389Ssklower ENDDEBUG 14736389Ssklower /* 14836389Ssklower * We would like sort of length check but since some OSI addrs 14936389Ssklower * do not have fixed length, we can't really do much. 15036389Ssklower * The ONLY thing we can say is that an osi addr has to have 15136389Ssklower * at LEAST an afi and one more byte and had better fit into 15236389Ssklower * a struct iso_addr. 15336389Ssklower * However, in fact the size of the whole thing is a struct 15436389Ssklower * sockaddr_iso, so probably this is what we should check for. 15536389Ssklower */ 15637469Ssklower if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) { 15736389Ssklower return ENAMETOOLONG; 15836389Ssklower } 15938841Ssklower if (siso->siso_tlen) { 16037469Ssklower register char *cp = TSEL(siso); 16137469Ssklower suf.data[0] = cp[0]; 16237469Ssklower suf.data[1] = cp[1]; 16337469Ssklower } 16437469Ssklower if (siso->siso_nlen) { 16536389Ssklower /* non-zero net addr- better match one of our interfaces */ 16636389Ssklower IFDEBUG(D_ISO) 16736389Ssklower printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); 16836389Ssklower ENDDEBUG 16937469Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) 17037469Ssklower if (SAME_ISOADDR(siso, &ia->ia_addr)) 17137469Ssklower break; 17237469Ssklower if (ia == 0) 17336389Ssklower return EADDRNOTAVAIL; 17436389Ssklower } 17537469Ssklower if (siso->siso_len <= sizeof (isop->isop_sladdr)) { 17637469Ssklower isop->isop_laddr = &isop->isop_sladdr; 17737469Ssklower } else { 17837469Ssklower if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0) 17937469Ssklower return ENOBUFS; 18037469Ssklower isop->isop_laddr = mtod(nam, struct sockaddr_iso *); 18137469Ssklower } 18237469Ssklower bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len); 183*39934Ssklower if (suf.s || siso->siso_tlen != 2) { 18438841Ssklower if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tlen <= 2) && 18537469Ssklower (u.u_uid != 0)) 18636389Ssklower return EACCES; 18736389Ssklower if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && 18837469Ssklower iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)) 18936389Ssklower return EADDRINUSE; 19037469Ssklower } else { 19137469Ssklower register char *cp; 19236389Ssklower noname: 19337469Ssklower cp = TSEL(isop->isop_laddr); 19436389Ssklower IFDEBUG(D_ISO) 19536389Ssklower printf("iso_pcbbind noname\n"); 19636389Ssklower ENDDEBUG 19736389Ssklower do { 19836389Ssklower if (head->isop_lport++ < ISO_PORT_RESERVED || 19936389Ssklower head->isop_lport > ISO_PORT_USERRESERVED) 20036389Ssklower head->isop_lport = ISO_PORT_RESERVED; 20137469Ssklower suf.s = head->isop_lport; 20237469Ssklower cp[0] = suf.data[0]; 20337469Ssklower cp[1] = suf.data[1]; 20437469Ssklower } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)); 20537469Ssklower } 20636389Ssklower IFDEBUG(D_ISO) 20736389Ssklower printf("iso_pcbbind returns 0, suf 0x%x\n", suf); 20836389Ssklower ENDDEBUG 20936389Ssklower return 0; 21036389Ssklower } 21136389Ssklower /* 21236389Ssklower * FUNCTION: iso_pcbconnect 21336389Ssklower * 21436389Ssklower * PURPOSE: Make the isopcb (isop) look like it's connected. 21536389Ssklower * In other words, give it the peer address given in 21636389Ssklower * the mbuf * (nam). Make sure such a combination 21736389Ssklower * of local, peer addresses doesn't already exist 21836389Ssklower * for this protocol. Internet mentality prevails here, 21936389Ssklower * wherein a src,dst pair uniquely identifies a connection. 22036389Ssklower * Both net address and port must be specified in argument 22136389Ssklower * (nam). 22236389Ssklower * If we don't have a local address for this socket yet, 22336389Ssklower * we pick one by calling iso_pcbbind(). 22436389Ssklower * 22536389Ssklower * RETURNS: errno E* or 0 if ok. 22636389Ssklower * 22736389Ssklower * SIDE EFFECTS: Looks up a route, which may cause one to be left 22836389Ssklower * in the isopcb. 22936389Ssklower * 23036389Ssklower * NOTES: 23136389Ssklower */ 23236389Ssklower int 23336389Ssklower iso_pcbconnect(isop, nam) 23437469Ssklower register struct isopcb *isop; 23536389Ssklower struct mbuf *nam; 23636389Ssklower { 23736389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 23837469Ssklower int local_zero, error = 0; 23937469Ssklower struct iso_ifaddr *ia; 24036389Ssklower 24136389Ssklower IFDEBUG(D_ISO) 24237469Ssklower printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x", 24337469Ssklower isop, isop->isop_socket, nam); 24437469Ssklower printf("nam->m_len 0x%x), addr:\n", nam->m_len); 24536389Ssklower dump_isoaddr(siso); 24636389Ssklower ENDDEBUG 24737469Ssklower if (nam->m_len < siso->siso_len) 24837469Ssklower return EINVAL; 24936389Ssklower if (siso->siso_family != AF_ISO) 25036389Ssklower return EAFNOSUPPORT; 25138477Ssklower if (siso->siso_nlen == 0) { 25238477Ssklower if (ia = iso_ifaddr) { 25338477Ssklower int nlen = ia->ia_addr.siso_nlen; 25438477Ssklower ovbcopy(TSEL(siso), nlen + TSEL(siso), 25538841Ssklower siso->siso_plen + siso->siso_tlen + siso->siso_slen); 25638477Ssklower bcopy((caddr_t)&ia->ia_addr.siso_addr, 25738477Ssklower (caddr_t)&siso->siso_addr, nlen + 1); 25838477Ssklower /* includes siso->siso_nlen = nlen; */ 25938477Ssklower } else 26038477Ssklower return EADDRNOTAVAIL; 26138477Ssklower } 26237469Ssklower /* 26337469Ssklower * Local zero means either not bound, or bound to a TSEL, but no 26437469Ssklower * particular local interface. So, if we want to send somebody 26537469Ssklower * we need to choose a return address. 26636389Ssklower */ 26737469Ssklower local_zero = 26837469Ssklower ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0)); 26936389Ssklower if (local_zero) { 27037469Ssklower int flags; 27136389Ssklower 27236389Ssklower IFDEBUG(D_ISO) 27336389Ssklower printf("iso_pcbconnect localzero 1\n"); 27436389Ssklower ENDDEBUG 27536389Ssklower /* 27636389Ssklower * If route is known or can be allocated now, 27736389Ssklower * our src addr is taken from the i/f, else punt. 27836389Ssklower */ 27937469Ssklower flags = isop->isop_socket->so_options & SO_DONTROUTE; 28037469Ssklower if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags, 28137469Ssklower (struct sockaddr **)0, &ia)) 28237469Ssklower return error; 28336389Ssklower IFDEBUG(D_ISO) 28437469Ssklower printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x", 28537469Ssklower isop->isop_route.ro_rt); 28637469Ssklower printf(" ia 0x%x\n", ia); 28736389Ssklower ENDDEBUG 28836389Ssklower } 28936389Ssklower IFDEBUG(D_ISO) 29036389Ssklower printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", 29136389Ssklower isop, isop->isop_socket); 29236389Ssklower ENDDEBUG 29336389Ssklower if (local_zero) { 29437469Ssklower int nlen, tlen, totlen; caddr_t oldtsel, newtsel; 29537469Ssklower siso = isop->isop_laddr; 29638841Ssklower if (siso == 0 || siso->siso_tlen == 0) 29736389Ssklower (void)iso_pcbbind(isop, (struct mbuf *)0); 29837469Ssklower /* 29937469Ssklower * Here we have problem of squezeing in a definite network address 30037469Ssklower * into an existing sockaddr_iso, which in fact may not have room 30137469Ssklower * for it. This gets messy. 30237469Ssklower */ 30337469Ssklower siso = isop->isop_laddr; 30437469Ssklower oldtsel = TSEL(siso); 30538841Ssklower tlen = siso->siso_tlen; 30637469Ssklower nlen = ia->ia_addr.siso_nlen; 30737469Ssklower totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]); 30837469Ssklower if ((siso == &isop->isop_sladdr) && 30937469Ssklower (totlen > sizeof(isop->isop_sladdr))) { 31037469Ssklower struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); 31137469Ssklower if (m == 0) 31237469Ssklower return ENOBUFS; 31337469Ssklower m->m_len = totlen; 31437469Ssklower isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *); 31537469Ssklower } 31637469Ssklower siso->siso_nlen = ia->ia_addr.siso_nlen; 31737469Ssklower newtsel = TSEL(siso); 31837469Ssklower ovbcopy(oldtsel, newtsel, tlen); 31937469Ssklower bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen); 32038841Ssklower siso->siso_tlen = tlen; 32137469Ssklower siso->siso_family = AF_ISO; 32237469Ssklower siso->siso_len = totlen; 32337469Ssklower siso = mtod(nam, struct sockaddr_iso *); 32436389Ssklower } 32536389Ssklower IFDEBUG(D_ISO) 32636389Ssklower printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", 32736389Ssklower isop, isop->isop_socket); 32836389Ssklower ENDDEBUG 32937469Ssklower /* 33037469Ssklower * If we had to allocate space to a previous big foreign address, 33137469Ssklower * and for some reason we didn't free it, we reuse it knowing 33237469Ssklower * that is going to be big enough, as sockaddrs are delivered in 33337469Ssklower * 128 byte mbufs. 33437469Ssklower * If the foreign address is small enough, we use default space; 33537469Ssklower * otherwise, we grab an mbuf to copy into. 33637469Ssklower */ 33737469Ssklower if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) { 33837469Ssklower if (siso->siso_len <= sizeof(isop->isop_sfaddr)) 33937469Ssklower isop->isop_faddr = &isop->isop_sfaddr; 34037469Ssklower else { 34137469Ssklower struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); 34237469Ssklower if (m == 0) 34337469Ssklower return ENOBUFS; 34437469Ssklower isop->isop_faddr = mtod(m, struct sockaddr_iso *); 34537469Ssklower } 34637469Ssklower } 34737469Ssklower bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len); 34836389Ssklower IFDEBUG(D_ISO) 34936389Ssklower printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", 35036389Ssklower isop, isop->isop_socket); 35136389Ssklower printf("iso_pcbconnect connected to addr:\n"); 35237469Ssklower dump_isoaddr(isop->isop_faddr); 35336389Ssklower printf("iso_pcbconnect end: src addr:\n"); 35437469Ssklower dump_isoaddr(isop->isop_laddr); 35536389Ssklower ENDDEBUG 35636389Ssklower return 0; 35736389Ssklower } 35836389Ssklower 35936389Ssklower /* 36036389Ssklower * FUNCTION: iso_pcbdisconnect() 36136389Ssklower * 36236389Ssklower * PURPOSE: washes away the peer address info so the socket 36336389Ssklower * appears to be disconnected. 36436389Ssklower * If there's no file descriptor associated with the socket 36536389Ssklower * it detaches the pcb. 36636389Ssklower * 36736389Ssklower * RETURNS: Nada. 36836389Ssklower * 36936389Ssklower * SIDE EFFECTS: May detach the pcb. 37036389Ssklower * 37136389Ssklower * NOTES: 37236389Ssklower */ 37336389Ssklower void 37436389Ssklower iso_pcbdisconnect(isop) 37536389Ssklower struct isopcb *isop; 37636389Ssklower { 37736389Ssklower void iso_pcbdetach(); 378*39934Ssklower register struct sockaddr_iso *siso; 37936389Ssklower 38036389Ssklower IFDEBUG(D_ISO) 38136389Ssklower printf("iso_pcbdisconnect(isop 0x%x)\n", isop); 38236389Ssklower ENDDEBUG 38337469Ssklower /* 38437469Ssklower * Preserver binding infnormation if already bound. 38537469Ssklower */ 386*39934Ssklower if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) { 387*39934Ssklower caddr_t otsel = TSEL(siso); 388*39934Ssklower siso->siso_nlen = 0; 389*39934Ssklower ovbcopy(otsel, TSEL(siso), siso->siso_tlen); 390*39934Ssklower } 39137469Ssklower if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr) 39237469Ssklower m_freem(dtom(isop->isop_faddr)); 39337469Ssklower isop->isop_faddr = 0; 39436389Ssklower if (isop->isop_socket->so_state & SS_NOFDREF) 39536389Ssklower iso_pcbdetach(isop); 39636389Ssklower } 39736389Ssklower 39836389Ssklower /* 39936389Ssklower * FUNCTION: iso_pcbdetach 40036389Ssklower * 40136389Ssklower * PURPOSE: detach the pcb at *(isop) from it's socket and free 40236389Ssklower * the mbufs associated with the pcb.. 40336389Ssklower * Dequeues (isop) from its head. 40436389Ssklower * 40536389Ssklower * RETURNS: Nada. 40636389Ssklower * 40736389Ssklower * SIDE EFFECTS: 40836389Ssklower * 40936389Ssklower * NOTES: 41036389Ssklower */ 41136389Ssklower void 41236389Ssklower iso_pcbdetach(isop) 41336389Ssklower struct isopcb *isop; 41436389Ssklower { 41536389Ssklower struct socket *so = isop->isop_socket; 41636389Ssklower 41736389Ssklower IFDEBUG(D_ISO) 41836389Ssklower printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 41936389Ssklower isop, isop->isop_socket, so); 42036389Ssklower ENDDEBUG 42136389Ssklower if (so ) { /* in the x.25 domain, we sometimes have no socket */ 42236389Ssklower so->so_pcb = 0; 42336389Ssklower sofree(so); 42436389Ssklower } 42536389Ssklower IFDEBUG(D_ISO) 42636389Ssklower printf("iso_pcbdetach 2 \n"); 42736389Ssklower ENDDEBUG 42836389Ssklower if (isop->isop_options) 42936389Ssklower (void)m_free(isop->isop_options); 43036389Ssklower IFDEBUG(D_ISO) 43136389Ssklower printf("iso_pcbdetach 3 \n"); 43236389Ssklower ENDDEBUG 43336389Ssklower if (isop->isop_route.ro_rt) 43436389Ssklower rtfree(isop->isop_route.ro_rt); 43536389Ssklower IFDEBUG(D_ISO) 43636389Ssklower printf("iso_pcbdetach 3.1\n"); 43736389Ssklower ENDDEBUG 43836389Ssklower if (isop->isop_clnpcache != NULL) { 43936389Ssklower struct clnp_cache *clcp = 44036389Ssklower mtod(isop->isop_clnpcache, struct clnp_cache *); 44136389Ssklower IFDEBUG(D_ISO) 44236389Ssklower printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", 44336389Ssklower clcp, clcp->clc_hdr); 44436389Ssklower ENDDEBUG 44536389Ssklower if (clcp->clc_hdr != NULL) 44636389Ssklower m_free(clcp->clc_hdr); 44736389Ssklower IFDEBUG(D_ISO) 44836389Ssklower printf("iso_pcbdetach 3.3: freeing cache x%x\n", 44936389Ssklower isop->isop_clnpcache); 45036389Ssklower ENDDEBUG 45136389Ssklower m_free(isop->isop_clnpcache); 45236389Ssklower } 45336389Ssklower IFDEBUG(D_ISO) 45436389Ssklower printf("iso_pcbdetach 4 \n"); 45536389Ssklower ENDDEBUG 45636389Ssklower remque(isop); 45736389Ssklower IFDEBUG(D_ISO) 45836389Ssklower printf("iso_pcbdetach 5 \n"); 45936389Ssklower ENDDEBUG 46037469Ssklower if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr)) 46137469Ssklower m_freem(dtom(isop->isop_laddr)); 46237469Ssklower free((caddr_t)isop, M_IFADDR); 46336389Ssklower } 46436389Ssklower 46536389Ssklower 46636389Ssklower /* 46736389Ssklower * FUNCTION: iso_pcbnotify 46836389Ssklower * 46936389Ssklower * PURPOSE: notify all connections in this protocol's queue (head) 47036389Ssklower * that have peer address (dst) of the problem (errno) 47136389Ssklower * by calling (notify) on the connections' isopcbs. 47236389Ssklower * 47336389Ssklower * RETURNS: Rien. 47436389Ssklower * 47536389Ssklower * SIDE EFFECTS: 47636389Ssklower * 47736389Ssklower * NOTES: (notify) is called at splimp! 47836389Ssklower */ 47936389Ssklower void 480*39934Ssklower iso_pcbnotify(head, siso, errno, notify) 48136389Ssklower struct isopcb *head; 482*39934Ssklower register struct sockaddr_iso *siso; 48336389Ssklower int errno, (*notify)(); 48436389Ssklower { 485*39934Ssklower register struct isopcb *isop; 48636389Ssklower int s = splimp(); 48736389Ssklower 48836389Ssklower IFDEBUG(D_ISO) 48936389Ssklower printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); 49036389Ssklower ENDDEBUG 491*39934Ssklower for (isop = head->isop_next; isop != head; isop = isop->isop_next) { 492*39934Ssklower if (isop->isop_socket == 0 || isop->isop_faddr == 0 || 493*39934Ssklower !SAME_ISOADDR(siso, isop->isop_faddr)) { 49436389Ssklower IFDEBUG(D_ISO) 49536389Ssklower printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , 49636389Ssklower isop, isop->isop_socket); 497*39934Ssklower printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr); 49837469Ssklower dump_isoaddr(isop->isop_faddr); 49936389Ssklower ENDDEBUG 50036389Ssklower continue; 50136389Ssklower } 50236389Ssklower if (errno) 50336389Ssklower isop->isop_socket->so_error = errno; 50436389Ssklower if (notify) 505*39934Ssklower (*notify)(isop); 50636389Ssklower } 50736389Ssklower splx(s); 50836389Ssklower IFDEBUG(D_ISO) 50936389Ssklower printf("END OF iso_pcbnotify\n" ); 51036389Ssklower ENDDEBUG 51136389Ssklower } 51236389Ssklower 51336389Ssklower 51436389Ssklower /* 51536389Ssklower * FUNCTION: iso_pcblookup 51636389Ssklower * 51736389Ssklower * PURPOSE: looks for a given combination of (faddr), (fport), 51836389Ssklower * (lport), (laddr) in the queue named by (head). 51936389Ssklower * Argument (flags) is ignored. 52036389Ssklower * 52136389Ssklower * RETURNS: ptr to the isopcb if it finds a connection matching 52236389Ssklower * these arguments, o.w. returns zero. 52336389Ssklower * 52436389Ssklower * SIDE EFFECTS: 52536389Ssklower * 52636389Ssklower * NOTES: 52736389Ssklower */ 52836389Ssklower struct isopcb * 52937469Ssklower iso_pcblookup(head, fportlen, fport, laddr) 53036389Ssklower struct isopcb *head; 53137469Ssklower register struct sockaddr_iso *laddr; 53237469Ssklower caddr_t fport; 53337469Ssklower int fportlen; 53436389Ssklower { 53536389Ssklower register struct isopcb *isop; 53637469Ssklower register caddr_t lp = TSEL(laddr); 53738841Ssklower unsigned int llen = laddr->siso_tlen; 53836389Ssklower 53936389Ssklower IFDEBUG(D_ISO) 54037469Ssklower printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", 54137469Ssklower head, laddr, fport); 54236389Ssklower ENDDEBUG 54336389Ssklower for (isop = head->isop_next; isop != head; isop = isop->isop_next) { 54437469Ssklower if (isop->isop_laddr == 0 || isop->isop_laddr == laddr) 54536389Ssklower continue; 54638841Ssklower if (isop->isop_laddr->siso_tlen != llen) 54736389Ssklower continue; 54837469Ssklower if (bcmp(lp, TSEL(isop->isop_laddr), llen)) 54937469Ssklower continue; 55037469Ssklower if (fportlen && isop->isop_faddr && 55137469Ssklower bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen)) 55237469Ssklower continue; 55336389Ssklower /* PHASE2 55436389Ssklower * addrmatch1 should be iso_addrmatch(a, b, mask) 55536389Ssklower * where mask is taken from isop->isop_laddrmask (new field) 55636389Ssklower * isop_lnetmask will also be available in isop 55736389Ssklower if (laddr != &zeroiso_addr && 55836389Ssklower !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) 55936389Ssklower continue; 56037469Ssklower */ 56137469Ssklower if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr))) 56237469Ssklower continue; 56336389Ssklower return (isop); 56436389Ssklower } 56536389Ssklower return (struct isopcb *)0; 56636389Ssklower } 56736389Ssklower #endif ISO 568