aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2017-09-11 15:11:45 -0700
committerGerald Combs <gerald@wireshark.org>2017-09-27 21:58:36 +0000
commitcd90f732a1354f4615fa51c136255991f362b5bf (patch)
treed0c1ec84efa4efeebb8ecc9fe08c390493aa90ff
parent3d661f2fe5851cb84fd6953774bb71ee5071c597 (diff)
Improve frame.protocols accuracy.
During single-pass tshark dissection we can end up adding "Protocols in frame: ...:tcp:http" to the tree even though we haven't dissected HTTP. This may be true of other protocols as well. Remove our last layer when we haven't added any items to the tree. Decrement curr_layer_num as well. Update the layer logic in dissector_try_heuristic to match call_dissector_work. Change-Id: Ibc0591e774761e9496d056080c980243a0447066 Reviewed-on: https://code.wireshark.org/review/23508 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
-rw-r--r--epan/packet.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/epan/packet.c b/epan/packet.c
index b416c8c03c..00c6609f0f 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -710,11 +710,12 @@ static int
call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo_arg,
proto_tree *tree, gboolean add_proto_name, void *data)
{
- packet_info *pinfo = pinfo_arg;
+ packet_info *pinfo = pinfo_arg;
const char *saved_proto;
guint16 saved_can_desegment;
int len;
guint saved_layers_len = 0;
+ int saved_tree_count = tree ? tree->tree_data->count : 0;
if (handle->protocol != NULL &&
!proto_is_protocol_enabled(handle->protocol)) {
@@ -747,9 +748,11 @@ call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo
proto_get_protocol_short_name(handle->protocol);
/*
- * Add the protocol name to the layers
- * if not told not to. Asn2wrs generated dissectors may be added multiple times otherwise.
+ * Add the protocol name to the layers only if told to
+ * do so. Asn2wrs generated dissectors may be added
+ * multiple times otherwise.
*/
+ /* XXX Should we check for a duplicate layer here? */
if (add_proto_name) {
pinfo->curr_layer_num++;
wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_get_id(handle->protocol)));
@@ -760,22 +763,24 @@ call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo
len = call_dissector_work_error(handle, tvb, pinfo, tree, data);
} else {
/*
- * Just call the subdissector.
- */
+ * Just call the subdissector.
+ */
len = call_dissector_through_handle(handle, tvb, pinfo, tree, data);
}
- if (len == 0) {
+ if (add_proto_name &&
+ (len == 0 || (tree && saved_tree_count == tree->tree_data->count))) {
/*
- * That dissector didn't accept the packet, so
- * remove its protocol's name from the list
- * of protocols.
+ * We've added a layer and either the dissector didn't
+ * accept the packet or we didn't add any items to the
+ * tree. Remove it.
*/
while (wmem_list_count(pinfo->layers) > saved_layers_len) {
+ pinfo->curr_layer_num--;
wmem_list_remove_frame(pinfo->layers, wmem_list_tail(pinfo->layers));
}
- }
- pinfo->current_proto = saved_proto;
- pinfo->can_desegment = saved_can_desegment;
+ }
+ pinfo->current_proto = saved_proto;
+ pinfo->can_desegment = saved_can_desegment;
return len;
}
@@ -2614,6 +2619,8 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
guint saved_layers_len = 0;
heur_dtbl_entry_t *hdtbl_entry;
int proto_id;
+ int len;
+ int saved_tree_count = tree ? tree->tree_data->count : 0;
/* can_desegment is set to 2 by anyone which offers this api/service.
then everytime a subdissector is called it is decremented by one.
@@ -2660,22 +2667,27 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
* Add the protocol name to the layers; we'll remove it
* if the dissector fails.
*/
+ pinfo->curr_layer_num++;
wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_id));
}
pinfo->heur_list_name = hdtbl_entry->list_name;
- if ((hdtbl_entry->dissector)(tvb, pinfo, tree, data)) {
+ len = (hdtbl_entry->dissector)(tvb, pinfo, tree, data);
+ if (len) {
*heur_dtbl_entry = hdtbl_entry;
status = TRUE;
break;
- } else {
+ }
+ if (hdtbl_entry->protocol != NULL &&
+ (len == 0 || (tree && saved_tree_count == tree->tree_data->count))) {
/*
- * That dissector didn't accept the packet, so
- * remove its protocol's name from the list
- * of protocols.
+ * We added a protocol layer above. The dissector
+ * didn't accept the packet or it didn't add any
+ * items to the tree so remove it from the list.
*/
while (wmem_list_count(pinfo->layers) > saved_layers_len) {
+ pinfo->curr_layer_num--;
wmem_list_remove_frame(pinfo->layers, wmem_list_tail(pinfo->layers));
}
}