From Francesco Fondelli via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8128...
authoralagoutte <alagoutte@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 23 Dec 2012 18:40:55 +0000 (18:40 +0000)
committeralagoutte <alagoutte@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 23 Dec 2012 18:40:55 +0000 (18:40 +0000)
This patch provides
i) support for Shared Use of Experimental TCP Options (draft-ietf-tcpm-experimental-options-03)
ii) support for TCP Fast Open (draft-ietf-tcpm-fastopen-02).

A new 'TFO=R' string is appended at the column info in case a client sends a SYN packet with a Fast Open Cookie Request. Moreover, if the server responds with a SYN-ACK containing a Fast Open Cookie option a 'TFO=C' is shown (as well as in any subsequent client attempt to send SYN + DATA).

tcp.options.tfo display filter can be used in order to easily select the complete TFO three-way handshake.

Chrome (and I think also Firefox) has support for client-side TFO. Linux 3.7 got both client and server-side support.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@46723 f5534014-38df-0310-8fa8-9805f1628bb7

AUTHORS
epan/dissectors/packet-tcp.c

diff --git a/AUTHORS b/AUTHORS
index aa8c9e303a2f4faf9e661c351f420a28b469ec98..34647515a019c6c7fc10599a0a37790157479f22 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -2365,6 +2365,8 @@ Francesco Fondelli        <francesco.fondelli[AT]gmail.com> {
        Support for MPLS Packet Loss and Delay Measurement, RFC 6374
        Support for DCCP Simultaneous-Open for NAT Traversal, RFC 5596
        MPLS-TP Protection State Coordination (PSC) Protocol, RFC 6378
+       Support for Shared Use of Experimental TCP Options
+       Support for TCP Fast Open
 }
 
 Artem Tamazov           <artem.tamazov[AT]tellabs.com> {
index 444f854d041fa2969428c149b4393d76204ee011..7d835e1e6f03146ad31b226d22cfd35a02ec1c35 100644 (file)
@@ -176,6 +176,7 @@ static int hf_tcp_option_md5 = -1;
 static int hf_tcp_option_qs = -1;
 static int hf_tcp_option_exp = -1;
 static int hf_tcp_option_exp_data = -1;
+static int hf_tcp_option_exp_magic_number = -1;
 
 static int hf_tcp_option_rvbd_probe = -1;
 static int hf_tcp_option_rvbd_probe_version1 = -1;
@@ -237,6 +238,9 @@ static int hf_tcp_option_mptcp_ipver = -1;
 static int hf_tcp_option_mptcp_ipv4 = -1;
 static int hf_tcp_option_mptcp_ipv6 = -1;
 static int hf_tcp_option_mptcp_port = -1;
+static int hf_tcp_option_fast_open = -1;
+static int hf_tcp_option_fast_open_cookie_request = -1;
+static int hf_tcp_option_fast_open_cookie = -1;
 
 static int hf_tcp_ts_relative = -1;
 static int hf_tcp_ts_delta = -1;
@@ -304,10 +308,18 @@ static gint ett_tcp_opt_rvbd_trpy_flags = -1;
  */
 static gboolean tcp_no_subdissector_on_error = FALSE;
 
+/* 
+ * FF: (draft-ietf-tcpm-experimental-options-03)
+ * With this flag set we assume the option structure for experimental 
+ * codepoints (253, 254) has a magic number field (first field after the 
+ * Kind and Length).  The magic number is used to differentiate different 
+ * experiments and thus will be used in data dissection.
+ */
+static gboolean tcp_exp_options_with_magic = TRUE;
+
 /*
  *  TCP option
  */
-
 #define TCPOPT_NOP              1       /* Padding */
 #define TCPOPT_EOL              0       /* End of options */
 #define TCPOPT_MSS              2       /* Segment size negotiating */
@@ -337,7 +349,6 @@ static gboolean tcp_no_subdissector_on_error = FALSE;
 /*
  *     TCP option lengths
  */
-
 #define TCPOLEN_MSS            4
 #define TCPOLEN_WINDOW         3
 #define TCPOLEN_SACK_PERM      2
@@ -2358,18 +2369,47 @@ dissect_tcpopt_exp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
 {
     proto_item *item;
     proto_tree *exp_tree;
+    proto_item *hidden_item;
+    guint16 magic;
 
     item = proto_tree_add_item(opt_tree, hf_tcp_option_exp, tvb,
-        offset, optlen, ENC_NA);
+                               offset, optlen, ENC_NA);
     exp_tree = proto_item_add_subtree(item, ett_tcp_option_exp);
     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
     proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
-    proto_tree_add_item(exp_tree, hf_tcp_option_exp_data, tvb,
-        offset + 2, optlen - 2, ENC_NA);
-    tcp_info_append_uint(pinfo, "Expxx", TRUE);
+    if (tcp_exp_options_with_magic && ((optlen - 2) > 0)) {
+        magic = tvb_get_ntohs(tvb, offset + 2);
+        proto_tree_add_item(exp_tree, hf_tcp_option_exp_magic_number, tvb,
+                            offset + 2, 2, ENC_BIG_ENDIAN);
+        switch (magic) {
+        case 0xf989:
+            /* FF: draft-ietf-tcpm-fastopen-02, TCP Fast Open */
+            hidden_item = proto_tree_add_item(exp_tree, hf_tcp_option_fast_open,
+                                              tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+            PROTO_ITEM_SET_HIDDEN(hidden_item);
+            if ((optlen - 2) == 2) {
+                /* Fast Open Cookie Request */
+                proto_tree_add_item(exp_tree, hf_tcp_option_fast_open_cookie_request, 
+                                    tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+                col_append_fstr(pinfo->cinfo, COL_INFO, " TFO=R");
+            } else if ((optlen - 2) > 2) {
+                /* Fast Open Cookie */
+                proto_tree_add_item(exp_tree, hf_tcp_option_fast_open_cookie, 
+                                    tvb, offset + 4, optlen - 4, ENC_NA);
+                col_append_fstr(pinfo->cinfo, COL_INFO, " TFO=C");
+            }
+            break;
+        default:
+            /* Unknown magic number */
+            break;
+        }
+    } else {
+        proto_tree_add_item(exp_tree, hf_tcp_option_exp_data, tvb,
+                            offset + 2, optlen - 2, ENC_NA);
+        tcp_info_append_uint(pinfo, "Expxx", TRUE);
+    }
 }
 
-
 static void
 dissect_tcpopt_sack_perm(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
@@ -5129,6 +5169,10 @@ proto_register_tcp(void)
           { "Data", "tcp.options.experimental.data", FT_BYTES,
             BASE_NONE, NULL, 0x0, NULL, HFILL}},
 
+        { &hf_tcp_option_exp_magic_number,
+          { "Magic Number", "tcp.options.experimental.magic_number", FT_UINT16,
+            BASE_HEX, NULL, 0x0, NULL, HFILL}},
+
         { &hf_tcp_option_sack_perm,
           { "TCP SACK Permitted Option", "tcp.options.sack_perm",
             FT_BOOLEAN,
@@ -5534,6 +5578,18 @@ proto_register_tcp(void)
           { "Out of band connection Client Port", "tcp.options.rvbd.trpy.client.port",
             FT_UINT16, BASE_DEC, NULL , 0x0, NULL, HFILL }},
 
+        { &hf_tcp_option_fast_open,
+          { "Fast Open", "tcp.options.tfo", FT_NONE,
+            BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+        { &hf_tcp_option_fast_open_cookie_request,
+          { "Fast Open Cookie Request", "tcp.options.tfo.request", FT_NONE,
+            BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+        { &hf_tcp_option_fast_open_cookie,
+          { "Fast Open Cookie", "tcp.options.tfo.cookie", FT_BYTES,
+            BASE_NONE, NULL, 0x0, NULL, HFILL}},
+
         { &hf_tcp_pdu_time,
           { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
             "How long time has passed until the last frame of this PDU", HFILL}},
@@ -5708,6 +5764,11 @@ proto_register_tcp(void)
         "Do not call any subdissectors for Retransmitted or OutOfOrder segments",
         &tcp_no_subdissector_on_error);
 
+    prefs_register_bool_preference(tcp_module, "dissect_experimental_options_with_magic",
+        "TCP Experimental Options with a Magic Number",
+        "Assume TCP Experimental Options (253, 254) have a Magic Number and use it for dissection",
+        &tcp_exp_options_with_magic);
+
     register_init_routine(tcp_init);
 }