|
|
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) 1992, 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: * @(#)tuba_subr.c 8.1 (Berkeley) 6/10/93 ! 58: */ ! 59: ! 60: #include <sys/param.h> ! 61: #include <sys/proc.h> ! 62: #include <sys/systm.h> ! 63: #include <sys/malloc.h> ! 64: #include <sys/mbuf.h> ! 65: #include <sys/socket.h> ! 66: #include <sys/socketvar.h> ! 67: #include <sys/protosw.h> ! 68: #include <sys/errno.h> ! 69: ! 70: #include <net/route.h> ! 71: #include <net/if.h> ! 72: ! 73: #include <netinet/in.h> ! 74: #include <netinet/in_systm.h> ! 75: #include <netinet/ip.h> ! 76: #include <netinet/in_pcb.h> ! 77: #include <netinet/ip_var.h> ! 78: #include <netinet/ip_icmp.h> ! 79: #include <netinet/tcp.h> ! 80: #include <netinet/tcp_fsm.h> ! 81: #include <netinet/tcp_seq.h> ! 82: #include <netinet/tcp_timer.h> ! 83: #include <netinet/tcp_var.h> ! 84: #include <netinet/tcpip.h> ! 85: #include <netinet/tcp_debug.h> ! 86: ! 87: #include <netiso/argo_debug.h> ! 88: #include <netiso/iso.h> ! 89: #include <netiso/clnp.h> ! 90: #include <netiso/iso_pcb.h> ! 91: #include <netiso/iso_var.h> ! 92: #include <netiso/tuba_table.h> ! 93: ! 94: static struct sockaddr_iso null_siso = { sizeof(null_siso), AF_ISO, }; ! 95: extern int tuba_table_size, tcp_keepidle, tcp_keepintvl, tcp_maxidle; ! 96: extern int tcppcbcachemiss, tcppredack, tcppreddat, tcprexmtthresh; ! 97: extern struct tcpiphdr tcp_saveti; ! 98: struct inpcb tuba_inpcb; ! 99: struct inpcb *tuba_last_inpcb = &tuba_inpcb; ! 100: struct isopcb tuba_isopcb; ! 101: /* ! 102: * Tuba initialization ! 103: */ ! 104: tuba_init() ! 105: { ! 106: #define TUBAHDRSIZE (3 /*LLC*/ + 9 /*CLNP Fixed*/ + 42 /*Addresses*/ \ ! 107: + 6 /*CLNP Segment*/ + 20 /*TCP*/) ! 108: ! 109: tuba_inpcb.inp_next = tuba_inpcb.inp_prev = &tuba_inpcb; ! 110: tuba_isopcb.isop_next = tuba_isopcb.isop_prev = &tuba_isopcb; ! 111: tuba_isopcb.isop_faddr = &tuba_isopcb.isop_sfaddr; ! 112: tuba_isopcb.isop_laddr = &tuba_isopcb.isop_sladdr; ! 113: if (max_protohdr < TUBAHDRSIZE) ! 114: max_protohdr = TUBAHDRSIZE; ! 115: if (max_linkhdr + TUBAHDRSIZE > MHLEN) ! 116: panic("tuba_init"); ! 117: } ! 118: ! 119: struct addr_arg { ! 120: int error; ! 121: int offset; ! 122: u_long sum; ! 123: }; ! 124: ! 125: /* ! 126: * Calculate contribution to fudge factor for TCP checksum, ! 127: * and coincidentally set pointer for convenience of clnp_output ! 128: * if we are are responding when there is no isopcb around. ! 129: */ ! 130: static void ! 131: tuba_getaddr(arg, siso, index) ! 132: register struct addr_arg *arg; ! 133: struct sockaddr_iso **siso; ! 134: u_long index; ! 135: { ! 136: register struct tuba_cache *tc; ! 137: if (index <= tuba_table_size && (tc = tuba_table[index])) { ! 138: if (siso) ! 139: *siso = &tc->tc_siso; ! 140: arg->sum += (arg->offset & 1 ? tc->tc_ssum : tc->tc_sum) ! 141: + (0xffff ^ index); ! 142: arg->offset += tc->tc_siso.siso_nlen + 1; ! 143: } else ! 144: arg->error = 1; ! 145: } ! 146: ! 147: tuba_output(m, tp) ! 148: register struct mbuf *m; ! 149: struct tcpcb *tp; ! 150: { ! 151: register struct tcpiphdr *n; ! 152: struct isopcb *isop; ! 153: struct addr_arg arg; ! 154: ! 155: if (tp == 0 || (n = tp->t_template) == 0 || ! 156: (isop = (struct isopcb *)tp->t_tuba_pcb) == 0) { ! 157: isop = &tuba_isopcb; ! 158: n = mtod(m, struct tcpiphdr *); ! 159: arg.error = arg.sum = arg.offset = 0; ! 160: tuba_getaddr(&arg, &tuba_isopcb.isop_faddr, n->ti_dst.s_addr); ! 161: tuba_getaddr(&arg, &tuba_isopcb.isop_laddr, n->ti_src.s_addr); ! 162: REDUCE(arg.sum, arg.sum); ! 163: goto adjust; ! 164: } ! 165: if (n->ti_sum == 0) { ! 166: arg.error = arg.sum = arg.offset = 0; ! 167: tuba_getaddr(&arg, (struct sockaddr_iso **)0, n->ti_dst.s_addr); ! 168: tuba_getaddr(&arg, (struct sockaddr_iso **)0, n->ti_src.s_addr); ! 169: REDUCE(arg.sum, arg.sum); ! 170: n->ti_sum = arg.sum; ! 171: n = mtod(m, struct tcpiphdr *); ! 172: adjust: ! 173: if (arg.error) { ! 174: m_freem(m); ! 175: return (EADDRNOTAVAIL); ! 176: } ! 177: REDUCE(n->ti_sum, n->ti_sum + (0xffff ^ arg.sum)); ! 178: } ! 179: m->m_len -= sizeof (struct ip); ! 180: m->m_pkthdr.len -= sizeof (struct ip); ! 181: m->m_data += sizeof (struct ip); ! 182: return (clnp_output(m, isop, m->m_pkthdr.len, 0)); ! 183: } ! 184: ! 185: tuba_refcnt(isop, delta) ! 186: struct isopcb *isop; ! 187: { ! 188: register struct tuba_cache *tc; ! 189: unsigned index, sum; ! 190: ! 191: if (delta != 1) ! 192: delta = -1; ! 193: if (isop == 0 || isop->isop_faddr == 0 || isop->isop_laddr == 0 || ! 194: (delta == -1 && isop->isop_tuba_cached == 0) || ! 195: (delta == 1 && isop->isop_tuba_cached != 0)) ! 196: return; ! 197: isop->isop_tuba_cached = (delta == 1); ! 198: if ((index = tuba_lookup(isop->isop_faddr, M_DONTWAIT)) != 0 && ! 199: (tc = tuba_table[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0)) ! 200: tc->tc_refcnt += delta; ! 201: if ((index = tuba_lookup(isop->isop_laddr, M_DONTWAIT)) != 0 && ! 202: (tc = tuba_table[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0)) ! 203: tc->tc_refcnt += delta; ! 204: } ! 205: ! 206: tuba_pcbdetach(isop) ! 207: struct isopcb *isop; ! 208: { ! 209: if (isop == 0) ! 210: return; ! 211: tuba_refcnt(isop, -1); ! 212: isop->isop_socket = 0; ! 213: iso_pcbdetach(isop); ! 214: } ! 215: ! 216: /* ! 217: * Avoid in_pcbconnect in faked out tcp_input() ! 218: */ ! 219: tuba_pcbconnect(inp, nam) ! 220: register struct inpcb *inp; ! 221: struct mbuf *nam; ! 222: { ! 223: register struct sockaddr_iso *siso; ! 224: struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); ! 225: struct tcpcb *tp = intotcpcb(inp); ! 226: struct isopcb *isop = (struct isopcb *)tp->t_tuba_pcb; ! 227: int error; ! 228: ! 229: /* hardwire iso_pcbbind() here */ ! 230: siso = isop->isop_laddr = &isop->isop_sladdr; ! 231: *siso = tuba_table[inp->inp_laddr.s_addr]->tc_siso; ! 232: siso->siso_tlen = sizeof(inp->inp_lport); ! 233: bcopy((caddr_t)&inp->inp_lport, TSEL(siso), sizeof(inp->inp_lport)); ! 234: ! 235: /* hardwire in_pcbconnect() here without assigning route */ ! 236: inp->inp_fport = sin->sin_port; ! 237: inp->inp_faddr = sin->sin_addr; ! 238: ! 239: /* reuse nam argument to call iso_pcbconnect() */ ! 240: nam->m_len = sizeof(*siso); ! 241: siso = mtod(nam, struct sockaddr_iso *); ! 242: *siso = tuba_table[inp->inp_faddr.s_addr]->tc_siso; ! 243: siso->siso_tlen = sizeof(inp->inp_fport); ! 244: bcopy((caddr_t)&inp->inp_fport, TSEL(siso), sizeof(inp->inp_fport)); ! 245: ! 246: if ((error = iso_pcbconnect(isop, nam)) == 0) ! 247: tuba_refcnt(isop, 1); ! 248: return (error); ! 249: } ! 250: ! 251: /* ! 252: * CALLED FROM: ! 253: * clnp's input routine, indirectly through the protosw. ! 254: * FUNCTION and ARGUMENTS: ! 255: * Take a packet (m) from clnp, strip off the clnp header ! 256: * and do tcp input processing. ! 257: * No return value. ! 258: */ ! 259: tuba_tcpinput(m, src, dst) ! 260: register struct mbuf *m; ! 261: struct sockaddr_iso *src, *dst; ! 262: { ! 263: unsigned long sum, lindex, findex; ! 264: register struct tcpiphdr *ti; ! 265: register struct inpcb *inp; ! 266: caddr_t optp = NULL; ! 267: int optlen; ! 268: int len, tlen, off; ! 269: register struct tcpcb *tp = 0; ! 270: int tiflags; ! 271: struct socket *so; ! 272: int todrop, acked, ourfinisacked, needoutput = 0; ! 273: short ostate; ! 274: struct in_addr laddr; ! 275: int dropsocket = 0, iss = 0; ! 276: u_long tiwin, ts_val, ts_ecr; ! 277: int ts_present = 0; ! 278: ! 279: if ((m->m_flags & M_PKTHDR) == 0) ! 280: panic("tuba_tcpinput"); ! 281: /* ! 282: * Do some housekeeping looking up CLNP addresses. ! 283: * If we are out of space might as well drop the packet now. ! 284: */ ! 285: tcpstat.tcps_rcvtotal++; ! 286: lindex = tuba_lookup(dst, M_DONTWAIT); ! 287: findex = tuba_lookup(src, M_DONTWAIT); ! 288: if (lindex == 0 || findex == 0) ! 289: goto drop; ! 290: /* ! 291: * CLNP gave us an mbuf chain WITH the clnp header pulled up, ! 292: * but the data pointer pushed past it. ! 293: */ ! 294: len = m->m_len; ! 295: tlen = m->m_pkthdr.len; ! 296: m->m_data -= sizeof(struct ip); ! 297: m->m_len += sizeof(struct ip); ! 298: m->m_pkthdr.len += sizeof(struct ip); ! 299: m->m_flags &= ~(M_MCAST|M_BCAST); /* XXX should do this in clnp_input */ ! 300: /* ! 301: * The reassembly code assumes it will be overwriting a useless ! 302: * part of the packet, which is why we need to have it point ! 303: * into the packet itself. ! 304: * ! 305: * Check to see if the data is properly alligned ! 306: * so that we can save copying the tcp header. ! 307: * This code knows way too much about the structure of mbufs! ! 308: */ ! 309: off = ((sizeof (long) - 1) & ((m->m_flags & M_EXT) ? ! 310: (m->m_data - m->m_ext.ext_buf) : (m->m_data - m->m_pktdat))); ! 311: if (off || len < sizeof(struct tcphdr)) { ! 312: struct mbuf *m0 = m; ! 313: ! 314: MGETHDR(m, M_DONTWAIT, MT_DATA); ! 315: if (m == 0) { ! 316: m = m0; ! 317: goto drop; ! 318: } ! 319: m->m_next = m0; ! 320: m->m_data += max_linkhdr; ! 321: m->m_pkthdr = m0->m_pkthdr; ! 322: m->m_flags = m0->m_flags & M_COPYFLAGS; ! 323: if (len < sizeof(struct tcphdr)) { ! 324: m->m_len = 0; ! 325: if ((m = m_pullup(m, sizeof(struct tcpiphdr))) == 0) { ! 326: tcpstat.tcps_rcvshort++; ! 327: return; ! 328: } ! 329: } else { ! 330: bcopy(mtod(m0, caddr_t) + sizeof(struct ip), ! 331: mtod(m, caddr_t) + sizeof(struct ip), ! 332: sizeof(struct tcphdr)); ! 333: m0->m_len -= sizeof(struct tcpiphdr); ! 334: m0->m_data += sizeof(struct tcpiphdr); ! 335: m->m_len = sizeof(struct tcpiphdr); ! 336: } ! 337: } ! 338: /* ! 339: * Calculate checksum of extended TCP header and data, ! 340: * replacing what would have been IP addresses by ! 341: * the IP checksum of the CLNP addresses. ! 342: */ ! 343: ti = mtod(m, struct tcpiphdr *); ! 344: ti->ti_dst.s_addr = tuba_table[lindex]->tc_sum; ! 345: if (dst->siso_nlen & 1) ! 346: ti->ti_src.s_addr = tuba_table[findex]->tc_sum; ! 347: else ! 348: ti->ti_src.s_addr = tuba_table[findex]->tc_ssum; ! 349: ti->ti_prev = ti->ti_next = 0; ! 350: ti->ti_x1 = 0; ti->ti_pr = ISOPROTO_TCP; ! 351: ti->ti_len = htons((u_short)tlen); ! 352: if (ti->ti_sum = in_cksum(m, m->m_pkthdr.len)) { ! 353: tcpstat.tcps_rcvbadsum++; ! 354: goto drop; ! 355: } ! 356: ti->ti_src.s_addr = findex; ! 357: ti->ti_dst.s_addr = lindex; ! 358: /* ! 359: * Now include the rest of TCP input ! 360: */ ! 361: #define TUBA_INCLUDE ! 362: #define in_pcbconnect tuba_pcbconnect ! 363: #define tcb tuba_inpcb ! 364: #define tcp_last_inpcb tuba_last_inpcb ! 365: ! 366: #include <netinet/tcp_input.c> ! 367: } ! 368: ! 369: #define tcp_slowtimo tuba_slowtimo ! 370: #define tcp_fasttimo tuba_fasttimo ! 371: ! 372: #include <netinet/tcp_timer.c>
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.