diff options
author | jake <jake@f5534014-38df-0310-8fa8-9805f1628bb7> | 2011-01-04 07:44:39 +0000 |
---|---|---|
committer | jake <jake@f5534014-38df-0310-8fa8-9805f1628bb7> | 2011-01-04 07:44:39 +0000 |
commit | e17b17e98843886bb3e37fa807bdf1f1f921ccdb (patch) | |
tree | 6dcbd33706a66be7217b684fd1436ed3b0cb27f3 /epan/dissectors/packet-icmpv6.c | |
parent | 68933e3d0bb607960995123def4479ab6ac52f4d (diff) |
From Alexis La Goutte:
A Patch to enchance the ICMPv6 Router Renumbering for IPv6 (RFC 2894) Dissector
- Make RR field filterable
- Add RR Result Message
- ...
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@35355 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-icmpv6.c')
-rw-r--r-- | epan/dissectors/packet-icmpv6.c | 611 |
1 files changed, 419 insertions, 192 deletions
diff --git a/epan/dissectors/packet-icmpv6.c b/epan/dissectors/packet-icmpv6.c index e8dba868be..5138d5e37a 100644 --- a/epan/dissectors/packet-icmpv6.c +++ b/epan/dissectors/packet-icmpv6.c @@ -59,32 +59,23 @@ #endif /* - * See, under http://www.ietf.org/internet-drafts/ - * - * draft-ietf-mobileip-ipv6-15.txt - * - * and - * - * rfc4620.txt - * - * and - * - * draft-ietf-mobileip-hmipv6-05.txt - * - * and - * - * draft-ieft-roll-rpl-12.txt - * - * and - * - * rfc4068.txt + * The information used comes from: + * RFC 2461: Neighbor Discovery for IP Version 6 (IPv6) + * RFC 2894: Router Renumbering for IPv6 + * RFC 4068: Fast Handovers for Mobile IPv6 + * RFC 4620: IPv6 Node Information Queries + * RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + * draft-ietf-mobileip-hmipv6-05.txt + * draft-ieft-roll-rpl-12.txt */ + 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_reserved = -1; static int hf_icmpv6_nor = -1; static int hf_icmpv6_haad_ha_addrs = -1; static int hf_icmpv6_ra_cur_hop_limit = -1; @@ -295,6 +286,52 @@ static int hf_icmpv6_ni_reply_node_name = -1; static int hf_icmpv6_ni_reply_node_address = -1; static int hf_icmpv6_ni_reply_ipv4_address = -1; +static int hf_icmpv6_rr_sequencenumber = -1; +static int hf_icmpv6_rr_segmentnumber = -1; +static int hf_icmpv6_rr_flag = -1; +static int hf_icmpv6_rr_flag_t = -1; +static int hf_icmpv6_rr_flag_r = -1; +static int hf_icmpv6_rr_flag_a = -1; +static int hf_icmpv6_rr_flag_s = -1; +static int hf_icmpv6_rr_flag_p = -1; +static int hf_icmpv6_rr_flag_rsv = -1; +static int hf_icmpv6_rr_maxdelay = -1; +static int hf_icmpv6_rr_pco_mp_part = -1; +static int hf_icmpv6_rr_pco_mp_opcode = -1; +static int hf_icmpv6_rr_pco_mp_oplength = -1; +static int hf_icmpv6_rr_pco_mp_ordinal = -1; +static int hf_icmpv6_rr_pco_mp_matchlen = -1; +static int hf_icmpv6_rr_pco_mp_minlen = -1; +static int hf_icmpv6_rr_pco_mp_maxlen = -1; +static int hf_icmpv6_rr_pco_mp_matchprefix = -1; +static int hf_icmpv6_rr_pco_up_part = -1; +static int hf_icmpv6_rr_pco_up_uselen = -1; +static int hf_icmpv6_rr_pco_up_keeplen = -1; +static int hf_icmpv6_rr_pco_up_flagmask = -1; +static int hf_icmpv6_rr_pco_up_flagmask_l = -1; +static int hf_icmpv6_rr_pco_up_flagmask_a = -1; +static int hf_icmpv6_rr_pco_up_flagmask_reserved = -1; +static int hf_icmpv6_rr_pco_up_raflags = -1; +static int hf_icmpv6_rr_pco_up_raflags_l = -1; +static int hf_icmpv6_rr_pco_up_raflags_a = -1; +static int hf_icmpv6_rr_pco_up_raflags_reserved = -1; +static int hf_icmpv6_rr_pco_up_validlifetime = -1; +static int hf_icmpv6_rr_pco_up_preferredlifetime = -1; +static int hf_icmpv6_rr_pco_up_flag = -1; +static int hf_icmpv6_rr_pco_up_flag_v = -1; +static int hf_icmpv6_rr_pco_up_flag_p = -1; +static int hf_icmpv6_rr_pco_up_flag_reserved = -1; +static int hf_icmpv6_rr_pco_up_useprefix = -1; +static int hf_icmpv6_rr_rm = -1; +static int hf_icmpv6_rr_rm_flag = -1; +static int hf_icmpv6_rr_rm_flag_b = -1; +static int hf_icmpv6_rr_rm_flag_f = -1; +static int hf_icmpv6_rr_rm_flag_reserved = -1; +static int hf_icmpv6_rr_rm_ordinal = -1; +static int hf_icmpv6_rr_rm_matchedlen = -1; +static int hf_icmpv6_rr_rm_interfaceindex = -1; +static int hf_icmpv6_rr_rm_matchedprefix = -1; + static gint ett_icmpv6 = -1; static gint ett_icmpv6opt = -1; static gint ett_icmpv6flag = -1; @@ -410,11 +447,22 @@ static const true_false_string tfs_ni_flag_a = { "Unicast addresses on the queried interface" }; -static const value_string names_rrenum_matchcode[] = { - { RPM_PCO_ADD, "Add" }, - { RPM_PCO_CHANGE, "Change" }, - { RPM_PCO_SETGLOBAL, "Set Global" }, - { 0, NULL } +/* + RFC2894 - Router Renumbering for IPv6 +*/ + +#define RR_FLAG_T 0x80 +#define RR_FLAG_R 0x40 +#define RR_FLAG_A 0x20 +#define RR_FLAG_S 0x10 +#define RR_FLAG_P 0x08 +#define RR_FLAG_RSV 0x07 + +static const value_string rr_pco_mp_opcode_val[] = { + { 1, "Add" }, + { 2, "Change" }, + { 3, "Set Global" }, + { 0, NULL } }; static const value_string names_router_pref[] = { @@ -1867,7 +1915,7 @@ dissect_icmpv6_rpl_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree } /* - * RFC 4620 : IPv6 Node Information Queries + * RFC 4620 - IPv6 Node Information Queries */ static void @@ -1976,175 +2024,212 @@ dissect_nodeinfo(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree * } } } - -#define RR_SIZE 16 -#define RR_SEQNUM_SIZE 4 -#define RR_SEQNUM_OFFSET 4 -#define RR_SEGNUM_SIZE 1 -#define RR_SEGNUM_OFFSET 8 -#define RR_FLAGS_SIZE 1 -#define RR_FLAGS_OFFSET 9 +/* + * RFC 2894 - Router Renumbering for IPv6 +*/ static void -dissect_rrenum(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +dissect_rrenum(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint8 icmp6_type _U_, guint8 icmp6_code) { - proto_tree *field_tree, *opt_tree; - proto_item *tf; - struct icmp6_router_renum icmp6_router_renum, *rr; - struct rr_pco_match rr_pco_match, *match; - struct rr_pco_use rr_pco_use, *use; - int flagoff, off; - unsigned int l; - guint8 flags; - - rr = &icmp6_router_renum; - tvb_memcpy(tvb, (guint8 *)rr, offset, sizeof *rr); - proto_tree_add_text(tree, tvb, - offset + RR_SEQNUM_OFFSET, RR_SEQNUM_SIZE, - "Sequence number: 0x%08x", pntohl(&rr->rr_seqnum)); - proto_tree_add_text(tree, tvb, - offset + RR_SEGNUM_OFFSET, RR_SEGNUM_SIZE, - "Segment number: 0x%02x", rr->rr_segnum); - - flagoff = offset + RR_FLAGS_OFFSET; - flags = tvb_get_guint8(tvb, flagoff); - tf = proto_tree_add_text(tree, tvb, flagoff, RR_FLAGS_SIZE, - "Flags: 0x%02x", flags); - field_tree = proto_item_add_subtree(tf, ett_icmpv6flag); - proto_tree_add_text(field_tree, tvb, flagoff, RR_FLAGS_SIZE, "%s", - decode_boolean_bitfield(flags, 0x80, 8, - "Test command", "Not test command")); - proto_tree_add_text(field_tree, tvb, flagoff, RR_FLAGS_SIZE, "%s", - decode_boolean_bitfield(flags, 0x40, 8, - "Result requested", "Result not requested")); - proto_tree_add_text(field_tree, tvb, flagoff, RR_FLAGS_SIZE, "%s", - decode_boolean_bitfield(flags, 0x20, 8, - "All interfaces", "Not all interfaces")); - proto_tree_add_text(field_tree, tvb, flagoff, RR_FLAGS_SIZE, "%s", - decode_boolean_bitfield(flags, 0x10, 8, - "Site specific", "Not site specific")); - proto_tree_add_text(field_tree, tvb, flagoff, RR_FLAGS_SIZE, "%s", - decode_boolean_bitfield(flags, 0x08, 8, - "Processed previously", "Complete result")); - - proto_tree_add_text(tree, tvb, - offset + offsetof(struct icmp6_router_renum, rr_maxdelay), 2, - "Max delay: 0x%04x", pntohs(&rr->rr_maxdelay)); - call_dissector(data_handle,tvb_new_subset_remaining(tvb, offset + RR_SIZE), pinfo, tree); /*XXX*/ - - if (rr->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) { - off = offset + RR_SIZE; - match = &rr_pco_match; - tvb_memcpy(tvb, (guint8 *)match, off, sizeof *match); - tf = proto_tree_add_text(tree, tvb, off, sizeof(*match), - "Match-Prefix: %s/%u (%u-%u)", ip6_to_str(&match->rpm_prefix), - match->rpm_matchlen, match->rpm_minlen, match->rpm_maxlen); - opt_tree = proto_item_add_subtree(tf, ett_icmpv6opt); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_match, rpm_code), - sizeof(match->rpm_code), "OpCode: %s (%u)", - val_to_str(match->rpm_code, names_rrenum_matchcode, "Unknown"), - match->rpm_code); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_match, rpm_len), - sizeof(match->rpm_len), "OpLength: %u (%u octets)", - match->rpm_len, match->rpm_len * 8); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_match, rpm_ordinal), - sizeof(match->rpm_ordinal), "Ordinal: %u", match->rpm_ordinal); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_match, rpm_matchlen), - sizeof(match->rpm_matchlen), "MatchLen: %u", match->rpm_matchlen); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_match, rpm_minlen), - sizeof(match->rpm_minlen), "MinLen: %u", match->rpm_minlen); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_match, rpm_maxlen), - sizeof(match->rpm_maxlen), "MaxLen: %u", match->rpm_maxlen); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_match, rpm_prefix), - sizeof(match->rpm_prefix), "MatchPrefix: %s", - ip6_to_str(&match->rpm_prefix)); - - off += sizeof(*match); - use = &rr_pco_use; - for (l = match->rpm_len * 8 - sizeof(*match); - l >= sizeof(*use); l -= sizeof(*use), off += sizeof(*use)) { - tvb_memcpy(tvb, (guint8 *)use, off, sizeof *use); - tf = proto_tree_add_text(tree, tvb, off, sizeof(*use), - "Use-Prefix: %s/%u (keep %u)", ip6_to_str(&use->rpu_prefix), - use->rpu_uselen, use->rpu_keeplen); - opt_tree = proto_item_add_subtree(tf, ett_icmpv6opt); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_use, rpu_uselen), - sizeof(use->rpu_uselen), "UseLen: %u", use->rpu_uselen); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_use, rpu_keeplen), - sizeof(use->rpu_keeplen), "KeepLen: %u", use->rpu_keeplen); - tf = proto_tree_add_text(opt_tree, tvb, - flagoff = off + offsetof(struct rr_pco_use, rpu_ramask), - sizeof(use->rpu_ramask), "FlagMask: 0x%x", use->rpu_ramask); - field_tree = proto_item_add_subtree(tf, ett_icmpv6flag); - flags = tvb_get_guint8(tvb, flagoff); - proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", - decode_boolean_bitfield(flags, - ICMP6_RR_PCOUSE_RAFLAGS_ONLINK, 8, - "Onlink", "Not onlink")); - proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", - decode_boolean_bitfield(flags, - ICMP6_RR_PCOUSE_RAFLAGS_AUTO, 8, - "Auto", "Not auto")); - tf = proto_tree_add_text(opt_tree, tvb, - flagoff = off + offsetof(struct rr_pco_use, rpu_raflags), - sizeof(use->rpu_raflags), "RAFlags: 0x%x", use->rpu_raflags); - field_tree = proto_item_add_subtree(tf, ett_icmpv6flag); - flags = tvb_get_guint8(tvb, flagoff); - proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", - decode_boolean_bitfield(flags, - ICMP6_RR_PCOUSE_RAFLAGS_ONLINK, 8, - "Onlink", "Not onlink")); - proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", - decode_boolean_bitfield(flags, - ICMP6_RR_PCOUSE_RAFLAGS_AUTO, 8, "Auto", "Not auto")); - if (pntohl(&use->rpu_vltime) == 0xffffffff) - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_use, rpu_vltime), - sizeof(use->rpu_vltime), "Valid Lifetime: infinity"); - else - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_use, rpu_vltime), - sizeof(use->rpu_vltime), "Valid Lifetime: %u", - pntohl(&use->rpu_vltime)); - if (pntohl(&use->rpu_pltime) == 0xffffffff) - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_use, rpu_pltime), - sizeof(use->rpu_pltime), "Preferred Lifetime: infinity"); - else - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_use, rpu_pltime), - sizeof(use->rpu_pltime), "Preferred Lifetime: %u", - pntohl(&use->rpu_pltime)); - tf = proto_tree_add_text(opt_tree, tvb, - flagoff = off + offsetof(struct rr_pco_use, rpu_flags), - sizeof(use->rpu_flags), "Flags: 0x%08x", - pntohl(&use->rpu_flags)); - field_tree = proto_item_add_subtree(tf, ett_icmpv6flag); - flags = tvb_get_guint8(tvb, flagoff); - proto_tree_add_text(field_tree, tvb, flagoff, 4, "%s", - decode_boolean_bitfield(flags, - ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, 32, - "Decrement valid lifetime", "No decrement valid lifetime")); - proto_tree_add_text(field_tree, tvb, flagoff, 4, "%s", - decode_boolean_bitfield(flags, - ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, 32, - "Decrement preferred lifetime", - "No decrement preferred lifetime")); - proto_tree_add_text(opt_tree, tvb, - off + offsetof(struct rr_pco_use, rpu_prefix), - sizeof(use->rpu_prefix), "UsePrefix: %s", - ip6_to_str(&use->rpu_prefix)); - } + proto_tree *flag_tree, *mp_tree, *up_tree, *rm_tree; + proto_item *ti, *ti_mp, *ti_up, *ti_rm; + int rr_offset = offset + 4; + + /* Sequence Number */ + proto_tree_add_item(tree, hf_icmpv6_rr_sequencenumber, tvb, rr_offset, 4, FALSE); + rr_offset += 4; + + /* Segment Number */ + proto_tree_add_item(tree, hf_icmpv6_rr_segmentnumber, tvb, rr_offset, 1, FALSE); + rr_offset += 1; + + /* Flags */ + ti = proto_tree_add_item(tree, hf_icmpv6_rr_flag, tvb, rr_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_t, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_r, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_a, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_s, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_p, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_rsv, tvb, rr_offset, 1, FALSE); + rr_offset += 1; + + /* Max Delay */ + proto_tree_add_item(tree, hf_icmpv6_rr_maxdelay, tvb, rr_offset, 2, FALSE); + rr_offset += 2; + + /* Reserved */ + proto_tree_add_item(tree, hf_icmpv6_reserved, tvb, rr_offset, 4, FALSE); + rr_offset += 4; + /* Data ? */ + if(tvb_reported_length_remaining(tvb, rr_offset) == 0){ + return; } + + if(icmp6_code == ICMP6_ROUTER_RENUMBERING_COMMAND){ + /* Match-Prefix Part */ + guint8 opcode, oplength, matchlen, minlen, maxlen; + struct e_in6_addr matchprefix; + + ti_mp = proto_tree_add_item(tree, hf_icmpv6_rr_pco_mp_part, tvb, rr_offset, 24, FALSE); + mp_tree = proto_item_add_subtree(ti_mp, ett_icmpv6opt); + + /* OpCode */ + proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_opcode, tvb, rr_offset, 1, FALSE); + opcode = tvb_get_guint8(tvb, rr_offset); + rr_offset += 1; + + /* OpLength */ + proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_oplength, tvb, rr_offset, 1, FALSE); + oplength = tvb_get_guint8(tvb, rr_offset); + rr_offset += 1; + + /* Ordinal */ + proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_ordinal, tvb, rr_offset, 1, FALSE); + rr_offset += 1; + + /* MatchLen */ + proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchlen, tvb, rr_offset, 1, FALSE); + matchlen = tvb_get_guint8(tvb, rr_offset); + rr_offset += 1; + + /* MinLen */ + proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_minlen, tvb, rr_offset, 1, FALSE); + minlen = tvb_get_guint8(tvb, rr_offset); + rr_offset += 1; + + /* MaxLen */ + proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_maxlen, tvb, rr_offset, 1, FALSE); + maxlen = tvb_get_guint8(tvb, rr_offset); + rr_offset += 1; + + /* Reserved */ + proto_tree_add_item(mp_tree, hf_icmpv6_reserved, tvb, rr_offset, 2, FALSE); + rr_offset += 2; + + /* Match Prefix */ + proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchprefix, tvb, rr_offset, 16, FALSE); + tvb_get_ipv6(tvb, rr_offset, &matchprefix); + rr_offset += 16; + + /* Add Info (Prefix, Length...) to Match Prefix Part label */ + proto_item_append_text(ti_mp, ": %s %s/%u (%u-%u)", val_to_str(opcode, rr_pco_mp_opcode_val, "Unknown %d"), ip6_to_str(&matchprefix), matchlen, minlen, maxlen); + + while ((int)tvb_reported_length(tvb) > rr_offset) { + /* Use-Prefix Part */ + guint8 uselen, keeplen; + struct e_in6_addr useprefix; + + ti_up = proto_tree_add_item(tree, hf_icmpv6_rr_pco_up_part, tvb, rr_offset, 32, FALSE); + up_tree = proto_item_add_subtree(ti_up, ett_icmpv6opt); + + /* UseLen */ + proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_uselen, tvb, rr_offset, 1, FALSE); + uselen = tvb_get_guint8(tvb, rr_offset); + rr_offset += 1; + + /* KeepLen */ + proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_keeplen, tvb, rr_offset, 1, FALSE); + keeplen = tvb_get_guint8(tvb, rr_offset); + rr_offset += 1; + + /* FlagMask */ + ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flagmask, tvb, rr_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_l, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_a, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_reserved, tvb, rr_offset, 1, FALSE); + rr_offset += 1; + + /* RaFlags */ + ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_raflags, tvb, rr_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_l, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_a, tvb, rr_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_reserved, tvb, rr_offset, 1, FALSE); + rr_offset += 1; + + /* Valid Lifetime */ + ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_validlifetime, tvb, rr_offset, 4, FALSE); + switch(tvb_get_ntohl(tvb, rr_offset)){ + case 0xffffffff: + proto_item_append_text(ti, " (Infinity)"); + break; + default: + break; + } + rr_offset += 4; + + /* Preferred Lifetime */ + ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_preferredlifetime, tvb, rr_offset, 4, FALSE); + switch(tvb_get_ntohl(tvb, rr_offset)){ + case 0xffffffff: + proto_item_append_text(ti, " (Infinity)"); + break; + default: + break; + } + rr_offset += 4; + + /* Flags */ + ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flag, tvb, rr_offset, 4, FALSE); + flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_v, tvb, rr_offset, 4, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_p, tvb, rr_offset, 4, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_reserved, tvb, rr_offset, 4, FALSE); + rr_offset += 4; + + /* UsePrefix */ + proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_useprefix, tvb, rr_offset, 16, FALSE); + tvb_get_ipv6(tvb, rr_offset, &useprefix); + rr_offset += 16; + + /* Add Info (Prefix, Length...) to Use Prefix Part label */ + proto_item_append_text(ti_up, ": %s/%u (keep %u)", ip6_to_str(&useprefix), uselen, keeplen); + } + + }else if(icmp6_code == ICMP6_ROUTER_RENUMBERING_RESULT){ + while ((int)tvb_reported_length(tvb) > rr_offset) { + guint8 matchlen; + guint32 interfaceindex; + struct e_in6_addr matchedprefix; + /* Result Message */ + + ti_rm = proto_tree_add_item(tree, hf_icmpv6_rr_rm, tvb, rr_offset, 24, FALSE); + rm_tree = proto_item_add_subtree(ti_rm, ett_icmpv6opt); + + /* Flags */ + ti = proto_tree_add_item(mp_tree, hf_icmpv6_rr_rm_flag, tvb, rr_offset, 2, FALSE); + flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_b, tvb, rr_offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_f, tvb, rr_offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_reserved, tvb, rr_offset, 2, FALSE); + rr_offset +=2; + + /* Ordinal */ + proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_ordinal, tvb, rr_offset, 1, FALSE); + rr_offset +=1; + + /* MatchLen */ + proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedlen, tvb, rr_offset, 1, FALSE); + matchlen = tvb_get_guint8(tvb, rr_offset); + rr_offset +=1; + + /* InterfaceIndex */ + proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_interfaceindex, tvb, rr_offset, 4, FALSE); + interfaceindex = tvb_get_ntohl(tvb, rr_offset); + rr_offset +=4; + + /* MatchedPrefix */ + proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedprefix, tvb, rr_offset, 16, FALSE); + tvb_get_ipv6(tvb, rr_offset, &matchedprefix); + rr_offset +=16; + + /* Add Info (Prefix, Length...) to Use Resultat Message label */ + proto_item_append_text(ti_rm, ": %s/%u (interface %u)", ip6_to_str(&matchedprefix), matchlen, interfaceindex); + } + } + } /* @@ -2268,7 +2353,7 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) break; case ICMP6_ROUTER_RENUMBERING: codename = colcodename = val_to_str (dp->icmp6_code, icmpv6_router_renum_code_str, "Unknown"); - len = sizeof(struct icmp6_router_renum); + len = 16; break; case ICMP6_NI_QUERY: case ICMP6_NI_REPLY: @@ -2723,7 +2808,7 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) break; } case ICMP6_ROUTER_RENUMBERING: - dissect_rrenum(tvb, offset, pinfo, icmp6_tree); + dissect_rrenum(tvb, offset, pinfo, icmp6_tree, dp->icmp6_type, dp->icmp6_code); break; case ICMP6_NI_QUERY: case ICMP6_NI_REPLY: @@ -3036,6 +3121,9 @@ proto_register_icmpv6(void) { &hf_icmpv6_checksum_bad, { "Bad Checksum", "icmpv6.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { &hf_icmpv6_reserved, + { "Reserved", "icmpv6.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, + "Must be Zero", HFILL }}, { &hf_icmpv6_nor, { "Number of records", "icmpv6.nor", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, @@ -3655,6 +3743,145 @@ proto_register_icmpv6(void) { &hf_icmpv6_ni_reply_ipv4_address, { "IPv4 Node address", "icmpv6.ni.query.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + + /* RFC 2894: Router Renumbering for IPv6 */ + { &hf_icmpv6_rr_sequencenumber, + { "Sequence Number", "icmpv6.rr.sequence_number", FT_UINT32, BASE_DEC, NULL, 0x0, + "The sequence number MUST be non-decreasing between Sequence Number Resets", HFILL }}, + { &hf_icmpv6_rr_segmentnumber, + { "Segment Number", "icmpv6.rr.segment_number", FT_UINT8, BASE_DEC, NULL, 0x0, + "Enumerates different valid RR messages having the same Sequence Number", HFILL }}, + { &hf_icmpv6_rr_flag, + { "Flags", "icmpv6.rr.flag", FT_UINT8, BASE_HEX, NULL, 0x0, + "Five are defined and three bits are reserved", HFILL }}, + { &hf_icmpv6_rr_flag_t, + { "Test Command", "icmpv6.rr.flag.t", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_T, + "Indicates a Test message: processing is to be simulated and no configuration changes are to be made", HFILL }}, + { &hf_icmpv6_rr_flag_r, + { "Result requested", "icmpv6.rr.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_R, + "Indicates that the router send a Result message upon completion of processing the Command message", HFILL }}, + { &hf_icmpv6_rr_flag_a, + { "All Interfaces", "icmpv6.rr.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_A, + "Indicates that the Command be applied to all interfaces regardless of administrative shutdown status", HFILL }}, + { &hf_icmpv6_rr_flag_s, + { "Site-specific", "icmpv6.rr.flag.s", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_S, + "Indicates that the Command be applied only to interfaces which belong to the same site as the interface to which the Command is addressed", HFILL }}, + { &hf_icmpv6_rr_flag_p, + { "Processed previously", "icmpv6.rr.flag.p", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_P, + "Indicates that the Command message was previously processed (and is not a Test) and the responding router is not processing it again", HFILL }}, + { &hf_icmpv6_rr_flag_rsv, + { "Reserved", "icmpv6.rr.flag.rsv", FT_UINT8, BASE_DEC, NULL, RR_FLAG_RSV, + "Must be Zero", HFILL }}, + { &hf_icmpv6_rr_maxdelay, + { "Max Delay", "icmpv6.rr.maxdelay", FT_UINT16, BASE_DEC, NULL, 0x0, + "Specifying the maximum time (in milliseconds) by which a router MUST delay sending any reply to this Command", HFILL }}, + + { &hf_icmpv6_rr_pco_mp_part, + { "Match-Prefix Part", "icmpv6.rr.pco.mp", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_icmpv6_rr_pco_mp_opcode, + { "OpCode", "icmpv6.rr.pco.mp.opcode", FT_UINT8, BASE_DEC, VALS(rr_pco_mp_opcode_val), 0x0, + "Specifying the operation to be performed when the associated MatchPrefix matches an interface's prefix or address", HFILL }}, + { &hf_icmpv6_rr_pco_mp_oplength, + { "OpLength", "icmpv6.rr.pco.mp.oplength", FT_UINT8, BASE_DEC, NULL, 0x0, + "The total length of this Prefix Control Operation (in units of 8 octets)", HFILL }}, + { &hf_icmpv6_rr_pco_mp_ordinal, + { "Ordinal", "icmpv6.rr.pco.mp.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0, + "The value is otherwise unconstrained", HFILL }}, + { &hf_icmpv6_rr_pco_mp_matchlen, + { "MatchLen", "icmpv6.rr.pco.mp.matchlen", FT_UINT8, BASE_DEC, NULL, 0x0, + "Between 0 and 128 inclusive specifying the number of initial bits of MatchPrefix which are significant in matching", HFILL }}, + { &hf_icmpv6_rr_pco_mp_minlen, + { "MinLen", "icmpv6.rr.pco.mp.minlen", FT_UINT8, BASE_DEC, NULL, 0x0, + "Specifying the minimum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }}, + { &hf_icmpv6_rr_pco_mp_maxlen, + { "MaxLen", "icmpv6.rr.pco.mp.maxlen", FT_UINT8, BASE_DEC, NULL, 0x0, + "Specifying the maximum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }}, + { &hf_icmpv6_rr_pco_mp_matchprefix, + { "MatchPrefix", "icmpv6.rr.pco.mp.matchprefix", FT_IPv6, BASE_NONE, NULL, 0x0, + "The 128-bit prefix to be compared with each interface's prefix or address", HFILL }}, + { &hf_icmpv6_rr_pco_up_part, + { "Use-Prefix Part", "icmpv6.rr.pco.up", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_icmpv6_rr_pco_up_uselen, + { "UseLen", "icmpv6.rr.pco.up.uselen", FT_UINT8, BASE_DEC, NULL, 0x0, + "specifying the number of initial bits of UsePrefix to use in creating a new prefix for an interface", HFILL }}, + { &hf_icmpv6_rr_pco_up_keeplen, + { "KeepLen", "icmpv6.rr.pco.up.keeplen", FT_UINT8, BASE_DEC, NULL, 0x0, + "Specifying the number of bits of the prefix or address which matched the associated Match-Prefix which should be retained in the new prefix", HFILL }}, + { &hf_icmpv6_rr_pco_up_flagmask, + { "FlagMask", "icmpv6.rr.pco.up.flagmask", FT_UINT8, BASE_HEX, NULL, 0x0, + "A 1 bit in any position means that the corresponding flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }}, + + { &hf_icmpv6_rr_pco_up_flagmask_l, + { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, + "When set, indicates the On-link (L) flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }}, + { &hf_icmpv6_rr_pco_up_flagmask_a, + { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, + "When set, indicates the Autonomous address-configuration (A) flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }}, + { &hf_icmpv6_rr_pco_up_flagmask_reserved, + { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f, + NULL, HFILL }}, + { &hf_icmpv6_rr_pco_up_raflags, + { "RAFlags", "icmpv6.rr.pco.up.raflags", FT_UINT8, BASE_HEX, NULL, 0x0, + "Under control of the FlagMask field, may be used to initialize the flags in Router Advertisement Prefix Information Options which advertise the New Prefix", HFILL }}, + { &hf_icmpv6_rr_pco_up_raflags_l, + { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, + "When set, indicates that this prefix can be used for on-link determination", HFILL }}, + { &hf_icmpv6_rr_pco_up_raflags_a, + { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, + "When set indicates that this prefix can be used for stateless address configuration", HFILL }}, + { &hf_icmpv6_rr_pco_up_raflags_reserved, + { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f, + NULL, HFILL }}, + { &hf_icmpv6_rr_pco_up_validlifetime, + { "Valid Lifetime", "icmpv6.rr.pco.up.validlifetime", FT_UINT32, BASE_DEC, NULL, 0x0, + "The number of seconds for which the New Prefix will be valid", HFILL }}, + { &hf_icmpv6_rr_pco_up_preferredlifetime, + { "Preferred Lifetime", "icmpv6.rr.pco.up.preferredlifetime", FT_UINT32, BASE_DEC, NULL, 0x0, + "The number of seconds for which the New Prefix will be preferred", HFILL }}, + { &hf_icmpv6_rr_pco_up_flag, + { "Flags", "icmpv6.rr.pco.up.flag", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + { &hf_icmpv6_rr_pco_up_flag_v, + { "Decrement valid lifetime", "icmpv6.rr.pco.up.flag.v", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x80000000, + "When set, indicating that the valid lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }}, + { &hf_icmpv6_rr_pco_up_flag_p, + { "Decrement preferred lifetime", "icmpv6.rr.pco.up.flag.p", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x40000000, + "When set, indicating that the preferred lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }}, + { &hf_icmpv6_rr_pco_up_flag_reserved, + { "Reserved", "icmpv6.rr.pco.up.flag.reserved", FT_UINT32, BASE_DEC, NULL, 0x3FFFFFFF, + NULL, HFILL }}, + { &hf_icmpv6_rr_pco_up_useprefix, + { "UsePrefix", "icmpv6.rr.pco.up.useprefix", FT_IPv6, BASE_NONE, NULL, 0x0, + "The 128-bit Use-prefix which either becomes or is used in forming (if KeepLen is nonzero) the New Prefix", HFILL }}, + { &hf_icmpv6_rr_rm, + { "Result Message", "icmpv6.rr.rm", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_icmpv6_rr_rm_flag, + { "Flags", "icmpv6.rr.rm.flag", FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + { &hf_icmpv6_rr_rm_flag_b, + { "Bounds", "icmpv6.rr.rm.flag.b", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002, + "When set, indicates that one or more fields in the associated PCO were out of bounds", HFILL }}, + { &hf_icmpv6_rr_rm_flag_f, + { "Forbidden", "icmpv6.rr.rm.flag.f", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001, + "When set, indicates that one or more Use-Prefix parts from the associated PCO were not honored by the router because of attempted formation of a forbidden prefix format, such as a multicast or loopback address", HFILL }}, + { &hf_icmpv6_rr_rm_flag_reserved, + { "Reserved", "icmpv6.rr.rm.flag.reserved", FT_UINT16, BASE_DEC, NULL, 0xFFFD, + "Must be Zero", HFILL }}, + { &hf_icmpv6_rr_rm_ordinal, + { "Ordinal", "icmpv6.rr.rm.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0, + "The value is otherwise unconstrained", HFILL }}, + { &hf_icmpv6_rr_rm_matchedlen, + { "MatchedLen", "icmpv6.rr.rm.matchedlen", FT_UINT8, BASE_DEC, NULL, 0x0, + "The length of the Matched Prefix", HFILL }}, + { &hf_icmpv6_rr_rm_interfaceindex, + { "InterfaceIndex", "icmpv6.rr.rm.interfaceindex", FT_UINT32, BASE_DEC, NULL, 0x0, + "The router's numeric designation of the interface on which the MatchedPrefix was configured", HFILL }}, + { &hf_icmpv6_rr_rm_matchedprefix, + { "MatchedPrefix", "icmpv6.rr.rm.matchedprefix", FT_IPv6, BASE_NONE, NULL, 0x0, + "The 128 Bits MatchedPrefix", HFILL }}, }; static gint *ett[] = { |