diff options
author | 2010-01-12 06:10:33 +0000 | |
---|---|---|
committer | 2010-01-12 06:10:33 +0000 | |
commit | 29b017f6103c6f450d336561eb02738e7b2190f3 (patch) | |
tree | 219295804d20285e1e493c2bdc2c965b59269362 /usr.sbin/tcpdump/print-tcp.c | |
parent | Remove simple_unlock() that is mistakenly introduced and add required (diff) | |
download | wireguard-openbsd-29b017f6103c6f450d336561eb02738e7b2190f3.tar.xz wireguard-openbsd-29b017f6103c6f450d336561eb02738e7b2190f3.zip |
Add TCP/UDP checksum display for v6 and clean up the checksum
calculation. Mostly from tcpdump.org; ok jsing@
Diffstat (limited to 'usr.sbin/tcpdump/print-tcp.c')
-rw-r--r-- | usr.sbin/tcpdump/print-tcp.c | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/usr.sbin/tcpdump/print-tcp.c b/usr.sbin/tcpdump/print-tcp.c index f393d1aff25..9b00d8244b2 100644 --- a/usr.sbin/tcpdump/print-tcp.c +++ b/usr.sbin/tcpdump/print-tcp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-tcp.c,v 1.27 2009/10/27 23:59:56 deraadt Exp $ */ +/* $OpenBSD: print-tcp.c,v 1.28 2010/01/12 06:10:33 naddy Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -126,11 +126,8 @@ static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE]; #endif #define NETBIOS_SSN_PORT 139 -static int tcp_cksum(register const struct ip *ip, - register const struct tcphdr *tp, - register int len) +static int tcp_cksum(const struct ip *ip, const struct tcphdr *tp, int len) { - int i, tlen; union phu { struct phdr { u_int32_t src; @@ -141,35 +138,52 @@ static int tcp_cksum(register const struct ip *ip, } ph; u_int16_t pa[6]; } phu; - register const u_int16_t *sp; + const u_int16_t *sp; u_int32_t sum; - tlen = ntohs(ip->ip_len) - ((const char *)tp-(const char*)ip); /* pseudo-header.. */ - phu.ph.len = htons(tlen); + phu.ph.len = htons((u_int16_t)len); phu.ph.mbz = 0; - phu.ph.proto = ip->ip_p; + phu.ph.proto = IPPROTO_TCP; memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); sp = &phu.pa[0]; sum = sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]; - sp = (const u_int16_t *)tp; + return in_cksum((u_short *)tp, len, sum); +} - for (i=0; i<(tlen&~1); i+= 2) - sum += *sp++; +#ifdef INET6 +static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp, + u_int len) +{ + union { + struct { + struct in6_addr ph_src; + struct in6_addr ph_dst; + u_int32_t ph_len; + u_int8_t ph_zero[3]; + u_int8_t ph_nxt; + } ph; + u_int16_t pa[20]; + } phu; + size_t i; + u_int32_t sum = 0; - if (tlen & 1) { - sum += htons( (*(const char *)sp) << 8); - } + /* pseudo-header */ + memset(&phu, 0, sizeof(phu)); + phu.ph.ph_src = ip6->ip6_src; + phu.ph.ph_dst = ip6->ip6_dst; + phu.ph.ph_len = htonl(len); + phu.ph.ph_nxt = IPPROTO_TCP; - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum = ~sum & 0xffff; + for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) + sum += phu.pa[i]; - return (sum); + return in_cksum((u_short *)tp, len, sum); } +#endif void @@ -416,6 +430,18 @@ tcp_print(register const u_char *bp, register u_int length, (void)printf(" [tcp sum ok]"); } } +#ifdef INET6 + if (ip6 && ip6->ip6_plen && vflag) { + int sum; + if (TTEST2(tp->th_sport, length)) { + sum = tcp6_cksum(ip6, tp, length); + if (sum != 0) + (void)printf(" [bad tcp cksum %x!]", sum); + else + (void)printf(" [tcp sum ok]"); + } + } +#endif /* OS Fingerprint */ if (oflag && (flags & (TH_SYN|TH_ACK)) == TH_SYN) { |