aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authorJonathan Lemon <jlemon@FreeBSD.org>2000-03-27 19:14:27 +0000
committerJonathan Lemon <jlemon@FreeBSD.org>2000-03-27 19:14:27 +0000
commitdb4f9cc70389b2004594fea6f910e5091855ddf8 (patch)
tree18fe751adcccc8aec961339214bd6bf346ee66d4 /sys/netinet/tcp_input.c
parent07b065a591b026c05dbb40e715987592c28db5cd (diff)
downloadsrc-db4f9cc70389b2004594fea6f910e5091855ddf8.tar.gz
src-db4f9cc70389b2004594fea6f910e5091855ddf8.zip
Notes
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 1d2d8c38e58f..dc8ba3c1b906 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -100,6 +100,8 @@ struct tcphdr tcp_savetcp;
#include <netkey/key.h>
#endif /*IPSEC*/
+#include <machine/in_cksum.h>
+
MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
static int tcprexmtthresh = 3;
@@ -425,17 +427,27 @@ tcp_input(m, off0, proto)
}
ip = mtod(m, struct ip *);
ipov = (struct ipovly *)ip;
-
- /*
- * Checksum extended TCP header and data.
- */
- tlen = ip->ip_len;
- len = sizeof (struct ip) + tlen;
- bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
- ipov->ih_len = (u_short)tlen;
- HTONS(ipov->ih_len);
th = (struct tcphdr *)((caddr_t)ip + off0);
- th->th_sum = in_cksum(m, len);
+ tlen = ip->ip_len;
+
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
+ if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
+ th->th_sum = m->m_pkthdr.csum_data;
+ else
+ th->th_sum = in_pseudo(ip->ip_src.s_addr,
+ ip->ip_dst.s_addr, htonl(m->m_pkthdr.csum_data +
+ ip->ip_len + IPPROTO_TCP));
+ th->th_sum ^= 0xffff;
+ } else {
+ /*
+ * Checksum extended TCP header and data.
+ */
+ len = sizeof (struct ip) + tlen;
+ bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
+ ipov->ih_len = (u_short)tlen;
+ HTONS(ipov->ih_len);
+ th->th_sum = in_cksum(m, len);
+ }
if (th->th_sum) {
tcpstat.tcps_rcvbadsum++;
goto drop;