]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netiso/tuba_subr.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1992, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
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.
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
54 * @(#)tuba_subr.c 8.1 (Berkeley) 6/10/93
57 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/malloc.h>
62 #include <sys/socket.h>
63 #include <sys/socketvar.h>
64 #include <sys/protosw.h>
65 #include <sys/errno.h>
67 #include <net/route.h>
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>
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>
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
;
103 #define TUBAHDRSIZE (3 /*LLC*/ + 9 /*CLNP Fixed*/ + 42 /*Addresses*/ \
104 + 6 /*CLNP Segment*/ + 20 /*TCP*/)
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
)
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.
128 tuba_getaddr(arg
, siso
, index
)
129 register struct addr_arg
*arg
;
130 struct sockaddr_iso
**siso
;
133 register struct tuba_cache
*tc
;
134 if (index
<= tuba_table_size
&& (tc
= tuba_table
[index
])) {
136 *siso
= &tc
->tc_siso
;
137 arg
->sum
+= (arg
->offset
& 1 ? tc
->tc_ssum
: tc
->tc_sum
)
139 arg
->offset
+= tc
->tc_siso
.siso_nlen
+ 1;
145 register struct mbuf
*m
;
148 register struct tcpiphdr
*n
;
152 if (tp
== 0 || (n
= tp
->t_template
) == 0 ||
153 (isop
= (struct isopcb
*)tp
->t_tuba_pcb
) == 0) {
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
);
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
);
168 n
= mtod(m
, struct tcpiphdr
*);
172 return (EADDRNOTAVAIL
);
174 REDUCE(n
->ti_sum
, n
->ti_sum
+ (0xffff ^ arg
.sum
));
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));
182 tuba_refcnt(isop
, delta
)
185 register struct tuba_cache
*tc
;
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))
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
;
208 tuba_refcnt(isop
, -1);
209 isop
->isop_socket
= 0;
214 * Avoid in_pcbconnect in faked out tcp_input()
216 tuba_pcbconnect(inp
, nam
)
217 register struct inpcb
*inp
;
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
;
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
));
232 /* hardwire in_pcbconnect() here without assigning route */
233 inp
->inp_fport
= sin
->sin_port
;
234 inp
->inp_faddr
= sin
->sin_addr
;
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
));
243 if ((error
= iso_pcbconnect(isop
, nam
)) == 0)
244 tuba_refcnt(isop
, 1);
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.
256 tuba_tcpinput(m
, src
, dst
)
257 register struct mbuf
*m
;
258 struct sockaddr_iso
*src
, *dst
;
260 unsigned long sum
, lindex
, findex
;
261 register struct tcpiphdr
*ti
;
262 register struct inpcb
*inp
;
266 register struct tcpcb
*tp
= 0;
269 int todrop
, acked
, ourfinisacked
, needoutput
= 0;
271 struct in_addr laddr
;
272 int dropsocket
= 0, iss
= 0;
273 u_long tiwin
, ts_val
, ts_ecr
;
276 if ((m
->m_flags
& M_PKTHDR
) == 0)
277 panic("tuba_tcpinput");
279 * Do some housekeeping looking up CLNP addresses.
280 * If we are out of space might as well drop the packet now.
282 tcpstat
.tcps_rcvtotal
++;
283 lindex
= tuba_lookup(dst
, M_DONTWAIT
);
284 findex
= tuba_lookup(src
, M_DONTWAIT
);
285 if (lindex
== 0 || findex
== 0)
288 * CLNP gave us an mbuf chain WITH the clnp header pulled up,
289 * but the data pointer pushed past it.
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 */
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.
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!
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
)) {
311 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
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
)) {
322 if ((m
= m_pullup(m
, sizeof(struct tcpiphdr
))) == 0) {
323 tcpstat
.tcps_rcvshort
++;
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
);
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.
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
;
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
++;
353 ti
->ti_src
.s_addr
= findex
;
354 ti
->ti_dst
.s_addr
= lindex
;
356 * Now include the rest of TCP input
359 #define in_pcbconnect tuba_pcbconnect
360 #define tcb tuba_inpcb
361 #define tcp_last_inpcb tuba_last_inpcb
363 #include <netinet/tcp_input.c>
366 #define tcp_slowtimo tuba_slowtimo
367 #define tcp_fasttimo tuba_fasttimo
369 #include <netinet/tcp_timer.c>