summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAhmed Abdelsalam <amsalam20@gmail.com>2017-12-29 17:43:35 +0100
committerAhmed Abdelsalam <amsalam20@gmail.com>2017-12-29 17:43:35 +0100
commit9c33608cb2fb6a64e1b76745efa530a63de08100 (patch)
tree66a09d9a96185cfa3ddc7ace7d1f6d2195237db8
parent2f7e7d424e495eb92b1ee5b765e908e7bf80e48c (diff)
downloadtcpdump-9c33608cb2fb6a64e1b76745efa530a63de08100.tar.gz
Add support for IPv6 routing header type 4
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.
-rw-r--r--ip6.h16
-rw-r--r--print-rt6.c28
-rw-r--r--tests/TESTLIST2
-rw-r--r--tests/ipv6-srh-ext-header.out1
-rw-r--r--tests/ipv6-srh-ext-header.pcapbin0 -> 238 bytes
5 files changed, 46 insertions, 1 deletions
diff --git a/ip6.h b/ip6.h
index 35f12e42..9ed1499c 100644
--- a/ip6.h
+++ b/ip6.h
@@ -174,6 +174,7 @@ struct ip6_rthdr {
#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 */
@@ -186,6 +187,21 @@ struct ip6_rthdr0 {
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 */
diff --git a/print-rt6.c b/print-rt6.c
index 269496aa..af74fa0a 100644
--- a/print-rt6.c
+++ b/print-rt6.c
@@ -40,6 +40,7 @@ rt6_print(netdissect_options *ndo, const u_char *bp, const u_char *bp2 _U_)
{
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;
@@ -83,6 +84,33 @@ rt6_print(netdissect_options *ndo, const u_char *bp, const u_char *bp2 _U_)
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;
diff --git a/tests/TESTLIST b/tests/TESTLIST
index ecc93da8..1e2a8508 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -222,7 +222,7 @@ dnssec-vv dnssec.pcap dnssec-vv.out -vv
#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
diff --git a/tests/ipv6-srh-ext-header.out b/tests/ipv6-srh-ext-header.out
new file mode 100644
index 00000000..bca97eaa
--- /dev/null
+++ b/tests/ipv6-srh-ext-header.out
@@ -0,0 +1 @@
+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
diff --git a/tests/ipv6-srh-ext-header.pcap b/tests/ipv6-srh-ext-header.pcap
new file mode 100644
index 00000000..871b9e42
--- /dev/null
+++ b/tests/ipv6-srh-ext-header.pcap
Binary files differ