diff options
author | Bill Meier <wmeier@newsguy.com> | 2011-02-07 18:49:29 +0000 |
---|---|---|
committer | Bill Meier <wmeier@newsguy.com> | 2011-02-07 18:49:29 +0000 |
commit | 121c65c613316380596cda4d3ae16c01f4e49c65 (patch) | |
tree | e8dc9e8b9d2010e6afedd90ff5a865d1278e9362 /epan/dissectors/packet-icmpv6.c | |
parent | 9d3586b4f5de8f9a9e4fd5f4ec0e5a4fa97518ac (diff) |
Remove unneeded #includes (stdio.h,stdlib.h);
Whitespace cleanup: trailing, indentation, "4-space tabs"
svn path=/trunk/; revision=35850
Diffstat (limited to 'epan/dissectors/packet-icmpv6.c')
-rw-r--r-- | epan/dissectors/packet-icmpv6.c | 3318 |
1 files changed, 1664 insertions, 1654 deletions
diff --git a/epan/dissectors/packet-icmpv6.c b/epan/dissectors/packet-icmpv6.c index da3492ce69..1e89ca06d8 100644 --- a/epan/dissectors/packet-icmpv6.c +++ b/epan/dissectors/packet-icmpv6.c @@ -54,7 +54,7 @@ /* * The information used comes from: - * RFC 1885/2463/4443: Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification + * RFC 1885/2463/4443: Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification * RFC 2461/4861: Neighbor Discovery for IP Version 6 (IPv6) * RFC 2491: IPv6 over Non-Broadcast Multiple Access (NBMA) networks * RFC 2710: Multicast Listener Discovery for IPv6 @@ -91,7 +91,7 @@ static int hf_icmpv6_echo_identifier = -1; static int hf_icmpv6_echo_sequence_number = -1; static int hf_icmpv6_nonce = -1; -/* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */ +/* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */ static int hf_icmpv6_nd_ra_cur_hop_limit = -1; static int hf_icmpv6_nd_ra_flag = -1; static int hf_icmpv6_nd_ra_flag_m = -1; @@ -271,7 +271,7 @@ static int hf_icmpv6_rr_rm_matchedlen = -1; static int hf_icmpv6_rr_rm_interfaceindex = -1; static int hf_icmpv6_rr_rm_matchedprefix = -1; -/* RFC 3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */ +/* RFC 3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */ static int hf_icmpv6_mld_mrc = -1; static int hf_icmpv6_mld_flag = -1; static int hf_icmpv6_mld_flag_s = -1; @@ -470,38 +470,38 @@ static gint ett_icmpv6_cga_param_name = -1; static dissector_handle_t ipv6_handle; static dissector_handle_t data_handle; -#define ICMP6_DST_UNREACH 1 -#define ICMP6_PACKET_TOO_BIG 2 -#define ICMP6_TIME_EXCEEDED 3 -#define ICMP6_PARAM_PROB 4 -#define ICMP6_ECHO_REQUEST 128 -#define ICMP6_ECHO_REPLY 129 -#define ICMP6_MEMBERSHIP_QUERY 130 -#define ICMP6_MEMBERSHIP_REPORT 131 -#define ICMP6_MEMBERSHIP_REDUCTION 132 -#define ICMP6_ND_ROUTER_SOLICIT 133 -#define ICMP6_ND_ROUTER_ADVERT 134 -#define ICMP6_ND_NEIGHBOR_SOLICIT 135 -#define ICMP6_ND_NEIGHBOR_ADVERT 136 -#define ICMP6_ND_REDIRECT 137 -#define ICMP6_ROUTER_RENUMBERING 138 -#define ICMP6_NI_QUERY 139 -#define ICMP6_NI_REPLY 140 -#define ICMP6_IND_SOLICIT 141 -#define ICMP6_IND_ADVERT 142 -#define ICMP6_MLDV2_REPORT 143 -#define ICMP6_MIP6_DHAAD_REQUEST 144 -#define ICMP6_MIP6_DHAAD_REPLY 145 -#define ICMP6_MIP6_MPS 146 -#define ICMP6_MIP6_MPA 147 -#define ICMP6_CERT_PATH_SOL 148 -#define ICMP6_CERT_PATH_AD 149 -#define ICMP6_EXPERIMENTAL_MOBILITY 150 -#define ICMP6_MCAST_ROUTER_ADVERT 151 -#define ICMP6_MCAST_ROUTER_SOLICIT 152 -#define ICMP6_MCAST_ROUTER_TERM 153 -#define ICMP6_FMIPV6_MESSAGES 154 -#define ICMP6_RPL_CONTROL 155 +#define ICMP6_DST_UNREACH 1 +#define ICMP6_PACKET_TOO_BIG 2 +#define ICMP6_TIME_EXCEEDED 3 +#define ICMP6_PARAM_PROB 4 +#define ICMP6_ECHO_REQUEST 128 +#define ICMP6_ECHO_REPLY 129 +#define ICMP6_MEMBERSHIP_QUERY 130 +#define ICMP6_MEMBERSHIP_REPORT 131 +#define ICMP6_MEMBERSHIP_REDUCTION 132 +#define ICMP6_ND_ROUTER_SOLICIT 133 +#define ICMP6_ND_ROUTER_ADVERT 134 +#define ICMP6_ND_NEIGHBOR_SOLICIT 135 +#define ICMP6_ND_NEIGHBOR_ADVERT 136 +#define ICMP6_ND_REDIRECT 137 +#define ICMP6_ROUTER_RENUMBERING 138 +#define ICMP6_NI_QUERY 139 +#define ICMP6_NI_REPLY 140 +#define ICMP6_IND_SOLICIT 141 +#define ICMP6_IND_ADVERT 142 +#define ICMP6_MLDV2_REPORT 143 +#define ICMP6_MIP6_DHAAD_REQUEST 144 +#define ICMP6_MIP6_DHAAD_REPLY 145 +#define ICMP6_MIP6_MPS 146 +#define ICMP6_MIP6_MPA 147 +#define ICMP6_CERT_PATH_SOL 148 +#define ICMP6_CERT_PATH_AD 149 +#define ICMP6_EXPERIMENTAL_MOBILITY 150 +#define ICMP6_MCAST_ROUTER_ADVERT 151 +#define ICMP6_MCAST_ROUTER_SOLICIT 152 +#define ICMP6_MCAST_ROUTER_TERM 153 +#define ICMP6_FMIPV6_MESSAGES 154 +#define ICMP6_RPL_CONTROL 155 static const value_string icmpv6_type_val[] = { @@ -546,14 +546,14 @@ static const value_string icmpv6_type_val[] = { { 0, NULL } }; -#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ -#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ -#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */ -#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ -#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ -#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */ -#define ICMP6_DST_UNREACH_INGR_EGR 5 /* source address failed ingress/egress policy */ -#define ICMP6_DST_UNREACH_REJECT 6 /* reject route to destination */ +#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ +#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ +#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */ +#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ +#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ +#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */ +#define ICMP6_DST_UNREACH_INGR_EGR 5 /* source address failed ingress/egress policy */ +#define ICMP6_DST_UNREACH_REJECT 6 /* reject route to destination */ static const value_string icmpv6_unreach_code_val[] = { { ICMP6_DST_UNREACH_NOROUTE, "no route to destination" }, @@ -566,8 +566,8 @@ static const value_string icmpv6_unreach_code_val[] = { { 0, NULL } }; -#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */ -#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */ +#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */ +#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */ static const value_string icmpv6_timeex_code_val[] = { { ICMP6_TIME_EXCEED_TRANSIT, "hop limit exceeded in transit" }, @@ -575,9 +575,9 @@ static const value_string icmpv6_timeex_code_val[] = { { 0, NULL } }; -#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ -#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */ -#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */ +#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ +#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */ +#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */ static const value_string icmpv6_paramprob_code_val[] = { { ICMP6_PARAMPROB_HEADER, "erroneous header field encountered" }, @@ -589,9 +589,9 @@ static const value_string icmpv6_paramprob_code_val[] = { /* RFC2894 - Router Renumbering for IPv6 */ -#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */ -#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */ -#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */ +#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */ +#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */ +#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */ static const value_string icmpv6_rr_code_val[] = { { ICMP6_ROUTER_RENUMBERING_COMMAND, "Command" }, @@ -600,11 +600,11 @@ static const value_string icmpv6_rr_code_val[] = { { 0, NULL } }; -#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_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[] = { @@ -635,10 +635,10 @@ static const value_string mldr_record_type_val[] = { /* RFC 4068/5268/5568: Fast Handovers for Mobile IPv6 ( Mobile IPv6 Fast Handovers ) */ -#define FMIP6_SUBTYPE_RTSOLPR 2 -#define FMIP6_SUBTYPE_PRRTADV 3 -#define FMIP6_SUBTYPE_HI 4 -#define FMIP6_SUBTYPE_HACK 5 +#define FMIP6_SUBTYPE_RTSOLPR 2 +#define FMIP6_SUBTYPE_PRRTADV 3 +#define FMIP6_SUBTYPE_HI 4 +#define FMIP6_SUBTYPE_HACK 5 static const value_string fmip6_subtype_val[] = { { FMIP6_SUBTYPE_RTSOLPR, "Router Solicitation for Proxy Advertisement" }, @@ -681,19 +681,19 @@ static const value_string fmip6_hack_code_val[] = { /* RFC 4620 - IPv6 Node Information Queries */ -#define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */ -#define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */ -#define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */ +#define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */ +#define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */ +#define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */ -#define ICMP6_NI_SUCCESS 0 /* node information successful reply */ -#define ICMP6_NI_REFUSED 1 /* node information request is refused */ -#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */ +#define ICMP6_NI_SUCCESS 0 /* node information successful reply */ +#define ICMP6_NI_REFUSED 1 /* node information request is refused */ +#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */ -#define NI_QTYPE_NOOP 0 /* NOOP */ -#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes (Obso) */ -#define NI_QTYPE_NODENAME 2 /* Node Name */ -#define NI_QTYPE_NODEADDR 3 /* Node Addresses */ -#define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */ +#define NI_QTYPE_NOOP 0 /* NOOP */ +#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes (Obso) */ +#define NI_QTYPE_NODENAME 2 /* Node Name */ +#define NI_QTYPE_NODEADDR 3 /* Node Addresses */ +#define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */ static const value_string ni_query_code_val[] = { { ICMP6_NI_SUBJ_IPV6, "Query subject = IPv6 addresses" }, @@ -717,12 +717,12 @@ static const value_string ni_qtype_val[] = { { 0, NULL } }; -#define NI_FLAG_G 0x0020 -#define NI_FLAG_S 0x0010 -#define NI_FLAG_L 0x0008 -#define NI_FLAG_C 0x0004 -#define NI_FLAG_A 0x0002 -#define NI_FLAG_T 0x0001 +#define NI_FLAG_G 0x0020 +#define NI_FLAG_S 0x0010 +#define NI_FLAG_L 0x0008 +#define NI_FLAG_C 0x0004 +#define NI_FLAG_A 0x0002 +#define NI_FLAG_T 0x0001 #define NI_FLAG_RSV 0xFFC0 static const true_false_string tfs_ni_flag_a = { @@ -730,29 +730,29 @@ static const true_false_string tfs_ni_flag_a = { "Unicast addresses on the queried interface" }; -#define ND_OPT_SOURCE_LINKADDR 1 -#define ND_OPT_TARGET_LINKADDR 2 -#define ND_OPT_PREFIX_INFORMATION 3 -#define ND_OPT_REDIRECTED_HEADER 4 -#define ND_OPT_MTU 5 -#define ND_OPT_NBMA 6 -#define ND_OPT_ADVINTERVAL 7 -#define ND_OPT_HOMEAGENT_INFO 8 -#define ND_OPT_SOURCE_ADDRLIST 9 -#define ND_OPT_TARGET_ADDRLIST 10 -#define ND_OPT_CGA 11 -#define ND_OPT_RSA 12 -#define ND_OPT_TIMESTAMP 13 -#define ND_OPT_NONCE 14 -#define ND_OPT_TRUST_ANCHOR 15 -#define ND_OPT_CERTIFICATE 16 +#define ND_OPT_SOURCE_LINKADDR 1 +#define ND_OPT_TARGET_LINKADDR 2 +#define ND_OPT_PREFIX_INFORMATION 3 +#define ND_OPT_REDIRECTED_HEADER 4 +#define ND_OPT_MTU 5 +#define ND_OPT_NBMA 6 +#define ND_OPT_ADVINTERVAL 7 +#define ND_OPT_HOMEAGENT_INFO 8 +#define ND_OPT_SOURCE_ADDRLIST 9 +#define ND_OPT_TARGET_ADDRLIST 10 +#define ND_OPT_CGA 11 +#define ND_OPT_RSA 12 +#define ND_OPT_TIMESTAMP 13 +#define ND_OPT_NONCE 14 +#define ND_OPT_TRUST_ANCHOR 15 +#define ND_OPT_CERTIFICATE 16 #define ND_OPT_IP_ADDRESS_PREFIX 17 #define ND_OPT_NEW_ROUTER_PREFIX_INFO 18 #define ND_OPT_LINK_LAYER_ADDRESS 19 #define ND_OPT_NEIGHBOR_ADV_ACK 20 -#define ND_OPT_MAP 23 -#define ND_OPT_ROUTE_INFO 24 -#define ND_OPT_RECURSIVE_DNS_SERVER 25 +#define ND_OPT_MAP 23 +#define ND_OPT_ROUTE_INFO 24 +#define ND_OPT_RECURSIVE_DNS_SERVER 25 #define ND_OPT_FLAGS_EXTENSION 26 #define ND_OPT_HANDOVER_KEY_REQUEST 27 #define ND_OPT_HANDOVER_KEY_REPLY 28 @@ -760,9 +760,9 @@ static const true_false_string tfs_ni_flag_a = { #define ND_OPT_MOBILE_NODE_ID 30 #define ND_OPT_DNS_SEARCH_LIST 31 /* draft-6lowpan-nd types, pending IANA assignment */ -#define ND_OPT_ADDR_RESOLUTION 131 /* Conflit with RFC6106.. */ -#define ND_OPT_6LOWPAN_CONTEXT 32 -#define ND_OPT_AUTH_BORDER_ROUTER 33 +#define ND_OPT_ADDR_RESOLUTION 131 /* Conflit with RFC6106.. */ +#define ND_OPT_6LOWPAN_CONTEXT 32 +#define ND_OPT_AUTH_BORDER_ROUTER 33 static const value_string option_vals[] = { /* 1 */ { ND_OPT_SOURCE_LINKADDR, "Source link-layer address" }, @@ -807,17 +807,17 @@ static const value_string option_vals[] = { { 0, NULL } }; -#define ND_RA_FLAG_M 0x80 -#define ND_RA_FLAG_O 0x40 -#define ND_RA_FLAG_H 0x20 +#define ND_RA_FLAG_M 0x80 +#define ND_RA_FLAG_O 0x40 +#define ND_RA_FLAG_H 0x20 #define ND_RA_FLAG_PRF 0x18 #define ND_RA_FLAG_P 0x04 #define ND_RA_FLAG_RSV 0x02 #define ND_NA_FLAG_R 0x80000000 -#define ND_NA_FLAG_S 0x40000000 -#define ND_NA_FLAG_O 0x20000000 -#define ND_NA_FLAG_RSV 0x1FFFFFFF +#define ND_NA_FLAG_S 0x40000000 +#define ND_NA_FLAG_O 0x20000000 +#define ND_NA_FLAG_RSV 0x1FFFFFFF static const value_string nd_flag_router_pref[] = { { 1, "High" }, @@ -899,8 +899,8 @@ static const value_string icmpv6_option_cert_type_vals[] = { /* RFC 4191: Default Router Preferences and More-Specific Routes */ -#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ -#define ND_RA_FLAG_RESERV_MASK 0xE7 /* 11100111 */ +#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ +#define ND_RA_FLAG_RESERV_MASK 0xE7 /* 11100111 */ /* RFC 5075/5175 : IPv6 Router Advertisement Flags Option */ #define FLAGS_EO_M 0x8000 @@ -951,7 +951,7 @@ static const value_string icmpv6_option_cert_type_vals[] = { #define RPL_SECURE_FLAG_T 0x80 #define RPL_SECURE_FLAG_RSV 0x7F -#define RPL_SECURE_LVL 0x07 +#define RPL_SECURE_LVL 0x07 #define RPL_SECURE_KIM 0xC0 #define RPL_SECURE_RSV 0x38 @@ -1015,15 +1015,15 @@ static const value_string rpl_secure_algorithm_signature_val[] = { #define RPL_OPT_TARGETDESC 9 /* RPL Target Descriptor */ static const value_string rpl_option_vals[] = { - { RPL_OPT_PAD1, "1-byte padding" }, - { RPL_OPT_PADN, "n-byte padding" }, - { RPL_OPT_METRIC, "Metric container" }, - { RPL_OPT_ROUTING, "Routing"}, - { RPL_OPT_CONFIG, "DODAG configuration" }, - { RPL_OPT_TARGET, "RPL Target" }, - { RPL_OPT_TRANSIT, "Transit Information" }, - { RPL_OPT_SOLICITED,"Solicited Information"}, - { RPL_OPT_PREFIX, "Prefix Information"}, + { RPL_OPT_PAD1, "1-byte padding" }, + { RPL_OPT_PADN, "n-byte padding" }, + { RPL_OPT_METRIC, "Metric container" }, + { RPL_OPT_ROUTING, "Routing"}, + { RPL_OPT_CONFIG, "DODAG configuration" }, + { RPL_OPT_TARGET, "RPL Target" }, + { RPL_OPT_TRANSIT, "Transit Information" }, + { RPL_OPT_SOLICITED, "Solicited Information"}, + { RPL_OPT_PREFIX, "Prefix Information"}, { RPL_OPT_TARGETDESC, "RPL Target Descriptor"}, { 0, NULL } }; @@ -1066,823 +1066,826 @@ dissect_icmpv6_nd_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree int opt_offset; while ((int)tvb_reported_length(tvb) > offset) { - /* there are more options */ + /* there are more options */ - /* ICMPv6 Option */ - opt_len = tvb_get_guint8(tvb, offset + 1) * 8; - ti = proto_tree_add_item(tree, hf_icmpv6_opt, tvb, offset, opt_len, FALSE); - icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_opt); + /* ICMPv6 Option */ + opt_len = tvb_get_guint8(tvb, offset + 1) * 8; + ti = proto_tree_add_item(tree, hf_icmpv6_opt, tvb, offset, opt_len, FALSE); + icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_opt); opt_offset = offset; - /* Option type */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_type, tvb, opt_offset, 1, FALSE); + /* Option type */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_type, tvb, opt_offset, 1, FALSE); opt_type = tvb_get_guint8(tvb, opt_offset); opt_offset += 1; - /* Add option name to option root label */ - proto_item_append_text(ti, " (%s", val_to_str(opt_type, option_vals, "Unknown %d")); + /* Add option name to option root label */ + proto_item_append_text(ti, " (%s", val_to_str(opt_type, option_vals, "Unknown %d")); - /* Option length */ - ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_length, tvb,opt_offset, 1, FALSE); + /* Option length */ + ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_length, tvb,opt_offset, 1, FALSE); opt_offset += 1; /* Add length value in bytes */ - proto_item_append_text(ti_opt_len, " (%i bytes)", opt_len); + proto_item_append_text(ti_opt_len, " (%i bytes)", opt_len); if(opt_len == 0){ expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid option length (Zero)"); return; } - /* decode... */ - switch (opt_type) { - case ND_OPT_SOURCE_LINKADDR: /* Source Link-layer Address (1) */ - { - const guint8 *link_addr; - /* if the opt len is 8, the Link Addr is MAC Address */ - if(opt_len == 8){ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, FALSE); - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr_mac, tvb, opt_offset, 6, FALSE); - PROTO_ITEM_SET_HIDDEN(ti_opt); - - link_addr = tvb_get_ptr(tvb, opt_offset, 6); - col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", ether_to_str(link_addr)); - proto_item_append_text(ti, " : %s", ether_to_str(link_addr)); - - }else{ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, FALSE); - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr, tvb, opt_offset, opt_len-2, FALSE); - PROTO_ITEM_SET_HIDDEN(ti_opt); + /* decode... */ + switch (opt_type) { + case ND_OPT_SOURCE_LINKADDR: /* Source Link-layer Address (1) */ + { + const guint8 *link_addr; + /* if the opt len is 8, the Link Addr is MAC Address */ + if(opt_len == 8){ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, FALSE); + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr_mac, tvb, opt_offset, 6, FALSE); + PROTO_ITEM_SET_HIDDEN(ti_opt); + + link_addr = tvb_get_ptr(tvb, opt_offset, 6); + col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", ether_to_str(link_addr)); + proto_item_append_text(ti, " : %s", ether_to_str(link_addr)); + + }else{ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, FALSE); + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_src_linkaddr, tvb, opt_offset, opt_len-2, FALSE); + PROTO_ITEM_SET_HIDDEN(ti_opt); + } + break; } - break; - } - case ND_OPT_TARGET_LINKADDR: /* Target Link-layer Address (2) */ - { - const guint8 *link_addr; - /* if the opt len is 8, the Link Addr is MAC Address */ - if(opt_len == 8){ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, FALSE); - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr_mac, tvb, opt_offset, 6, FALSE); - PROTO_ITEM_SET_HIDDEN(ti_opt); - - link_addr = tvb_get_ptr(tvb, opt_offset, 6); - col_append_fstr(pinfo->cinfo, COL_INFO, " is at %s", ether_to_str(link_addr)); - proto_item_append_text(ti, " : %s", ether_to_str(link_addr)); - - }else{ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, FALSE); - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr, tvb, opt_offset, opt_len-2, FALSE); - PROTO_ITEM_SET_HIDDEN(ti_opt); + case ND_OPT_TARGET_LINKADDR: /* Target Link-layer Address (2) */ + { + const guint8 *link_addr; + /* if the opt len is 8, the Link Addr is MAC Address */ + if(opt_len == 8){ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr_mac, tvb, opt_offset, 6, FALSE); + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr_mac, tvb, opt_offset, 6, FALSE); + PROTO_ITEM_SET_HIDDEN(ti_opt); + + link_addr = tvb_get_ptr(tvb, opt_offset, 6); + col_append_fstr(pinfo->cinfo, COL_INFO, " is at %s", ether_to_str(link_addr)); + proto_item_append_text(ti, " : %s", ether_to_str(link_addr)); + + }else{ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_linkaddr, tvb, opt_offset, opt_len-2, FALSE); + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_target_linkaddr, tvb, opt_offset, opt_len-2, FALSE); + PROTO_ITEM_SET_HIDDEN(ti_opt); + } + + break; } + case ND_OPT_PREFIX_INFORMATION: /* Prefix Information (3) */ + { + guint8 prefix_len; + /* RFC 4861 */ + + /* Prefix Length */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, FALSE); + prefix_len = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_prefix); + + proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_l, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_a, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Prefix Valid Lifetime */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_valid_lifetime, tvb, opt_offset, 4, FALSE); + + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; + } + opt_offset += 4; - break; - } - case ND_OPT_PREFIX_INFORMATION: /* Prefix Information (3) */ - { - guint8 prefix_len; - /* RFC 4861 */ + /* Prefix Preferred Lifetime */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_preferred_lifetime, tvb, opt_offset, 4, FALSE); - /* Prefix Length */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, FALSE); - prefix_len = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; + } + opt_offset += 4; + + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); + opt_offset += 4; + + /* Prefix */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " : %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + opt_offset += 16; - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_prefix); - - proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_l, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_a, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_prefix_flag_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Prefix Valid Lifetime */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_valid_lifetime, tvb, opt_offset, 4, FALSE); - - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); - break; - default: break; } - opt_offset += 4; + case ND_OPT_REDIRECTED_HEADER: /* Redirected Header (4) */ - /* Prefix Preferred Lifetime */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_preferred_lifetime, tvb, opt_offset, 4, FALSE); - - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, FALSE); + opt_offset += 6; + + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_redirected_packet, tvb, opt_offset, -1, FALSE); + + dissect_contained_icmpv6(tvb, opt_offset, pinfo, icmp6opt_tree); break; - default: + case ND_OPT_MTU: /* MTU (5) */ + + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mtu, tvb, opt_offset, 4, FALSE); + proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset)); break; - } - opt_offset += 4; + case ND_OPT_NBMA: /* NBMA Shortcut Limit Option (6) */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); - opt_offset += 4; - - /* Prefix */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " : %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); - opt_offset += 16; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nbma_shortcut_limit, tvb, opt_offset, 1, FALSE); + proto_item_append_text(ti, " : %d", tvb_get_guint8(tvb, opt_offset)); - break; - } - case ND_OPT_REDIRECTED_HEADER: /* Redirected Header (4) */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, FALSE); - opt_offset += 6; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); + opt_offset += 4; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_redirected_packet, tvb, opt_offset, -1, FALSE); + break; + case ND_OPT_ADVINTERVAL: /* Advertisement Interval Option (7) */ - dissect_contained_icmpv6(tvb, opt_offset, pinfo, icmp6opt_tree); - break; - case ND_OPT_MTU: /* MTU (5) */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); + opt_offset += 2; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); - opt_offset += 2; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_advertisement_interval, tvb, opt_offset, 4, FALSE); + proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset)); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mtu, tvb, opt_offset, 4, FALSE); - proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset)); - break; - case ND_OPT_NBMA: /* NBMA Shortcut Limit Option (6) */ + break; + case ND_OPT_HOMEAGENT_INFO: /* Home Agent Information Option (8) */ + { - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nbma_shortcut_limit, tvb, opt_offset, 1, FALSE); - proto_item_append_text(ti, " : %d", tvb_get_guint8(tvb, opt_offset)); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); + opt_offset += 2; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_preference, tvb, opt_offset, 2, FALSE); + opt_offset += 2; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); - opt_offset += 4; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_lifetime, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + break; + } + case ND_OPT_SOURCE_ADDRLIST: /* Source Address List (9) */ + case ND_OPT_TARGET_ADDRLIST: /* Target Address List (10)*/ + { + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, FALSE); + opt_offset += 6; - break; - case ND_OPT_ADVINTERVAL: /* Advertisement Interval Option (7) */ + while(opt_offset < (offset + opt_len) ) { + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipv6_address, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset)); + opt_offset += 16; + } + break; + } + case ND_OPT_CGA: /* CGA option (11) */ + { + proto_tree *cga_tree; + proto_item *cga_item; + guint16 ext_data_len; + guint8 padd_length; + int par_len; + asn1_ctx_t asn1_ctx; + /* RFC 3971 5.1. CGA Option */ + + /* Pad Length */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, FALSE); + padd_length = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + /* Reserved 8 bits */ + + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* CGA Parameters A variable-length field containing the CGA Parameters data + * structure described in Section 4 of + * "Cryptographically Generated Addresses (CGA)", RFC3972. + */ + par_len = opt_len -4 -padd_length; + cga_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga, tvb, opt_offset, par_len, FALSE); + par_len += opt_offset; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); - opt_offset += 2; + cga_tree = proto_item_add_subtree(cga_item, ett_icmpv6_cga_param_name); + proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_modifier, tvb, opt_offset, 16, FALSE); + opt_offset += 16; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_advertisement_interval, tvb, opt_offset, 4, FALSE); - proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, opt_offset)); + proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_subnet_prefix, tvb, opt_offset, 8, FALSE); + opt_offset += 8; - break; - case ND_OPT_HOMEAGENT_INFO: /* Home Agent Information Option (8) */ - { + proto_tree_add_item(cga_tree ,hf_icmpv6_opt_cga_count, tvb, opt_offset, 1, FALSE); + opt_offset++; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); - opt_offset += 2; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + opt_offset = dissect_x509af_SubjectPublicKeyInfo(FALSE, tvb, opt_offset, &asn1_ctx, cga_tree, -1); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_preference, tvb, opt_offset, 2, FALSE); - opt_offset += 2; + /* Process RFC 4581*/ + while (opt_offset < par_len) { + proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_type, tvb, opt_offset, 2, FALSE); + opt_offset += 2; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_home_agent_lifetime, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - break; - } - case ND_OPT_SOURCE_ADDRLIST: /* Source Address List (9) */ - case ND_OPT_TARGET_ADDRLIST: /* Target Address List (10)*/ - { - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, FALSE); - opt_offset += 6; - - while(opt_offset < (offset + opt_len) ) { - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipv6_address, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset)); - opt_offset += 16; - } - break; - } - case ND_OPT_CGA: /* CGA option (11) */ - { - proto_tree *cga_tree; - proto_item *cga_item; - guint16 ext_data_len; - guint8 padd_length; - int par_len; - asn1_ctx_t asn1_ctx; - /* RFC 3971 5.1. CGA Option */ - - /* Pad Length */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, FALSE); - padd_length = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - /* Reserved 8 bits */ - - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* CGA Parameters A variable-length field containing the CGA Parameters data - * structure described in Section 4 of - * "Cryptographically Generated Addresses (CGA)", RFC3972. - */ - par_len = opt_len -4 -padd_length; - cga_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga, tvb, opt_offset, par_len, FALSE); - par_len += opt_offset; - - cga_tree = proto_item_add_subtree(cga_item, ett_icmpv6_cga_param_name); - proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_modifier, tvb, opt_offset, 16, FALSE); - opt_offset += 16; - - proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_subnet_prefix, tvb, opt_offset, 8, FALSE); - opt_offset += 8; - - proto_tree_add_item(cga_tree ,hf_icmpv6_opt_cga_count, tvb, opt_offset, 1, FALSE); - opt_offset++; - - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - opt_offset = dissect_x509af_SubjectPublicKeyInfo(FALSE, tvb, opt_offset, &asn1_ctx, cga_tree, -1); - - /* Process RFC 4581*/ - while (opt_offset < par_len) { - proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_type, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - ext_data_len = tvb_get_ntohs(tvb, opt_offset); - proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_length, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_data, tvb, opt_offset, ext_data_len, FALSE); - opt_offset += ext_data_len; - } - - /* Padding */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); - break; - } - case ND_OPT_RSA: /* RSA Signature option (12) */ - { - int par_len; - /*5.2. RSA Signature Option */ - /* Reserved, A 16-bit field reserved for future use. */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); - opt_offset = opt_offset + 2; - - /* Key Hash - * A 128-bit field containing the most significant (leftmost) 128 - * bits of a SHA-1 [14] hash of the public key used for constructing - * the signature. - */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rsa_key_hash, tvb, opt_offset, 16, FALSE); - opt_offset = opt_offset + 16; - - /* Digital Signature */ - par_len = opt_len - 20; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_digital_signature_padding , tvb, opt_offset, par_len, FALSE); - - /* Padding */ - /* TODO: Calculate padding length and exlude from the signature */ - break; - } - case ND_OPT_TIMESTAMP: /* Timestamp option (13) */ - /* Reserved A 48-bit field reserved for future use. */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, FALSE); - opt_offset += 6; - - /* Timestamp - * A 64-bit unsigned integer field containing a timestamp. The value - * indicates the number of seconds since January 1, 1970, 00:00 UTC, - * by using a fixed point format. In this format, the integer number - * of seconds is contained in the first 48 bits of the field, and the - * remaining 16 bits indicate the number of 1/64K fractions of a - * second. - */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_timestamp, tvb, opt_offset + 2, 4, FALSE); - break; - case ND_OPT_NONCE: /* Nonce option (14) */ - /* 5.3.2. Nonce Option */ - - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nonce, tvb, opt_offset, opt_len - 2, FALSE); - /* Nonce */ - break; - case ND_OPT_TRUST_ANCHOR: /* Trust Anchor option (15) */ - { - proto_tree *name_tree; - proto_item *name_item; - guint8 name_type; - guint8 padd_length; - int par_len; - asn1_ctx_t asn1_ctx; - - /* Name Type */ - name_type = tvb_get_guint8(tvb, opt_offset); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_type, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Pad Length */ - padd_length = tvb_get_guint8(tvb, opt_offset); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - par_len = opt_len - 4 - padd_length; - - switch (name_type){ - case 1: - /* DER Encoded X.501 Name */ - name_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_x501, tvb, opt_offset, par_len, FALSE); - name_tree = proto_item_add_subtree(name_item, ett_icmpv6_opt_name); - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - dissect_x509if_Name(FALSE, tvb, opt_offset, &asn1_ctx, name_tree, hf_icmpv6_x509if_Name); - break; - case 2: - /* FQDN */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_fqdn, tvb, opt_offset, par_len, FALSE); - break; - default: - break; - } - opt_offset = opt_offset + par_len; - - /* Padding */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); - - break; - } - case ND_OPT_CERTIFICATE: /* Certificate option (16) */ - { - guint8 cert_type; - guint8 padd_length; - asn1_ctx_t asn1_ctx; - - /* Cert Type */ - cert_type = tvb_get_guint8(tvb, opt_offset); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cert_type, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Certificate */ - - if(cert_type == 1){ - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - opt_offset = dissect_x509af_Certificate(FALSE, tvb, opt_offset, &asn1_ctx, icmp6opt_tree, hf_icmpv6_x509af_Certificate); - padd_length = opt_len - (opt_offset - offset); - /* Padding */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); - }else{ - padd_length = opt_len - 4; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_certificate_padding, tvb, opt_offset, padd_length, FALSE); - } - break; - } - case ND_OPT_IP_ADDRESS_PREFIX: /* IP Address/Prefix Option (17) */ - { - guint8 prefix_len; - - /* Option-code */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_option_code, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Prefix Len */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_prefix_len, tvb, opt_offset, 1, FALSE); - prefix_len = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); - opt_offset += 4; - - /* IPv6 Address */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_ipv6_address, tvb, opt_offset, 16, FALSE); - opt_offset += 16; - - proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); - - break; - } - case ND_OPT_NEW_ROUTER_PREFIX_INFO: /* New Router Prefix Information Option (18) OBSO... */ - { - - guint8 prefix_len; - - /* Option-code */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_option_code, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Prefix Len */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix_len, tvb, opt_offset, 1, FALSE); - prefix_len = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); - opt_offset += 4; - - /* Prefix */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix, tvb, opt_offset, 16, FALSE); - opt_offset += 16; - - proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); - break; - } - case ND_OPT_LINK_LAYER_ADDRESS: /* Link-layer Address Option (19) */ - { - /* Option-Code */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_option_code, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Link Layer Address */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_bytes, tvb, opt_offset, opt_len-3, FALSE); - break; - } - - case ND_OPT_NEIGHBOR_ADV_ACK: /* Neighbor Advertisement Acknowledgment Option (20) */ - { - guint8 status; - - /* Option-Code */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_option_code, tvb, opt_offset, 1, FALSE); - opt_offset += 1; + ext_data_len = tvb_get_ntohs(tvb, opt_offset); + proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_length, tvb, opt_offset, 2, FALSE); + opt_offset += 2; - /* Status */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_status, tvb, opt_offset, 1, FALSE); - status = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - if(status == 2){ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_supplied_ncoa, tvb, opt_offset, 16, FALSE); - }else{ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, opt_len - 4, FALSE); + proto_tree_add_item(cga_tree, hf_icmpv6_opt_cga_ext_data, tvb, opt_offset, ext_data_len, FALSE); + opt_offset += ext_data_len; + } + + /* Padding */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); + break; } - break; - } - case ND_OPT_MAP: /* MAP Option (23) */ - { - - /* Dist */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_dist, tvb, opt_offset, 1, FALSE); - - /* Pref */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_pref, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_map); + case ND_OPT_RSA: /* RSA Signature option (12) */ + { + int par_len; + /*5.2. RSA Signature Option */ + /* Reserved, A 16-bit field reserved for future use. */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); + opt_offset = opt_offset + 2; + + /* Key Hash + * A 128-bit field containing the most significant (leftmost) 128 + * bits of a SHA-1 [14] hash of the public key used for constructing + * the signature. + */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rsa_key_hash, tvb, opt_offset, 16, FALSE); + opt_offset = opt_offset + 16; - proto_tree_add_item(flag_tree, hf_icmpv6_opt_map_flag_r, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_map_flag_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; + /* Digital Signature */ + par_len = opt_len - 20; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_digital_signature_padding , tvb, opt_offset, par_len, FALSE); - /* Valid Lifetime */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_valid_lifetime, tvb, opt_offset, 4, FALSE); - opt_offset += 4; - - /* Global Address */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_global_address, tvb, opt_offset, 16, FALSE); - opt_offset += 16; - break; - } - case ND_OPT_ROUTE_INFO: /* Route Information Option (24) */ - { - /* RFC 4191 */ - guint8 prefix_len; - guint8 route_preference; - struct e_in6_addr prefix; - - /* Prefix Len */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, FALSE); - prefix_len = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_route_info_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_route_info); + /* Padding */ + /* TODO: Calculate padding length and exlude from the signature */ + break; + } + case ND_OPT_TIMESTAMP: /* Timestamp option (13) */ + /* Reserved A 48-bit field reserved for future use. */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 6, FALSE); + opt_offset += 6; + + /* Timestamp + * A 64-bit unsigned integer field containing a timestamp. The value + * indicates the number of seconds since January 1, 1970, 00:00 UTC, + * by using a fixed point format. In this format, the integer number + * of seconds is contained in the first 48 bits of the field, and the + * remaining 16 bits indicate the number of 1/64K fractions of a + * second. + */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_timestamp, tvb, opt_offset + 2, 4, FALSE); + break; + case ND_OPT_NONCE: /* Nonce option (14) */ + /* 5.3.2. Nonce Option */ - proto_tree_add_item(flag_tree, hf_icmpv6_opt_route_info_flag_route_preference, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_route_info_flag_reserved, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nonce, tvb, opt_offset, opt_len - 2, FALSE); + /* Nonce */ + break; + case ND_OPT_TRUST_ANCHOR: /* Trust Anchor option (15) */ + { + proto_tree *name_tree; + proto_item *name_item; + guint8 name_type; + guint8 padd_length; + int par_len; + asn1_ctx_t asn1_ctx; + + /* Name Type */ + name_type = tvb_get_guint8(tvb, opt_offset); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_type, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Pad Length */ + padd_length = tvb_get_guint8(tvb, opt_offset); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cga_pad_len, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + par_len = opt_len - 4 - padd_length; + + switch (name_type){ + case 1: + /* DER Encoded X.501 Name */ + name_item = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_x501, tvb, opt_offset, par_len, FALSE); + name_tree = proto_item_add_subtree(name_item, ett_icmpv6_opt_name); + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + dissect_x509if_Name(FALSE, tvb, opt_offset, &asn1_ctx, name_tree, hf_icmpv6_x509if_Name); + break; + case 2: + /* FQDN */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_name_fqdn, tvb, opt_offset, par_len, FALSE); + break; + default: + break; + } + opt_offset = opt_offset + par_len; - route_preference = tvb_get_guint8(tvb, opt_offset); - route_preference = (route_preference & ND_RA_FLAG_RTPREF_MASK) >> 3; - proto_item_append_text(ti, " : %s", val_to_str(route_preference, nd_flag_router_pref, "Unknown %d") ); - opt_offset += 1; + /* Padding */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); - /* Route Lifetime */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_route_lifetime, tvb, opt_offset, 4, FALSE); - - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); break; - default: + } + case ND_OPT_CERTIFICATE: /* Certificate option (16) */ + { + guint8 cert_type; + guint8 padd_length; + asn1_ctx_t asn1_ctx; + + /* Cert Type */ + cert_type = tvb_get_guint8(tvb, opt_offset); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_cert_type, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Certificate */ + + if(cert_type == 1){ + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + opt_offset = dissect_x509af_Certificate(FALSE, tvb, opt_offset, &asn1_ctx, icmp6opt_tree, hf_icmpv6_x509af_Certificate); + padd_length = opt_len - (opt_offset - offset); + /* Padding */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); + }else{ + padd_length = opt_len - 4; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_certificate_padding, tvb, opt_offset, padd_length, FALSE); + } break; } - opt_offset += 4; + case ND_OPT_IP_ADDRESS_PREFIX: /* IP Address/Prefix Option (17) */ + { + guint8 prefix_len; + + /* Option-code */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_option_code, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Prefix Len */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_prefix_len, tvb, opt_offset, 1, FALSE); + prefix_len = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); + opt_offset += 4; + + /* IPv6 Address */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_ipa_ipv6_address, tvb, opt_offset, 16, FALSE); + opt_offset += 16; + + proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); - /* Prefix */ - switch(opt_len){ - case 8: /* Default Option Length without prefix */ - proto_item_append_text(ti, " ::/%d", prefix_len); break; - case 16: - memset(&prefix, 0, sizeof(prefix)); - tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8); - proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 8, prefix.bytes); - proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len); + } + case ND_OPT_NEW_ROUTER_PREFIX_INFO: /* New Router Prefix Information Option (18) OBSO... */ + { + + guint8 prefix_len; + + /* Option-code */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_option_code, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Prefix Len */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix_len, tvb, opt_offset, 1, FALSE); + prefix_len = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); + opt_offset += 4; + + /* Prefix */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_nrpi_prefix, tvb, opt_offset, 16, FALSE); + opt_offset += 16; + + proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); break; - case 24: - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + } + case ND_OPT_LINK_LAYER_ADDRESS: /* Link-layer Address Option (19) */ + { + /* Option-Code */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_option_code, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Link Layer Address */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_lla_bytes, tvb, opt_offset, opt_len-3, FALSE); break; - default: - expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); - break; } - break; - } + case ND_OPT_NEIGHBOR_ADV_ACK: /* Neighbor Advertisement Acknowledgment Option (20) */ + { + guint8 status; - case ND_OPT_RECURSIVE_DNS_SERVER: /* Recursive DNS Server Option (25) */ - { - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - /* RDNSS Lifetime */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss_lifetime, tvb, opt_offset, 4, FALSE); - /* A value of all one bits (0xffffffff) represents infinity. A value of - * zero means that the RDNSS address MUST no longer be used. - */ - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0: - proto_item_append_text(ti_opt, " (RDNSS address MUST no longer be used)"); + /* Option-Code */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_option_code, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Status */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_status, tvb, opt_offset, 1, FALSE); + status = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + if(status == 2){ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_naack_supplied_ncoa, tvb, opt_offset, 16, FALSE); + }else{ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, opt_len - 4, FALSE); + } break; - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); + } + case ND_OPT_MAP: /* MAP Option (23) */ + { + + /* Dist */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_dist, tvb, opt_offset, 1, FALSE); + + /* Pref */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_pref, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_map); + + proto_tree_add_item(flag_tree, hf_icmpv6_opt_map_flag_r, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_map_flag_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Valid Lifetime */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_valid_lifetime, tvb, opt_offset, 4, FALSE); + opt_offset += 4; + + /* Global Address */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_map_global_address, tvb, opt_offset, 16, FALSE); + opt_offset += 16; break; - default: + } + case ND_OPT_ROUTE_INFO: /* Route Information Option (24) */ + { + /* RFC 4191 */ + guint8 prefix_len; + guint8 route_preference; + struct e_in6_addr prefix; + + /* Prefix Len */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix_len, tvb, opt_offset, 1, FALSE); + prefix_len = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_route_info_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_route_info); + + proto_tree_add_item(flag_tree, hf_icmpv6_opt_route_info_flag_route_preference, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_route_info_flag_reserved, tvb, opt_offset, 1, FALSE); + + route_preference = tvb_get_guint8(tvb, opt_offset); + route_preference = (route_preference & ND_RA_FLAG_RTPREF_MASK) >> 3; + proto_item_append_text(ti, " : %s", val_to_str(route_preference, nd_flag_router_pref, "Unknown %d") ); + opt_offset += 1; + + /* Route Lifetime */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_route_lifetime, tvb, opt_offset, 4, FALSE); + + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; + } + opt_offset += 4; + + /* Prefix */ + switch(opt_len){ + case 8: /* Default Option Length without prefix */ + proto_item_append_text(ti, " ::/%d", prefix_len); + break; + case 16: + memset(&prefix, 0, sizeof(prefix)); + tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8); + proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 8, prefix.bytes); + proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len); + break; + case 24: + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + break; + default: + expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); + break; + } break; + } - opt_offset += 4; - - while(opt_offset < (offset + opt_len) ) { - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset)); - opt_offset += 16; - } - break; - } - case ND_OPT_FLAGS_EXTENSION: /* RA Flags Extension Option (26) */ - { - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_efo, tvb, opt_offset, 6, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_efo); - - proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_m, tvb, opt_offset, 2, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_o, tvb, opt_offset, 2, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_h, tvb, opt_offset, 2, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_prf, tvb, opt_offset, 2, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_p, tvb, opt_offset, 2, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_rsv, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - proto_tree_add_item(flag_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); - break; - } - case ND_OPT_HANDOVER_KEY_REQUEST: /* Handover Key Request Option (27) */ - { - int par_len; - guint padd_length; + case ND_OPT_RECURSIVE_DNS_SERVER: /* Recursive DNS Server Option (25) */ + { + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); + opt_offset += 2; - /* Pad Length */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, FALSE); - padd_length = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; + /* RDNSS Lifetime */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss_lifetime, tvb, opt_offset, 4, FALSE); + /* A value of all one bits (0xffffffff) represents infinity. A value of + * zero means that the RDNSS address MUST no longer be used. + */ + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0: + proto_item_append_text(ti_opt, " (RDNSS address MUST no longer be used)"); + break; + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; + } + opt_offset += 4; - /* AT */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, FALSE); + while(opt_offset < (offset + opt_len) ) { + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_rdnss, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset)); + opt_offset += 16; - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; + } + break; + } + case ND_OPT_FLAGS_EXTENSION: /* RA Flags Extension Option (26) */ + { + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_efo, tvb, opt_offset, 6, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_efo); + + proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_m, tvb, opt_offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_o, tvb, opt_offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_h, tvb, opt_offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_prf, tvb, opt_offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_p, tvb, opt_offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_efo_rsv, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + proto_tree_add_item(flag_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); + break; + } + case ND_OPT_HANDOVER_KEY_REQUEST: /* Handover Key Request Option (27) */ + { + int par_len; + guint padd_length; - /* Handover Key Encryption Public Key */ - par_len = opt_len-4-padd_length; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encryption_public_key, tvb, opt_offset, par_len, FALSE); - opt_offset += par_len; + /* Pad Length */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, FALSE); + padd_length = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; - /* Padding */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, FALSE); - opt_offset += 1; - break; - } - case ND_OPT_HANDOVER_KEY_REPLY: /* Handover Key Reply Option (28) */ - { - int par_len; - guint padd_length; + /* AT */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, FALSE); - /* Pad Length */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, FALSE); - padd_length = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; - /* AT */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, FALSE); + /* Handover Key Encryption Public Key */ + par_len = opt_len-4-padd_length; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encryption_public_key, tvb, opt_offset, par_len, FALSE); + opt_offset += par_len; - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; + /* Padding */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, FALSE); + opt_offset += 1; + break; + } + case ND_OPT_HANDOVER_KEY_REPLY: /* Handover Key Reply Option (28) */ + { + int par_len; + guint padd_length; - /* Lifetime */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_lifetime, tvb, opt_offset, 2, FALSE); - opt_offset += 2; + /* Pad Length */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_pad_length, tvb, opt_offset, 1, FALSE); + padd_length = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; - /* Encrypted Handover Key */ - par_len = opt_len-6-padd_length; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encrypted_handover_key, tvb, opt_offset, par_len, FALSE); - opt_offset += par_len; + /* AT */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, FALSE); - /* Padding */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, FALSE); - opt_offset += 1; - break; - } - case ND_OPT_HANDOVER_ASSIST_INFO: /* Handover Assist Information Option (29) */ - { - guint8 hai_len; - int padd_length; - /* Option-Code */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_option_code, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* HAI Length */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_length, tvb, opt_offset, 1, FALSE); - hai_len = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - /* HAI Value */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_value, tvb, opt_offset, hai_len, FALSE); - opt_offset += hai_len; - - /* Padding... */ - padd_length = opt_len - opt_offset; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; - break; - } - case ND_OPT_MOBILE_NODE_ID: /* Mobile Node Identifier Option (30) */ - { - guint8 mn_len; - int padd_length; - /* Option-Code */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_option_code, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* MN Length */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_length, tvb, opt_offset, 1, FALSE); - mn_len = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - /* MN Value */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_value, tvb, opt_offset, mn_len, FALSE); - opt_offset += mn_len; - - /* Padding... */ - padd_length = opt_len - opt_offset; - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); - break; - } - case ND_OPT_DNS_SEARCH_LIST: /* DNS Search List Option (31) */ - { - int dnssl_len; - const guchar *dnssl_name; + /* Lifetime */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_lifetime, tvb, opt_offset, 2, FALSE); + opt_offset += 2; - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); - opt_offset += 2; + /* Encrypted Handover Key */ + par_len = opt_len-6-padd_length; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_encrypted_handover_key, tvb, opt_offset, par_len, FALSE); + opt_offset += par_len; - /* DNSSL Lifetime */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_dnssl_lifetime, tvb, opt_offset, 4, FALSE); - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); + /* Padding */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_padding, tvb, opt_offset, padd_length, FALSE); + opt_offset += 1; break; - default: + } + case ND_OPT_HANDOVER_ASSIST_INFO: /* Handover Assist Information Option (29) */ + { + guint8 hai_len; + int padd_length; + /* Option-Code */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_option_code, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* HAI Length */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_length, tvb, opt_offset, 1, FALSE); + hai_len = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + /* HAI Value */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hai_value, tvb, opt_offset, hai_len, FALSE); + opt_offset += hai_len; + + /* Padding... */ + padd_length = opt_len - opt_offset; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); + break; } - opt_offset += 4; - while(opt_offset < (offset + opt_len) ) { - - if(tvb_get_guint8(tvb, opt_offset) == 0){ /* if Zero there is padding, skip the loop */ + case ND_OPT_MOBILE_NODE_ID: /* Mobile Node Identifier Option (30) */ + { + guint8 mn_len; + int padd_length; + /* Option-Code */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_option_code, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* MN Length */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_length, tvb, opt_offset, 1, FALSE); + mn_len = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + /* MN Value */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_mn_value, tvb, opt_offset, mn_len, FALSE); + opt_offset += mn_len; + + /* Padding... */ + padd_length = opt_len - opt_offset; + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_padding, tvb, opt_offset, padd_length, FALSE); break; + } + case ND_OPT_DNS_SEARCH_LIST: /* DNS Search List Option (31) */ + { + int dnssl_len; + const guchar *dnssl_name; + + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + /* DNSSL Lifetime */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_dnssl_lifetime, tvb, opt_offset, 4, FALSE); + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; } - dnssl_len = get_dns_name(tvb, opt_offset, 0, opt_offset, &dnssl_name); - proto_tree_add_string(icmp6opt_tree, hf_icmpv6_opt_dnssl, tvb, opt_offset, dnssl_len, dnssl_name); - proto_item_append_text(ti, " %s", dnssl_name); - opt_offset += dnssl_len; + opt_offset += 4; + while(opt_offset < (offset + opt_len) ) { - } - break; - } - case ND_OPT_6LOWPAN_CONTEXT: /* 6LoWPAN Context (32) */ - { - /* 6lowpan-ND */ - guint8 context_len; - struct e_in6_addr context_prefix; - - /* Context Length */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_length, tvb, opt_offset, 1, FALSE); - context_len = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - /* Flags & CID */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_6lowpan); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_c, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_cid, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_reserved, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - /* Lifetime */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_valid_lifetime, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - /* Context */ - switch(opt_len){ - case 8: /* Default Option Length without context prefix */ - proto_item_append_text(ti, " ::/%d", context_len); - break; - case 16: - memset(&context_prefix, 0, sizeof(context_prefix)); - tvb_memcpy(tvb, (guint8 *)&context_prefix.bytes, opt_offset, 8); - proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 8, context_prefix.bytes); - proto_item_append_text(ti, " %s/%d", ip6_to_str(&context_prefix), context_len); - break; - case 24: - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), context_len); + if(tvb_get_guint8(tvb, opt_offset) == 0){ /* if Zero there is padding, skip the loop */ + break; + } + dnssl_len = get_dns_name(tvb, opt_offset, 0, opt_offset, &dnssl_name); + proto_tree_add_string(icmp6opt_tree, hf_icmpv6_opt_dnssl, tvb, opt_offset, dnssl_len, dnssl_name); + proto_item_append_text(ti, " %s", dnssl_name); + opt_offset += dnssl_len; + + } break; - default: - expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); - break; } - } - break; - case ND_OPT_ADDR_RESOLUTION: /* Address Registration (TBD2 Pending IANA...) */ - { - /* 6lowpan-ND */ - guint8 status; - gchar *eui64; - - /* Status */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_status, tvb, opt_offset, 1, FALSE); - status = tvb_get_guint8(tvb, opt_offset); - opt_offset += 1; - - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 3, FALSE); - opt_offset += 3; - - /* Lifetime */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_registration_lifetime, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - /* EUI-64 */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_eui64, tvb, opt_offset, 8, FALSE); - eui64 = tvb_bytes_to_str_punct(tvb, opt_offset, 8, ':'); - proto_item_append_text(ti, " : Register %s %s", eui64, val_to_str(status, nd_opt_6lowpannd_status_val, "Unknown %d")); - opt_offset += 8; - - } - break; - case ND_OPT_AUTH_BORDER_ROUTER: /* Authoritative Border Router (33) */ - { - guint16 version; - - /* Version */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_abro_version, tvb, opt_offset, 2, FALSE); - version = tvb_get_ntohs(tvb, opt_offset); - opt_offset += 2; + case ND_OPT_6LOWPAN_CONTEXT: /* 6LoWPAN Context (32) */ + { + /* 6lowpan-ND */ + guint8 context_len; + struct e_in6_addr context_prefix; + + /* Context Length */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_length, tvb, opt_offset, 1, FALSE); + context_len = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; + + /* Flags & CID */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_flag_6lowpan); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_c, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_cid, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_opt_6co_flag_reserved, tvb, opt_offset, 1, FALSE); + opt_offset += 1; - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); - opt_offset += 4; + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + /* Lifetime */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_valid_lifetime, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + /* Context */ + switch(opt_len){ + case 8: /* Default Option Length without context prefix */ + proto_item_append_text(ti, " ::/%d", context_len); + break; + case 16: + memset(&context_prefix, 0, sizeof(context_prefix)); + tvb_memcpy(tvb, (guint8 *)&context_prefix.bytes, opt_offset, 8); + proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 8, context_prefix.bytes); + proto_item_append_text(ti, " %s/%d", ip6_to_str(&context_prefix), context_len); + break; + case 24: + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), context_len); + break; + default: + expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); + break; + } + } + break; + case ND_OPT_ADDR_RESOLUTION: /* Address Registration (TBD2 Pending IANA...) */ + { + /* 6lowpan-ND */ + guint8 status; + gchar *eui64; - /* 6LBR Address */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_abro_6lbr_address, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " : Version %d, 6LBR : %s", version, tvb_ip6_to_str(tvb, opt_offset)); - opt_offset += 16; + /* Status */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_status, tvb, opt_offset, 1, FALSE); + status = tvb_get_guint8(tvb, opt_offset); + opt_offset += 1; - } - break; + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 3, FALSE); + opt_offset += 3; - default : - expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE, "Dissector for ICMPv6 Option (%d) code not implemented, Contact Wireshark developers if you want this supported", opt_type); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_data, tvb, opt_offset, opt_len, FALSE); + /* Lifetime */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_registration_lifetime, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + /* EUI-64 */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_aro_eui64, tvb, opt_offset, 8, FALSE); + eui64 = tvb_bytes_to_str_punct(tvb, opt_offset, 8, ':'); + proto_item_append_text(ti, " : Register %s %s", eui64, val_to_str(status, nd_opt_6lowpannd_status_val, "Unknown %d")); + opt_offset += 8; + + } + break; + case ND_OPT_AUTH_BORDER_ROUTER: /* Authoritative Border Router (33) */ + { + guint16 version; + + /* Version */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_abro_version, tvb, opt_offset, 2, FALSE); + version = tvb_get_ntohs(tvb, opt_offset); + opt_offset += 2; + + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); + opt_offset += 4; + + /* 6LBR Address */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_abro_6lbr_address, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " : Version %d, 6LBR : %s", version, tvb_ip6_to_str(tvb, opt_offset)); + opt_offset += 16; + + } break; - } /* switch (opt_type) */ + default : + expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE, + "Dissector for ICMPv6 Option (%d)" + " code not implemented, Contact Wireshark developers" + " if you want this supported", opt_type); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_data, tvb, opt_offset, opt_len, FALSE); + break; + + } /* switch (opt_type) */ offset += opt_len; - /* Close the ) to option root label */ - proto_item_append_text(ti, ")"); + /* Close the ) to option root label */ + proto_item_append_text(ti, ")"); } } @@ -1898,306 +1901,309 @@ dissect_icmpv6_rpl_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree int opt_offset; while ((int)tvb_reported_length(tvb) > offset) { - /* there are more options */ + /* there are more options */ - /* ICMPv6 RPL Option */ - ti = proto_tree_add_item(tree, hf_icmpv6_rpl_opt, tvb, offset, 1, FALSE); - icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_rpl_opt); + /* ICMPv6 RPL Option */ + ti = proto_tree_add_item(tree, hf_icmpv6_rpl_opt, tvb, offset, 1, FALSE); + icmp6opt_tree = proto_item_add_subtree(ti, ett_icmpv6_rpl_opt); opt_offset = offset; - /* Option type */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_type, tvb, opt_offset, 1, FALSE); + /* Option type */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_type, tvb, opt_offset, 1, FALSE); opt_type = tvb_get_guint8(tvb, opt_offset); opt_offset += 1; - /* Add option name to option root label */ - proto_item_append_text(ti, " (%s", val_to_str(opt_type, rpl_option_vals, "Unknown %d")); + /* Add option name to option root label */ + proto_item_append_text(ti, " (%s", val_to_str(opt_type, rpl_option_vals, "Unknown %d")); - /* The Pad1 option is a special case, and contains no data. */ - if (opt_type == RPL_OPT_PAD1) { - offset += 1; - proto_item_append_text(ti, ")"); - continue; - } + /* The Pad1 option is a special case, and contains no data. */ + if (opt_type == RPL_OPT_PAD1) { + offset += 1; + proto_item_append_text(ti, ")"); + continue; + } - /* Option length */ - ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_length, tvb, opt_offset, 1, FALSE); - opt_len = tvb_get_guint8(tvb, opt_offset); - proto_item_set_len(ti, opt_len + 2); + /* Option length */ + ti_opt_len = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_length, tvb, opt_offset, 1, FALSE); + opt_len = tvb_get_guint8(tvb, opt_offset); + proto_item_set_len(ti, opt_len + 2); opt_offset += 1; - /* decode... */ - switch (opt_type) { - case RPL_OPT_PADN: - /* n-byte padding */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_padn, tvb, opt_offset, opt_len, FALSE); - proto_item_append_text(ti_opt, " (Length : %i bytes)", opt_len); - break; - - case RPL_OPT_METRIC: - /* DAG metric container */ - /* See draft-ietf-roll-routing-metrics for formatting. */ - break; - case RPL_OPT_ROUTING: { - guint8 prefix_len; - struct e_in6_addr prefix; - - /* Prefix length */ - prefix_len = tvb_get_guint8(tvb, opt_offset); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix_length, tvb, opt_offset, 1, FALSE); - opt_offset +=1; - - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_routing); - - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_pref, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_reserved, tvb, opt_offset, 1, FALSE); - opt_offset +=1; - - /* Prefix lifetime. */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_lifetime, tvb, opt_offset, 4, FALSE); - - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); - break; - default: - break; - } - opt_offset += 4; - - switch(opt_len){ - case 6: /* Default Option Length without prefix */ - proto_item_append_text(ti, " ::/%d", prefix_len); + /* decode... */ + switch (opt_type) { + case RPL_OPT_PADN: + /* n-byte padding */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_padn, tvb, opt_offset, opt_len, FALSE); + proto_item_append_text(ti_opt, " (Length : %i bytes)", opt_len); break; - case 14: - memset(&prefix, 0, sizeof(prefix)); - tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8); - proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 8, prefix.bytes); - proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len); + + case RPL_OPT_METRIC: + /* DAG metric container */ + /* See draft-ietf-roll-routing-metrics for formatting. */ break; - case 22: - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + case RPL_OPT_ROUTING: { + guint8 prefix_len; + struct e_in6_addr prefix; + + /* Prefix length */ + prefix_len = tvb_get_guint8(tvb, opt_offset); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix_length, tvb, opt_offset, 1, FALSE); + opt_offset +=1; + + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_routing); + + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_pref, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_route_reserved, tvb, opt_offset, 1, FALSE); + opt_offset +=1; + + /* Prefix lifetime. */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_lifetime, tvb, opt_offset, 4, FALSE); + + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; + } + opt_offset += 4; + + switch(opt_len){ + case 6: /* Default Option Length without prefix */ + proto_item_append_text(ti, " ::/%d", prefix_len); + break; + case 14: + memset(&prefix, 0, sizeof(prefix)); + tvb_memcpy(tvb, (guint8 *)&prefix.bytes, opt_offset, 8); + proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 8, prefix.bytes); + proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len); + break; + case 22: + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + break; + default: + expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); + break; + } break; - default: - expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); - break; - } - break; } - case RPL_OPT_CONFIG: { - - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_config); - - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_reserved, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_auth, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_pcs, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* DIOIntervalDoublings */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_doublings, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* DIOIntervalMin */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_min_interval, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* DIORedundancyConstant */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_redundancy, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* MaxRankIncrease */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rank_incr, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - /* MinHopRankInc */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_hop_rank_inc, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - /* OCP */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_ocp, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - - /* Reserved */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rsv, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Default Lifetime */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_def_lifetime, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Lifetime Unit */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_lifetime_unit, tvb, opt_offset, 2, FALSE); - opt_offset += 2; - break; - } - case RPL_OPT_TARGET: { - guint8 prefix_len; - struct e_in6_addr target_prefix; + case RPL_OPT_CONFIG: { - /* Flag */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_flag, tvb, opt_offset, 1, FALSE); - opt_offset += 1; + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_config); - /* Prefix length */ - prefix_len = tvb_get_guint8(tvb, opt_offset); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix_length, tvb, opt_offset, 1, FALSE); - opt_offset += 1; + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_reserved, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_auth, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_config_pcs, tvb, opt_offset, 1, FALSE); + opt_offset += 1; - /* Target Prefix */ + /* DIOIntervalDoublings */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_doublings, tvb, opt_offset, 1, FALSE); + opt_offset += 1; - switch(opt_len){ - case 2: /* Default Option Length without prefix */ - proto_item_append_text(ti, " ::/%d", prefix_len); - break; - case 10: - memset(&target_prefix, 0, sizeof(target_prefix)); - tvb_memcpy(tvb, (guint8 *)&target_prefix.bytes, opt_offset, 8); - proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 8, target_prefix.bytes); - proto_item_append_text(ti, " %s/%d", ip6_to_str(&target_prefix), prefix_len); - break; - case 18: - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + /* DIOIntervalMin */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_min_interval, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* DIORedundancyConstant */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_redundancy, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* MaxRankIncrease */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rank_incr, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + /* MinHopRankInc */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_hop_rank_inc, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + /* OCP */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_ocp, tvb, opt_offset, 2, FALSE); + opt_offset += 2; + + /* Reserved */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_rsv, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Default Lifetime */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_def_lifetime, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Lifetime Unit */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_config_lifetime_unit, tvb, opt_offset, 2, FALSE); + opt_offset += 2; break; - default: - expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); - break; } - break; - } - case RPL_OPT_TRANSIT: { - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_transit); - - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_transit_flag_e, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_transit_flag_rsv, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Path Control */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathctl, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Path Sequence */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathseq, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Path Lifetime */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathlifetime, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Option contains parent */ - if(opt_len > 4) - { - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_parent, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset)); - opt_offset += 16; - } - - break; - } - case RPL_OPT_SOLICITED: { - - /*Instance ID */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_instance, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_solicited); - - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_v, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_i, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_d, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_rsv, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* DODAG ID */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_dodagid, tvb, opt_offset, 16, FALSE); - opt_offset += 16; - - /* Version Number */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_version, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - break; - } - case RPL_OPT_PREFIX: { - /* Destination prefix option. */ - guint8 prefix_len; - - /* Prefix length */ - prefix_len = tvb_get_guint8(tvb, opt_offset); - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_length, tvb, opt_offset, 1, FALSE); - opt_offset +=1; - - /* Flags */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_flag, tvb, opt_offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_prefix); - - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_l, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_a, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_r, tvb, opt_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_rsv, tvb, opt_offset, 1, FALSE); - opt_offset += 1; - - /* Valid lifetime. */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_vlifetime, tvb, opt_offset, 4, FALSE); - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); - break; - default: + case RPL_OPT_TARGET: { + guint8 prefix_len; + struct e_in6_addr target_prefix; + + /* Flag */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_flag, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Prefix length */ + prefix_len = tvb_get_guint8(tvb, opt_offset); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix_length, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Target Prefix */ + + switch(opt_len){ + case 2: /* Default Option Length without prefix */ + proto_item_append_text(ti, " ::/%d", prefix_len); + break; + case 10: + memset(&target_prefix, 0, sizeof(target_prefix)); + tvb_memcpy(tvb, (guint8 *)&target_prefix.bytes, opt_offset, 8); + proto_tree_add_ipv6(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 8, target_prefix.bytes); + proto_item_append_text(ti, " %s/%d", ip6_to_str(&target_prefix), prefix_len); + break; + case 18: + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + break; + default: + expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); + break; + } break; } - opt_offset += 4; + case RPL_OPT_TRANSIT: { + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_transit); + + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_transit_flag_e, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_transit_flag_rsv, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Path Control */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathctl, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Path Sequence */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathseq, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Path Lifetime */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_pathlifetime, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Option contains parent */ + if(opt_len > 4) + { + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_transit_parent, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s", tvb_ip6_to_str(tvb, opt_offset)); + opt_offset += 16; + } - /* Preferrred Lifetime */ - ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_plifetime, tvb, opt_offset, 4, FALSE); - switch(tvb_get_ntohl(tvb, opt_offset)){ - case 0xffffffff: - proto_item_append_text(ti_opt, " (Infinity)"); break; - default: + } + case RPL_OPT_SOLICITED: { + + /*Instance ID */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_instance, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_solicited); + + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_v, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_i, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_d, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_solicited_flag_rsv, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* DODAG ID */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_dodagid, tvb, opt_offset, 16, FALSE); + opt_offset += 16; + + /* Version Number */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_solicited_version, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + break; } - opt_offset += 4; + case RPL_OPT_PREFIX: { + /* Destination prefix option. */ + guint8 prefix_len; + + /* Prefix length */ + prefix_len = tvb_get_guint8(tvb, opt_offset); + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_length, tvb, opt_offset, 1, FALSE); + opt_offset +=1; + + /* Flags */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_flag, tvb, opt_offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_opt, ett_icmpv6_rpl_flag_prefix); + + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_l, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_a, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_r, tvb, opt_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_opt_prefix_flag_rsv, tvb, opt_offset, 1, FALSE); + opt_offset += 1; + + /* Valid lifetime. */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_vlifetime, tvb, opt_offset, 4, FALSE); + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; + } + opt_offset += 4; + + /* Preferrred Lifetime */ + ti_opt = proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix_plifetime, tvb, opt_offset, 4, FALSE); + switch(tvb_get_ntohl(tvb, opt_offset)){ + case 0xffffffff: + proto_item_append_text(ti_opt, " (Infinity)"); + break; + default: + break; + } + opt_offset += 4; - /* 4 reserved bytes. */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_reserved, tvb, opt_offset, 4, FALSE); - opt_offset += 4; + /* 4 reserved bytes. */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_reserved, tvb, opt_offset, 4, FALSE); + opt_offset += 4; - /* Prefix */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix, tvb, opt_offset, 16, FALSE); - proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); - opt_offset += 16; + /* Prefix */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix, tvb, opt_offset, 16, FALSE); + proto_item_append_text(ti, " %s/%d", tvb_ip6_to_str(tvb, opt_offset), prefix_len); + opt_offset += 16; - break; - } + break; + } - case RPL_OPT_TARGETDESC: { + case RPL_OPT_TARGETDESC: { - /* Descriptor */ - proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_targetdesc, tvb, opt_offset, 4, FALSE); - opt_offset += 4; - break; - } - default : - expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE, "Dissector for ICMPv6 RPL Option (%d) code not implemented, Contact Wireshark developers if you want this supported", opt_type); + /* Descriptor */ + proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_targetdesc, tvb, opt_offset, 4, FALSE); + opt_offset += 4; + break; + } + default : + expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE, + "Dissector for ICMPv6 RPL Option" + " (%d) code not implemented, Contact" + " Wireshark developers if you want this supported", opt_type); proto_tree_add_item(icmp6opt_tree, hf_icmpv6_data, tvb, opt_offset, opt_len, FALSE); - break; - } /* switch (opt_type) */ + break; + } /* switch (opt_type) */ offset += opt_len + 2; - /* Close the ) to option root label */ - proto_item_append_text(ti, ")"); - } + /* Close the ) to option root label */ + proto_item_append_text(ti, ")"); + } /* while */ } static void @@ -2214,25 +2220,25 @@ dissect_rpl_control(tvbuff_t *tvb, int rpl_offset, packet_info *pinfo _U_, proto /* Flags */ ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_flag, tvb, rpl_offset, 1, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_secure); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_flag_t, tvb, rpl_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_flag_rsv, tvb, rpl_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_flag_t, tvb, rpl_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_flag_rsv, tvb, rpl_offset, 1, FALSE); rpl_offset += 1; /* Algorithm */ ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_algorithm, tvb, rpl_offset, 1, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_secure); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_algorithm_encryption, tvb, rpl_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_algorithm_signature, tvb, rpl_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_algorithm_encryption, tvb, rpl_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_algorithm_signature, tvb, rpl_offset, 1, FALSE); rpl_offset += 1; - /* KIM & LVL */ + /* KIM & LVL */ ti = proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_secure_flag, tvb, rpl_offset, 1, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6_flag_secure); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_kim, tvb, rpl_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_lvl, tvb, rpl_offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_rsv, tvb, rpl_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_kim, tvb, rpl_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_lvl, tvb, rpl_offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_rpl_secure_rsv, tvb, rpl_offset, 1, FALSE); kim = tvb_get_guint8(tvb, rpl_offset) & RPL_SECURE_KIM >> 6; - lvl = tvb_get_guint8(tvb, rpl_offset) & RPL_SECURE_LVL; + lvl = tvb_get_guint8(tvb, rpl_offset) & RPL_SECURE_LVL; rpl_offset += 1; /* Flags */ @@ -2323,7 +2329,7 @@ dissect_rpl_control(tvbuff_t *tvb, int rpl_offset, packet_info *pinfo _U_, proto proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_dtsn, tvb, rpl_offset, 1, FALSE); rpl_offset += 1; - /* Flags */ + /* Flags */ proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_dio_flag, tvb, rpl_offset, 1, FALSE); rpl_offset += 1; @@ -2433,13 +2439,13 @@ dissect_rpl_control(tvbuff_t *tvb, int rpl_offset, packet_info *pinfo _U_, proto /* Destination Counter */ proto_tree_add_item(icmp6_tree, hf_icmpv6_rpl_cc_destination_counter, tvb, rpl_offset, 4, FALSE); - rpl_offset += 4; + rpl_offset += 4; /* Options */ dissect_icmpv6_rpl_opt(tvb, rpl_offset, pinfo, icmp6_tree); break; } - + } } /* RFC 4620 - IPv6 Node Information Queries */ @@ -2467,11 +2473,11 @@ dissect_nodeinfo(tvbuff_t *tvb, int ni_offset, packet_info *pinfo _U_, proto_tre proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_t, tvb, ni_offset, 2, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_rsv, tvb, ni_offset, 2, FALSE); ni_offset += 2; - + /* Nonce */ proto_tree_add_item(tree, hf_icmpv6_ni_nonce, tvb, ni_offset, 8, FALSE); ni_offset += 8; - + /* Data ? */ if(tvb_reported_length_remaining(tvb, ni_offset) == 0){ return; @@ -2479,73 +2485,73 @@ dissect_nodeinfo(tvbuff_t *tvb, int ni_offset, packet_info *pinfo _U_, proto_tre if(icmp6_type == ICMP6_NI_QUERY){ switch(icmp6_code){ - case ICMP6_NI_SUBJ_IPV6: { - proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv6, tvb, ni_offset, 16, FALSE); - ni_offset += 16; - break; - } - case ICMP6_NI_SUBJ_FQDN: { - int fqdn_len; - const guchar *fqdn_name; - fqdn_len = get_dns_name(tvb, ni_offset, 0, ni_offset, &fqdn_name); - proto_tree_add_string(tree, hf_icmpv6_ni_query_subject_fqdn, tvb, ni_offset, fqdn_len, fqdn_name); - ni_offset += fqdn_len; - break; - } - case ICMP6_NI_SUBJ_IPV4: { - proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv4, tvb, ni_offset, 4, FALSE); - ni_offset += 4; - break; - } - } - } else { /* It is ICMP6_NI_REPLY */ - switch(qtype){ - case NI_QTYPE_NOOP: - break; - case NI_QTYPE_NODENAME: { - int node_len; - const guchar *node_name; - /* TTL */ - proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, FALSE); - ni_offset += 4; - /* Data ? */ - if(tvb_reported_length_remaining(tvb, ni_offset) == 0){ - return; + case ICMP6_NI_SUBJ_IPV6: { + proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv6, tvb, ni_offset, 16, FALSE); + ni_offset += 16; + break; } - while(ni_offset < (int)tvb_reported_length(tvb) ) { - - if(tvb_get_guint8(tvb, ni_offset) == 0){ /* if Zero there is padding, skip the loop */ - break; - } - /* Node Name */ - node_len = get_dns_name(tvb, ni_offset, 0, ni_offset, &node_name); - proto_tree_add_string(tree, hf_icmpv6_ni_reply_node_name, tvb, ni_offset, node_len, node_name); - ni_offset += node_len; + case ICMP6_NI_SUBJ_FQDN: { + int fqdn_len; + const guchar *fqdn_name; + fqdn_len = get_dns_name(tvb, ni_offset, 0, ni_offset, &fqdn_name); + proto_tree_add_string(tree, hf_icmpv6_ni_query_subject_fqdn, tvb, ni_offset, fqdn_len, fqdn_name); + ni_offset += fqdn_len; + break; + } + case ICMP6_NI_SUBJ_IPV4: { + proto_tree_add_item(tree, hf_icmpv6_ni_query_subject_ipv4, tvb, ni_offset, 4, FALSE); + ni_offset += 4; + break; } - break; } - case NI_QTYPE_NODEADDR: { - while(ni_offset < (int)tvb_reported_length(tvb) ) { + } else { /* It is ICMP6_NI_REPLY */ + switch(qtype){ + case NI_QTYPE_NOOP: + break; + case NI_QTYPE_NODENAME: { + int node_len; + const guchar *node_name; /* TTL */ proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, FALSE); ni_offset += 4; - /* Node Addresses */ - proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_address, tvb, ni_offset, 16, FALSE); - ni_offset += 16; + /* Data ? */ + if(tvb_reported_length_remaining(tvb, ni_offset) == 0){ + return; + } + while(ni_offset < (int)tvb_reported_length(tvb) ) { + + if(tvb_get_guint8(tvb, ni_offset) == 0){ /* if Zero there is padding, skip the loop */ + break; + } + /* Node Name */ + node_len = get_dns_name(tvb, ni_offset, 0, ni_offset, &node_name); + proto_tree_add_string(tree, hf_icmpv6_ni_reply_node_name, tvb, ni_offset, node_len, node_name); + ni_offset += node_len; + } + break; } - break; - } - case NI_QTYPE_IPV4ADDR: { - while(ni_offset < (int)tvb_reported_length(tvb) ) { - /* TTL */ - proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, FALSE); - ni_offset += 4; - /* IPv4 Address */ - proto_tree_add_item(tree, hf_icmpv6_ni_reply_ipv4_address, tvb, ni_offset, 4, FALSE); - ni_offset += 4; + case NI_QTYPE_NODEADDR: { + while(ni_offset < (int)tvb_reported_length(tvb) ) { + /* TTL */ + proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, FALSE); + ni_offset += 4; + /* Node Addresses */ + proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_address, tvb, ni_offset, 16, FALSE); + ni_offset += 16; + } + break; + } + case NI_QTYPE_IPV4ADDR: { + while(ni_offset < (int)tvb_reported_length(tvb) ) { + /* TTL */ + proto_tree_add_item(tree, hf_icmpv6_ni_reply_node_ttl, tvb, ni_offset, 4, FALSE); + ni_offset += 4; + /* IPv4 Address */ + proto_tree_add_item(tree, hf_icmpv6_ni_reply_ipv4_address, tvb, ni_offset, 4, FALSE); + ni_offset += 4; + } + break; } - break; - } } } } @@ -2604,39 +2610,39 @@ dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree /* 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; + rr_offset += 1; /* Ordinal */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_ordinal, tvb, rr_offset, 1, FALSE); - rr_offset += 1; + 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; + 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; + 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; + rr_offset += 1; /* Reserved */ proto_tree_add_item(mp_tree, hf_icmpv6_reserved, tvb, rr_offset, 2, FALSE); - rr_offset += 2; + rr_offset += 2; /* Match Prefix */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchprefix, tvb, rr_offset, 16, FALSE); - rr_offset += 16; + 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"), tvb_ip6_to_str(tvb, rr_offset), matchlen, minlen, maxlen); - while ((int)tvb_reported_length(tvb) > rr_offset) { + while ((int)tvb_reported_length(tvb) > rr_offset) { /* Use-Prefix Part */ guint8 uselen, keeplen; @@ -2651,7 +2657,7 @@ dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree /* 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; + rr_offset += 1; /* FlagMask */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flagmask, tvb, rr_offset, 1, FALSE); @@ -2659,7 +2665,7 @@ dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree 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; + rr_offset += 1; /* RaFlags */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_raflags, tvb, rr_offset, 1, FALSE); @@ -2667,13 +2673,13 @@ dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree 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; + 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)"); + proto_item_append_text(ti, " (Infinity)"); break; default: break; @@ -2684,12 +2690,12 @@ dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree 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)"); + proto_item_append_text(ti, " (Infinity)"); break; default: break; } - rr_offset += 4; + rr_offset += 4; /* Flags */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flag, tvb, rr_offset, 4, FALSE); @@ -2697,20 +2703,20 @@ dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree 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; + rr_offset += 4; /* UsePrefix */ proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_useprefix, tvb, rr_offset, 16, FALSE); - rr_offset += 16; + rr_offset += 16; /* Add Info (Prefix, Length...) to Use Prefix Part label */ proto_item_append_text(ti_up, ": %s/%u (keep %u)", tvb_ip6_to_str(tvb, rr_offset), uselen, keeplen); } - + }else if(icmp6_code == ICMP6_ROUTER_RENUMBERING_RESULT){ - while ((int)tvb_reported_length(tvb) > rr_offset) { + while ((int)tvb_reported_length(tvb) > rr_offset) { guint8 matchlen; - guint32 interfaceindex; + guint32 interfaceindex; /* Result Message */ ti_rm = proto_tree_add_item(tree, hf_icmpv6_rr_rm, tvb, rr_offset, 24, FALSE); @@ -2724,21 +2730,21 @@ dissect_rrenum(tvbuff_t *tvb, int rr_offset, packet_info *pinfo _U_, proto_tree proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_reserved, tvb, rr_offset, 2, FALSE); rr_offset +=2; - /* Ordinal */ + /* Ordinal */ proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_ordinal, tvb, rr_offset, 1, FALSE); rr_offset +=1; - /* MatchLen */ + /* 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 */ + /* 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 */ + /* MatchedPrefix */ proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedprefix, tvb, rr_offset, 16, FALSE); rr_offset +=16; @@ -2775,7 +2781,7 @@ dissect_mldrv2( tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tre ti_mar = proto_tree_add_item(tree, hf_icmpv6_mldr_mar, tvb, mldr_offset, -1, FALSE); mar_tree = proto_item_add_subtree(ti_mar, ett_icmpv6_mar); - + /* Record Type */ proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_record_type, tvb, mldr_offset, 1, FALSE); record_type = tvb_get_guint8(tvb, mldr_offset); @@ -2795,13 +2801,13 @@ dissect_mldrv2( tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tre proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_multicast_address, tvb, mldr_offset, 16, FALSE); tvb_get_ipv6(tvb, mldr_offset, &multicast_address); mldr_offset += 16; - + /* Source Address */ - for (i=1; i <= nb_sources; i++){ + for (i=1; i <= nb_sources; i++){ proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_source_address, tvb, mldr_offset, 16, FALSE); mldr_offset += 16; } - + /* Auxiliary Data ? */ if(aux_data_len) { @@ -2840,7 +2846,7 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) ti = proto_tree_add_item(tree, proto_icmpv6, tvb, offset, -1, FALSE); icmp6_tree = proto_item_add_subtree(ti, ett_icmpv6); - /* Type */ + /* Type */ proto_tree_add_item(icmp6_tree, hf_icmpv6_type, tvb, offset, 1, FALSE); } icmp6_type = tvb_get_guint8(tvb, offset); @@ -2849,7 +2855,7 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) col_add_str(pinfo->cinfo, COL_INFO, val_to_str(icmp6_type, icmpv6_type_val, "Unknown (%d)")); if (tree) { - /* Code */ + /* Code */ code_item = proto_tree_add_item(icmp6_tree, hf_icmpv6_code, tvb, offset, 1, FALSE); } @@ -2857,27 +2863,27 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) offset += 1; switch (icmp6_type) { - case ICMP6_DST_UNREACH: - code_name = val_to_str(icmp6_code, icmpv6_unreach_code_val, "Unknown"); - break; - case ICMP6_TIME_EXCEEDED: - code_name = val_to_str(icmp6_code, icmpv6_timeex_code_val, "Unknown (%d)"); - break; - case ICMP6_PARAM_PROB: - code_name = val_to_str(icmp6_code, icmpv6_paramprob_code_val, "Unknown (%d)"); - break; - case ICMP6_ROUTER_RENUMBERING: - code_name = val_to_str(icmp6_code, icmpv6_rr_code_val, "Unknown (%d)"); - break; - case ICMP6_NI_QUERY: - code_name = val_to_str(icmp6_code, ni_query_code_val, "Unknown (%d)"); - break; - case ICMP6_NI_REPLY: - code_name = val_to_str(icmp6_code, ni_reply_code_val, "Unknown (%d)"); - break; - case ICMP6_RPL_CONTROL: - code_name = val_to_str(icmp6_code, rpl_code_val, "Unknown (%d)"); - break; + case ICMP6_DST_UNREACH: + code_name = val_to_str(icmp6_code, icmpv6_unreach_code_val, "Unknown"); + break; + case ICMP6_TIME_EXCEEDED: + code_name = val_to_str(icmp6_code, icmpv6_timeex_code_val, "Unknown (%d)"); + break; + case ICMP6_PARAM_PROB: + code_name = val_to_str(icmp6_code, icmpv6_paramprob_code_val, "Unknown (%d)"); + break; + case ICMP6_ROUTER_RENUMBERING: + code_name = val_to_str(icmp6_code, icmpv6_rr_code_val, "Unknown (%d)"); + break; + case ICMP6_NI_QUERY: + code_name = val_to_str(icmp6_code, ni_query_code_val, "Unknown (%d)"); + break; + case ICMP6_NI_REPLY: + code_name = val_to_str(icmp6_code, ni_reply_code_val, "Unknown (%d)"); + break; + case ICMP6_RPL_CONTROL: + code_name = val_to_str(icmp6_code, rpl_code_val, "Unknown (%d)"); + break; } if(code_name) @@ -2928,456 +2934,460 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) PROTO_ITEM_SET_GENERATED(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, PI_CHECKSUM, PI_WARN, "ICMPv6 Checksum Incorrect, should be 0x%04x",in_cksum_shouldbe(cksum, computed_cksum)); + expert_add_info_format(pinfo, checksum_item, PI_CHECKSUM, PI_WARN, + "ICMPv6 Checksum Incorrect, should be 0x%04x", in_cksum_shouldbe(cksum, computed_cksum)); } } - + offset +=2; /* decode... */ switch (icmp6_type) { - case ICMP6_DST_UNREACH: /* Destination Unreachable (1) */ - case ICMP6_TIME_EXCEEDED: /* Time Exceeded (3) */ - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); - offset += 4; - - dissect_contained_icmpv6(tvb, offset, 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, FALSE); - offset += 4; + case ICMP6_DST_UNREACH: /* Destination Unreachable (1) */ + case ICMP6_TIME_EXCEEDED: /* Time Exceeded (3) */ + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); + offset += 4; - dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree); - break; - case ICMP6_PARAM_PROB: /* Parameter Problem (4) */ - /* MTU */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_pointer, tvb, offset, 4, FALSE); - offset += 4; + dissect_contained_icmpv6(tvb, offset, 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, FALSE); + offset += 4; - dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree); - break; - case ICMP6_ECHO_REQUEST: /* Echo Request (128) */ - case ICMP6_ECHO_REPLY: /* Echo Reply (129) */ - { - guint16 identifier, sequence; - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_identifier, tvb, offset, 2, FALSE); - identifier = tvb_get_ntohs(tvb, offset); - offset += 2; - - /* Sequence Number */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_sequence_number, tvb, offset, 2, FALSE); - sequence = tvb_get_ntohs(tvb, offset); - offset += 2; - - col_append_fstr(pinfo->cinfo, COL_INFO, " id=0x%04x, seq=%u", identifier, sequence); - - if (pinfo->destport == 0x0dd8 && icmp6_type == ICMP6_ECHO_REQUEST) { - /* RFC 4380 - * 5.2.9. Direct IPv6 Connectivity Test - */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_nonce, tvb, offset, 4, FALSE); + dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree); + break; + case ICMP6_PARAM_PROB: /* Parameter Problem (4) */ + /* MTU */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_pointer, tvb, offset, 4, FALSE); offset += 4; - } else { - next_tvb = tvb_new_subset(tvb, offset, -1, -1); - call_dissector(data_handle,next_tvb, pinfo, icmp6_tree); - } - break; - } - case ICMP6_MEMBERSHIP_QUERY: /* Multicast Listener Query (130) */ - case ICMP6_MEMBERSHIP_REPORT: /* Multicast Listener Report (131) */ - case ICMP6_MEMBERSHIP_REDUCTION: /* Multicast Listener Done (132) */ - { - /* It is MLDv2 packet ? (the min length for a MLDv2 packet is 28) */ - if ((icmp6_type == ICMP6_MEMBERSHIP_QUERY) && (length >= MLDV2_PACKET_MINLEN)) { - guint32 mrc; - guint16 qqi, i, nb_sources; - - /* Maximum Response Code */ - mrc = tvb_get_ntohs(tvb, offset); - if (mrc >= 32768){ - mrc = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3); - } - proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_mrc, tvb, offset, 2, mrc); - offset += 2; - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); + dissect_contained_icmpv6(tvb, offset, pinfo, icmp6_tree); + break; + case ICMP6_ECHO_REQUEST: /* Echo Request (128) */ + case ICMP6_ECHO_REPLY: /* Echo Reply (129) */ + { + guint16 identifier, sequence; + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_identifier, tvb, offset, 2, FALSE); + identifier = tvb_get_ntohs(tvb, offset); offset += 2; - /* Multicast Address */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, FALSE); - offset += 16; + /* Sequence Number */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_echo_sequence_number, tvb, offset, 2, FALSE); + sequence = tvb_get_ntohs(tvb, offset); + offset += 2; - /* Flag */ - ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_flag, tvb, offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_mld); - proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_s, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_qrv, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_rsv, tvb, offset, 1, FALSE); - offset += 1; - - /* QQI */ - qqi = tvb_get_guint8(tvb, offset); - if (qqi >= 128){ - qqi = ((qqi & 0x0f) | 0x10) << (((qqi & 0x70) >> 4) + 3); + col_append_fstr(pinfo->cinfo, COL_INFO, " id=0x%04x, seq=%u", identifier, sequence); + + if (pinfo->destport == 0x0dd8 && icmp6_type == ICMP6_ECHO_REQUEST) { + /* RFC 4380 + * 5.2.9. Direct IPv6 Connectivity Test + */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_nonce, tvb, offset, 4, FALSE); + offset += 4; + } else { + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + call_dissector(data_handle,next_tvb, pinfo, icmp6_tree); } - proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_qqi, tvb, offset, 1, qqi); - offset += 1; + break; + } + case ICMP6_MEMBERSHIP_QUERY: /* Multicast Listener Query (130) */ + case ICMP6_MEMBERSHIP_REPORT: /* Multicast Listener Report (131) */ + case ICMP6_MEMBERSHIP_REDUCTION: /* Multicast Listener Done (132) */ + { + /* It is MLDv2 packet ? (the min length for a MLDv2 packet is 28) */ + if ((icmp6_type == ICMP6_MEMBERSHIP_QUERY) && (length >= MLDV2_PACKET_MINLEN)) { + guint32 mrc; + guint16 qqi, i, nb_sources; + + /* Maximum Response Code */ + mrc = tvb_get_ntohs(tvb, offset); + if (mrc >= 32768){ + mrc = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3); + } + proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_mrc, tvb, offset, 2, mrc); + offset += 2; - /* Number of Sources */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_nb_sources, tvb, offset, 2, FALSE); - nb_sources = tvb_get_ntohs(tvb, offset); - offset += 2; + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); + offset += 2; - /* Source Address */ - for (i=1; i <= nb_sources; i++){ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_source_address, tvb, offset, 16, FALSE); + /* Multicast Address */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, FALSE); offset += 16; - } - - }else{ /* It is a MLDv1 Packet */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_mrd, tvb, offset, 2, FALSE); - offset += 2; + /* Flag */ + ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_flag, tvb, offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_mld); + proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_s, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_qrv, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_mld_flag_rsv, tvb, offset, 1, FALSE); + offset += 1; + + /* QQI */ + qqi = tvb_get_guint8(tvb, offset); + if (qqi >= 128){ + qqi = ((qqi & 0x0f) | 0x10) << (((qqi & 0x70) >> 4) + 3); + } + proto_tree_add_uint(icmp6_tree, hf_icmpv6_mld_qqi, tvb, offset, 1, qqi); + offset += 1; + + /* Number of Sources */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_nb_sources, tvb, offset, 2, FALSE); + nb_sources = tvb_get_ntohs(tvb, offset); + offset += 2; + + /* Source Address */ + for (i=1; i <= nb_sources; i++){ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_source_address, tvb, offset, 16, FALSE); + offset += 16; + } + + }else{ /* It is a MLDv1 Packet */ + + proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_mrd, tvb, offset, 2, FALSE); + offset += 2; - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); - offset += 2; + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); + offset += 2; - /* Multicast Address */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, FALSE); - offset += 16; + /* Multicast Address */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, FALSE); + offset += 16; + } + break; } - break; - } - case ICMP6_ND_ROUTER_SOLICIT: /* Router Solicitation (133) */ - { - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); - offset += 4; + case ICMP6_ND_ROUTER_SOLICIT: /* Router Solicitation (133) */ + { + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); + offset += 4; - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_ND_ROUTER_ADVERT: /* Router Advertisement (134) */ - { + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_ND_ROUTER_ADVERT: /* Router Advertisement (134) */ + { - /* Current hop limit */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_cur_hop_limit, tvb, offset, 1, FALSE); - offset += 1; + /* Current hop limit */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_cur_hop_limit, tvb, offset, 1, FALSE); + offset += 1; - /* Flags */ - ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_flag, tvb, offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_ra); - - proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_m, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_o, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_h, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_prf, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_p, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_rsv, tvb, offset, 1, FALSE); - offset += 1; + /* Flags */ + ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_flag, tvb, offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_ra); - /* Router lifetime */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_router_lifetime, tvb, offset, 2, FALSE); - offset += 2; + proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_m, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_o, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_h, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_prf, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_p, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_ra_flag_rsv, tvb, offset, 1, FALSE); + offset += 1; - /* Reachable time */ - proto_tree_add_uint(icmp6_tree, hf_icmpv6_nd_ra_reachable_time, tvb, offset, 4, FALSE); - offset += 4; + /* Router lifetime */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ra_router_lifetime, tvb, offset, 2, FALSE); + offset += 2; - /* Retrans timer */ - proto_tree_add_uint(icmp6_tree, hf_icmpv6_nd_ra_retrans_timer, tvb, offset, 4, FALSE); - offset += 4; + /* Reachable time */ + proto_tree_add_uint(icmp6_tree, hf_icmpv6_nd_ra_reachable_time, tvb, offset, 4, FALSE); + offset += 4; - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_ND_NEIGHBOR_SOLICIT: /* Neighbor Solicitation (135) */ - { - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); - offset += 4; + /* Retrans timer */ + proto_tree_add_uint(icmp6_tree, hf_icmpv6_nd_ra_retrans_timer, tvb, offset, 4, FALSE); + offset += 4; - /* Target Address */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ns_target_address, tvb, offset, 16, FALSE); - col_append_fstr(pinfo->cinfo, COL_INFO, " for %s", tvb_ip6_to_str(tvb, offset)); + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_ND_NEIGHBOR_SOLICIT: /* Neighbor Solicitation (135) */ + { + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); + offset += 4; - offset += 16; + /* Target Address */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_ns_target_address, tvb, offset, 16, FALSE); + col_append_fstr(pinfo->cinfo, COL_INFO, " for %s", tvb_ip6_to_str(tvb, offset)); - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_ND_NEIGHBOR_ADVERT: /* Neighbor Advertisement (136) */ - { - guint32 na_flags; - emem_strbuf_t *flags_strbuf = ep_strbuf_new_label(""); + offset += 16; - /* Flags */ - ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_na_flag, tvb, offset, 4, FALSE); - flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_na); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_r, tvb, offset, 4, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_s, tvb, offset, 4, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_o, tvb, offset, 4, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_rsv, tvb, offset, 4, FALSE); - na_flags = tvb_get_ntohl(tvb, offset); - offset += 4; + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_ND_NEIGHBOR_ADVERT: /* Neighbor Advertisement (136) */ + { + guint32 na_flags; + emem_strbuf_t *flags_strbuf = ep_strbuf_new_label(""); + + /* Flags */ + ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_na_flag, tvb, offset, 4, FALSE); + flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_na); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_r, tvb, offset, 4, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_s, tvb, offset, 4, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_o, tvb, offset, 4, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_nd_na_flag_rsv, tvb, offset, 4, FALSE); + na_flags = tvb_get_ntohl(tvb, offset); + offset += 4; - /* Target Address */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_na_target_address, tvb, offset, 16, FALSE); + /* Target Address */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_na_target_address, tvb, offset, 16, FALSE); - if (na_flags & ND_NA_FLAG_R) { - ep_strbuf_append(flags_strbuf, "rtr, "); - } - if (na_flags & ND_NA_FLAG_S) { - ep_strbuf_append(flags_strbuf, "sol, "); - } - if (na_flags & ND_NA_FLAG_O) { - ep_strbuf_append(flags_strbuf, "ovr, "); - } - if (flags_strbuf->len > 2) { - ep_strbuf_truncate(flags_strbuf, flags_strbuf->len - 2); - } else { - ep_strbuf_printf(flags_strbuf, "none"); - } + if (na_flags & ND_NA_FLAG_R) { + ep_strbuf_append(flags_strbuf, "rtr, "); + } + if (na_flags & ND_NA_FLAG_S) { + ep_strbuf_append(flags_strbuf, "sol, "); + } + if (na_flags & ND_NA_FLAG_O) { + ep_strbuf_append(flags_strbuf, "ovr, "); + } + if (flags_strbuf->len > 2) { + ep_strbuf_truncate(flags_strbuf, flags_strbuf->len - 2); + } else { + ep_strbuf_printf(flags_strbuf, "none"); + } - col_append_fstr(pinfo->cinfo, COL_INFO, " %s (%s)", tvb_ip6_to_str(tvb, offset), flags_strbuf->str); - offset += 16; + col_append_fstr(pinfo->cinfo, COL_INFO, " %s (%s)", tvb_ip6_to_str(tvb, offset), flags_strbuf->str); + offset += 16; - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_ND_REDIRECT: /* Redirect Message (137) */ - { - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); - offset += 4; + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_ND_REDIRECT: /* Redirect Message (137) */ + { + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); + offset += 4; - /* Target Address */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_target_address, tvb, offset, 16, FALSE); - offset += 16; + /* Target Address */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_target_address, tvb, offset, 16, FALSE); + offset += 16; - /* Destination Address */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_destination_address, tvb, offset, 16, FALSE); - offset += 16; + /* Destination Address */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_nd_rd_destination_address, tvb, offset, 16, FALSE); + offset += 16; - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_ROUTER_RENUMBERING: /* Router Renumbering (138) */ - { - dissect_rrenum(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code); - break; - } - case ICMP6_NI_QUERY: /* ICMP Node Information Query (139) */ - case ICMP6_NI_REPLY: /* ICMP Node Information Response (140) */ - { - dissect_nodeinfo(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code); - break; - } - case ICMP6_IND_SOLICIT: /* Inverse Neighbor Discovery Solicitation Message (141) */ - case ICMP6_IND_ADVERT: /* Inverse Neighbor Discovery Advertisement Message (142) */ - { - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); - offset += 4; + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_ROUTER_RENUMBERING: /* Router Renumbering (138) */ + { + dissect_rrenum(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code); + break; + } + case ICMP6_NI_QUERY: /* ICMP Node Information Query (139) */ + case ICMP6_NI_REPLY: /* ICMP Node Information Response (140) */ + { + dissect_nodeinfo(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code); + break; + } + case ICMP6_IND_SOLICIT: /* Inverse Neighbor Discovery Solicitation Message (141) */ + case ICMP6_IND_ADVERT: /* Inverse Neighbor Discovery Advertisement Message (142) */ + { + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 4, FALSE); + offset += 4; - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_MLDV2_REPORT: /* Version 2 Multicast Listener Report (143) */ - { - dissect_mldrv2( tvb, offset, pinfo, icmp6_tree ); - break; - } - case ICMP6_MIP6_DHAAD_REQUEST: /* Home Agent Address Discovery Request Message (144) */ - { - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); - offset += 2; + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_MLDV2_REPORT: /* Version 2 Multicast Listener Report (143) */ + { + dissect_mldrv2( tvb, offset, pinfo, icmp6_tree ); + break; + } + case ICMP6_MIP6_DHAAD_REQUEST: /* Home Agent Address Discovery Request Message (144) */ + { + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); + offset += 2; - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); - offset += 2; + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); + offset += 2; - break; - } - case ICMP6_MIP6_DHAAD_REPLY: /* Home Agent Address Discovery Reply Message (145) */ - { - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); - offset += 2; + break; + } + case ICMP6_MIP6_DHAAD_REPLY: /* Home Agent Address Discovery Reply Message (145) */ + { + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); + offset += 2; - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); - offset += 2; + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); + offset += 2; - /* Show all Home Agent Addresses */ - while((int)length > offset) - { - proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_home_agent_address, tvb, offset, 16, FALSE); - offset += 16; + /* Show all Home Agent Addresses */ + while((int)length > offset) + { + proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_home_agent_address, tvb, offset, 16, FALSE); + offset += 16; + } + break; } - break; - } - case ICMP6_MIP6_MPS: /* Mobile Prefix Solicitation (146) */ - { - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); - offset += 2; + case ICMP6_MIP6_MPS: /* Mobile Prefix Solicitation (146) */ + { + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); + offset += 2; - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); - offset += 2; - break; - } - case ICMP6_MIP6_MPA: /* Mobile Prefix Advertisement (147) */ - { - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); - offset += 2; - - /* Flag */ - ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_flag, tvb,offset, 6, FALSE); - flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_mip6); - proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_m, tvb, offset, 2, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_o, tvb, offset, 2, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_rsv, tvb, offset, 2, FALSE); - offset += 2; - - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_CERT_PATH_SOL: /* Certification Path Solicitation Message (148) */ - { + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); + offset += 2; + break; + } + case ICMP6_MIP6_MPA: /* Mobile Prefix Advertisement (147) */ + { + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_identifier, tvb, offset, 2, FALSE); + offset += 2; - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, FALSE); - offset += 2; + /* Flag */ + ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_mip6_flag, tvb,offset, 6, FALSE); + flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_mip6); + proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_m, tvb, offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_o, tvb, offset, 2, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_mip6_flag_rsv, tvb, offset, 2, FALSE); + offset += 2; - /* Component */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, FALSE); - offset += 2; + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_CERT_PATH_SOL: /* Certification Path Solicitation Message (148) */ + { - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_CERT_PATH_AD: /* Certification Path Advertisement Message (149) */ - { + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, FALSE); + offset += 2; - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, FALSE); - offset += 2; + /* Component */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, FALSE); + offset += 2; - /* All Components */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_send_all_components, tvb, offset, 2, FALSE); - offset += 2; + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); + break; + } + case ICMP6_CERT_PATH_AD: /* Certification Path Advertisement Message (149) */ + { - /* Component */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, FALSE); - offset += 2; + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_send_identifier, tvb, offset, 2, FALSE); + offset += 2; - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); - offset += 2; + /* All Components */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_send_all_components, tvb, offset, 2, FALSE); + offset += 2; - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_EXPERIMENTAL_MOBILITY: /* ICMP messages utilized by experimental mobility protocols (150) */ - case ICMP6_FMIPV6_MESSAGES: /* FMIPv6 Messages (154)*/ - { - guint8 subtype; + /* Component */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_send_component, tvb, offset, 2, FALSE); + offset += 2; - /* Subtype */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_subtype, tvb, offset, 1, FALSE); - subtype = tvb_get_guint8(tvb, offset); - col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(subtype, fmip6_subtype_val, "Unknown (%d)")); - offset += 1; + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 2, FALSE); + offset += 2; - switch(subtype){ - case FMIP6_SUBTYPE_RTSOLPR: - { - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, FALSE); - } + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); break; - case FMIP6_SUBTYPE_PRRTADV: - { - proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_prrtadv_code_val, "Unknown %d") ); - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, FALSE); + } + case ICMP6_EXPERIMENTAL_MOBILITY: /* ICMP messages utilized by experimental mobility protocols (150) */ + case ICMP6_FMIPV6_MESSAGES: /* FMIPv6 Messages (154)*/ + { + guint8 subtype; + + /* Subtype */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_subtype, tvb, offset, 1, FALSE); + subtype = tvb_get_guint8(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(subtype, fmip6_subtype_val, "Unknown (%d)")); + offset += 1; + + switch(subtype){ + case FMIP6_SUBTYPE_RTSOLPR: + { + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, FALSE); + } + break; + case FMIP6_SUBTYPE_PRRTADV: + { + proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_prrtadv_code_val, "Unknown %d") ); + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, FALSE); + } + break; + case FMIP6_SUBTYPE_HI: + { + proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hi_code_val, "Unknown %d") ); + /* Flags */ + ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_hi_flag, tvb, offset, 1, FALSE); + flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_fmip6); + + proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_s, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_u, tvb, offset, 1, FALSE); + proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_reserved, tvb, offset, 1, FALSE); + } + break; + case FMIP6_SUBTYPE_HACK: + { + proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hack_code_val, "Unknown %d") ); + /* Reserved */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, FALSE); + } + break; } + offset +=1; + + /* Identifier */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_identifier, tvb, offset, 2, FALSE); + offset += 2; + + /* Show options */ + dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); break; - case FMIP6_SUBTYPE_HI: - { - proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hi_code_val, "Unknown %d") ); - /* Flags */ - ti_flag = proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_hi_flag, tvb, offset, 1, FALSE); - flag_tree = proto_item_add_subtree(ti_flag, ett_icmpv6_flag_fmip6); - - proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_s, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_u, tvb, offset, 1, FALSE); - proto_tree_add_item(flag_tree, hf_icmpv6_fmip6_hi_flag_reserved, tvb, offset, 1, FALSE); - } + } + case ICMP6_MCAST_ROUTER_ADVERT: /* Multicast Router Advertisement (151) */ + { + /* Query Interval */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_query_interval, tvb, offset, 2, FALSE); + offset += 2; + + /* Robustness Variable */ + proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_robustness_variable, tvb, offset, 2, FALSE); + offset += 2; + } + case ICMP6_MCAST_ROUTER_SOLICIT: /* Multicast Router Solicitation (152) */ + case ICMP6_MCAST_ROUTER_TERM: /* Multicast Router Termination (153) */ + { + /* No Action... */ break; - case FMIP6_SUBTYPE_HACK: - { - proto_item_append_text(code_item, " (%s)", val_to_str(icmp6_code, fmip6_hack_code_val, "Unknown %d") ); - /* Reserved */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_reserved, tvb, offset, 1, FALSE); - } + } + case ICMP6_RPL_CONTROL: /* RPL Control (155) */ + { + /* RPL: draft-ietf-roll-rpl-17.txt: Routing over Low-Power and Lossy Networks. */ + dissect_rpl_control(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code); break; } - offset +=1; - - /* Identifier */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_fmip6_identifier, tvb, offset, 2, FALSE); - offset += 2; - - /* Show options */ - dissect_icmpv6_nd_opt(tvb, offset, pinfo, icmp6_tree); - break; - } - case ICMP6_MCAST_ROUTER_ADVERT: /* Multicast Router Advertisement (151) */ - { - /* Query Interval */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_query_interval, tvb, offset, 2, FALSE); - offset += 2; - - /* Robustness Variable */ - proto_tree_add_item(icmp6_tree, hf_icmpv6_mcast_ra_robustness_variable, tvb, offset, 2, FALSE); - offset += 2; - } - case ICMP6_MCAST_ROUTER_SOLICIT: /* Multicast Router Solicitation (152) */ - case ICMP6_MCAST_ROUTER_TERM: /* Multicast Router Termination (153) */ - { - /* No Action... */ - break; - } - case ICMP6_RPL_CONTROL: /* RPL Control (155) */ - { - /* RPL: draft-ietf-roll-rpl-17.txt: Routing over Low-Power and Lossy Networks. */ - dissect_rpl_control(tvb, offset, pinfo, icmp6_tree, icmp6_type, icmp6_code); - break; - } - default: - expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE, "Dissector for ICMPv6 Type (%d) code not implemented, Contact Wireshark developers if you want this supported", icmp6_type); - proto_tree_add_item(icmp6_tree, hf_icmpv6_data, tvb, offset, -1, FALSE); - break; + default: + expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_NOTE, + "Dissector for ICMPv6 Type (%d)" + " code not implemented, Contact Wireshark" + " developers if you want this supported", icmp6_type); + proto_tree_add_item(icmp6_tree, hf_icmpv6_data, tvb, offset, -1, FALSE); + break; } /* switch (icmp6_type) */ } /* if (tree) */ } @@ -3419,7 +3429,7 @@ proto_register_icmpv6(void) { &hf_icmpv6_nonce, { "Nonce", "icmpv6.nonce", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - /* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */ + /* RFC 2461/4861 : Neighbor Discovery for IP version 6 (IPv6) */ { &hf_icmpv6_nd_ra_cur_hop_limit, { "Cur hop limit", "icmpv6.nd.ra.cur_hop_limit", FT_UINT8, BASE_DEC, NULL, 0x0, "The default value that should be placed in the Hop Count field of the IP header for outgoing IP packets", HFILL }}, @@ -3513,28 +3523,28 @@ proto_register_icmpv6(void) { &hf_icmpv6_opt_target_linkaddr_mac, { "Target Link-layer address", "icmpv6.opt.target_linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - { &hf_icmpv6_opt_prefix_len, + { &hf_icmpv6_opt_prefix_len, { "Prefix Length", "icmpv6.opt.prefix.length", FT_UINT8, BASE_DEC, NULL, 0x0, "The number of leading bits in the Prefix that are valid", HFILL }}, - { &hf_icmpv6_opt_prefix_flag, + { &hf_icmpv6_opt_prefix_flag, { "Flag", "icmpv6.opt.prefix.flag", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL }}, - { &hf_icmpv6_opt_prefix_flag_l, + { &hf_icmpv6_opt_prefix_flag_l, { "On-link flag(L)", "icmpv6.opt.prefix.flag.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_opt_prefix_flag_a, + { &hf_icmpv6_opt_prefix_flag_a, { "Autonomous address-configuration flag(A)", "icmpv6.opt.prefix.flag.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_opt_prefix_flag_reserved, + { &hf_icmpv6_opt_prefix_flag_reserved, { "Reserved", "icmpv6.opt.prefix.flag.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f, NULL, HFILL }}, - { &hf_icmpv6_opt_prefix_valid_lifetime, + { &hf_icmpv6_opt_prefix_valid_lifetime, { "Valid Lifetime", "icmpv6.opt.prefix.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0x00, "The length of time in seconds that the prefix is valid for the purpose of on-link determination", HFILL }}, - { &hf_icmpv6_opt_prefix_preferred_lifetime, + { &hf_icmpv6_opt_prefix_preferred_lifetime, { "Preferred Lifetime", "icmpv6.opt.prefix.preferred_lifetime", FT_UINT32, BASE_DEC, NULL, 0x00, "The length of time in seconds that addresses generated from the prefix via stateless address autoconfiguration remain preferred", HFILL }}, - { &hf_icmpv6_opt_prefix, + { &hf_icmpv6_opt_prefix, { "Prefix", "icmpv6.opt.prefix", FT_IPv6, BASE_NONE, NULL, 0x00, "An IP address or a prefix of an IP address", HFILL }}, { &hf_icmpv6_opt_cga_pad_len, @@ -3576,39 +3586,39 @@ proto_register_icmpv6(void) { &hf_icmpv6_opt_certificate_padding, { "Certificat and Padding", "icmpv6.opt.certificate_padding", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - { &hf_icmpv6_opt_ipa_option_code, + { &hf_icmpv6_opt_ipa_option_code, { "Option-code", "icmpv6.opt.ipa.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_ipa_option_code_val), 0x00, NULL, HFILL }}, - { &hf_icmpv6_opt_ipa_prefix_len, + { &hf_icmpv6_opt_ipa_prefix_len, { "Prefix Length", "icmpv6.opt.ipa.prefix_len", FT_UINT8, BASE_DEC, NULL, 0x00, "That indicates the length of the IPv6 Address Prefix", HFILL }}, - { &hf_icmpv6_opt_ipa_ipv6_address, + { &hf_icmpv6_opt_ipa_ipv6_address, { "IPv6 Address", "icmpv6.opt.ipa.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x00, "The IP address/prefix defined by the Option-Code field", HFILL }}, - { &hf_icmpv6_opt_nrpi_option_code, + { &hf_icmpv6_opt_nrpi_option_code, { "Option-code", "icmpv6.opt.nrpi.option_code", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL }}, - { &hf_icmpv6_opt_nrpi_prefix_len, + { &hf_icmpv6_opt_nrpi_prefix_len, { "Prefix Length", "icmpv6.opt.nrpi.prefix_len", FT_UINT8, BASE_DEC, NULL, 0x00, "The number of leading bits in the Prefix that are valid", HFILL }}, - { &hf_icmpv6_opt_nrpi_prefix, + { &hf_icmpv6_opt_nrpi_prefix, { "Prefix", "icmpv6.opt.nrpi.prefix", FT_IPv6, BASE_NONE, NULL, 0x00, "An IP address or a prefix of an IP address", HFILL }}, - { &hf_icmpv6_opt_lla_option_code, + { &hf_icmpv6_opt_lla_option_code, { "Option-code", "icmpv6.opt.lla.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_lla_option_code_val), 0x00, NULL, HFILL }}, - { &hf_icmpv6_opt_lla_bytes, + { &hf_icmpv6_opt_lla_bytes, { "Link-Layer Address", "icmpv6.opt.lla.bytes", FT_BYTES, BASE_NONE, NULL, 0x00, "(in Bytes Format)", HFILL }}, - { &hf_icmpv6_opt_naack_option_code, + { &hf_icmpv6_opt_naack_option_code, { "Option-Code", "icmpv6.opt.naack.option_code", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL }}, - { &hf_icmpv6_opt_naack_status, + { &hf_icmpv6_opt_naack_status, { "Status", "icmpv6.opt.naack.status", FT_UINT8, BASE_DEC, VALS(nd_opt_naack_status_val), 0x00, "Indicating the disposition of the Unsolicited Neighbor Advertisement message", HFILL }}, - { &hf_icmpv6_opt_naack_supplied_ncoa, + { &hf_icmpv6_opt_naack_supplied_ncoa, { "Supplied NCoA", "icmpv6.opt.naack.supplied_ncoa", FT_IPv6, BASE_NONE, NULL, 0x00, - NULL, HFILL }}, + NULL, HFILL }}, { &hf_icmpv6_opt_map_dist, { "Distance", "icmpv6.opt.map.distance", FT_UINT8, BASE_DEC, NULL, 0xF0, "Identifying the distance between MAP and the receiver of the advertisement (in the number of hops)", HFILL }}, @@ -3630,16 +3640,16 @@ proto_register_icmpv6(void) { &hf_icmpv6_opt_map_global_address, { "Global Address", "icmpv6.opt.map.global_address", FT_IPv6, BASE_NONE, NULL, 0x0, "TOne of the MAP's global addresses", HFILL }}, - { &hf_icmpv6_opt_route_info_flag, + { &hf_icmpv6_opt_route_info_flag, { "Flag", "icmpv6.opt.route_info.flag", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL }}, - { &hf_icmpv6_opt_route_info_flag_route_preference, + { &hf_icmpv6_opt_route_info_flag_route_preference, { "Route Preference", "icmpv6.opt.route_info.flag.route_preference", FT_UINT8, BASE_DEC, VALS(nd_flag_router_pref), ND_RA_FLAG_RTPREF_MASK, "The Route Preference indicates whether to prefer the router associated with this prefix over others", HFILL }}, - { &hf_icmpv6_opt_route_info_flag_reserved, + { &hf_icmpv6_opt_route_info_flag_reserved, { "Reserved", "icmpv6.opt.route_info.flag.reserved", FT_UINT8, BASE_DEC, NULL, ND_RA_FLAG_RESERV_MASK, "Must be 0", HFILL }}, - { &hf_icmpv6_opt_route_lifetime, + { &hf_icmpv6_opt_route_lifetime, { "Route Lifetime", "icmpv6.opt.route_lifetime", FT_UINT32, BASE_DEC, NULL, 0x00, "The length of time in seconds that the prefix is valid for the purpose of route determination", HFILL }}, { &hf_icmpv6_opt_name_type, @@ -3877,25 +3887,25 @@ proto_register_icmpv6(void) { "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, + { &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, + { &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, + { &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, + { &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, + { &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, + { &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, @@ -3907,13 +3917,13 @@ proto_register_icmpv6(void) { &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, + { &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, + { &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, + { &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, @@ -3925,13 +3935,13 @@ proto_register_icmpv6(void) { &hf_icmpv6_rr_rm_flag, { "Flags", "icmpv6.rr.rm.flag", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, - { &hf_icmpv6_rr_rm_flag_b, + { &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, + { &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, + { &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, @@ -4020,16 +4030,16 @@ proto_register_icmpv6(void) { &hf_icmpv6_fmip6_subtype, { "Subtype", "icmpv6.fmip6.subtype", FT_UINT8, BASE_DEC, VALS(fmip6_subtype_val), 0x0, "Designates the Subtype of information", HFILL }}, - { &hf_icmpv6_fmip6_hi_flag, + { &hf_icmpv6_fmip6_hi_flag, { "Flag", "icmpv6.fmip6.hi.flag", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL }}, - { &hf_icmpv6_fmip6_hi_flag_s, + { &hf_icmpv6_fmip6_hi_flag_s, { "Assigned address configuration", "icmpv6.fmip6.hi.flag.s", FT_BOOLEAN, 8, TFS(&tfs_set_notset), FMIP6_HI_FLAG_S, "When set, this message requests a new CoA to be returned by the destination", HFILL }}, - { &hf_icmpv6_fmip6_hi_flag_u, + { &hf_icmpv6_fmip6_hi_flag_u, { "Buffer", "icmpv6.fmip6.hi.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), FMIP6_HI_FLAG_U, "When set, the destination SHOULD buffer any packets toward the node indicated in the options of this message", HFILL }}, - { &hf_icmpv6_fmip6_hi_flag_reserved, + { &hf_icmpv6_fmip6_hi_flag_reserved, { "Reserved", "icmpv6.fmip6.hi.flag.reserved", FT_UINT8, BASE_DEC, NULL, FMIP6_HI_FLAG_RSV, NULL, HFILL }}, { &hf_icmpv6_fmip6_identifier, |