|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1991 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms, with or without ! 6: * modification, are permitted provided that the following conditions ! 7: * are met: ! 8: * 1. Redistributions of source code must retain the above copyright ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * 3. All advertising materials mentioning features or use of this software ! 14: * must display the following acknowledgement: ! 15: * This product includes software developed by the University of ! 16: * California, Berkeley and its contributors. ! 17: * 4. Neither the name of the University nor the names of its contributors ! 18: * may be used to endorse or promote products derived from this software ! 19: * without specific prior written permission. ! 20: * ! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 31: * SUCH DAMAGE. ! 32: * ! 33: * @(#)iso_pcb.c 7.10 (Berkeley) 6/27/91 ! 34: */ ! 35: ! 36: /*********************************************************** ! 37: Copyright IBM Corporation 1987 ! 38: ! 39: All Rights Reserved ! 40: ! 41: Permission to use, copy, modify, and distribute this software and its ! 42: documentation for any purpose and without fee is hereby granted, ! 43: provided that the above copyright notice appear in all copies and that ! 44: both that copyright notice and this permission notice appear in ! 45: supporting documentation, and that the name of IBM not be ! 46: used in advertising or publicity pertaining to distribution of the ! 47: software without specific, written prior permission. ! 48: ! 49: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 50: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 51: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 52: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 53: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 54: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 55: SOFTWARE. ! 56: ! 57: ******************************************************************/ ! 58: ! 59: /* ! 60: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison ! 61: */ ! 62: /* ! 63: * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $ ! 64: * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $ ! 65: * ! 66: * Iso address family net-layer(s) pcb stuff. NEH 1/29/87 ! 67: */ ! 68: ! 69: #ifdef ISO ! 70: ! 71: #include "param.h" ! 72: #include "systm.h" ! 73: #include "mbuf.h" ! 74: #include "socket.h" ! 75: #include "socketvar.h" ! 76: #include "errno.h" ! 77: ! 78: #include "argo_debug.h" ! 79: #include "iso.h" ! 80: #include "clnp.h" ! 81: #include "../netinet/in_systm.h" ! 82: #include "../net/if.h" ! 83: #include "../net/route.h" ! 84: #include "iso_pcb.h" ! 85: #include "iso_var.h" ! 86: #include "protosw.h" ! 87: ! 88: #ifdef TPCONS ! 89: #include "../netccitt/x25.h" ! 90: #include "../netccitt/pk.h" ! 91: #include "../netccitt/pk_var.h" ! 92: #endif ! 93: ! 94: #define PCBNULL (struct isopcb *)0 ! 95: struct iso_addr zeroiso_addr = { ! 96: 0 ! 97: }; ! 98: ! 99: ! 100: /* ! 101: * FUNCTION: iso_pcballoc ! 102: * ! 103: * PURPOSE: creates an isopcb structure in an mbuf, ! 104: * with socket (so), and ! 105: * puts it in the queue with head (head) ! 106: * ! 107: * RETURNS: 0 if OK, ENOBUFS if can't alloc the necessary mbuf ! 108: */ ! 109: int ! 110: iso_pcballoc(so, head) ! 111: struct socket *so; ! 112: struct isopcb *head; ! 113: { ! 114: register struct isopcb *isop; ! 115: ! 116: IFDEBUG(D_ISO) ! 117: printf("iso_pcballoc(so 0x%x)\n", so); ! 118: ENDDEBUG ! 119: MALLOC(isop, struct isopcb *, sizeof(*isop), M_PCB, M_NOWAIT); ! 120: if (isop == NULL) ! 121: return ENOBUFS; ! 122: bzero((caddr_t)isop, sizeof(*isop)); ! 123: isop->isop_head = head; ! 124: isop->isop_socket = so; ! 125: insque(isop, head); ! 126: if (so) ! 127: so->so_pcb = (caddr_t)isop; ! 128: return 0; ! 129: } ! 130: ! 131: /* ! 132: * FUNCTION: iso_pcbbind ! 133: * ! 134: * PURPOSE: binds the address given in *(nam) to the socket ! 135: * specified by the isopcb in *(isop) ! 136: * If the given address is zero, it makes sure the ! 137: * address isn't already in use and if it's got a network ! 138: * portion, we look for an interface with that network ! 139: * address. If the address given is zero, we allocate ! 140: * a port and stuff it in the (nam) structure. ! 141: * ! 142: * RETURNS: errno E* or 0 if ok. ! 143: * ! 144: * SIDE EFFECTS: increments head->isop_lport if it allocates a port # ! 145: * ! 146: * NOTES: ! 147: */ ! 148: #define satosiso(sa) ((struct sockaddr_iso *)(sa)) ! 149: int ! 150: iso_pcbbind(isop, nam) ! 151: register struct isopcb *isop; ! 152: struct mbuf *nam; ! 153: { ! 154: register struct isopcb *head = isop->isop_head; ! 155: register struct sockaddr_iso *siso; ! 156: struct iso_ifaddr *ia; ! 157: union { ! 158: char data[2]; ! 159: u_short s; ! 160: } suf; ! 161: ! 162: IFDEBUG(D_ISO) ! 163: printf("iso_pcbbind(isop 0x%x, nam 0x%x)\n", isop, nam); ! 164: ENDDEBUG ! 165: suf.s = 0; ! 166: if (iso_ifaddr == 0) /* any interfaces attached? */ ! 167: return EADDRNOTAVAIL; ! 168: if (isop->isop_laddr) /* already bound */ ! 169: return EADDRINUSE; ! 170: if(nam == (struct mbuf *)0) { ! 171: isop->isop_laddr = &isop->isop_sladdr; ! 172: isop->isop_sladdr.siso_len = sizeof(struct sockaddr_iso); ! 173: isop->isop_sladdr.siso_family = AF_ISO; ! 174: isop->isop_sladdr.siso_tlen = 2; ! 175: isop->isop_sladdr.siso_nlen = 0; ! 176: isop->isop_sladdr.siso_slen = 0; ! 177: isop->isop_sladdr.siso_plen = 0; ! 178: goto noname; ! 179: } ! 180: siso = mtod(nam, struct sockaddr_iso *); ! 181: IFDEBUG(D_ISO) ! 182: printf("iso_pcbbind(name len 0x%x)\n", nam->m_len); ! 183: printf("The address is %s\n", clnp_iso_addrp(&siso->siso_addr)); ! 184: ENDDEBUG ! 185: /* ! 186: * We would like sort of length check but since some OSI addrs ! 187: * do not have fixed length, we can't really do much. ! 188: * The ONLY thing we can say is that an osi addr has to have ! 189: * at LEAST an afi and one more byte and had better fit into ! 190: * a struct iso_addr. ! 191: * However, in fact the size of the whole thing is a struct ! 192: * sockaddr_iso, so probably this is what we should check for. ! 193: */ ! 194: if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) { ! 195: return ENAMETOOLONG; ! 196: } ! 197: if (siso->siso_tlen) { ! 198: register char *cp = TSEL(siso); ! 199: suf.data[0] = cp[0]; ! 200: suf.data[1] = cp[1]; ! 201: } ! 202: if (siso->siso_nlen) { ! 203: /* non-zero net addr- better match one of our interfaces */ ! 204: IFDEBUG(D_ISO) ! 205: printf("iso_pcbbind: bind to NOT zeroisoaddr\n"); ! 206: ENDDEBUG ! 207: for (ia = iso_ifaddr; ia; ia = ia->ia_next) ! 208: if (SAME_ISOADDR(siso, &ia->ia_addr)) ! 209: break; ! 210: if (ia == 0) ! 211: return EADDRNOTAVAIL; ! 212: } ! 213: if (siso->siso_len <= sizeof (isop->isop_sladdr)) { ! 214: isop->isop_laddr = &isop->isop_sladdr; ! 215: } else { ! 216: if ((nam = m_copy(nam, 0, (int)M_COPYALL)) == 0) ! 217: return ENOBUFS; ! 218: isop->isop_laddr = mtod(nam, struct sockaddr_iso *); ! 219: } ! 220: bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len); ! 221: if (suf.s || siso->siso_tlen != 2) { ! 222: if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tlen <= 2) && ! 223: (isop->isop_socket->so_state && SS_PRIV) == 0) ! 224: return EACCES; ! 225: if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 && ! 226: iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)) ! 227: return EADDRINUSE; ! 228: } else { ! 229: register char *cp; ! 230: noname: ! 231: cp = TSEL(isop->isop_laddr); ! 232: IFDEBUG(D_ISO) ! 233: printf("iso_pcbbind noname\n"); ! 234: ENDDEBUG ! 235: do { ! 236: if (head->isop_lport++ < ISO_PORT_RESERVED || ! 237: head->isop_lport > ISO_PORT_USERRESERVED) ! 238: head->isop_lport = ISO_PORT_RESERVED; ! 239: suf.s = head->isop_lport; ! 240: cp[0] = suf.data[0]; ! 241: cp[1] = suf.data[1]; ! 242: } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr)); ! 243: } ! 244: IFDEBUG(D_ISO) ! 245: printf("iso_pcbbind returns 0, suf 0x%x\n", suf); ! 246: ENDDEBUG ! 247: return 0; ! 248: } ! 249: /* ! 250: * FUNCTION: iso_pcbconnect ! 251: * ! 252: * PURPOSE: Make the isopcb (isop) look like it's connected. ! 253: * In other words, give it the peer address given in ! 254: * the mbuf * (nam). Make sure such a combination ! 255: * of local, peer addresses doesn't already exist ! 256: * for this protocol. Internet mentality prevails here, ! 257: * wherein a src,dst pair uniquely identifies a connection. ! 258: * Both net address and port must be specified in argument ! 259: * (nam). ! 260: * If we don't have a local address for this socket yet, ! 261: * we pick one by calling iso_pcbbind(). ! 262: * ! 263: * RETURNS: errno E* or 0 if ok. ! 264: * ! 265: * SIDE EFFECTS: Looks up a route, which may cause one to be left ! 266: * in the isopcb. ! 267: * ! 268: * NOTES: ! 269: */ ! 270: int ! 271: iso_pcbconnect(isop, nam) ! 272: register struct isopcb *isop; ! 273: struct mbuf *nam; ! 274: { ! 275: register struct sockaddr_iso *siso = mtod(nam, struct sockaddr_iso *); ! 276: int local_zero, error = 0; ! 277: struct iso_ifaddr *ia; ! 278: ! 279: IFDEBUG(D_ISO) ! 280: printf("iso_pcbconnect(isop 0x%x sock 0x%x nam 0x%x", ! 281: isop, isop->isop_socket, nam); ! 282: printf("nam->m_len 0x%x), addr:\n", nam->m_len); ! 283: dump_isoaddr(siso); ! 284: ENDDEBUG ! 285: if (nam->m_len < siso->siso_len) ! 286: return EINVAL; ! 287: if (siso->siso_family != AF_ISO) ! 288: return EAFNOSUPPORT; ! 289: if (siso->siso_nlen == 0) { ! 290: if (ia = iso_ifaddr) { ! 291: int nlen = ia->ia_addr.siso_nlen; ! 292: ovbcopy(TSEL(siso), nlen + TSEL(siso), ! 293: siso->siso_plen + siso->siso_tlen + siso->siso_slen); ! 294: bcopy((caddr_t)&ia->ia_addr.siso_addr, ! 295: (caddr_t)&siso->siso_addr, nlen + 1); ! 296: /* includes siso->siso_nlen = nlen; */ ! 297: } else ! 298: return EADDRNOTAVAIL; ! 299: } ! 300: /* ! 301: * Local zero means either not bound, or bound to a TSEL, but no ! 302: * particular local interface. So, if we want to send somebody ! 303: * we need to choose a return address. ! 304: */ ! 305: local_zero = ! 306: ((isop->isop_laddr == 0) || (isop->isop_laddr->siso_nlen == 0)); ! 307: if (local_zero) { ! 308: int flags; ! 309: ! 310: IFDEBUG(D_ISO) ! 311: printf("iso_pcbconnect localzero 1\n"); ! 312: ENDDEBUG ! 313: /* ! 314: * If route is known or can be allocated now, ! 315: * our src addr is taken from the i/f, else punt. ! 316: */ ! 317: flags = isop->isop_socket->so_options & SO_DONTROUTE; ! 318: if (error = clnp_route(&siso->siso_addr, &isop->isop_route, flags, ! 319: (struct sockaddr **)0, &ia)) ! 320: return error; ! 321: IFDEBUG(D_ISO) ! 322: printf("iso_pcbconnect localzero 2, ro->ro_rt 0x%x", ! 323: isop->isop_route.ro_rt); ! 324: printf(" ia 0x%x\n", ia); ! 325: ENDDEBUG ! 326: } ! 327: IFDEBUG(D_ISO) ! 328: printf("in iso_pcbconnect before lookup isop 0x%x isop->sock 0x%x\n", ! 329: isop, isop->isop_socket); ! 330: ENDDEBUG ! 331: if (local_zero) { ! 332: int nlen, tlen, totlen; caddr_t oldtsel, newtsel; ! 333: siso = isop->isop_laddr; ! 334: if (siso == 0 || siso->siso_tlen == 0) ! 335: (void)iso_pcbbind(isop, (struct mbuf *)0); ! 336: /* ! 337: * Here we have problem of squezeing in a definite network address ! 338: * into an existing sockaddr_iso, which in fact may not have room ! 339: * for it. This gets messy. ! 340: */ ! 341: siso = isop->isop_laddr; ! 342: oldtsel = TSEL(siso); ! 343: tlen = siso->siso_tlen; ! 344: nlen = ia->ia_addr.siso_nlen; ! 345: totlen = tlen + nlen + _offsetof(struct sockaddr_iso, siso_data[0]); ! 346: if ((siso == &isop->isop_sladdr) && ! 347: (totlen > sizeof(isop->isop_sladdr))) { ! 348: struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); ! 349: if (m == 0) ! 350: return ENOBUFS; ! 351: m->m_len = totlen; ! 352: isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *); ! 353: } ! 354: siso->siso_nlen = ia->ia_addr.siso_nlen; ! 355: newtsel = TSEL(siso); ! 356: ovbcopy(oldtsel, newtsel, tlen); ! 357: bcopy(ia->ia_addr.siso_data, siso->siso_data, nlen); ! 358: siso->siso_tlen = tlen; ! 359: siso->siso_family = AF_ISO; ! 360: siso->siso_len = totlen; ! 361: siso = mtod(nam, struct sockaddr_iso *); ! 362: } ! 363: IFDEBUG(D_ISO) ! 364: printf("in iso_pcbconnect before bcopy isop 0x%x isop->sock 0x%x\n", ! 365: isop, isop->isop_socket); ! 366: ENDDEBUG ! 367: /* ! 368: * If we had to allocate space to a previous big foreign address, ! 369: * and for some reason we didn't free it, we reuse it knowing ! 370: * that is going to be big enough, as sockaddrs are delivered in ! 371: * 128 byte mbufs. ! 372: * If the foreign address is small enough, we use default space; ! 373: * otherwise, we grab an mbuf to copy into. ! 374: */ ! 375: if (isop->isop_faddr == 0 || isop->isop_faddr == &isop->isop_sfaddr) { ! 376: if (siso->siso_len <= sizeof(isop->isop_sfaddr)) ! 377: isop->isop_faddr = &isop->isop_sfaddr; ! 378: else { ! 379: struct mbuf *m = m_get(MT_SONAME, M_DONTWAIT); ! 380: if (m == 0) ! 381: return ENOBUFS; ! 382: isop->isop_faddr = mtod(m, struct sockaddr_iso *); ! 383: } ! 384: } ! 385: bcopy((caddr_t)siso, (caddr_t)isop->isop_faddr, siso->siso_len); ! 386: IFDEBUG(D_ISO) ! 387: printf("in iso_pcbconnect after bcopy isop 0x%x isop->sock 0x%x\n", ! 388: isop, isop->isop_socket); ! 389: printf("iso_pcbconnect connected to addr:\n"); ! 390: dump_isoaddr(isop->isop_faddr); ! 391: printf("iso_pcbconnect end: src addr:\n"); ! 392: dump_isoaddr(isop->isop_laddr); ! 393: ENDDEBUG ! 394: return 0; ! 395: } ! 396: ! 397: /* ! 398: * FUNCTION: iso_pcbdisconnect() ! 399: * ! 400: * PURPOSE: washes away the peer address info so the socket ! 401: * appears to be disconnected. ! 402: * If there's no file descriptor associated with the socket ! 403: * it detaches the pcb. ! 404: * ! 405: * RETURNS: Nada. ! 406: * ! 407: * SIDE EFFECTS: May detach the pcb. ! 408: * ! 409: * NOTES: ! 410: */ ! 411: void ! 412: iso_pcbdisconnect(isop) ! 413: struct isopcb *isop; ! 414: { ! 415: void iso_pcbdetach(); ! 416: register struct sockaddr_iso *siso; ! 417: ! 418: IFDEBUG(D_ISO) ! 419: printf("iso_pcbdisconnect(isop 0x%x)\n", isop); ! 420: ENDDEBUG ! 421: /* ! 422: * Preserver binding infnormation if already bound. ! 423: */ ! 424: if ((siso = isop->isop_laddr) && siso->siso_nlen && siso->siso_tlen) { ! 425: caddr_t otsel = TSEL(siso); ! 426: siso->siso_nlen = 0; ! 427: ovbcopy(otsel, TSEL(siso), siso->siso_tlen); ! 428: } ! 429: if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr) ! 430: m_freem(dtom(isop->isop_faddr)); ! 431: isop->isop_faddr = 0; ! 432: if (isop->isop_socket->so_state & SS_NOFDREF) ! 433: iso_pcbdetach(isop); ! 434: } ! 435: ! 436: /* ! 437: * FUNCTION: iso_pcbdetach ! 438: * ! 439: * PURPOSE: detach the pcb at *(isop) from it's socket and free ! 440: * the mbufs associated with the pcb.. ! 441: * Dequeues (isop) from its head. ! 442: * ! 443: * RETURNS: Nada. ! 444: * ! 445: * SIDE EFFECTS: ! 446: * ! 447: * NOTES: ! 448: */ ! 449: void ! 450: iso_pcbdetach(isop) ! 451: struct isopcb *isop; ! 452: { ! 453: struct socket *so = isop->isop_socket; ! 454: ! 455: IFDEBUG(D_ISO) ! 456: printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", ! 457: isop, isop->isop_socket, so); ! 458: ENDDEBUG ! 459: #ifdef TPCONS ! 460: if (isop->isop_refcnt) { ! 461: register struct pklcd *lcp = (struct pklcd *)isop->isop_chan; ! 462: if (--isop->isop_refcnt > 0) ! 463: return; ! 464: if (lcp && lcp->lcd_state == DATA_TRANSFER) ! 465: pk_disconnect(lcp); ! 466: isop->isop_chan = 0; ! 467: } ! 468: #endif ! 469: if (so) { /* in the x.25 domain, we sometimes have no socket */ ! 470: so->so_pcb = 0; ! 471: sofree(so); ! 472: } ! 473: IFDEBUG(D_ISO) ! 474: printf("iso_pcbdetach 2 \n"); ! 475: ENDDEBUG ! 476: if (isop->isop_options) ! 477: (void)m_free(isop->isop_options); ! 478: IFDEBUG(D_ISO) ! 479: printf("iso_pcbdetach 3 \n"); ! 480: ENDDEBUG ! 481: if (isop->isop_route.ro_rt) ! 482: rtfree(isop->isop_route.ro_rt); ! 483: IFDEBUG(D_ISO) ! 484: printf("iso_pcbdetach 3.1\n"); ! 485: ENDDEBUG ! 486: if (isop->isop_clnpcache != NULL) { ! 487: struct clnp_cache *clcp = ! 488: mtod(isop->isop_clnpcache, struct clnp_cache *); ! 489: IFDEBUG(D_ISO) ! 490: printf("iso_pcbdetach 3.2: clcp 0x%x freeing clc_hdr x%x\n", ! 491: clcp, clcp->clc_hdr); ! 492: ENDDEBUG ! 493: if (clcp->clc_hdr != NULL) ! 494: m_free(clcp->clc_hdr); ! 495: IFDEBUG(D_ISO) ! 496: printf("iso_pcbdetach 3.3: freeing cache x%x\n", ! 497: isop->isop_clnpcache); ! 498: ENDDEBUG ! 499: m_free(isop->isop_clnpcache); ! 500: } ! 501: IFDEBUG(D_ISO) ! 502: printf("iso_pcbdetach 4 \n"); ! 503: ENDDEBUG ! 504: remque(isop); ! 505: IFDEBUG(D_ISO) ! 506: printf("iso_pcbdetach 5 \n"); ! 507: ENDDEBUG ! 508: if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr)) ! 509: m_freem(dtom(isop->isop_laddr)); ! 510: free((caddr_t)isop, M_PCB); ! 511: } ! 512: ! 513: ! 514: /* ! 515: * FUNCTION: iso_pcbnotify ! 516: * ! 517: * PURPOSE: notify all connections in this protocol's queue (head) ! 518: * that have peer address (dst) of the problem (errno) ! 519: * by calling (notify) on the connections' isopcbs. ! 520: * ! 521: * RETURNS: Rien. ! 522: * ! 523: * SIDE EFFECTS: ! 524: * ! 525: * NOTES: (notify) is called at splimp! ! 526: */ ! 527: void ! 528: iso_pcbnotify(head, siso, errno, notify) ! 529: struct isopcb *head; ! 530: register struct sockaddr_iso *siso; ! 531: int errno, (*notify)(); ! 532: { ! 533: register struct isopcb *isop; ! 534: int s = splimp(); ! 535: ! 536: IFDEBUG(D_ISO) ! 537: printf("iso_pcbnotify(head 0x%x, notify 0x%x) dst:\n", head, notify); ! 538: ENDDEBUG ! 539: for (isop = head->isop_next; isop != head; isop = isop->isop_next) { ! 540: if (isop->isop_socket == 0 || isop->isop_faddr == 0 || ! 541: !SAME_ISOADDR(siso, isop->isop_faddr)) { ! 542: IFDEBUG(D_ISO) ! 543: printf("iso_pcbnotify: CONTINUE isop 0x%x, sock 0x%x\n" , ! 544: isop, isop->isop_socket); ! 545: printf("addrmatch cmp'd with (0x%x):\n", isop->isop_faddr); ! 546: dump_isoaddr(isop->isop_faddr); ! 547: ENDDEBUG ! 548: continue; ! 549: } ! 550: if (errno) ! 551: isop->isop_socket->so_error = errno; ! 552: if (notify) ! 553: (*notify)(isop); ! 554: } ! 555: splx(s); ! 556: IFDEBUG(D_ISO) ! 557: printf("END OF iso_pcbnotify\n" ); ! 558: ENDDEBUG ! 559: } ! 560: ! 561: ! 562: /* ! 563: * FUNCTION: iso_pcblookup ! 564: * ! 565: * PURPOSE: looks for a given combination of (faddr), (fport), ! 566: * (lport), (laddr) in the queue named by (head). ! 567: * Argument (flags) is ignored. ! 568: * ! 569: * RETURNS: ptr to the isopcb if it finds a connection matching ! 570: * these arguments, o.w. returns zero. ! 571: * ! 572: * SIDE EFFECTS: ! 573: * ! 574: * NOTES: ! 575: */ ! 576: struct isopcb * ! 577: iso_pcblookup(head, fportlen, fport, laddr) ! 578: struct isopcb *head; ! 579: register struct sockaddr_iso *laddr; ! 580: caddr_t fport; ! 581: int fportlen; ! 582: { ! 583: register struct isopcb *isop; ! 584: register caddr_t lp = TSEL(laddr); ! 585: unsigned int llen = laddr->siso_tlen; ! 586: ! 587: IFDEBUG(D_ISO) ! 588: printf("iso_pcblookup(head 0x%x laddr 0x%x fport 0x%x)\n", ! 589: head, laddr, fport); ! 590: ENDDEBUG ! 591: for (isop = head->isop_next; isop != head; isop = isop->isop_next) { ! 592: if (isop->isop_laddr == 0 || isop->isop_laddr == laddr) ! 593: continue; ! 594: if (isop->isop_laddr->siso_tlen != llen) ! 595: continue; ! 596: if (bcmp(lp, TSEL(isop->isop_laddr), llen)) ! 597: continue; ! 598: if (fportlen && isop->isop_faddr && ! 599: bcmp(fport, TSEL(isop->isop_faddr), (unsigned)fportlen)) ! 600: continue; ! 601: /* PHASE2 ! 602: * addrmatch1 should be iso_addrmatch(a, b, mask) ! 603: * where mask is taken from isop->isop_laddrmask (new field) ! 604: * isop_lnetmask will also be available in isop ! 605: if (laddr != &zeroiso_addr && ! 606: !iso_addrmatch1(laddr, &(isop->isop_laddr.siso_addr))) ! 607: continue; ! 608: */ ! 609: if (laddr->siso_nlen && (!SAME_ISOADDR(laddr, isop->isop_laddr))) ! 610: continue; ! 611: return (isop); ! 612: } ! 613: return (struct isopcb *)0; ! 614: } ! 615: #endif ISO
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.