|
|
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) 1989, 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: * @(#)cltp_usrreq.c 8.1 (Berkeley) 6/10/93 ! 58: */ ! 59: ! 60: #ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */ ! 61: #include <sys/param.h> ! 62: #include <sys/malloc.h> ! 63: #include <sys/mbuf.h> ! 64: #include <sys/protosw.h> ! 65: #include <sys/socket.h> ! 66: #include <sys/socketvar.h> ! 67: #include <sys/errno.h> ! 68: #include <sys/stat.h> ! 69: ! 70: #include <net/if.h> ! 71: #include <net/route.h> ! 72: ! 73: #include <netiso/argo_debug.h> ! 74: #include <netiso/iso.h> ! 75: #include <netiso/iso_pcb.h> ! 76: #include <netiso/iso_var.h> ! 77: #include <netiso/clnp.h> ! 78: #include <netiso/cltp_var.h> ! 79: #endif ! 80: ! 81: /* ! 82: * CLTP protocol implementation. ! 83: * Per ISO 8602, December, 1987. ! 84: */ ! 85: cltp_init() ! 86: { ! 87: ! 88: cltb.isop_next = cltb.isop_prev = &cltb; ! 89: } ! 90: ! 91: int cltp_cksum = 1; ! 92: ! 93: ! 94: /* ARGUSED */ ! 95: cltp_input(m0, srcsa, dstsa, cons_channel, output) ! 96: struct mbuf *m0; ! 97: struct sockaddr *srcsa, *dstsa; ! 98: u_int cons_channel; ! 99: int (*output)(); ! 100: { ! 101: register struct isopcb *isop; ! 102: register struct mbuf *m = m0; ! 103: register u_char *up = mtod(m, u_char *); ! 104: register struct sockaddr_iso *src = (struct sockaddr_iso *)srcsa; ! 105: int len, hdrlen = *up + 1, dlen = 0; ! 106: u_char *uplim = up + hdrlen; ! 107: caddr_t dtsap; ! 108: ! 109: for (len = 0; m; m = m->m_next) ! 110: len += m->m_len; ! 111: up += 2; /* skip header */ ! 112: while (up < uplim) switch (*up) { /* process options */ ! 113: case CLTPOVAL_SRC: ! 114: src->siso_tlen = up[1]; ! 115: src->siso_len = up[1] + TSEL(src) - (caddr_t)src; ! 116: if (src->siso_len < sizeof(*src)) ! 117: src->siso_len = sizeof(*src); ! 118: else if (src->siso_len > sizeof(*src)) { ! 119: MGET(m, M_DONTWAIT, MT_SONAME); ! 120: if (m == 0) ! 121: goto bad; ! 122: m->m_len = src->siso_len; ! 123: src = mtod(m, struct sockaddr_iso *); ! 124: bcopy((caddr_t)srcsa, (caddr_t)src, srcsa->sa_len); ! 125: } ! 126: bcopy((caddr_t)up + 2, TSEL(src), up[1]); ! 127: up += 2 + src->siso_tlen; ! 128: continue; ! 129: ! 130: case CLTPOVAL_DST: ! 131: dtsap = 2 + (caddr_t)up; ! 132: dlen = up[1]; ! 133: up += 2 + dlen; ! 134: continue; ! 135: ! 136: case CLTPOVAL_CSM: ! 137: if (iso_check_csum(m0, len)) { ! 138: cltpstat.cltps_badsum++; ! 139: goto bad; ! 140: } ! 141: up += 4; ! 142: continue; ! 143: ! 144: default: ! 145: printf("clts: unknown option (%x)\n", up[0]); ! 146: cltpstat.cltps_hdrops++; ! 147: goto bad; ! 148: } ! 149: if (dlen == 0 || src->siso_tlen == 0) ! 150: goto bad; ! 151: for (isop = cltb.isop_next;; isop = isop->isop_next) { ! 152: if (isop == &cltb) { ! 153: cltpstat.cltps_noport++; ! 154: goto bad; ! 155: } ! 156: if (isop->isop_laddr && ! 157: bcmp(TSEL(isop->isop_laddr), dtsap, dlen) == 0) ! 158: break; ! 159: } ! 160: m = m0; ! 161: m->m_len -= hdrlen; ! 162: m->m_data += hdrlen; ! 163: if (sbappendaddr(&isop->isop_socket->so_rcv, (struct sockaddr *)src, ! 164: m, (struct mbuf *)0) == 0) ! 165: goto bad; ! 166: cltpstat.cltps_ipackets++; ! 167: sorwakeup(isop->isop_socket); ! 168: m0 = 0; ! 169: bad: ! 170: if (src != (struct sockaddr_iso *)srcsa) ! 171: m_freem(dtom(src)); ! 172: if (m0) ! 173: m_freem(m0); ! 174: return 0; ! 175: } ! 176: ! 177: /* ! 178: * Notify a cltp user of an asynchronous error; ! 179: * just wake up so that he can collect error status. ! 180: */ ! 181: cltp_notify(isop) ! 182: register struct isopcb *isop; ! 183: { ! 184: ! 185: sorwakeup(isop->isop_socket); ! 186: sowwakeup(isop->isop_socket); ! 187: } ! 188: ! 189: cltp_ctlinput(cmd, sa) ! 190: int cmd; ! 191: struct sockaddr *sa; ! 192: { ! 193: extern u_char inetctlerrmap[]; ! 194: struct sockaddr_iso *siso; ! 195: int iso_rtchange(); ! 196: ! 197: if ((unsigned)cmd > PRC_NCMDS) ! 198: return; ! 199: if (sa->sa_family != AF_ISO && sa->sa_family != AF_CCITT) ! 200: return; ! 201: siso = (struct sockaddr_iso *)sa; ! 202: if (siso == 0 || siso->siso_nlen == 0) ! 203: return; ! 204: ! 205: switch (cmd) { ! 206: case PRC_ROUTEDEAD: ! 207: case PRC_REDIRECT_NET: ! 208: case PRC_REDIRECT_HOST: ! 209: case PRC_REDIRECT_TOSNET: ! 210: case PRC_REDIRECT_TOSHOST: ! 211: iso_pcbnotify(&cltb, siso, ! 212: (int)inetctlerrmap[cmd], iso_rtchange); ! 213: break; ! 214: ! 215: default: ! 216: if (inetctlerrmap[cmd] == 0) ! 217: return; /* XXX */ ! 218: iso_pcbnotify(&cltb, siso, (int)inetctlerrmap[cmd], ! 219: cltp_notify); ! 220: } ! 221: } ! 222: ! 223: cltp_output(isop, m) ! 224: register struct isopcb *isop; ! 225: register struct mbuf *m; ! 226: { ! 227: register int len; ! 228: register struct sockaddr_iso *siso; ! 229: int hdrlen, error = 0, docsum; ! 230: register u_char *up; ! 231: ! 232: if (isop->isop_laddr == 0 || isop->isop_faddr == 0) { ! 233: error = ENOTCONN; ! 234: goto bad; ! 235: } ! 236: /* ! 237: * Calculate data length and get a mbuf for CLTP header. ! 238: */ ! 239: hdrlen = 2 + 2 + isop->isop_laddr->siso_tlen ! 240: + 2 + isop->isop_faddr->siso_tlen; ! 241: if (docsum = /*isop->isop_flags & CLNP_NO_CKSUM*/ cltp_cksum) ! 242: hdrlen += 4; ! 243: M_PREPEND(m, hdrlen, M_WAIT); ! 244: len = m->m_pkthdr.len; ! 245: /* ! 246: * Fill in mbuf with extended CLTP header ! 247: */ ! 248: up = mtod(m, u_char *); ! 249: up[0] = hdrlen - 1; ! 250: up[1] = UD_TPDU_type; ! 251: up[2] = CLTPOVAL_SRC; ! 252: up[3] = (siso = isop->isop_laddr)->siso_tlen; ! 253: up += 4; ! 254: bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen); ! 255: up += siso->siso_tlen; ! 256: up[0] = CLTPOVAL_DST; ! 257: up[1] = (siso = isop->isop_faddr)->siso_tlen; ! 258: up += 2; ! 259: bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen); ! 260: /* ! 261: * Stuff checksum and output datagram. ! 262: */ ! 263: if (docsum) { ! 264: up += siso->siso_tlen; ! 265: up[0] = CLTPOVAL_CSM; ! 266: up[1] = 2; ! 267: iso_gen_csum(m, 2 + up - mtod(m, u_char *), len); ! 268: } ! 269: cltpstat.cltps_opackets++; ! 270: return (tpclnp_output(isop, m, len, !docsum)); ! 271: bad: ! 272: m_freem(m); ! 273: return (error); ! 274: } ! 275: ! 276: u_long cltp_sendspace = 9216; /* really max datagram size */ ! 277: u_long cltp_recvspace = 40 * (1024 + sizeof(struct sockaddr_iso)); ! 278: /* 40 1K datagrams */ ! 279: ! 280: ! 281: /*ARGSUSED*/ ! 282: cltp_usrreq(so, req, m, nam, control) ! 283: struct socket *so; ! 284: int req; ! 285: struct mbuf *m, *nam, *control; ! 286: { ! 287: register struct isopcb *isop = sotoisopcb(so); ! 288: int s, error = 0; ! 289: ! 290: if (req == PRU_CONTROL) ! 291: return (iso_control(so, (int)m, (caddr_t)nam, ! 292: (struct ifnet *)control)); ! 293: if ((isop == NULL && req != PRU_ATTACH) || ! 294: (control && control->m_len)) { ! 295: error = EINVAL; ! 296: goto release; ! 297: } ! 298: switch (req) { ! 299: ! 300: case PRU_ATTACH: ! 301: if (isop != NULL) { ! 302: error = EINVAL; ! 303: break; ! 304: } ! 305: error = iso_pcballoc(so, &cltb); ! 306: if (error) ! 307: break; ! 308: error = soreserve(so, cltp_sendspace, cltp_recvspace); ! 309: if (error) ! 310: break; ! 311: break; ! 312: ! 313: case PRU_DETACH: ! 314: iso_pcbdetach(isop); ! 315: break; ! 316: ! 317: case PRU_BIND: ! 318: error = iso_pcbbind(isop, nam); ! 319: break; ! 320: ! 321: case PRU_LISTEN: ! 322: error = EOPNOTSUPP; ! 323: break; ! 324: ! 325: case PRU_CONNECT: ! 326: if (isop->isop_faddr) { ! 327: error = EISCONN; ! 328: break; ! 329: } ! 330: error = iso_pcbconnect(isop, nam); ! 331: if (error == 0) ! 332: soisconnected(so); ! 333: break; ! 334: ! 335: case PRU_CONNECT2: ! 336: error = EOPNOTSUPP; ! 337: break; ! 338: ! 339: case PRU_ACCEPT: ! 340: error = EOPNOTSUPP; ! 341: break; ! 342: ! 343: case PRU_DISCONNECT: ! 344: if (isop->isop_faddr == 0) { ! 345: error = ENOTCONN; ! 346: break; ! 347: } ! 348: iso_pcbdisconnect(isop); ! 349: so->so_state &= ~SS_ISCONNECTED; /* XXX */ ! 350: break; ! 351: ! 352: case PRU_SHUTDOWN: ! 353: socantsendmore(so); ! 354: break; ! 355: ! 356: case PRU_SEND: ! 357: if (nam) { ! 358: if (isop->isop_faddr) { ! 359: error = EISCONN; ! 360: break; ! 361: } ! 362: /* ! 363: * Must block input while temporarily connected. ! 364: */ ! 365: s = splnet(); ! 366: error = iso_pcbconnect(isop, nam); ! 367: if (error) { ! 368: splx(s); ! 369: break; ! 370: } ! 371: } else { ! 372: if (isop->isop_faddr == 0) { ! 373: error = ENOTCONN; ! 374: break; ! 375: } ! 376: } ! 377: error = cltp_output(isop, m); ! 378: m = 0; ! 379: if (nam) { ! 380: iso_pcbdisconnect(isop); ! 381: splx(s); ! 382: } ! 383: break; ! 384: ! 385: case PRU_ABORT: ! 386: soisdisconnected(so); ! 387: iso_pcbdetach(isop); ! 388: break; ! 389: ! 390: case PRU_SOCKADDR: ! 391: if (isop->isop_laddr) ! 392: bcopy((caddr_t)isop->isop_laddr, mtod(m, caddr_t), ! 393: nam->m_len = isop->isop_laddr->siso_len); ! 394: break; ! 395: ! 396: case PRU_PEERADDR: ! 397: if (isop->isop_faddr) ! 398: bcopy((caddr_t)isop->isop_faddr, mtod(m, caddr_t), ! 399: nam->m_len = isop->isop_faddr->siso_len); ! 400: break; ! 401: ! 402: case PRU_SENSE: ! 403: /* ! 404: * stat: don't bother with a blocksize. ! 405: */ ! 406: return (0); ! 407: ! 408: case PRU_SENDOOB: ! 409: case PRU_FASTTIMO: ! 410: case PRU_SLOWTIMO: ! 411: case PRU_PROTORCV: ! 412: case PRU_PROTOSEND: ! 413: error = EOPNOTSUPP; ! 414: break; ! 415: ! 416: case PRU_RCVD: ! 417: case PRU_RCVOOB: ! 418: return (EOPNOTSUPP); /* do not free mbuf's */ ! 419: ! 420: default: ! 421: panic("cltp_usrreq"); ! 422: } ! 423: release: ! 424: if (control != NULL) ! 425: m_freem(control); ! 426: if (m != NULL) ! 427: m_freem(m); ! 428: return (error); ! 429: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.