From: Ahmed Abdelsalam Date: Thu, 22 Nov 2018 18:05:16 +0000 (+0100) Subject: Fix checksum calculation for IPv6 Segment Routing (SRv6) traffic X-Git-Tag: tcpdump-4.99-bp~865 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/a87d6a044893dace0534e91d77ce236a101d5794 Fix checksum calculation for IPv6 Segment Routing (SRv6) traffic The checksum calculation for IPv6 packets is based on a pseudo header that includes the packet's final Destination Address (DA). If the IPv6 packet contains a Routing header, the final DA is the last element of the Routing header [RFC8200]. Currently, tcpdump supports Routing header types 0 and 2. IPv6 Segment Routing Header (SRH) is a new Routing header type (4). SRH is defined in draft-ietf-6man-segment-routing-header [1]. This patch fix the checksum calculation for SRv6 packets. It allows tcpdump to get the final DA value from SRv6 packets. [1] https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-17 --- diff --git a/print-ip6.c b/print-ip6.c index b6893cf3..9f8b4dbf 100644 --- a/print-ip6.c +++ b/print-ip6.c @@ -53,6 +53,7 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, const void *dst_addr; const struct ip6_rthdr *dp; const struct ip6_rthdr0 *dp0; + const struct ip6_srh *srh; const u_char *p; int i, len; @@ -114,6 +115,19 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, p += 16; } break; + case IPV6_RTHDR_TYPE_4: + /* IPv6 Segment Routing Header (SRH) */ + srh = (const struct ip6_srh *)dp; + if (len % 2 == 1) + goto trunc; + p = (const u_char *) srh->srh_segments; + /* + * The list of segments are encoded in the reverse order. + * Accordingly, the final DA is encoded in srh_segments[0] + */ + ND_TCHECK_16(p); + dst_addr = (const void *)p; + break; default: break; diff --git a/tests/TESTLIST b/tests/TESTLIST index aaf22aea..ceab4adf 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -237,6 +237,7 @@ dnssec-vv dnssec.pcap dnssec-vv.out -vv ipv6-bad-version ipv6-bad-version.pcap ipv6-bad-version.out ipv6-routing-header ipv6-routing-header.pcap ipv6-routing-header.out -v ipv6-srh-ext-header ipv6-srh-ext-header.pcap ipv6-srh-ext-header.out -v +ipv6-srh-insert-cksum ipv6-srh-insert-cksum.pcap ipv6-srh-insert-cksum.out -v # Loopback/CTP test case loopback loopback.pcap loopback.out diff --git a/tests/ipv6-srh-insert-cksum.out b/tests/ipv6-srh-insert-cksum.out new file mode 100644 index 00000000..1815c661 --- /dev/null +++ b/tests/ipv6-srh-insert-cksum.out @@ -0,0 +1 @@ + 1 17:59:40.591932 IP6 (flowlabel 0x8f8b8, hlim 64, next-header Routing (43) payload length: 1088) 12::1 > 2::f1:0: srcrt (len=6, type=4, segleft=2, last-entry=2, flags=0x0, tag=0, [0]b2::2, [1]3::d6, [2]2::f1:0) 57745 > 5001: [udp sum ok] UDP, length 1024 diff --git a/tests/ipv6-srh-insert-cksum.pcap b/tests/ipv6-srh-insert-cksum.pcap new file mode 100644 index 00000000..daeb55ad Binary files /dev/null and b/tests/ipv6-srh-insert-cksum.pcap differ