MPTCP: parse MP_CAPABLE v1 options

A new version of MPTCP protocol (RFC8684) has been published, with some
changes to the MP_CAPABLE options handling. Let tcpdump print the protocol
version, and adjust parsing of MP_CAPABLE options according to RFC8684.

Signed-off-by: Davide Caratti <dcaratti@redhat.com>
diff --git a/print-mptcp.c b/print-mptcp.c
index e3a82fe..43258e5 100644
--- a/print-mptcp.c
+++ b/print-mptcp.c
@@ -178,21 +178,30 @@
 {
         const struct mp_capable *mpc = (const struct mp_capable *) opt;
 
-        if (!(opt_len == 12 && (flags & TH_SYN)) &&
-            !(opt_len == 20 && (flags & (TH_SYN | TH_ACK)) == TH_ACK))
+        if (!((opt_len == 12 || opt_len == 4) && flags & TH_SYN) &&
+            !((opt_len == 20 || opt_len == 22) && (flags & (TH_SYN | TH_ACK)) ==
+              TH_ACK))
                 return 0;
 
-        if (MP_CAPABLE_OPT_VERSION(mpc->sub_ver) != 0) {
-                ND_PRINT(" Unknown Version (%u)", MP_CAPABLE_OPT_VERSION(mpc->sub_ver));
-                return 1;
+        switch (MP_CAPABLE_OPT_VERSION(mpc->sub_ver)) {
+                case 0: /* fall through */
+                case 1:
+                        ND_PRINT(" v%d", MP_CAPABLE_OPT_VERSION(mpc->sub_ver));
+                        break;
+                default:
+                        ND_PRINT(" Unknown Version (%d)",
+                                  MP_CAPABLE_OPT_VERSION(mpc->sub_ver));
+                        return 1;
         }
 
         if (GET_U_1(mpc->flags) & MP_CAPABLE_C)
                 ND_PRINT(" csum");
-        ND_PRINT(" {0x%" PRIx64, GET_BE_U_8(mpc->sender_key));
-        if (opt_len == 20) /* ACK */
-                ND_PRINT(",0x%" PRIx64, GET_BE_U_8(mpc->receiver_key));
-        ND_PRINT("}");
+        if (opt_len == 12 || opt_len >= 20) {
+                ND_PRINT(" {0x%" PRIx64, GET_BE_U_8(mpc->sender_key));
+                if (opt_len >= 20)
+                        ND_PRINT(",0x%" PRIx64, GET_BE_U_8(mpc->receiver_key));
+                ND_PRINT("}");
+        }
         return 1;
 }
 
diff --git a/tests/TESTLIST b/tests/TESTLIST
index 695888d..9d33686 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -219,7 +219,8 @@
 msnlb2		msnlb2.pcapng		msnlb2.out
 
 # MPTCP tests
-mptcp		mptcp.pcap		mptcp.out
+mptcp-v0	mptcp-v0.pcap		mptcp-v0.out
+mptcp-v1	mptcp-v1.pcap		mptcp-v1.out
 mptcp-fclose	mptcp-fclose.pcap	mptcp-fclose.out
 # TFO tests
 tfo		tfo-5c1fa7f9ae91.pcap	tfo.out
diff --git a/tests/mptcp-fclose.out b/tests/mptcp-fclose.out
index d57c195..1e28a65 100644
--- a/tests/mptcp-fclose.out
+++ b/tests/mptcp-fclose.out
@@ -1,8 +1,8 @@
     1  15:40:42.767916 ARP, Request who-has 10.2.1.2 tell 10.2.1.1, length 28
     2  15:40:42.768169 ARP, Reply 10.2.1.2 is-at d6:06:3c:4a:35:7a, length 28
-    3  15:40:42.768187 IP 10.1.1.2.37479 > 10.2.1.2.2002: Flags [S], seq 1895673170, win 14600, options [mss 1460,sackOK,TS val 38230 ecr 0,nop,wscale 6,mptcp capable csum {0x9b59be3d695e66a7}], length 0
-    4  15:40:42.768439 IP 10.2.1.2.2002 > 10.1.1.2.37479: Flags [S.], seq 2868811558, ack 1895673171, win 14280, options [mss 1460,sackOK,TS val 4294943148 ecr 38230,nop,wscale 6,mptcp capable csum {0xd005b1ab34bad344}], length 0
-    5  15:40:42.768831 IP 10.1.1.2.37479 > 10.2.1.2.2002: Flags [.], ack 1, win 229, options [nop,nop,TS val 38230 ecr 4294943148,mptcp capable csum {0x9b59be3d695e66a7,0xd005b1ab34bad344}], length 0
+    3  15:40:42.768187 IP 10.1.1.2.37479 > 10.2.1.2.2002: Flags [S], seq 1895673170, win 14600, options [mss 1460,sackOK,TS val 38230 ecr 0,nop,wscale 6,mptcp capable v0 csum {0x9b59be3d695e66a7}], length 0
+    4  15:40:42.768439 IP 10.2.1.2.2002 > 10.1.1.2.37479: Flags [S.], seq 2868811558, ack 1895673171, win 14280, options [mss 1460,sackOK,TS val 4294943148 ecr 38230,nop,wscale 6,mptcp capable v0 csum {0xd005b1ab34bad344}], length 0
+    5  15:40:42.768831 IP 10.1.1.2.37479 > 10.2.1.2.2002: Flags [.], ack 1, win 229, options [nop,nop,TS val 38230 ecr 4294943148,mptcp capable v0 csum {0x9b59be3d695e66a7,0xd005b1ab34bad344}], length 0
     6  15:40:42.769130 IP 10.1.1.2.37479 > 10.2.1.2.2002: Flags [P.], seq 1:2, ack 1, win 229, options [nop,nop,TS val 38230 ecr 4294943148,mptcp dss ack 3386645601 seq 2976985014 subseq 1 len 1 csum 0x9e91], length 1
     7  15:40:42.769364 IP 10.2.1.2.2002 > 10.1.1.2.37479: Flags [.], ack 2, win 224, options [nop,nop,TS val 4294943148 ecr 38230,mptcp dss ack 2976985015], length 0
     8  15:40:43.780182 IP 10.2.1.2.2002 > 10.1.1.2.37479: Flags [P.], seq 1:2, ack 2, win 224, options [nop,nop,TS val 4294943250 ecr 38230,mptcp dss ack 2976985015 seq 3386645601 subseq 1 len 1 csum 0x54ab], length 1
diff --git a/tests/mptcp.out b/tests/mptcp-v0.out
similarity index 99%
rename from tests/mptcp.out
rename to tests/mptcp-v0.out
index 29bbc5e..722759d 100644
--- a/tests/mptcp.out
+++ b/tests/mptcp-v0.out
@@ -1,6 +1,6 @@
-    1  12:56:35.701161 IP 10.2.1.2.35961 > 10.1.1.2.22: Flags [S], seq 2912457561, win 14600, options [mss 1460,sackOK,TS val 4294943152 ecr 0,nop,wscale 6,mptcp capable csum {0x9c9eabd1e46a33b2}], length 0
-    2  12:56:35.701661 IP 10.1.1.2.22 > 10.2.1.2.35961: Flags [S.], seq 125971326, ack 2912457562, win 14280, options [mss 1460,sackOK,TS val 4294943467 ecr 4294943152,nop,wscale 5,mptcp capable csum {0x967d2770b6960552}], length 0
-    3  12:56:35.702022 IP 10.2.1.2.35961 > 10.1.1.2.22: Flags [.], ack 1, win 229, options [nop,nop,TS val 4294943152 ecr 4294943467,mptcp capable csum {0x9c9eabd1e46a33b2,0x967d2770b6960552}], length 0
+    1  12:56:35.701161 IP 10.2.1.2.35961 > 10.1.1.2.22: Flags [S], seq 2912457561, win 14600, options [mss 1460,sackOK,TS val 4294943152 ecr 0,nop,wscale 6,mptcp capable v0 csum {0x9c9eabd1e46a33b2}], length 0
+    2  12:56:35.701661 IP 10.1.1.2.22 > 10.2.1.2.35961: Flags [S.], seq 125971326, ack 2912457562, win 14280, options [mss 1460,sackOK,TS val 4294943467 ecr 4294943152,nop,wscale 5,mptcp capable v0 csum {0x967d2770b6960552}], length 0
+    3  12:56:35.702022 IP 10.2.1.2.35961 > 10.1.1.2.22: Flags [.], ack 1, win 229, options [nop,nop,TS val 4294943152 ecr 4294943467,mptcp capable v0 csum {0x9c9eabd1e46a33b2,0x967d2770b6960552}], length 0
     4  12:56:35.786074 IP 10.1.1.2.22 > 10.2.1.2.35961: Flags [P.], seq 1:42, ack 1, win 447, options [nop,nop,TS val 4294943474 ecr 4294943152,mptcp add-addr id 1 10.1.2.2,mptcp dss ack 3576348362 seq 3518592144 subseq 1 len 41 csum 0x82f], length 41: SSH: SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze1
     5  12:56:35.786240 IP 10.2.1.2.35961 > 10.1.1.2.22: Flags [.], ack 42, win 229, options [nop,nop,TS val 4294943168 ecr 4294943474,mptcp dss ack 3518592185], length 0
     6  12:56:35.787634 IP 10.2.1.2.35961 > 10.1.1.2.22: Flags [P.], seq 1:42, ack 42, win 229, options [nop,nop,TS val 4294943168 ecr 4294943474,mptcp dss ack 3518592185 seq 3576348362 subseq 1 len 41 csum 0x45c9], length 41: SSH: SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze2
diff --git a/tests/mptcp.pcap b/tests/mptcp-v0.pcap
similarity index 100%
rename from tests/mptcp.pcap
rename to tests/mptcp-v0.pcap
Binary files differ
diff --git a/tests/mptcp-v1.out b/tests/mptcp-v1.out
new file mode 100644
index 0000000..e0e43f8
--- /dev/null
+++ b/tests/mptcp-v1.out
@@ -0,0 +1,20 @@
+    1  15:51:06.676845 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [S], seq 2180756989, win 65535, options [mss 1460,sackOK,TS val 464494241 ecr 0,nop,wscale 8,mptcp capable v1], length 0
+    2  15:51:06.676888 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [S.], seq 791415661, ack 2180756990, win 65535, options [mss 1460,sackOK,TS val 3275212179 ecr 464494241,nop,wscale 8,mptcp capable v1 {0x29a6c86981ad933c}], length 0
+    3  15:51:06.676958 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [.], ack 1, win 256, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp capable v1 {0x1fdb5df328bc3def,0x29a6c86981ad933c}], length 0
+    4  15:51:06.677099 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [P.], seq 1:7101, ack 1, win 256, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp capable v1 {0x1fdb5df328bc3def,0x29a6c86981ad933c},nop,nop], length 7100
+    5  15:51:06.677113 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [.], ack 7101, win 312, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss ack 14413541604287230030], length 0
+    6  15:51:06.677130 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [P.], seq 7101:8193, ack 1, win 256, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss ack 11713449205243392242], length 1092
+    7  15:51:06.677136 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [P.], seq 1:7101, ack 7101, win 312, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss ack 14413541604287230030 seq 11713449205243392242 subseq 1 len 8192,nop,nop], length 7100
+    8  15:51:06.677163 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [.], ack 7101, win 312, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss ack 11713449205243392242], length 0
+    9  15:51:06.677173 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [.], seq 8193:9613, ack 7101, win 312, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss ack 11713449205243392242 seq 14413541604287238222 subseq 8193 len 2076,nop,nop], length 1420
+   10  15:51:06.677174 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [P.], seq 7101:8193, ack 7101, win 312, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss ack 14413541604287230030], length 1092
+   11  15:51:06.677188 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [.], ack 8193, win 323, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss ack 14413541604287230030], length 0
+   12  15:51:06.677188 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [.], ack 8193, win 323, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss ack 11713449205243392242], length 0
+   13  15:51:06.677207 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [P.], seq 9613:10269, ack 8193, win 323, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss ack 11713449205243392242], length 656
+   14  15:51:06.677221 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [.], ack 9613, win 334, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss ack 14413541604287230030], length 0
+   15  15:51:06.677237 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [.], ack 10269, win 345, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss ack 14413541604287230030], length 0
+   16  15:51:06.677259 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [F.], seq 10269, ack 8193, win 323, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss fin ack 11713449205243400434 seq 14413541604287240298 subseq 0 len 1,nop,nop], length 0
+   17  15:51:06.677321 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [P.], seq 8193:10269, ack 10270, win 345, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss ack 14413541604287238222 seq 11713449205243400434 subseq 8193 len 2076,nop,nop], length 2076
+   18  15:51:06.677357 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [.], ack 10269, win 339, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss ack 11713449205243400434], length 0
+   19  15:51:06.677404 IP 10.0.2.1.10004 > 10.0.1.1.33306: Flags [F.], seq 10269, ack 10270, win 345, options [nop,nop,TS val 3275212179 ecr 464494241,mptcp dss fin ack 14413541604287240298 seq 11713449205243402510 subseq 0 len 1,nop,nop], length 0
+   20  15:51:06.677429 IP 10.0.1.1.33306 > 10.0.2.1.10004: Flags [.], ack 10270, win 339, options [nop,nop,TS val 464494241 ecr 3275212179,mptcp dss ack 11713449205243402510], length 0
diff --git a/tests/mptcp-v1.pcap b/tests/mptcp-v1.pcap
new file mode 100644
index 0000000..871e3a5
--- /dev/null
+++ b/tests/mptcp-v1.pcap
Binary files differ