summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-http2.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:26 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:26 +0000
commitc4e8a3222648fcf22ca207f1815ebbf7cd144eeb (patch)
tree93d5c6aa93d9987680dd1adad5685e2ad698f223 /epan/dissectors/packet-http2.c
parentAdding upstream version 4.2.6. (diff)
downloadwireshark-upstream.tar.xz
wireshark-upstream.zip
Adding upstream version 4.4.0.upstream/4.4.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--epan/dissectors/packet-http2.c1258
1 files changed, 690 insertions, 568 deletions
diff --git a/epan/dissectors/packet-http2.c b/epan/dissectors/packet-http2.c
index fa51d447..724eae6e 100644
--- a/epan/dissectors/packet-http2.c
+++ b/epan/dissectors/packet-http2.c
@@ -56,6 +56,7 @@
#include "wsutil/strtoi.h"
#include "wsutil/str_util.h"
#include <wsutil/unicode-utils.h>
+#include <wsutil/wsjson.h>
#ifdef HAVE_NGHTTP2
#define http2_header_repr_type_VALUE_STRING_LIST(XXX) \
@@ -75,16 +76,16 @@ VALUE_STRING_ARRAY(http2_header_repr_type);
/*
* Decompression of zlib or brotli encoded entities.
*/
-#if defined(HAVE_ZLIB) || defined(HAVE_BROTLI)
-static gboolean http2_decompress_body = TRUE;
+#if defined(HAVE_ZLIB) || defined(HAVE_ZLIBNG)|| defined(HAVE_BROTLI)
+static bool http2_decompress_body = true;
#else
-static gboolean http2_decompress_body = FALSE;
+static bool http2_decompress_body;
#endif
/* Try to dissect reassembled http2.data.data according to content-type later */
static dissector_table_t media_type_dissector_table;
-static int http_eo_tap = -1;
+static int http_eo_tap;
#endif
/* Some protocols on top of http2 require http2 streams to remain open. For example, the stream
@@ -108,7 +109,7 @@ enum http2_data_reassembly_mode_t {
};
static enum http2_data_reassembly_mode_t
-http2_get_data_reassembly_mode(const gchar* content_type)
+http2_get_data_reassembly_mode(const char* content_type)
{
return dissector_get_string_handle(streaming_content_type_dissector_table, content_type) ?
HTTP2_DATA_REASSEMBLY_MODE_STREAMING : HTTP2_DATA_REASSEMBLY_MODE_END_STREAM;
@@ -118,34 +119,34 @@ http2_get_data_reassembly_mode(const gchar* content_type)
/* Decompressed header field */
typedef struct {
/* one of http2_header_repr_type */
- gint type;
+ int type;
/* encoded (compressed) length */
- gint length;
+ int length;
union {
struct {
/* header data */
char *data;
/* length of data */
- guint datalen;
+ unsigned datalen;
/* name index or name/value index if type is one of
HTTP2_HD_INDEXED and HTTP2_HD_*_INDEXED_NAMEs */
- guint idx;
+ unsigned idx;
} data;
/* header table size if type == HTTP2_HD_HEADER_TABLE_SIZE_UPDATE */
- guint header_table_size;
+ unsigned header_table_size;
} table;
} http2_header_t;
/* Context to decode header representation */
typedef struct {
/* one of http2_header_repr_type */
- gint type;
+ int type;
/* final or temporal result of decoding integer */
- guint integer;
+ unsigned integer;
/* next bit shift to made when decoding integer */
- guint next_shift;
- /* TRUE if integer decoding was completed */
- gboolean complete;
+ unsigned next_shift;
+ /* true if integer decoding was completed */
+ bool complete;
} http2_header_repr_info_t;
/* Cached decompressed header data in one packet_info */
@@ -157,40 +158,40 @@ typedef struct {
header for dissecting later. */
wmem_list_frame_t *current;
/* Bytes decompressed if we exceeded MAX_HTTP2_HEADER_SIZE */
- guint header_size_reached;
+ unsigned header_size_reached;
/* Bytes decompressed if we had not exceeded MAX_HTTP2_HEADER_SIZE */
- guint header_size_attempted;
- /* TRUE if we found >= MAX_HTTP2_HEADER_LINES */
- gboolean header_lines_exceeded;
+ unsigned header_size_attempted;
+ /* true if we found >= MAX_HTTP2_HEADER_LINES */
+ bool header_lines_exceeded;
} http2_header_data_t;
/* In-flight SETTINGS data. */
typedef struct {
/* header table size last seen in SETTINGS */
- guint32 header_table_size;
+ uint32_t header_table_size;
/* minimum header table size in SETTINGS */
- guint32 min_header_table_size;
+ uint32_t min_header_table_size;
/* nonzero if header_table_size has effective value. */
int has_header_table_size;
} http2_settings_t;
#ifdef HAVE_NGHTTP2
-typedef guint64 http2_frame_num_t;
+typedef uint64_t http2_frame_num_t;
/* struct for per-stream, per-direction DATA frame reassembly */
typedef struct {
http2_frame_num_t data_initiated_in;
- gboolean has_transfer_encoded_body;
+ bool has_transfer_encoded_body;
/* streaming_reassembly_info only used for STREAMING reassembly mode */
streaming_reassembly_info_t* streaming_reassembly_info;
} http2_data_stream_reassembly_info_t;
/* struct for per-stream, per-direction entity body info */
typedef struct {
- gchar *content_type;
- gchar *content_type_parameters;
- gchar *content_encoding;
- gboolean is_partial_content;
+ char *content_type;
+ char *content_type_parameters;
+ char *content_encoding;
+ bool is_partial_content;
} http2_data_stream_body_info_t;
/* struct to track header state, so we know if continuation frames are part
@@ -202,7 +203,7 @@ typedef struct {
* later passes. */
http2_frame_num_t header_start_in;
http2_frame_num_t header_end_in;
- guint32 stream_id; /* Normally the same as the parent http2_stream_info_t
+ uint32_t stream_id; /* Normally the same as the parent http2_stream_info_t
* During a PUSH_PROMISE, this is the promised stream. */
/* list of pointer to wmem_array_t, which is array of http2_header_t
* that come from all HEADERS and CONTINUATION frames. */
@@ -217,9 +218,9 @@ typedef struct {
http2_data_stream_body_info_t data_stream_body_info;
http2_data_stream_reassembly_info_t data_stream_reassembly_info;
http2_header_stream_info_t header_stream_info;
- gboolean is_window_initialized;
+ bool is_window_initialized;
/* Current window size of the one-way session */
- gint32 current_window_size;
+ int32_t current_window_size;
} http2_oneway_stream_info_t;
/* struct to hold per-stream information for both directions */
@@ -230,10 +231,10 @@ typedef struct {
* the capture is started but the index will be consistent for the lifetime
* of the http2_session_t */
http2_oneway_stream_info_t oneway_stream_info[2];
- gboolean is_stream_http_connect;
- guint32 stream_id;
- guint32 request_in_frame_num;
- guint32 response_in_frame_num;
+ bool is_stream_http_connect;
+ uint32_t stream_id;
+ uint32_t request_in_frame_num;
+ uint32_t response_in_frame_num;
nstime_t request_ts;
enum http2_data_reassembly_mode_t reassembly_mode;
char *authority;
@@ -257,63 +258,63 @@ typedef struct {
nghttp2_hd_inflater *hd_inflater[2];
http2_header_repr_info_t header_repr_info[2];
wmem_map_t *per_stream_info;
- gboolean fix_dynamic_table[2];
+ bool fix_dynamic_table[2];
#endif
- guint32 current_stream_id;
+ uint32_t current_stream_id;
tcp_flow_t *fwd_flow;
/* Initial window size of new streams (in both directions) */
- guint32 initial_new_stream_window_size[2];
- /* Curent window size of the connection (in both directions) */
- gint32 current_connection_window_size[2];
+ uint32_t initial_new_stream_window_size[2];
+ /* Current window size of the connection (in both directions) */
+ int32_t current_connection_window_size[2];
} http2_session_t;
typedef struct http2_follow_tap_data {
tvbuff_t *tvb;
- guint64 stream_id;
+ uint64_t stream_id;
} http2_follow_tap_data_t;
typedef struct http2_adjust_window {
- gint32 windowSizeDiff;
- guint32 flow_index;
+ int32_t windowSizeDiff;
+ uint32_t flow_index;
} http2_adjust_window_t;
#ifdef HAVE_NGHTTP2
/* Decode as functions */
-static gpointer
+static void *
http2_current_stream_id_value(packet_info* pinfo)
{
return GUINT_TO_POINTER(http2_get_stream_id(pinfo));
}
static void
-http2_streamid_prompt(packet_info* pinfo, gchar* result)
+http2_streamid_prompt(packet_info* pinfo, char* result)
{
snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "stream (%u)", http2_get_stream_id(pinfo));
}
static void
-decode_as_http2_populate_list(const gchar* table_name _U_, decode_as_add_to_list_func add_to_list, gpointer ui_element)
+decode_as_http2_populate_list(const char* table_name _U_, decode_as_add_to_list_func add_to_list, void *ui_element)
{
decode_as_default_populate_list("media_type", add_to_list, ui_element);
}
#endif /*HAVE_NGHTTP2*/
-static GHashTable* streamid_hash = NULL;
+static GHashTable* streamid_hash;
void proto_register_http2(void);
void proto_reg_handoff_http2(void);
struct HTTP2Tap {
- guint8 type;
+ uint8_t type;
};
-static int http2_tap = -1;
-static int http2_follow_tap = -1;
+static int http2_tap;
+static int http2_follow_tap;
-static const guint8* st_str_http2 = "HTTP2";
-static const guint8* st_str_http2_type = "Type";
+static const uint8_t* st_str_http2 = "HTTP2";
+static const uint8_t* st_str_http2_type = "Type";
static int st_node_http2 = -1;
static int st_node_http2_type = -1;
@@ -323,178 +324,178 @@ static int st_node_http2_type = -1;
#define PROTO_DATA_KEY_WINDOW_SIZE_STREAM_BEFORE 2
/* Packet Header */
-static int proto_http2 = -1;
-static int hf_http2_stream = -1;
-static int hf_http2_length = -1;
-static int hf_http2_type = -1;
-static int hf_http2_r = -1;
-static int hf_http2_streamid = -1;
-static int hf_http2_magic = -1;
-static int hf_http2_unknown = -1;
+static int proto_http2;
+static int hf_http2_stream;
+static int hf_http2_length;
+static int hf_http2_type;
+static int hf_http2_r;
+static int hf_http2_streamid;
+static int hf_http2_magic;
+static int hf_http2_unknown;
/* Flags */
-static int hf_http2_flags = -1;
-static int hf_http2_flags_end_stream = -1;
-static int hf_http2_flags_end_headers = -1;
-static int hf_http2_flags_padded = -1;
-static int hf_http2_flags_priority = -1;
-static int hf_http2_flags_settings_ack = -1;
-static int hf_http2_flags_ping_ack = -1;
-static int hf_http2_flags_unused = -1;
-static int hf_http2_flags_unused_settings = -1;
-static int hf_http2_flags_unused_ping = -1;
-static int hf_http2_flags_unused_continuation = -1;
-static int hf_http2_flags_unused_push_promise = -1;
-static int hf_http2_flags_unused_data = -1;
-static int hf_http2_flags_unused_headers = -1;
+static int hf_http2_flags;
+static int hf_http2_flags_end_stream;
+static int hf_http2_flags_end_headers;
+static int hf_http2_flags_padded;
+static int hf_http2_flags_priority;
+static int hf_http2_flags_settings_ack;
+static int hf_http2_flags_ping_ack;
+static int hf_http2_flags_unused;
+static int hf_http2_flags_unused_settings;
+static int hf_http2_flags_unused_ping;
+static int hf_http2_flags_unused_continuation;
+static int hf_http2_flags_unused_push_promise;
+static int hf_http2_flags_unused_data;
+static int hf_http2_flags_unused_headers;
/* generic */
-static int hf_http2_padding = -1;
-static int hf_http2_pad_length = -1;
+static int hf_http2_padding;
+static int hf_http2_pad_length;
-static int hf_http2_weight = -1;
-static int hf_http2_weight_real = -1;
-static int hf_http2_stream_dependency = -1;
-static int hf_http2_excl_dependency = -1;
+static int hf_http2_weight;
+static int hf_http2_weight_real;
+static int hf_http2_stream_dependency;
+static int hf_http2_excl_dependency;
/* Data */
-static int hf_http2_data_segment = -1;
-static int hf_http2_data_data = -1;
-static int hf_http2_data_padding = -1;
-static int hf_http2_body_fragments = -1;
-static int hf_http2_body_fragment = -1;
-static int hf_http2_body_fragment_overlap = -1;
-static int hf_http2_body_fragment_overlap_conflicts = -1;
-static int hf_http2_body_fragment_multiple_tails = -1;
-static int hf_http2_body_fragment_too_long_fragment = -1;
-static int hf_http2_body_fragment_error = -1;
-static int hf_http2_body_fragment_count = -1;
-static int hf_http2_body_reassembled_in = -1;
-static int hf_http2_body_reassembled_length = -1;
-static int hf_http2_body_reassembled_data = -1;
+static int hf_http2_data_segment;
+static int hf_http2_data_data;
+static int hf_http2_data_padding;
+static int hf_http2_body_fragments;
+static int hf_http2_body_fragment;
+static int hf_http2_body_fragment_overlap;
+static int hf_http2_body_fragment_overlap_conflicts;
+static int hf_http2_body_fragment_multiple_tails;
+static int hf_http2_body_fragment_too_long_fragment;
+static int hf_http2_body_fragment_error;
+static int hf_http2_body_fragment_count;
+static int hf_http2_body_reassembled_in;
+static int hf_http2_body_reassembled_length;
+static int hf_http2_body_reassembled_data;
/* Headers */
-static int hf_http2_headers = -1;
-static int hf_http2_headers_padding = -1;
-static int hf_http2_header = -1;
-static int hf_http2_header_length = -1;
-static int hf_http2_header_count = -1;
-static int hf_http2_header_name_length = -1;
-static int hf_http2_header_name = -1;
-static int hf_http2_header_value_length = -1;
-static int hf_http2_header_value = -1;
-static int hf_http2_header_unescaped = -1;
-static int hf_http2_header_repr = -1;
-static int hf_http2_header_index = -1;
-static int hf_http2_header_table_size_update = -1;
-static int hf_http2_header_table_size = -1;
-static int hf_http2_fake_header_count = -1;
-static int hf_http2_fake_header = -1;
-static int hf_http2_header_request_full_uri = -1;
+static int hf_http2_headers;
+static int hf_http2_headers_padding;
+static int hf_http2_header;
+static int hf_http2_header_length;
+static int hf_http2_header_count;
+static int hf_http2_header_name_length;
+static int hf_http2_header_name;
+static int hf_http2_header_value_length;
+static int hf_http2_header_value;
+static int hf_http2_header_unescaped;
+static int hf_http2_header_repr;
+static int hf_http2_header_index;
+static int hf_http2_header_table_size_update;
+static int hf_http2_header_table_size;
+static int hf_http2_fake_header_count;
+static int hf_http2_fake_header;
+static int hf_http2_header_request_full_uri;
/* RST Stream */
-static int hf_http2_rst_stream_error = -1;
+static int hf_http2_rst_stream_error;
/* Settings */
-static int hf_http2_settings = -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_max_frame_size = -1;
-static int hf_http2_settings_max_header_list_size = -1;
-static int hf_http2_settings_extended_connect = -1;
-static int hf_http2_settings_no_rfc7540_priorities = -1;
-static int hf_http2_settings_unknown = -1;
+static int hf_http2_settings;
+static int hf_http2_settings_identifier;
+static int hf_http2_settings_header_table_size;
+static int hf_http2_settings_enable_push;
+static int hf_http2_settings_max_concurrent_streams;
+static int hf_http2_settings_initial_window_size;
+static int hf_http2_settings_max_frame_size;
+static int hf_http2_settings_max_header_list_size;
+static int hf_http2_settings_extended_connect;
+static int hf_http2_settings_no_rfc7540_priorities;
+static int hf_http2_settings_unknown;
/* Push Promise */
-static int hf_http2_push_promise_r = -1;
-static int hf_http2_push_promise_promised_stream_id = -1;
-static int hf_http2_push_promise_header = -1;
-static int hf_http2_push_promise_padding = -1;
+static int hf_http2_push_promise_r;
+static int hf_http2_push_promise_promised_stream_id;
+static int hf_http2_push_promise_header;
+static int hf_http2_push_promise_padding;
/* Ping */
-static int hf_http2_ping = -1;
-static int hf_http2_pong = -1;
+static int hf_http2_ping;
+static int hf_http2_pong;
/* Goaway */
-static int hf_http2_goaway_r = -1;
-static int hf_http2_goaway_last_stream_id = -1;
-static int hf_http2_goaway_error = -1;
-static int hf_http2_goaway_addata = -1;
+static int hf_http2_goaway_r;
+static int hf_http2_goaway_last_stream_id;
+static int hf_http2_goaway_error;
+static int hf_http2_goaway_addata;
/* Window Update */
-static int hf_http2_window_update_r = -1;
-static int hf_http2_window_update_window_size_increment = -1;
+static int hf_http2_window_update_r;
+static int hf_http2_window_update_window_size_increment;
/* Continuation */
-static int hf_http2_continuation_header = -1;
-static int hf_http2_continuation_padding = -1;
+static int hf_http2_continuation_header;
+static int hf_http2_continuation_padding;
/* Altsvc */
-static int hf_http2_altsvc_origin_len = -1;
-static int hf_http2_altsvc_origin = -1;
-static int hf_http2_altsvc_field_value = -1;
+static int hf_http2_altsvc_origin_len;
+static int hf_http2_altsvc_origin;
+static int hf_http2_altsvc_field_value;
/* Calculated */
-static int hf_http2_calculated_window_size_connection_before = -1;
-static int hf_http2_calculated_window_size_connection_after = -1;
-static int hf_http2_calculated_window_size_stream_before = -1;
-static int hf_http2_calculated_window_size_stream_after = -1;
+static int hf_http2_calculated_window_size_connection_before;
+static int hf_http2_calculated_window_size_connection_after;
+static int hf_http2_calculated_window_size_stream_before;
+static int hf_http2_calculated_window_size_stream_after;
#if HAVE_NGHTTP2
/* HTTP2 header static fields */
-static int hf_http2_headers_status = -1;
-static int hf_http2_headers_path = -1;
-static int hf_http2_headers_method = -1;
-static int hf_http2_headers_scheme = -1;
-static int hf_http2_headers_accept = -1;
-static int hf_http2_headers_accept_charset = -1;
-static int hf_http2_headers_accept_encoding = -1;
-static int hf_http2_headers_accept_language = -1;
-static int hf_http2_headers_accept_ranges = -1;
-static int hf_http2_headers_access_control_allow_origin = -1;
-static int hf_http2_headers_age = -1;
-static int hf_http2_headers_allow = -1;
-static int hf_http2_headers_authorization = -1;
-static int hf_http2_headers_authority = -1;
-static int hf_http2_headers_cache_control = -1;
-static int hf_http2_headers_content_disposition = -1;
-static int hf_http2_headers_content_encoding = -1;
-static int hf_http2_headers_content_language = -1;
-static int hf_http2_headers_content_length = -1;
-static int hf_http2_headers_content_location = -1;
-static int hf_http2_headers_content_range = -1;
-static int hf_http2_headers_content_type = -1;
-static int hf_http2_headers_cookie = -1;
-static int hf_http2_headers_date = -1;
-static int hf_http2_headers_etag = -1;
-static int hf_http2_headers_expect = -1;
-static int hf_http2_headers_expires = -1;
-static int hf_http2_headers_from = -1;
-static int hf_http2_headers_if_match = -1;
-static int hf_http2_headers_if_modified_since = -1;
-static int hf_http2_headers_if_none_match = -1;
-static int hf_http2_headers_if_range = -1;
-static int hf_http2_headers_if_unmodified_since = -1;
-static int hf_http2_headers_last_modified = -1;
-static int hf_http2_headers_link = -1;
-static int hf_http2_headers_location = -1;
-static int hf_http2_headers_max_forwards = -1;
-static int hf_http2_headers_proxy_authenticate = -1;
-static int hf_http2_headers_proxy_authorization = -1;
-static int hf_http2_headers_range = -1;
-static int hf_http2_headers_referer = -1;
-static int hf_http2_headers_refresh = -1;
-static int hf_http2_headers_retry_after = -1;
-static int hf_http2_headers_server = -1;
-static int hf_http2_headers_set_cookie = -1;
-static int hf_http2_headers_strict_transport_security = -1;
-static int hf_http2_headers_user_agent = -1;
-static int hf_http2_headers_vary = -1;
-static int hf_http2_headers_via = -1;
-static int hf_http2_headers_www_authenticate = -1;
+static int hf_http2_headers_status;
+static int hf_http2_headers_path;
+static int hf_http2_headers_method;
+static int hf_http2_headers_scheme;
+static int hf_http2_headers_accept;
+static int hf_http2_headers_accept_charset;
+static int hf_http2_headers_accept_encoding;
+static int hf_http2_headers_accept_language;
+static int hf_http2_headers_accept_ranges;
+static int hf_http2_headers_access_control_allow_origin;
+static int hf_http2_headers_age;
+static int hf_http2_headers_allow;
+static int hf_http2_headers_authorization;
+static int hf_http2_headers_authority;
+static int hf_http2_headers_cache_control;
+static int hf_http2_headers_content_disposition;
+static int hf_http2_headers_content_encoding;
+static int hf_http2_headers_content_language;
+static int hf_http2_headers_content_length;
+static int hf_http2_headers_content_location;
+static int hf_http2_headers_content_range;
+static int hf_http2_headers_content_type;
+static int hf_http2_headers_cookie;
+static int hf_http2_headers_date;
+static int hf_http2_headers_etag;
+static int hf_http2_headers_expect;
+static int hf_http2_headers_expires;
+static int hf_http2_headers_from;
+static int hf_http2_headers_if_match;
+static int hf_http2_headers_if_modified_since;
+static int hf_http2_headers_if_none_match;
+static int hf_http2_headers_if_range;
+static int hf_http2_headers_if_unmodified_since;
+static int hf_http2_headers_last_modified;
+static int hf_http2_headers_link;
+static int hf_http2_headers_location;
+static int hf_http2_headers_max_forwards;
+static int hf_http2_headers_proxy_authenticate;
+static int hf_http2_headers_proxy_authorization;
+static int hf_http2_headers_range;
+static int hf_http2_headers_referer;
+static int hf_http2_headers_refresh;
+static int hf_http2_headers_retry_after;
+static int hf_http2_headers_server;
+static int hf_http2_headers_set_cookie;
+static int hf_http2_headers_strict_transport_security;
+static int hf_http2_headers_user_agent;
+static int hf_http2_headers_vary;
+static int hf_http2_headers_via;
+static int hf_http2_headers_www_authenticate;
#endif
/* Blocked */
/* Origin */
-static int hf_http2_origin = -1;
-static int hf_http2_origin_origin_len = -1;
-static int hf_http2_origin_origin = -1;
+static int hf_http2_origin;
+static int hf_http2_origin_origin_len;
+static int hf_http2_origin_origin;
/* Priority Update */
-static int hf_http2_priority_update_stream_id = -1;
-static int hf_http2_priority_update_field_value = -1;
+static int hf_http2_priority_update_stream_id;
+static int hf_http2_priority_update_field_value;
/* Generated fields */
-static int hf_http2_time = -1;
-static int hf_http2_request_in = -1;
-static int hf_http2_response_in = -1;
+static int hf_http2_time;
+static int hf_http2_request_in;
+static int hf_http2_response_in;
/*
* These values *should* be large enough to handle most use cases while
@@ -512,20 +513,20 @@ static int hf_http2_response_in = -1;
*/
#define MAX_HTTP2_HEADER_SIZE (256 * 1024)
#define MAX_HTTP2_HEADER_LINES 200
-static expert_field ei_http2_header_size = EI_INIT;
-static expert_field ei_http2_header_lines = EI_INIT;
-static expert_field ei_http2_body_decompression_failed = EI_INIT;
-static expert_field ei_http2_reassembly_error = EI_INIT;
-
-static gint ett_http2 = -1;
-static gint ett_http2_header = -1;
-static gint ett_http2_headers = -1;
-static gint ett_http2_flags = -1;
-static gint ett_http2_settings = -1;
-static gint ett_http2_encoded_entity = -1;
-static gint ett_http2_body_fragment = -1;
-static gint ett_http2_body_fragments = -1;
-static gint ett_http2_origin = -1;
+static expert_field ei_http2_header_size;
+static expert_field ei_http2_header_lines;
+static expert_field ei_http2_body_decompression_failed;
+static expert_field ei_http2_reassembly_error;
+
+static int ett_http2;
+static int ett_http2_header;
+static int ett_http2_headers;
+static int ett_http2_flags;
+static int ett_http2_settings;
+static int ett_http2_encoded_entity;
+static int ett_http2_body_fragment;
+static int ett_http2_body_fragments;
+static int ett_http2_origin;
#ifdef HAVE_NGHTTP2
static const fragment_items http2_body_fragment_items = {
@@ -554,9 +555,9 @@ static const fragment_items http2_body_fragment_items = {
bytes. We reduce memory usage by caching header field in this
wmem_map_t to reuse its memory region when we see the same header
field next time. */
-static wmem_map_t *http2_hdrcache_map = NULL;
+static wmem_map_t *http2_hdrcache_map;
/* Header name_length + name + value_length + value */
-static char *http2_header_pstr = NULL;
+static char *http2_header_pstr;
#endif
#ifdef HAVE_NGHTTP2
@@ -568,16 +569,16 @@ enum header_field_type {
};
typedef struct _header_field_t {
- gchar* header_name;
+ char* header_name;
enum header_field_type header_type;
- gchar* header_desc;
+ char* header_desc;
} header_field_t;
-static header_field_t* header_fields = NULL;
-static guint num_header_fields = 0;
-static guint num_header_fields_cleanup = 0;
+static header_field_t* header_fields;
+static unsigned num_header_fields;
+static unsigned num_header_fields_cleanup;
-static GHashTable* header_fields_hash = NULL;
+static GHashTable* header_fields_hash;
static bool
header_fields_update_cb(void *r, char **err)
@@ -587,13 +588,13 @@ header_fields_update_cb(void *r, char **err)
if (rec->header_name == NULL) {
*err = g_strdup("Header name can't be empty");
- return FALSE;
+ return false;
}
g_strstrip(rec->header_name);
if (rec->header_name[0] == 0) {
*err = g_strdup("Header name can't be empty");
- return FALSE;
+ return false;
}
/* Check for invalid characters (to avoid asserting out when
@@ -602,20 +603,20 @@ header_fields_update_cb(void *r, char **err)
c = proto_check_field_name(rec->header_name);
if (c) {
*err = ws_strdup_printf("Header name can't contain '%c'", c);
- return FALSE;
+ return false;
}
/* If the hash table is empty(e.g. on startup), do not try to check a value */
if (header_fields_hash != NULL) {
- const gint *entry = (const gint *) g_hash_table_lookup(header_fields_hash, rec->header_name);
+ const int *entry = (const int *) g_hash_table_lookup(header_fields_hash, rec->header_name);
if (entry != NULL) {
*err = ws_strdup_printf("This header field is already defined in UAT or it is a static header field");
- return FALSE;
+ return false;
}
}
*err = NULL;
- return TRUE;
+ return true;
}
static void *
@@ -643,13 +644,13 @@ header_fields_free_cb(void*r)
}
-static hf_register_info* hf_uat = NULL;
+static hf_register_info* hf_uat;
static void
deregister_header_fields(void)
{
if (hf_uat) {
- for (guint i = 0; i < num_header_fields_cleanup; ++i) {
+ for (unsigned i = 0; i < num_header_fields_cleanup; ++i) {
proto_deregister_field(proto_http2, *(hf_uat[i].p_id));
g_free(hf_uat[i].p_id);
}
@@ -668,9 +669,9 @@ deregister_header_fields(void)
static void
header_fields_post_update_cb(void)
{
- gint* hf_id;
- gchar* header_name;
- gchar* header_name_key;
+ int* hf_id;
+ char* header_name;
+ char* header_name_key;
deregister_header_fields();
@@ -679,9 +680,9 @@ header_fields_post_update_cb(void)
hf_uat = g_new0(hf_register_info, num_header_fields);
num_header_fields_cleanup = num_header_fields;
- for (guint i = 0; i < num_header_fields; i++) {
- hf_id = g_new(gint,1);
- *hf_id = -1;
+ for (unsigned i = 0; i < num_header_fields; i++) {
+ hf_id = g_new(int,1);
+ *hf_id = 0;
header_name = g_strdup(header_fields[i].header_name);
header_name_key = g_ascii_strdown(header_name, -1);
@@ -1025,8 +1026,8 @@ register_static_headers(void) {
"Authentication method that should be used to gain access to a resource", HFILL}
}
};
- gchar* header_name;
- for (guint i = 0; i < G_N_ELEMENTS(hf); ++i) {
+ char* header_name;
+ for (unsigned i = 0; i < G_N_ELEMENTS(hf); ++i) {
header_name = g_strdup(hf[i].hfinfo.name);
g_hash_table_insert(header_fields_hash, header_name, &hf[i].hfinfo.id);
@@ -1049,15 +1050,16 @@ VALUE_STRING_ARRAY(http2_direction_type_vals);
/* The fake headers will be used if the HEADERS frame before the first DATA is missing. */
typedef struct {
range_t* server_port_range;
- guint32 stream_id; /* 0 means applicable to all streams */
+ uint32_t stream_id; /* 0 means applicable to all streams */
http2_direction_type direction;
- gchar* header_name;
- gchar* header_value;
- gboolean enable; /* enable or disable this rule */
+ char* header_name;
+ char* header_value;
+ bool override; /* override existing header */
+ bool enable; /* enable or disable this rule */
} http2_fake_header_t;
-static http2_fake_header_t* http2_fake_headers = NULL;
-static guint num_http2_fake_headers = 0;
+static http2_fake_header_t* http2_fake_headers;
+static unsigned num_http2_fake_headers;
static void*
http2_fake_headers_copy_cb(void* n, const void* o, size_t siz _U_)
@@ -1065,7 +1067,7 @@ http2_fake_headers_copy_cb(void* n, const void* o, size_t siz _U_)
http2_fake_header_t* new_rec = (http2_fake_header_t*)n;
const http2_fake_header_t* old_rec = (const http2_fake_header_t*)o;
- /* copy values like guint32 */
+ /* copy values like uint32_t */
memcpy(new_rec, old_rec, sizeof(http2_fake_header_t));
if (old_rec->server_port_range)
@@ -1087,7 +1089,7 @@ http2_fake_headers_update_cb(void* r, char** err)
if (ranges_are_equal(rec->server_port_range, empty)) {
*err = g_strdup("Must specify server port(s) (like 50051 or 50051,60051-60054)");
wmem_free(NULL, empty);
- return FALSE;
+ return false;
}
wmem_free(NULL, empty);
@@ -1095,29 +1097,29 @@ http2_fake_headers_update_cb(void* r, char** err)
/* Check header_name */
if (rec->header_name == NULL) {
*err = g_strdup("Header name can't be empty");
- return FALSE;
+ return false;
}
g_strstrip(rec->header_name);
if (rec->header_name[0] == 0) {
*err = g_strdup("Header name can't be empty");
- return FALSE;
+ return false;
}
/* check value */
if (rec->header_value == NULL) {
*err = g_strdup("Header value can't be empty");
- return FALSE;
+ return false;
}
g_strstrip(rec->header_value);
if (rec->header_name[0] == 0) {
*err = g_strdup("Header value can't be empty");
- return FALSE;
+ return false;
}
*err = NULL;
- return TRUE;
+ return true;
}
static void
@@ -1136,10 +1138,11 @@ UAT_VS_DEF(http2_fake_headers, direction, http2_fake_header_t, http2_direction_t
DIRECTION_IN, try_val_to_str(DIRECTION_IN, http2_direction_type_vals))
UAT_CSTRING_CB_DEF(http2_fake_headers, header_name, http2_fake_header_t)
UAT_CSTRING_CB_DEF(http2_fake_headers, header_value, http2_fake_header_t)
+UAT_BOOL_CB_DEF(http2_fake_headers, override, http2_fake_header_t)
UAT_BOOL_CB_DEF(http2_fake_headers, enable, http2_fake_header_t)
-static const gchar*
-get_fake_header_value(packet_info* pinfo, const gchar* name, gboolean the_other_direction)
+static const char*
+get_fake_header_value(packet_info* pinfo, const char* name, bool the_other_direction, bool* override)
{
if (num_http2_fake_headers == 0) {
return NULL;
@@ -1147,12 +1150,12 @@ get_fake_header_value(packet_info* pinfo, const gchar* name, gboolean the_other_
http2_direction_type direction;
range_t* server_port_range;
- guint32 stream_id = http2_get_stream_id(pinfo);
+ uint32_t stream_id = http2_get_stream_id(pinfo);
- for (guint i = 0; i < num_http2_fake_headers; i++) {
+ for (unsigned i = 0; i < num_http2_fake_headers; i++) {
http2_fake_header_t* fake_header = http2_fake_headers + i;
- if (fake_header->enable == FALSE ||
+ if (fake_header->enable == false ||
(fake_header->stream_id > 0 && fake_header->stream_id != stream_id)) {
continue;
}
@@ -1167,6 +1170,9 @@ get_fake_header_value(packet_info* pinfo, const gchar* name, gboolean the_other_
}
if (fake_header->direction == direction && strcmp(fake_header->header_name, name) == 0) {
+ if(override) {
+ *override = fake_header->override;
+ }
return wmem_strdup(pinfo->pool, fake_header->header_value);
}
}
@@ -1195,6 +1201,7 @@ static reassembly_table http2_streaming_reassembly_table;
#define FRAME_HEADER_LENGTH 9
#define MAGIC_FRAME_LENGTH 24
+#define MAGIC_FRAME_FIRST_LINE 16
#define MASK_HTTP2_RESERVED 0x80000000
#define MASK_HTTP2_STREAMID 0X7FFFFFFF
#define MASK_HTTP2_PRIORITY 0X7FFFFFFF
@@ -1262,7 +1269,7 @@ static const value_string http2_type_vals[] = {
#define IS_HTTP2_END_STREAM(flags) (flags & HTTP2_FLAGS_END_STREAM)
/* Magic Header : PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n */
-static guint8 kMagicHello[] = {
+static uint8_t kMagicHello[] = {
0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54,
0x54, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a,
0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a
@@ -1337,7 +1344,7 @@ static const value_string http2_settings_vals[] = {
*/
#define INITIAL_WINDOW_SIZE 65535
-static guint32
+static uint32_t
select_http2_flow_index(packet_info *pinfo, http2_session_t *h2session)
{
struct tcp_analysis *tcpd;
@@ -1359,14 +1366,14 @@ hd_inflate_del_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, vo
http2_hdrcache_map = NULL;
http2_header_pstr = NULL;
- return FALSE;
+ return false;
}
static http2_stream_info_t*
-get_stream_info_for_id(packet_info *pinfo, http2_session_t *http2_session, gboolean initializeOppositeDirection, guint32 stream_id)
+get_stream_info_for_id(packet_info *pinfo, http2_session_t *http2_session, bool initializeOppositeDirection, uint32_t stream_id)
{
wmem_map_t *stream_map = http2_session->per_stream_info;
- guint32 flow_index = select_http2_flow_index(pinfo, http2_session);
+ uint32_t flow_index = select_http2_flow_index(pinfo, http2_session);
http2_stream_info_t *stream_info = (http2_stream_info_t *)wmem_map_lookup(stream_map, GINT_TO_POINTER(stream_id));
if (stream_info == NULL) {
@@ -1377,9 +1384,9 @@ get_stream_info_for_id(packet_info *pinfo, http2_session_t *http2_session, gbool
stream_info->oneway_stream_info[0].header_stream_info.stream_id = stream_id;
stream_info->oneway_stream_info[1].header_stream_info.stream_id = stream_id;
stream_info->reassembly_mode = HTTP2_DATA_REASSEMBLY_MODE_END_STREAM;
- stream_info->oneway_stream_info[0].is_window_initialized = FALSE;
+ stream_info->oneway_stream_info[0].is_window_initialized = false;
stream_info->oneway_stream_info[0].current_window_size = INITIAL_WINDOW_SIZE;
- stream_info->oneway_stream_info[1].is_window_initialized = FALSE;
+ stream_info->oneway_stream_info[1].is_window_initialized = false;
stream_info->oneway_stream_info[1].current_window_size = INITIAL_WINDOW_SIZE;
nstime_set_unset(&(stream_info->request_ts));
wmem_map_insert(stream_map, GINT_TO_POINTER(stream_id), stream_info);
@@ -1389,23 +1396,23 @@ get_stream_info_for_id(packet_info *pinfo, http2_session_t *http2_session, gbool
* particular direction, initialize the window size
* in that direction to the current initial window size for
* that direction. Flip what we're checking around if
- * initializeOppositeDirection is TRUE.
+ * initializeOppositeDirection is true.
*/
if (initializeOppositeDirection) {
flow_index ^= 1;
}
if (!stream_info->oneway_stream_info[flow_index].is_window_initialized) {
stream_info->oneway_stream_info[flow_index].current_window_size = http2_session->initial_new_stream_window_size[flow_index];
- stream_info->oneway_stream_info[flow_index].is_window_initialized = TRUE;
+ stream_info->oneway_stream_info[flow_index].is_window_initialized = true;
}
return stream_info;
}
static http2_stream_info_t*
-get_stream_info(packet_info *pinfo, http2_session_t *http2_session, gboolean initializeOppositeDirection)
+get_stream_info(packet_info *pinfo, http2_session_t *http2_session, bool initializeOppositeDirection)
{
- guint32 stream_id = http2_session->current_stream_id;
+ uint32_t stream_id = http2_session->current_stream_id;
return get_stream_info_for_id(pinfo, http2_session, initializeOppositeDirection, stream_id);
}
@@ -1439,8 +1446,8 @@ get_http2_session(packet_info *pinfo, conversation_t* conversation)
g_direct_equal);
/* Unless found otherwise, assume that some earlier Header Block
* Fragments were missing and that recovery should be attempted. */
- h2session->fix_dynamic_table[0] = TRUE;
- h2session->fix_dynamic_table[1] = TRUE;
+ h2session->fix_dynamic_table[0] = true;
+ h2session->fix_dynamic_table[1] = true;
#endif
h2session->fwd_flow = tcpd->fwd;
@@ -1458,7 +1465,7 @@ get_http2_session(packet_info *pinfo, conversation_t* conversation)
}
#ifdef HAVE_NGHTTP2
-guint32
+uint32_t
http2_get_stream_id(packet_info *pinfo)
{
conversation_t *conversation;
@@ -1477,7 +1484,7 @@ http2_get_stream_id(packet_info *pinfo)
return h2session->current_stream_id;
}
#else /* ! HAVE_NGHTTP2 */
-guint32
+uint32_t
http2_get_stream_id(packet_info *pinfo _U_)
{
return 0;
@@ -1485,8 +1492,8 @@ http2_get_stream_id(packet_info *pinfo _U_)
#endif /* ! HAVE_NGHTTP2 */
#ifdef HAVE_NGHTTP2
-static const gchar*
-get_real_header_value(packet_info* pinfo, const gchar* name, gboolean the_other_direction);
+static const char*
+get_real_header_value(packet_info* pinfo, const char* name, bool the_other_direction);
static http2_frame_num_t
get_http2_frame_num(tvbuff_t *tvb, packet_info *pinfo)
@@ -1508,14 +1515,14 @@ get_http2_frame_num(tvbuff_t *tvb, packet_info *pinfo)
* I have seen instances where the pinfo->curr_layer_num can change between the first and second
* pass of a packet so this needs to be taken into account when this is used as an identifier.
*/
- return (((guint64)pinfo->num) << 32) + (((guint64)pinfo->curr_layer_num) << 24) + ((guint64)tvb_raw_offset(tvb));
+ return (((uint64_t)pinfo->num) << 32) + (((uint64_t)pinfo->curr_layer_num) << 24) + ((uint64_t)tvb_raw_offset(tvb));
}
static http2_oneway_stream_info_t*
-get_oneway_stream_info_for_id(packet_info *pinfo, http2_session_t* http2_session, gboolean the_other_direction, guint32 stream_id)
+get_oneway_stream_info_for_id(packet_info *pinfo, http2_session_t* http2_session, bool the_other_direction, uint32_t stream_id)
{
- http2_stream_info_t *http2_stream_info = get_stream_info_for_id(pinfo, http2_session, FALSE, stream_id);
- guint32 flow_index = select_http2_flow_index(pinfo, http2_session);
+ http2_stream_info_t *http2_stream_info = get_stream_info_for_id(pinfo, http2_session, false, stream_id);
+ uint32_t flow_index = select_http2_flow_index(pinfo, http2_session);
if (the_other_direction) {
/* need stream info of the other direction,
so set index from 0 to 1, or from 1 to 0 */
@@ -1526,43 +1533,43 @@ get_oneway_stream_info_for_id(packet_info *pinfo, http2_session_t* http2_session
}
static http2_oneway_stream_info_t*
-get_oneway_stream_info(packet_info *pinfo, http2_session_t* http2_session, gboolean the_other_direction)
+get_oneway_stream_info(packet_info *pinfo, http2_session_t* http2_session, bool the_other_direction)
{
return get_oneway_stream_info_for_id(pinfo, http2_session, the_other_direction, http2_session->current_stream_id);
}
static http2_data_stream_body_info_t*
-get_data_stream_body_info_for_id(packet_info *pinfo, http2_session_t* http2_session, guint32 stream_id)
+get_data_stream_body_info_for_id(packet_info *pinfo, http2_session_t* http2_session, uint32_t stream_id)
{
- return &(get_oneway_stream_info_for_id(pinfo, http2_session, FALSE, stream_id)->data_stream_body_info);
+ return &(get_oneway_stream_info_for_id(pinfo, http2_session, false, stream_id)->data_stream_body_info);
}
static http2_data_stream_body_info_t*
get_data_stream_body_info(packet_info *pinfo, http2_session_t* http2_session)
{
- return &(get_oneway_stream_info(pinfo, http2_session, FALSE)->data_stream_body_info);
+ return &(get_oneway_stream_info(pinfo, http2_session, false)->data_stream_body_info);
}
static http2_data_stream_reassembly_info_t*
-get_data_reassembly_info_for_id(packet_info *pinfo, http2_session_t* http2_session, guint32 stream_id)
+get_data_reassembly_info_for_id(packet_info *pinfo, http2_session_t* http2_session, uint32_t stream_id)
{
- return &(get_oneway_stream_info_for_id(pinfo, http2_session, FALSE, stream_id)->data_stream_reassembly_info);
+ return &(get_oneway_stream_info_for_id(pinfo, http2_session, false, stream_id)->data_stream_reassembly_info);
}
static http2_data_stream_reassembly_info_t*
get_data_reassembly_info(packet_info *pinfo, http2_session_t* http2_session)
{
- return &(get_oneway_stream_info(pinfo, http2_session, FALSE)->data_stream_reassembly_info);
+ return &(get_oneway_stream_info(pinfo, http2_session, false)->data_stream_reassembly_info);
}
static http2_header_stream_info_t*
-get_header_stream_info_for_id(packet_info *pinfo, http2_session_t* http2_session,gboolean the_other_direction, guint32 stream_id)
+get_header_stream_info_for_id(packet_info *pinfo, http2_session_t* http2_session,bool the_other_direction, uint32_t stream_id)
{
return &(get_oneway_stream_info_for_id(pinfo, http2_session, the_other_direction, stream_id)->header_stream_info);
}
static http2_header_stream_info_t*
-get_header_stream_info(packet_info *pinfo, http2_session_t* http2_session,gboolean the_other_direction)
+get_header_stream_info(packet_info *pinfo, http2_session_t* http2_session,bool the_other_direction)
{
return &(get_oneway_stream_info(pinfo, http2_session, the_other_direction)->header_stream_info);
}
@@ -1572,7 +1579,7 @@ push_settings(packet_info *pinfo, http2_session_t *h2session,
http2_settings_t *settings)
{
wmem_queue_t *queue;
- guint32 flow_index;
+ uint32_t flow_index;
flow_index = select_http2_flow_index(pinfo, h2session);
@@ -1587,7 +1594,7 @@ apply_and_pop_settings(packet_info *pinfo, http2_session_t *h2session)
wmem_queue_t *queue;
http2_settings_t *settings;
nghttp2_hd_inflater *inflater;
- guint32 flow_index;
+ uint32_t flow_index;
/* When header table size is applied, it affects the inflater of
opposite side. */
@@ -1619,19 +1626,19 @@ apply_and_pop_settings(packet_info *pinfo, http2_session_t *h2session)
function can be called several times if buf does not contain whole
integer. header_repr_info remembers the result of previous call.
Returns the number bytes processed. */
-static guint read_integer(http2_header_repr_info_t *header_repr_info,
- const guint8 *buf, guint len, guint p, guint prefix)
+static unsigned read_integer(http2_header_repr_info_t *header_repr_info,
+ const uint8_t *buf, unsigned len, unsigned p, unsigned prefix)
{
- guint k = (1 << prefix) - 1;
- guint n = header_repr_info->integer;
- guint shift = header_repr_info->next_shift;
+ unsigned k = (1 << prefix) - 1;
+ unsigned n = header_repr_info->integer;
+ unsigned shift = header_repr_info->next_shift;
if(n == 0) {
DISSECTOR_ASSERT(p < len);
if((buf[p] & k) != k) {
header_repr_info->integer = buf[p] & k;
- header_repr_info->complete = TRUE;
+ header_repr_info->complete = true;
return p + 1;
}
@@ -1644,7 +1651,7 @@ static guint read_integer(http2_header_repr_info_t *header_repr_info,
n += (buf[p] & 0x7F) << shift;
if((buf[p] & 0x80) == 0) {
- header_repr_info->complete = TRUE;
+ header_repr_info->complete = true;
++p;
break;
}
@@ -1661,7 +1668,7 @@ reset_http2_header_repr_info(http2_header_repr_info_t *header_repr_info)
header_repr_info->type = HTTP2_HD_NONE;
header_repr_info->integer = 0;
header_repr_info->next_shift = 0;
- header_repr_info->complete = FALSE;
+ header_repr_info->complete = false;
}
/* Reads zero or more header table size update and optionally header
@@ -1669,13 +1676,13 @@ reset_http2_header_repr_info(http2_header_repr_info_t *header_repr_info)
header representation is decoded or buf is processed completely.
This function returns the number bytes processed for header table
size update. */
-static guint
+static unsigned
process_http2_header_repr_info(wmem_array_t *headers,
http2_header_repr_info_t *header_repr_info,
- const guint8 *buf, guint len)
+ const uint8_t *buf, unsigned len)
{
- guint i;
- guint start;
+ unsigned i;
+ unsigned start;
if(header_repr_info->type != HTTP2_HD_NONE &&
header_repr_info->type != HTTP2_HD_HEADER_TABLE_SIZE_UPDATE &&
@@ -1687,7 +1694,7 @@ process_http2_header_repr_info(wmem_array_t *headers,
for(i = 0; i < len;) {
if(header_repr_info->type == HTTP2_HD_NONE) {
- guchar c = buf[i];
+ unsigned char c = buf[i];
if((c & 0xE0) == 0x20) {
header_repr_info->type = HTTP2_HD_HEADER_TABLE_SIZE_UPDATE;
@@ -1697,7 +1704,7 @@ process_http2_header_repr_info(wmem_array_t *headers,
i = read_integer(header_repr_info, buf, len, i, 7);
} else if(c == 0x40 || c == 0 || c == 0x10) {
/* New name */
- header_repr_info->complete = TRUE;
+ header_repr_info->complete = true;
if(c & 0x40) {
header_repr_info->type = HTTP2_HD_LITERAL_INDEXING_NEW_NAME;
} else if((c & 0xF0) == 0x10) {
@@ -1748,10 +1755,10 @@ process_http2_header_repr_info(wmem_array_t *headers,
return start;
}
-static size_t http2_hdrcache_length(gconstpointer vv)
+static size_t http2_hdrcache_length(const void *vv)
{
- const guint8 *v = (const guint8 *)vv;
- guint32 namelen, valuelen;
+ const uint8_t *v = (const uint8_t *)vv;
+ uint32_t namelen, valuelen;
namelen = pntoh32(v);
valuelen = pntoh32(v + sizeof(namelen) + namelen);
@@ -1759,15 +1766,15 @@ static size_t http2_hdrcache_length(gconstpointer vv)
return namelen + valuelen + sizeof(namelen) + sizeof(valuelen);
}
-static guint http2_hdrcache_hash(gconstpointer key)
+static unsigned http2_hdrcache_hash(const void *key)
{
- return wmem_strong_hash((const guint8 *)key, http2_hdrcache_length(key));
+ return wmem_strong_hash((const uint8_t *)key, http2_hdrcache_length(key));
}
-static gboolean http2_hdrcache_equal(gconstpointer lhs, gconstpointer rhs)
+static gboolean http2_hdrcache_equal(const void *lhs, const void *rhs)
{
- const guint8 *a = (const guint8 *)lhs;
- const guint8 *b = (const guint8 *)rhs;
+ const uint8_t *a = (const uint8_t *)lhs;
+ const uint8_t *b = (const uint8_t *)rhs;
size_t alen = http2_hdrcache_length(a);
size_t blen = http2_hdrcache_length(b);
@@ -1778,10 +1785,10 @@ static gboolean http2_hdrcache_equal(gconstpointer lhs, gconstpointer rhs)
* the headers describe. (For PUSH_PROMISE or CONTIUATIONs thereof, this
* is the promised stream id.) Otherwise return 0.
*/
-static guint32
+static uint32_t
is_in_header_context(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2session)
{
- http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, h2session, FALSE);
+ http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, h2session, false);
if (get_http2_frame_num(tvb, pinfo) >= stream_info->header_start_in) {
/* We either haven't established the frame that the headers end in so we are currently in the HEADERS context,
* or if we have, it should be equal or less that the current frame number */
@@ -1798,10 +1805,10 @@ is_in_header_context(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2sessi
Allocates file-scoped string when called as its only called when the header population is done.
*/
-static gchar*
-get_content_type_only(const gchar *content_type, int content_type_str_len) {
- gchar *cp = wmem_strndup(wmem_file_scope(), content_type, content_type_str_len);
- gchar *start = cp;
+static char*
+get_content_type_only(const char *content_type, int content_type_str_len) {
+ char *cp = wmem_strndup(wmem_file_scope(), content_type, content_type_str_len);
+ char *start = cp;
while (*cp != '\0' && *cp != ';' && !g_ascii_isspace(*cp)) {
*cp = g_ascii_tolower(*cp);
@@ -1820,9 +1827,9 @@ get_content_type_only(const gchar *content_type, int content_type_str_len) {
Allocates file-scoped string when called as its only called when the header population is done.
*/
-static gchar*
-get_content_type_parameters_only(const gchar *content_type, int content_type_str_len) {
- gchar *cp = wmem_strndup(wmem_file_scope(), content_type, content_type_str_len);
+static char*
+get_content_type_parameters_only(const char *content_type, int content_type_str_len) {
+ char *cp = wmem_strndup(wmem_file_scope(), content_type, content_type_str_len);
/* Get past the first part of the content type EG: "text/html" */
while (*cp != '\0' && *cp != ';' && !g_ascii_isspace(*cp)) {
@@ -1853,15 +1860,15 @@ get_content_type_parameters_only(const gchar *content_type, int content_type_str
*/
static void
populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t *h2session, int header_value_length,
- const gchar *header_name, const gchar *header_value, guint32 stream_id)
+ const char *header_name, const char *header_value, uint32_t stream_id, const bool override)
{
- http2_stream_info_t *stream_info = get_stream_info_for_id(pinfo, h2session, FALSE, stream_id);
+ http2_stream_info_t *stream_info = get_stream_info_for_id(pinfo, h2session, false, stream_id);
http2_data_stream_body_info_t *body_info = get_data_stream_body_info_for_id(pinfo, h2session, stream_id);
http2_data_stream_reassembly_info_t *reassembly_info = get_data_reassembly_info_for_id(pinfo, h2session, stream_id);
/* Populate the content encoding used so we can uncompress the body later if required */
if (strcmp(header_name, HTTP2_HEADER_CONTENT_ENCODING) == 0) {
- if (body_info->content_encoding == NULL) {
+ if (body_info->content_encoding == NULL || override == true) {
body_info->content_encoding = wmem_strndup(wmem_file_scope(), header_value, header_value_length);
}
}
@@ -1878,7 +1885,7 @@ populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t
/* Is this a partial content? */
if (strcmp(header_name, HTTP2_HEADER_STATUS) == 0 &&
strcmp(header_value, HTTP2_HEADER_STATUS_PARTIAL_CONTENT) == 0) {
- body_info->is_partial_content = TRUE;
+ body_info->is_partial_content = true;
}
/* Was this header used to initiate transfer of data frames? We'll use this later for reassembly */
@@ -1893,18 +1900,18 @@ populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t
/* Do we have transfer encoding of bodies? We don't support reassembling these so mark it as such. */
if (strcmp(header_name, HTTP2_HEADER_TRANSFER_ENCODING) == 0) {
- reassembly_info->has_transfer_encoded_body = TRUE;
+ reassembly_info->has_transfer_encoded_body = true;
}
/* Store away if the stream is associated with a CONNECT request */
if (strcmp(header_name, HTTP2_HEADER_METHOD) == 0 &&
strcmp(header_value, HTTP2_HEADER_METHOD_CONNECT) == 0) {
- stream_info->is_stream_http_connect = TRUE;
+ stream_info->is_stream_http_connect = true;
}
/* Populate the content type so we can dissect the body later */
if (strcmp(header_name, HTTP2_HEADER_CONTENT_TYPE) == 0) {
- if (body_info->content_type == NULL) {
+ if (body_info->content_type == NULL || override == true) {
body_info->content_type = get_content_type_only(header_value, header_value_length);
body_info->content_type_parameters = get_content_type_parameters_only(header_value, header_value_length);
stream_info->reassembly_mode = http2_get_data_reassembly_mode(body_info->content_type);
@@ -1926,10 +1933,10 @@ populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t
static void
try_append_method_path_info(packet_info *pinfo, proto_tree *tree,
- const gchar *method_header_value, const gchar *path_header_value)
+ const char *method_header_value, const char *path_header_value)
{
if (method_header_value != NULL && path_header_value != NULL) {
- /* append request inforamtion to info column (for example, HEADERS: GET /demo/1.jpg) */
+ /* append request information to info column (for example, HEADERS: GET /demo/1.jpg) */
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s %s", method_header_value, path_header_value);
/* append request information to Stream node */
proto_item_append_text(tree, ", %s %s", method_header_value, path_header_value);
@@ -1937,13 +1944,13 @@ try_append_method_path_info(packet_info *pinfo, proto_tree *tree,
}
static proto_item*
-try_add_named_header_field(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 length, const char *header_name, const char *header_value)
+try_add_named_header_field(proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t length, const char *header_name, const char *header_value)
{
- int hf_id = -1;
+ int hf_id;
header_field_info *hfi;
proto_item* ti = NULL;
- const gint *entry = (const gint*) g_hash_table_lookup(header_fields_hash, header_name);
+ const int *entry = (const int*) g_hash_table_lookup(header_fields_hash, header_name);
if (entry == NULL) {
return NULL;
}
@@ -1954,12 +1961,12 @@ try_add_named_header_field(proto_tree *tree, tvbuff_t *tvb, int offset, guint32
DISSECTOR_ASSERT(hfi != NULL);
if (FT_IS_UINT32(hfi->type)) {
- guint32 value;
+ uint32_t value;
if (ws_strtou32(header_value, NULL, &value)) {
ti = proto_tree_add_uint(tree, hf_id, tvb, offset, length, value);
}
} else if (FT_IS_UINT(hfi->type)) {
- guint64 value;
+ uint64_t value;
if (ws_strtou64(header_value, NULL, &value)) {
ti = proto_tree_add_uint64(tree, hf_id, tvb, offset, length, value);
}
@@ -1970,13 +1977,13 @@ try_add_named_header_field(proto_tree *tree, tvbuff_t *tvb, int offset, guint32
}
static void
-fix_partial_header_dissection_support(nghttp2_hd_inflater *hd_inflater, gboolean *fix_it)
+fix_partial_header_dissection_support(nghttp2_hd_inflater *hd_inflater, bool *fix_it)
{
/* Workaround is not necessary or has already been applied, skip. */
if (!*fix_it) {
return;
}
- *fix_it = FALSE;
+ *fix_it = false;
/* Sanity-check: the workaround should fill an empty dynamic table only and
* not evict existing entries. It is expected to be empty given that this is
@@ -2003,7 +2010,7 @@ fix_partial_header_dissection_support(nghttp2_hd_inflater *hd_inflater, gboolean
*
* The binary instruction to insert this is defined in Figure 7 of RFC 7541.
*/
- static const guint8 dummy_header[] = "\x40"
+ static const uint8_t dummy_header[] = "\x40"
"\x09" /* Name String Length */
HTTP2_HEADER_UNKNOWN /* Name String */
"\0"; /* Value Length */
@@ -2026,34 +2033,34 @@ fix_partial_header_dissection_support(nghttp2_hd_inflater *hd_inflater, gboolean
}
static void
-inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree,
- guint headlen, http2_session_t *h2session, guint8 flags)
+inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, proto_tree *tree,
+ unsigned headlen, http2_session_t *h2session, uint8_t flags)
{
- guint8 *headbuf;
+ uint8_t *headbuf;
proto_tree *header_tree;
proto_item *header, *ti, *ti_named_field;
- guint32 header_name_length;
- guint32 header_value_length;
- const guint8 *header_name;
- const guint8 *header_value;
+ uint32_t header_name_length;
+ uint32_t header_value_length;
+ const uint8_t *header_name;
+ const uint8_t *header_value;
int hoffset = 0;
nghttp2_hd_inflater *hd_inflater;
tvbuff_t *header_tvb = NULL;
int rv;
int header_len = 0;
int final;
- guint32 flow_index;
+ uint32_t flow_index;
http2_header_data_t *header_data;
http2_header_repr_info_t *header_repr_info;
wmem_list_t *header_list;
wmem_array_t *headers;
- guint i;
- const gchar *method_header_value = NULL;
- const gchar *path_header_value = NULL;
- const gchar *scheme_header_value = NULL;
- const gchar *authority_header_value = NULL;
+ unsigned i;
+ const char *method_header_value = NULL;
+ const char *path_header_value = NULL;
+ const char *scheme_header_value = NULL;
+ const char *authority_header_value = NULL;
http2_header_stream_info_t* header_stream_info;
- gchar *header_unescaped = NULL;
+ char *header_unescaped = NULL;
if (!http2_hdrcache_map) {
http2_hdrcache_map = wmem_map_new(wmem_file_scope(), http2_hdrcache_hash, http2_hdrcache_equal);
@@ -2073,7 +2080,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
/* Make sure the length isn't too large. */
tvb_ensure_bytes_exist(tvb, offset, headlen);
- headbuf = (guint8*)wmem_alloc(pinfo->pool, headlen);
+ headbuf = (uint8_t*)wmem_alloc(pinfo->pool, headlen);
tvb_memcpy(tvb, headbuf, offset, headlen);
flow_index = select_http2_flow_index(pinfo, h2session);
@@ -2091,7 +2098,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
int inflate_flags = 0;
if (wmem_array_get_count(headers) >= MAX_HTTP2_HEADER_LINES) {
- header_data->header_lines_exceeded = TRUE;
+ header_data->header_lines_exceeded = true;
break;
}
@@ -2109,8 +2116,8 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
char *cached_pstr;
- guint32 len;
- guint datalen = (guint)(4 + nv.namelen + 4 + nv.valuelen);
+ uint32_t len;
+ unsigned datalen = (unsigned)(4 + nv.namelen + 4 + nv.valuelen);
http2_header_t *out;
if (decompressed_bytes + datalen >= MAX_HTTP2_HEADER_SIZE) {
@@ -2138,12 +2145,12 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
/* nv.namelen and nv.valuelen are of size_t. In order
to get length in 4 bytes, we have to copy it to
- guint32. */
- len = (guint32)nv.namelen;
+ uint32_t. */
+ len = (uint32_t)nv.namelen;
phton32(&http2_header_pstr[0], len);
memcpy(&http2_header_pstr[4], nv.name, nv.namelen);
- len = (guint32)nv.valuelen;
+ len = (uint32_t)nv.valuelen;
phton32(&http2_header_pstr[4 + nv.namelen], len);
memcpy(&http2_header_pstr[4 + nv.namelen + 4], nv.value, nv.valuelen);
@@ -2181,11 +2188,11 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
* field block), we don't want to add it to this list, but to the list
* for the promised stream.
*/
- guint32 header_stream_id = is_in_header_context(tvb, pinfo, h2session);
+ uint32_t header_stream_id = is_in_header_context(tvb, pinfo, h2session);
if (header_stream_id == 0) {
header_stream_id = h2session->current_stream_id;
}
- header_stream_info = get_header_stream_info_for_id(pinfo, h2session, FALSE, header_stream_id);
+ header_stream_info = get_header_stream_info_for_id(pinfo, h2session, false, header_stream_id);
if (header_stream_info) {
wmem_list_append(header_stream_info->stream_header_list, headers);
}
@@ -2306,9 +2313,9 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
* For PUSH_PROMISE and CONTINUATION frames thereof, add to the promised stream id.
* Only do it for the first pass in case the current layer changes, altering where the headers frame number,
* http2_frame_num_t points to. */
- guint32 header_stream_id;
+ uint32_t header_stream_id;
if (!PINFO_FD_VISITED(pinfo) && (header_stream_id = is_in_header_context(tvb, pinfo, h2session))) {
- populate_http_header_tracking(tvb, pinfo, h2session, header_value_length, header_name, header_value, header_stream_id);
+ populate_http_header_tracking(tvb, pinfo, h2session, header_value_length, header_name, header_value, header_stream_id, false);
}
/* Add encoding representation */
@@ -2322,7 +2329,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
/* Only for HTTP2_HD_INDEXED, the index value covers the full
* "in->length". In other cases, it is a subset. For simplicity,
* just select 1 octet (this might not be accurate though). */
- guint index_length = in->length;
+ unsigned index_length = in->length;
if (in->type != HTTP2_HD_INDEXED) {
index_length = 1;
}
@@ -2345,7 +2352,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
http_add_path_components_to_tree(header_tvb, pinfo, ti_named_field, hoffset - header_value_length, header_value_length);
}
else if (strcmp(header_name, HTTP2_HEADER_STATUS) == 0) {
- const gchar* reason_phase = val_to_str_const((guint)strtoul(header_value, NULL, 10), vals_http_status_code, "Unknown");
+ const char* reason_phase = val_to_str_const((unsigned)strtoul(header_value, NULL, 10), vals_http_status_code, "Unknown");
/* append response status and reason phrase to info column (for example, HEADERS: 200 OK) */
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s %s", header_value, reason_phase);
/* append response status and reason phrase to header_tree and Stream node */
@@ -2363,7 +2370,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
}
if (have_tap_listener(http2_follow_tap)) {
- http2_follow_tap_data_t* follow_data = wmem_new0(wmem_packet_scope(), http2_follow_tap_data_t);
+ http2_follow_tap_data_t* follow_data = wmem_new0(pinfo->pool, http2_follow_tap_data_t);
wmem_strbuf_append(headers_buf, "\n");
follow_data->tvb = tvb_new_child_real_data(header_tvb,
@@ -2377,7 +2384,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
/* Use the Authority Header as an indication that this packet is a request */
if (authority_header_value) {
proto_item *e_ti;
- gchar *uri;
+ char *uri;
/* RFC9113 8.3.1:
"All HTTP/2 requests MUST include exactly one valid value for the
@@ -2386,9 +2393,9 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
*/
if (method_header_value &&
strcmp(method_header_value, HTTP2_HEADER_METHOD_CONNECT) == 0) {
- uri = wmem_strdup(wmem_packet_scope(), authority_header_value);
+ uri = wmem_strdup(pinfo->pool, authority_header_value);
} else {
- uri = wmem_strdup_printf(wmem_packet_scope(), "%s://%s%s", scheme_header_value, authority_header_value, path_header_value);
+ uri = wmem_strdup_printf(pinfo->pool, "%s://%s%s", scheme_header_value, authority_header_value, path_header_value);
}
e_ti = proto_tree_add_string(tree, hf_http2_header_request_full_uri, tvb, 0, 0, uri);
proto_item_set_url(e_ti);
@@ -2403,7 +2410,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
* frames were not captured that causing HPACK index table not completed. Fake headers can also be used in this situation.
*/
static void
-try_init_stream_with_fake_headers(tvbuff_t* tvb, packet_info* pinfo, http2_session_t* h2session, proto_tree* tree, guint offset)
+try_init_stream_with_fake_headers(tvbuff_t* tvb, packet_info* pinfo, http2_session_t* h2session, proto_tree* tree, unsigned offset)
{
if (num_http2_fake_headers == 0) {
return;
@@ -2411,13 +2418,13 @@ try_init_stream_with_fake_headers(tvbuff_t* tvb, packet_info* pinfo, http2_sessi
http2_direction_type direction;
range_t* server_port_range;
- guint32 stream_id = h2session->current_stream_id;
+ uint32_t stream_id = h2session->current_stream_id;
wmem_array_t* indexes = NULL; /* the indexes of fake headers matching this stream and direction */
proto_item* ti, * ti_header;
proto_tree* header_tree;
http2_frame_num_t http2_frame_num = get_http2_frame_num(tvb, pinfo);
- http2_header_stream_info_t* header_stream_info = get_header_stream_info(pinfo, h2session, FALSE);
+ http2_header_stream_info_t* header_stream_info = get_header_stream_info(pinfo, h2session, false);
http2_data_stream_reassembly_info_t* reassembly_info = get_data_reassembly_info(pinfo, h2session);
if (!PINFO_FD_VISITED(pinfo) && header_stream_info->fake_headers_initiated_fn == 0) {
@@ -2433,9 +2440,9 @@ try_init_stream_with_fake_headers(tvbuff_t* tvb, packet_info* pinfo, http2_sessi
* Use only those fake headers that do not appear. */
header_stream_info->fake_headers = wmem_array_sized_new(wmem_file_scope(), sizeof(http2_fake_header_t*), 16);
- for (guint i = 0; i < num_http2_fake_headers; ++i) {
+ for (unsigned i = 0; i < num_http2_fake_headers; ++i) {
http2_fake_header_t* fake_header = http2_fake_headers + i;
- if (fake_header->enable == FALSE ||
+ if (fake_header->enable == false ||
(fake_header->stream_id > 0 && fake_header->stream_id != stream_id)) {
continue;
}
@@ -2454,13 +2461,13 @@ try_init_stream_with_fake_headers(tvbuff_t* tvb, packet_info* pinfo, http2_sessi
}
/* now match one */
- if (get_real_header_value(pinfo, fake_header->header_name, FALSE)) {
- /* If this header already appears, the fake header is ignored. */
+ if (get_real_header_value(pinfo, fake_header->header_name, false) && fake_header->override == false) {
+ /* If this header already appears, the fake header is ignored, unless we want to override. */
continue;
}
populate_http_header_tracking(tvb, pinfo, h2session, (int)strlen(fake_header->header_value),
- fake_header->header_name, fake_header->header_value, h2session->current_stream_id);
+ fake_header->header_name, fake_header->header_value, h2session->current_stream_id, fake_header->override);
wmem_array_append(header_stream_info->fake_headers, &fake_header, 1);
}
@@ -2470,13 +2477,13 @@ try_init_stream_with_fake_headers(tvbuff_t* tvb, packet_info* pinfo, http2_sessi
indexes = header_stream_info->fake_headers;
/* Try to add the tree item of fake headers. */
if (indexes) {
- guint total_matching_fake_headers = wmem_array_get_count(indexes);
+ unsigned total_matching_fake_headers = wmem_array_get_count(indexes);
ti = proto_tree_add_uint(tree, hf_http2_fake_header_count, tvb, offset, 0, total_matching_fake_headers);
proto_item_append_text(ti, " (Using fake headers because previous initial HEADERS frame is missing)");
proto_item_set_generated(ti);
- for (guint i = 0; i < total_matching_fake_headers; ++i) {
+ for (unsigned i = 0; i < total_matching_fake_headers; ++i) {
http2_fake_header_t* header = *(http2_fake_header_t**)wmem_array_index(indexes, i);
ti_header = proto_tree_add_item(tree, hf_http2_fake_header, tvb, offset, 0, ENC_NA);
@@ -2494,8 +2501,8 @@ try_init_stream_with_fake_headers(tvbuff_t* tvb, packet_info* pinfo, http2_sessi
}
#endif
-static gchar*
-http2_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream)
+static char*
+http2_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, unsigned *stream, unsigned *sub_stream)
{
http2_session_t *h2session;
struct tcp_analysis *tcpd;
@@ -2528,11 +2535,11 @@ http2_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *str
return NULL;
}
-static guint32
-get_http2_stream_count(guint streamid)
+static uint32_t
+get_http2_stream_count(unsigned streamid)
{
- guint32 result = 0;
- guint32 key;
+ uint32_t result = 0;
+ uint32_t key;
GHashTable *entry;
GList *entry_set, *it;
@@ -2551,57 +2558,57 @@ get_http2_stream_count(guint streamid)
return result;
}
-static gboolean
-is_http2_stream_contains(guint streamid, gint sub_stream_id)
+static bool
+is_http2_stream_contains(unsigned streamid, int sub_stream_id)
{
GHashTable *entry;
entry = (GHashTable*)g_hash_table_lookup(streamid_hash, GUINT_TO_POINTER(streamid));
if (entry == NULL) {
- return FALSE;
+ return false;
}
if (!g_hash_table_contains(entry, GINT_TO_POINTER(sub_stream_id))) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
-gboolean
-http2_get_stream_id_le(guint streamid, guint sub_stream_id, guint *sub_stream_id_out)
+bool
+http2_get_stream_id_le(unsigned streamid, unsigned sub_stream_id, unsigned *sub_stream_id_out)
{
// HTTP/2 Stream IDs are always 31 bit.
- gint max_id = (gint)get_http2_stream_count(streamid);
- gint id = (gint)(sub_stream_id & MASK_HTTP2_STREAMID);
+ int max_id = (int)get_http2_stream_count(streamid);
+ int id = (int)(sub_stream_id & MASK_HTTP2_STREAMID);
if (id > max_id) {
id = max_id;
}
for (; id >= 0; id--) {
if (is_http2_stream_contains(streamid, id)) {
- *sub_stream_id_out = (guint)id;
- return TRUE;
+ *sub_stream_id_out = (unsigned)id;
+ return true;
}
}
- return FALSE;
+ return false;
}
-gboolean
-http2_get_stream_id_ge(guint streamid, guint sub_stream_id, guint *sub_stream_id_out)
+bool
+http2_get_stream_id_ge(unsigned streamid, unsigned sub_stream_id, unsigned *sub_stream_id_out)
{
// HTTP/2 Stream IDs are always 31 bit.
- gint max_id = (gint)get_http2_stream_count(streamid);
- for (gint id = (gint)(sub_stream_id & MASK_HTTP2_STREAMID); id <= max_id; id++) {
+ int max_id = (int)get_http2_stream_count(streamid);
+ for (int id = (int)(sub_stream_id & MASK_HTTP2_STREAMID); id <= max_id; id++) {
if (is_http2_stream_contains(streamid, id)) {
- *sub_stream_id_out = (guint)id;
- return TRUE;
+ *sub_stream_id_out = (unsigned)id;
+ return true;
}
}
- return FALSE;
+ return false;
}
-static gboolean
-http2_get_sub_stream_id(guint streamid, guint sub_stream_id, gboolean le, guint *sub_stream_id_out)
+static bool
+http2_get_sub_stream_id(unsigned streamid, unsigned sub_stream_id, bool le, unsigned *sub_stream_id_out)
{
if (le) {
return http2_get_stream_id_le(streamid, sub_stream_id, sub_stream_id_out);
@@ -2610,8 +2617,8 @@ http2_get_sub_stream_id(guint streamid, guint sub_stream_id, gboolean le, guint
}
}
-static gchar*
-http2_follow_index_filter(guint stream, guint sub_stream)
+static char*
+http2_follow_index_filter(unsigned stream, unsigned sub_stream)
{
return ws_strdup_printf("tcp.stream eq %u and http2.streamid eq %u", stream, sub_stream);
}
@@ -2630,11 +2637,11 @@ follow_http2_tap_listener(void *tapdata, packet_info *pinfo, epan_dissect_t *edt
return follow_tvb_tap_listener(tapdata, pinfo, NULL, follow_data->tvb, flags);
}
-static guint8
-dissect_http2_header_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 type)
+static uint8_t
+dissect_http2_header_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, unsigned offset, uint8_t type)
{
- guint64 flags_val;
+ uint64_t flags_val;
int* const * fields;
static int* const http2_hdr_flags[] = {
@@ -2721,23 +2728,23 @@ dissect_http2_header_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ht
proto_tree_add_bitmask_with_flags_ret_uint64(http2_tree, tvb, offset, hf_http2_flags,
ett_http2_flags, fields, ENC_BIG_ENDIAN, BMT_NO_FALSE | BMT_NO_INT, &flags_val);
- return (guint8)flags_val;
+ return (uint8_t)flags_val;
}
/* helper function to get the padding data for the frames that feature them */
-static guint
-dissect_frame_padding(tvbuff_t *tvb, guint16 *padding, proto_tree *http2_tree,
- guint offset, guint8 flags)
+static unsigned
+dissect_frame_padding(tvbuff_t *tvb, uint16_t *padding, proto_tree *http2_tree,
+ unsigned offset, uint8_t flags)
{
proto_item *ti;
- guint pad_len = 0;
+ unsigned pad_len = 0;
*padding = 0;
if(flags & HTTP2_FLAGS_PADDED)
{
- *padding = tvb_get_guint8(tvb, offset); /* read a single octet */
+ *padding = tvb_get_uint8(tvb, offset); /* read a single octet */
proto_tree_add_item(http2_tree, hf_http2_padding, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
pad_len ++;
@@ -2750,11 +2757,11 @@ dissect_frame_padding(tvbuff_t *tvb, guint16 *padding, proto_tree *http2_tree,
/* helper function to get the priority dependence for the frames that feature them:
HEADERS and PRIORITY */
-static guint
-dissect_frame_prio(tvbuff_t *tvb, proto_tree *http2_tree, guint offset, guint8 flags)
+static unsigned
+dissect_frame_prio(tvbuff_t *tvb, proto_tree *http2_tree, unsigned offset, uint8_t flags)
{
proto_tree *ti;
- guint8 weight;
+ uint8_t weight;
if(flags & HTTP2_FLAGS_PRIORITY)
{
@@ -2762,7 +2769,7 @@ dissect_frame_prio(tvbuff_t *tvb, proto_tree *http2_tree, guint offset, guint8 f
proto_tree_add_item(http2_tree, hf_http2_stream_dependency, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(http2_tree, hf_http2_weight, tvb, offset, 1, ENC_BIG_ENDIAN);
- weight = tvb_get_guint8(tvb, offset);
+ weight = tvb_get_uint8(tvb, offset);
/* 6.2: Weight: An 8-bit weight for the stream; Add one to the value to obtain a weight between 1 and 256 */
ti = proto_tree_add_uint(http2_tree, hf_http2_weight_real, tvb, offset, 1, weight+1);
proto_item_set_generated(ti);
@@ -2778,7 +2785,7 @@ static streaming_reassembly_info_t*
get_streaming_reassembly_info(packet_info* pinfo, http2_session_t* http2_session)
{
http2_data_stream_reassembly_info_t* data_reassembly_info =
- &get_oneway_stream_info(pinfo, http2_session, FALSE)->data_stream_reassembly_info;
+ &get_oneway_stream_info(pinfo, http2_session, false)->data_stream_reassembly_info;
if (data_reassembly_info->streaming_reassembly_info == NULL) {
data_reassembly_info->streaming_reassembly_info = streaming_reassembly_info_new();
@@ -2797,14 +2804,18 @@ static enum body_uncompression
get_body_uncompression_info(packet_info *pinfo, http2_session_t* h2session)
{
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, h2session);
- gchar *content_encoding = body_info->content_encoding;
+ char *content_encoding = body_info->content_encoding;
/* Check we have a content-encoding header appropriate as well as checking if this is partial content.
* We can't decompress part of a gzip encoded entity */
- if (!http2_decompress_body || body_info->is_partial_content == TRUE || content_encoding == NULL) {
+ if (!http2_decompress_body || body_info->is_partial_content == true || content_encoding == NULL) {
return BODY_UNCOMPRESSION_NONE;
}
-
+#ifdef HAVE_ZLIBNG
+ if (strncmp(content_encoding, "gzip", 4) == 0 || strncmp(content_encoding, "deflate", 7) == 0) {
+ return BODY_UNCOMPRESSION_ZLIB;
+ }
+#endif
#ifdef HAVE_ZLIB
if (strncmp(content_encoding, "gzip", 4) == 0 || strncmp(content_encoding, "deflate", 7) == 0) {
return BODY_UNCOMPRESSION_ZLIB;
@@ -2822,21 +2833,21 @@ get_body_uncompression_info(packet_info *pinfo, http2_session_t* h2session)
/* Try to dissect reassembled http2.data.data according to content_type. */
static void
dissect_body_data(proto_tree *tree, packet_info *pinfo, http2_session_t* h2session, tvbuff_t *tvb,
- const gint start, gint length, const guint encoding, gboolean streaming_mode)
+ const int start, int length, const unsigned encoding, bool streaming_mode)
{
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, h2session);
- http2_stream_info_t *stream_info = get_stream_info(pinfo, h2session, FALSE);
- gchar *content_type = body_info->content_type;
+ http2_stream_info_t *stream_info = get_stream_info(pinfo, h2session, false);
+ char *content_type = body_info->content_type;
media_content_info_t metadata_used_for_media_type_handle = { MEDIA_CONTAINER_HTTP_OTHERS, body_info->content_type_parameters, NULL, NULL };
http_eo_t *eo_info;
- guint32 stream_id;
+ uint32_t stream_id;
stream_id = http2_get_stream_id(pinfo);
if (!streaming_mode)
proto_tree_add_item(tree, hf_http2_data_data, tvb, start, length, encoding);
if (have_tap_listener(http2_follow_tap)) {
- http2_follow_tap_data_t *follow_data = wmem_new0(wmem_packet_scope(), http2_follow_tap_data_t);
+ http2_follow_tap_data_t *follow_data = wmem_new0(pinfo->pool, http2_follow_tap_data_t);
follow_data->tvb = tvb_new_subset_length(tvb, start, length);
follow_data->stream_id = stream_id;
@@ -2855,15 +2866,74 @@ dissect_body_data(proto_tree *tree, packet_info *pinfo, http2_session_t* h2sessi
tap_queue_packet(http_eo_tap, pinfo, eo_info);
}
+ tvbuff_t *data_tvb = tvb_new_subset_length(tvb, start, length);
if (content_type != NULL) {
/* add it to STREAM level */
proto_tree* ptree = proto_tree_get_parent_tree(tree);
dissector_try_string((streaming_mode ? streaming_content_type_dissector_table : media_type_dissector_table),
- content_type, tvb_new_subset_length(tvb, start, length), pinfo,
+ content_type, data_tvb, pinfo,
ptree, &metadata_used_for_media_type_handle);
} else {
- dissector_try_uint_new(stream_id_content_type_dissector_table, stream_id,
- tvb_new_subset_length(tvb, start, length), pinfo, proto_tree_get_parent_tree(tree), TRUE, &metadata_used_for_media_type_handle);
+ if (!dissector_try_uint_new(stream_id_content_type_dissector_table, stream_id,
+ data_tvb, pinfo, proto_tree_get_parent_tree(tree), true, &metadata_used_for_media_type_handle))
+ {
+ /* Try heuristics */
+ /* Check for possible boundary string */
+ if (tvb_strneql(data_tvb, 0, "--", 2) == 0) {
+ int next_offset;
+ int boundary_len = tvb_find_line_end(data_tvb, 0, -1, &next_offset, true);
+ if ((boundary_len > 4) && (boundary_len < 70)){
+ boundary_len = boundary_len - 2; /* ignore ending CRLF*/
+ /* We have a potential boundary string */
+ uint8_t *boundary = tvb_get_string_enc(wmem_packet_scope(), data_tvb, 2, boundary_len, ENC_ASCII | ENC_NA);
+ if (tvb_strneql(data_tvb, (length - 4) - boundary_len, boundary, boundary_len) == 0) {
+ /* We have multipart/mixed */
+ /* Populate the content type so we can dissect the body later */
+ body_info->content_type = wmem_strndup(wmem_file_scope(), "multipart/mixed", 15);
+ body_info->content_type_parameters = wmem_strdup_printf(wmem_file_scope(), "boundary=\"%s\"", boundary);
+ metadata_used_for_media_type_handle.media_str = body_info->content_type_parameters;
+ dissector_try_uint_new(stream_id_content_type_dissector_table, stream_id,
+ data_tvb, pinfo, proto_tree_get_parent_tree(tree), true, &metadata_used_for_media_type_handle);
+ }
+ }
+ return;
+ } /* Not multipart/mixed*/
+ /* check for json, from RFC 4627
+ * A JSON text is a serialized object or array.
+ * JSON-text = object / array
+ * These are the six structural characters:
+ * begin-array = ws %x5B ws ; [ left square bracket
+ * begin-object = ws %x7B ws ; { left curly bracket
+ * :
+ * Insignificant whitespace is allowed before or after any of the six
+ * structural characters.
+ * ws = *(
+ * %x20 / ; Space
+ * %x09 / ; Horizontal tab
+ * %x0A / ; Line feed or New line
+ * %x0D ; Carriage return
+ * )
+ */
+ int offset = 0;
+ offset = tvb_skip_wsp(data_tvb, 0, length);
+ uint8_t oct = tvb_get_uint8(data_tvb, offset);
+ if ((oct == 0x5b) || (oct == 0x7b)) {
+ /* Potential json */
+ const uint8_t* buf = tvb_get_string_enc(pinfo->pool, tvb, 0, length, ENC_ASCII);
+
+ if (json_validate(buf, length) == true) {
+ body_info->content_type = wmem_strndup(wmem_file_scope(), "application/json", 16);
+ dissector_handle_t handle = dissector_get_string_handle(media_type_dissector_table, body_info->content_type);
+ metadata_used_for_media_type_handle.media_str = body_info->content_type_parameters;
+ if (handle) {
+ dissector_add_uint("http2.streamid", stream_info->stream_id, handle);
+ }
+ dissector_try_uint_new(stream_id_content_type_dissector_table, stream_id,
+ data_tvb, pinfo, proto_tree_get_parent_tree(tree), true, &metadata_used_for_media_type_handle);
+ }
+ return;
+ }
+ }
}
}
@@ -2874,7 +2944,7 @@ dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t*
return;
}
- gint datalen = tvb_reported_length(tvb);
+ int datalen = tvb_reported_length(tvb);
enum body_uncompression uncompression = get_body_uncompression_info(pinfo, h2session);
if (uncompression != BODY_UNCOMPRESSION_NONE) {
@@ -2882,13 +2952,13 @@ dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t*
tvbuff_t *uncompressed_tvb = NULL;
if (uncompression == BODY_UNCOMPRESSION_ZLIB) {
- uncompressed_tvb = tvb_child_uncompress(tvb, tvb, 0, datalen);
+ uncompressed_tvb = tvb_child_uncompress_zlib(tvb, tvb, 0, datalen);
} else if (uncompression == BODY_UNCOMPRESSION_BROTLI) {
uncompressed_tvb = tvb_child_uncompress_brotli(tvb, tvb, 0, datalen);
}
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, h2session);
- gchar *compression_method = body_info->content_encoding;
+ char *compression_method = body_info->content_encoding;
proto_tree *compressed_entity_tree = proto_tree_add_subtree_format(http2_tree, tvb, 0, datalen, ett_http2_encoded_entity,
&compressed_proto_item, "Content-encoded entity body (%s): %u bytes",
@@ -2896,17 +2966,17 @@ dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t*
);
if (uncompressed_tvb != NULL) {
- guint uncompressed_length = tvb_captured_length(uncompressed_tvb);
+ unsigned uncompressed_length = tvb_captured_length(uncompressed_tvb);
add_new_data_source(pinfo, uncompressed_tvb, "Uncompressed entity body");
proto_item_append_text(compressed_proto_item, " -> %u bytes", uncompressed_length);
- dissect_body_data(compressed_entity_tree, pinfo, h2session, uncompressed_tvb, 0, uncompressed_length, ENC_NA, FALSE);
+ dissect_body_data(compressed_entity_tree, pinfo, h2session, uncompressed_tvb, 0, uncompressed_length, ENC_NA, false);
} else {
proto_tree_add_expert(compressed_entity_tree, pinfo, &ei_http2_body_decompression_failed, tvb, 0, datalen);
- dissect_body_data(compressed_entity_tree, pinfo, h2session, tvb, 0, datalen, ENC_NA, FALSE);
+ dissect_body_data(compressed_entity_tree, pinfo, h2session, tvb, 0, datalen, ENC_NA, false);
}
} else {
- dissect_body_data(http2_tree, pinfo, h2session, tvb, 0, datalen, ENC_NA, FALSE);
+ dissect_body_data(http2_tree, pinfo, h2session, tvb, 0, datalen, ENC_NA, false);
}
}
@@ -2918,7 +2988,7 @@ should_attempt_to_reassemble_data_frame(http2_data_stream_reassembly_info_t *rea
/* If we haven't captured the header frame with the request/response we don't know how many data
* frames we might have lost before processing */
if (reassembly->data_initiated_in == 0) {
- return FALSE;
+ return false;
}
/* For now, do not reassemble transfer encoded bodies. Chunked encoding is explicitly disallowed by RFC7540,
@@ -2926,23 +2996,23 @@ should_attempt_to_reassemble_data_frame(http2_data_stream_reassembly_info_t *rea
* which transfer-encoding is allowed) is trailers, suggesting transfer coding other than chunked (gzip,
* deflate, etc) are not allowed */
if (reassembly->has_transfer_encoded_body) {
- return FALSE;
+ return false;
}
/* Is this data frame part of an established tunnel? Don't try to reassemble the data if that is the case */
- http2_stream_info_t *stream_info = get_stream_info(pinfo, http2_session, FALSE);
+ http2_stream_info_t *stream_info = get_stream_info(pinfo, http2_session, false);
if (stream_info->is_stream_http_connect) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
-static guint32
+static uint32_t
get_reassembly_id_from_stream(packet_info *pinfo, http2_session_t* session)
{
- http2_stream_info_t *stream_info = get_stream_info(pinfo, session, FALSE);
- guint32 flow_index = select_http2_flow_index(pinfo, session);
+ http2_stream_info_t *stream_info = get_stream_info(pinfo, session, false);
+ uint32_t flow_index = select_http2_flow_index(pinfo, session);
/* With a stream ID being 31 bits, use the most significant bit to determine the flow direction of the
* stream. We use this for the ID in the body reassembly using the reassemble API */
@@ -2957,10 +3027,10 @@ get_reassembly_id_from_stream(packet_info *pinfo, http2_session_t* session)
static tvbuff_t*
http2_process_reassembled_data(tvbuff_t *tvb, const int offset, packet_info *pinfo,
const char *name, fragment_head *fd_head, const fragment_items *fit,
- gboolean *update_col_infop, proto_tree *tree)
+ bool *update_col_infop, proto_tree *tree)
{
tvbuff_t* next_tvb;
- gboolean update_col_info;
+ bool update_col_info;
proto_item* frag_tree_item;
if (fd_head != NULL) {
@@ -2999,8 +3069,8 @@ http2_process_reassembled_data(tvbuff_t *tvb, const int offset, packet_info *pin
* Return a tvbuff with the payload. next_tvb ist from offset until end
*/
next_tvb = tvb_new_subset_remaining(tvb, offset);
- pinfo->fragmented = FALSE; /* one-fragment packet */
- update_col_info = TRUE;
+ pinfo->fragmented = false; /* one-fragment packet */
+ update_col_info = true;
}
if (update_col_infop != NULL)
*update_col_infop = update_col_info;
@@ -3022,8 +3092,8 @@ http2_process_reassembled_data(tvbuff_t *tvb, const int offset, packet_info *pin
}
static tvbuff_t*
-reassemble_http2_data_into_full_frame(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_session, proto_tree *http2_tree, guint offset,
- guint8 flags, guint datalen)
+reassemble_http2_data_into_full_frame(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_session, proto_tree *http2_tree, unsigned offset,
+ uint8_t flags, unsigned datalen)
{
http2_data_stream_reassembly_info_t *reassembly = get_data_reassembly_info(pinfo, http2_session);
@@ -3033,7 +3103,7 @@ reassemble_http2_data_into_full_frame(tvbuff_t *tvb, packet_info *pinfo, http2_s
}
/* Continue to add fragments, checking if we have any more fragments */
- guint32 reassembly_id = get_reassembly_id_from_stream(pinfo, http2_session);
+ uint32_t reassembly_id = get_reassembly_id_from_stream(pinfo, http2_session);
fragment_head *head = NULL;
if (IS_HTTP2_END_STREAM(flags) && datalen == 0) {
/* Workaround displaying "[Frame: N (no data)]" for a HTTP2 frame that contains no data but ends the stream */
@@ -3064,8 +3134,8 @@ reassemble_http2_data_into_full_frame(tvbuff_t *tvb, packet_info *pinfo, http2_s
}
static void
-dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_session, proto_tree *http2_tree, guint offset, gint length,
- guint8 flags)
+dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_session, proto_tree *http2_tree, unsigned offset, int length,
+ uint8_t flags)
{
http2_data_stream_reassembly_info_t *reassembly = get_data_reassembly_info(pinfo, http2_session);
@@ -3080,7 +3150,7 @@ dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, http2_session
}
/* Is this part of a tunneled connection? */
- http2_stream_info_t *stream_info = get_stream_info(pinfo, http2_session, FALSE);
+ http2_stream_info_t *stream_info = get_stream_info(pinfo, http2_session, false);
if (stream_info->is_stream_http_connect) {
proto_item_append_text(http2_tree, " (tunneled data)");
}
@@ -3090,9 +3160,9 @@ dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, http2_session
static void
check_reassembly_completion_status(tvbuff_t* tvb, packet_info* pinfo, proto_tree* http2_tree,
- guint offset, guint8 flags, gint length, streaming_reassembly_info_t* reassembly_info)
+ unsigned offset, uint8_t flags, int length, streaming_reassembly_info_t* reassembly_info)
{
- gint more_bytes_expected = additional_bytes_expected_to_complete_reassembly(reassembly_info);
+ int more_bytes_expected = additional_bytes_expected_to_complete_reassembly(reassembly_info);
if (IS_HTTP2_END_STREAM(flags) && more_bytes_expected) {
if (more_bytes_expected == DESEGMENT_ONE_MORE_SEGMENT) {
@@ -3143,7 +3213,7 @@ check_reassembly_completion_status(tvbuff_t* tvb, packet_info* pinfo, proto_tree
*/
static void
reassemble_http2_data_according_to_subdissector(tvbuff_t* tvb, packet_info* pinfo, http2_session_t* http2_session,
- proto_tree* http2_tree, guint offset, guint8 flags, gint length)
+ proto_tree* http2_tree, unsigned offset, uint8_t flags, int length)
{
const char* saved_match_string = pinfo->match_string;
http2_frame_num_t cur_frame_num = get_http2_frame_num(tvb, pinfo);
@@ -3152,7 +3222,7 @@ reassemble_http2_data_according_to_subdissector(tvbuff_t* tvb, packet_info* pinf
length, NULL, "DATA payload (%u byte%s)", length, plurality(length, "", "s"));
http2_data_stream_body_info_t* body_info = get_data_stream_body_info(pinfo, http2_session);
- gchar* content_type = body_info->content_type;
+ char* content_type = body_info->content_type;
media_content_info_t metadata_used_for_media_type_handle = {
MEDIA_CONTAINER_HTTP_OTHERS, body_info->content_type_parameters, NULL, NULL
};
@@ -3178,7 +3248,7 @@ reassemble_http2_data_according_to_subdissector(tvbuff_t* tvb, packet_info* pinf
reassemble_streaming_data_and_call_subdissector(
tvb, pinfo, offset, length, http2_tree, proto_tree_get_parent_tree(http2_tree),
- http2_streaming_reassembly_table, reassembly_info, (guint64)cur_frame_num,
+ http2_streaming_reassembly_table, reassembly_info, (uint64_t)cur_frame_num,
subdissector_handle, proto_tree_get_parent_tree(http2_tree), &metadata_used_for_media_type_handle,
"HTTP2 body", &http2_body_fragment_items, hf_http2_data_segment);
@@ -3190,11 +3260,11 @@ reassemble_http2_data_according_to_subdissector(tvbuff_t* tvb, packet_info* pinf
}
static void
-dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2session, proto_tree *http2_tree, guint offset, guint8 flags, gint length)
+dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2session, proto_tree *http2_tree, unsigned offset, uint8_t flags, int length)
{
try_init_stream_with_fake_headers(tvb, pinfo, h2session, http2_tree, offset);
- http2_stream_info_t *stream_info = get_stream_info(pinfo, h2session, FALSE);
+ http2_stream_info_t *stream_info = get_stream_info(pinfo, h2session, false);
if (stream_info->reassembly_mode == HTTP2_DATA_REASSEMBLY_MODE_STREAMING) {
reassemble_http2_data_according_to_subdissector(tvb, pinfo, h2session, http2_tree, offset, flags, length);
return;
@@ -3210,17 +3280,17 @@ dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2se
}
/* Get real header value from current or the other direction stream_header_list */
-static const gchar*
-get_real_header_value(packet_info* pinfo, const gchar* name, gboolean the_other_direction)
+static const char*
+get_real_header_value(packet_info* pinfo, const char* name, bool the_other_direction)
{
http2_header_stream_info_t* header_stream_info;
wmem_list_frame_t* frame;
wmem_array_t* headers;
- guint i;
- guint32 name_len;
- guint32 value_len;
+ unsigned i;
+ uint32_t name_len;
+ uint32_t value_len;
http2_header_t *hdr;
- gchar* data;
+ char* data;
conversation_t* conversation = find_or_create_conversation(pinfo);
header_stream_info = get_header_stream_info(pinfo, get_http2_session(pinfo, conversation), the_other_direction);
@@ -3249,7 +3319,7 @@ get_real_header_value(packet_info* pinfo, const gchar* name, gboolean the_other_
value length (uint32)
value (string)
*/
- data = (gchar*) hdr->table.data.data;
+ data = (char*) hdr->table.data.data;
name_len = pntoh32(data);
if (strlen(name) == name_len && strncmp(data + 4, name, name_len) == 0) {
value_len = pntoh32(data + 4 + name_len);
@@ -3268,25 +3338,28 @@ get_real_header_value(packet_info* pinfo, const gchar* name, gboolean the_other_
}
/* Get header value from current or the other direction stream_header_list */
-const gchar*
-http2_get_header_value(packet_info *pinfo, const gchar* name, gboolean the_other_direction)
+const char*
+http2_get_header_value(packet_info *pinfo, const char* name, bool the_other_direction)
{
- const gchar* value = get_real_header_value(pinfo, name, the_other_direction);
- if (value) {
- return value;
- } else {
- return get_fake_header_value(pinfo, name, the_other_direction);
+ bool override = false;
+ const char* real_value = get_real_header_value(pinfo, name, the_other_direction);
+ const char* fake_value = get_fake_header_value(pinfo, name, the_other_direction, &override);
+ if (real_value && override == false) {
+ return real_value;
+ } else if (fake_value) {
+ return fake_value;
}
+ return NULL;
}
#else
static void
-dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* http2_session _U_, proto_tree *http2_tree, guint offset, guint8 flags _U_, gint datalen)
+dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* http2_session _U_, proto_tree *http2_tree, unsigned offset, uint8_t flags _U_, int datalen)
{
proto_tree_add_item(http2_tree, hf_http2_data_data, tvb, offset, datalen, ENC_NA);
}
-const gchar*
-http2_get_header_value(packet_info *pinfo _U_, const gchar* name _U_, gboolean the_other_direction _U_)
+const char*
+http2_get_header_value(packet_info *pinfo _U_, const char* name _U_, bool the_other_direction _U_)
{
return NULL;
}
@@ -3294,14 +3367,14 @@ http2_get_header_value(packet_info *pinfo _U_, const gchar* name _U_, gboolean t
/* Increment or decrement the accumulated connection and/or stream window
* sizes based on the flow direction, stream ID and increaseWindow parameter.
- * In other words, if increaseWindow is TRUE, then we're processing a
+ * In other words, if increaseWindow is true, then we're processing a
* WINDOW_UPDATE frame; otherwise, we're processing a DATA frame.
*/
static void
-adjust_window_size(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_session, proto_tree *http2_tree, gint32 adjustment, gboolean increaseWindow)
+adjust_window_size(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_session, proto_tree *http2_tree, int32_t adjustment, bool increaseWindow)
{
- guint32 flow_index = select_http2_flow_index(pinfo, http2_session);
- gint32 finalAdjustment = ((increaseWindow ? 1 : -1) * adjustment);
+ uint32_t flow_index = select_http2_flow_index(pinfo, http2_session);
+ int32_t finalAdjustment = ((increaseWindow ? 1 : -1) * adjustment);
if (increaseWindow) {
/* The WINDOW_UPDATE comes in for the other direction */
@@ -3311,12 +3384,12 @@ adjust_window_size(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_ses
/* Always decrease the connection window after sending data,
* but only increase the connection window for a WINDOW_UPDATE on stream 0 (the connection). */
if (!increaseWindow || http2_session->current_stream_id == 0) {
- gint32* window_size_connection_before = p_get_proto_data(wmem_file_scope(), pinfo, proto_http2, PROTO_DATA_KEY_WINDOW_SIZE_CONNECTION_BEFORE);
- gint32 window_size_connection_after;
+ int32_t* window_size_connection_before = p_get_proto_data(wmem_file_scope(), pinfo, proto_http2, PROTO_DATA_KEY_WINDOW_SIZE_CONNECTION_BEFORE);
+ int32_t window_size_connection_after;
if (!window_size_connection_before) {
/* There may be multiple passes, so we must use proto_data to keep state */
- window_size_connection_before = wmem_new0(wmem_file_scope(), gint32);
+ window_size_connection_before = wmem_new0(wmem_file_scope(), int32_t);
(*window_size_connection_before) = http2_session->current_connection_window_size[flow_index];
http2_session->current_connection_window_size[flow_index] += finalAdjustment;
p_add_proto_data(wmem_file_scope(), pinfo, proto_http2, PROTO_DATA_KEY_WINDOW_SIZE_CONNECTION_BEFORE, window_size_connection_before);
@@ -3336,12 +3409,12 @@ adjust_window_size(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_ses
* but only increase the stream window for a WINDOW_UPDATE on stream > 0 (not the connection). */
if (!increaseWindow || http2_session->current_stream_id > 0) {
http2_stream_info_t *http2_stream_info = get_stream_info(pinfo, http2_session, increaseWindow);
- gint32* window_size_stream_before = p_get_proto_data(wmem_file_scope(), pinfo, proto_http2, PROTO_DATA_KEY_WINDOW_SIZE_STREAM_BEFORE);
- gint32 window_size_stream_after;
+ int32_t* window_size_stream_before = p_get_proto_data(wmem_file_scope(), pinfo, proto_http2, PROTO_DATA_KEY_WINDOW_SIZE_STREAM_BEFORE);
+ int32_t window_size_stream_after;
if (!window_size_stream_before) {
/* There may be multiple passes, so we must use proto_data to keep state */
- window_size_stream_before = wmem_new0(wmem_file_scope(), gint32);
+ window_size_stream_before = wmem_new0(wmem_file_scope(), int32_t);
(*window_size_stream_before) = http2_stream_info->oneway_stream_info[flow_index].current_window_size;
http2_stream_info->oneway_stream_info[flow_index].current_window_size += finalAdjustment;
p_add_proto_data(wmem_file_scope(), pinfo, proto_http2, PROTO_DATA_KEY_WINDOW_SIZE_STREAM_BEFORE, window_size_stream_before);
@@ -3361,10 +3434,10 @@ adjust_window_size(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_ses
/* Data (0) */
static int
dissect_http2_data(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_session, proto_tree *http2_tree,
- guint offset, guint8 flags)
+ unsigned offset, uint8_t flags)
{
- guint16 padding;
- gint datalen;
+ uint16_t padding;
+ int datalen;
offset = dissect_frame_padding(tvb, &padding, http2_tree, offset, flags);
datalen = tvb_reported_length_remaining(tvb, offset) - padding;
@@ -3378,7 +3451,7 @@ dissect_http2_data(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_ses
offset += padding;
}
- adjust_window_size(tvb, pinfo, http2_session, http2_tree, (gint32)datalen, FALSE);
+ adjust_window_size(tvb, pinfo, http2_session, http2_tree, (int32_t)datalen, false);
return offset;
}
@@ -3387,14 +3460,14 @@ dissect_http2_data(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* http2_ses
static int
#ifdef HAVE_NGHTTP2
dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2session, proto_tree *http2_tree,
- guint offset, guint8 flags)
+ unsigned offset, uint8_t flags)
#else
dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2session _U_, proto_tree *http2_tree,
- guint offset, guint8 flags)
+ unsigned offset, uint8_t flags)
#endif
{
- guint16 padding;
- gint headlen;
+ uint16_t padding;
+ int headlen;
#ifdef HAVE_NGHTTP2
fragment_head *head;
http2_stream_info_t *info;
@@ -3403,7 +3476,7 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2sess
/* Trailing headers coming after a DATA stream should have END_STREAM set. DATA should be complete
* so try to reassemble DATA fragments if that is the case */
if(IS_HTTP2_END_STREAM(flags)) {
- info = get_stream_info(pinfo, h2session, FALSE);
+ info = get_stream_info(pinfo, h2session, false);
switch (info->reassembly_mode) {
case HTTP2_DATA_REASSEMBLY_MODE_END_STREAM:
head = fragment_end_seq_next(&http2_body_reassembly_table, pinfo, get_reassembly_id_from_stream(pinfo, h2session), NULL);
@@ -3429,7 +3502,7 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2sess
* is set. We use this to ensure when we read header values, we are not reading ones
* that have come from a PUSH_PROMISE header (and associated CONTINUATION frames) */
if (!PINFO_FD_VISITED(pinfo)) {
- http2_header_stream_info_t *header_stream_info = get_header_stream_info(pinfo, h2session, FALSE);
+ http2_header_stream_info_t *header_stream_info = get_header_stream_info(pinfo, h2session, false);
header_stream_info->header_start_in = get_http2_frame_num(tvb, pinfo);
if (flags & HTTP2_FLAGS_END_HEADERS) {
header_stream_info->header_end_in = get_http2_frame_num(tvb, pinfo);
@@ -3454,7 +3527,7 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2sess
#ifdef HAVE_NGHTTP2
/* decompress the header block */
inflate_http2_header_block(tvb, pinfo, offset, http2_tree, headlen, h2session, flags);
- http2_stream_info_t *stream_info = get_stream_info(pinfo, h2session, FALSE);
+ http2_stream_info_t *stream_info = get_stream_info(pinfo, h2session, false);
/* Display request/response links */
if (pinfo->num > stream_info->request_in_frame_num && stream_info->request_in_frame_num > 0) {
@@ -3490,7 +3563,7 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, http2_session_t* h2sess
/* Priority */
static int
dissect_http2_priority(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree,
- guint offset, guint8 flags)
+ unsigned offset, uint8_t flags)
{
/* we pretend the HTTP2_FLAGS_PRIORITY flag is set to share the dissect
function */
@@ -3501,7 +3574,7 @@ dissect_http2_priority(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_
/* RST Stream */
static int
-dissect_http2_rst_stream(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 flags _U_)
+dissect_http2_rst_stream(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, unsigned offset, uint8_t flags _U_)
{
proto_tree_add_item(http2_tree, hf_http2_rst_stream_error, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -3523,17 +3596,17 @@ adjust_existing_window(void *key _U_, void *value, void *userData _U_)
/* Settings */
static int
#ifdef HAVE_NGHTTP2
-dissect_http2_settings(tvbuff_t* tvb, packet_info* pinfo _U_, http2_session_t* h2session, proto_tree* http2_tree, guint offset, guint8 flags)
+dissect_http2_settings(tvbuff_t* tvb, packet_info* pinfo _U_, http2_session_t* h2session, proto_tree* http2_tree, unsigned offset, uint8_t flags)
#else
-dissect_http2_settings(tvbuff_t* tvb, packet_info* pinfo _U_, http2_session_t* h2session _U_, proto_tree* http2_tree, guint offset, guint8 flags _U_)
+dissect_http2_settings(tvbuff_t* tvb, packet_info* pinfo _U_, http2_session_t* h2session _U_, proto_tree* http2_tree, unsigned offset, uint8_t flags _U_)
#endif
{
- guint32 settingsid;
+ uint32_t settingsid;
proto_item *ti_settings;
proto_tree *settings_tree;
#ifdef HAVE_NGHTTP2
- guint32 header_table_size;
- guint32 min_header_table_size;
+ uint32_t header_table_size;
+ uint32_t min_header_table_size;
int header_table_size_found;
header_table_size_found = 0;
@@ -3573,12 +3646,12 @@ dissect_http2_settings(tvbuff_t* tvb, packet_info* pinfo _U_, http2_session_t* h
break;
case HTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
{
- guint32 newInitialWindowSize;
+ uint32_t newInitialWindowSize;
proto_tree_add_item_ret_uint(settings_tree, hf_http2_settings_initial_window_size, tvb, offset, 4, ENC_BIG_ENDIAN, &newInitialWindowSize);
if (h2session) {
- guint32 flow_index = select_http2_flow_index(pinfo, h2session);
+ uint32_t flow_index = select_http2_flow_index(pinfo, h2session);
/* This new initial window size will be applied to
* any new future streams going in the other direction.
@@ -3591,8 +3664,8 @@ dissect_http2_settings(tvbuff_t* tvb, packet_info* pinfo _U_, http2_session_t* h
#ifdef HAVE_NGHTTP2
{
- guint32 previousInitialWindowSize = h2session->initial_new_stream_window_size[flow_index];
- gint32 windowSizeDiff = newInitialWindowSize - previousInitialWindowSize;
+ uint32_t previousInitialWindowSize = h2session->initial_new_stream_window_size[flow_index];
+ int32_t windowSizeDiff = newInitialWindowSize - previousInitialWindowSize;
/* "When the value of SETTINGS_INITIAL_WINDOW_SIZE changes,
* a receiver MUST adjust the size of all stream flow-control
@@ -3656,7 +3729,7 @@ dissect_http2_settings(tvbuff_t* tvb, packet_info* pinfo _U_, http2_session_t* h
}
void
-dissect_http2_settings_ext(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* http2_tree, guint offset) {
+dissect_http2_settings_ext(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* http2_tree, unsigned offset) {
dissect_http2_settings(tvb, pinfo, NULL, http2_tree, offset, 0);
}
@@ -3664,15 +3737,15 @@ dissect_http2_settings_ext(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* ht
static int
#ifdef HAVE_NGHTTP2
dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* h2session, proto_tree *http2_tree,
- guint offset, guint8 flags _U_)
+ unsigned offset, uint8_t flags _U_)
#else
dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* h2session _U_, proto_tree *http2_tree,
- guint offset, guint8 flags _U_)
+ unsigned offset, uint8_t flags _U_)
#endif
{
- guint16 padding;
- gint headlen;
- guint32 promised_stream_id;
+ uint16_t padding;
+ int headlen;
+ uint32_t promised_stream_id;
offset = dissect_frame_padding(tvb, &padding, http2_tree, offset, flags);
@@ -3681,7 +3754,7 @@ dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_
offset, 4, ENC_BIG_ENDIAN, &promised_stream_id);
#ifdef HAVE_NGHTTP2
if (!PINFO_FD_VISITED(pinfo)) {
- http2_header_stream_info_t *header_stream_info = get_header_stream_info(pinfo, h2session, FALSE);
+ http2_header_stream_info_t *header_stream_info = get_header_stream_info(pinfo, h2session, false);
header_stream_info->header_start_in = get_http2_frame_num(tvb, pinfo);
if (flags & HTTP2_FLAGS_END_HEADERS) {
header_stream_info->header_end_in = get_http2_frame_num(tvb, pinfo);
@@ -3709,7 +3782,7 @@ dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_
/* For PUSH_PROMISE, the response is on the promised stream ID. The
* response is also in the same direction as the request.
*/
- http2_stream_info_t *stream_info = get_stream_info_for_id(pinfo, h2session, FALSE, promised_stream_id);
+ http2_stream_info_t *stream_info = get_stream_info_for_id(pinfo, h2session, false, promised_stream_id);
if (pinfo->num == stream_info->request_in_frame_num && stream_info->response_in_frame_num > 0) {
/* Request frame */
proto_item_set_generated(proto_tree_add_uint(http2_tree, hf_http2_response_in, tvb, 0, 0, stream_info->response_in_frame_num));
@@ -3732,7 +3805,7 @@ dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_
/* Ping */
static int
dissect_http2_ping(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree,
- guint offset, guint8 flags)
+ unsigned offset, uint8_t flags)
{
/* TODO : Add Response time */
if(flags & HTTP2_FLAGS_ACK)
@@ -3748,7 +3821,7 @@ dissect_http2_ping(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree
/* Goaway */
static int
-dissect_http2_goaway(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 flags _U_)
+dissect_http2_goaway(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, unsigned offset, uint8_t flags _U_)
{
proto_tree_add_item(http2_tree, hf_http2_goaway_r, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -3767,33 +3840,33 @@ dissect_http2_goaway(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tr
/* Window Update */
static int
-dissect_http2_window_update(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* http2_session, proto_tree *http2_tree, guint offset, guint8 flags _U_)
+dissect_http2_window_update(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* http2_session, proto_tree *http2_tree, unsigned offset, uint8_t flags _U_)
{
- gint32 wsi;
+ int32_t wsi;
proto_tree_add_item(http2_tree, hf_http2_window_update_r, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item_ret_uint(http2_tree, hf_http2_window_update_window_size_increment, tvb, offset, 4, ENC_BIG_ENDIAN, &wsi);
offset += 4;
- adjust_window_size(tvb, pinfo, http2_session, http2_tree, wsi, TRUE);
+ adjust_window_size(tvb, pinfo, http2_session, http2_tree, wsi, true);
return offset;
}
static int
#ifdef HAVE_NGHTTP2
-dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* h2session, proto_tree *http2_tree, guint offset, guint8 flags)
+dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* h2session, proto_tree *http2_tree, unsigned offset, uint8_t flags)
#else
-dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* h2session _U_, proto_tree *http2_tree, guint offset, guint8 flags)
+dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_t* h2session _U_, proto_tree *http2_tree, unsigned offset, uint8_t flags)
#endif
{
- guint16 padding;
- gint headlen;
+ uint16_t padding;
+ int headlen;
#ifdef HAVE_NGHTTP2
/* Mark this as the last CONTINUATION frame for a HEADERS frame. This is used to know the context when we read
* header (is the source a HEADER frame or a PUSH_PROMISE frame?) */
if (!PINFO_FD_VISITED(pinfo) && flags & HTTP2_FLAGS_END_HEADERS) {
- http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, h2session, FALSE);
+ http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, h2session, false);
if (stream_info->header_start_in != 0 && stream_info->header_end_in == 0) {
stream_info->header_end_in = get_http2_frame_num(tvb, pinfo);
}
@@ -3829,9 +3902,9 @@ dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, http2_session_
/* Altsvc */
static int
dissect_http2_altsvc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree,
- guint offset, guint8 flags _U_, guint16 length)
+ unsigned offset, uint8_t flags _U_, uint16_t length)
{
- guint32 origin_len;
+ uint32_t origin_len;
int remain = length;
proto_tree_add_item_ret_uint(http2_tree, hf_http2_altsvc_origin_len, tvb, offset, 2, ENC_BIG_ENDIAN, &origin_len);
@@ -3853,9 +3926,9 @@ dissect_http2_altsvc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tr
/* Origin */
static int
dissect_http2_origin(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree,
- guint offset, guint8 flags _U_)
+ unsigned offset, uint8_t flags _U_)
{
- guint32 origin_len;
+ uint32_t origin_len;
proto_item *ti_origin_entry;
proto_tree *origin_entry_tree;
@@ -3878,7 +3951,7 @@ dissect_http2_origin(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tr
/* Priority Update */
static int
dissect_http2_priority_update(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree,
- guint offset, guint8 flags _U_, guint16 length)
+ unsigned offset, uint8_t flags _U_, uint16_t length)
{
int remain = length;
@@ -3898,15 +3971,15 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
{
proto_item *ti;
proto_tree *http2_tree;
- guint offset = 0;
- guint8 type, flags;
- guint16 length;
- guint32 streamid;
+ unsigned offset = 0;
+ uint8_t type, flags;
+ uint16_t length;
+ uint32_t streamid;
struct HTTP2Tap *http2_stats;
GHashTable* entry;
struct tcp_analysis* tcpd;
conversation_t* conversation = find_or_create_conversation(pinfo);
- gboolean use_follow_tap = TRUE;
+ bool use_follow_tap = true;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "HTTP2");
@@ -3968,10 +4041,10 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
offset += 3;
proto_tree_add_item(http2_tree, hf_http2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
- type = tvb_get_guint8(tvb, offset);
+ type = tvb_get_uint8(tvb, offset);
- gint type_idx;
- const gchar *type_str = try_val_to_str_idx(type, http2_type_vals, &type_idx);
+ int type_idx;
+ const char *type_str = try_val_to_str_idx(type, http2_type_vals, &type_idx);
if (type_str == NULL) {
type_str = wmem_strdup_printf(pinfo->pool, "Unknown type (%d)", type);
}
@@ -4014,14 +4087,14 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
case HTTP2_DATA: /* Data (0) */
dissect_http2_data(tvb, pinfo, http2_session, http2_tree, offset, flags);
#ifdef HAVE_NGHTTP2
- use_follow_tap = FALSE;
+ use_follow_tap = false;
#endif
break;
case HTTP2_HEADERS: /* Headers (1) */
dissect_http2_headers(tvb, pinfo, http2_session, http2_tree, offset, flags);
#ifdef HAVE_NGHTTP2
- use_follow_tap = FALSE;
+ use_follow_tap = false;
#endif
break;
@@ -4040,7 +4113,7 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
case HTTP2_PUSH_PROMISE: /* PUSH Promise (5) */
dissect_http2_push_promise(tvb, pinfo, http2_session, http2_tree, offset, flags);
#ifdef HAVE_NGHTTP2
- use_follow_tap = FALSE;
+ use_follow_tap = false;
#endif
break;
@@ -4059,7 +4132,7 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
case HTTP2_CONTINUATION: /* Continuation (9) */
dissect_http2_continuation(tvb, pinfo, http2_session, http2_tree, offset, flags);
#ifdef HAVE_NGHTTP2
- use_follow_tap = FALSE;
+ use_follow_tap = false;
#endif
break;
@@ -4089,7 +4162,7 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
* and sent to the follow tap inside inflate_http2_header_block.
*/
if (have_tap_listener(http2_follow_tap) && use_follow_tap) {
- http2_follow_tap_data_t *follow_data = wmem_new0(wmem_packet_scope(), http2_follow_tap_data_t);
+ http2_follow_tap_data_t *follow_data = wmem_new0(pinfo->pool, http2_follow_tap_data_t);
follow_data->tvb = tvb;
follow_data->stream_id = streamid;
@@ -4100,14 +4173,19 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
return tvb_captured_length(tvb);
}
-static guint get_http2_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
+static unsigned get_http2_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
int offset, void *data _U_)
{
- if ( tvb_memeql( tvb, offset, kMagicHello, MAGIC_FRAME_LENGTH ) == 0 ) {
- return MAGIC_FRAME_LENGTH;
+ if ( tvb_memeql( tvb, offset, kMagicHello, FRAME_HEADER_LENGTH ) == 0 ) {
+ /* We're only guaranteed to have FRAME_HEADER_LENGTH here, but if
+ * those bytes match it's not a legal ordinary frame so it's
+ * sufficient. If we're here, we've already decided this is HTTP/2
+ * via heuristics or setting HTTP/2 to the port.
+ */
+ return MAGIC_FRAME_LENGTH;
}
- return (guint)tvb_get_ntoh24(tvb, offset) + FRAME_HEADER_LENGTH;
+ return (unsigned)tvb_get_ntoh24(tvb, offset) + FRAME_HEADER_LENGTH;
}
@@ -4120,13 +4198,13 @@ dissect_http2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*/
col_clear(pinfo->cinfo, COL_INFO);
- tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LENGTH,
+ tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LENGTH,
get_http2_message_len, dissect_http2_pdu, data);
return tvb_captured_length(tvb);
}
-static gboolean
+static bool
dissect_http2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
conversation_t *conversation;
@@ -4138,30 +4216,72 @@ dissect_http2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *da
/* A http2 conversation was previously started, assume it is still active */
if (session) {
dissect_http2(tvb, pinfo, tree, data);
- return TRUE;
+ return true;
}
if (tvb_memeql(tvb, 0, kMagicHello, MAGIC_FRAME_LENGTH) != 0) {
/* we couldn't find the Magic Hello (PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n). */
- return FALSE;
+ return false;
}
/* Remember http2 conversation. */
get_http2_session(pinfo, conversation);
dissect_http2(tvb, pinfo, tree, data);
- return (TRUE);
+ return true;
}
-static gboolean
+static bool
+dissect_http2_heur_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ conversation_t *conversation;
+ http2_session_t *session;
+
+ conversation = find_or_create_conversation(pinfo);
+ session = (http2_session_t *)conversation_get_proto_data(conversation,
+ proto_http2);
+ /* A http2 conversation was previously started, assume it is still active */
+ if (session) {
+ dissect_http2(tvb, pinfo, tree, data);
+ return true;
+ }
+
+ /* The HTTP dissector should hand us at least one line, but possibly only
+ * the first (if the TCP segment length is absurdly small.) 16 bytes is
+ * still enough to call this HTTP/2.
+ */
+ if (tvb_memeql(tvb, 0, kMagicHello, MAGIC_FRAME_FIRST_LINE) != 0) {
+ /* we couldn't find the Magic Hello (PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n). */
+ return false;
+ }
+
+ /* Remember http2 conversation. */
+ get_http2_session(pinfo, conversation);
+
+ /* XXX - Ideally we'd set the conversation dissector so that TCP calls
+ * HTTP/2 directly instead of HTTP. (Note we don't call this path for
+ * upgraded connections, which still go through the HTTP dissector.)
+ * That would change pinfo->curr_layer_num for this first packet on the
+ * second pass, though, so we'd want to make sure we're using
+ * curr_proto_layer_num or similar to avoid that being an issue,
+ * e.g. on reassembly of HEADERS or DATA sent along with this frame.
+ * So for now we have the HTTP dissector call the HTTP/2 dissector.
+ */
+ //conversation_set_dissector_from_frame_number(conversation, pinfo->num, http2_handle);
+ dissect_http2(tvb, pinfo, tree, data);
+
+ return true;
+}
+
+static bool
dissect_http2_heur_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
struct tlsinfo *tlsinfo = (struct tlsinfo *) data;
if (dissect_http2_heur(tvb, pinfo, tree, NULL)) {
*(tlsinfo->app_handle) = http2_handle;
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
void
@@ -4570,7 +4690,7 @@ proto_register_http2(void)
/* Goaway */
{ &hf_http2_goaway_r,
- { "Reserved", "http2.goway.r",
+ { "Reserved", "http2.goaway.r",
FT_UINT32, BASE_HEX, NULL, MASK_HTTP2_RESERVED,
"Must be zero", HFILL }
},
@@ -4700,7 +4820,7 @@ proto_register_http2(void)
},
};
- static gint *ett[] = {
+ static int *ett[] = {
&ett_http2,
&ett_http2_header,
&ett_http2_headers,
@@ -4770,7 +4890,7 @@ proto_register_http2(void)
headers_uat = uat_new("Custom HTTP2 Header Fields",
sizeof(header_field_t),
"custom_http2_header_fields",
- TRUE,
+ true,
&header_fields,
&num_header_fields,
/* specifies named fields, so affects dissection
@@ -4800,6 +4920,7 @@ proto_register_http2(void)
"This rule applies to the message sent to (IN) or from (OUT) server."),
UAT_FLD_CSTRING(http2_fake_headers, header_name, "Header name", "HTTP2 header name"),
UAT_FLD_CSTRING(http2_fake_headers, header_value, "Header value", "HTTP2 header value"),
+ UAT_FLD_BOOL(http2_fake_headers, override, "Override", "Override existing header"),
UAT_FLD_BOOL(http2_fake_headers, enable, "Enable", "Enable this rule"),
UAT_END_FIELDS
};
@@ -4807,7 +4928,7 @@ proto_register_http2(void)
fake_headers_uat = uat_new("HTTP2 Fake Headers",
sizeof(http2_fake_header_t),
"http2_fake_headers",
- TRUE,
+ true,
&http2_fake_headers,
&num_http2_fake_headers,
UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS,
@@ -4862,7 +4983,7 @@ proto_register_http2(void)
static void http2_stats_tree_init(stats_tree* st)
{
- st_node_http2 = stats_tree_create_node(st, st_str_http2, 0, STAT_DT_INT, TRUE);
+ st_node_http2 = stats_tree_create_node(st, st_str_http2, 0, STAT_DT_INT, true);
st_node_http2_type = stats_tree_create_pivot(st, st_str_http2_type, st_node_http2);
}
@@ -4870,7 +4991,7 @@ static void http2_stats_tree_init(stats_tree* st)
static tap_packet_status http2_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p, tap_flags_t flags _U_)
{
const struct HTTP2Tap *pi = (const struct HTTP2Tap *)p;
- tick_stat_node(st, st_str_http2, 0, FALSE);
+ tick_stat_node(st, st_str_http2, 0, false);
stats_tree_tick_pivot(st, st_node_http2_type,
val_to_str(pi->type, http2_type_vals, "Unknown type (%d)"));
@@ -4897,7 +5018,8 @@ proto_reg_handoff_http2(void)
dissector_add_string("http.upgrade", "h2c", http2_handle);
heur_dissector_add("tls", dissect_http2_heur_ssl, "HTTP2 over TLS", "http2_tls", proto_http2, HEURISTIC_ENABLE);
- heur_dissector_add("http", dissect_http2_heur, "HTTP2 over TCP", "http2_tcp", proto_http2, HEURISTIC_ENABLE);
+ heur_dissector_add("tcp", dissect_http2_heur, "HTTP2 over TCP", "http2_tcp", proto_http2, HEURISTIC_ENABLE);
+ heur_dissector_add("http", dissect_http2_heur_http, "HTTP2 on an HTTP port", "http2_http", proto_http2, HEURISTIC_ENABLE);
stats_tree_register("http2", "http2", "HTTP2", 0, http2_stats_tree_packet, http2_stats_tree_init, NULL);