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
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;
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;
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
--- /dev/null
+ 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