1/* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95 |
34 * $FreeBSD: head/sys/netinet/tcp_timewait.c 58698 2000-03-27 19:14:27Z jlemon $ |
35 */ 36 37#include "opt_compat.h" 38#include "opt_inet6.h" 39#include "opt_ipsec.h" 40#include "opt_tcpdebug.h" 41 |
42#include <stddef.h> |
43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/callout.h> 46#include <sys/kernel.h> 47#include <sys/sysctl.h> 48#include <sys/malloc.h> 49#include <sys/mbuf.h> 50#ifdef INET6 --- 38 unchanged lines hidden (view full) --- 89#include <netinet/tcp_debug.h> 90#endif 91#include <netinet6/ip6protosw.h> 92 93#ifdef IPSEC 94#include <netinet6/ipsec.h> 95#endif /*IPSEC*/ 96 |
97#include <machine/in_cksum.h> 98 |
99int tcp_mssdflt = TCP_MSS; 100SYSCTL_INT(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLFLAG_RW, 101 &tcp_mssdflt , 0, "Default TCP Maximum Segment Size"); 102 103#ifdef INET6 104int tcp_v6mssdflt = TCP6_MSS; 105SYSCTL_INT(_net_inet_tcp, TCPCTL_V6MSSDFLT, v6mssdflt, 106 CTLFLAG_RW, &tcp_v6mssdflt , 0, --- 133 unchanged lines hidden (view full) --- 240 ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) | 241 (inp->in6p_flowinfo & IPV6_FLOWINFO_MASK); 242 ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) | 243 (IPV6_VERSION & IPV6_VERSION_MASK); 244 ip6->ip6_nxt = IPPROTO_TCP; 245 ip6->ip6_plen = sizeof(struct tcphdr); 246 ip6->ip6_src = inp->in6p_laddr; 247 ip6->ip6_dst = inp->in6p_faddr; |
248 n->tt_t.th_sum = 0; |
249 } else 250#endif 251 { |
252 struct ip *ip = (struct ip *)n->tt_ipgen; |
253 |
254 bzero(ip, sizeof(struct ip)); /* XXX overkill? */ 255 ip->ip_vhl = IP_VHL_BORING; 256 ip->ip_p = IPPROTO_TCP; 257 ip->ip_src = inp->inp_laddr; 258 ip->ip_dst = inp->inp_faddr; 259 n->tt_t.th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, 260 htons(sizeof(struct tcphdr) + IPPROTO_TCP)); |
261 } 262 n->tt_t.th_sport = inp->inp_lport; 263 n->tt_t.th_dport = inp->inp_fport; 264 n->tt_t.th_seq = 0; 265 n->tt_t.th_ack = 0; 266 n->tt_t.th_x2 = 0; 267 n->tt_t.th_off = 5; 268 n->tt_t.th_flags = 0; 269 n->tt_t.th_win = 0; |
270 n->tt_t.th_urp = 0; 271 return (n); 272} 273 274/* 275 * Send a single message to the TCP at address specified by 276 * the given TCP/IP header. If m == 0, then we make a copy 277 * of the tcpiphdr at ti and send directly to the addressed host. --- 17 unchanged lines hidden (view full) --- 295 tcp_seq ack, seq; 296 int flags; 297{ 298 register int tlen; 299 int win = 0; 300 struct route *ro = 0; 301 struct route sro; 302 struct ip *ip; |
303 struct tcphdr *nth; 304#ifdef INET6 305 struct route_in6 *ro6 = 0; 306 struct route_in6 sro6; 307 struct ip6_hdr *ip6; 308 int isipv6; 309#endif /* INET6 */ 310 int ipflags = 0; 311 312#ifdef INET6 313 isipv6 = IP_VHL_V(((struct ip *)ipgen)->ip_vhl) == 6; 314 ip6 = ipgen; 315#endif /* INET6 */ 316 ip = ipgen; |
317 318 if (tp) { 319 if (!(flags & TH_RST)) { 320 win = sbspace(&tp->t_inpcb->inp_socket->so_rcv); 321 if (win > (long)TCP_MAXWIN << tp->rcv_scale) 322 win = (long)TCP_MAXWIN << tp->rcv_scale; 323 } 324#ifdef INET6 --- 30 unchanged lines hidden (view full) --- 355 sizeof(struct ip6_hdr)); 356 ip6 = mtod(m, struct ip6_hdr *); 357 nth = (struct tcphdr *)(ip6 + 1); 358 } else 359#endif /* INET6 */ 360 { 361 bcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); 362 ip = mtod(m, struct ip *); |
363 nth = (struct tcphdr *)(ip + 1); 364 } 365 bcopy((caddr_t)th, (caddr_t)nth, sizeof(struct tcphdr)); 366 flags = TH_ACK; 367 } else { 368 m_freem(m->m_next); 369 m->m_next = 0; 370 m->m_data = (caddr_t)ipgen; --- 25 unchanged lines hidden (view full) --- 396#ifdef INET6 397 if (isipv6) { 398 ip6->ip6_plen = htons((u_short)(sizeof (struct tcphdr) + 399 tlen)); 400 tlen += sizeof (struct ip6_hdr) + sizeof (struct tcphdr); 401 } else 402#endif 403 { |
404 tlen += sizeof (struct tcpiphdr); |
405 ip->ip_len = tlen; 406 ip->ip_ttl = ip_defttl; |
407 } 408 m->m_len = tlen; 409 m->m_pkthdr.len = tlen; 410 m->m_pkthdr.rcvif = (struct ifnet *) 0; 411 nth->th_seq = htonl(seq); 412 nth->th_ack = htonl(ack); 413 nth->th_x2 = 0; 414 nth->th_off = sizeof (struct tcphdr) >> 2; 415 nth->th_flags = flags; 416 if (tp) 417 nth->th_win = htons((u_short) (win >> tp->rcv_scale)); 418 else 419 nth->th_win = htons((u_short)win); 420 nth->th_urp = 0; |
421#ifdef INET6 422 if (isipv6) { 423 nth->th_sum = in6_cksum(m, IPPROTO_TCP, 424 sizeof(struct ip6_hdr), 425 tlen - sizeof(struct ip6_hdr)); 426 ip6->ip6_hlim = in6_selecthlim(tp ? tp->t_inpcb : NULL, 427 ro6 && ro6->ro_rt ? 428 ro6->ro_rt->rt_ifp : 429 NULL); 430 } else 431#endif /* INET6 */ 432 { |
433 nth->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, 434 htons((u_short)(tlen - sizeof(struct ip) + ip->ip_p))); 435 m->m_pkthdr.csum_flags = CSUM_TCP; 436 m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); |
437 } 438#ifdef TCPDEBUG 439 if (tp == NULL || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) 440 tcp_trace(TA_OUTPUT, 0, tp, mtod(m, void *), th, 0); 441#endif 442#ifdef IPSEC 443 if (tp != NULL) { 444 m->m_pkthdr.rcvif = (struct ifnet *)tp->t_inpcb->inp_socket; --- 856 unchanged lines hidden --- |