aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-http2.c
diff options
context:
space:
mode:
authorAlexis La Goutte <alexis.lagoutte@gmail.com>2013-12-15 19:07:40 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2013-12-15 19:07:40 +0000
commit93594d61b2ddf737c5f36f408c1cde22e4fd23b6 (patch)
tree4c81a2d380a5b545fcf49a932f513112ea1e3f11 /epan/dissectors/packet-http2.c
parentc00a12652fc6d1c4273ba3a66f94862cf6512443 (diff)
Upgrade to HTTP2 draft-09
Add HTTP2 to Decode as svn path=/trunk/; revision=54131
Diffstat (limited to 'epan/dissectors/packet-http2.c')
-rw-r--r--epan/dissectors/packet-http2.c102
1 files changed, 76 insertions, 26 deletions
diff --git a/epan/dissectors/packet-http2.c b/epan/dissectors/packet-http2.c
index 80fd0c16a0..b3f80ed78a 100644
--- a/epan/dissectors/packet-http2.c
+++ b/epan/dissectors/packet-http2.c
@@ -26,8 +26,8 @@
/*
* The information used comes from:
- * Hypertext Transfer Protocol version 2.0 draft-ietf-httpbis-http2-06
- * HTTP Header Compression draft-ietf-httpbis-header-compression-02
+ * Hypertext Transfer Protocol version 2.0 draft-ietf-httpbis-http2-09
+ * HTTP Header Compression draft-ietf-httpbis-header-compression-05
*
* TODO
* Support HTTP Header Compression (draft-ietf-httpbis-header-compression)
@@ -50,6 +50,7 @@
static int proto_http2 = -1;
static int hf_http2 = -1;
static int hf_http2_length = -1;
+static int hf_http2_len_rsv = -1;
static int hf_http2_type = -1;
static int hf_http2_r = -1;
static int hf_http2_streamid = -1;
@@ -61,10 +62,13 @@ static int hf_http2_flags_end_stream = -1;
static int hf_http2_flags_end_headers = -1;
static int hf_http2_flags_priority = -1;
static int hf_http2_flags_end_push_promise = -1;
-static int hf_http2_flags_pong = -1;
+static int hf_http2_flags_settings_ack = -1;
+static int hf_http2_flags_ping_ack = -1;
static int hf_http2_flags_reserved = -1;
static int hf_http2_flags_reserved1 = -1;
+#if 0
static int hf_http2_flags_reserved2 = -1;
+#endif
static int hf_http2_flags_reserved3 = -1;
static int hf_http2_flags_reserved4 = -1;
/* Headers */
@@ -80,6 +84,8 @@ static int hf_http2_rst_stream_error = -1;
static int hf_http2_settings = -1;
static int hf_http2_settings_r = -1;
static int hf_http2_settings_identifier = -1;
+static int hf_http2_settings_header_table_size = -1;
+static int hf_http2_settings_enable_push = -1;
static int hf_http2_settings_max_concurrent_streams = -1;
static int hf_http2_settings_initial_window_size = -1;
static int hf_http2_settings_flow_control_options = -1;
@@ -109,11 +115,13 @@ static gint ett_http2_settings = -1;
static expert_field ei_http2_flags_epp_old = EI_INIT;
-
static dissector_handle_t data_handle;
+static dissector_handle_t http2_handle;
#define FRAME_HEADER_LENGTH 8
#define MAGIC_FRAME_LENGTH 24
+#define MASK_HTTP2_LENGTH 0X1FFF
+#define MASK_HTTP2_LEN_RSV 0XE000
#define MASK_HTTP2_RESERVED 0x80000000
#define MASK_HTTP2_STREAMID 0X7FFFFFFF
#define MASK_HTTP2_PRIORITY 0X7FFFFFFF
@@ -150,7 +158,7 @@ static const value_string http2_type_vals[] = {
#define HTTP2_FLAGS_PR 0x08
#define HTTP2_FLAGS_EPP_OLD 0x01 /* from draft-04 */
#define HTTP2_FLAGS_EPP 0x04
-#define HTTP2_FLAGS_PO 0x01
+#define HTTP2_FLAGS_ACK 0x01
#define HTTP2_FLAGS_R 0xFF
#define HTTP2_FLAGS_R1 0xFE
#define HTTP2_FLAGS_R2 0xFA
@@ -168,32 +176,42 @@ static guint8 kMagicHello[] = {
#define EC_NO_ERROR 0
#define EC_PROTOCOL_ERROR 1
#define EC_INTERNAL_ERROR 2
-#define EC_FLOW_CONTROL_ERROR 4
+#define EC_FLOW_CONTROL_ERROR 3
+#define EC_SETTINGS_TIMEOUT 4
#define EC_STREAM_CLOSED 5
-#define EC_FRAME_TOO_LARGE 6
+#define EC_FRAME_SIZE_ERROR 6
#define EC_REFUSED_STREAM 7
#define EC_CANCEL 8
#define EC_COMPRESSION_ERROR 9
+#define EC_CONNECT_ERROR 10
+#define EC_ENHANCE_YOUR_CALM 420
static const value_string http2_error_codes_vals[] = {
- { EC_NO_ERROR, "NO ERROR" },
+ { EC_NO_ERROR, "NO8ERROR" },
{ EC_PROTOCOL_ERROR, "PROTOCOL_ERROR" },
{ EC_INTERNAL_ERROR, "INTERNAL_ERROR" },
{ EC_FLOW_CONTROL_ERROR, "FLOW_CONTROL_ERROR" },
+ { EC_SETTINGS_TIMEOUT, "SETTINGS_TIMEOUT" },
{ EC_STREAM_CLOSED, "STREAM_CLOSED" },
- { EC_FRAME_TOO_LARGE, "FRAME_TOO_LARGE" },
+ { EC_FRAME_SIZE_ERROR, "FRAME_SIZE_ERROR" },
{ EC_REFUSED_STREAM, "REFUSED_STREAM" },
{ EC_CANCEL, "CANCEL" },
{ EC_COMPRESSION_ERROR, "COMPRESSION_ERROR" },
+ { EC_CONNECT_ERROR, "CONNECT_ERROR" },
+ { EC_ENHANCE_YOUR_CALM, "ENHANCE_YOUR_CALM" },
{ 0, NULL }
};
/* Settings */
+#define HTTP2_SETTINGS_HEADER_TABLE_SIZE 1
+#define HTTP2_SETTINGS_ENABLE_PUSH 2
#define HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS 4
#define HTTP2_SETTINGS_INITIAL_WINDOW_SIZE 7
#define HTTP2_SETTINGS_FLOW_CONTROL_OPTIONS 10
static const value_string http2_settings_vals[] = {
+ { HTTP2_SETTINGS_HEADER_TABLE_SIZE, "Header table size" },
+ { HTTP2_SETTINGS_ENABLE_PUSH, "Enable PUSH" },
{ HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, "Max concurrent streams" },
{ HTTP2_SETTINGS_INITIAL_WINDOW_SIZE, "Initial Windows size" },
{ HTTP2_SETTINGS_FLOW_CONTROL_OPTIONS, "Flow Control Options" },
@@ -211,13 +229,12 @@ static const value_string http2_settings_vals[] = {
| | | PRIORITY(8) | |
| 2 | PRIORITY | - | Section 6.3 |
| 3 | RST_STREAM | - | Section 6.4 |
- | 4 | SETTINGS | - | Section 6.5 |
+ | 4 | SETTINGS | ACK(1) | Section 6.5 |
| 5 | PUSH_PROMISE | END_PUSH_PROMISE(4) | Section 6.6 |
- | 6 | PING | PONG(1) | Section 6.7 |
+ | 6 | PING | ACK(1) | Section 6.7 |
| 7 | GOAWAY | - | Section 6.8 |
| 9 | WINDOW_UPDATE | - | Section 6.9 |
- | 10 | CONTINUATION | END_STREAM(1), | Section 6.10 |
- | | | END_HEADERS(4) | |
+ | 10 | CONTINUATION | END_HEADERS(4) | Section 6.10 |
+--------+---------------+---------------------------+--------------+
*/
static guint8
@@ -251,17 +268,18 @@ dissect_http2_header_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_
proto_tree_add_item(flags_tree, hf_http2_flags_reserved4, tvb, offset, 1, ENC_NA);
break;
case HTTP2_PING:
- proto_tree_add_item(flags_tree, hf_http2_flags_pong, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(flags_tree, hf_http2_flags_ping_ack, tvb, offset, 1, ENC_NA);
proto_tree_add_item(flags_tree, hf_http2_flags_reserved1, tvb, offset, 1, ENC_NA);
break;
case HTTP2_CONTINUATION:
- proto_tree_add_item(flags_tree, hf_http2_flags_end_stream, tvb, offset, 1, ENC_NA);
proto_tree_add_item(flags_tree, hf_http2_flags_end_headers, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(flags_tree, hf_http2_flags_reserved2, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(flags_tree, hf_http2_flags_reserved4, tvb, offset, 1, ENC_NA);
break;
case HTTP2_PRIORITY:
case HTTP2_RST_STREAM:
case HTTP2_SETTINGS:
+ proto_tree_add_item(flags_tree, hf_http2_flags_settings_ack, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(flags_tree, hf_http2_flags_reserved1, tvb, offset, 1, ENC_NA);
case HTTP2_GOAWAY:
case HTTP2_WINDOW_UPDATE:
default:
@@ -336,6 +354,12 @@ dissect_http2_settings(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_
switch(settingsid){
+ case HTTP2_SETTINGS_HEADER_TABLE_SIZE:
+ proto_tree_add_item(settings_tree, hf_http2_settings_header_table_size, tvb, offset, 4, ENC_NA);
+ break;
+ case HTTP2_SETTINGS_ENABLE_PUSH:
+ proto_tree_add_item(settings_tree, hf_http2_settings_enable_push, tvb, offset, 4, ENC_NA);
+ break;
case HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
proto_tree_add_item(settings_tree, hf_http2_settings_max_concurrent_streams, tvb, offset, 4, ENC_NA);
break;
@@ -377,7 +401,7 @@ static int
dissect_http2_ping(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 flags)
{
/* TODO : Add Response time */
- if(flags & HTTP2_FLAGS_PO)
+ if(flags & HTTP2_FLAGS_ACK)
{
proto_tree_add_item(http2_tree, hf_http2_pong, tvb, offset, 8, ENC_NA);
}else{
@@ -478,7 +502,8 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
}
proto_tree_add_item(http2_tree, hf_http2_length, tvb, offset, 2, ENC_NA);
- length = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(http2_tree, hf_http2_len_rsv, tvb, offset, 2, ENC_NA);
+ length = tvb_get_ntohs(tvb, offset) & MASK_HTTP2_LENGTH;
offset += 2;
proto_tree_add_item(http2_tree, hf_http2_type, tvb, offset, 1, ENC_NA);
@@ -571,7 +596,7 @@ dissect_http2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_clear(pinfo->cinfo, COL_INFO);
ti = proto_tree_add_item(tree, proto_http2, tvb, 0, -1, ENC_NA);
- proto_item_append_text(ti, " (draft-06)");
+ proto_item_append_text(ti, " (draft-09)");
http2_tree = proto_item_add_subtree(ti, ett_http2);
@@ -606,8 +631,13 @@ proto_register_http2(void)
},
{ &hf_http2_length,
{ "Length", "http2.length",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "The length of the frame payload (The 8 octets of the frame header are not included)", HFILL }
+ FT_UINT16, BASE_DEC, NULL, MASK_HTTP2_LENGTH,
+ "The length (14 bits) of the frame payload (The 8 octets of the frame header are not included)", HFILL }
+ },
+ { &hf_http2_len_rsv,
+ { "Reserved", "http2.len.rsv",
+ FT_UINT16, BASE_DEC, NULL, MASK_HTTP2_LEN_RSV,
+ "Must be zero", HFILL }
},
{ &hf_http2_type,
{ "Type", "http2.type",
@@ -643,12 +673,12 @@ proto_register_http2(void)
{ &hf_http2_flags_end_stream,
{ "End Stream", "http2.flags.es",
FT_BOOLEAN, 8, NULL, HTTP2_FLAGS_ES,
- "Set indicates that this frame is the last that the endpoint will send for the identified stream", HFILL }
+ "Indicates that this frame is the last that the endpoint will send for the identified stream", HFILL }
},
{ &hf_http2_flags_end_headers,
{ "End Headers", "http2.flags.eh",
FT_BOOLEAN, 8, NULL, HTTP2_FLAGS_EH,
- "Set indicates that this frame ends the sequence of header block fragments necessary to provide a complete set of headers", HFILL }
+ "Indicates that this frame contains an entire header block and is not followed by any CONTINUATION frames.", HFILL }
},
{ &hf_http2_flags_priority,
{ "Priority", "http2.flags.pr",
@@ -660,11 +690,16 @@ proto_register_http2(void)
FT_BOOLEAN, 8, NULL, HTTP2_FLAGS_EPP,
"Set indicates that this frame ends the sequence of header block fragments necessary to provide a complete set of headers", HFILL }
},
- { &hf_http2_flags_pong,
- { "Pong", "http2.flags.po",
- FT_BOOLEAN, 8, NULL, HTTP2_FLAGS_PO,
+ { &hf_http2_flags_ping_ack,
+ { "ACK", "http2.flags.ack.ping",
+ FT_BOOLEAN, 8, NULL, HTTP2_FLAGS_ACK,
"Set indicates that this PING frame is a PING response", HFILL }
},
+ { &hf_http2_flags_settings_ack,
+ { "ACK", "http2.flags.ack.settings",
+ FT_BOOLEAN, 8, NULL, HTTP2_FLAGS_ACK,
+ "Indicates that this frame acknowledges receipt and application of the peer's SETTINGS frame", HFILL }
+ },
{ &hf_http2_flags_reserved,
{ "Reserved", "http2.flags.r",
FT_UINT8, BASE_HEX, NULL, HTTP2_FLAGS_R,
@@ -675,11 +710,13 @@ proto_register_http2(void)
FT_UINT8, BASE_HEX, NULL, HTTP2_FLAGS_R1,
"(Must be zero)", HFILL }
},
+#if 0
{ &hf_http2_flags_reserved2,
{ "Reserved", "http2.flags.r2",
FT_UINT8, BASE_HEX, NULL, HTTP2_FLAGS_R2,
"(Must be zero)", HFILL }
},
+#endif
{ &hf_http2_flags_reserved3,
{ "Reserved", "http2.flags.r3",
FT_UINT8, BASE_HEX, NULL, HTTP2_FLAGS_R3,
@@ -742,6 +779,16 @@ proto_register_http2(void)
FT_UINT24, BASE_DEC, VALS(http2_settings_vals), 0x0,
NULL, HFILL }
},
+ { &hf_http2_settings_header_table_size,
+ { "Header table size", "http2.settings.header_table_size",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Allows the sender to inform the remote endpoint of the size of the header compression table used to decode header blocks. The initial value is 4096 byte", HFILL }
+ },
+ { &hf_http2_settings_enable_push,
+ { "Enable PUSH", "http2.settings.enable_push",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "The initial value is 1, which indicates that push is permitted", HFILL }
+ },
{ &hf_http2_settings_max_concurrent_streams,
{ "Max concurrent streams", "http2.settings.max_concurrent_streams",
FT_UINT32, BASE_DEC, NULL, 0x0,
@@ -863,6 +910,9 @@ proto_reg_handoff_http2(void)
{
data_handle = find_dissector("data");
+ http2_handle = new_create_dissector_handle(dissect_http2, proto_http2);
+ dissector_add_handle("tcp.port", http2_handle);
+
heur_dissector_add("ssl", dissect_http2_heur, proto_http2);
heur_dissector_add("http", dissect_http2_heur, proto_http2);
}