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 $ 3036389Ssklower * 3136389Ssklower * Iso address family net-layer(s) pcb stuff. NEH 1/29/87 3236389Ssklower */ 3336389Ssklower #ifndef lint 3436389Ssklower static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $"; 3536389Ssklower #endif 3636389Ssklower 3736389Ssklower #ifdef ISO 3836389Ssklower 3936389Ssklower #include "param.h" 4036389Ssklower #include "systm.h" 4136389Ssklower #include "dir.h" 4236389Ssklower #include "user.h" 4336389Ssklower #include "mbuf.h" 44*37469Ssklower #include "socket.h" 45*37469Ssklower #include "socketvar.h" 46*37469Ssklower #include "argo_debug.h" 47*37469Ssklower #include "iso.h" 48*37469Ssklower #include "clnp.h" 4936389Ssklower #include "../netinet/in_systm.h" 5036389Ssklower #include "../net/if.h" 5136389Ssklower #include "../net/route.h" 52*37469Ssklower #include "iso_pcb.h" 53*37469Ssklower #include "iso_var.h" 5436389Ssklower #include "protosw.h" 5536389Ssklower 5636389Ssklower #define PCBNULL (struct isopcb *)0 5736389Ssklower struct iso_addr zeroiso_addr = { 5836389Ssklower 0 5936389Ssklower }; 6036389Ssklower 6136389Ssklower 6236389Ssklower /* 6336389Ssklower * FUNCTION: iso_pcballoc 6436389Ssklower * 6536389Ssklower * PURPOSE: creates an isopcb structure in an mbuf, 6636389Ssklower * with socket (so), and 6736389Ssklower * puts it in the queue with head (head) 6836389Ssklower * 6936389Ssklower * RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf 7036389Ssklower */ 7136389Ssklower int 7236389Ssklower iso_pcballoc(so, head) 7336389Ssklower struct socket *so; 7436389Ssklower struct isopcb *head; 7536389Ssklower { 7636389Ssklower register struct isopcb *isop; 7736389Ssklower 7836389Ssklower IFDEBUG(D_ISO) 7936389Ssklower printf("iso_pcballoc(so 0x%x)\n", so); 8036389Ssklower ENDDEBUG 81*37469Ssklower MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT); 82*37469Ssklower if (isop == NULL) 8336389Ssklower return ENOBUFS; 84*37469Ssklower bzero((caddr_t)isop, sizeof(*isop)); 8536389Ssklower isop->isop_head = head; 8636389Ssklower isop->isop_socket = so; 8736389Ssklower insque(isop, head); 8836389Ssklower so->so_pcb = (caddr_t)isop; 8936389Ssklower return 0; 9036389Ssklower } 9136389Ssklower 9236389Ssklower /* 9336389Ssklower * FUNCTION: iso_pcbbind 9436389Ssklower * 9536389Ssklower * PURPOSE: binds the address given in *(nam) to the socket 9636389Ssklower * specified by the isopcb in *(isop) 9736389Ssklower * If the given address is zero, it makes sure the 9836389Ssklower * address isn't already in use and if it's got a network 9936389Ssklower * portion, we look for an interface with that network 10036389Ssklower * address. If the address given is zero, we allocate 10136389Ssklower * a port and stuff it in the (nam) structure. 10236389Ssklower * 10336389Ssklower * RETURNS: errno E* or 0 if ok. 10436389Ssklower * 10536389Ssklower * SIDE EFFECTS: increments head->isop_lport if it allocates a port # 10636389Ssklower * 10736389Ssklower * NOTES: 10836389Ssklower */ 109*37469Ssklower #define satosiso(sa) ((struct sockaddr_iso *)(sa)) 11036389Ssklower int 11136389Ssklower iso_pcbbind(isop, nam) 11236389Ssklower register struct isopcb *isop; 11336389Ssklower struct mbuf *nam; 11436389Ssklower { 11536389Ssklower register struct isopcb *head = isop->isop_head; 11636389Ssklower register struct sockaddr_iso *siso; 117*37469Ssklower struct iso_ifaddr *ia; 118*37469Ssklower union { 119*37469Ssklower char data[2]; 120*37469Ssklower u_short s; 121*37469Ssklower } suf; 12236389Ssklower 12336389Ssklower IFDEBUG(D_ISO) 12436389Ssklower printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam); 12536389Ssklower ENDDEBUG 126*37469Ssklower suf.s = 0; 12736389Ssklower if (iso_ifaddr == 0) /* any interfaces attached? */ 12836389Ssklower return EADDRNOTAVAIL; 129*37469Ssklower if (isop->isop_laddr) /* already bound */ 13036389Ssklower return EADDRINUSE; 131*37469Ssklower if(nam == (struct mbuf *)0) { 132*37469Ssklower isop->isop_laddr = &isop->isop_sladdr; 133*37469Ssklower isop->isop_sladdr.siso_tsuffixlen = 2; 134*37469Ssklower isop->isop_sladdr.siso_nlen = 0; 135*37469Ssklower isop->isop_sladdr.siso_family = AF_ISO; 136*37469Ssklower isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso); 13736389Ssklower goto noname; 138*37469Ssklower } 13936389Ssklower siso = mtod(nam, struct sockaddr_iso *); 14036389Ssklower IFDEBUG(D_ISO) 14136389Ssklower printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); 14236389Ssklower printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr)); 14336389Ssklower ENDDEBUG 14436389Ssklower /* 14536389Ssklower * We would like sort of length check but since some OSI addrs 14636389Ssklower * do not have fixed length, we can't really do much. 14736389Ssklower * The ONLY thing we can say is that an osi addr has to have 14836389Ssklower * at LEAST an afi and one more byte and had better fit into 14936389Ssklower * a struct iso_addr. 15036389Ssklower * However, in fact the size of the whole thing is a struct 15136389Ssklower * sockaddr_iso, so probably this is what we should check for. 15236389Ssklower */ 153*37469Ssklower if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) { 15436389Ssklower return ENAMETOOLONG; 15536389Ssklower } 156*37469Ssklower if (siso->siso_tsuffixlen) { 157*37469Ssklower register char *cp = TSEL(siso); 158*37469Ssklower suf.data[0] = cp[0]; 159*37469Ssklower suf.data[1] = cp[1]; 160*37469Ssklower } 161*37469Ssklower if (siso->siso_nlen) { 16236389Ssklower /* non-zero net addr- better match one of our interfaces */ 16336389Ssklower IFDEBUG(D_ISO) 16436389Ssklower printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); 16536389Ssklower ENDDEBUG 166*37469Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) 167*37469Ssklower if (SAME_ISOADDR(siso, &ia->ia_addr)) 168*37469Ssklower break; 169*37469Ssklower if (ia == 0) 17036389Ssklower return EADDRNOTAVAIL; 17136389Ssklower } 172*37469Ssklower if (siso->siso_len <= sizeof (isop->isop_sladdr)) { 173*37469Ssklower isop->isop_laddr = &isop->isop_sladdr; 174*37469Ssklower } else { 175*37469Ssklower if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0) 176*37469Ssklower return ENOBUFS; 177*37469Ssklower isop->isop_laddr = mtod(nam, struct sockaddr_iso *); 178*37469Ssklower } 179*37469Ssklower bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len); 180*37469Ssklower if (suf.s) { 181*37469Ssklower if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tsuffixlen <= 2) && 182*37469Ssklower (u.u_uid != 0)) 18336389Ssklower return EACCES; 18436389Ssklower if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && 185*37469Ssklower iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)) 18636389Ssklower return EADDRINUSE; 187*37469Ssklower } else { 188*37469Ssklower register char *cp; 18936389Ssklower noname: 190*37469Ssklower cp = TSEL(isop->isop_laddr); 19136389Ssklower IFDEBUG(D_ISO) 19236389Ssklower printf("iso_pcbbind noname\n"); 19336389Ssklower ENDDEBUG 19436389Ssklower do { 19536389Ssklower if (head->isop_lport++ < ISO_PORT_RESERVED || 19636389Ssklower head->isop_lport > ISO_PORT_USERRESERVED) 19736389Ssklower head->isop_lport = ISO_PORT_RESERVED; 198*37469Ssklower suf.s = head->isop_lport; 199*37469Ssklower cp[0] = suf.data[0]; 200*37469Ssklower cp[1] = suf.data[1]; 201*37469Ssklower } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)); 202*37469Ssklower } 20336389Ssklower IFDEBUG(D_ISO) 20436389Ssklower printf("iso_pcbbind returns 0, suf 0x%x\n", suf); 20536389Ssklower ENDDEBUG 20636389Ssklower return 0; 20736389Ssklower } 20836389Ssklower /* 20936389Ssklower * FUNCTION: iso_pcbconnect 21036389Ssklower * 21136389Ssklower * PURPOSE: Make the isopcb (isop) look like it's connected. 21236389Ssklower * In other words, give it the peer address given in 21336389Ssklower * the mbuf * (nam). Make sure such a combination 21436389Ssklower * of local, peer addresses doesn't already exist 21536389Ssklower * for this protocol. Internet mentality prevails here, 21636389Ssklower * wherein a src,dst pair uniquely identifies a connection. 21736389Ssklower * Both net address and port must be specified in argument 21836389Ssklower * (nam). 21936389Ssklower * If we don't have a local address for this socket yet, 22036389Ssklower * we pick one by calling iso_pcbbind(). 22136389Ssklower * 22236389Ssklower * RETURNS: errno E* or 0 if ok. 22336389Ssklower * 22436389Ssklower * SIDE EFFECTS: Looks up a route, which may cause one to be left 22536389Ssklower * in the isopcb. 22636389Ssklower * 22736389Ssklower * NOTES: 22836389Ssklower */ 22936389Ssklower int 23036389Ssklower iso_pcbconnect(isop, nam) 231*37469Ssklower register struct isopcb *isop; 23236389Ssklower struct mbuf *nam; 23336389Ssklower { 23436389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 235*37469Ssklower int local_zero, error = 0; 236*37469Ssklower struct iso_ifaddr *ia; 23736389Ssklower 23836389Ssklower IFDEBUG(D_ISO) 239*37469Ssklower printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x", 240*37469Ssklower isop, isop->isop_socket, nam); 241*37469Ssklower printf("nam->m_len 0x%x), addr:\n", nam->m_len); 24236389Ssklower dump_isoaddr(siso); 24336389Ssklower ENDDEBUG 244*37469Ssklower if (nam->m_len < siso->siso_len) 245*37469Ssklower return EINVAL; 24636389Ssklower if (siso->siso_family != AF_ISO) 24736389Ssklower return EAFNOSUPPORT; 248*37469Ssklower /* 249*37469Ssklower * Local zero means either not bound, or bound to a TSEL, but no 250*37469Ssklower * particular local interface. So, if we want to send somebody 251*37469Ssklower * we need to choose a return address. 25236389Ssklower */ 253*37469Ssklower local_zero = 254*37469Ssklower ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0)); 25536389Ssklower if (local_zero) { 256*37469Ssklower int flags; 25736389Ssklower 25836389Ssklower IFDEBUG(D_ISO) 25936389Ssklower printf("iso_pcbconnect localzero 1\n"); 26036389Ssklower ENDDEBUG 26136389Ssklower /* 26236389Ssklower * If route is known or can be allocated now, 26336389Ssklower * our src addr is taken from the i/f, else punt. 26436389Ssklower */ 265*37469Ssklower flags = isop->isop_socket->so_options & SO_DONTROUTE; 266*37469Ssklower if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags, 267*37469Ssklower (struct sockaddr **)0, &ia)) 268*37469Ssklower return error; 26936389Ssklower IFDEBUG(D_ISO) 270*37469Ssklower printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x", 271*37469Ssklower isop->isop_route.ro_rt); 272*37469Ssklower printf(" ia 0x%x\n", ia); 27336389Ssklower ENDDEBUG 27436389Ssklower } 27536389Ssklower IFDEBUG(D_ISO) 27636389Ssklower printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", 27736389Ssklower isop, isop->isop_socket); 27836389Ssklower ENDDEBUG 27936389Ssklower if (local_zero) { 280*37469Ssklower int nlen, tlen, totlen; caddr_t oldtsel, newtsel; 281*37469Ssklower siso = isop->isop_laddr; 282*37469Ssklower if (siso == 0 || siso->siso_tsuffixlen == 0) 28336389Ssklower (void)iso_pcbbind(isop, (struct mbuf *)0); 284*37469Ssklower /* 285*37469Ssklower * Here we have problem of squezeing in a definite network address 286*37469Ssklower * into an existing sockaddr_iso, which in fact may not have room 287*37469Ssklower * for it. This gets messy. 288*37469Ssklower */ 289*37469Ssklower siso = isop->isop_laddr; 290*37469Ssklower oldtsel = TSEL(siso); 291*37469Ssklower tlen = siso->siso_tsuffixlen; 292*37469Ssklower nlen = ia->ia_addr.siso_nlen; 293*37469Ssklower totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]); 294*37469Ssklower if ((siso == &isop->isop_sladdr) && 295*37469Ssklower (totlen > sizeof(isop->isop_sladdr))) { 296*37469Ssklower struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); 297*37469Ssklower if (m == 0) 298*37469Ssklower return ENOBUFS; 299*37469Ssklower m->m_len = totlen; 300*37469Ssklower isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *); 301*37469Ssklower } 302*37469Ssklower siso->siso_nlen = ia->ia_addr.siso_nlen; 303*37469Ssklower newtsel = TSEL(siso); 304*37469Ssklower ovbcopy(oldtsel, newtsel, tlen); 305*37469Ssklower bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen); 306*37469Ssklower siso->siso_tsuffixlen = tlen; 307*37469Ssklower siso->siso_family = AF_ISO; 308*37469Ssklower siso->siso_len = totlen; 309*37469Ssklower siso = mtod(nam, struct sockaddr_iso *); 31036389Ssklower } 31136389Ssklower IFDEBUG(D_ISO) 31236389Ssklower printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", 31336389Ssklower isop, isop->isop_socket); 31436389Ssklower ENDDEBUG 315*37469Ssklower /* 316*37469Ssklower * If we had to allocate space to a previous big foreign address, 317*37469Ssklower * and for some reason we didn't free it, we reuse it knowing 318*37469Ssklower * that is going to be big enough, as sockaddrs are delivered in 319*37469Ssklower * 128 byte mbufs. 320*37469Ssklower * If the foreign address is small enough, we use default space; 321*37469Ssklower * otherwise, we grab an mbuf to copy into. 322*37469Ssklower */ 323*37469Ssklower if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) { 324*37469Ssklower if (siso->siso_len <= sizeof(isop->isop_sfaddr)) 325*37469Ssklower isop->isop_faddr = &isop->isop_sfaddr; 326*37469Ssklower else { 327*37469Ssklower struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); 328*37469Ssklower if (m == 0) 329*37469Ssklower return ENOBUFS; 330*37469Ssklower isop->isop_faddr = mtod(m, struct sockaddr_iso *); 331*37469Ssklower } 332*37469Ssklower } 333*37469Ssklower bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len); 33436389Ssklower IFDEBUG(D_ISO) 33536389Ssklower printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", 33636389Ssklower isop, isop->isop_socket); 33736389Ssklower printf("iso_pcbconnect connected to addr:\n"); 338*37469Ssklower dump_isoaddr(isop->isop_faddr); 33936389Ssklower printf("iso_pcbconnect end: src addr:\n"); 340*37469Ssklower dump_isoaddr(isop->isop_laddr); 34136389Ssklower ENDDEBUG 34236389Ssklower return 0; 34336389Ssklower } 34436389Ssklower 34536389Ssklower /* 34636389Ssklower * FUNCTION: iso_pcbdisconnect() 34736389Ssklower * 34836389Ssklower * PURPOSE: washes away the peer address info so the socket 34936389Ssklower * appears to be disconnected. 35036389Ssklower * If there's no file descriptor associated with the socket 35136389Ssklower * it detaches the pcb. 35236389Ssklower * 35336389Ssklower * RETURNS: Nada. 35436389Ssklower * 35536389Ssklower * SIDE EFFECTS: May detach the pcb. 35636389Ssklower * 35736389Ssklower * NOTES: 35836389Ssklower */ 35936389Ssklower void 36036389Ssklower iso_pcbdisconnect(isop) 36136389Ssklower struct isopcb *isop; 36236389Ssklower { 36336389Ssklower void iso_pcbdetach(); 36436389Ssklower 36536389Ssklower IFDEBUG(D_ISO) 36636389Ssklower printf("iso_pcbdisconnect(isop 0x%x)\n", isop); 36736389Ssklower ENDDEBUG 368*37469Ssklower /* 369*37469Ssklower * Preserver binding infnormation if already bound. 370*37469Ssklower */ 371*37469Ssklower if (isop->isop_laddr && isop->isop_laddr->siso_nlen) 372*37469Ssklower isop->isop_laddr->siso_nlen = 0; 373*37469Ssklower if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr) 374*37469Ssklower m_freem(dtom(isop->isop_faddr)); 375*37469Ssklower isop->isop_faddr = 0; 37636389Ssklower if (isop->isop_socket->so_state & SS_NOFDREF) 37736389Ssklower iso_pcbdetach(isop); 37836389Ssklower } 37936389Ssklower 38036389Ssklower /* 38136389Ssklower * FUNCTION: iso_pcbdetach 38236389Ssklower * 38336389Ssklower * PURPOSE: detach the pcb at *(isop) from it's socket and free 38436389Ssklower * the mbufs associated with the pcb.. 38536389Ssklower * Dequeues (isop) from its head. 38636389Ssklower * 38736389Ssklower * RETURNS: Nada. 38836389Ssklower * 38936389Ssklower * SIDE EFFECTS: 39036389Ssklower * 39136389Ssklower * NOTES: 39236389Ssklower */ 39336389Ssklower void 39436389Ssklower iso_pcbdetach(isop) 39536389Ssklower struct isopcb *isop; 39636389Ssklower { 39736389Ssklower struct socket *so = isop->isop_socket; 39836389Ssklower 39936389Ssklower IFDEBUG(D_ISO) 40036389Ssklower printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 40136389Ssklower isop, isop->isop_socket, so); 40236389Ssklower ENDDEBUG 40336389Ssklower if (so ) { /* in the x.25 domain, we sometimes have no socket */ 40436389Ssklower so->so_pcb = 0; 40536389Ssklower sofree(so); 40636389Ssklower } 40736389Ssklower IFDEBUG(D_ISO) 40836389Ssklower printf("iso_pcbdetach 2 \n"); 40936389Ssklower ENDDEBUG 41036389Ssklower if (isop->isop_options) 41136389Ssklower (void)m_free(isop->isop_options); 41236389Ssklower IFDEBUG(D_ISO) 41336389Ssklower printf("iso_pcbdetach 3 \n"); 41436389Ssklower ENDDEBUG 41536389Ssklower if (isop->isop_route.ro_rt) 41636389Ssklower rtfree(isop->isop_route.ro_rt); 41736389Ssklower IFDEBUG(D_ISO) 41836389Ssklower printf("iso_pcbdetach 3.1\n"); 41936389Ssklower ENDDEBUG 42036389Ssklower if (isop->isop_clnpcache != NULL) { 42136389Ssklower struct clnp_cache *clcp = 42236389Ssklower mtod(isop->isop_clnpcache, struct clnp_cache *); 42336389Ssklower IFDEBUG(D_ISO) 42436389Ssklower printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", 42536389Ssklower clcp, clcp->clc_hdr); 42636389Ssklower ENDDEBUG 42736389Ssklower if (clcp->clc_hdr != NULL) 42836389Ssklower m_free(clcp->clc_hdr); 42936389Ssklower IFDEBUG(D_ISO) 43036389Ssklower printf("iso_pcbdetach 3.3: freeing cache x%x\n", 43136389Ssklower isop->isop_clnpcache); 43236389Ssklower ENDDEBUG 43336389Ssklower m_free(isop->isop_clnpcache); 43436389Ssklower } 43536389Ssklower IFDEBUG(D_ISO) 43636389Ssklower printf("iso_pcbdetach 4 \n"); 43736389Ssklower ENDDEBUG 43836389Ssklower remque(isop); 43936389Ssklower IFDEBUG(D_ISO) 44036389Ssklower printf("iso_pcbdetach 5 \n"); 44136389Ssklower ENDDEBUG 442*37469Ssklower if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr)) 443*37469Ssklower m_freem(dtom(isop->isop_laddr)); 444*37469Ssklower free((caddr_t)isop, M_IFADDR); 44536389Ssklower } 44636389Ssklower 44736389Ssklower #ifdef notdef 44836389Ssklower /* NEEDED? */ 44936389Ssklower void 45036389Ssklower iso_setsockaddr(isop, nam) 45136389Ssklower register struct isopcb *isop; 45236389Ssklower struct mbuf *nam; 45336389Ssklower { 45436389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 45536389Ssklower 45636389Ssklower nam->m_len = sizeof (*siso); 45736389Ssklower siso = mtod(nam, struct sockaddr_iso *); 45836389Ssklower bzero((caddr_t)siso, sizeof (*siso)); 45936389Ssklower siso->siso_family = AF_ISO; 46036389Ssklower siso->siso_tsuffix = isop->isop_lport; 46136389Ssklower siso->siso_addr = isop->isop_laddr.siso_addr; 46236389Ssklower } 46336389Ssklower 46436389Ssklower /* NEEDED? */ 46536389Ssklower void 46636389Ssklower iso_setpeeraddr(isop, nam) 46736389Ssklower register struct isopcb *isop; 46836389Ssklower struct mbuf *nam; 46936389Ssklower { 47036389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 47136389Ssklower 47236389Ssklower nam->m_len = sizeof (*siso); 47336389Ssklower siso = mtod(nam, struct sockaddr_iso *); 47436389Ssklower bzero((caddr_t)siso, sizeof (*siso)); 47536389Ssklower siso->siso_family = AF_ISO; 47636389Ssklower siso->siso_tsuffix = isop->isop_fport; 47736389Ssklower siso->siso_addr = isop->isop_faddr.siso_addr; 47836389Ssklower } 47936389Ssklower #endif notdef 48036389Ssklower 48136389Ssklower /* 48236389Ssklower * FUNCTION: iso_pcbnotify 48336389Ssklower * 48436389Ssklower * PURPOSE: notify all connections in this protocol's queue (head) 48536389Ssklower * that have peer address (dst) of the problem (errno) 48636389Ssklower * by calling (notify) on the connections' isopcbs. 48736389Ssklower * 48836389Ssklower * RETURNS: Rien. 48936389Ssklower * 49036389Ssklower * SIDE EFFECTS: 49136389Ssklower * 49236389Ssklower * NOTES: (notify) is called at splimp! 49336389Ssklower */ 49436389Ssklower void 49536389Ssklower iso_pcbnotify(head, dst, errno, notify) 49636389Ssklower struct isopcb *head; 49736389Ssklower register struct iso_addr *dst; 49836389Ssklower int errno, (*notify)(); 49936389Ssklower { 50036389Ssklower register struct isopcb *isop, *oisop; 50136389Ssklower int s = splimp(); 50236389Ssklower 50336389Ssklower IFDEBUG(D_ISO) 50436389Ssklower printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); 50536389Ssklower ENDDEBUG 50636389Ssklower for (isop = head->isop_next; isop != head;) { 507*37469Ssklower if (!iso_addrmatch1(&(isop->isop_faddr->siso_addr), dst) || 50836389Ssklower isop->isop_socket == 0) { 50936389Ssklower IFDEBUG(D_ISO) 51036389Ssklower printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , 51136389Ssklower isop, isop->isop_socket); 51236389Ssklower printf("addrmatch cmp'd with (0x%x):\n", 513*37469Ssklower &(isop->isop_faddr->siso_addr)); 514*37469Ssklower dump_isoaddr(isop->isop_faddr); 51536389Ssklower ENDDEBUG 51636389Ssklower isop = isop->isop_next; 51736389Ssklower continue; 51836389Ssklower } 51936389Ssklower if (errno) 52036389Ssklower isop->isop_socket->so_error = errno; 52136389Ssklower oisop = isop; 52236389Ssklower isop = isop->isop_next; 52336389Ssklower if (notify) 52436389Ssklower (*notify)(oisop); 52536389Ssklower } 52636389Ssklower splx(s); 52736389Ssklower IFDEBUG(D_ISO) 52836389Ssklower printf("END OF iso_pcbnotify\n" ); 52936389Ssklower ENDDEBUG 53036389Ssklower } 53136389Ssklower 53236389Ssklower 53336389Ssklower /* 53436389Ssklower * FUNCTION: iso_pcblookup 53536389Ssklower * 53636389Ssklower * PURPOSE: looks for a given combination of (faddr), (fport), 53736389Ssklower * (lport), (laddr) in the queue named by (head). 53836389Ssklower * Argument (flags) is ignored. 53936389Ssklower * 54036389Ssklower * RETURNS: ptr to the isopcb if it finds a connection matching 54136389Ssklower * these arguments, o.w. returns zero. 54236389Ssklower * 54336389Ssklower * SIDE EFFECTS: 54436389Ssklower * 54536389Ssklower * NOTES: 54636389Ssklower */ 54736389Ssklower struct isopcb * 548*37469Ssklower iso_pcblookup(head, fportlen, fport, laddr) 54936389Ssklower struct isopcb *head; 550*37469Ssklower register struct sockaddr_iso *laddr; 551*37469Ssklower caddr_t fport; 552*37469Ssklower int fportlen; 55336389Ssklower { 55436389Ssklower register struct isopcb *isop; 555*37469Ssklower register caddr_t lp = TSEL(laddr); 556*37469Ssklower unsigned int llen = laddr->siso_tsuffixlen; 55736389Ssklower 55836389Ssklower IFDEBUG(D_ISO) 559*37469Ssklower printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", 560*37469Ssklower head, laddr, fport); 56136389Ssklower ENDDEBUG 56236389Ssklower for (isop = head->isop_next; isop != head; isop = isop->isop_next) { 563*37469Ssklower if (isop->isop_laddr == 0 || isop->isop_laddr == laddr) 56436389Ssklower continue; 565*37469Ssklower if (isop->isop_laddr->siso_tsuffixlen != llen) 56636389Ssklower continue; 567*37469Ssklower if (bcmp(lp, TSEL(isop->isop_laddr), llen)) 568*37469Ssklower continue; 569*37469Ssklower if (fportlen && isop->isop_faddr && 570*37469Ssklower bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen)) 571*37469Ssklower continue; 57236389Ssklower /* PHASE2 57336389Ssklower * addrmatch1 should be iso_addrmatch(a, b, mask) 57436389Ssklower * where mask is taken from isop->isop_laddrmask (new field) 57536389Ssklower * isop_lnetmask will also be available in isop 57636389Ssklower if (laddr != &zeroiso_addr && 57736389Ssklower !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) 57836389Ssklower continue; 579*37469Ssklower */ 580*37469Ssklower if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr))) 581*37469Ssklower continue; 58236389Ssklower return (isop); 58336389Ssklower } 58436389Ssklower return (struct isopcb *)0; 58536389Ssklower } 58636389Ssklower #endif ISO 587