IPv6 routing header type 4 is known as Segment Routing Header (SRH).
It is used by Segment Routing (SR) to steer a packet through a
controlled set of instructions, called segments. It is described in
https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-07
An extension is added to allow tcpdump to print SRH information.
#define IPV6_RTHDR_TYPE_0 0
#define IPV6_RTHDR_TYPE_2 2
+#define IPV6_RTHDR_TYPE_4 4
/* Type 0 Routing header */
/* Also used for Type 2 */
struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
};
+/**
+ * Type 4 Routing header
+ * known as Segment Routing Header 'SRH'
+ */
+struct ip6_srh {
+ nd_uint8_t srh_nxt; /* next header */
+ nd_uint8_t srh_len; /* length in units of 8 octets */
+ nd_uint8_t srh_type; /* Routing Type 4 */
+ nd_uint8_t srh_segleft; /* segments left */
+ nd_uint8_t srh_last_ent; /* Last Entry*/
+ nd_uint8_t srh_flags; /* Flags */
+ nd_uint16_t srh_tag; /* Tag */
+ struct in6_addr srh_segments[1]; /* SRH segments list*/
+};
+
/* Fragment header */
struct ip6_frag {
nd_uint8_t ip6f_nxt; /* next header */
{
const struct ip6_rthdr *dp;
const struct ip6_rthdr0 *dp0;
+ const struct ip6_srh *srh;
const u_char *ep;
u_int i, len, type;
const struct in6_addr *addr;
ND_PRINT((ndo, ") "));
return((EXTRACT_U_1(dp0->ip6r0_len) + 1) << 3);
break;
+ case IPV6_RTHDR_TYPE_4:
+ srh = (const struct ip6_srh *)dp;
+ ND_PRINT((ndo, ", last-entry=%u", EXTRACT_U_1(srh->srh_last_ent)));
+
+ ND_TCHECK(srh->srh_flags);
+ if (EXTRACT_U_1(srh->srh_flags) || ndo->ndo_vflag) {
+ ND_PRINT((ndo, ", flags=0x%0x",
+ EXTRACT_U_1(srh->srh_flags)));
+ }
+
+ ND_PRINT((ndo, ", tag=%x", EXTRACT_BE_U_2(srh->srh_tag)));
+
+ if (len % 2 == 1)
+ goto trunc;
+ len >>= 1;
+ addr = &srh->srh_segments[0];
+ for (i = 0; i < len; i++) {
+ if ((const u_char *)(addr + 1) > ep)
+ goto trunc;
+
+ ND_PRINT((ndo, ", [%d]%s", i, ip6addr_string(ndo, addr)));
+ addr++;
+ }
+ /*(*/
+ ND_PRINT((ndo, ") "));
+ return((EXTRACT_U_1(srh->srh_len) + 1) << 3);
+ break;
default:
goto trunc;
break;
#IPv6 tests
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
# Loopback/CTP test case
loopback loopback.pcap loopback.out
--- /dev/null
+IP6 (flowlabel 0x889ad, hlim 64, next-header Routing (43) payload length: 144) a:b:c:12::1 > a:b:c:2::f1:0: srcrt (len=4, type=4, segleft=1, last-entry=1, flags=0x0, tag=0, [0]a:b:c:3::d6, [1]a:b:c:2::f1:0) IP6 (flowlabel 0x889ad, hlim 64, next-header ICMPv6 (58) payload length: 64) a:b:c:12::1 > b2::2: [icmp6 sum ok] ICMP6, echo request, seq 1