Support for looking for incomplete dissectors.
Change-Id: I03e592dd3d54fc0e1c4af09d5d5336dda93f950e Reviewed-on: https://code.wireshark.org/review/6978 Reviewed-by: Evan Huus <eapache@gmail.com> Petri-Dish: Evan Huus <eapache@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
This commit is contained in:
parent
207b52a988
commit
60cc8b4fd8
|
@ -40,6 +40,7 @@
|
||||||
#include <wsutil/md5.h>
|
#include <wsutil/md5.h>
|
||||||
|
|
||||||
#include "packet-frame.h"
|
#include "packet-frame.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "color_filters.h"
|
#include "color_filters.h"
|
||||||
|
@ -91,6 +92,7 @@ static gint ett_comments = -1;
|
||||||
|
|
||||||
static expert_field ei_comments_text = EI_INIT;
|
static expert_field ei_comments_text = EI_INIT;
|
||||||
static expert_field ei_arrive_time_out_of_range = EI_INIT;
|
static expert_field ei_arrive_time_out_of_range = EI_INIT;
|
||||||
|
static expert_field ei_incomplete = EI_INIT;
|
||||||
|
|
||||||
static int frame_tap = -1;
|
static int frame_tap = -1;
|
||||||
|
|
||||||
|
@ -626,6 +628,32 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
|
||||||
pinfo->frame_end_routines = NULL;
|
pinfo->frame_end_routines = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefs.enable_incomplete_dissectors_check && tree && tree->tree_data->visible) {
|
||||||
|
gchar* decoded;
|
||||||
|
guint length;
|
||||||
|
guint i;
|
||||||
|
guint byte;
|
||||||
|
guint bit;
|
||||||
|
|
||||||
|
length = tvb_captured_length(tvb);
|
||||||
|
decoded = proto_find_undecoded_data(tree, length);
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
byte = i / 8;
|
||||||
|
bit = i % 8;
|
||||||
|
if (!(decoded[byte] & (1 << bit))) {
|
||||||
|
field_info* fi = proto_find_field_from_offset(tree, i, tvb);
|
||||||
|
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING,
|
||||||
|
"Dissector %s incomplete in frame %u: undecoded byte number %u "
|
||||||
|
"(0x%.4X+%u)\n",
|
||||||
|
(fi ? fi->hfinfo->abbrev : "[unknown]"),
|
||||||
|
pinfo->fd->num, i, i - i % 16, i % 16);
|
||||||
|
expert_add_info_format(pinfo, tree, &ei_incomplete,
|
||||||
|
"Undecoded byte number: %u (0x%.4X+%u)", i, i - i % 16, i % 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tvb_captured_length(tvb);
|
return tvb_captured_length(tvb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,6 +847,7 @@ proto_register_frame(void)
|
||||||
static ei_register_info ei[] = {
|
static ei_register_info ei[] = {
|
||||||
{ &ei_comments_text, { "frame.comment.expert", PI_COMMENTS_GROUP, PI_COMMENT, "Formatted comment", EXPFILL }},
|
{ &ei_comments_text, { "frame.comment.expert", PI_COMMENTS_GROUP, PI_COMMENT, "Formatted comment", EXPFILL }},
|
||||||
{ &ei_arrive_time_out_of_range, { "frame.time_invalid", PI_SEQUENCE, PI_NOTE, "Arrival Time: Fractional second out of range (0-1000000000)", EXPFILL }},
|
{ &ei_arrive_time_out_of_range, { "frame.time_invalid", PI_SEQUENCE, PI_NOTE, "Arrival Time: Fractional second out of range (0-1000000000)", EXPFILL }},
|
||||||
|
{ &ei_incomplete, { "frame.incomplete", PI_UNDECODED, PI_WARN, "Incomplete dissector", EXPFILL }}
|
||||||
};
|
};
|
||||||
|
|
||||||
module_t *frame_module;
|
module_t *frame_module;
|
||||||
|
|
|
@ -2569,6 +2569,11 @@ prefs_register_modules(void)
|
||||||
"Display all byte fields with a space character between each byte in the packet list.",
|
"Display all byte fields with a space character between each byte in the packet list.",
|
||||||
&prefs.display_byte_fields_with_spaces);
|
&prefs.display_byte_fields_with_spaces);
|
||||||
|
|
||||||
|
prefs_register_bool_preference(protocols_module, "enable_incomplete_dissectors_check",
|
||||||
|
"Look for incomplete dissectors",
|
||||||
|
"Look for dissectors that left some bytes undecoded.",
|
||||||
|
&prefs.enable_incomplete_dissectors_check);
|
||||||
|
|
||||||
/* Obsolete preferences
|
/* Obsolete preferences
|
||||||
* These "modules" were reorganized/renamed to correspond to their GUI
|
* These "modules" were reorganized/renamed to correspond to their GUI
|
||||||
* configuration screen within the preferences dialog
|
* configuration screen within the preferences dialog
|
||||||
|
|
|
@ -204,6 +204,7 @@ typedef struct _e_prefs {
|
||||||
guint tap_update_interval;
|
guint tap_update_interval;
|
||||||
gboolean display_hidden_proto_items;
|
gboolean display_hidden_proto_items;
|
||||||
gboolean display_byte_fields_with_spaces;
|
gboolean display_byte_fields_with_spaces;
|
||||||
|
gboolean enable_incomplete_dissectors_check;
|
||||||
gpointer filter_expressions;/* Actually points to &head */
|
gpointer filter_expressions;/* Actually points to &head */
|
||||||
gboolean gui_update_enabled;
|
gboolean gui_update_enabled;
|
||||||
software_update_channel_e gui_update_channel;
|
software_update_channel_e gui_update_channel;
|
||||||
|
|
30
epan/proto.c
30
epan/proto.c
|
@ -6966,6 +6966,36 @@ proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
|
||||||
return offsearch.finfo;
|
return offsearch.finfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
check_for_undecoded(proto_node *node, const gpointer data)
|
||||||
|
{
|
||||||
|
field_info *fi = PNODE_FINFO(node);
|
||||||
|
gchar* decoded = (gchar*)data;
|
||||||
|
gint i;
|
||||||
|
guint byte;
|
||||||
|
guint bit;
|
||||||
|
|
||||||
|
if (fi && fi->hfinfo->type != FT_PROTOCOL) {
|
||||||
|
for (i = fi->start; i < fi->start + fi->length; i++) {
|
||||||
|
byte = i / 8;
|
||||||
|
bit = i % 8;
|
||||||
|
decoded[byte] |= (1 << bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar*
|
||||||
|
proto_find_undecoded_data(proto_tree *tree, guint length)
|
||||||
|
{
|
||||||
|
gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
|
||||||
|
|
||||||
|
proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dumps the protocols in the registration database to stdout. An independent
|
/* Dumps the protocols in the registration database to stdout. An independent
|
||||||
* program can take this output and format it into nice tables or HTML or
|
* program can take this output and format it into nice tables or HTML or
|
||||||
* whatever.
|
* whatever.
|
||||||
|
|
|
@ -2235,6 +2235,14 @@ proto_construct_match_selected_string(field_info *finfo, struct epan_dissect *ed
|
||||||
WS_DLL_PUBLIC field_info*
|
WS_DLL_PUBLIC field_info*
|
||||||
proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb);
|
proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb);
|
||||||
|
|
||||||
|
/** Find undecoded bytes in a tree
|
||||||
|
@param tree tree of interest
|
||||||
|
@param offset offset in the tvb
|
||||||
|
@param length the length of the frame
|
||||||
|
@return an array to be used as bitmap of decoded bytes */
|
||||||
|
WS_DLL_PUBLIC gchar*
|
||||||
|
proto_find_undecoded_data(proto_tree *tree, guint length);
|
||||||
|
|
||||||
/** This function will dissect a sequence of bytes that describe a bitmask.
|
/** This function will dissect a sequence of bytes that describe a bitmask.
|
||||||
@param tree the tree to append this item to
|
@param tree the tree to append this item to
|
||||||
@param tvb the tv buffer of the current data
|
@param tvb the tv buffer of the current data
|
||||||
|
|
Loading…
Reference in New Issue