From 85d57b53e88cc1193c9259e13c531746b6f56c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Sat, 30 Apr 2016 21:19:24 +0100 Subject: ICMPv6: Observe "Redirected Header" option length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: 12400 Change-Id: Ic4116082b0f6c119172b222aadefab821f1b0971 Reviewed-on: https://code.wireshark.org/review/15205 Reviewed-by: Michael Mann Petri-Dish: Michael Mann Tested-by: Petri Dish Buildbot Reviewed-by: João Valverde --- epan/dissectors/packet-icmpv6.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'epan/dissectors/packet-icmpv6.c') diff --git a/epan/dissectors/packet-icmpv6.c b/epan/dissectors/packet-icmpv6.c index 5d623e5385..1a7dc1e115 100644 --- a/epan/dissectors/packet-icmpv6.c +++ b/epan/dissectors/packet-icmpv6.c @@ -1165,10 +1165,10 @@ static const value_string rpl_option_vals[] = { #define ND_OPT_6CIO_FLAG_UNASSIGNED 0xFFFE static int -dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +dissect_contained_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gboolean save_in_error_pkt; - tvbuff_t *next_tvb; + gint offset; /* Save the current value of the "we're inside an error packet" flag, and set that flag; subdissectors may treat packets @@ -1177,14 +1177,13 @@ dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tr save_in_error_pkt = pinfo->flags.in_error_pkt; pinfo->flags.in_error_pkt = TRUE; - next_tvb = tvb_new_subset_remaining(tvb, offset); - /* tiny sanity check */ - if ((tvb_get_guint8(tvb, offset) & 0xf0) == 0x60) { + if ((tvb_get_guint8(tvb, 0) & 0xf0) == 0x60) { /* The contained packet is an IPv6 datagram; dissect it. */ - offset += call_dissector(ipv6_handle, next_tvb, pinfo, tree); - } else - offset += call_data_dissector(next_tvb, pinfo, tree); + offset = call_dissector(ipv6_handle, tvb, pinfo, tree); + } else { + offset = call_data_dissector(tvb, pinfo, tree); + } /* Restore the "we're inside an error packet" flag. */ pinfo->flags.in_error_pkt = save_in_error_pkt; @@ -1392,6 +1391,7 @@ dissect_icmpv6_nd_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree guint8 opt_type; int opt_len; int opt_offset; + tvbuff_t *opt_tvb; while ((int)tvb_reported_length(tvb) > offset) { /* there are more options */ @@ -1553,9 +1553,11 @@ dissect_icmpv6_nd_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, ENC_NA); opt_offset += 6; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_redirected_packet, tvb, opt_offset, -1, ENC_NA); - - opt_offset = dissect_contained_icmpv6(tvb, opt_offset, pinfo, icmp6opt_tree); + if (opt_len > 8) { + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_redirected_packet, tvb, opt_offset, opt_len - 8, ENC_NA); + opt_tvb = tvb_new_subset_length(tvb, opt_offset, opt_len - 8); + opt_offset += dissect_contained_icmpv6(opt_tvb, pinfo, icmp6opt_tree); + } break; case ND_OPT_MTU: /* MTU (5) */ @@ -3648,21 +3650,24 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, ENC_NA); offset += 4; - offset = dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree); + next_tvb = tvb_new_subset_remaining(tvb, offset); + offset += dissect_contained_icmpv6(next_tvb, pinfo, icmp6_tree); break; case ICMP6_PACKET_TOO_BIG: /* Packet Too Big (2) */ /* MTU */ proto_tree_add_item(icmp6_tree, hf_icmpv6_mtu, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; - offset = dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree); + next_tvb = tvb_new_subset_remaining(tvb, offset); + offset += dissect_contained_icmpv6(next_tvb, pinfo, icmp6_tree); break; case ICMP6_PARAM_PROB: /* Parameter Problem (4) */ /* MTU */ proto_tree_add_item(icmp6_tree, hf_icmpv6_pointer, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; - offset = dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree); + next_tvb = tvb_new_subset_remaining(tvb, offset); + offset += dissect_contained_icmpv6(next_tvb, pinfo, icmp6_tree); break; case ICMP6_ECHO_REQUEST: /* Echo Request (128) */ case ICMP6_ECHO_REPLY: /* Echo Reply (129) */ -- cgit v1.2.3