aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/asn1/cmp/packet-cmp-template.c4
-rw-r--r--epan/dissectors/packet-cmp.c4
-rw-r--r--epan/dissectors/packet-daap.c2
-rw-r--r--epan/dissectors/packet-http.c186
-rw-r--r--epan/dissectors/packet-http.h4
-rw-r--r--epan/dissectors/packet-ipp.c2
6 files changed, 140 insertions, 62 deletions
diff --git a/epan/dissectors/asn1/cmp/packet-cmp-template.c b/epan/dissectors/asn1/cmp/packet-cmp-template.c
index b1219cab72..0446c6040c 100644
--- a/epan/dissectors/asn1/cmp/packet-cmp-template.c
+++ b/epan/dissectors/asn1/cmp/packet-cmp-template.c
@@ -417,7 +417,7 @@ void proto_reg_handoff_cmp(void) {
dissector_delete_uint("http.port", cmp_alternate_http_port_prev, NULL);
}
if (cmp_alternate_http_port != 0)
- http_dissector_add( cmp_alternate_http_port, cmp_http_handle);
+ http_tcp_dissector_add( cmp_alternate_http_port, cmp_http_handle);
cmp_alternate_http_port_prev = cmp_alternate_http_port;
}
@@ -428,7 +428,7 @@ void proto_reg_handoff_cmp(void) {
dissector_delete_uint("http.port", cmp_alternate_tcp_style_http_port_prev, NULL);
}
if (cmp_alternate_tcp_style_http_port != 0)
- http_dissector_add( cmp_alternate_tcp_style_http_port, cmp_tcp_style_http_handle);
+ http_tcp_dissector_add( cmp_alternate_tcp_style_http_port, cmp_tcp_style_http_handle);
cmp_alternate_tcp_style_http_port_prev = cmp_alternate_tcp_style_http_port;
}
diff --git a/epan/dissectors/packet-cmp.c b/epan/dissectors/packet-cmp.c
index 91fe979703..8e0bc7b492 100644
--- a/epan/dissectors/packet-cmp.c
+++ b/epan/dissectors/packet-cmp.c
@@ -2538,7 +2538,7 @@ void proto_reg_handoff_cmp(void) {
dissector_delete_uint("http.port", cmp_alternate_http_port_prev, NULL);
}
if (cmp_alternate_http_port != 0)
- http_dissector_add( cmp_alternate_http_port, cmp_http_handle);
+ http_tcp_dissector_add( cmp_alternate_http_port, cmp_http_handle);
cmp_alternate_http_port_prev = cmp_alternate_http_port;
}
@@ -2549,7 +2549,7 @@ void proto_reg_handoff_cmp(void) {
dissector_delete_uint("http.port", cmp_alternate_tcp_style_http_port_prev, NULL);
}
if (cmp_alternate_tcp_style_http_port != 0)
- http_dissector_add( cmp_alternate_tcp_style_http_port, cmp_tcp_style_http_handle);
+ http_tcp_dissector_add( cmp_alternate_tcp_style_http_port, cmp_tcp_style_http_handle);
cmp_alternate_tcp_style_http_port_prev = cmp_alternate_tcp_style_http_port;
}
diff --git a/epan/dissectors/packet-daap.c b/epan/dissectors/packet-daap.c
index cd670faae9..4d1b600bab 100644
--- a/epan/dissectors/packet-daap.c
+++ b/epan/dissectors/packet-daap.c
@@ -775,7 +775,7 @@ proto_reg_handoff_daap(void)
dissector_handle_t daap_handle;
daap_handle = create_dissector_handle(dissect_daap, proto_daap);
- http_port_add(TCP_PORT_DAAP);
+ http_tcp_port_add(TCP_PORT_DAAP);
dissector_add_string("media_type", "application/x-dmap-tagged", daap_handle);
png_handle = find_dissector_add_dependency("png", proto_daap);
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index bb4ea9816a..dd5c1dd273 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -151,6 +151,9 @@ static expert_field ei_http_ssl_port = EI_INIT;
static expert_field ei_http_leading_crlf = EI_INIT;
static dissector_handle_t http_handle;
+static dissector_handle_t http_tcp_handle;
+static dissector_handle_t http_ssl_handle;
+static dissector_handle_t http_sctp_handle;
static dissector_handle_t media_handle;
static dissector_handle_t websocket_handle;
@@ -723,7 +726,8 @@ static http_info_value_t *stat_info;
static int
dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, http_conv_t *conv_data, const char* proto_tag, int proto, struct tcpinfo *tcpinfo)
+ proto_tree *tree, http_conv_t *conv_data,
+ const char* proto_tag, int proto, gboolean end_of_stream)
{
proto_tree *http_tree = NULL;
proto_item *ti = NULL;
@@ -830,7 +834,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
*/
gboolean try_desegment_body = (http_desegment_body &&
(!(conv_data->request_method && g_str_equal(conv_data->request_method, "HEAD"))) &&
- ((tcpinfo == NULL) || (!IS_TH_FIN(tcpinfo->flags))));
+ !end_of_stream);
if (!req_resp_hdrs_do_reassembly(tvb, offset, pinfo,
http_desegment_headers, try_desegment_body)) {
/*
@@ -2034,6 +2038,19 @@ chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
}
#endif
+static gboolean
+conversation_dissector_is_http(conversation_t *conv, guint32 frame_num)
+{
+ dissector_handle_t conv_handle;
+
+ if (conv == NULL)
+ return FALSE;
+ conv_handle = conversation_get_dissector(conv, frame_num);
+ return conv_handle == http_handle ||
+ conv_handle == http_tcp_handle ||
+ conv_handle == http_sctp_handle;
+}
+
/* Call a subdissector to handle HTTP CONNECT's traffic */
static void
http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
@@ -2086,7 +2103,8 @@ http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
* conversation (e.g., one we detected heuristically or via Decode-As) call the data
* dissector directly.
*/
- if (value_is_in_range(http_tcp_range, uri_port) || (conv && conversation_get_dissector(conv, pinfo->num) == http_handle)) {
+ if (value_is_in_range(http_tcp_range, uri_port) ||
+ conversation_dissector_is_http(conv, pinfo->num)) {
call_data_dissector(tvb, pinfo, tree);
} else {
/* set pinfo->{src/dst port} and call the TCP sub-dissector lookup */
@@ -3009,17 +3027,58 @@ check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo, con
return FALSE;
}
-static int
-dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+static void
+dissect_http_on_stream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ http_conv_t *conv_data, gboolean end_of_stream)
{
- http_conv_t *conv_data;
int offset = 0;
int len;
- conversation_t *conversation;
dissector_handle_t next_handle = NULL;
+
+ while (tvb_reported_length_remaining(tvb, offset) > 0) {
+ if (conv_data->upgrade == UPGRADE_WEBSOCKET && pinfo->num >= conv_data->startframe) {
+ next_handle = websocket_handle;
+ }
+ if (conv_data->upgrade == UPGRADE_HTTP2 && pinfo->num >= conv_data->startframe) {
+ next_handle = http2_handle;
+ }
+ if (conv_data->upgrade == UPGRADE_SSTP && conv_data->response_code == 200 && pinfo->num >= conv_data->startframe) {
+ next_handle = sstp_handle;
+ }
+ if (next_handle) {
+ /* Increase pinfo->can_desegment because we are traversing
+ * http and want to preserve desegmentation functionality for
+ * the proxied protocol
+ */
+ if (pinfo->can_desegment > 0)
+ pinfo->can_desegment++;
+ call_dissector_only(next_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree, NULL);
+ break;
+ }
+ len = dissect_http_message(tvb, offset, pinfo, tree, conv_data, "HTTP", proto_http, end_of_stream);
+ if (len == -1)
+ break;
+ offset += len;
+
+ /*
+ * OK, we've set the Protocol and Info columns for the
+ * first HTTP message; set a fence so that subsequent
+ * HTTP messages don't overwrite the Info column.
+ */
+ col_set_fence(pinfo->cinfo, COL_INFO);
+ }
+}
+
+static int
+dissect_http_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
struct tcpinfo *tcpinfo = (struct tcpinfo *)data;
+ conversation_t *conversation;
+ http_conv_t *conv_data;
+ gboolean end_of_stream;
conv_data = get_http_conversation_data(pinfo, &conversation);
+
/* Call HTTP2 dissector directly when detected via heuristics, but not
* when it was upgraded (the conversation started with HTTP). */
if (conversation_get_proto_data(conversation, proto_http2) &&
@@ -3041,42 +3100,12 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
if(conv_data->startframe == 0 && !pinfo->fd->flags.visited)
conv_data->startframe = pinfo->num;
http_payload_subdissector(tvb, tree, pinfo, conv_data, data);
- } else {
- while (tvb_reported_length_remaining(tvb, offset) > 0) {
- if (conv_data->upgrade == UPGRADE_WEBSOCKET && pinfo->num >= conv_data->startframe) {
- next_handle = websocket_handle;
- }
- if (conv_data->upgrade == UPGRADE_HTTP2 && pinfo->num >= conv_data->startframe) {
- next_handle = http2_handle;
- }
- if (conv_data->upgrade == UPGRADE_SSTP && conv_data->response_code == 200 && pinfo->num >= conv_data->startframe) {
- next_handle = sstp_handle;
- }
- if (next_handle) {
- /* Increase pinfo->can_desegment because we are traversing
- * http and want to preserve desegmentation functionality for
- * the proxied protocol
- */
- if (pinfo->can_desegment > 0)
- pinfo->can_desegment++;
-
- call_dissector_only(next_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree, NULL);
- break;
- }
- len = dissect_http_message(tvb, offset, pinfo, tree, conv_data, "HTTP", proto_http, tcpinfo);
- if (len == -1)
- break;
- offset += len;
- /*
- * OK, we've set the Protocol and Info columns for the
- * first HTTP message; set a fence so that subsequent
- * HTTP messages don't overwrite the Info column.
- */
- col_set_fence(pinfo->cinfo, COL_INFO);
- }
+ return tvb_captured_length(tvb);
}
+ end_of_stream = IS_TH_FIN(tcpinfo->flags);
+ dissect_http_on_stream(tvb, pinfo, tree, conv_data, end_of_stream);
return tvb_captured_length(tvb);
}
@@ -3101,8 +3130,8 @@ dissect_http_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
/* Check if the line start or ends with the HTTP token */
if((tvb_strncaseeql(tvb, linelen-8, "HTTP/1.1", 8) == 0)||(tvb_strncaseeql(tvb, 0, "HTTP/1.1", 8) == 0)){
conversation = find_or_create_conversation(pinfo);
- conversation_set_dissector_from_frame_number(conversation, pinfo->num, http_handle);
- dissect_http(tvb, pinfo, tree, data);
+ conversation_set_dissector_from_frame_number(conversation, pinfo->num, http_tcp_handle);
+ dissect_http_tcp(tvb, pinfo, tree, data);
return TRUE;
}
@@ -3110,36 +3139,82 @@ dissect_http_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
}
static int
+dissect_http_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ conversation_t *conversation;
+ http_conv_t *conv_data;
+
+ conv_data = get_http_conversation_data(pinfo, &conversation);
+
+ /*
+ * XXX - we need to provide an end-of-stream indication.
+ */
+ dissect_http_on_stream(tvb, pinfo, tree, conv_data, FALSE);
+ return tvb_captured_length(tvb);
+}
+
+static int
+dissect_http_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ conversation_t *conversation;
+ http_conv_t *conv_data;
+
+ conv_data = get_http_conversation_data(pinfo, &conversation);
+
+ /*
+ * XXX - we need to provide an end-of-stream indication.
+ */
+ dissect_http_on_stream(tvb, pinfo, tree, conv_data, FALSE);
+ return tvb_captured_length(tvb);
+}
+
+static int
+dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ conversation_t *conversation;
+ http_conv_t *conv_data;
+
+ conv_data = get_http_conversation_data(pinfo, &conversation);
+
+ /*
+ * XXX - what should be done about reassembly, pipelining, etc.
+ * here?
+ */
+ dissect_http_on_stream(tvb, pinfo, tree, conv_data, FALSE);
+ return tvb_captured_length(tvb);
+}
+
+static int
dissect_ssdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
conversation_t *conversation;
http_conv_t *conv_data;
conv_data = get_http_conversation_data(pinfo, &conversation);
- dissect_http_message(tvb, 0, pinfo, tree, conv_data, "SSDP", proto_ssdp, NULL);
+ dissect_http_message(tvb, 0, pinfo, tree, conv_data, "SSDP", proto_ssdp, FALSE);
return tvb_captured_length(tvb);
}
static void
range_delete_http_ssl_callback(guint32 port) {
- ssl_dissector_delete(port, http_handle);
+ ssl_dissector_delete(port, http_ssl_handle);
}
static void
range_add_http_ssl_callback(guint32 port) {
- ssl_dissector_add(port, http_handle);
+ ssl_dissector_add(port, http_ssl_handle);
}
static void reinit_http(void) {
- dissector_delete_uint_range("tcp.port", http_tcp_range, http_handle);
+ dissector_delete_uint_range("tcp.port", http_tcp_range, http_tcp_handle);
g_free(http_tcp_range);
http_tcp_range = range_copy(global_http_tcp_range);
- dissector_add_uint_range("tcp.port", http_tcp_range, http_handle);
+ dissector_add_uint_range("tcp.port", http_tcp_range, http_tcp_handle);
- dissector_delete_uint_range("sctp.port", http_sctp_range, http_handle);
+ dissector_delete_uint_range("sctp.port", http_sctp_range, http_sctp_handle);
g_free(http_sctp_range);
http_sctp_range = range_copy(global_http_sctp_range);
- dissector_add_uint_range("sctp.port", http_sctp_range, http_handle);
+ dissector_add_uint_range("sctp.port", http_sctp_range, http_sctp_handle);
range_foreach(http_ssl_range, range_delete_http_ssl_callback);
g_free(http_ssl_range);
@@ -3441,6 +3516,9 @@ proto_register_http(void)
expert_register_field_array(expert_http, ei, array_length(ei));
http_handle = register_dissector("http", dissect_http, proto_http);
+ http_tcp_handle = register_dissector("http-over-tcp", dissect_http_tcp, proto_http);
+ http_ssl_handle = register_dissector("http-over-ssl", dissect_http_ssl, proto_http);
+ http_sctp_handle = register_dissector("http-over-sctp", dissect_http_sctp, proto_http);
http_module = prefs_register_protocol(proto_http, reinit_http);
prefs_register_bool_preference(http_module, "desegment_headers",
@@ -3514,7 +3592,7 @@ proto_register_http(void)
/*
* Dissectors shouldn't register themselves in this table;
- * instead, they should call "http_dissector_add()", and
+ * instead, they should call "http_tcp_dissector_add()", and
* we'll register the port number they specify as a port
* for HTTP, and register them in our subdissector table.
*
@@ -3555,13 +3633,13 @@ proto_register_http(void)
* Called by dissectors for protocols that run atop HTTP/TCP.
*/
void
-http_dissector_add(guint32 port, dissector_handle_t handle)
+http_tcp_dissector_add(guint32 port, dissector_handle_t handle)
{
/*
* Register ourselves as the handler for that port number
* over TCP.
*/
- dissector_add_uint("tcp.port", port, http_handle);
+ dissector_add_uint("tcp.port", port, http_tcp_handle);
/*
* And register them in *our* table for that port.
@@ -3570,14 +3648,14 @@ http_dissector_add(guint32 port, dissector_handle_t handle)
}
void
-http_port_add(guint32 port)
+http_tcp_port_add(guint32 port)
{
/*
* Register ourselves as the handler for that port number
* over TCP. We rely on our caller having registered
* themselves for the appropriate media type.
*/
- dissector_add_uint("tcp.port", port, http_handle);
+ dissector_add_uint("tcp.port", port, http_tcp_handle);
}
void
diff --git a/epan/dissectors/packet-http.h b/epan/dissectors/packet-http.h
index c6411aa757..179ca200a0 100644
--- a/epan/dissectors/packet-http.h
+++ b/epan/dissectors/packet-http.h
@@ -28,9 +28,9 @@
extern const value_string vals_http_status_code[];
WS_DLL_PUBLIC
-void http_dissector_add(guint32 port, dissector_handle_t handle);
+void http_tcp_dissector_add(guint32 port, dissector_handle_t handle);
WS_DLL_PUBLIC
-void http_port_add(guint32 port);
+void http_tcp_port_add(guint32 port);
/* Used for HTTP statistics */
typedef struct _http_info_value_t {
diff --git a/epan/dissectors/packet-ipp.c b/epan/dissectors/packet-ipp.c
index 4abacb8c51..e0447bbb2d 100644
--- a/epan/dissectors/packet-ipp.c
+++ b/epan/dissectors/packet-ipp.c
@@ -715,7 +715,7 @@ proto_reg_handoff_ipp(void)
* Register ourselves as running atop HTTP and using port 631.
*/
ipp_handle = create_dissector_handle(dissect_ipp, proto_ipp);
- http_dissector_add(631, ipp_handle);
+ http_tcp_dissector_add(631, ipp_handle);
dissector_add_string("media_type", "application/ipp", ipp_handle);
}