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