summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornaddy <naddy@openbsd.org>2010-01-12 06:10:33 +0000
committernaddy <naddy@openbsd.org>2010-01-12 06:10:33 +0000
commit29b017f6103c6f450d336561eb02738e7b2190f3 (patch)
tree219295804d20285e1e493c2bdc2c965b59269362
parentRemove simple_unlock() that is mistakenly introduced and add required (diff)
downloadwireguard-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.h6
-rw-r--r--usr.sbin/tcpdump/print-ip.c4
-rw-r--r--usr.sbin/tcpdump/print-tcp.c64
-rw-r--r--usr.sbin/tcpdump/print-udp.c67
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))