diff options
author | 2010-01-12 06:10:33 +0000 | |
---|---|---|
committer | 2010-01-12 06:10:33 +0000 | |
commit | 29b017f6103c6f450d336561eb02738e7b2190f3 (patch) | |
tree | 219295804d20285e1e493c2bdc2c965b59269362 | |
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@
-rw-r--r-- | usr.sbin/tcpdump/interface.h | 6 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-ip.c | 4 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-tcp.c | 64 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-udp.c | 67 |
4 files changed, 97 insertions, 44 deletions
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h index c6aee4b2c65..4475e742570 100644 --- a/usr.sbin/tcpdump/interface.h +++ b/usr.sbin/tcpdump/interface.h @@ -1,4 +1,4 @@ -/* $OpenBSD: interface.h,v 1.59 2009/11/04 09:43:11 jsing Exp $ */ +/* $OpenBSD: interface.h,v 1.60 2010/01/12 06:10:33 naddy Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -20,7 +20,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Id: interface.h,v 1.59 2009/11/04 09:43:11 jsing Exp $ (LBL) + * @(#) $Id: interface.h,v 1.60 2010/01/12 06:10:33 naddy Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -288,4 +288,4 @@ extern void ospf6_print(const u_char *, u_int); extern void dhcp6_print(const u_char *, u_int, u_short, u_short); #endif /*INET6*/ -extern u_short in_cksum(const u_short *addr, register int len, u_short csum); +extern u_short in_cksum(const u_short *addr, register int len, int csum); diff --git a/usr.sbin/tcpdump/print-ip.c b/usr.sbin/tcpdump/print-ip.c index 9ea03d17154..dacbeef78e5 100644 --- a/usr.sbin/tcpdump/print-ip.c +++ b/usr.sbin/tcpdump/print-ip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-ip.c,v 1.35 2009/10/27 23:59:55 deraadt Exp $ */ +/* $OpenBSD: print-ip.c,v 1.36 2010/01/12 06:10:33 naddy Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -320,7 +320,7 @@ trunc: * don't modifiy the packet. */ u_short -in_cksum(const u_short *addr, register int len, u_short csum) +in_cksum(const u_short *addr, register int len, int csum) { int nleft = len; const u_short *w = addr; 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) { diff --git a/usr.sbin/tcpdump/print-udp.c b/usr.sbin/tcpdump/print-udp.c index 3661d308d0e..4ddfbdeb732 100644 --- a/usr.sbin/tcpdump/print-udp.c +++ b/usr.sbin/tcpdump/print-udp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-udp.c,v 1.33 2009/11/04 09:43:11 jsing Exp $ */ +/* $OpenBSD: print-udp.c,v 1.34 2010/01/12 06:10:33 naddy Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 @@ -289,11 +289,8 @@ rtcp_print(const u_char *hdr, const u_char *ep) return (hdr + len); } -static int udp_cksum(register const struct ip *ip, - register const struct udphdr *up, - register int len) +static int udp_cksum(const struct ip *ip, const struct udphdr *up, int len) { - int i, tlen; union phu { struct phdr { u_int32_t src; @@ -304,35 +301,52 @@ static int udp_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 *)up-(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_UDP; 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 *)up; + return in_cksum((u_short *)up, len, sum); +} - for (i=0; i<(tlen&~1); i+= 2) - sum += *sp++; +#ifdef INET6 +static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, + 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_UDP; - 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 *)up, len, sum); } +#endif @@ -556,13 +570,26 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) if (sum == 0) { (void)printf(" [no cksum]"); } else if (TTEST2(cp[0], length)) { - sum = udp_cksum(ip, up, length); + sum = udp_cksum(ip, up, length + sizeof(struct udphdr)); + if (sum != 0) + (void)printf(" [bad udp cksum %x!]", sum); + else + (void)printf(" [udp sum ok]"); + } + } +#ifdef INET6 + if (ip->ip_v == 6 && ip6->ip6_plen && vflag) { + int sum = up->uh_sum; + /* for IPv6, UDP checksum is mandatory */ + if (TTEST2(cp[0], length)) { + sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); if (sum != 0) (void)printf(" [bad udp cksum %x!]", sum); else (void)printf(" [udp sum ok]"); } } +#endif if (!qflag) { #define ISPORT(p) (dport == (p) || sport == (p)) |