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