Upgrade to HTTP2 draft-09

Add HTTP2 to Decode as

svn path=/trunk/; revision=54131
This commit is contained in:
Alexis La Goutte 2013-12-15 19:07:40 +00:00
parent c00a12652f
commit 93594d61b2

View file

@ -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);
}