diff options
author | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2013-12-15 19:07:40 +0000 |
---|---|---|
committer | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2013-12-15 19:07:40 +0000 |
commit | 93594d61b2ddf737c5f36f408c1cde22e4fd23b6 (patch) | |
tree | 4c81a2d380a5b545fcf49a932f513112ea1e3f11 /epan/dissectors/packet-http2.c | |
parent | c00a12652fc6d1c4273ba3a66f94862cf6512443 (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.c | 102 |
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); } |