]> git.saurik.com Git - apple/xnu.git/blame - bsd/netiso/tuba_subr.c
xnu-201.42.3.tar.gz
[apple/xnu.git] / bsd / netiso / tuba_subr.c
CommitLineData
1c79356b
A
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
91static struct sockaddr_iso null_siso = { sizeof(null_siso), AF_ISO, };
92extern int tuba_table_size, tcp_keepidle, tcp_keepintvl, tcp_maxidle;
93extern int tcppcbcachemiss, tcppredack, tcppreddat, tcprexmtthresh;
94extern struct tcpiphdr tcp_saveti;
95struct inpcb tuba_inpcb;
96struct inpcb *tuba_last_inpcb = &tuba_inpcb;
97struct isopcb tuba_isopcb;
98/*
99 * Tuba initialization
100 */
101tuba_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
116struct 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 */
127static void
128tuba_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
144tuba_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
182tuba_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
203tuba_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 */
216tuba_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 */
256tuba_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>