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