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