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