aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-icmpv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-icmpv6.c')
-rw-r--r--epan/dissectors/packet-icmpv6.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/epan/dissectors/packet-icmpv6.c b/epan/dissectors/packet-icmpv6.c
index 642b7edf39..3d830c7248 100644
--- a/epan/dissectors/packet-icmpv6.c
+++ b/epan/dissectors/packet-icmpv6.c
@@ -97,7 +97,7 @@ static int proto_icmpv6 = -1;
static int hf_icmpv6_type = -1;
static int hf_icmpv6_code = -1;
static int hf_icmpv6_checksum = -1;
-static int hf_icmpv6_checksum_bad = -1;
+static int hf_icmpv6_checksum_status = -1;
static int hf_icmpv6_reserved = -1;
static int hf_icmpv6_data = -1;
static int hf_icmpv6_unknown_data = -1;
@@ -3470,12 +3470,12 @@ static int
dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_tree *icmp6_tree = NULL, *flag_tree = NULL;
- proto_item *ti = NULL, *hidden_item, *checksum_item = NULL, *code_item = NULL, *ti_flag = NULL;
+ proto_item *ti = NULL, *checksum_item = NULL, *code_item = NULL, *ti_flag = NULL;
const char *code_name = NULL;
guint length = 0, reported_length;
vec_t cksum_vec[4];
guint32 phdr[2];
- guint16 cksum, computed_cksum;
+ guint16 cksum;
int offset;
tvbuff_t *next_tvb;
guint8 icmp6_type, icmp6_code;
@@ -3540,46 +3540,32 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
col_set_str(pinfo->cinfo, COL_INFO, "Direct IPv6 Connectivity Test");
}
- if (tree) {
- if (code_name)
- proto_item_append_text(code_item, " (%s)", code_name);
- checksum_item = proto_tree_add_item(icmp6_tree, hf_icmpv6_checksum, tvb, offset, 2, ENC_BIG_ENDIAN);
- }
+ if (code_name)
+ proto_item_append_text(code_item, " (%s)", code_name);
cksum = tvb_get_ntohs(tvb, offset);
-
- if (1) { /* There's an expert info in here so always execute */
- length = tvb_captured_length(tvb);
- reported_length = tvb_reported_length(tvb);
- if (!pinfo->fragmented && length >= reported_length && !pinfo->flags.in_error_pkt) {
- /* The packet isn't part of a fragmented datagram, isn't truncated,
- * and we aren't in an ICMP error packet, so we can checksum it.
- */
-
- /* Set up the fields of the pseudo-header. */
- SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len);
- SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len);
- phdr[0] = g_htonl(reported_length);
- phdr[1] = g_htonl(IP_PROTO_ICMPV6);
- SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 8);
- SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, reported_length);
- computed_cksum = in_cksum(cksum_vec, 4);
-
- if (computed_cksum == 0) {
- hidden_item = proto_tree_add_boolean(icmp6_tree, hf_icmpv6_checksum_bad, tvb, offset, 2, FALSE);
- PROTO_ITEM_SET_HIDDEN(hidden_item);
- proto_item_append_text(checksum_item, " [correct]");
- } else {
- hidden_item = proto_tree_add_boolean(icmp6_tree, hf_icmpv6_checksum_bad, tvb, offset, 2, TRUE);
- PROTO_ITEM_SET_HIDDEN(hidden_item);
- proto_item_append_text(checksum_item, " [incorrect, should be 0x%04x]", in_cksum_shouldbe(cksum, computed_cksum));
- expert_add_info_format(pinfo, checksum_item, &ei_icmpv6_checksum,
- "ICMPv6 Checksum Incorrect, should be 0x%04x", in_cksum_shouldbe(cksum, computed_cksum));
- }
- } else {
- proto_item_append_text(checksum_item, " [%s]",
- pinfo->flags.in_error_pkt ? "in ICMP error packet" : "fragmented datagram");
- }
+ length = tvb_captured_length(tvb);
+ reported_length = tvb_reported_length(tvb);
+ if (!pinfo->fragmented && length >= reported_length && !pinfo->flags.in_error_pkt) {
+ /* The packet isn't part of a fragmented datagram, isn't truncated,
+ * and we aren't in an ICMP error packet, so we can checksum it.
+ */
+
+ /* Set up the fields of the pseudo-header. */
+ SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len);
+ SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len);
+ phdr[0] = g_htonl(reported_length);
+ phdr[1] = g_htonl(IP_PROTO_ICMPV6);
+ SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 8);
+ SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, reported_length);
+
+ proto_tree_add_checksum(icmp6_tree, tvb, 2, hf_icmpv6_checksum, hf_icmpv6_checksum_status, &ei_icmpv6_checksum, pinfo, in_cksum(cksum_vec, 4),
+ ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM);
+ } else {
+ checksum_item = proto_tree_add_checksum(icmp6_tree, tvb, 2, hf_icmpv6_checksum, hf_icmpv6_checksum_status, &ei_icmpv6_checksum, pinfo, 0,
+ ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
+ proto_item_append_text(checksum_item, " [%s]",
+ pinfo->flags.in_error_pkt ? "in ICMP error packet" : "fragmented datagram");
}
offset += 2;
@@ -3612,8 +3598,7 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
* Shouldn't the nonce be at least 8 then? Why not just use (-1),
* as it could really be any length, couldn't it?
*/
- if (tree)
- proto_tree_add_item(icmp6_tree, hf_icmpv6_nonce, tvb, offset, 4, ENC_NA);
+ proto_tree_add_item(icmp6_tree, hf_icmpv6_nonce, tvb, offset, 4, ENC_NA);
offset += 4;
} else {
if (!pinfo->flags.in_error_pkt) {
@@ -4158,8 +4143,8 @@ proto_register_icmpv6(void)
{ &hf_icmpv6_checksum,
{ "Checksum", "icmpv6.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
"Used to detect data corruption in the ICMPv6 message and parts of the IPv6 header", HFILL }},
- { &hf_icmpv6_checksum_bad,
- { "Bad Checksum", "icmpv6.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ { &hf_icmpv6_checksum_status,
+ { "Checksum Status", "icmpv6.checksum.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
NULL, HFILL }},
{ &hf_icmpv6_reserved,
{ "Reserved", "icmpv6.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,