1*36389Ssklower /*********************************************************** 2*36389Ssklower Copyright IBM Corporation 1987 3*36389Ssklower 4*36389Ssklower All Rights Reserved 5*36389Ssklower 6*36389Ssklower Permission to use, copy, modify, and distribute this software and its 7*36389Ssklower documentation for any purpose and without fee is hereby granted, 8*36389Ssklower provided that the above copyright notice appear in all copies and that 9*36389Ssklower both that copyright notice and this permission notice appear in 10*36389Ssklower supporting documentation, and that the name of IBM not be 11*36389Ssklower used in advertising or publicity pertaining to distribution of the 12*36389Ssklower software without specific, written prior permission. 13*36389Ssklower 14*36389Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15*36389Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16*36389Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17*36389Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18*36389Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19*36389Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20*36389Ssklower SOFTWARE. 21*36389Ssklower 22*36389Ssklower ******************************************************************/ 23*36389Ssklower 24*36389Ssklower /* 25*36389Ssklower * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison 26*36389Ssklower */ 27*36389Ssklower /* 28*36389Ssklower * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $ 29*36389Ssklower * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $ 30*36389Ssklower * 31*36389Ssklower * Iso address family net-layer(s) pcb stuff. NEH 1/29/87 32*36389Ssklower */ 33*36389Ssklower #ifndef lint 34*36389Ssklower static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $"; 35*36389Ssklower #endif 36*36389Ssklower 37*36389Ssklower #ifdef ISO 38*36389Ssklower 39*36389Ssklower #include "param.h" 40*36389Ssklower #include "systm.h" 41*36389Ssklower #include "dir.h" 42*36389Ssklower #include "user.h" 43*36389Ssklower #include "mbuf.h" 44*36389Ssklower #include "../h/socket.h" 45*36389Ssklower #include "../h/socketvar.h" 46*36389Ssklower #include "../netiso/argo_debug.h" 47*36389Ssklower #include "../netiso/iso.h" 48*36389Ssklower #include "../netiso/clnp.h" 49*36389Ssklower #include "../netinet/in_systm.h" 50*36389Ssklower #include "../net/if.h" 51*36389Ssklower #include "../net/route.h" 52*36389Ssklower #include "../netiso/iso_pcb.h" 53*36389Ssklower #include "../netiso/iso_var.h" 54*36389Ssklower #include "protosw.h" 55*36389Ssklower 56*36389Ssklower #define PCBNULL (struct isopcb *)0 57*36389Ssklower struct iso_addr zeroiso_addr = { 58*36389Ssklower 0 59*36389Ssklower }; 60*36389Ssklower 61*36389Ssklower 62*36389Ssklower /* 63*36389Ssklower * FUNCTION: iso_pcballoc 64*36389Ssklower * 65*36389Ssklower * PURPOSE: creates an isopcb structure in an mbuf, 66*36389Ssklower * with socket (so), and 67*36389Ssklower * puts it in the queue with head (head) 68*36389Ssklower * 69*36389Ssklower * RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf 70*36389Ssklower */ 71*36389Ssklower int 72*36389Ssklower iso_pcballoc(so, head) 73*36389Ssklower struct socket *so; 74*36389Ssklower struct isopcb *head; 75*36389Ssklower { 76*36389Ssklower struct mbuf *m; 77*36389Ssklower register struct isopcb *isop; 78*36389Ssklower 79*36389Ssklower IFDEBUG(D_ISO) 80*36389Ssklower printf("iso_pcballoc(so 0x%x)\n", so); 81*36389Ssklower ENDDEBUG 82*36389Ssklower m = m_getclr(M_DONTWAIT, MT_PCB); 83*36389Ssklower if (m == NULL) 84*36389Ssklower return ENOBUFS; 85*36389Ssklower isop = mtod(m, struct isopcb *); 86*36389Ssklower isop->isop_head = head; 87*36389Ssklower isop->isop_socket = so; 88*36389Ssklower insque(isop, head); 89*36389Ssklower so->so_pcb = (caddr_t)isop; 90*36389Ssklower return 0; 91*36389Ssklower } 92*36389Ssklower 93*36389Ssklower /* 94*36389Ssklower * FUNCTION: iso_pcbbind 95*36389Ssklower * 96*36389Ssklower * PURPOSE: binds the address given in *(nam) to the socket 97*36389Ssklower * specified by the isopcb in *(isop) 98*36389Ssklower * If the given address is zero, it makes sure the 99*36389Ssklower * address isn't already in use and if it's got a network 100*36389Ssklower * portion, we look for an interface with that network 101*36389Ssklower * address. If the address given is zero, we allocate 102*36389Ssklower * a port and stuff it in the (nam) structure. 103*36389Ssklower * 104*36389Ssklower * RETURNS: errno E* or 0 if ok. 105*36389Ssklower * 106*36389Ssklower * SIDE EFFECTS: increments head->isop_lport if it allocates a port # 107*36389Ssklower * 108*36389Ssklower * NOTES: 109*36389Ssklower */ 110*36389Ssklower int 111*36389Ssklower iso_pcbbind(isop, nam) 112*36389Ssklower register struct isopcb *isop; 113*36389Ssklower struct mbuf *nam; 114*36389Ssklower { 115*36389Ssklower register struct isopcb *head = isop->isop_head; 116*36389Ssklower register struct sockaddr_iso *siso; 117*36389Ssklower struct ifaddr *ia; 118*36389Ssklower u_short suf = 0; 119*36389Ssklower 120*36389Ssklower IFDEBUG(D_ISO) 121*36389Ssklower printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam); 122*36389Ssklower ENDDEBUG 123*36389Ssklower if (iso_ifaddr == 0) /* any interfaces attached? */ 124*36389Ssklower return EADDRNOTAVAIL; 125*36389Ssklower if (isop->isop_lport) /* already bound */ 126*36389Ssklower return EADDRINUSE; 127*36389Ssklower if(nam == (struct mbuf *)0) 128*36389Ssklower goto noname; 129*36389Ssklower siso = mtod(nam, struct sockaddr_iso *); 130*36389Ssklower IFDEBUG(D_ISO) 131*36389Ssklower printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); 132*36389Ssklower printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr)); 133*36389Ssklower ENDDEBUG 134*36389Ssklower /* 135*36389Ssklower * We would like sort of length check but since some OSI addrs 136*36389Ssklower * do not have fixed length, we can't really do much. 137*36389Ssklower * The ONLY thing we can say is that an osi addr has to have 138*36389Ssklower * at LEAST an afi and one more byte and had better fit into 139*36389Ssklower * a struct iso_addr. 140*36389Ssklower * However, in fact the size of the whole thing is a struct 141*36389Ssklower * sockaddr_iso, so probably this is what we should check for. 142*36389Ssklower */ 143*36389Ssklower if( (nam->m_len < 2) || (nam->m_len > sizeof(struct sockaddr_iso))) { 144*36389Ssklower return ENAMETOOLONG; 145*36389Ssklower } 146*36389Ssklower suf = siso->siso_tsuffix; 147*36389Ssklower 148*36389Ssklower if (bcmp(&siso->siso_addr,&zeroiso_addr, 1)) { 149*36389Ssklower /* non-zero net addr- better match one of our interfaces */ 150*36389Ssklower IFDEBUG(D_ISO) 151*36389Ssklower printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); 152*36389Ssklower ENDDEBUG 153*36389Ssklower siso->siso_tsuffix = 0; /* yech... */ 154*36389Ssklower /* PHASE 2: this call is ok */ 155*36389Ssklower if ((ia = ifa_ifwithaddr((struct sockaddr *)siso)) 156*36389Ssklower == (struct ifaddr *)0) 157*36389Ssklower return EADDRNOTAVAIL; 158*36389Ssklower /* copy to the inpcb */ 159*36389Ssklower bcopy( (caddr_t)&((struct sockaddr_iso *)&(ia->ifa_addr))->siso_addr, 160*36389Ssklower (caddr_t)&(isop->isop_laddr.siso_addr), 161*36389Ssklower sizeof(struct sockaddr_iso) ); 162*36389Ssklower isop->isop_laddr.siso_tsuffix = suf; 163*36389Ssklower /* copy also to the nam parameter */ 164*36389Ssklower bcopy( (caddr_t)&(isop->isop_laddr.siso_addr), 165*36389Ssklower (caddr_t)&(siso->siso_addr), sizeof(struct sockaddr_iso)); 166*36389Ssklower siso->siso_tsuffix = suf; 167*36389Ssklower } 168*36389Ssklower if (suf) { 169*36389Ssklower if((suf < ISO_PORT_RESERVED) && (u.u_uid != 0)) 170*36389Ssklower return EACCES; 171*36389Ssklower if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && 172*36389Ssklower iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0) ) 173*36389Ssklower return EADDRINUSE; 174*36389Ssklower } 175*36389Ssklower /* copy the if addr to the result (siso) and to the isopcb */ 176*36389Ssklower noname: 177*36389Ssklower IFDEBUG(D_ISO) 178*36389Ssklower printf("iso_pcbbind noname\n"); 179*36389Ssklower ENDDEBUG 180*36389Ssklower if (suf == 0) 181*36389Ssklower do { 182*36389Ssklower if (head->isop_lport++ < ISO_PORT_RESERVED || 183*36389Ssklower head->isop_lport > ISO_PORT_USERRESERVED) 184*36389Ssklower head->isop_lport = ISO_PORT_RESERVED; 185*36389Ssklower suf = head->isop_lport; 186*36389Ssklower } while (iso_pcblookup(head, 0, &(isop->isop_laddr.siso_addr), suf, 0)); 187*36389Ssklower isop->isop_lport = suf; 188*36389Ssklower IFDEBUG(D_ISO) 189*36389Ssklower printf("iso_pcbbind returns 0, suf 0x%x\n", suf); 190*36389Ssklower ENDDEBUG 191*36389Ssklower return 0; 192*36389Ssklower } 193*36389Ssklower 194*36389Ssklower /* 195*36389Ssklower * FUNCTION: iso_pcbconnect 196*36389Ssklower * 197*36389Ssklower * PURPOSE: Make the isopcb (isop) look like it's connected. 198*36389Ssklower * In other words, give it the peer address given in 199*36389Ssklower * the mbuf * (nam). Make sure such a combination 200*36389Ssklower * of local, peer addresses doesn't already exist 201*36389Ssklower * for this protocol. Internet mentality prevails here, 202*36389Ssklower * wherein a src,dst pair uniquely identifies a connection. 203*36389Ssklower * Both net address and port must be specified in argument 204*36389Ssklower * (nam). 205*36389Ssklower * If we don't have a local address for this socket yet, 206*36389Ssklower * we pick one by calling iso_pcbbind(). 207*36389Ssklower * 208*36389Ssklower * RETURNS: errno E* or 0 if ok. 209*36389Ssklower * 210*36389Ssklower * SIDE EFFECTS: Looks up a route, which may cause one to be left 211*36389Ssklower * in the isopcb. 212*36389Ssklower * 213*36389Ssklower * NOTES: 214*36389Ssklower */ 215*36389Ssklower #define satosiso(sa) ((struct sockaddr_iso *)(sa)) 216*36389Ssklower 217*36389Ssklower int 218*36389Ssklower iso_pcbconnect(isop, nam) 219*36389Ssklower struct isopcb *isop; 220*36389Ssklower struct mbuf *nam; 221*36389Ssklower { 222*36389Ssklower struct ifnet *ifp = (struct ifnet *)0; 223*36389Ssklower struct sockaddr_iso ifaddr; 224*36389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 225*36389Ssklower int local_zero = 0; 226*36389Ssklower 227*36389Ssklower IFDEBUG(D_ISO) 228*36389Ssklower printf( 229*36389Ssklower "iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x nam->m_len 0x%x), addr:\n", 230*36389Ssklower isop, isop->isop_socket, nam, nam->m_len); 231*36389Ssklower dump_isoaddr(siso); 232*36389Ssklower ENDDEBUG 233*36389Ssklower if (nam->m_len > sizeof (*siso)) 234*36389Ssklower return ENAMETOOLONG; /* not great but better than EINVAL! */ 235*36389Ssklower if (siso->siso_family != AF_ISO) 236*36389Ssklower return EAFNOSUPPORT; 237*36389Ssklower #ifdef notdef 238*36389Ssklower /* removed for the sake of extended tsels - 239*36389Ssklower * user may setsockopt for extended tsel (foreign) and then 240*36389Ssklower * connect to nsap w/ tsuffix zero 241*36389Ssklower */ 242*36389Ssklower if (siso->siso_tsuffix == 0) 243*36389Ssklower return EADDRNOTAVAIL; 244*36389Ssklower local_zero = iso_addrmatch1(&(isop->isop_laddr.siso_addr), &zeroiso_addr); 245*36389Ssklower #endif notdef 246*36389Ssklower local_zero = !bcmp(&(isop->isop_laddr.siso_addr), &zeroiso_addr, 1); 247*36389Ssklower 248*36389Ssklower #ifdef PHASEONE 249*36389Ssklower if (local_zero) { 250*36389Ssklower /* 251*36389Ssklower * We need to get the local nsap address. 252*36389Ssklower * First, route to the destination. This will provide us with 253*36389Ssklower * an ifp. Second, determine which local address linked on 254*36389Ssklower * that ifp is appropriate 255*36389Ssklower */ 256*36389Ssklower struct sockaddr_iso *first_hop; /* filled by clnp_route */ 257*36389Ssklower struct ifnet *ifp; /* filled by clnp_route */ 258*36389Ssklower int err; 259*36389Ssklower struct iso_addr *localaddr; 260*36389Ssklower 261*36389Ssklower if (err = clnp_route(&siso->siso_addr, &isop->isop_route, /* flags */0, 262*36389Ssklower &first_hop, &ifp)) 263*36389Ssklower return(err); 264*36389Ssklower 265*36389Ssklower /* determine local address based upon ifp */ 266*36389Ssklower if ((localaddr = clnp_srcaddr(ifp, &first_hop->siso_addr)) == NULL) 267*36389Ssklower return(ENETUNREACH); 268*36389Ssklower 269*36389Ssklower ifaddr.siso_family = AF_ISO; 270*36389Ssklower ifaddr.siso_addr = *localaddr; 271*36389Ssklower 272*36389Ssklower if (isop->isop_lport == 0) 273*36389Ssklower (void)iso_pcbbind(isop, (struct mbuf *)0); 274*36389Ssklower isop->isop_laddr = ifaddr; 275*36389Ssklower } 276*36389Ssklower #else 277*36389Ssklower if (local_zero) { 278*36389Ssklower struct iso_ifaddr *ia; 279*36389Ssklower register struct route *ro; 280*36389Ssklower 281*36389Ssklower IFDEBUG(D_ISO) 282*36389Ssklower printf("iso_pcbconnect localzero 1\n"); 283*36389Ssklower ENDDEBUG 284*36389Ssklower ia = (struct iso_ifaddr *)0; 285*36389Ssklower /* 286*36389Ssklower * If route is known or can be allocated now, 287*36389Ssklower * our src addr is taken from the i/f, else punt. 288*36389Ssklower */ 289*36389Ssklower ro = &isop->isop_route; 290*36389Ssklower IFDEBUG(D_ISO) 291*36389Ssklower printf("iso_pcbconnect rtalloc 1.1, ro->ro_rt 0x%x\n", 292*36389Ssklower ro->ro_rt); 293*36389Ssklower ENDDEBUG 294*36389Ssklower if (ro->ro_rt && ! iso_addrmatch1( &(satosiso(&ro->ro_dst)->siso_addr), 295*36389Ssklower &siso->siso_addr)) { 296*36389Ssklower RTFREE(ro->ro_rt); 297*36389Ssklower ro->ro_rt = (struct rtentry *)0; 298*36389Ssklower } 299*36389Ssklower /* 300*36389Ssklower * TODO: it seems this code has a lot in common with clnp_route. 301*36389Ssklower * Maybe they could be combined? (RAH) 302*36389Ssklower */ 303*36389Ssklower if ((isop->isop_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 304*36389Ssklower (ro->ro_rt == (struct rtentry *)0 || 305*36389Ssklower (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0)) { 306*36389Ssklower /* No route yet, so try to acquire one */ 307*36389Ssklower ro->ro_dst.sa_family = AF_ISO; 308*36389Ssklower ((struct sockaddr_iso *) &ro->ro_dst)->siso_addr = 309*36389Ssklower siso->siso_addr; 310*36389Ssklower rtalloc(ro); 311*36389Ssklower IFDEBUG(D_ISO) 312*36389Ssklower printf("iso_pcbconnect rtalloc 1.5, ro->ro_rt 0x%x\n", 313*36389Ssklower ro->ro_rt); 314*36389Ssklower if (ro->ro_rt != NULL) { 315*36389Ssklower printf("ro->ro_rt->rt_refcnt %d\n", 316*36389Ssklower ro->ro_rt->rt_refcnt); 317*36389Ssklower printf("rt entry rt_gateway (as sockaddr):\n"); 318*36389Ssklower dump_buf(&ro->ro_rt->rt_gateway, 319*36389Ssklower sizeof (struct sockaddr)); 320*36389Ssklower } 321*36389Ssklower ENDDEBUG 322*36389Ssklower /* 323*36389Ssklower * If we found a route, use the address 324*36389Ssklower * corresponding to the outgoing interface 325*36389Ssklower * unless it is the loopback (in case a route 326*36389Ssklower * to our address on another net goes to loopback). 327*36389Ssklower * 328*36389Ssklower * We must check to use the address that is of the 329*36389Ssklower * same type (in the case where the interface has more 330*36389Ssklower * than one type associated with it). (ie ecn0 has 331*36389Ssklower * both t37 and osinet addresses. 332*36389Ssklower */ 333*36389Ssklower if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp) && 334*36389Ssklower (ifp->if_flags & IFF_LOOPBACK) == 0) 335*36389Ssklower for (ia = iso_ifaddr; ia; ia = ia->ia_next) { 336*36389Ssklower struct iso_addr *isoap = &IA_SIS(ia)->siso_addr; 337*36389Ssklower 338*36389Ssklower IFDEBUG(D_ISO) 339*36389Ssklower printf("iso_pcbconnect: ia x%x yields: %s\n", 340*36389Ssklower ia, clnp_iso_addrp(isoap)); 341*36389Ssklower ENDDEBUG 342*36389Ssklower 343*36389Ssklower if ((ia->ia_ifp == ifp) && 344*36389Ssklower (iso_eqtype(&siso->siso_addr, isoap))) 345*36389Ssklower break; 346*36389Ssklower } 347*36389Ssklower } 348*36389Ssklower IFDEBUG(D_ISO) 349*36389Ssklower printf("iso_pcbconnect localzero 2: ia x%x\n", ia); 350*36389Ssklower ENDDEBUG 351*36389Ssklower if (ia == 0) { 352*36389Ssklower ia = (struct iso_ifaddr *) 353*36389Ssklower ifa_ifwithdstaddr((struct sockaddr *)siso); 354*36389Ssklower if (ia == 0) 355*36389Ssklower ia = iso_iaonnetof(siso); 356*36389Ssklower if (ia == 0) 357*36389Ssklower return EADDRNOTAVAIL; 358*36389Ssklower } 359*36389Ssklower ifaddr = *(struct sockaddr_iso *)&ia->ia_addr; 360*36389Ssklower } 361*36389Ssklower IFDEBUG(D_ISO) 362*36389Ssklower printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", 363*36389Ssklower isop, isop->isop_socket); 364*36389Ssklower ENDDEBUG 365*36389Ssklower if (local_zero) { 366*36389Ssklower if (isop->isop_lport == 0) 367*36389Ssklower (void)iso_pcbbind(isop, (struct mbuf *)0); 368*36389Ssklower isop->isop_laddr.siso_addr = ifaddr.siso_addr; 369*36389Ssklower isop->isop_laddr.siso_family = AF_ISO; 370*36389Ssklower } 371*36389Ssklower #endif PHASEONE 372*36389Ssklower IFDEBUG(D_ISO) 373*36389Ssklower printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", 374*36389Ssklower isop, isop->isop_socket); 375*36389Ssklower ENDDEBUG 376*36389Ssklower bcopy((caddr_t) &(siso->siso_addr), (caddr_t) &(isop->isop_faddr.siso_addr), 377*36389Ssklower sizeof(struct iso_addr)); 378*36389Ssklower IFDEBUG(D_ISO) 379*36389Ssklower printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", 380*36389Ssklower isop, isop->isop_socket); 381*36389Ssklower ENDDEBUG 382*36389Ssklower isop->isop_faddr.siso_family = AF_ISO; 383*36389Ssklower isop->isop_fport = siso->siso_tsuffix; 384*36389Ssklower IFDEBUG(D_ISO) 385*36389Ssklower printf("in iso_pcbconnect end isop 0x%x isop->sock 0x%x\n", 386*36389Ssklower isop, isop->isop_socket); 387*36389Ssklower printf("iso_pcbconnect connected to addr:\n"); 388*36389Ssklower dump_isoaddr(&isop->isop_faddr); 389*36389Ssklower printf("iso_pcbconnect end: src addr:\n"); 390*36389Ssklower dump_isoaddr(&isop->isop_laddr); 391*36389Ssklower ENDDEBUG 392*36389Ssklower return 0; 393*36389Ssklower } 394*36389Ssklower 395*36389Ssklower /* 396*36389Ssklower * FUNCTION: iso_pcbdisconnect() 397*36389Ssklower * 398*36389Ssklower * PURPOSE: washes away the peer address info so the socket 399*36389Ssklower * appears to be disconnected. 400*36389Ssklower * If there's no file descriptor associated with the socket 401*36389Ssklower * it detaches the pcb. 402*36389Ssklower * 403*36389Ssklower * RETURNS: Nada. 404*36389Ssklower * 405*36389Ssklower * SIDE EFFECTS: May detach the pcb. 406*36389Ssklower * 407*36389Ssklower * NOTES: 408*36389Ssklower */ 409*36389Ssklower void 410*36389Ssklower iso_pcbdisconnect(isop) 411*36389Ssklower struct isopcb *isop; 412*36389Ssklower { 413*36389Ssklower void iso_pcbdetach(); 414*36389Ssklower 415*36389Ssklower IFDEBUG(D_ISO) 416*36389Ssklower printf("iso_pcbdisconnect(isop 0x%x)\n", isop); 417*36389Ssklower ENDDEBUG 418*36389Ssklower isop->isop_laddr.siso_addr = zeroiso_addr; 419*36389Ssklower isop->isop_fport = 0; 420*36389Ssklower if (isop->isop_socket->so_state & SS_NOFDREF) 421*36389Ssklower iso_pcbdetach(isop); 422*36389Ssklower } 423*36389Ssklower 424*36389Ssklower /* 425*36389Ssklower * FUNCTION: iso_pcbdetach 426*36389Ssklower * 427*36389Ssklower * PURPOSE: detach the pcb at *(isop) from it's socket and free 428*36389Ssklower * the mbufs associated with the pcb.. 429*36389Ssklower * Dequeues (isop) from its head. 430*36389Ssklower * 431*36389Ssklower * RETURNS: Nada. 432*36389Ssklower * 433*36389Ssklower * SIDE EFFECTS: 434*36389Ssklower * 435*36389Ssklower * NOTES: 436*36389Ssklower */ 437*36389Ssklower void 438*36389Ssklower iso_pcbdetach(isop) 439*36389Ssklower struct isopcb *isop; 440*36389Ssklower { 441*36389Ssklower struct socket *so = isop->isop_socket; 442*36389Ssklower 443*36389Ssklower IFDEBUG(D_ISO) 444*36389Ssklower printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 445*36389Ssklower isop, isop->isop_socket, so); 446*36389Ssklower ENDDEBUG 447*36389Ssklower if (so ) { /* in the x.25 domain, we sometimes have no socket */ 448*36389Ssklower so->so_pcb = 0; 449*36389Ssklower sofree(so); 450*36389Ssklower } 451*36389Ssklower IFDEBUG(D_ISO) 452*36389Ssklower printf("iso_pcbdetach 2 \n"); 453*36389Ssklower ENDDEBUG 454*36389Ssklower if (isop->isop_options) 455*36389Ssklower (void)m_free(isop->isop_options); 456*36389Ssklower IFDEBUG(D_ISO) 457*36389Ssklower printf("iso_pcbdetach 3 \n"); 458*36389Ssklower ENDDEBUG 459*36389Ssklower if (isop->isop_route.ro_rt) 460*36389Ssklower rtfree(isop->isop_route.ro_rt); 461*36389Ssklower IFDEBUG(D_ISO) 462*36389Ssklower printf("iso_pcbdetach 3.1\n"); 463*36389Ssklower ENDDEBUG 464*36389Ssklower if (isop->isop_clnpcache != NULL) { 465*36389Ssklower struct clnp_cache *clcp = 466*36389Ssklower mtod(isop->isop_clnpcache, struct clnp_cache *); 467*36389Ssklower IFDEBUG(D_ISO) 468*36389Ssklower printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", 469*36389Ssklower clcp, clcp->clc_hdr); 470*36389Ssklower ENDDEBUG 471*36389Ssklower if (clcp->clc_hdr != NULL) 472*36389Ssklower m_free(clcp->clc_hdr); 473*36389Ssklower IFDEBUG(D_ISO) 474*36389Ssklower printf("iso_pcbdetach 3.3: freeing cache x%x\n", 475*36389Ssklower isop->isop_clnpcache); 476*36389Ssklower ENDDEBUG 477*36389Ssklower m_free(isop->isop_clnpcache); 478*36389Ssklower } 479*36389Ssklower IFDEBUG(D_ISO) 480*36389Ssklower printf("iso_pcbdetach 4 \n"); 481*36389Ssklower ENDDEBUG 482*36389Ssklower remque(isop); 483*36389Ssklower IFDEBUG(D_ISO) 484*36389Ssklower printf("iso_pcbdetach 5 \n"); 485*36389Ssklower ENDDEBUG 486*36389Ssklower (void) m_free(dtom(isop)); 487*36389Ssklower } 488*36389Ssklower 489*36389Ssklower #ifdef notdef 490*36389Ssklower /* NEEDED? */ 491*36389Ssklower void 492*36389Ssklower iso_setsockaddr(isop, nam) 493*36389Ssklower register struct isopcb *isop; 494*36389Ssklower struct mbuf *nam; 495*36389Ssklower { 496*36389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 497*36389Ssklower 498*36389Ssklower nam->m_len = sizeof (*siso); 499*36389Ssklower siso = mtod(nam, struct sockaddr_iso *); 500*36389Ssklower bzero((caddr_t)siso, sizeof (*siso)); 501*36389Ssklower siso->siso_family = AF_ISO; 502*36389Ssklower siso->siso_tsuffix = isop->isop_lport; 503*36389Ssklower siso->siso_addr = isop->isop_laddr.siso_addr; 504*36389Ssklower } 505*36389Ssklower 506*36389Ssklower /* NEEDED? */ 507*36389Ssklower void 508*36389Ssklower iso_setpeeraddr(isop, nam) 509*36389Ssklower register struct isopcb *isop; 510*36389Ssklower struct mbuf *nam; 511*36389Ssklower { 512*36389Ssklower register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); 513*36389Ssklower 514*36389Ssklower nam->m_len = sizeof (*siso); 515*36389Ssklower siso = mtod(nam, struct sockaddr_iso *); 516*36389Ssklower bzero((caddr_t)siso, sizeof (*siso)); 517*36389Ssklower siso->siso_family = AF_ISO; 518*36389Ssklower siso->siso_tsuffix = isop->isop_fport; 519*36389Ssklower siso->siso_addr = isop->isop_faddr.siso_addr; 520*36389Ssklower } 521*36389Ssklower #endif notdef 522*36389Ssklower 523*36389Ssklower /* 524*36389Ssklower * FUNCTION: iso_pcbnotify 525*36389Ssklower * 526*36389Ssklower * PURPOSE: notify all connections in this protocol's queue (head) 527*36389Ssklower * that have peer address (dst) of the problem (errno) 528*36389Ssklower * by calling (notify) on the connections' isopcbs. 529*36389Ssklower * 530*36389Ssklower * RETURNS: Rien. 531*36389Ssklower * 532*36389Ssklower * SIDE EFFECTS: 533*36389Ssklower * 534*36389Ssklower * NOTES: (notify) is called at splimp! 535*36389Ssklower */ 536*36389Ssklower void 537*36389Ssklower iso_pcbnotify(head, dst, errno, notify) 538*36389Ssklower struct isopcb *head; 539*36389Ssklower register struct iso_addr *dst; 540*36389Ssklower int errno, (*notify)(); 541*36389Ssklower { 542*36389Ssklower register struct isopcb *isop, *oisop; 543*36389Ssklower int s = splimp(); 544*36389Ssklower 545*36389Ssklower IFDEBUG(D_ISO) 546*36389Ssklower printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); 547*36389Ssklower ENDDEBUG 548*36389Ssklower for (isop = head->isop_next; isop != head;) { 549*36389Ssklower if (!iso_addrmatch1(&(isop->isop_faddr.siso_addr), dst) || 550*36389Ssklower isop->isop_socket == 0) { 551*36389Ssklower IFDEBUG(D_ISO) 552*36389Ssklower printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , 553*36389Ssklower isop, isop->isop_socket); 554*36389Ssklower printf("addrmatch cmp'd with (0x%x):\n", 555*36389Ssklower &(isop->isop_faddr.siso_addr)); 556*36389Ssklower dump_isoaddr(&isop->isop_faddr); 557*36389Ssklower ENDDEBUG 558*36389Ssklower isop = isop->isop_next; 559*36389Ssklower continue; 560*36389Ssklower } 561*36389Ssklower if (errno) 562*36389Ssklower isop->isop_socket->so_error = errno; 563*36389Ssklower oisop = isop; 564*36389Ssklower isop = isop->isop_next; 565*36389Ssklower if (notify) 566*36389Ssklower (*notify)(oisop); 567*36389Ssklower } 568*36389Ssklower splx(s); 569*36389Ssklower IFDEBUG(D_ISO) 570*36389Ssklower printf("END OF iso_pcbnotify\n" ); 571*36389Ssklower ENDDEBUG 572*36389Ssklower } 573*36389Ssklower 574*36389Ssklower 575*36389Ssklower /* 576*36389Ssklower * FUNCTION: iso_pcblookup 577*36389Ssklower * 578*36389Ssklower * PURPOSE: looks for a given combination of (faddr), (fport), 579*36389Ssklower * (lport), (laddr) in the queue named by (head). 580*36389Ssklower * Argument (flags) is ignored. 581*36389Ssklower * 582*36389Ssklower * RETURNS: ptr to the isopcb if it finds a connection matching 583*36389Ssklower * these arguments, o.w. returns zero. 584*36389Ssklower * 585*36389Ssklower * SIDE EFFECTS: 586*36389Ssklower * 587*36389Ssklower * NOTES: 588*36389Ssklower */ 589*36389Ssklower struct isopcb * 590*36389Ssklower iso_pcblookup(head, fport, laddr, lport, flags) 591*36389Ssklower struct isopcb *head; 592*36389Ssklower struct iso_addr *laddr; 593*36389Ssklower u_short fport, lport; 594*36389Ssklower int flags; 595*36389Ssklower { 596*36389Ssklower register struct isopcb *isop; 597*36389Ssklower 598*36389Ssklower IFDEBUG(D_ISO) 599*36389Ssklower printf("iso_pcblookup(head 0x%x lport 0x%x fport 0x%x)\n", 600*36389Ssklower head, lport, fport); 601*36389Ssklower ENDDEBUG 602*36389Ssklower for (isop = head->isop_next; isop != head; isop = isop->isop_next) { 603*36389Ssklower #ifdef notdef 604*36389Ssklower /* 605*36389Ssklower * This should be changed to do bcmp on lsuffix in the tpcb instead 606*36389Ssklower * since we should be ignoring the lport concept. 607*36389Ssklower */ 608*36389Ssklower #endif notdef 609*36389Ssklower if (isop->isop_lport != lport) 610*36389Ssklower continue; 611*36389Ssklower if (isop->isop_fport != fport) 612*36389Ssklower continue; 613*36389Ssklower /* PHASE2 614*36389Ssklower * addrmatch1 should be iso_addrmatch(a, b, mask) 615*36389Ssklower * where mask is taken from isop->isop_laddrmask (new field) 616*36389Ssklower * isop_lnetmask will also be available in isop 617*36389Ssklower */ 618*36389Ssklower if (laddr != &zeroiso_addr && 619*36389Ssklower !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) 620*36389Ssklower continue; 621*36389Ssklower return (isop); 622*36389Ssklower } 623*36389Ssklower return (struct isopcb *)0; 624*36389Ssklower } 625*36389Ssklower #endif ISO 626