diff options
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-frame.c | 29 | ||||
-rw-r--r-- | epan/prefs.c | 5 | ||||
-rw-r--r-- | epan/prefs.h | 1 | ||||
-rw-r--r-- | epan/proto.c | 30 | ||||
-rw-r--r-- | epan/proto.h | 8 |
5 files changed, 73 insertions, 0 deletions
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c index 0ac617a089..52a1384b08 100644 --- a/epan/dissectors/packet-frame.c +++ b/epan/dissectors/packet-frame.c @@ -40,6 +40,7 @@ #include <wsutil/md5.h> #include "packet-frame.h" +#include "log.h" #include "color.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_arrive_time_out_of_range = EI_INIT; +static expert_field ei_incomplete = EI_INIT; 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; } + 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); } @@ -819,6 +847,7 @@ proto_register_frame(void) static ei_register_info ei[] = { { &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_incomplete, { "frame.incomplete", PI_UNDECODED, PI_WARN, "Incomplete dissector", EXPFILL }} }; module_t *frame_module; diff --git a/epan/prefs.c b/epan/prefs.c index 415f3e57cb..43c3d6948c 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -2569,6 +2569,11 @@ prefs_register_modules(void) "Display all byte fields with a space character between each byte in the packet list.", &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 * These "modules" were reorganized/renamed to correspond to their GUI * configuration screen within the preferences dialog diff --git a/epan/prefs.h b/epan/prefs.h index 8e77a782c2..a91864b1f2 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -204,6 +204,7 @@ typedef struct _e_prefs { guint tap_update_interval; gboolean display_hidden_proto_items; gboolean display_byte_fields_with_spaces; + gboolean enable_incomplete_dissectors_check; gpointer filter_expressions;/* Actually points to &head */ gboolean gui_update_enabled; software_update_channel_e gui_update_channel; diff --git a/epan/proto.c b/epan/proto.c index 7b44e9004b..cbb6274f91 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -6966,6 +6966,36 @@ proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb) 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 * program can take this output and format it into nice tables or HTML or * whatever. diff --git a/epan/proto.h b/epan/proto.h index af9b7e9120..7436c3099a 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -2235,6 +2235,14 @@ proto_construct_match_selected_string(field_info *finfo, struct epan_dissect *ed WS_DLL_PUBLIC field_info* 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. @param tree the tree to append this item to @param tvb the tv buffer of the current data |