tcp_rndiss.c revision 1.1.1.1 1 1.1.1.1 martti /* $OpenBSD: tcp_subr.c,v 1.98 2007/06/25 12:17:43 markus Exp $ */
2 1.1.1.1 martti /* $NetBSD: tcp_rndiss.c,v 1.1.1.1 2009/12/01 07:03:11 martti Exp $ */
3 1.1.1.1 martti
4 1.1.1.1 martti /*
5 1.1.1.1 martti * Copyright (c) 1982, 1986, 1988, 1990, 1993
6 1.1.1.1 martti * The Regents of the University of California. All rights reserved.
7 1.1.1.1 martti *
8 1.1.1.1 martti * Redistribution and use in source and binary forms, with or without
9 1.1.1.1 martti * modification, are permitted provided that the following conditions
10 1.1.1.1 martti * are met:
11 1.1.1.1 martti * 1. Redistributions of source code must retain the above copyright
12 1.1.1.1 martti * notice, this list of conditions and the following disclaimer.
13 1.1.1.1 martti * 2. Redistributions in binary form must reproduce the above copyright
14 1.1.1.1 martti * notice, this list of conditions and the following disclaimer in the
15 1.1.1.1 martti * documentation and/or other materials provided with the distribution.
16 1.1.1.1 martti * 3. Neither the name of the University nor the names of its contributors
17 1.1.1.1 martti * may be used to endorse or promote products derived from this software
18 1.1.1.1 martti * without specific prior written permission.
19 1.1.1.1 martti *
20 1.1.1.1 martti * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 1.1.1.1 martti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 1.1.1.1 martti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 1.1.1.1 martti * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 1.1.1.1 martti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 1.1.1.1 martti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 1.1.1.1 martti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 1.1.1.1 martti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 1.1.1.1 martti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 1.1.1.1 martti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 1.1.1.1 martti * SUCH DAMAGE.
31 1.1.1.1 martti *
32 1.1.1.1 martti * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
33 1.1.1.1 martti *
34 1.1.1.1 martti * NRL grants permission for redistribution and use in source and binary
35 1.1.1.1 martti * forms, with or without modification, of the software and documentation
36 1.1.1.1 martti * created at NRL provided that the following conditions are met:
37 1.1.1.1 martti *
38 1.1.1.1 martti * 1. Redistributions of source code must retain the above copyright
39 1.1.1.1 martti * notice, this list of conditions and the following disclaimer.
40 1.1.1.1 martti * 2. Redistributions in binary form must reproduce the above copyright
41 1.1.1.1 martti * notice, this list of conditions and the following disclaimer in the
42 1.1.1.1 martti * documentation and/or other materials provided with the distribution.
43 1.1.1.1 martti * 3. All advertising materials mentioning features or use of this software
44 1.1.1.1 martti * must display the following acknowledgements:
45 1.1.1.1 martti * This product includes software developed by the University of
46 1.1.1.1 martti * California, Berkeley and its contributors.
47 1.1.1.1 martti * This product includes software developed at the Information
48 1.1.1.1 martti * Technology Division, US Naval Research Laboratory.
49 1.1.1.1 martti * 4. Neither the name of the NRL nor the names of its contributors
50 1.1.1.1 martti * may be used to endorse or promote products derived from this software
51 1.1.1.1 martti * without specific prior written permission.
52 1.1.1.1 martti *
53 1.1.1.1 martti * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
54 1.1.1.1 martti * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55 1.1.1.1 martti * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
56 1.1.1.1 martti * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
57 1.1.1.1 martti * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58 1.1.1.1 martti * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59 1.1.1.1 martti * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60 1.1.1.1 martti * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61 1.1.1.1 martti * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62 1.1.1.1 martti * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63 1.1.1.1 martti * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 1.1.1.1 martti *
65 1.1.1.1 martti * The views and conclusions contained in the software and documentation
66 1.1.1.1 martti * are those of the authors and should not be interpreted as representing
67 1.1.1.1 martti * official policies, either expressed or implied, of the US Naval
68 1.1.1.1 martti * Research Laboratory (NRL).
69 1.1.1.1 martti */
70 1.1.1.1 martti
71 1.1.1.1 martti #include <sys/param.h>
72 1.1.1.1 martti #include <sys/systm.h>
73 1.1.1.1 martti #include <sys/proc.h>
74 1.1.1.1 martti #include <sys/mbuf.h>
75 1.1.1.1 martti #include <sys/socket.h>
76 1.1.1.1 martti #include <sys/socketvar.h>
77 1.1.1.1 martti #include <sys/protosw.h>
78 1.1.1.1 martti #include <sys/kernel.h>
79 1.1.1.1 martti
80 1.1.1.1 martti #include <net/route.h>
81 1.1.1.1 martti #include <net/if.h>
82 1.1.1.1 martti
83 1.1.1.1 martti #include <netinet/in.h>
84 1.1.1.1 martti #include <netinet/in_systm.h>
85 1.1.1.1 martti #include <netinet/ip.h>
86 1.1.1.1 martti #include <netinet/in_pcb.h>
87 1.1.1.1 martti #include <netinet/ip_var.h>
88 1.1.1.1 martti #include <netinet/ip_icmp.h>
89 1.1.1.1 martti #include <netinet/tcp.h>
90 1.1.1.1 martti #include <netinet/tcp_fsm.h>
91 1.1.1.1 martti #include <netinet/tcp_seq.h>
92 1.1.1.1 martti #include <netinet/tcp_timer.h>
93 1.1.1.1 martti #include <netinet/tcp_var.h>
94 1.1.1.1 martti #include <netinet/tcpip.h>
95 1.1.1.1 martti #include <dev/rndvar.h>
96 1.1.1.1 martti
97 1.1.1.1 martti #ifdef INET6
98 1.1.1.1 martti #include <netinet6/in6_var.h>
99 1.1.1.1 martti #include <netinet6/ip6protosw.h>
100 1.1.1.1 martti #endif /* INET6 */
101 1.1.1.1 martti
102 1.1.1.1 martti #include <crypto/md5.h>
103 1.1.1.1 martti
104 1.1.1.1 martti /* patchable/settable parameters for tcp */
105 1.1.1.1 martti int tcp_mssdflt = TCP_MSS;
106 1.1.1.1 martti int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
107 1.1.1.1 martti
108 1.1.1.1 martti /* values controllable via sysctl */
109 1.1.1.1 martti int tcp_do_rfc1323 = 1;
110 1.1.1.1 martti #ifdef TCP_SACK
111 1.1.1.1 martti int tcp_do_sack = 1; /* RFC 2018 selective ACKs */
112 1.1.1.1 martti #endif
113 1.1.1.1 martti int tcp_ack_on_push = 0; /* set to enable immediate ACK-on-PUSH */
114 1.1.1.1 martti #ifdef TCP_ECN
115 1.1.1.1 martti int tcp_do_ecn = 0; /* RFC3168 ECN enabled/disabled? */
116 1.1.1.1 martti #endif
117 1.1.1.1 martti int tcp_do_rfc3390 = 1; /* RFC3390 Increasing TCP's Initial Window */
118 1.1.1.1 martti
119 1.1.1.1 martti u_int32_t tcp_now = 1;
120 1.1.1.1 martti
121 1.1.1.1 martti #ifndef TCBHASHSIZE
122 1.1.1.1 martti #define TCBHASHSIZE 128
123 1.1.1.1 martti #endif
124 1.1.1.1 martti int tcbhashsize = TCBHASHSIZE;
125 1.1.1.1 martti
126 1.1.1.1 martti /* syn hash parameters */
127 1.1.1.1 martti #define TCP_SYN_HASH_SIZE 293
128 1.1.1.1 martti #define TCP_SYN_BUCKET_SIZE 35
129 1.1.1.1 martti int tcp_syn_cache_size = TCP_SYN_HASH_SIZE;
130 1.1.1.1 martti int tcp_syn_cache_limit = TCP_SYN_HASH_SIZE*TCP_SYN_BUCKET_SIZE;
131 1.1.1.1 martti int tcp_syn_bucket_limit = 3*TCP_SYN_BUCKET_SIZE;
132 1.1.1.1 martti struct syn_cache_head tcp_syn_cache[TCP_SYN_HASH_SIZE];
133 1.1.1.1 martti
134 1.1.1.1 martti int tcp_reass_limit = NMBCLUSTERS / 2; /* hardlimit for tcpqe_pool */
135 1.1.1.1 martti #ifdef TCP_SACK
136 1.1.1.1 martti int tcp_sackhole_limit = 32*1024; /* hardlimit for sackhl_pool */
137 1.1.1.1 martti #endif
138 1.1.1.1 martti
139 1.1.1.1 martti #ifdef INET6
140 1.1.1.1 martti extern int ip6_defhlim;
141 1.1.1.1 martti #endif /* INET6 */
142 1.1.1.1 martti
143 1.1.1.1 martti struct pool tcpcb_pool;
144 1.1.1.1 martti struct pool tcpqe_pool;
145 1.1.1.1 martti #ifdef TCP_SACK
146 1.1.1.1 martti struct pool sackhl_pool;
147 1.1.1.1 martti #endif
148 1.1.1.1 martti
149 1.1.1.1 martti struct tcpstat tcpstat; /* tcp statistics */
150 1.1.1.1 martti tcp_seq tcp_iss;
151 1.1.1.1 martti
152 1.1.1.1 martti /*
153 1.1.1.1 martti * Tcp initialization
154 1.1.1.1 martti */
155 1.1.1.1 martti void
156 1.1.1.1 martti tcp_init()
157 1.1.1.1 martti {
158 1.1.1.1 martti tcp_iss = 1; /* wrong */
159 1.1.1.1 martti pool_init(&tcpcb_pool, sizeof(struct tcpcb), 0, 0, 0, "tcpcbpl",
160 1.1.1.1 martti NULL);
161 1.1.1.1 martti pool_init(&tcpqe_pool, sizeof(struct tcpqent), 0, 0, 0, "tcpqepl",
162 1.1.1.1 martti NULL);
163 1.1.1.1 martti pool_sethardlimit(&tcpqe_pool, tcp_reass_limit, NULL, 0);
164 1.1.1.1 martti #ifdef TCP_SACK
165 1.1.1.1 martti pool_init(&sackhl_pool, sizeof(struct sackhole), 0, 0, 0, "sackhlpl",
166 1.1.1.1 martti NULL);
167 1.1.1.1 martti pool_sethardlimit(&sackhl_pool, tcp_sackhole_limit, NULL, 0);
168 1.1.1.1 martti #endif /* TCP_SACK */
169 1.1.1.1 martti in_pcbinit(&tcbtable, tcbhashsize);
170 1.1.1.1 martti
171 1.1.1.1 martti #ifdef INET6
172 1.1.1.1 martti /*
173 1.1.1.1 martti * Since sizeof(struct ip6_hdr) > sizeof(struct ip), we
174 1.1.1.1 martti * do max length checks/computations only on the former.
175 1.1.1.1 martti */
176 1.1.1.1 martti if (max_protohdr < (sizeof(struct ip6_hdr) + sizeof(struct tcphdr)))
177 1.1.1.1 martti max_protohdr = (sizeof(struct ip6_hdr) + sizeof(struct tcphdr));
178 1.1.1.1 martti if ((max_linkhdr + sizeof(struct ip6_hdr) + sizeof(struct tcphdr)) >
179 1.1.1.1 martti MHLEN)
180 1.1.1.1 martti panic("tcp_init");
181 1.1.1.1 martti
182 1.1.1.1 martti icmp6_mtudisc_callback_register(tcp6_mtudisc_callback);
183 1.1.1.1 martti #endif /* INET6 */
184 1.1.1.1 martti
185 1.1.1.1 martti /* Initialize the compressed state engine. */
186 1.1.1.1 martti syn_cache_init();
187 1.1.1.1 martti
188 1.1.1.1 martti /* Initialize timer state. */
189 1.1.1.1 martti tcp_timer_init();
190 1.1.1.1 martti }
191 1.1.1.1 martti
192 1.1.1.1 martti /*
193 1.1.1.1 martti * Create template to be used to send tcp packets on a connection.
194 1.1.1.1 martti * Call after host entry created, allocates an mbuf and fills
195 1.1.1.1 martti * in a skeletal tcp/ip header, minimizing the amount of work
196 1.1.1.1 martti * necessary when the connection is used.
197 1.1.1.1 martti *
198 1.1.1.1 martti * To support IPv6 in addition to IPv4 and considering that the sizes of
199 1.1.1.1 martti * the IPv4 and IPv6 headers are not the same, we now use a separate pointer
200 1.1.1.1 martti * for the TCP header. Also, we made the former tcpiphdr header pointer
201 1.1.1.1 martti * into just an IP overlay pointer, with casting as appropriate for v6. rja
202 1.1.1.1 martti */
203 1.1.1.1 martti struct mbuf *
204 1.1.1.1 martti tcp_template(tp)
205 1.1.1.1 martti struct tcpcb *tp;
206 1.1.1.1 martti {
207 1.1.1.1 martti struct inpcb *inp = tp->t_inpcb;
208 1.1.1.1 martti struct mbuf *m;
209 1.1.1.1 martti struct tcphdr *th;
210 1.1.1.1 martti
211 1.1.1.1 martti if ((m = tp->t_template) == 0) {
212 1.1.1.1 martti m = m_get(M_DONTWAIT, MT_HEADER);
213 1.1.1.1 martti if (m == NULL)
214 1.1.1.1 martti return (0);
215 1.1.1.1 martti
216 1.1.1.1 martti switch (tp->pf) {
217 1.1.1.1 martti case 0: /*default to PF_INET*/
218 1.1.1.1 martti #ifdef INET
219 1.1.1.1 martti case AF_INET:
220 1.1.1.1 martti m->m_len = sizeof(struct ip);
221 1.1.1.1 martti break;
222 1.1.1.1 martti #endif /* INET */
223 1.1.1.1 martti #ifdef INET6
224 1.1.1.1 martti case AF_INET6:
225 1.1.1.1 martti m->m_len = sizeof(struct ip6_hdr);
226 1.1.1.1 martti break;
227 1.1.1.1 martti #endif /* INET6 */
228 1.1.1.1 martti }
229 1.1.1.1 martti m->m_len += sizeof (struct tcphdr);
230 1.1.1.1 martti
231 1.1.1.1 martti /*
232 1.1.1.1 martti * The link header, network header, TCP header, and TCP options
233 1.1.1.1 martti * all must fit in this mbuf. For now, assume the worst case of
234 1.1.1.1 martti * TCP options size. Eventually, compute this from tp flags.
235 1.1.1.1 martti */
236 1.1.1.1 martti if (m->m_len + MAX_TCPOPTLEN + max_linkhdr >= MHLEN) {
237 1.1.1.1 martti MCLGET(m, M_DONTWAIT);
238 1.1.1.1 martti if ((m->m_flags & M_EXT) == 0) {
239 1.1.1.1 martti m_free(m);
240 1.1.1.1 martti return (0);
241 1.1.1.1 martti }
242 1.1.1.1 martti }
243 1.1.1.1 martti }
244 1.1.1.1 martti
245 1.1.1.1 martti switch(tp->pf) {
246 1.1.1.1 martti #ifdef INET
247 1.1.1.1 martti case AF_INET:
248 1.1.1.1 martti {
249 1.1.1.1 martti struct ipovly *ipovly;
250 1.1.1.1 martti
251 1.1.1.1 martti ipovly = mtod(m, struct ipovly *);
252 1.1.1.1 martti
253 1.1.1.1 martti bzero(ipovly->ih_x1, sizeof ipovly->ih_x1);
254 1.1.1.1 martti ipovly->ih_pr = IPPROTO_TCP;
255 1.1.1.1 martti ipovly->ih_len = htons(sizeof (struct tcphdr));
256 1.1.1.1 martti ipovly->ih_src = inp->inp_laddr;
257 1.1.1.1 martti ipovly->ih_dst = inp->inp_faddr;
258 1.1.1.1 martti
259 1.1.1.1 martti th = (struct tcphdr *)(mtod(m, caddr_t) +
260 1.1.1.1 martti sizeof(struct ip));
261 1.1.1.1 martti th->th_sum = in_cksum_phdr(ipovly->ih_src.s_addr,
262 1.1.1.1 martti ipovly->ih_dst.s_addr,
263 1.1.1.1 martti htons(sizeof (struct tcphdr) + IPPROTO_TCP));
264 1.1.1.1 martti }
265 1.1.1.1 martti break;
266 1.1.1.1 martti #endif /* INET */
267 1.1.1.1 martti #ifdef INET6
268 1.1.1.1 martti case AF_INET6:
269 1.1.1.1 martti {
270 1.1.1.1 martti struct ip6_hdr *ip6;
271 1.1.1.1 martti
272 1.1.1.1 martti ip6 = mtod(m, struct ip6_hdr *);
273 1.1.1.1 martti
274 1.1.1.1 martti ip6->ip6_src = inp->inp_laddr6;
275 1.1.1.1 martti ip6->ip6_dst = inp->inp_faddr6;
276 1.1.1.1 martti ip6->ip6_flow = htonl(0x60000000) |
277 1.1.1.1 martti (inp->inp_flowinfo & IPV6_FLOWLABEL_MASK);
278 1.1.1.1 martti
279 1.1.1.1 martti ip6->ip6_nxt = IPPROTO_TCP;
280 1.1.1.1 martti ip6->ip6_plen = htons(sizeof(struct tcphdr)); /*XXX*/
281 1.1.1.1 martti ip6->ip6_hlim = in6_selecthlim(inp, NULL); /*XXX*/
282 1.1.1.1 martti
283 1.1.1.1 martti th = (struct tcphdr *)(mtod(m, caddr_t) +
284 1.1.1.1 martti sizeof(struct ip6_hdr));
285 1.1.1.1 martti th->th_sum = 0;
286 1.1.1.1 martti }
287 1.1.1.1 martti break;
288 1.1.1.1 martti #endif /* INET6 */
289 1.1.1.1 martti }
290 1.1.1.1 martti
291 1.1.1.1 martti th->th_sport = inp->inp_lport;
292 1.1.1.1 martti th->th_dport = inp->inp_fport;
293 1.1.1.1 martti th->th_seq = 0;
294 1.1.1.1 martti th->th_ack = 0;
295 1.1.1.1 martti th->th_x2 = 0;
296 1.1.1.1 martti th->th_off = 5;
297 1.1.1.1 martti th->th_flags = 0;
298 1.1.1.1 martti th->th_win = 0;
299 1.1.1.1 martti th->th_urp = 0;
300 1.1.1.1 martti return (m);
301 1.1.1.1 martti }
302 1.1.1.1 martti
303 1.1.1.1 martti /*
304 1.1.1.1 martti * Send a single message to the TCP at address specified by
305 1.1.1.1 martti * the given TCP/IP header. If m == 0, then we make a copy
306 1.1.1.1 martti * of the tcpiphdr at ti and send directly to the addressed host.
307 1.1.1.1 martti * This is used to force keep alive messages out using the TCP
308 1.1.1.1 martti * template for a connection tp->t_template. If flags are given
309 1.1.1.1 martti * then we send a message back to the TCP which originated the
310 1.1.1.1 martti * segment ti, and discard the mbuf containing it and any other
311 1.1.1.1 martti * attached mbufs.
312 1.1.1.1 martti *
313 1.1.1.1 martti * In any case the ack and sequence number of the transmitted
314 1.1.1.1 martti * segment are as specified by the parameters.
315 1.1.1.1 martti */
316 1.1.1.1 martti #ifdef INET6
317 1.1.1.1 martti /* This function looks hairy, because it was so IPv4-dependent. */
318 1.1.1.1 martti #endif /* INET6 */
319 1.1.1.1 martti void
320 1.1.1.1 martti tcp_respond(tp, template, m, ack, seq, flags)
321 1.1.1.1 martti struct tcpcb *tp;
322 1.1.1.1 martti caddr_t template;
323 1.1.1.1 martti struct mbuf *m;
324 1.1.1.1 martti tcp_seq ack, seq;
325 1.1.1.1 martti int flags;
326 1.1.1.1 martti {
327 1.1.1.1 martti int tlen;
328 1.1.1.1 martti int win = 0;
329 1.1.1.1 martti struct route *ro = 0;
330 1.1.1.1 martti struct tcphdr *th;
331 1.1.1.1 martti struct tcpiphdr *ti = (struct tcpiphdr *)template;
332 1.1.1.1 martti int af; /* af on wire */
333 1.1.1.1 martti
334 1.1.1.1 martti if (tp) {
335 1.1.1.1 martti win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
336 1.1.1.1 martti /*
337 1.1.1.1 martti * If this is called with an unconnected
338 1.1.1.1 martti * socket/tp/pcb (tp->pf is 0), we lose.
339 1.1.1.1 martti */
340 1.1.1.1 martti af = tp->pf;
341 1.1.1.1 martti
342 1.1.1.1 martti /*
343 1.1.1.1 martti * The route/route6 distinction is meaningless
344 1.1.1.1 martti * unless you're allocating space or passing parameters.
345 1.1.1.1 martti */
346 1.1.1.1 martti ro = &tp->t_inpcb->inp_route;
347 1.1.1.1 martti } else
348 1.1.1.1 martti af = (((struct ip *)ti)->ip_v == 6) ? AF_INET6 : AF_INET;
349 1.1.1.1 martti if (m == 0) {
350 1.1.1.1 martti m = m_gethdr(M_DONTWAIT, MT_HEADER);
351 1.1.1.1 martti if (m == NULL)
352 1.1.1.1 martti return;
353 1.1.1.1 martti #ifdef TCP_COMPAT_42
354 1.1.1.1 martti tlen = 1;
355 1.1.1.1 martti #else
356 1.1.1.1 martti tlen = 0;
357 1.1.1.1 martti #endif
358 1.1.1.1 martti m->m_data += max_linkhdr;
359 1.1.1.1 martti switch (af) {
360 1.1.1.1 martti #ifdef INET6
361 1.1.1.1 martti case AF_INET6:
362 1.1.1.1 martti bcopy(ti, mtod(m, caddr_t), sizeof(struct tcphdr) +
363 1.1.1.1 martti sizeof(struct ip6_hdr));
364 1.1.1.1 martti break;
365 1.1.1.1 martti #endif /* INET6 */
366 1.1.1.1 martti case AF_INET:
367 1.1.1.1 martti bcopy(ti, mtod(m, caddr_t), sizeof(struct tcphdr) +
368 1.1.1.1 martti sizeof(struct ip));
369 1.1.1.1 martti break;
370 1.1.1.1 martti }
371 1.1.1.1 martti
372 1.1.1.1 martti ti = mtod(m, struct tcpiphdr *);
373 1.1.1.1 martti flags = TH_ACK;
374 1.1.1.1 martti } else {
375 1.1.1.1 martti m_freem(m->m_next);
376 1.1.1.1 martti m->m_next = 0;
377 1.1.1.1 martti m->m_data = (caddr_t)ti;
378 1.1.1.1 martti tlen = 0;
379 1.1.1.1 martti #define xchg(a,b,type) do { type t; t=a; a=b; b=t; } while (0)
380 1.1.1.1 martti switch (af) {
381 1.1.1.1 martti #ifdef INET6
382 1.1.1.1 martti case AF_INET6:
383 1.1.1.1 martti m->m_len = sizeof(struct tcphdr) + sizeof(struct ip6_hdr);
384 1.1.1.1 martti xchg(((struct ip6_hdr *)ti)->ip6_dst,
385 1.1.1.1 martti ((struct ip6_hdr *)ti)->ip6_src, struct in6_addr);
386 1.1.1.1 martti th = (void *)((caddr_t)ti + sizeof(struct ip6_hdr));
387 1.1.1.1 martti break;
388 1.1.1.1 martti #endif /* INET6 */
389 1.1.1.1 martti case AF_INET:
390 1.1.1.1 martti m->m_len = sizeof (struct tcpiphdr);
391 1.1.1.1 martti xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t);
392 1.1.1.1 martti th = (void *)((caddr_t)ti + sizeof(struct ip));
393 1.1.1.1 martti break;
394 1.1.1.1 martti }
395 1.1.1.1 martti xchg(th->th_dport, th->th_sport, u_int16_t);
396 1.1.1.1 martti #undef xchg
397 1.1.1.1 martti }
398 1.1.1.1 martti switch (af) {
399 1.1.1.1 martti #ifdef INET6
400 1.1.1.1 martti case AF_INET6:
401 1.1.1.1 martti tlen += sizeof(struct tcphdr) + sizeof(struct ip6_hdr);
402 1.1.1.1 martti th = (struct tcphdr *)((caddr_t)ti + sizeof(struct ip6_hdr));
403 1.1.1.1 martti break;
404 1.1.1.1 martti #endif /* INET6 */
405 1.1.1.1 martti case AF_INET:
406 1.1.1.1 martti ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + tlen));
407 1.1.1.1 martti tlen += sizeof (struct tcpiphdr);
408 1.1.1.1 martti th = (struct tcphdr *)((caddr_t)ti + sizeof(struct ip));
409 1.1.1.1 martti break;
410 1.1.1.1 martti }
411 1.1.1.1 martti
412 1.1.1.1 martti m->m_len = tlen;
413 1.1.1.1 martti m->m_pkthdr.len = tlen;
414 1.1.1.1 martti m->m_pkthdr.rcvif = (struct ifnet *) 0;
415 1.1.1.1 martti th->th_seq = htonl(seq);
416 1.1.1.1 martti th->th_ack = htonl(ack);
417 1.1.1.1 martti th->th_x2 = 0;
418 1.1.1.1 martti th->th_off = sizeof (struct tcphdr) >> 2;
419 1.1.1.1 martti th->th_flags = flags;
420 1.1.1.1 martti if (tp)
421 1.1.1.1 martti win >>= tp->rcv_scale;
422 1.1.1.1 martti if (win > TCP_MAXWIN)
423 1.1.1.1 martti win = TCP_MAXWIN;
424 1.1.1.1 martti th->th_win = htons((u_int16_t)win);
425 1.1.1.1 martti th->th_urp = 0;
426 1.1.1.1 martti
427 1.1.1.1 martti switch (af) {
428 1.1.1.1 martti #ifdef INET6
429 1.1.1.1 martti case AF_INET6:
430 1.1.1.1 martti ((struct ip6_hdr *)ti)->ip6_flow = htonl(0x60000000);
431 1.1.1.1 martti ((struct ip6_hdr *)ti)->ip6_nxt = IPPROTO_TCP;
432 1.1.1.1 martti ((struct ip6_hdr *)ti)->ip6_hlim =
433 1.1.1.1 martti in6_selecthlim(tp ? tp->t_inpcb : NULL, NULL); /*XXX*/
434 1.1.1.1 martti ((struct ip6_hdr *)ti)->ip6_plen = tlen - sizeof(struct ip6_hdr);
435 1.1.1.1 martti th->th_sum = 0;
436 1.1.1.1 martti th->th_sum = in6_cksum(m, IPPROTO_TCP,
437 1.1.1.1 martti sizeof(struct ip6_hdr), ((struct ip6_hdr *)ti)->ip6_plen);
438 1.1.1.1 martti HTONS(((struct ip6_hdr *)ti)->ip6_plen);
439 1.1.1.1 martti ip6_output(m, tp ? tp->t_inpcb->inp_outputopts6 : NULL,
440 1.1.1.1 martti (struct route_in6 *)ro, 0, NULL, NULL,
441 1.1.1.1 martti tp ? tp->t_inpcb : NULL);
442 1.1.1.1 martti break;
443 1.1.1.1 martti #endif /* INET6 */
444 1.1.1.1 martti case AF_INET:
445 1.1.1.1 martti bzero(ti->ti_x1, sizeof ti->ti_x1);
446 1.1.1.1 martti ti->ti_len = htons((u_short)tlen - sizeof(struct ip));
447 1.1.1.1 martti
448 1.1.1.1 martti /*
449 1.1.1.1 martti * There's no point deferring to hardware checksum processing
450 1.1.1.1 martti * here, as we only send a minimal TCP packet whose checksum
451 1.1.1.1 martti * we need to compute in any case.
452 1.1.1.1 martti */
453 1.1.1.1 martti th->th_sum = 0;
454 1.1.1.1 martti th->th_sum = in_cksum(m, tlen);
455 1.1.1.1 martti ((struct ip *)ti)->ip_len = htons(tlen);
456 1.1.1.1 martti ((struct ip *)ti)->ip_ttl = ip_defttl;
457 1.1.1.1 martti ip_output(m, (void *)NULL, ro, ip_mtudisc ? IP_MTUDISC : 0,
458 1.1.1.1 martti (void *)NULL, tp ? tp->t_inpcb : (void *)NULL);
459 1.1.1.1 martti }
460 1.1.1.1 martti }
461 1.1.1.1 martti
462 1.1.1.1 martti /*
463 1.1.1.1 martti * Create a new TCP control block, making an
464 1.1.1.1 martti * empty reassembly queue and hooking it to the argument
465 1.1.1.1 martti * protocol control block.
466 1.1.1.1 martti */
467 1.1.1.1 martti struct tcpcb *
468 1.1.1.1 martti tcp_newtcpcb(struct inpcb *inp)
469 1.1.1.1 martti {
470 1.1.1.1 martti struct tcpcb *tp;
471 1.1.1.1 martti int i;
472 1.1.1.1 martti
473 1.1.1.1 martti tp = pool_get(&tcpcb_pool, PR_NOWAIT);
474 1.1.1.1 martti if (tp == NULL)
475 1.1.1.1 martti return ((struct tcpcb *)0);
476 1.1.1.1 martti bzero((char *) tp, sizeof(struct tcpcb));
477 1.1.1.1 martti TAILQ_INIT(&tp->t_segq);
478 1.1.1.1 martti tp->t_maxseg = tcp_mssdflt;
479 1.1.1.1 martti tp->t_maxopd = 0;
480 1.1.1.1 martti
481 1.1.1.1 martti TCP_INIT_DELACK(tp);
482 1.1.1.1 martti for (i = 0; i < TCPT_NTIMERS; i++)
483 1.1.1.1 martti TCP_TIMER_INIT(tp, i);
484 1.1.1.1 martti timeout_set(&tp->t_reap_to, tcp_reaper, tp);
485 1.1.1.1 martti
486 1.1.1.1 martti #ifdef TCP_SACK
487 1.1.1.1 martti tp->sack_enable = tcp_do_sack;
488 1.1.1.1 martti #endif
489 1.1.1.1 martti tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
490 1.1.1.1 martti tp->t_inpcb = inp;
491 1.1.1.1 martti /*
492 1.1.1.1 martti * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
493 1.1.1.1 martti * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives
494 1.1.1.1 martti * reasonable initial retransmit time.
495 1.1.1.1 martti */
496 1.1.1.1 martti tp->t_srtt = TCPTV_SRTTBASE;
497 1.1.1.1 martti tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ <<
498 1.1.1.1 martti (TCP_RTTVAR_SHIFT + TCP_RTT_BASE_SHIFT - 1);
499 1.1.1.1 martti tp->t_rttmin = TCPTV_MIN;
500 1.1.1.1 martti TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
501 1.1.1.1 martti TCPTV_MIN, TCPTV_REXMTMAX);
502 1.1.1.1 martti tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
503 1.1.1.1 martti tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
504 1.1.1.1 martti
505 1.1.1.1 martti tp->t_pmtud_mtu_sent = 0;
506 1.1.1.1 martti tp->t_pmtud_mss_acked = 0;
507 1.1.1.1 martti
508 1.1.1.1 martti #ifdef INET6
509 1.1.1.1 martti /* we disallow IPv4 mapped address completely. */
510 1.1.1.1 martti if ((inp->inp_flags & INP_IPV6) == 0)
511 1.1.1.1 martti tp->pf = PF_INET;
512 1.1.1.1 martti else
513 1.1.1.1 martti tp->pf = PF_INET6;
514 1.1.1.1 martti #else
515 1.1.1.1 martti tp->pf = PF_INET;
516 1.1.1.1 martti #endif
517 1.1.1.1 martti
518 1.1.1.1 martti #ifdef INET6
519 1.1.1.1 martti if (inp->inp_flags & INP_IPV6)
520 1.1.1.1 martti inp->inp_ipv6.ip6_hlim = ip6_defhlim;
521 1.1.1.1 martti else
522 1.1.1.1 martti #endif /* INET6 */
523 1.1.1.1 martti inp->inp_ip.ip_ttl = ip_defttl;
524 1.1.1.1 martti
525 1.1.1.1 martti inp->inp_ppcb = (caddr_t)tp;
526 1.1.1.1 martti return (tp);
527 1.1.1.1 martti }
528 1.1.1.1 martti
529 1.1.1.1 martti /*
530 1.1.1.1 martti * Drop a TCP connection, reporting
531 1.1.1.1 martti * the specified error. If connection is synchronized,
532 1.1.1.1 martti * then send a RST to peer.
533 1.1.1.1 martti */
534 1.1.1.1 martti struct tcpcb *
535 1.1.1.1 martti tcp_drop(tp, errno)
536 1.1.1.1 martti struct tcpcb *tp;
537 1.1.1.1 martti int errno;
538 1.1.1.1 martti {
539 1.1.1.1 martti struct socket *so = tp->t_inpcb->inp_socket;
540 1.1.1.1 martti
541 1.1.1.1 martti if (TCPS_HAVERCVDSYN(tp->t_state)) {
542 1.1.1.1 martti tp->t_state = TCPS_CLOSED;
543 1.1.1.1 martti (void) tcp_output(tp);
544 1.1.1.1 martti tcpstat.tcps_drops++;
545 1.1.1.1 martti } else
546 1.1.1.1 martti tcpstat.tcps_conndrops++;
547 1.1.1.1 martti if (errno == ETIMEDOUT && tp->t_softerror)
548 1.1.1.1 martti errno = tp->t_softerror;
549 1.1.1.1 martti so->so_error = errno;
550 1.1.1.1 martti return (tcp_close(tp));
551 1.1.1.1 martti }
552 1.1.1.1 martti
553 1.1.1.1 martti /*
554 1.1.1.1 martti * Close a TCP control block:
555 1.1.1.1 martti * discard all space held by the tcp
556 1.1.1.1 martti * discard internet protocol block
557 1.1.1.1 martti * wake up any sleepers
558 1.1.1.1 martti */
559 1.1.1.1 martti struct tcpcb *
560 1.1.1.1 martti tcp_close(struct tcpcb *tp)
561 1.1.1.1 martti {
562 1.1.1.1 martti struct inpcb *inp = tp->t_inpcb;
563 1.1.1.1 martti struct socket *so = inp->inp_socket;
564 1.1.1.1 martti #ifdef TCP_SACK
565 1.1.1.1 martti struct sackhole *p, *q;
566 1.1.1.1 martti #endif
567 1.1.1.1 martti
568 1.1.1.1 martti /* free the reassembly queue, if any */
569 1.1.1.1 martti tcp_reass_lock(tp);
570 1.1.1.1 martti tcp_freeq(tp);
571 1.1.1.1 martti tcp_reass_unlock(tp);
572 1.1.1.1 martti
573 1.1.1.1 martti tcp_canceltimers(tp);
574 1.1.1.1 martti TCP_CLEAR_DELACK(tp);
575 1.1.1.1 martti syn_cache_cleanup(tp);
576 1.1.1.1 martti
577 1.1.1.1 martti #ifdef TCP_SACK
578 1.1.1.1 martti /* Free SACK holes. */
579 1.1.1.1 martti q = p = tp->snd_holes;
580 1.1.1.1 martti while (p != 0) {
581 1.1.1.1 martti q = p->next;
582 1.1.1.1 martti pool_put(&sackhl_pool, p);
583 1.1.1.1 martti p = q;
584 1.1.1.1 martti }
585 1.1.1.1 martti #endif
586 1.1.1.1 martti if (tp->t_template)
587 1.1.1.1 martti (void) m_free(tp->t_template);
588 1.1.1.1 martti
589 1.1.1.1 martti tp->t_flags |= TF_DEAD;
590 1.1.1.1 martti timeout_add(&tp->t_reap_to, 0);
591 1.1.1.1 martti
592 1.1.1.1 martti inp->inp_ppcb = 0;
593 1.1.1.1 martti soisdisconnected(so);
594 1.1.1.1 martti in_pcbdetach(inp);
595 1.1.1.1 martti return ((struct tcpcb *)0);
596 1.1.1.1 martti }
597 1.1.1.1 martti
598 1.1.1.1 martti void
599 1.1.1.1 martti tcp_reaper(void *arg)
600 1.1.1.1 martti {
601 1.1.1.1 martti struct tcpcb *tp = arg;
602 1.1.1.1 martti int s;
603 1.1.1.1 martti
604 1.1.1.1 martti s = splsoftnet();
605 1.1.1.1 martti pool_put(&tcpcb_pool, tp);
606 1.1.1.1 martti splx(s);
607 1.1.1.1 martti tcpstat.tcps_closed++;
608 1.1.1.1 martti }
609 1.1.1.1 martti
610 1.1.1.1 martti int
611 1.1.1.1 martti tcp_freeq(struct tcpcb *tp)
612 1.1.1.1 martti {
613 1.1.1.1 martti struct tcpqent *qe;
614 1.1.1.1 martti int rv = 0;
615 1.1.1.1 martti
616 1.1.1.1 martti while ((qe = TAILQ_FIRST(&tp->t_segq)) != NULL) {
617 1.1.1.1 martti TAILQ_REMOVE(&tp->t_segq, qe, tcpqe_q);
618 1.1.1.1 martti m_freem(qe->tcpqe_m);
619 1.1.1.1 martti pool_put(&tcpqe_pool, qe);
620 1.1.1.1 martti rv = 1;
621 1.1.1.1 martti }
622 1.1.1.1 martti return (rv);
623 1.1.1.1 martti }
624 1.1.1.1 martti
625 1.1.1.1 martti void
626 1.1.1.1 martti tcp_drain()
627 1.1.1.1 martti {
628 1.1.1.1 martti struct inpcb *inp;
629 1.1.1.1 martti
630 1.1.1.1 martti /* called at splnet() */
631 1.1.1.1 martti CIRCLEQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue) {
632 1.1.1.1 martti struct tcpcb *tp = (struct tcpcb *)inp->inp_ppcb;
633 1.1.1.1 martti
634 1.1.1.1 martti if (tp != NULL) {
635 1.1.1.1 martti if (tcp_reass_lock_try(tp) == 0)
636 1.1.1.1 martti continue;
637 1.1.1.1 martti if (tcp_freeq(tp))
638 1.1.1.1 martti tcpstat.tcps_conndrained++;
639 1.1.1.1 martti tcp_reass_unlock(tp);
640 1.1.1.1 martti }
641 1.1.1.1 martti }
642 1.1.1.1 martti }
643 1.1.1.1 martti
644 1.1.1.1 martti /*
645 1.1.1.1 martti * Compute proper scaling value for receiver window from buffer space
646 1.1.1.1 martti */
647 1.1.1.1 martti
648 1.1.1.1 martti void
649 1.1.1.1 martti tcp_rscale(struct tcpcb *tp, u_long hiwat)
650 1.1.1.1 martti {
651 1.1.1.1 martti tp->request_r_scale = 0;
652 1.1.1.1 martti while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
653 1.1.1.1 martti TCP_MAXWIN << tp->request_r_scale < hiwat)
654 1.1.1.1 martti tp->request_r_scale++;
655 1.1.1.1 martti }
656 1.1.1.1 martti
657 1.1.1.1 martti /*
658 1.1.1.1 martti * Notify a tcp user of an asynchronous error;
659 1.1.1.1 martti * store error as soft error, but wake up user
660 1.1.1.1 martti * (for now, won't do anything until can select for soft error).
661 1.1.1.1 martti */
662 1.1.1.1 martti void
663 1.1.1.1 martti tcp_notify(inp, error)
664 1.1.1.1 martti struct inpcb *inp;
665 1.1.1.1 martti int error;
666 1.1.1.1 martti {
667 1.1.1.1 martti struct tcpcb *tp = (struct tcpcb *)inp->inp_ppcb;
668 1.1.1.1 martti struct socket *so = inp->inp_socket;
669 1.1.1.1 martti
670 1.1.1.1 martti /*
671 1.1.1.1 martti * Ignore some errors if we are hooked up.
672 1.1.1.1 martti * If connection hasn't completed, has retransmitted several times,
673 1.1.1.1 martti * and receives a second error, give up now. This is better
674 1.1.1.1 martti * than waiting a long time to establish a connection that
675 1.1.1.1 martti * can never complete.
676 1.1.1.1 martti */
677 1.1.1.1 martti if (tp->t_state == TCPS_ESTABLISHED &&
678 1.1.1.1 martti (error == EHOSTUNREACH || error == ENETUNREACH ||
679 1.1.1.1 martti error == EHOSTDOWN)) {
680 1.1.1.1 martti return;
681 1.1.1.1 martti } else if (TCPS_HAVEESTABLISHED(tp->t_state) == 0 &&
682 1.1.1.1 martti tp->t_rxtshift > 3 && tp->t_softerror)
683 1.1.1.1 martti so->so_error = error;
684 1.1.1.1 martti else
685 1.1.1.1 martti tp->t_softerror = error;
686 1.1.1.1 martti wakeup((caddr_t) &so->so_timeo);
687 1.1.1.1 martti sorwakeup(so);
688 1.1.1.1 martti sowwakeup(so);
689 1.1.1.1 martti }
690 1.1.1.1 martti
691 1.1.1.1 martti #ifdef INET6
692 1.1.1.1 martti void
693 1.1.1.1 martti tcp6_ctlinput(cmd, sa, d)
694 1.1.1.1 martti int cmd;
695 1.1.1.1 martti struct sockaddr *sa;
696 1.1.1.1 martti void *d;
697 1.1.1.1 martti {
698 1.1.1.1 martti struct tcphdr th;
699 1.1.1.1 martti struct tcpcb *tp;
700 1.1.1.1 martti void (*notify)(struct inpcb *, int) = tcp_notify;
701 1.1.1.1 martti struct ip6_hdr *ip6;
702 1.1.1.1 martti const struct sockaddr_in6 *sa6_src = NULL;
703 1.1.1.1 martti struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
704 1.1.1.1 martti struct inpcb *inp;
705 1.1.1.1 martti struct mbuf *m;
706 1.1.1.1 martti tcp_seq seq;
707 1.1.1.1 martti int off;
708 1.1.1.1 martti struct {
709 1.1.1.1 martti u_int16_t th_sport;
710 1.1.1.1 martti u_int16_t th_dport;
711 1.1.1.1 martti u_int32_t th_seq;
712 1.1.1.1 martti } *thp;
713 1.1.1.1 martti
714 1.1.1.1 martti if (sa->sa_family != AF_INET6 ||
715 1.1.1.1 martti sa->sa_len != sizeof(struct sockaddr_in6) ||
716 1.1.1.1 martti IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr) ||
717 1.1.1.1 martti IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
718 1.1.1.1 martti return;
719 1.1.1.1 martti if ((unsigned)cmd >= PRC_NCMDS)
720 1.1.1.1 martti return;
721 1.1.1.1 martti else if (cmd == PRC_QUENCH) {
722 1.1.1.1 martti /*
723 1.1.1.1 martti * Don't honor ICMP Source Quench messages meant for
724 1.1.1.1 martti * TCP connections.
725 1.1.1.1 martti */
726 1.1.1.1 martti /* XXX there's no PRC_QUENCH in IPv6 */
727 1.1.1.1 martti return;
728 1.1.1.1 martti } else if (PRC_IS_REDIRECT(cmd))
729 1.1.1.1 martti notify = in_rtchange, d = NULL;
730 1.1.1.1 martti else if (cmd == PRC_MSGSIZE)
731 1.1.1.1 martti ; /* special code is present, see below */
732 1.1.1.1 martti else if (cmd == PRC_HOSTDEAD)
733 1.1.1.1 martti d = NULL;
734 1.1.1.1 martti else if (inet6ctlerrmap[cmd] == 0)
735 1.1.1.1 martti return;
736 1.1.1.1 martti
737 1.1.1.1 martti /* if the parameter is from icmp6, decode it. */
738 1.1.1.1 martti if (d != NULL) {
739 1.1.1.1 martti struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
740 1.1.1.1 martti m = ip6cp->ip6c_m;
741 1.1.1.1 martti ip6 = ip6cp->ip6c_ip6;
742 1.1.1.1 martti off = ip6cp->ip6c_off;
743 1.1.1.1 martti sa6_src = ip6cp->ip6c_src;
744 1.1.1.1 martti } else {
745 1.1.1.1 martti m = NULL;
746 1.1.1.1 martti ip6 = NULL;
747 1.1.1.1 martti sa6_src = &sa6_any;
748 1.1.1.1 martti }
749 1.1.1.1 martti
750 1.1.1.1 martti if (ip6) {
751 1.1.1.1 martti /*
752 1.1.1.1 martti * XXX: We assume that when ip6 is non NULL,
753 1.1.1.1 martti * M and OFF are valid.
754 1.1.1.1 martti */
755 1.1.1.1 martti
756 1.1.1.1 martti /* check if we can safely examine src and dst ports */
757 1.1.1.1 martti if (m->m_pkthdr.len < off + sizeof(*thp))
758 1.1.1.1 martti return;
759 1.1.1.1 martti
760 1.1.1.1 martti bzero(&th, sizeof(th));
761 1.1.1.1 martti #ifdef DIAGNOSTIC
762 1.1.1.1 martti if (sizeof(*thp) > sizeof(th))
763 1.1.1.1 martti panic("assumption failed in tcp6_ctlinput");
764 1.1.1.1 martti #endif
765 1.1.1.1 martti m_copydata(m, off, sizeof(*thp), (caddr_t)&th);
766 1.1.1.1 martti
767 1.1.1.1 martti /*
768 1.1.1.1 martti * Check to see if we have a valid TCP connection
769 1.1.1.1 martti * corresponding to the address in the ICMPv6 message
770 1.1.1.1 martti * payload.
771 1.1.1.1 martti */
772 1.1.1.1 martti inp = in6_pcbhashlookup(&tcbtable, &sa6->sin6_addr,
773 1.1.1.1 martti th.th_dport, (struct in6_addr *)&sa6_src->sin6_addr,
774 1.1.1.1 martti th.th_sport);
775 1.1.1.1 martti if (cmd == PRC_MSGSIZE) {
776 1.1.1.1 martti /*
777 1.1.1.1 martti * Depending on the value of "valid" and routing table
778 1.1.1.1 martti * size (mtudisc_{hi,lo}wat), we will:
779 1.1.1.1 martti * - recalcurate the new MTU and create the
780 1.1.1.1 martti * corresponding routing entry, or
781 1.1.1.1 martti * - ignore the MTU change notification.
782 1.1.1.1 martti */
783 1.1.1.1 martti icmp6_mtudisc_update((struct ip6ctlparam *)d, inp != NULL);
784 1.1.1.1 martti return;
785 1.1.1.1 martti }
786 1.1.1.1 martti if (inp) {
787 1.1.1.1 martti seq = ntohl(th.th_seq);
788 1.1.1.1 martti if (inp->inp_socket &&
789 1.1.1.1 martti (tp = intotcpcb(inp)) &&
790 1.1.1.1 martti SEQ_GEQ(seq, tp->snd_una) &&
791 1.1.1.1 martti SEQ_LT(seq, tp->snd_max))
792 1.1.1.1 martti notify(inp, inet6ctlerrmap[cmd]);
793 1.1.1.1 martti } else if (syn_cache_count &&
794 1.1.1.1 martti (inet6ctlerrmap[cmd] == EHOSTUNREACH ||
795 1.1.1.1 martti inet6ctlerrmap[cmd] == ENETUNREACH ||
796 1.1.1.1 martti inet6ctlerrmap[cmd] == EHOSTDOWN))
797 1.1.1.1 martti syn_cache_unreach((struct sockaddr *)sa6_src,
798 1.1.1.1 martti sa, &th);
799 1.1.1.1 martti } else {
800 1.1.1.1 martti (void) in6_pcbnotify(&tcbtable, sa, 0,
801 1.1.1.1 martti (struct sockaddr *)sa6_src, 0, cmd, NULL, notify);
802 1.1.1.1 martti }
803 1.1.1.1 martti }
804 1.1.1.1 martti #endif
805 1.1.1.1 martti
806 1.1.1.1 martti void *
807 1.1.1.1 martti tcp_ctlinput(cmd, sa, v)
808 1.1.1.1 martti int cmd;
809 1.1.1.1 martti struct sockaddr *sa;
810 1.1.1.1 martti void *v;
811 1.1.1.1 martti {
812 1.1.1.1 martti struct ip *ip = v;
813 1.1.1.1 martti struct tcphdr *th;
814 1.1.1.1 martti struct tcpcb *tp;
815 1.1.1.1 martti struct inpcb *inp;
816 1.1.1.1 martti struct in_addr faddr;
817 1.1.1.1 martti tcp_seq seq;
818 1.1.1.1 martti u_int mtu;
819 1.1.1.1 martti extern int inetctlerrmap[];
820 1.1.1.1 martti void (*notify)(struct inpcb *, int) = tcp_notify;
821 1.1.1.1 martti int errno;
822 1.1.1.1 martti
823 1.1.1.1 martti if (sa->sa_family != AF_INET)
824 1.1.1.1 martti return NULL;
825 1.1.1.1 martti faddr = satosin(sa)->sin_addr;
826 1.1.1.1 martti if (faddr.s_addr == INADDR_ANY)
827 1.1.1.1 martti return NULL;
828 1.1.1.1 martti
829 1.1.1.1 martti if ((unsigned)cmd >= PRC_NCMDS)
830 1.1.1.1 martti return NULL;
831 1.1.1.1 martti errno = inetctlerrmap[cmd];
832 1.1.1.1 martti if (cmd == PRC_QUENCH)
833 1.1.1.1 martti /*
834 1.1.1.1 martti * Don't honor ICMP Source Quench messages meant for
835 1.1.1.1 martti * TCP connections.
836 1.1.1.1 martti */
837 1.1.1.1 martti return NULL;
838 1.1.1.1 martti else if (PRC_IS_REDIRECT(cmd))
839 1.1.1.1 martti notify = in_rtchange, ip = 0;
840 1.1.1.1 martti else if (cmd == PRC_MSGSIZE && ip_mtudisc && ip) {
841 1.1.1.1 martti /*
842 1.1.1.1 martti * Verify that the packet in the icmp payload refers
843 1.1.1.1 martti * to an existing TCP connection.
844 1.1.1.1 martti */
845 1.1.1.1 martti th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
846 1.1.1.1 martti seq = ntohl(th->th_seq);
847 1.1.1.1 martti inp = in_pcbhashlookup(&tcbtable,
848 1.1.1.1 martti ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport);
849 1.1.1.1 martti if (inp && (tp = intotcpcb(inp)) &&
850 1.1.1.1 martti SEQ_GEQ(seq, tp->snd_una) &&
851 1.1.1.1 martti SEQ_LT(seq, tp->snd_max)) {
852 1.1.1.1 martti struct icmp *icp;
853 1.1.1.1 martti icp = (struct icmp *)((caddr_t)ip -
854 1.1.1.1 martti offsetof(struct icmp, icmp_ip));
855 1.1.1.1 martti
856 1.1.1.1 martti /*
857 1.1.1.1 martti * If the ICMP message advertises a Next-Hop MTU
858 1.1.1.1 martti * equal or larger than the maximum packet size we have
859 1.1.1.1 martti * ever sent, drop the message.
860 1.1.1.1 martti */
861 1.1.1.1 martti mtu = (u_int)ntohs(icp->icmp_nextmtu);
862 1.1.1.1 martti if (mtu >= tp->t_pmtud_mtu_sent)
863 1.1.1.1 martti return NULL;
864 1.1.1.1 martti if (mtu >= tcp_hdrsz(tp) + tp->t_pmtud_mss_acked) {
865 1.1.1.1 martti /*
866 1.1.1.1 martti * Calculate new MTU, and create corresponding
867 1.1.1.1 martti * route (traditional PMTUD).
868 1.1.1.1 martti */
869 1.1.1.1 martti tp->t_flags &= ~TF_PMTUD_PEND;
870 1.1.1.1 martti icmp_mtudisc(icp);
871 1.1.1.1 martti } else {
872 1.1.1.1 martti /*
873 1.1.1.1 martti * Record the information got in the ICMP
874 1.1.1.1 martti * message; act on it later.
875 1.1.1.1 martti * If we had already recorded an ICMP message,
876 1.1.1.1 martti * replace the old one only if the new message
877 1.1.1.1 martti * refers to an older TCP segment
878 1.1.1.1 martti */
879 1.1.1.1 martti if (tp->t_flags & TF_PMTUD_PEND) {
880 1.1.1.1 martti if (SEQ_LT(tp->t_pmtud_th_seq, seq))
881 1.1.1.1 martti return NULL;
882 1.1.1.1 martti } else
883 1.1.1.1 martti tp->t_flags |= TF_PMTUD_PEND;
884 1.1.1.1 martti tp->t_pmtud_th_seq = seq;
885 1.1.1.1 martti tp->t_pmtud_nextmtu = icp->icmp_nextmtu;
886 1.1.1.1 martti tp->t_pmtud_ip_len = icp->icmp_ip.ip_len;
887 1.1.1.1 martti tp->t_pmtud_ip_hl = icp->icmp_ip.ip_hl;
888 1.1.1.1 martti return NULL;
889 1.1.1.1 martti }
890 1.1.1.1 martti } else {
891 1.1.1.1 martti /* ignore if we don't have a matching connection */
892 1.1.1.1 martti return NULL;
893 1.1.1.1 martti }
894 1.1.1.1 martti notify = tcp_mtudisc, ip = 0;
895 1.1.1.1 martti } else if (cmd == PRC_MTUINC)
896 1.1.1.1 martti notify = tcp_mtudisc_increase, ip = 0;
897 1.1.1.1 martti else if (cmd == PRC_HOSTDEAD)
898 1.1.1.1 martti ip = 0;
899 1.1.1.1 martti else if (errno == 0)
900 1.1.1.1 martti return NULL;
901 1.1.1.1 martti
902 1.1.1.1 martti if (ip) {
903 1.1.1.1 martti th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
904 1.1.1.1 martti inp = in_pcbhashlookup(&tcbtable,
905 1.1.1.1 martti ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport);
906 1.1.1.1 martti if (inp) {
907 1.1.1.1 martti seq = ntohl(th->th_seq);
908 1.1.1.1 martti if (inp->inp_socket &&
909 1.1.1.1 martti (tp = intotcpcb(inp)) &&
910 1.1.1.1 martti SEQ_GEQ(seq, tp->snd_una) &&
911 1.1.1.1 martti SEQ_LT(seq, tp->snd_max))
912 1.1.1.1 martti notify(inp, errno);
913 1.1.1.1 martti } else if (syn_cache_count &&
914 1.1.1.1 martti (inetctlerrmap[cmd] == EHOSTUNREACH ||
915 1.1.1.1 martti inetctlerrmap[cmd] == ENETUNREACH ||
916 1.1.1.1 martti inetctlerrmap[cmd] == EHOSTDOWN)) {
917 1.1.1.1 martti struct sockaddr_in sin;
918 1.1.1.1 martti
919 1.1.1.1 martti bzero(&sin, sizeof(sin));
920 1.1.1.1 martti sin.sin_len = sizeof(sin);
921 1.1.1.1 martti sin.sin_family = AF_INET;
922 1.1.1.1 martti sin.sin_port = th->th_sport;
923 1.1.1.1 martti sin.sin_addr = ip->ip_src;
924 1.1.1.1 martti syn_cache_unreach((struct sockaddr *)&sin,
925 1.1.1.1 martti sa, th);
926 1.1.1.1 martti }
927 1.1.1.1 martti } else
928 1.1.1.1 martti in_pcbnotifyall(&tcbtable, sa, errno, notify);
929 1.1.1.1 martti
930 1.1.1.1 martti return NULL;
931 1.1.1.1 martti }
932 1.1.1.1 martti
933 1.1.1.1 martti
934 1.1.1.1 martti #ifdef INET6
935 1.1.1.1 martti /*
936 1.1.1.1 martti * Path MTU Discovery handlers.
937 1.1.1.1 martti */
938 1.1.1.1 martti void
939 1.1.1.1 martti tcp6_mtudisc_callback(faddr)
940 1.1.1.1 martti struct in6_addr *faddr;
941 1.1.1.1 martti {
942 1.1.1.1 martti struct sockaddr_in6 sin6;
943 1.1.1.1 martti
944 1.1.1.1 martti bzero(&sin6, sizeof(sin6));
945 1.1.1.1 martti sin6.sin6_family = AF_INET6;
946 1.1.1.1 martti sin6.sin6_len = sizeof(struct sockaddr_in6);
947 1.1.1.1 martti sin6.sin6_addr = *faddr;
948 1.1.1.1 martti (void) in6_pcbnotify(&tcbtable, (struct sockaddr *)&sin6, 0,
949 1.1.1.1 martti (struct sockaddr *)&sa6_any, 0, PRC_MSGSIZE, NULL, tcp_mtudisc);
950 1.1.1.1 martti }
951 1.1.1.1 martti #endif /* INET6 */
952 1.1.1.1 martti
953 1.1.1.1 martti /*
954 1.1.1.1 martti * On receipt of path MTU corrections, flush old route and replace it
955 1.1.1.1 martti * with the new one. Retransmit all unacknowledged packets, to ensure
956 1.1.1.1 martti * that all packets will be received.
957 1.1.1.1 martti */
958 1.1.1.1 martti void
959 1.1.1.1 martti tcp_mtudisc(inp, errno)
960 1.1.1.1 martti struct inpcb *inp;
961 1.1.1.1 martti int errno;
962 1.1.1.1 martti {
963 1.1.1.1 martti struct tcpcb *tp = intotcpcb(inp);
964 1.1.1.1 martti struct rtentry *rt = in_pcbrtentry(inp);
965 1.1.1.1 martti int change = 0;
966 1.1.1.1 martti
967 1.1.1.1 martti if (tp != 0) {
968 1.1.1.1 martti int orig_maxseg = tp->t_maxseg;
969 1.1.1.1 martti if (rt != 0) {
970 1.1.1.1 martti /*
971 1.1.1.1 martti * If this was not a host route, remove and realloc.
972 1.1.1.1 martti */
973 1.1.1.1 martti if ((rt->rt_flags & RTF_HOST) == 0) {
974 1.1.1.1 martti in_rtchange(inp, errno);
975 1.1.1.1 martti if ((rt = in_pcbrtentry(inp)) == 0)
976 1.1.1.1 martti return;
977 1.1.1.1 martti }
978 1.1.1.1 martti if (orig_maxseg != tp->t_maxseg ||
979 1.1.1.1 martti (rt->rt_rmx.rmx_locks & RTV_MTU))
980 1.1.1.1 martti change = 1;
981 1.1.1.1 martti }
982 1.1.1.1 martti tcp_mss(tp, -1);
983 1.1.1.1 martti
984 1.1.1.1 martti /*
985 1.1.1.1 martti * Resend unacknowledged packets
986 1.1.1.1 martti */
987 1.1.1.1 martti tp->snd_nxt = tp->snd_una;
988 1.1.1.1 martti if (change || errno > 0)
989 1.1.1.1 martti tcp_output(tp);
990 1.1.1.1 martti }
991 1.1.1.1 martti }
992 1.1.1.1 martti
993 1.1.1.1 martti void
994 1.1.1.1 martti tcp_mtudisc_increase(inp, errno)
995 1.1.1.1 martti struct inpcb *inp;
996 1.1.1.1 martti int errno;
997 1.1.1.1 martti {
998 1.1.1.1 martti struct tcpcb *tp = intotcpcb(inp);
999 1.1.1.1 martti struct rtentry *rt = in_pcbrtentry(inp);
1000 1.1.1.1 martti
1001 1.1.1.1 martti if (tp != 0 && rt != 0) {
1002 1.1.1.1 martti /*
1003 1.1.1.1 martti * If this was a host route, remove and realloc.
1004 1.1.1.1 martti */
1005 1.1.1.1 martti if (rt->rt_flags & RTF_HOST)
1006 1.1.1.1 martti in_rtchange(inp, errno);
1007 1.1.1.1 martti
1008 1.1.1.1 martti /* also takes care of congestion window */
1009 1.1.1.1 martti tcp_mss(tp, -1);
1010 1.1.1.1 martti }
1011 1.1.1.1 martti }
1012 1.1.1.1 martti
1013 1.1.1.1 martti #define TCP_ISS_CONN_INC 4096
1014 1.1.1.1 martti int tcp_secret_init;
1015 1.1.1.1 martti u_char tcp_secret[16];
1016 1.1.1.1 martti MD5_CTX tcp_secret_ctx;
1017 1.1.1.1 martti
1018 1.1.1.1 martti void
1019 1.1.1.1 martti tcp_set_iss_tsm(struct tcpcb *tp)
1020 1.1.1.1 martti {
1021 1.1.1.1 martti MD5_CTX ctx;
1022 1.1.1.1 martti u_int32_t digest[4];
1023 1.1.1.1 martti
1024 1.1.1.1 martti if (tcp_secret_init == 0) {
1025 1.1.1.1 martti arc4random_bytes(tcp_secret, sizeof(tcp_secret));
1026 1.1.1.1 martti MD5Init(&tcp_secret_ctx);
1027 1.1.1.1 martti MD5Update(&tcp_secret_ctx, tcp_secret, sizeof(tcp_secret));
1028 1.1.1.1 martti tcp_secret_init = 1;
1029 1.1.1.1 martti }
1030 1.1.1.1 martti ctx = tcp_secret_ctx;
1031 1.1.1.1 martti MD5Update(&ctx, (char *)&tp->t_inpcb->inp_lport, sizeof(u_short));
1032 1.1.1.1 martti MD5Update(&ctx, (char *)&tp->t_inpcb->inp_fport, sizeof(u_short));
1033 1.1.1.1 martti if (tp->pf == AF_INET6) {
1034 1.1.1.1 martti MD5Update(&ctx, (char *)&tp->t_inpcb->inp_laddr6,
1035 1.1.1.1 martti sizeof(struct in6_addr));
1036 1.1.1.1 martti MD5Update(&ctx, (char *)&tp->t_inpcb->inp_faddr6,
1037 1.1.1.1 martti sizeof(struct in6_addr));
1038 1.1.1.1 martti } else {
1039 1.1.1.1 martti MD5Update(&ctx, (char *)&tp->t_inpcb->inp_laddr,
1040 1.1.1.1 martti sizeof(struct in_addr));
1041 1.1.1.1 martti MD5Update(&ctx, (char *)&tp->t_inpcb->inp_faddr,
1042 1.1.1.1 martti sizeof(struct in_addr));
1043 1.1.1.1 martti }
1044 1.1.1.1 martti MD5Final((u_char *)digest, &ctx);
1045 1.1.1.1 martti tcp_iss += TCP_ISS_CONN_INC;
1046 1.1.1.1 martti tp->iss = digest[0] + tcp_iss;
1047 1.1.1.1 martti tp->ts_modulate = digest[1];
1048 1.1.1.1 martti }
1049 1.1.1.1 martti
1050 1.1.1.1 martti #ifdef TCP_SIGNATURE
1051 1.1.1.1 martti int
1052 1.1.1.1 martti tcp_signature_tdb_attach()
1053 1.1.1.1 martti {
1054 1.1.1.1 martti return (0);
1055 1.1.1.1 martti }
1056 1.1.1.1 martti
1057 1.1.1.1 martti int
1058 1.1.1.1 martti tcp_signature_tdb_init(tdbp, xsp, ii)
1059 1.1.1.1 martti struct tdb *tdbp;
1060 1.1.1.1 martti struct xformsw *xsp;
1061 1.1.1.1 martti struct ipsecinit *ii;
1062 1.1.1.1 martti {
1063 1.1.1.1 martti if ((ii->ii_authkeylen < 1) || (ii->ii_authkeylen > 80))
1064 1.1.1.1 martti return (EINVAL);
1065 1.1.1.1 martti
1066 1.1.1.1 martti tdbp->tdb_amxkey = malloc(ii->ii_authkeylen, M_XDATA, M_DONTWAIT);
1067 1.1.1.1 martti if (tdbp->tdb_amxkey == NULL)
1068 1.1.1.1 martti return (ENOMEM);
1069 1.1.1.1 martti bcopy(ii->ii_authkey, tdbp->tdb_amxkey, ii->ii_authkeylen);
1070 1.1.1.1 martti tdbp->tdb_amxkeylen = ii->ii_authkeylen;
1071 1.1.1.1 martti
1072 1.1.1.1 martti return (0);
1073 1.1.1.1 martti }
1074 1.1.1.1 martti
1075 1.1.1.1 martti int
1076 1.1.1.1 martti tcp_signature_tdb_zeroize(tdbp)
1077 1.1.1.1 martti struct tdb *tdbp;
1078 1.1.1.1 martti {
1079 1.1.1.1 martti if (tdbp->tdb_amxkey) {
1080 1.1.1.1 martti bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
1081 1.1.1.1 martti free(tdbp->tdb_amxkey, M_XDATA);
1082 1.1.1.1 martti tdbp->tdb_amxkey = NULL;
1083 1.1.1.1 martti }
1084 1.1.1.1 martti
1085 1.1.1.1 martti return (0);
1086 1.1.1.1 martti }
1087 1.1.1.1 martti
1088 1.1.1.1 martti int
1089 1.1.1.1 martti tcp_signature_tdb_input(m, tdbp, skip, protoff)
1090 1.1.1.1 martti struct mbuf *m;
1091 1.1.1.1 martti struct tdb *tdbp;
1092 1.1.1.1 martti int skip, protoff;
1093 1.1.1.1 martti {
1094 1.1.1.1 martti return (0);
1095 1.1.1.1 martti }
1096 1.1.1.1 martti
1097 1.1.1.1 martti int
1098 1.1.1.1 martti tcp_signature_tdb_output(m, tdbp, mp, skip, protoff)
1099 1.1.1.1 martti struct mbuf *m;
1100 1.1.1.1 martti struct tdb *tdbp;
1101 1.1.1.1 martti struct mbuf **mp;
1102 1.1.1.1 martti int skip, protoff;
1103 1.1.1.1 martti {
1104 1.1.1.1 martti return (EINVAL);
1105 1.1.1.1 martti }
1106 1.1.1.1 martti
1107 1.1.1.1 martti int
1108 1.1.1.1 martti tcp_signature_apply(fstate, data, len)
1109 1.1.1.1 martti caddr_t fstate;
1110 1.1.1.1 martti caddr_t data;
1111 1.1.1.1 martti unsigned int len;
1112 1.1.1.1 martti {
1113 1.1.1.1 martti MD5Update((MD5_CTX *)fstate, (char *)data, len);
1114 1.1.1.1 martti return 0;
1115 1.1.1.1 martti }
1116 1.1.1.1 martti
1117 1.1.1.1 martti int
1118 1.1.1.1 martti tcp_signature(struct tdb *tdb, int af, struct mbuf *m, struct tcphdr *th,
1119 1.1.1.1 martti int iphlen, int doswap, char *sig)
1120 1.1.1.1 martti {
1121 1.1.1.1 martti MD5_CTX ctx;
1122 1.1.1.1 martti int len;
1123 1.1.1.1 martti struct tcphdr th0;
1124 1.1.1.1 martti
1125 1.1.1.1 martti MD5Init(&ctx);
1126 1.1.1.1 martti
1127 1.1.1.1 martti switch(af) {
1128 1.1.1.1 martti case 0:
1129 1.1.1.1 martti #ifdef INET
1130 1.1.1.1 martti case AF_INET: {
1131 1.1.1.1 martti struct ippseudo ippseudo;
1132 1.1.1.1 martti struct ip *ip;
1133 1.1.1.1 martti
1134 1.1.1.1 martti ip = mtod(m, struct ip *);
1135 1.1.1.1 martti
1136 1.1.1.1 martti ippseudo.ippseudo_src = ip->ip_src;
1137 1.1.1.1 martti ippseudo.ippseudo_dst = ip->ip_dst;
1138 1.1.1.1 martti ippseudo.ippseudo_pad = 0;
1139 1.1.1.1 martti ippseudo.ippseudo_p = IPPROTO_TCP;
1140 1.1.1.1 martti ippseudo.ippseudo_len = htons(m->m_pkthdr.len - iphlen);
1141 1.1.1.1 martti
1142 1.1.1.1 martti MD5Update(&ctx, (char *)&ippseudo,
1143 1.1.1.1 martti sizeof(struct ippseudo));
1144 1.1.1.1 martti break;
1145 1.1.1.1 martti }
1146 1.1.1.1 martti #endif
1147 1.1.1.1 martti #ifdef INET6
1148 1.1.1.1 martti case AF_INET6: {
1149 1.1.1.1 martti struct ip6_hdr_pseudo ip6pseudo;
1150 1.1.1.1 martti struct ip6_hdr *ip6;
1151 1.1.1.1 martti
1152 1.1.1.1 martti ip6 = mtod(m, struct ip6_hdr *);
1153 1.1.1.1 martti bzero(&ip6pseudo, sizeof(ip6pseudo));
1154 1.1.1.1 martti ip6pseudo.ip6ph_src = ip6->ip6_src;
1155 1.1.1.1 martti ip6pseudo.ip6ph_dst = ip6->ip6_dst;
1156 1.1.1.1 martti in6_clearscope(&ip6pseudo.ip6ph_src);
1157 1.1.1.1 martti in6_clearscope(&ip6pseudo.ip6ph_dst);
1158 1.1.1.1 martti ip6pseudo.ip6ph_nxt = IPPROTO_TCP;
1159 1.1.1.1 martti ip6pseudo.ip6ph_len = htonl(m->m_pkthdr.len - iphlen);
1160 1.1.1.1 martti
1161 1.1.1.1 martti MD5Update(&ctx, (char *)&ip6pseudo,
1162 1.1.1.1 martti sizeof(ip6pseudo));
1163 1.1.1.1 martti break;
1164 1.1.1.1 martti }
1165 1.1.1.1 martti #endif
1166 1.1.1.1 martti }
1167 1.1.1.1 martti
1168 1.1.1.1 martti th0 = *th;
1169 1.1.1.1 martti th0.th_sum = 0;
1170 1.1.1.1 martti
1171 1.1.1.1 martti if (doswap) {
1172 1.1.1.1 martti HTONL(th0.th_seq);
1173 1.1.1.1 martti HTONL(th0.th_ack);
1174 1.1.1.1 martti HTONS(th0.th_win);
1175 1.1.1.1 martti HTONS(th0.th_urp);
1176 1.1.1.1 martti }
1177 1.1.1.1 martti MD5Update(&ctx, (char *)&th0, sizeof(th0));
1178 1.1.1.1 martti
1179 1.1.1.1 martti len = m->m_pkthdr.len - iphlen - th->th_off * sizeof(uint32_t);
1180 1.1.1.1 martti
1181 1.1.1.1 martti if (len > 0 &&
1182 1.1.1.1 martti m_apply(m, iphlen + th->th_off * sizeof(uint32_t), len,
1183 1.1.1.1 martti tcp_signature_apply, (caddr_t)&ctx))
1184 1.1.1.1 martti return (-1);
1185 1.1.1.1 martti
1186 1.1.1.1 martti MD5Update(&ctx, tdb->tdb_amxkey, tdb->tdb_amxkeylen);
1187 1.1.1.1 martti MD5Final(sig, &ctx);
1188 1.1.1.1 martti
1189 1.1.1.1 martti return (0);
1190 1.1.1.1 martti }
1191 1.1.1.1 martti #endif /* TCP_SIGNATURE */
1192 1.1.1.1 martti
1193 1.1.1.1 martti #define TCP_RNDISS_ROUNDS 16
1194 1.1.1.1 martti #define TCP_RNDISS_OUT 7200
1195 1.1.1.1 martti #define TCP_RNDISS_MAX 30000
1196 1.1.1.1 martti
1197 1.1.1.1 martti u_int8_t tcp_rndiss_sbox[128];
1198 1.1.1.1 martti u_int16_t tcp_rndiss_msb;
1199 1.1.1.1 martti u_int16_t tcp_rndiss_cnt;
1200 1.1.1.1 martti long tcp_rndiss_reseed;
1201 1.1.1.1 martti
1202 1.1.1.1 martti u_int16_t
1203 1.1.1.1 martti tcp_rndiss_encrypt(val)
1204 1.1.1.1 martti u_int16_t val;
1205 1.1.1.1 martti {
1206 1.1.1.1 martti u_int16_t sum = 0, i;
1207 1.1.1.1 martti
1208 1.1.1.1 martti for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
1209 1.1.1.1 martti sum += 0x79b9;
1210 1.1.1.1 martti val ^= ((u_int16_t)tcp_rndiss_sbox[(val^sum) & 0x7f]) << 7;
1211 1.1.1.1 martti val = ((val & 0xff) << 7) | (val >> 8);
1212 1.1.1.1 martti }
1213 1.1.1.1 martti
1214 1.1.1.1 martti return val;
1215 1.1.1.1 martti }
1216 1.1.1.1 martti
1217 1.1.1.1 martti void
1218 1.1.1.1 martti tcp_rndiss_init()
1219 1.1.1.1 martti {
1220 1.1.1.1 martti get_random_bytes(tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox));
1221 1.1.1.1 martti
1222 1.1.1.1 martti tcp_rndiss_reseed = time_second + TCP_RNDISS_OUT;
1223 1.1.1.1 martti tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
1224 1.1.1.1 martti tcp_rndiss_cnt = 0;
1225 1.1.1.1 martti }
1226 1.1.1.1 martti
1227 1.1.1.1 martti tcp_seq
1228 1.1.1.1 martti tcp_rndiss_next()
1229 1.1.1.1 martti {
1230 1.1.1.1 martti if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
1231 1.1.1.1 martti time_second > tcp_rndiss_reseed)
1232 1.1.1.1 martti tcp_rndiss_init();
1233 1.1.1.1 martti
1234 1.1.1.1 martti /* (arc4random() & 0x7fff) ensures a 32768 byte gap between ISS */
1235 1.1.1.1 martti return ((tcp_rndiss_encrypt(tcp_rndiss_cnt++) | tcp_rndiss_msb) <<16) |
1236 1.1.1.1 martti (arc4random() & 0x7fff);
1237 1.1.1.1 martti }
1238 1.1.1.1 martti
1239