aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorJoão Valverde <joao.valverde@tecnico.ulisboa.pt>2016-04-30 21:19:24 +0100
committerJoão Valverde <j@v6e.pt>2016-05-01 23:19:18 +0000
commit85d57b53e88cc1193c9259e13c531746b6f56c0e (patch)
tree27aa9bd5a7b353b6cce9c81e397554cb8f772b5f /epan
parent11edc83b98a61e890d7bb01855389d40e984ea82 (diff)
ICMPv6: Observe "Redirected Header" option length
Bug: 12400 Change-Id: Ic4116082b0f6c119172b222aadefab821f1b0971 Reviewed-on: https://code.wireshark.org/review/15205 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: João Valverde <j@v6e.pt>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-icmpv6.c33
1 files changed, 19 insertions, 14 deletions
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) */