diff options
author | Michael Mann <mmann78@netscape.net> | 2016-07-10 23:47:28 -0400 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2016-07-21 12:35:22 +0000 |
commit | ad6fc87d64de30cdcdca18168a117d2ec24591da (patch) | |
tree | b5df109654ae6806db7544933f8bf1a848a02ae7 /epan/proto.c | |
parent | 1e19f55f0c44b850bc6304be28d5b272a3553204 (diff) |
Add proto_tree_add_checksum.
This is an attempt to standardize display/handling of checksum fields for all dissectors.
The main target is for dissectors that do validation, but dissectors that just report the
checksum were also included just to make them easier to find in the future.
Bug: 10620
Bug: 12058
Ping-Bug: 8859
Change-Id: Ia8abd86e42eaf8ed50de6b173409e914b17993bf
Reviewed-on: https://code.wireshark.org/review/16380
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Jeff Morriss <jeff.morriss.ws@gmail.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/proto.c')
-rw-r--r-- | epan/proto.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/epan/proto.c b/epan/proto.c index 268e443221..5298ba4c16 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -53,6 +53,7 @@ #include "osi-utils.h" #include "expert.h" #include "show_exception.h" +#include "in_cksum.h" #include <wsutil/plugins.h> @@ -10012,6 +10013,133 @@ proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *t return pi; } +const value_string proto_checksum_vals[] = { + { PROTO_CHECKSUM_E_BAD, "Bad" }, + { PROTO_CHECKSUM_E_GOOD, "Good" }, + { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" }, + { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" }, + + { 0, NULL } +}; + +proto_item * +proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset, + const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert, + packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags) +{ + header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum); + guint32 checksum; + guint32 len; + proto_item* ti = NULL; + proto_item* ti2; + gboolean incorrect_checksum = TRUE; + + DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!"); + + if (flags & PROTO_CHECKSUM_NOT_PRESENT) { + ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, 0, 0, "[missing]"); + PROTO_ITEM_SET_GENERATED(ti); + if (hf_checksum_status != -1) { + ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_NOT_PRESENT); + PROTO_ITEM_SET_GENERATED(ti2); + } + return ti; + } + + switch (hfinfo->type){ + case FT_UINT8: + len = 1; + break; + case FT_UINT16: + len = 2; + break; + case FT_UINT24: + len = 3; + break; + case FT_UINT32: + len = 4; + break; + default: + DISSECTOR_ASSERT_NOT_REACHED(); + } + + if (flags & PROTO_CHECKSUM_GENERATED) { + ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, 0, computed_checksum); + PROTO_ITEM_SET_GENERATED(ti); + } else { + ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum); + if (flags & PROTO_CHECKSUM_VERIFY) { + if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) { + if (computed_checksum == 0) { + proto_item_append_text(ti, " [correct]"); + if (hf_checksum_status != -1) { + ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD); + PROTO_ITEM_SET_GENERATED(ti2); + } + incorrect_checksum = FALSE; + } else if (flags & PROTO_CHECKSUM_IN_CKSUM) { + computed_checksum = in_cksum_shouldbe(checksum, computed_checksum); + } + } else { + if (checksum == computed_checksum) { + proto_item_append_text(ti, " [correct]"); + if (hf_checksum_status != -1) { + ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD); + PROTO_ITEM_SET_GENERATED(ti2); + } + incorrect_checksum = FALSE; + } + } + + if (incorrect_checksum) { + if (hf_checksum_status != -1) { + ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD); + PROTO_ITEM_SET_GENERATED(ti2); + } + if (flags & PROTO_CHECKSUM_ZERO) { + proto_item_append_text(ti, " [incorrect]"); + if (bad_checksum_expert != NULL) + expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum"); + } else { + switch(hfinfo->type) + { + case FT_UINT8: + proto_item_append_text(ti, " [incorrect, should be 0x%02x]", computed_checksum); + if (bad_checksum_expert != NULL) + expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%02x]", computed_checksum); + break; + case FT_UINT16: + proto_item_append_text(ti, " [incorrect, should be 0x%04x]", computed_checksum); + if (bad_checksum_expert != NULL) + expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%04x]", computed_checksum); + break; + case FT_UINT24: + proto_item_append_text(ti, " [incorrect, should be 0x%06x]", computed_checksum); + if (bad_checksum_expert != NULL) + expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%06x]", computed_checksum); + break; + case FT_UINT32: + proto_item_append_text(ti, " [incorrect, should be 0x%08x]", computed_checksum); + if (bad_checksum_expert != NULL) + expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%08x]", computed_checksum); + break; + default: + DISSECTOR_ASSERT_NOT_REACHED(); + } + } + } + } else { + if (hf_checksum_status != -1) { + proto_item_append_text(ti, " [unverified]"); + ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED); + PROTO_ITEM_SET_GENERATED(ti2); + } + } + } + + return ti; +} + guchar proto_check_field_name(const gchar *field_name) { |