From 3625533c9acb33b9a9d57f3d38290b1408a96341 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Le Bail Date: Sun, 16 Feb 2014 18:29:37 +0100 Subject: [PATCH] fix partial checksum errors in DCCP decoder, IPv6 case --- ip6.h | 2 +- netdissect.h | 1 - print-dccp.c | 4 ++-- print-icmp6.c | 4 ++-- print-ip6.c | 6 +++--- print-tcp.c | 3 ++- print-udp.c | 4 ++-- tests/TESTLIST | 2 ++ tests/dccp_partial_csum_v6_longer.out | 9 +++++++++ tests/dccp_partial_csum_v6_longer.pcap | Bin 0 -> 1230 bytes tests/dccp_partial_csum_v6_simple.out | 7 +++++++ tests/dccp_partial_csum_v6_simple.pcap | Bin 0 -> 782 bytes 12 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 tests/dccp_partial_csum_v6_longer.out create mode 100644 tests/dccp_partial_csum_v6_longer.pcap create mode 100644 tests/dccp_partial_csum_v6_simple.out create mode 100644 tests/dccp_partial_csum_v6_simple.pcap diff --git a/ip6.h b/ip6.h index c19d7ee4..f1032ec2 100644 --- a/ip6.h +++ b/ip6.h @@ -196,6 +196,6 @@ struct ip6_frag { #define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */ /* in print-ip6.c */ -extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int); +extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int, u_int); #endif /* not _NETINET_IP6_H_ */ diff --git a/netdissect.h b/netdissect.h index 37bc59e0..241f585a 100644 --- a/netdissect.h +++ b/netdissect.h @@ -527,7 +527,6 @@ extern u_int ieee802_15_4_if_print(netdissect_options *,const struct pcap_pkthdr extern void ip6_print(netdissect_options *,const u_char *, u_int); #if 0 extern void ip6_opt_print(netdissect_options *,const u_char *, int); -extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int); extern int hbhopt_print(netdissect_options *,const u_char *); extern int dstopt_print(netdissect_options *,const u_char *); extern int frag6_print(netdissect_options *,const u_char *, diff --git a/print-dccp.c b/print-dccp.c index ffadfb66..68d0a978 100644 --- a/print-dccp.c +++ b/print-dccp.c @@ -192,8 +192,8 @@ static int dccp_cksum(const struct ip *ip, #ifdef INET6 static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) { - return nextproto6_cksum(ip6, (const u_int8_t *)(void *)dh, - dccp_csum_coverage(dh, len), IPPROTO_DCCP); + return nextproto6_cksum(ip6, (const u_int8_t *)(void *)dh, len, + dccp_csum_coverage(dh, len), IPPROTO_DCCP); } #endif diff --git a/print-icmp6.c b/print-icmp6.c index 58f49847..ba5cfa62 100644 --- a/print-icmp6.c +++ b/print-icmp6.c @@ -625,8 +625,8 @@ print_lladdr(netdissect_options *ndo, const u_int8_t *p, size_t l) static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, u_int len) { - return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)icp, len, - IPPROTO_ICMPV6)); + return nextproto6_cksum(ip6, (const u_int8_t *)(void *)icp, len, len, + IPPROTO_ICMPV6); } const struct tok rpl_mop_values[] = { diff --git a/print-ip6.c b/print-ip6.c index 908a5dee..484b2f1b 100644 --- a/print-ip6.c +++ b/print-ip6.c @@ -44,7 +44,7 @@ */ int nextproto6_cksum(const struct ip6_hdr *ip6, const u_int8_t *data, - u_int len, u_int next_proto) + u_int len, u_int covlen, u_int next_proto) { struct { struct in6_addr ph_src; @@ -65,7 +65,7 @@ nextproto6_cksum(const struct ip6_hdr *ip6, const u_int8_t *data, vec[0].ptr = (const u_int8_t *)(void *)&ph; vec[0].len = sizeof(ph); vec[1].ptr = data; - vec[1].len = len; + vec[1].len = covlen; return in_cksum(vec, 2); } @@ -225,7 +225,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) } case IPPROTO_PIM: - pim_print(cp, len, nextproto6_cksum(ip6, cp, len, + pim_print(cp, len, nextproto6_cksum(ip6, cp, len, len, IPPROTO_PIM)); return; diff --git a/print-tcp.c b/print-tcp.c index eee98fe9..e5acfa4c 100644 --- a/print-tcp.c +++ b/print-tcp.c @@ -386,7 +386,8 @@ tcp_print(register const u_char *bp, register u_int length, #ifdef INET6 else if (IP_V(ip) == 6 && ip6->ip6_plen) { if (TTEST2(tp->th_sport, length)) { - sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP); + sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, + length, length, IPPROTO_TCP); tcp_sum = EXTRACT_16BITS(&tp->th_sum); (void)printf(", cksum 0x%04x", tcp_sum); diff --git a/print-udp.c b/print-udp.c index a8566d04..cd41e323 100644 --- a/print-udp.c +++ b/print-udp.c @@ -289,8 +289,8 @@ static int udp_cksum(register const struct ip *ip, static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, u_int len) { - return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len, - IPPROTO_UDP)); + return nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len, len, + IPPROTO_UDP); } #endif diff --git a/tests/TESTLIST b/tests/TESTLIST index 30abaeda..6e54b8d8 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -177,3 +177,5 @@ loopback loopback.pcap loopback.out -t # DCCP partial checksums tests dccp_partial_csum_v4_simple dccp_partial_csum_v4_simple.pcap dccp_partial_csum_v4_simple.out -t -vv dccp_partial_csum_v4_longer dccp_partial_csum_v4_longer.pcap dccp_partial_csum_v4_longer.out -t -vv +dccp_partial_csum_v6_simple dccp_partial_csum_v6_simple.pcap dccp_partial_csum_v6_simple.out -t -vv +dccp_partial_csum_v6_longer dccp_partial_csum_v6_longer.pcap dccp_partial_csum_v6_longer.out -t -vv diff --git a/tests/dccp_partial_csum_v6_longer.out b/tests/dccp_partial_csum_v6_longer.out new file mode 100644 index 00000000..adee6c3a --- /dev/null +++ b/tests/dccp_partial_csum_v6_longer.out @@ -0,0 +1,9 @@ +IP6 (hlim 64, next-header DCCP (33) payload length: 32) 3ffe::1.55024 > 3ffe::2.5001: CCVal 0, CsCov 0, cksum 0xd538 (correct), request (service=0) seq 1559687427 +IP6 (hlim 64, next-header DCCP (33) payload length: 48) 3ffe::2.5001 > 3ffe::1.55024: CCVal 0, CsCov 0, cksum 0x81a3 (correct), response (service=0) (ack=1559687427) seq 1585962456 +IP6 (hlim 64, next-header DCCP (33) payload length: 36) 3ffe::1.55024 > 3ffe::2.5001: CCVal 0, CsCov 0, cksum 0xc692 (correct), ack (ack=1585962456) seq 1559687428 +IP6 (hlim 64, next-header DCCP (33) payload length: 164) 3ffe::1.55024 > 3ffe::2.5001: CCVal 0, CsCov 10, cksum 0xe362 (correct), dataack (ack=1585962456) seq 1559687429 +IP6 (hlim 64, next-header DCCP (33) payload length: 32) 3ffe::2.5001 > 3ffe::1.55024: CCVal 0, CsCov 0, cksum 0xcdbb (correct), ack (ack=1559687429) seq 1585962457 +IP6 (hlim 64, next-header DCCP (33) payload length: 160) 3ffe::1.55024 > 3ffe::2.5001: CCVal 0, CsCov 10, cksum 0x5574 (correct), dataack (ack=1585962457) seq 1559687430 +IP6 (hlim 64, next-header DCCP (33) payload length: 32) 3ffe::1.55024 > 3ffe::2.5001: CCVal 0, CsCov 0, cksum 0xc778 (correct), close (ack=1585962457) seq 1559687431 +IP6 (hlim 64, next-header DCCP (33) payload length: 32) 3ffe::2.5001 > 3ffe::1.55024: CCVal 0, CsCov 0, cksum 0xd2bc (correct), ack (ack=1559687430) seq 1585962458 +IP6 (hlim 64, next-header DCCP (33) payload length: 40) 3ffe::2.5001 > 3ffe::1.55024: CCVal 0, CsCov 0, cksum 0xc186 (correct), reset (code=closed) (ack=1559687431) seq 1585962459 diff --git a/tests/dccp_partial_csum_v6_longer.pcap b/tests/dccp_partial_csum_v6_longer.pcap new file mode 100644 index 0000000000000000000000000000000000000000..644379d8dfeea5d498f9b3624371b7e3d60e5ad4 GIT binary patch literal 1230 zcmca|c+)~A1{MYw`2U}Qff300(jDSz@5I9p24sUUgNRaOXdnao%e}GkZFdtuA_|HQ z_WwW(IABEMGhO>2+{wXk)dFN<%(susAe9O%tV~KQj7$nZ46@~xGY>-=P#lCI=0og) z+G2oV3lo|xjKZDQKJYL!E(RGN*M9c~$RL<)5c`x_8JU=4_)K?t@TWQ7_tgEk8TBgm%n3A_xqfNDS(i%m<2w2A9+5+}qa zR**pue}b)%DNR#8<`*U;3`*3s3|H!w6ZHZe6bx3ILbwz0LdcW`uac5!uc z_we-c_VM-e4+snj4hanlkBE$lj){$nPe@EkPDxEm&&bTm&dJToFDNW3E-5W5uc)l5 zuBojfXgtWLvy*ud=>?opP+}4@yj`feZrM28lIuf}W*ASmpqINsYXByn+|#J75@sf)v@8&Y&3E zn2ux%1u=GM4>ZQWi5zGfFie4g2~3wDTP!ko8R9^;gPeeAiv~uFVNDlY3`+P`LuK37j}onVA62^9cR` literal 0 HcmV?d00001 diff --git a/tests/dccp_partial_csum_v6_simple.out b/tests/dccp_partial_csum_v6_simple.out new file mode 100644 index 00000000..55136770 --- /dev/null +++ b/tests/dccp_partial_csum_v6_simple.out @@ -0,0 +1,7 @@ +IP6 (hlim 64, next-header DCCP (33) payload length: 32) 3ffe::1.52921 > 3ffe::2.5001: CCVal 0, CsCov 0, cksum 0xef1a (correct), request (service=0) seq 1337846929 +IP6 (hlim 64, next-header DCCP (33) payload length: 48) 3ffe::2.5001 > 3ffe::1.52921: CCVal 0, CsCov 0, cksum 0x0b73 (correct), response (service=0) (ack=1337846929) seq 1385331168 +IP6 (hlim 64, next-header DCCP (33) payload length: 36) 3ffe::1.52921 > 3ffe::2.5001: CCVal 0, CsCov 0, cksum 0x5062 (correct), ack (ack=1385331168) seq 1337846930 +IP6 (hlim 64, next-header DCCP (33) payload length: 48) 3ffe::1.52921 > 3ffe::2.5001: CCVal 0, CsCov 1, cksum 0x8792 (correct), dataack (ack=1385331168) seq 1337846931 +IP6 (hlim 64, next-header DCCP (33) payload length: 32) 3ffe::2.5001 > 3ffe::1.52921: CCVal 0, CsCov 0, cksum 0x578b (correct), ack (ack=1337846931) seq 1385331169 +IP6 (hlim 64, next-header DCCP (33) payload length: 32) 3ffe::1.52921 > 3ffe::2.5001: CCVal 0, CsCov 0, cksum 0x61e0 (correct), close (ack=1385331169) seq 1337846932 +IP6 (hlim 64, next-header DCCP (33) payload length: 40) 3ffe::2.5001 > 3ffe::1.52921: CCVal 0, CsCov 0, cksum 0x4b59 (correct), reset (code=closed) (ack=1337846932) seq 1385331170 diff --git a/tests/dccp_partial_csum_v6_simple.pcap b/tests/dccp_partial_csum_v6_simple.pcap new file mode 100644 index 0000000000000000000000000000000000000000..c343d9060dbf6e7e9812497b68cb2f7e55e7a6c0 GIT binary patch literal 782 zcmca|c+)~A1{MYw`2U}Qff2~j><)2#TE@;024sUUgNRaOXdnao%e}GkZFdtuA_|HQ z_WwW(IABEMGo9Nh+{wZ4UJ7KQ|K2wfK`IqkSecYq7?~7+7-UOF1v^6;P#lCI=0og) z+G2oV3lo|xjKZDgcJeTA7c&D52%1#+0Avu%Hi&)7tc*-diXcK6XgkQ(e?VKKfa*XP zi{Df*Y{lv~PKJOac8G10Kn8(r2U(%U%%IJ}zzDMG83RAUf0&_&=|Ai?F}6?QgxEA0 zZW9C8ngeH5nHe)ub8_+(%JYkIQn*021~Ty@;tm{ZD4~iOcUVJ}gCV>d