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