/* packet-icmpv6.c * Routines for ICMPv6 packet disassembly * * $Id$ * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * MobileIPv6 support added by Tomislav Borosa * Copyright 2006, Nicolas DICHTEL - 6WIND - * * HMIPv6 support added by Martti Kuparinen * * FMIPv6 support added by Martin Andre * * RPL support added by Colin O'Flynn & Owen Kirby. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "packet-ber.h" #include "packet-ipv6.h" #include "packet-dns.h" #include "packet-x509af.h" #include "packet-x509if.h" #ifndef offsetof #define offsetof(type, member) ((size_t)(&((type *)0)->member)) #endif /* * The information used comes from: * RFC 2461: Neighbor Discovery for IP Version 6 (IPv6) * RFC 2710: Multicast Listener Discovery for IPv6 * RFC 2894: Router Renumbering for IPv6 * RFC 3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 * RFC 4068: Fast Handovers for Mobile IPv6 * RFC 4620: IPv6 Node Information Queries * RFC 4861: Neighbor Discovery for IP version 6 (IPv6) * draft-ietf-mobileip-hmipv6-05.txt * draft-ieft-roll-rpl-12.txt */ static int proto_icmpv6 = -1; static int hf_icmpv6_type = -1; static int hf_icmpv6_code = -1; static int hf_icmpv6_checksum = -1; static int hf_icmpv6_checksum_bad = -1; static int hf_icmpv6_reserved = -1; /* RFC 2710: Multicast Listener Discovery for IPv6 */ static int hf_icmpv6_mld_mrd = -1; static int hf_icmpv6_mld_multicast_address = -1; /* 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; static int hf_icmpv6_mld_flag_qrv = -1; static int hf_icmpv6_mld_flag_rsv = -1; static int hf_icmpv6_mld_qqi = -1; static int hf_icmpv6_mld_nb_sources = -1; static int hf_icmpv6_mld_source_address = -1; static int hf_icmpv6_mldr_nb_mcast_records = -1; static int hf_icmpv6_mldr_mar = -1; static int hf_icmpv6_mldr_mar_record_type = -1; static int hf_icmpv6_mldr_mar_aux_data_len = -1; static int hf_icmpv6_mldr_mar_nb_sources = -1; static int hf_icmpv6_mldr_mar_multicast_address = -1; static int hf_icmpv6_mldr_mar_source_address = -1; static int hf_icmpv6_mldr_mar_auxiliary_data = -1; static int hf_icmpv6_haad_ha_addrs = -1; static int hf_icmpv6_ra_cur_hop_limit = -1; static int hf_icmpv6_ra_router_lifetime = -1; static int hf_icmpv6_ra_reachable_time = -1; static int hf_icmpv6_ra_retrans_timer = -1; /* RPL: draft-ietf-roll-rpl-12.txt: Routing over Low-Power and Lossy Networks. */ static int hf_icmpv6_dis_reserved = -1; static int hf_icmpv6_dio_grounded = -1; static int hf_icmpv6_dio_preference = -1; static int hf_icmpv6_dio_rank = -1; static int hf_icmpv6_dio_instance = -1; static int hf_icmpv6_dio_version = -1; static int hf_icmpv6_dio_zero = -1; static int hf_icmpv6_dio_trigger_seqnum = -1; static int hf_icmpv6_dio_dagid = -1; static int hf_icmpv6_dio_mop = -1; static int hf_icmpv6_dao_instance = -1; static int hf_icmpv6_dao_seqnum = -1; static int hf_icmpv6_dao_reserved = -1; static int hf_icmpv6_dao_flag_k = -1; static int hf_icmpv6_dao_flag_d = -1; static int hf_icmpv6_dao_flag_rsv = -1; static int hf_icmpv6_dao_dodagid = -1; static int hf_icmpv6_daoack_instance = -1; static int hf_icmpv6_daoack_seqnum = -1; static int hf_icmpv6_daoack_status = -1; static int hf_icmpv6_daoack_flag_d = -1; static int hf_icmpv6_daoack_flag_rsv = -1; static int hf_icmpv6_daoack_dodagid = -1; static int hf_icmpv6_rpl_opt = -1; static int hf_icmpv6_rpl_opt_type = -1; static int hf_icmpv6_rpl_opt_length = -1; static int hf_icmpv6_rpl_opt_reserved = -1; static int hf_icmpv6_rpl_opt_padn = -1; static int hf_icmpv6_rpl_opt_route_prefix_length = -1; static int hf_icmpv6_rpl_opt_route_flag = -1; static int hf_icmpv6_rpl_opt_route_pref = -1; static int hf_icmpv6_rpl_opt_route_reserved = -1; static int hf_icmpv6_rpl_opt_route_lifetime = -1; static int hf_icmpv6_rpl_opt_route_prefix = -1; static int hf_icmpv6_rpl_opt_config_flag = -1; static int hf_icmpv6_rpl_opt_config_reserved = -1; static int hf_icmpv6_rpl_opt_config_auth = -1; static int hf_icmpv6_rpl_opt_config_pcs = -1; static int hf_icmpv6_rpl_opt_config_doublings = -1; static int hf_icmpv6_rpl_opt_config_min_interval = -1; static int hf_icmpv6_rpl_opt_config_redundancy = -1; static int hf_icmpv6_rpl_opt_config_rank_incr = -1; static int hf_icmpv6_rpl_opt_config_hop_rank_inc = -1; static int hf_icmpv6_rpl_opt_config_ocp = -1; static int hf_icmpv6_rpl_opt_config_rsv = -1; static int hf_icmpv6_rpl_opt_config_def_lifetime = -1; static int hf_icmpv6_rpl_opt_config_lifetime_unit = -1; static int hf_icmpv6_rpl_opt_target_flag = -1; static int hf_icmpv6_rpl_opt_target_prefix_length = -1; static int hf_icmpv6_rpl_opt_target_prefix = -1; static int hf_icmpv6_rpl_opt_transit_flag = -1; static int hf_icmpv6_rpl_opt_transit_flag_e = -1; static int hf_icmpv6_rpl_opt_transit_flag_rsv = -1; static int hf_icmpv6_rpl_opt_transit_pathseq = -1; static int hf_icmpv6_rpl_opt_transit_pathctl = -1; static int hf_icmpv6_rpl_opt_transit_pathlifetime = -1; static int hf_icmpv6_rpl_opt_transit_parent = -1; static int hf_icmpv6_rpl_opt_solicited_instance = -1; static int hf_icmpv6_rpl_opt_solicited_flag = -1; static int hf_icmpv6_rpl_opt_solicited_flag_v = -1; static int hf_icmpv6_rpl_opt_solicited_flag_i = -1; static int hf_icmpv6_rpl_opt_solicited_flag_d = -1; static int hf_icmpv6_rpl_opt_solicited_flag_rsv = -1; static int hf_icmpv6_rpl_opt_solicited_dodagid = -1; static int hf_icmpv6_rpl_opt_solicited_version = -1; static int hf_icmpv6_rpl_opt_prefix = -1; static int hf_icmpv6_rpl_opt_prefix_flag = -1; static int hf_icmpv6_rpl_opt_prefix_flag_l = -1; static int hf_icmpv6_rpl_opt_prefix_flag_a = -1; static int hf_icmpv6_rpl_opt_prefix_flag_r = -1; static int hf_icmpv6_rpl_opt_prefix_flag_rsv = -1; static int hf_icmpv6_rpl_opt_prefix_vlifetime = -1; static int hf_icmpv6_rpl_opt_prefix_plifetime = -1; static int hf_icmpv6_rpl_opt_prefix_length = -1; static int hf_icmpv6_rpl_opt_targetdesc = -1; static int hf_icmpv6_opt = -1; static int hf_icmpv6_opt_type = -1; static int hf_icmpv6_opt_length = -1; static int hf_icmpv6_opt_linkaddr_mac = -1; static int hf_icmpv6_opt_src_linkaddr_mac = -1; static int hf_icmpv6_opt_target_linkaddr_mac = -1; static int hf_icmpv6_opt_linkaddr = -1; static int hf_icmpv6_opt_src_linkaddr = -1; static int hf_icmpv6_opt_target_linkaddr = -1; static int hf_icmpv6_opt_prefix_len = -1; static int hf_icmpv6_opt_prefix_flag = -1; static int hf_icmpv6_opt_prefix_flag_l = -1; static int hf_icmpv6_opt_prefix_flag_a = -1; static int hf_icmpv6_opt_prefix_flag_reserved = -1; static int hf_icmpv6_opt_prefix_valid_lifetime = -1; static int hf_icmpv6_opt_prefix_preferred_lifetime = -1; static int hf_icmpv6_opt_prefix = -1; static int hf_icmpv6_opt_naack_option_code = -1; static int hf_icmpv6_opt_naack_status = -1; static int hf_icmpv6_opt_naack_supplied_ncoa = -1; static int hf_icmpv6_opt_cga_pad_len = -1; static int hf_icmpv6_opt_cga = -1; static int hf_icmpv6_opt_cga_modifier = -1; static int hf_icmpv6_opt_cga_subnet_prefix = -1; static int hf_icmpv6_opt_cga_count = -1; static int hf_icmpv6_opt_cga_ext_type = -1; static int hf_icmpv6_opt_cga_ext_length = -1; static int hf_icmpv6_opt_cga_ext_data = -1; static int hf_icmpv6_opt_rsa_key_hash = -1; static int hf_icmpv6_opt_digital_signature_padding = -1; static int hf_icmpv6_opt_timestamp = -1; static int hf_icmpv6_opt_nonce = -1; static int hf_icmpv6_opt_certificate_padding = -1; static int hf_icmpv6_opt_ipa_option_code = -1; static int hf_icmpv6_opt_ipa_prefix_len = -1; static int hf_icmpv6_opt_ipa_ipv6_address = -1; static int hf_icmpv6_opt_nrpi_option_code = -1; static int hf_icmpv6_opt_nrpi_prefix_len = -1; static int hf_icmpv6_opt_nrpi_prefix = -1; static int hf_icmpv6_opt_lla_option_code = -1; static int hf_icmpv6_opt_lla_bytes = -1; static int hf_icmpv6_opt_map_dist = -1; static int hf_icmpv6_opt_map_pref = -1; static int hf_icmpv6_opt_map_flag = -1; static int hf_icmpv6_opt_map_flag_r = -1; static int hf_icmpv6_opt_map_flag_reserved = -1; static int hf_icmpv6_opt_map_valid_lifetime = -1; static int hf_icmpv6_opt_map_global_address = -1; static int hf_icmpv6_opt_route_info_flag = -1; static int hf_icmpv6_opt_route_info_flag_route_preference = -1; static int hf_icmpv6_opt_route_info_flag_reserved = -1; static int hf_icmpv6_opt_route_lifetime = -1; static int hf_icmpv6_opt_name_type = -1; static int hf_icmpv6_opt_name_x501 = -1; static int hf_icmpv6_opt_name_fqdn = -1; static int hf_icmpv6_opt_cert_type = -1; static int hf_icmpv6_identifier = -1; static int hf_icmpv6_all_comp = -1; static int hf_icmpv6_comp = -1; static int hf_icmpv6_x509if_Name = -1; static int hf_icmpv6_x509af_Certificate = -1; static int hf_icmpv6_opt_redirected_packet = -1; static int hf_icmpv6_opt_mtu = -1; static int hf_icmpv6_opt_nbma_shortcut_limit = -1; static int hf_icmpv6_opt_advertisement_interval = -1; static int hf_icmpv6_opt_home_agent_preference = -1; static int hf_icmpv6_opt_home_agent_lifetime = -1; static int hf_icmpv6_opt_ipv6_address = -1; static int hf_icmpv6_opt_reserved = -1; static int hf_icmpv6_opt_padding = -1; static int hf_icmpv6_opt_rdnss_lifetime = -1; static int hf_icmpv6_opt_rdnss = -1; static int hf_icmpv6_opt_efo = -1; static int hf_icmpv6_opt_efo_m = -1; static int hf_icmpv6_opt_efo_o = -1; static int hf_icmpv6_opt_efo_h = -1; static int hf_icmpv6_opt_efo_prf = -1; static int hf_icmpv6_opt_efo_p = -1; static int hf_icmpv6_opt_efo_rsv = -1; static int hf_icmpv6_opt_hkr_pad_length = -1; static int hf_icmpv6_opt_hkr_at = -1; static int hf_icmpv6_opt_hkr_reserved = -1; static int hf_icmpv6_opt_hkr_encryption_public_key = -1; static int hf_icmpv6_opt_hkr_padding = -1; static int hf_icmpv6_opt_hkr_lifetime = -1; static int hf_icmpv6_opt_hkr_encrypted_handover_key = -1; static int hf_icmpv6_opt_hai_option_code = -1; static int hf_icmpv6_opt_hai_length = -1; static int hf_icmpv6_opt_hai_value = -1; static int hf_icmpv6_opt_mn_option_code = -1; static int hf_icmpv6_opt_mn_length = -1; static int hf_icmpv6_opt_mn_value = -1; static int hf_icmpv6_opt_dnssl_lifetime = -1; static int hf_icmpv6_opt_dnssl = -1; static int hf_icmpv6_opt_aro_status = -1; static int hf_icmpv6_opt_aro_registration_lifetime = -1; static int hf_icmpv6_opt_aro_eui64 = -1; static int hf_icmpv6_opt_6co_context_length = -1; static int hf_icmpv6_opt_6co_flag = -1; static int hf_icmpv6_opt_6co_flag_c = -1; static int hf_icmpv6_opt_6co_flag_cid = -1; static int hf_icmpv6_opt_6co_flag_reserved = -1; static int hf_icmpv6_opt_6co_valid_lifetime = -1; static int hf_icmpv6_opt_6co_context_prefix = -1; static int hf_icmpv6_opt_abro_version = -1; static int hf_icmpv6_opt_abro_6lbr_address = -1; /* RFC 4620: IPv6 Node Information Queries */ static int hf_icmpv6_ni_qtype = -1; static int hf_icmpv6_ni_flag = -1; static int hf_icmpv6_ni_flag_g = -1; static int hf_icmpv6_ni_flag_s = -1; static int hf_icmpv6_ni_flag_l = -1; static int hf_icmpv6_ni_flag_c = -1; static int hf_icmpv6_ni_flag_a = -1; static int hf_icmpv6_ni_flag_t = -1; static int hf_icmpv6_ni_flag_rsv = -1; static int hf_icmpv6_ni_nonce = -1; static int hf_icmpv6_ni_query_subject_ipv6 = -1; static int hf_icmpv6_ni_query_subject_fqdn = -1; static int hf_icmpv6_ni_query_subject_ipv4 = -1; static int hf_icmpv6_ni_reply_node_ttl = -1; static int hf_icmpv6_ni_reply_node_name = -1; static int hf_icmpv6_ni_reply_node_address = -1; static int hf_icmpv6_ni_reply_ipv4_address = -1; /* RFC 2894: Router Renumbering for IPv6 */ static int hf_icmpv6_rr_sequencenumber = -1; static int hf_icmpv6_rr_segmentnumber = -1; static int hf_icmpv6_rr_flag = -1; static int hf_icmpv6_rr_flag_t = -1; static int hf_icmpv6_rr_flag_r = -1; static int hf_icmpv6_rr_flag_a = -1; static int hf_icmpv6_rr_flag_s = -1; static int hf_icmpv6_rr_flag_p = -1; static int hf_icmpv6_rr_flag_rsv = -1; static int hf_icmpv6_rr_maxdelay = -1; static int hf_icmpv6_rr_pco_mp_part = -1; static int hf_icmpv6_rr_pco_mp_opcode = -1; static int hf_icmpv6_rr_pco_mp_oplength = -1; static int hf_icmpv6_rr_pco_mp_ordinal = -1; static int hf_icmpv6_rr_pco_mp_matchlen = -1; static int hf_icmpv6_rr_pco_mp_minlen = -1; static int hf_icmpv6_rr_pco_mp_maxlen = -1; static int hf_icmpv6_rr_pco_mp_matchprefix = -1; static int hf_icmpv6_rr_pco_up_part = -1; static int hf_icmpv6_rr_pco_up_uselen = -1; static int hf_icmpv6_rr_pco_up_keeplen = -1; static int hf_icmpv6_rr_pco_up_flagmask = -1; static int hf_icmpv6_rr_pco_up_flagmask_l = -1; static int hf_icmpv6_rr_pco_up_flagmask_a = -1; static int hf_icmpv6_rr_pco_up_flagmask_reserved = -1; static int hf_icmpv6_rr_pco_up_raflags = -1; static int hf_icmpv6_rr_pco_up_raflags_l = -1; static int hf_icmpv6_rr_pco_up_raflags_a = -1; static int hf_icmpv6_rr_pco_up_raflags_reserved = -1; static int hf_icmpv6_rr_pco_up_validlifetime = -1; static int hf_icmpv6_rr_pco_up_preferredlifetime = -1; static int hf_icmpv6_rr_pco_up_flag = -1; static int hf_icmpv6_rr_pco_up_flag_v = -1; static int hf_icmpv6_rr_pco_up_flag_p = -1; static int hf_icmpv6_rr_pco_up_flag_reserved = -1; static int hf_icmpv6_rr_pco_up_useprefix = -1; static int hf_icmpv6_rr_rm = -1; static int hf_icmpv6_rr_rm_flag = -1; static int hf_icmpv6_rr_rm_flag_b = -1; static int hf_icmpv6_rr_rm_flag_f = -1; static int hf_icmpv6_rr_rm_flag_reserved = -1; static int hf_icmpv6_rr_rm_ordinal = -1; static int hf_icmpv6_rr_rm_matchedlen = -1; static int hf_icmpv6_rr_rm_interfaceindex = -1; static int hf_icmpv6_rr_rm_matchedprefix = -1; static gint ett_icmpv6 = -1; static gint ett_icmpv6opt = -1; static gint ett_icmpv6flag = -1; static gint ett_icmpv6mar = -1; static gint ett_icmpv6opt_name = -1; static gint ett_cga_param_name = -1; static gint ett_dao_rr_stack = -1; static dissector_handle_t ipv6_handle; static dissector_handle_t data_handle; static const value_string icmpv6_type_str[] = { { ICMP6_DST_UNREACH, "Unreachable" }, { ICMP6_PACKET_TOO_BIG, "Too big" }, { ICMP6_TIME_EXCEEDED, "Time exceeded" }, { ICMP6_PARAM_PROB, "Parameter problem" }, { 100, "Private experimentation" }, { 101, "Private experimentation" }, { 127, "Reserved for expansion of ICMPv6 error messages" }, { ICMP6_ECHO_REQUEST, "Echo (ping) request" }, { ICMP6_ECHO_REPLY, "Echo (ping) reply" }, { ICMP6_MEMBERSHIP_QUERY, "Multicast listener query" }, { ICMP6_MEMBERSHIP_REPORT, "Multicast listener report" }, { ICMP6_MEMBERSHIP_REDUCTION, "Multicast listener done" }, { ND_ROUTER_SOLICIT, "Router solicitation" }, { ND_ROUTER_ADVERT, "Router advertisement" }, { ND_NEIGHBOR_SOLICIT, "Neighbor solicitation" }, { ND_NEIGHBOR_ADVERT, "Neighbor advertisement" }, { ND_REDIRECT, "Redirect" }, { ICMP6_ROUTER_RENUMBERING, "Router renumbering" }, { ICMP6_NI_QUERY, "Node information query" }, { ICMP6_NI_REPLY, "Node information reply" }, { ICMP6_IND_SOLICIT, "Inverse neighbor discovery solicitation" }, { ICMP6_IND_ADVERT, "Inverse neighbor discovery advertisement" }, { ICMP6_MLDV2_REPORT, "Multicast Listener Report Message v2" }, { ICMP6_MIP6_DHAAD_REQUEST, "Dynamic Home Agent Address Discovery Request" }, { ICMP6_MIP6_DHAAD_REPLY, "Dynamic Home Agent Address Discovery Reply" }, { ICMP6_MIP6_MPS, "Mobile Prefix Solicitation" }, { ICMP6_MIP6_MPA, "Mobile Prefix Advertisement" }, { ICMP6_CERT_PATH_SOL, "Certification Path Solicitation" }, { ICMP6_CERT_PATH_AD, "Certification Path Advertisement" }, { ICMP6_EXPERIMENTAL_MOBILITY, "Experimental Mobility" }, { ICMP6_MCAST_ROUTER_ADVERT, "Multicast Router Advertisement" }, { ICMP6_MCAST_ROUTER_SOLICIT, "Multicast Router Solicitation" }, { ICMP6_MCAST_ROUTER_TERM, "Multicast Router Termination" }, { ICMP6_FMIPV6_MESSAGES, "FMIPv6 Messages" }, { ICMP6_RPL_CONTROL, "RPL Control Message" }, { 200, "Private experimentation" }, { 201, "Private experimentation" }, { 255, "Reserved for expansion of ICMPv6 informational messages" }, { 0, NULL } }; static const value_string icmpv6_unreach_code_str[] = { { ICMP6_DST_UNREACH_NOROUTE, "Route unreachable" }, { ICMP6_DST_UNREACH_ADMIN, "Administratively prohibited" }, { ICMP6_DST_UNREACH_BEYONDSCOPE, "Beyond scope of source address" }, { ICMP6_DST_UNREACH_ADDR, "Address unreachable" }, { ICMP6_DST_UNREACH_NOPORT, "Port unreachable" }, { ICMP6_DST_UNREACH_INGR_EGR, "Source address failed ingress/egress policy" }, { ICMP6_DST_UNREACH_REJECT, "Reject route to destination" }, { 0, NULL } }; static const value_string icmpv6_timeex_code_str[] = { { ICMP6_TIME_EXCEED_TRANSIT, "In-transit" }, { ICMP6_TIME_EXCEED_REASSEMBLY, "Reassembly" }, { 0, NULL } }; static const value_string icmpv6_paramprob_code_str[] = { { ICMP6_PARAMPROB_HEADER, "Header" }, { ICMP6_PARAMPROB_NEXTHEADER, "Next header" }, { ICMP6_PARAMPROB_OPTION, "Option" }, { 0, NULL } }; static const value_string icmpv6_router_renum_code_str[] = { { ICMP6_ROUTER_RENUMBERING_COMMAND, "Command" }, { ICMP6_ROUTER_RENUMBERING_RESULT, "Result" }, { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "Sequence number reset" }, { 0, NULL } }; /* RFC4620 - IPv6 Node Information Queries */ #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_qtype_val[] = { { NI_QTYPE_NOOP, "NOOP" }, { NI_QTYPE_SUPTYPES, "Supported query types (Obsolete)" }, { NI_QTYPE_NODENAME, "Node Name" }, { NI_QTYPE_NODEADDR, "Node addresses" }, { NI_QTYPE_IPV4ADDR, "IPv4 node addresses" }, { 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_RSV 0xFFC0 static const true_false_string tfs_ni_flag_a = { "All unicast address", "Unicast addresses on the queried interface" }; /* RFC2894 - Router Renumbering for IPv6 */ #define RR_FLAG_T 0x80 #define RR_FLAG_R 0x40 #define RR_FLAG_A 0x20 #define RR_FLAG_S 0x10 #define RR_FLAG_P 0x08 #define RR_FLAG_RSV 0x07 static const value_string rr_pco_mp_opcode_val[] = { { 1, "Add" }, { 2, "Change" }, { 3, "Set Global" }, { 0, NULL } }; /* * RFC3810 - Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */ #define MLDV2_PACKET_MINLEN 28 #define MLD_FLAG_S 0x08 #define MLD_FLAG_QRV 0x07 #define MLD_FLAG_RSV 0xF0 static const value_string mldr_record_type_val[] = { { 1, "Include" }, { 2, "Exclude" }, { 3, "Changed to include" }, { 4, "Changed to exclude" }, { 5, "Allow new sources" }, { 6, "Block old sources" }, { 0, NULL } }; static const value_string names_router_pref[] = { { ND_RA_FLAG_RTPREF_HIGH, "High" }, { ND_RA_FLAG_RTPREF_MEDIUM, "Medium" }, { ND_RA_FLAG_RTPREF_LOW, "Low" }, { ND_RA_FLAG_RTPREF_RSV, "Reserved" }, { 0, NULL} }; static const value_string names_fmip6_prrtadv_code[] = { { FMIP6_PRRTADV_MNTUP, "MN should use AP-ID, AR-info tuple" }, { FMIP6_PRRTADV_NI_HOVER, "Network Initiated Handover trigger" }, { FMIP6_PRRTADV_NORTINFO, "No new router information" }, { FMIP6_PRRTADV_LIMRTINFO, "Limited new router information" }, { FMIP6_PRRTADV_UNSOL, "Unsolicited" }, { 0, NULL } }; static const value_string names_fmip6_hi_code[] = { { FMIP6_HI_PCOA, "FBU sent from previous link" }, { FMIP6_HI_NOTPCOA, "FBU sent from new link" }, { 0, NULL } }; static const value_string names_fmip6_hack_code[] = { { FMIP6_HACK_VALID, "Handover Accepted, NCoA valid" }, { FMIP6_HACK_INVALID, "Handover Accepted, NCoA not valid" }, { FMIP6_HACK_INUSE, "Handover Accepted, NCoA in use" }, { FMIP6_HACK_ASSIGNED, "Handover Accepted, NCoA assigned" }, { FMIP6_HACK_NOTASSIGNED, "Handover Accepted, NCoA not assigned" }, { FMIP6_HACK_NOTACCEPTED, "Handover Not Accepted, reason unspecified" }, { FMIP6_HACK_PROHIBITED, "Administratively prohibited" }, { FMIP6_HACK_INSUFFICIENT, "Insufficient resources" }, { 0, NULL } }; static const value_string nd_opt_ipa_option_code_val[] = { { 1, "Old Care-of Address" }, { 2, "New Care-of Address" }, { 3, "NAR's IP address" }, { 4, "NAR's Prefix (sent in PrRtAdv)" }, { 0, NULL } }; static const value_string nd_opt_lla_option_code_val[] = { { 0, "Wildcard" }, { 1, "Link-layer Address of the New Access Point" }, { 2, "Link-layer Address of the MN" }, { 3, "Link-layer Address of the NAR" }, { 4, "Link-layer Address of the source" }, { 5, "The AP belongs to the current interface of the router" }, { 6, "No prefix information available" }, { 7, "No fast handovers support available" }, { 0, NULL } }; static const value_string nd_opt_hai_option_code_val[] = { { 1, "Access Network Identifier (AN ID)" }, { 2, "Sector ID" }, { 0, NULL } }; static const value_string nd_opt_mn_option_code_val[] = { { 1, "NAI" }, { 2, "IMSI" }, { 0, NULL } }; static const value_string nd_opt_naack_status_val[] = { { 1, "New CoA is invalid, perform address configuration" }, { 2, "New CoA is invalid, use the supplied CoA" }, { 3, "NCoA is invalid, use NAR's IP address as NCoA in FBU" }, { 4, "PCoA supplied, do not send FBU" }, { 128, "LLA is unrecognized" }, { 0, NULL } }; static const value_string names_6lowpannd_aro_status_str[] = { { 0, "Success" }, { 1, "Duplicate Exists" }, { 2, "Neighbor Cache Full" }, { 0, NULL } }; /* RPL: draft-ietf-roll-rpl-12.txt: Routing over Low-Power and Lossy Networks. */ /* Pending IANA Assignment */ /* RPL ICMPv6 Codes */ #define ICMP6_RPL_DIS 0 /* DODAG Information Solicitation */ #define ICMP6_RPL_DIO 1 /* DODAG Information Object */ #define ICMP6_RPL_DAO 2 /* Destination Advertisement Object */ #define ICMP6_RPL_DAOACK 3 /* Destination Advertisement Object Ack */ /* RPL DIO Flags */ #define RPL_DIO_FLAG_GROUNDED 0x80 #define RPL_DIO_FLAG_ZERO 0x40 #define RPL_DIO_FLAG_MOP 0x38 #define RPL_DIO_FLAG_PREFERENCE 0x07 /* RPL DAO Flags */ #define RPL_DAO_FLAG_K 0x80 #define RPL_DAO_FLAG_D 0x40 #define RPL_DAO_FLAG_RESERVED 0x3F /* RPL DAO ACK Flags */ #define RPL_DAOACK_FLAG_D 0x80 #define RPL_DAOACK_FLAG_RESERVED 0x7F /* RPL Option Bitfields */ #define RPL_OPT_PREFIX_FLAG_L 0x80 #define RPL_OPT_PREFIX_FLAG_A 0x40 #define RPL_OPT_PREFIX_FLAG_R 0x20 #define RPL_OPT_PREFIX_FLAG_RSV 0x1F #define RPL_OPT_ROUTE_PREFERENCE 0x18 #define RPL_OPT_ROUTE_RESERVED 0xE7 #define RPL_OPT_CONFIG_FLAG_AUTH 0x08 #define RPL_OPT_CONFIG_FLAG_PCS 0x07 #define RPL_OPT_CONFIG_FLAG_RESERVED 0xF0 #define RPL_OPT_TRANSIT_FLAG_E 0x80 #define RPL_OPT_TRANSIT_FLAG_RSV 0x7F #define RPL_OPT_SOLICITED_FLAG_V 0x80 #define RPL_OPT_SOLICITED_FLAG_I 0x40 #define RPL_OPT_SOLICITED_FLAG_D 0x20 #define RPL_OPT_SOLICITED_FLAG_RSV 0x1F static const value_string names_rpl_code[] = { { ICMP6_RPL_DIS, "DODAG Information Solicitation" }, { ICMP6_RPL_DIO, "DODAG Information Object" }, { ICMP6_RPL_DAO, "Destination Advertisement Object" }, { ICMP6_RPL_DAOACK, "Destination Advertisement Object Acknowledgement" }, { 0, NULL } }; /* RPL Option Types */ /* Pending IANA Assignment */ #define RPL_OPT_PAD1 0 /* 1-byte padding */ #define RPL_OPT_PADN 1 /* n-byte padding */ #define RPL_OPT_METRIC 2 /* DAG metric container */ #define RPL_OPT_ROUTING 3 /* Routing Information */ #define RPL_OPT_CONFIG 4 /* DAG configuration */ #define RPL_OPT_TARGET 5 /* RPL Target */ #define RPL_OPT_TRANSIT 6 /* Transit */ #define RPL_OPT_SOLICITED 7 /* Solicited Information */ #define RPL_OPT_PREFIX 8 /* Destination prefix */ #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_TARGETDESC, "RPL Target Descriptor"}, { 0, NULL } }; /* http://www.iana.org/assignments/icmpv6-parameters */ #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_FLAGS_EXTENSION 26 #define ND_OPT_HANDOVER_KEY_REQUEST 27 #define ND_OPT_HANDOVER_KEY_REPLY 28 #define ND_OPT_HANDOVER_ASSIST_INFO 29 #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 static const value_string option_vals[] = { /* 1 */ { ND_OPT_SOURCE_LINKADDR, "Source link-layer address" }, /* 2 */ { ND_OPT_TARGET_LINKADDR, "Target link-layer address" }, /* 3 */ { ND_OPT_PREFIX_INFORMATION, "Prefix information" }, /* 4 */ { ND_OPT_REDIRECTED_HEADER, "Redirected header" }, /* 5 */ { ND_OPT_MTU, "MTU" }, /* 6 */ { ND_OPT_NBMA, "NBMA Shortcut Limit Option" }, /* [RFC2491] */ /* 7 */ { ND_OPT_ADVINTERVAL, "Advertisement Interval" }, /* [RFC3775] */ /* 8 */ { ND_OPT_HOMEAGENT_INFO, "Home Agent Information" }, /* [RFC3775] */ /* 9 */ { ND_OPT_SOURCE_ADDRLIST, "Source Address List" }, /* [RFC3122] */ /* 10 */ { ND_OPT_TARGET_ADDRLIST, "Target Address List" }, /* [RFC3122] */ /* 11 */ { ND_OPT_CGA, "CGA" }, /* [RFC3971] */ /* 12 */ { ND_OPT_RSA, "RSA Signature" }, /* [RFC3971] */ /* 13 */ { ND_OPT_TIMESTAMP, "Timestamp" }, /* [RFC3971] */ /* 14 */ { ND_OPT_NONCE, "Nonce" }, /* [RFC3971] */ /* 15 */ { ND_OPT_TRUST_ANCHOR, "Trust Anchor" }, /* [RFC3971] */ /* 16 */ { ND_OPT_CERTIFICATE, "Certificate" }, /* [RFC3971] */ /* 17 */ { ND_OPT_IP_ADDRESS_PREFIX, "IP Address/Prefix Option" }, /* [RFC5568] */ /* 18 */ { ND_OPT_NEW_ROUTER_PREFIX_INFO, "New Router Prefix Information" }, /* [RFC4068] OBSO */ /* 19 */ { ND_OPT_LINK_LAYER_ADDRESS, "Link-layer Address" }, /* [RFC5568] */ /* 20 */ { ND_OPT_NEIGHBOR_ADV_ACK, "Neighbor Advertisement Acknowledgment" }, /* [RFC5568] */ /* 21-22 Unassigned */ /* 23 */ { ND_OPT_MAP, "MAP" }, /* [RFC4140] */ /* 24 */ { ND_OPT_ROUTE_INFO, "Route Information" }, /* [RFC4191] */ /* 25 */ { ND_OPT_RECURSIVE_DNS_SERVER, "Recursive DNS Server" }, /* [RFC6106] */ /* 26 */ { ND_OPT_FLAGS_EXTENSION, "RA Flags Extension" }, /* [RFC5175] */ /* 27 */ { ND_OPT_HANDOVER_KEY_REQUEST, "Handover Key Request" }, /* [RFC5269] */ /* 28 */ { ND_OPT_HANDOVER_KEY_REPLY, "Handover Key Reply" }, /* [RFC5269] */ /* 29 */ { ND_OPT_HANDOVER_ASSIST_INFO, "Handover Assist Information" }, /* [RFC5271] */ /* 30 */ { ND_OPT_MOBILE_NODE_ID, "Mobile Node Identifier Option" }, /* [RFC5271] */ /* 31 */ { ND_OPT_DNS_SEARCH_LIST, "DNS Search List Option" }, /* [RFC6106] */ /* 31 */ { ND_OPT_ADDR_RESOLUTION, "Address Resolution Option" }, /* 6LoWPAN-ND */ /* 32 */ { ND_OPT_6LOWPAN_CONTEXT, "6LoWPAN Context Option" }, /* 6LoWPAN-ND */ /* 33 */ { ND_OPT_AUTH_BORDER_ROUTER, "Authorative Border Router" }, /* 6LoWPAN-ND */ /* 34-137 Unassigned */ { 138, "CARD Request" }, /* [RFC4065] */ { 139, "CARD Reply" }, /* [RFC4065] */ /* 140-252 Unassigned */ { 253, "RFC3692-style Experiment 1" }, /* [RFC4727] */ { 254, "RFC3692-style Experiment 2" }, /* [RFC4727] */ { 0, NULL } }; static const value_string icmpv6_option_name_type_vals[] = { { 1, "DER Encoded X.501 Name" }, { 2, "FQDN" }, { 3, "SHA-1 Subject Key Identifier (SKI)" }, { 4, "SHA-224 Subject Key Identifier (SKI)" }, { 5, "SHA-256 Subject Key Identifier (SKI)" }, { 6, "SHA-384 Subject Key Identifier (SKI)" }, { 7, "SHA-512 Subject Key Identifier (SKI)" }, { 253, "Reserved for Experimental Use" }, { 254, "Reserved for Experimental Use" }, { 255, "Reserved" }, { 0, NULL } }; static const value_string icmpv6_option_cert_type_vals[] = { { 1, "X.509v3 Certificate" }, { 0, NULL } }; #define FLAGS_EO_M 0x8000 #define FLAGS_EO_O 0x4000 #define FLAGS_EO_H 0x2000 #define FLAGS_EO_PRF 0x1800 #define FLAGS_EO_P 0x0400 #define FLAGS_EO_RSV 0x02FF static void dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { gboolean save_in_error_pkt; tvbuff_t *next_tvb; /* Save the current value of the "we're inside an error packet" flag, and set that flag; subdissectors may treat packets that are the payload of error packets differently from "real" packets. */ save_in_error_pkt = pinfo->in_error_pkt; pinfo->in_error_pkt = TRUE; next_tvb = tvb_new_subset_remaining(tvb, offset); /* tiny sanity check */ if ((tvb_get_guint8(tvb, offset) & 0xf0) == 0x60) { /* The contained packet is an IPv6 datagram; dissect it. */ call_dissector(ipv6_handle, next_tvb, pinfo, tree); } else call_dissector(data_handle,next_tvb, pinfo, tree); /* Restore the "we're inside an error packet" flag. */ pinfo->in_error_pkt = save_in_error_pkt; } static void dissect_icmpv6ndopt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_tree *icmp6opt_tree, *flag_tree; proto_item *ti, *ti_opt, *ti_opt_len; guint8 opt_type; int opt_len; int opt_offset; while ((int)tvb_reported_length(tvb) > offset) { /* 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_icmpv6opt); opt_offset = offset; /* 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")); /* 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); 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); } 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); } break; } case ND_OPT_PREFIX_INFORMATION: /* Prefix Information (3) */ { guint8 prefix_len; struct e_in6_addr prefix; /* 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_icmpv6flag); 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; /* 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)"); 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); tvb_get_ipv6(tvb, opt_offset, &prefix); proto_item_append_text(ti, " : %s/%d", ip6_to_str(&prefix), prefix_len); opt_offset += 16; break; } case ND_OPT_REDIRECTED_HEADER: /* Redirected Header (4) */ 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; 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; case ND_OPT_NBMA: /* NBMA Shortcut Limit Option (6) */ 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, 1, FALSE); opt_offset += 1; proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_reserved, tvb, opt_offset, 4, FALSE); opt_offset += 4; break; case ND_OPT_ADVINTERVAL: /* Advertisement Interval Option (7) */ 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)); break; case ND_OPT_HOMEAGENT_INFO: /* Home Agent Information Option (8) */ { 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_home_agent_preference, 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)*/ { struct e_in6_addr ipv6_address; 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); tvb_get_ipv6(tvb, opt_offset, &ipv6_address); proto_item_append_text(ti, " %s", ip6_to_str(&ipv6_address)); 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_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_icmpv6opt_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; struct e_in6_addr ipv6_address; /* 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); tvb_get_ipv6(tvb, opt_offset, &ipv6_address); opt_offset += 16; proto_item_append_text(ti, " %s/%d", ip6_to_str(&ipv6_address), prefix_len); break; } case ND_OPT_NEW_ROUTER_PREFIX_INFO: /* New Router Prefix Information Option (18) OBSO... */ { guint8 prefix_len; struct e_in6_addr prefix; /* 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); tvb_get_ipv6(tvb, opt_offset, &prefix); opt_offset += 16; proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), 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; /* 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 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_icmpv6flag); 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; } 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_icmpv6flag); 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, names_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: tvb_get_ipv6(tvb, opt_offset, &prefix); proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_prefix, tvb, opt_offset, 16, FALSE); proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len); break; default: expert_add_info_format(pinfo, ti_opt_len, PI_MALFORMED, PI_ERROR, "Invalid Option Length"); break; } break; } case ND_OPT_RECURSIVE_DNS_SERVER: /* Recursive DNS Server Option (25) */ { struct e_in6_addr rdnss; /* 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)"); break; case 0xffffffff: proto_item_append_text(ti_opt, " (Infinity)"); break; default: 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); tvb_get_ipv6(tvb, opt_offset, &rdnss); proto_item_append_text(ti, " %s", ip6_to_str(&rdnss)); 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_icmpv6flag); 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; /* 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; /* AT */ proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, FALSE); /* Reserved */ proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, FALSE); opt_offset += 1; /* 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; /* 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; /* 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; /* AT */ proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_at, tvb, opt_offset, 1, FALSE); /* Reserved */ proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_reserved, tvb, opt_offset, 1, FALSE); opt_offset += 1; /* Lifetime */ proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_hkr_lifetime, 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; /* 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); 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; /* 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; } 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 */ 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; } 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_icmpv6flag); 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: tvb_get_ipv6(tvb, opt_offset, &context_prefix); proto_tree_add_item(icmp6opt_tree, hf_icmpv6_opt_6co_context_prefix, tvb, opt_offset, 16, FALSE); proto_item_append_text(ti, " %s/%d", ip6_to_str(&context_prefix), 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; /* 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, names_6lowpannd_aro_status_str, "Unknown %d")); opt_offset += 8; } break; case ND_OPT_AUTH_BORDER_ROUTER: /* Authoritative Border Router (33) */ { guint16 version; struct e_in6_addr addr_6lbr; /* 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); tvb_get_ipv6(tvb, opt_offset, &addr_6lbr); proto_item_append_text(ti, " : Version %d, 6LBR : %s", version, ip6_to_str(&addr_6lbr)); opt_offset += 16; } break; 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); break; } /* switch (opt_type) */ offset += opt_len; /* Close the ) to option root label */ proto_item_append_text(ti, ")"); } } /* RPL: draft-ietf-roll-rpl-12.txt: Routing over Low-Power and Lossy Networks. */ static void dissect_icmpv6_rpl_opt(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_tree *icmp6opt_tree, *flag_tree; proto_item *ti, *ti_opt, *ti_opt_len; guint8 opt_type; int opt_len; int opt_offset; while ((int)tvb_reported_length(tvb) > offset) { /* 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_icmpv6opt); opt_offset = offset; /* 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")); /* The Pad1 option is a special case, and contains no data. */ if (opt_type == RPL_OPT_PAD1) { offset += 1; 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); 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_icmpv6flag); 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: tvb_get_ipv6(tvb, opt_offset, &prefix); proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_route_prefix, tvb, opt_offset, 16, FALSE); proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len); 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_icmpv6flag); 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; /* 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: tvb_get_ipv6(tvb, opt_offset, &target_prefix); proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_target_prefix, tvb, opt_offset, 16, FALSE); proto_item_append_text(ti, " %s/%d", ip6_to_str(&target_prefix), prefix_len); 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_icmpv6flag); 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); 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_icmpv6flag); 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; 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_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_icmpv6flag); 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; /* Prefix */ tvb_get_ipv6(tvb, opt_offset, &prefix); proto_tree_add_item(icmp6opt_tree, hf_icmpv6_rpl_opt_prefix, tvb, opt_offset, 16, FALSE); proto_item_append_text(ti, " %s/%d", ip6_to_str(&prefix), prefix_len); opt_offset += 16; break; } 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); break; } /* switch (opt_type) */ offset += opt_len + 2; /* Close the ) to option root label */ proto_item_append_text(ti, ")"); } } /* * RFC 4620 - IPv6 Node Information Queries */ static void dissect_nodeinfo(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint8 icmp6_type, guint8 icmp6_code) { proto_tree *flag_tree; proto_item *ti; guint16 qtype; int ni_offset = offset + 4; /* Qtype */ proto_tree_add_item(tree, hf_icmpv6_ni_qtype, tvb, ni_offset, 2, FALSE); qtype = tvb_get_ntohs(tvb, ni_offset); ni_offset += 2; /* Flags */ ti = proto_tree_add_item(tree, hf_icmpv6_ni_flag, tvb, ni_offset, 2, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_g, tvb, ni_offset, 2, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_s, tvb, ni_offset, 2, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_l, tvb, ni_offset, 2, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_c, tvb, ni_offset, 2, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_ni_flag_a, tvb, ni_offset, 2, FALSE); 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; } 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; } 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; } 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; } } } } /* * RFC 2894 - Router Renumbering for IPv6 */ static void dissect_rrenum(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint8 icmp6_type _U_, guint8 icmp6_code) { proto_tree *flag_tree, *mp_tree, *up_tree, *rm_tree; proto_item *ti, *ti_mp, *ti_up, *ti_rm; int rr_offset = offset + 4; /* Sequence Number */ proto_tree_add_item(tree, hf_icmpv6_rr_sequencenumber, tvb, rr_offset, 4, FALSE); rr_offset += 4; /* Segment Number */ proto_tree_add_item(tree, hf_icmpv6_rr_segmentnumber, tvb, rr_offset, 1, FALSE); rr_offset += 1; /* Flags */ ti = proto_tree_add_item(tree, hf_icmpv6_rr_flag, tvb, rr_offset, 1, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_t, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_r, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_a, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_s, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_p, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_flag_rsv, tvb, rr_offset, 1, FALSE); rr_offset += 1; /* Max Delay */ proto_tree_add_item(tree, hf_icmpv6_rr_maxdelay, tvb, rr_offset, 2, FALSE); rr_offset += 2; /* Reserved */ proto_tree_add_item(tree, hf_icmpv6_reserved, tvb, rr_offset, 4, FALSE); rr_offset += 4; /* Data ? */ if(tvb_reported_length_remaining(tvb, rr_offset) == 0){ return; } if(icmp6_code == ICMP6_ROUTER_RENUMBERING_COMMAND){ /* Match-Prefix Part */ guint8 opcode, oplength, matchlen, minlen, maxlen; struct e_in6_addr matchprefix; ti_mp = proto_tree_add_item(tree, hf_icmpv6_rr_pco_mp_part, tvb, rr_offset, 24, FALSE); mp_tree = proto_item_add_subtree(ti_mp, ett_icmpv6opt); /* OpCode */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_opcode, tvb, rr_offset, 1, FALSE); opcode = tvb_get_guint8(tvb, rr_offset); rr_offset += 1; /* OpLength */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_oplength, tvb, rr_offset, 1, FALSE); oplength = tvb_get_guint8(tvb, rr_offset); rr_offset += 1; /* Ordinal */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_ordinal, tvb, rr_offset, 1, FALSE); rr_offset += 1; /* MatchLen */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchlen, tvb, rr_offset, 1, FALSE); matchlen = tvb_get_guint8(tvb, rr_offset); rr_offset += 1; /* MinLen */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_minlen, tvb, rr_offset, 1, FALSE); minlen = tvb_get_guint8(tvb, rr_offset); rr_offset += 1; /* MaxLen */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_maxlen, tvb, rr_offset, 1, FALSE); maxlen = tvb_get_guint8(tvb, rr_offset); rr_offset += 1; /* Reserved */ proto_tree_add_item(mp_tree, hf_icmpv6_reserved, tvb, rr_offset, 2, FALSE); rr_offset += 2; /* Match Prefix */ proto_tree_add_item(mp_tree, hf_icmpv6_rr_pco_mp_matchprefix, tvb, rr_offset, 16, FALSE); tvb_get_ipv6(tvb, rr_offset, &matchprefix); rr_offset += 16; /* Add Info (Prefix, Length...) to Match Prefix Part label */ proto_item_append_text(ti_mp, ": %s %s/%u (%u-%u)", val_to_str(opcode, rr_pco_mp_opcode_val, "Unknown %d"), ip6_to_str(&matchprefix), matchlen, minlen, maxlen); while ((int)tvb_reported_length(tvb) > rr_offset) { /* Use-Prefix Part */ guint8 uselen, keeplen; struct e_in6_addr useprefix; ti_up = proto_tree_add_item(tree, hf_icmpv6_rr_pco_up_part, tvb, rr_offset, 32, FALSE); up_tree = proto_item_add_subtree(ti_up, ett_icmpv6opt); /* UseLen */ proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_uselen, tvb, rr_offset, 1, FALSE); uselen = tvb_get_guint8(tvb, rr_offset); rr_offset += 1; /* KeepLen */ proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_keeplen, tvb, rr_offset, 1, FALSE); keeplen = tvb_get_guint8(tvb, rr_offset); rr_offset += 1; /* FlagMask */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flagmask, tvb, rr_offset, 1, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_l, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_a, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flagmask_reserved, tvb, rr_offset, 1, FALSE); rr_offset += 1; /* RaFlags */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_raflags, tvb, rr_offset, 1, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_l, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_a, tvb, rr_offset, 1, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_raflags_reserved, tvb, rr_offset, 1, FALSE); rr_offset += 1; /* Valid Lifetime */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_validlifetime, tvb, rr_offset, 4, FALSE); switch(tvb_get_ntohl(tvb, rr_offset)){ case 0xffffffff: proto_item_append_text(ti, " (Infinity)"); break; default: break; } rr_offset += 4; /* Preferred Lifetime */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_preferredlifetime, tvb, rr_offset, 4, FALSE); switch(tvb_get_ntohl(tvb, rr_offset)){ case 0xffffffff: proto_item_append_text(ti, " (Infinity)"); break; default: break; } rr_offset += 4; /* Flags */ ti = proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_flag, tvb, rr_offset, 4, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_v, tvb, rr_offset, 4, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_p, tvb, rr_offset, 4, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_pco_up_flag_reserved, tvb, rr_offset, 4, FALSE); rr_offset += 4; /* UsePrefix */ proto_tree_add_item(up_tree, hf_icmpv6_rr_pco_up_useprefix, tvb, rr_offset, 16, FALSE); tvb_get_ipv6(tvb, rr_offset, &useprefix); rr_offset += 16; /* Add Info (Prefix, Length...) to Use Prefix Part label */ proto_item_append_text(ti_up, ": %s/%u (keep %u)", ip6_to_str(&useprefix), uselen, keeplen); } }else if(icmp6_code == ICMP6_ROUTER_RENUMBERING_RESULT){ while ((int)tvb_reported_length(tvb) > rr_offset) { guint8 matchlen; guint32 interfaceindex; struct e_in6_addr matchedprefix; /* Result Message */ ti_rm = proto_tree_add_item(tree, hf_icmpv6_rr_rm, tvb, rr_offset, 24, FALSE); rm_tree = proto_item_add_subtree(ti_rm, ett_icmpv6opt); /* Flags */ ti = proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_flag, tvb, rr_offset, 2, FALSE); flag_tree = proto_item_add_subtree(ti, ett_icmpv6flag); proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_b, tvb, rr_offset, 2, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_f, tvb, rr_offset, 2, FALSE); proto_tree_add_item(flag_tree, hf_icmpv6_rr_rm_flag_reserved, tvb, rr_offset, 2, FALSE); rr_offset +=2; /* Ordinal */ proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_ordinal, tvb, rr_offset, 1, FALSE); rr_offset +=1; /* MatchLen */ proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedlen, tvb, rr_offset, 1, FALSE); matchlen = tvb_get_guint8(tvb, rr_offset); rr_offset +=1; /* InterfaceIndex */ proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_interfaceindex, tvb, rr_offset, 4, FALSE); interfaceindex = tvb_get_ntohl(tvb, rr_offset); rr_offset +=4; /* MatchedPrefix */ proto_tree_add_item(rm_tree, hf_icmpv6_rr_rm_matchedprefix, tvb, rr_offset, 16, FALSE); tvb_get_ipv6(tvb, rr_offset, &matchedprefix); rr_offset +=16; /* Add Info (Prefix, Length...) to Use Resultat Message label */ proto_item_append_text(ti_rm, ": %s/%u (interface %u)", ip6_to_str(&matchedprefix), matchlen, interfaceindex); } } } static void dissect_mldrv2( tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tree *tree ) { proto_tree *mar_tree; proto_item *ti_mar; guint16 nb_mcast_records; int mldr_offset = offset; /* Reserved */ proto_tree_add_item(tree, hf_icmpv6_reserved, tvb, mldr_offset, 2, FALSE ); mldr_offset += 2; /* Nr of Mcast Address Records (M) */ proto_tree_add_item(tree, hf_icmpv6_mldr_nb_mcast_records, tvb, mldr_offset, 2, FALSE ); nb_mcast_records = tvb_get_ntohs(tvb, mldr_offset); mldr_offset += 2; /* Multicast Address Record */ while(mldr_offset < (int)tvb_reported_length(tvb) ) { guint8 aux_data_len, record_type; guint16 i, nb_sources; struct e_in6_addr multicast_address; 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_icmpv6mar); /* 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); mldr_offset += 1; /* Aux Data Len */ proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_aux_data_len, tvb, mldr_offset, 1, FALSE); aux_data_len = tvb_get_guint8(tvb, mldr_offset); mldr_offset += 1; /* Number of Sources (N) */ proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_nb_sources, tvb, mldr_offset, 2, FALSE); nb_sources = tvb_get_ntohs(tvb, mldr_offset); mldr_offset += 2; /* Multicast Address */ 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++){ 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) { proto_tree_add_item(mar_tree, hf_icmpv6_mldr_mar_auxiliary_data, tvb, mldr_offset, aux_data_len * 4, FALSE); mldr_offset += aux_data_len * 4; } /* Multicast Address Record Length */ proto_item_set_len(ti_mar, 4 + 16 + (16 * nb_sources) + (aux_data_len * 4)); proto_item_append_text(ti_mar, " %s: %s", val_to_str(record_type, mldr_record_type_val,"Unknown Record Type (%d)"), ip6_to_str(&multicast_address)); } } static void dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *icmp6_tree, *field_tree, *flag_tree; proto_item *ti, *hidden_item, *tf, *ti_flag = NULL; struct icmp6_hdr icmp6_hdr, *dp; const char *codename, *typename; const char *colcodename, *coltypename; int len; guint length, reported_length; vec_t cksum_vec[4]; guint32 phdr[2]; guint16 cksum, computed_cksum; int offset; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICMPv6"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; tvb_memcpy(tvb, (guint8 *)&icmp6_hdr, offset, sizeof icmp6_hdr); dp = &icmp6_hdr; typename = coltypename = val_to_str (dp->icmp6_type, icmpv6_type_str, "Unknown"); codename = colcodename = NULL; len = sizeof(*dp); switch (dp->icmp6_type) { case ICMP6_DST_UNREACH: codename = colcodename = val_to_str (dp->icmp6_code, icmpv6_unreach_code_str, "Unknown"); break; case ICMP6_TIME_EXCEEDED: codename = colcodename = val_to_str (dp->icmp6_code, icmpv6_timeex_code_str, "Unknown"); break; case ICMP6_PARAM_PROB: codename = colcodename = val_to_str (dp->icmp6_code, icmpv6_paramprob_code_str, "Unknown"); break; case ND_ROUTER_SOLICIT: len = sizeof(struct nd_router_solicit); break; case ND_ROUTER_ADVERT: len = sizeof(struct nd_router_advert); break; case ND_NEIGHBOR_SOLICIT: len = sizeof(struct nd_neighbor_solicit); break; case ND_NEIGHBOR_ADVERT: len = sizeof(struct nd_neighbor_advert); break; case ND_REDIRECT: len = sizeof(struct nd_redirect); break; case ICMP6_ROUTER_RENUMBERING: codename = colcodename = val_to_str (dp->icmp6_code, icmpv6_router_renum_code_str, "Unknown"); len = 16; break; case ICMP6_NI_QUERY: case ICMP6_NI_REPLY: { struct icmp6_nodeinfo icmp6_nodeinfo, *ni; ni = &icmp6_nodeinfo; tvb_memcpy(tvb, (guint8 *)ni, offset, sizeof *ni); if (ni->ni_type == ICMP6_NI_QUERY) { switch (ni->ni_code) { case ICMP6_NI_SUBJ_IPV6: codename = "Query subject = IPv6 addresses"; break; case ICMP6_NI_SUBJ_FQDN: if (tvb_bytes_exist(tvb, offset, sizeof(*ni))) codename = "Query subject = DNS name"; else codename = "Query subject = empty"; break; case ICMP6_NI_SUBJ_IPV4: codename = "Query subject = IPv4 addresses"; break; default: codename = "Unknown"; break; } } else { switch (ni->ni_code) { case ICMP6_NI_SUCCESS: codename = "Successful"; break; case ICMP6_NI_REFUSED: codename = "Refused"; break; case ICMP6_NI_UNKNOWN: codename = "Unknown query type"; break; default: codename = "Unknown"; break; } } colcodename = val_to_str(pntohs(&ni->ni_qtype), ni_qtype_val, "Unknown"); len = sizeof(struct icmp6_nodeinfo); break; } case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: case ICMP6_MEMBERSHIP_REPORT: case ICMP6_MIP6_DHAAD_REQUEST: case ICMP6_MIP6_DHAAD_REPLY: case ICMP6_MIP6_MPS: case ICMP6_MIP6_MPA: case ICMP6_CERT_PATH_SOL: case ICMP6_CERT_PATH_AD: case ICMP6_MLDV2_REPORT: codename = "Should always be zero"; break; case ICMP6_EXPERIMENTAL_MOBILITY: switch (dp->icmp6_data8[0]) { case FMIP6_SUBTYPE_RTSOLPR: typename = coltypename = "RtSolPr (ICMPv6 Experimental Mobility)"; codename = "Should always be zero"; break; case FMIP6_SUBTYPE_PRRTADV: typename = coltypename = "PrRtAdv (ICMPv6 Experimental Mobility)"; codename = val_to_str(dp->icmp6_code, names_fmip6_prrtadv_code, "Unknown"); break; case FMIP6_SUBTYPE_HI: typename = coltypename = "HI (ICMPv6 Experimental Mobility)"; codename = val_to_str(dp->icmp6_code, names_fmip6_hi_code, "Unknown"); break; case FMIP6_SUBTYPE_HACK: typename = coltypename = "HAck (ICMPv6 Experimental Mobility)"; codename = val_to_str(dp->icmp6_code, names_fmip6_hack_code, "Unknown"); break; default: codename = colcodename = "Unknown"; break; } /* switch (dp->icmp6_data8[0]) */ break; case ICMP6_RPL_CONTROL: codename = colcodename = val_to_str (dp->icmp6_code, names_rpl_code, "Unknown"); break; default: codename = colcodename = "Unknown"; break; } /* switch (dp->icmp6_type) */ if (check_col(pinfo->cinfo, COL_INFO)) { char typebuf[256], codebuf[256]; if (pinfo->destport == 0x0dd8 && dp->icmp6_type == ICMP6_ECHO_REQUEST) { /* RFC 4380 * 5.2.9. Direct IPv6 Connectivity Test */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Teredo"); col_set_str(pinfo->cinfo, COL_INFO, "Direct IPv6 Connectivity Test"); } else { if (coltypename && strcmp(coltypename, "Unknown") == 0) { g_snprintf(typebuf, sizeof(typebuf), "Unknown (0x%02x)", dp->icmp6_type); coltypename = typebuf; } if (colcodename && strcmp(colcodename, "Unknown") == 0) { g_snprintf(codebuf, sizeof(codebuf), "Unknown (0x%02x)", dp->icmp6_code); colcodename = codebuf; } if (colcodename) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s (%s)", coltypename, colcodename); } else { col_add_str(pinfo->cinfo, COL_INFO, coltypename); } } } if (tree) { /* !!! specify length */ ti = proto_tree_add_item(tree, proto_icmpv6, tvb, offset, -1, FALSE); icmp6_tree = proto_item_add_subtree(ti, ett_icmpv6); proto_tree_add_uint_format(icmp6_tree, hf_icmpv6_type, tvb, offset + offsetof(struct icmp6_hdr, icmp6_type), 1, dp->icmp6_type, "Type: %u (%s)", dp->icmp6_type, typename); if (codename) { proto_tree_add_uint_format(icmp6_tree, hf_icmpv6_code, tvb, offset + offsetof(struct icmp6_hdr, icmp6_code), 1, dp->icmp6_code, "Code: %u (%s)", dp->icmp6_code, codename); } else { proto_tree_add_uint_format(icmp6_tree, hf_icmpv6_code, tvb, offset + offsetof(struct icmp6_hdr, icmp6_code), 1, dp->icmp6_code, "Code: %u", dp->icmp6_code); } cksum = (guint16)g_htons(dp->icmp6_cksum); length = tvb_length(tvb); reported_length = tvb_reported_length(tvb); if (!pinfo->fragmented && length >= reported_length) { /* The packet isn't part of a fragmented datagram and isn't truncated, so we can checksum it. */ /* Set up the fields of the pseudo-header. */ cksum_vec[0].ptr = pinfo->src.data; cksum_vec[0].len = pinfo->src.len; cksum_vec[1].ptr = pinfo->dst.data; cksum_vec[1].len = pinfo->dst.len; cksum_vec[2].ptr = (const guint8 *)&phdr; phdr[0] = g_htonl(tvb_reported_length(tvb)); phdr[1] = g_htonl(IP_PROTO_ICMPV6); cksum_vec[2].len = 8; cksum_vec[3].len = tvb_reported_length(tvb); cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, cksum_vec[3].len); computed_cksum = in_cksum(cksum_vec, 4); if (computed_cksum == 0) { proto_tree_add_uint_format(icmp6_tree, hf_icmpv6_checksum, tvb, offset + offsetof(struct icmp6_hdr, icmp6_cksum), 2, cksum, "Checksum: 0x%04x [correct]", cksum); } else { hidden_item = proto_tree_add_boolean(icmp6_tree, hf_icmpv6_checksum_bad, tvb, offset + offsetof(struct icmp6_hdr, icmp6_cksum), 2, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_uint_format(icmp6_tree, hf_icmpv6_checksum, tvb, offset + offsetof(struct icmp6_hdr, icmp6_cksum), 2, cksum, "Checksum: 0x%04x [incorrect, should be 0x%04x]", cksum, in_cksum_shouldbe(cksum, computed_cksum)); } } else { proto_tree_add_uint(icmp6_tree, hf_icmpv6_checksum, tvb, offset + offsetof(struct icmp6_hdr, icmp6_cksum), 2, cksum); } #define ICMP6_DATA_OFFSET 4 #define ICMP6_SEQ_OFFSET 6 /* decode... */ switch (dp->icmp6_type) { case ICMP6_DST_UNREACH: case ICMP6_TIME_EXCEEDED: dissect_contained_icmpv6(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; case ICMP6_PACKET_TOO_BIG: proto_tree_add_text(icmp6_tree, tvb, offset + ICMP6_DATA_OFFSET, 4, "MTU: %u", pntohl(&dp->icmp6_mtu)); dissect_contained_icmpv6(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; case ICMP6_PARAM_PROB: proto_tree_add_text(icmp6_tree, tvb, offset + ICMP6_DATA_OFFSET, 4, "Problem pointer: 0x%04x", pntohl(&dp->icmp6_pptr)); dissect_contained_icmpv6(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: proto_tree_add_text(icmp6_tree, tvb, offset + ICMP6_DATA_OFFSET, 2, "ID: 0x%04x", (guint16)g_ntohs(dp->icmp6_id)); proto_tree_add_text(icmp6_tree, tvb, offset + ICMP6_SEQ_OFFSET, 2, "Sequence: %u", (guint16)g_ntohs(dp->icmp6_seq)); col_append_fstr(pinfo->cinfo, COL_INFO, " id=0x%04x, seq=%u", g_ntohs(dp->icmp6_id), g_ntohs(dp->icmp6_seq)); if (pinfo->destport == 0x0dd8 && dp->icmp6_type == ICMP6_ECHO_REQUEST) { /* RFC 4380 * 5.2.9. Direct IPv6 Connectivity Test */ proto_tree_add_text(icmp6_tree, tvb, offset + ICMP6_SEQ_OFFSET + 2, 4, "Nonce: 0x%08x", tvb_get_ntohl(tvb, offset + ICMP6_SEQ_OFFSET + 2)); } else { next_tvb = tvb_new_subset(tvb, offset + sizeof(*dp), -1, -1); call_dissector(data_handle,next_tvb, pinfo, icmp6_tree); } break; case ICMP6_MEMBERSHIP_QUERY: case ICMP6_MEMBERSHIP_REPORT: case ICMP6_MEMBERSHIP_REDUCTION: offset += 4; /* It is MLDv2 packet ? (the min length for a MLDv2 packet is 28) */ if ((dp->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); offset += 2; /* Multicast Address */ proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, FALSE); offset += 16; /* 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_icmpv6flag); 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; /* Multicast Address */ proto_tree_add_item(icmp6_tree, hf_icmpv6_mld_multicast_address, tvb, offset, 16, FALSE); offset += 16; } break; case ND_ROUTER_SOLICIT: dissect_icmpv6ndopt(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; case ICMP6_MLDV2_REPORT: { dissect_mldrv2( tvb, offset+4, pinfo, icmp6_tree ); break; } #define ND_RA_CURHOPLIMIT_OFFSET 4 #define ND_RA_FLAGS_RESERVED_OFFSET 5 #define ND_RA_ROUTER_LIFETIME_OFFSET 6 case ND_ROUTER_ADVERT: { struct nd_router_advert nd_router_advert, *ra; int flagoff; guint32 ra_flags; ra = &nd_router_advert; tvb_memcpy(tvb, (guint8 *)ra, offset, sizeof *ra); /* Current hop limit */ proto_tree_add_uint(icmp6_tree, hf_icmpv6_ra_cur_hop_limit, tvb, offset + ND_RA_CURHOPLIMIT_OFFSET, 1, ra->nd_ra_curhoplimit); /* Flags */ flagoff = offset + ND_RA_FLAGS_RESERVED_OFFSET; ra_flags = tvb_get_guint8(tvb, flagoff); tf = proto_tree_add_text(icmp6_tree, tvb, flagoff, 1, "Flags: 0x%02x", ra_flags); field_tree = proto_item_add_subtree(tf, ett_icmpv6flag); proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", decode_boolean_bitfield(ra_flags, ND_RA_FLAG_MANAGED, 8, "Managed", "Not managed")); proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", decode_boolean_bitfield(ra_flags, ND_RA_FLAG_OTHER, 8, "Other", "Not other")); proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", decode_boolean_bitfield(ra_flags, ND_RA_FLAG_HOME_AGENT, 8, "Home Agent", "Not Home Agent")); proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", decode_enumerated_bitfield(ra_flags, ND_RA_FLAG_RTPREF_MASK, 8, names_router_pref, "Router preference: %s")); proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", decode_boolean_bitfield(ra_flags, ND_RA_FLAG_ND_PROXY, 8, "Proxied", "Not Proxied")); /* Router lifetime */ proto_tree_add_uint(icmp6_tree, hf_icmpv6_ra_router_lifetime, tvb, offset + ND_RA_ROUTER_LIFETIME_OFFSET, 2, (guint16)g_ntohs(ra->nd_ra_router_lifetime)); /* Reachable time */ proto_tree_add_uint(icmp6_tree, hf_icmpv6_ra_reachable_time, tvb, offset + offsetof(struct nd_router_advert, nd_ra_reachable), 4, pntohl(&ra->nd_ra_reachable)); /* Retrans timer */ proto_tree_add_uint(icmp6_tree, hf_icmpv6_ra_retrans_timer, tvb, offset + offsetof(struct nd_router_advert, nd_ra_retransmit), 4, pntohl(&ra->nd_ra_retransmit)); dissect_icmpv6ndopt(tvb, offset + sizeof(struct nd_router_advert), pinfo, icmp6_tree); break; } case ND_NEIGHBOR_SOLICIT: { struct nd_neighbor_solicit nd_neighbor_solicit, *ns; ns = &nd_neighbor_solicit; tvb_memcpy(tvb, (guint8 *)ns, offset, sizeof *ns); proto_tree_add_text(icmp6_tree, tvb, offset+4, 4, "Reserved: %d (Should always be zero)", tvb_get_ntohl (tvb, offset+4)); proto_tree_add_text(icmp6_tree, tvb, offset + offsetof(struct nd_neighbor_solicit, nd_ns_target), 16, "Target: %s (%s)", get_hostname6(&ns->nd_ns_target), ip6_to_str(&ns->nd_ns_target)); col_append_fstr(pinfo->cinfo, COL_INFO, " for %s", ip6_to_str(&ns->nd_ns_target)); dissect_icmpv6ndopt(tvb, offset + sizeof(*ns), pinfo, icmp6_tree); break; } #define ND_NA_FLAGS_RESERVED_OFFSET 4 case ND_NEIGHBOR_ADVERT: { int flagoff, targetoff; guint32 na_flags; struct e_in6_addr na_target; emem_strbuf_t *flags_strbuf = ep_strbuf_new_label(""); flagoff = offset + ND_NA_FLAGS_RESERVED_OFFSET; na_flags = tvb_get_ntohl(tvb, flagoff); tf = proto_tree_add_text(icmp6_tree, tvb, flagoff, 4, "Flags: 0x%08x", na_flags); field_tree = proto_item_add_subtree(tf, ett_icmpv6flag); proto_tree_add_text(field_tree, tvb, flagoff, 4, "%s", decode_boolean_bitfield(na_flags, ND_NA_FLAG_ROUTER, 32, "Router", "Not router")); proto_tree_add_text(field_tree, tvb, flagoff, 4, "%s", decode_boolean_bitfield(na_flags, ND_NA_FLAG_SOLICITED, 32, "Solicited", "Not adverted")); proto_tree_add_text(field_tree, tvb, flagoff, 4, "%s", decode_boolean_bitfield(na_flags, ND_NA_FLAG_OVERRIDE, 32, "Override", "Not override")); targetoff = offset + offsetof(struct nd_neighbor_advert, nd_na_target); tvb_memcpy(tvb, (guint8 *)&na_target, targetoff, sizeof na_target); proto_tree_add_text(icmp6_tree, tvb, targetoff, 16, "Target: %s (%s)", get_hostname6(&na_target), ip6_to_str(&na_target)); if (na_flags & ND_NA_FLAG_ROUTER) { ep_strbuf_append(flags_strbuf, "rtr, "); } if (na_flags & ND_NA_FLAG_SOLICITED) { ep_strbuf_append(flags_strbuf, "sol, "); } if (na_flags & ND_NA_FLAG_OVERRIDE) { 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)", ip6_to_str(&na_target), flags_strbuf->str); dissect_icmpv6ndopt(tvb, offset + sizeof(struct nd_neighbor_advert), pinfo, icmp6_tree); break; } case ND_REDIRECT: { struct nd_redirect nd_redirect, *rd; rd = &nd_redirect; tvb_memcpy(tvb, (guint8 *)rd, offset, sizeof *rd); proto_tree_add_text(icmp6_tree, tvb, offset+4, 4, "Reserved: %d (Should always be zero)", tvb_get_ntohs (tvb, offset+4)); proto_tree_add_text(icmp6_tree, tvb, offset + offsetof(struct nd_redirect, nd_rd_target), 16, "Target: %s (%s)", get_hostname6(&rd->nd_rd_target), ip6_to_str(&rd->nd_rd_target)); proto_tree_add_text(icmp6_tree, tvb, offset + offsetof(struct nd_redirect, nd_rd_dst), 16, "Destination: %s (%s)", get_hostname6(&rd->nd_rd_dst), ip6_to_str(&rd->nd_rd_dst)); dissect_icmpv6ndopt(tvb, offset + sizeof(*rd), pinfo, icmp6_tree); break; } case ICMP6_ROUTER_RENUMBERING: dissect_rrenum(tvb, offset, pinfo, icmp6_tree, dp->icmp6_type, dp->icmp6_code); break; case ICMP6_NI_QUERY: case ICMP6_NI_REPLY: { dissect_nodeinfo(tvb, offset, pinfo, icmp6_tree, dp->icmp6_type, dp->icmp6_code); break; } case ICMP6_MIP6_DHAAD_REQUEST: proto_tree_add_text(icmp6_tree, tvb, offset + 4, 2, "Identifier: %d (0x%02x)", tvb_get_ntohs(tvb, offset + 4), tvb_get_ntohs(tvb, offset + 4)); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 2, "Reserved: %d", tvb_get_ntohs(tvb, offset + 6)); break; case ICMP6_MIP6_DHAAD_REPLY: proto_tree_add_text(icmp6_tree, tvb, offset + 4, 2, "Identifier: %d (0x%02x)", tvb_get_ntohs(tvb, offset + 4), tvb_get_ntohs(tvb, offset + 4)); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 2, "Reserved: %d", tvb_get_ntohs(tvb, offset + 6)); /* Show all Home Agent Addresses */ { int i, suboffset; int ha_num = (length - 8)/16; for (i = 0; i < ha_num; i++) { suboffset = 16 * i; proto_tree_add_ipv6(icmp6_tree, hf_icmpv6_haad_ha_addrs, tvb, offset + 8 + suboffset, 16, tvb_get_ptr(tvb, offset + 8 + suboffset, 16)); } } break; case ICMP6_MIP6_MPS: proto_tree_add_text(icmp6_tree, tvb, offset + 4, 2, "Identifier: %d (0x%02x)", tvb_get_ntohs(tvb, offset + 4), tvb_get_ntohs(tvb, offset + 4)); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 2, "Reserved: %d", tvb_get_ntohs(tvb, offset + 6)); break; case ICMP6_MIP6_MPA: proto_tree_add_text(icmp6_tree, tvb, offset + 4, 2, "Identifier: %d (0x%02x)", tvb_get_ntohs(tvb, offset + 4), tvb_get_ntohs(tvb, offset + 4)); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 1, "%s", decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 6), 0x80, 8, "Managed Address Configuration", "No Managed Address Configuration")); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 1, "%s", decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 6), 0x40, 8, "Other Stateful Configuration", "No Other Stateful Configuration")); proto_tree_add_text(icmp6_tree, tvb, offset + 7, 1, "Reserved: %d", tvb_get_guint8(tvb, offset + 7)); /* Show all options */ dissect_icmpv6ndopt(tvb, offset + 8, pinfo, icmp6_tree); break; case ICMP6_EXPERIMENTAL_MOBILITY: switch (dp->icmp6_data8[0]) { case FMIP6_SUBTYPE_RTSOLPR: { struct fmip6_rtsolpr *rtsolpr; rtsolpr = (struct fmip6_rtsolpr*) dp; proto_tree_add_text(icmp6_tree, tvb, offset + 4, 1, "Subtype: Router Solicitation for Proxy Advertisement"); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 2, "Identifier: %d", pntohs(&rtsolpr->fmip6_rtsolpr_id)); dissect_icmpv6ndopt(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; } case FMIP6_SUBTYPE_PRRTADV: { struct fmip6_prrtadv *prrtadv; prrtadv = (struct fmip6_prrtadv*) dp; proto_tree_add_text(icmp6_tree, tvb, offset + 4, 1, "Subtype: Proxy Router Advertisement"); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 2, "Identifier: %d", pntohs(&prrtadv->fmip6_prrtadv_id)); dissect_icmpv6ndopt(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; } case FMIP6_SUBTYPE_HI: { struct fmip6_hi *hi; int flagoff; guint8 hi_flags; hi = (struct fmip6_hi*) dp; proto_tree_add_text(icmp6_tree, tvb, offset + 4, 1, "Subtype: Handover Initiate"); flagoff = offset + 5; hi_flags = tvb_get_guint8(tvb, flagoff); tf = proto_tree_add_text(icmp6_tree, tvb, flagoff, 1, "Flags: 0x%02x", hi_flags); field_tree = proto_item_add_subtree(tf, ett_icmpv6flag); proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", decode_boolean_bitfield(hi_flags, FMIP_HI_FLAG_ASSIGNED, 8, "Assigned", "Not assigned")); proto_tree_add_text(field_tree, tvb, flagoff, 1, "%s", decode_boolean_bitfield(hi_flags, FMIP_HI_FLAG_BUFFER, 8, "Buffered", "Not buffered")); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 2, "Identifier: %d", pntohs(&hi->fmip6_hi_id)); dissect_icmpv6ndopt(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; } case FMIP6_SUBTYPE_HACK: { struct fmip6_hack *hack; hack = (struct fmip6_hack*) dp; proto_tree_add_text(icmp6_tree, tvb, offset + 4, 1, "Subtype: Handover Acknowledge"); proto_tree_add_text(icmp6_tree, tvb, offset + 6, 2, "Identifier: %d", pntohs(&hack->fmip6_hack_id)); dissect_icmpv6ndopt(tvb, offset + sizeof(*dp), pinfo, icmp6_tree); break; } } /* switch (dp->icmp6_data8[0]) */ break; case ICMP6_CERT_PATH_SOL: /*RFC 3971 6.4.1. Certification Path Solicitation Message Format */ offset += 4; proto_tree_add_text(icmp6_tree, tvb, offset, -1, "Certification Path Solicitation Message"); /* Identifier A 16-bit unsigned integer field */ proto_tree_add_item(icmp6_tree, hf_icmpv6_identifier, tvb, offset, 2, FALSE); offset += 2; /* Component A 16-bit unsigned integer field, * 65,535 if the sender seeks to retrieve all certificates. * Otherwise, set to the identifier that the receiver wants. */ proto_tree_add_item(icmp6_tree, hf_icmpv6_comp, tvb, offset, 2, FALSE); offset += 2; dissect_icmpv6ndopt(tvb, offset, pinfo, icmp6_tree); break; case ICMP6_CERT_PATH_AD: /*RFC 3971 6.4.2. Certification Path Advertisement Message Format */ offset = offset +4; proto_tree_add_text(icmp6_tree, tvb, offset, -1,"Certification Path Advertisement Message"); /* Identifier A 16-bit unsigned integer field */ proto_tree_add_item(icmp6_tree, hf_icmpv6_identifier, tvb, offset, 2, FALSE); offset = offset + 2; /* All Components A 16-bit unsigned integer field*/ proto_tree_add_item(icmp6_tree, hf_icmpv6_all_comp, tvb, offset, 2, FALSE); offset = offset + 2; /* Component A 16-bit unsigned integer field, used to inform the receiver * which certificate is being sent. */ proto_tree_add_item(icmp6_tree, hf_icmpv6_comp, tvb, offset, 2, FALSE); offset = offset + 2; /* Reserved */ proto_tree_add_text(icmp6_tree, tvb, offset, 2,"Reserved"); offset = offset + 2; dissect_icmpv6ndopt(tvb, offset, pinfo, icmp6_tree); break; case ICMP6_RPL_CONTROL: /* RPL: draft-ietf-roll-rpl-12.txt: Routing over Low-Power and Lossy Networks. */ offset += 4; /* Skip the type, code and checksum. */ if (dp->icmp6_code == ICMP6_RPL_DIS) { /* Reserved */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dis_reserved, tvb, offset, 2, FALSE); offset += 2; } else if (dp->icmp6_code == ICMP6_RPL_DIO) { /* DODAG Information Object */ guint8 flags; /* RPLInstanceID */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dio_instance, tvb, offset, 1, FALSE); offset += 1; /* RPLInstanceID */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dio_version, tvb, offset, 1, FALSE); offset += 1; /* Rank */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dio_rank, tvb, offset, 2, FALSE); offset += 2; /* flags */ flags = tvb_get_guint8(tvb, offset); proto_tree_add_boolean(icmp6_tree, hf_icmpv6_dio_grounded, tvb, offset, 1, flags & RPL_DIO_FLAG_GROUNDED); proto_tree_add_boolean(icmp6_tree, hf_icmpv6_dio_zero, tvb, offset, 1, flags & RPL_DIO_FLAG_ZERO); proto_tree_add_uint(icmp6_tree, hf_icmpv6_dio_mop, tvb, offset, 1, flags & RPL_DIO_FLAG_MOP); proto_tree_add_uint(icmp6_tree, hf_icmpv6_dio_preference, tvb, offset, 1, flags & RPL_DIO_FLAG_PREFERENCE); offset += 1; /* Destination Advertisement Trigger Sequence Number (DTSN) */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dio_trigger_seqnum, tvb, offset, 1, FALSE); offset += 1; offset += 2; /* DODAGID */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dio_dagid, tvb, offset, 16, FALSE); offset += 16; } else if (dp->icmp6_code == ICMP6_RPL_DAO) { /* Destination Advertisement Object */ struct e_in6_addr addr6; guint8 flags; /* DAO Instance */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dao_instance, tvb, offset, 1, FALSE); offset += 1; /* flags */ flags = tvb_get_guint8(tvb, offset); proto_tree_add_boolean(icmp6_tree, hf_icmpv6_dao_flag_k, tvb, offset, 1, flags & RPL_DAO_FLAG_K); proto_tree_add_boolean(icmp6_tree, hf_icmpv6_dao_flag_d, tvb, offset, 1, flags & RPL_DAO_FLAG_D); proto_tree_add_uint(icmp6_tree, hf_icmpv6_dao_flag_rsv, tvb, offset, 1, flags & RPL_DAO_FLAG_RESERVED); offset += 1; /* DAO Reserved */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dao_reserved, tvb, offset, 1, FALSE); offset += 1; /* DAO Reserved */ proto_tree_add_item(icmp6_tree, hf_icmpv6_dao_seqnum, tvb, offset, 1, FALSE); offset += 1; if(flags & RPL_DAO_FLAG_D) { tvb_memcpy(tvb, addr6.bytes, offset, 16); proto_tree_add_ipv6(icmp6_tree, hf_icmpv6_dao_dodagid, tvb, offset, 16, addr6.bytes); offset += 16; } } else if (dp->icmp6_code == ICMP6_RPL_DAOACK) { /* Destination Advertisement Object */ struct e_in6_addr addr6; guint8 flags; /* DAO Instance */ proto_tree_add_item(icmp6_tree, hf_icmpv6_daoack_instance, tvb, offset, 1, FALSE); offset += 1; /* flags */ flags = tvb_get_guint8(tvb, offset); proto_tree_add_boolean(icmp6_tree, hf_icmpv6_daoack_flag_d, tvb, offset, 1, flags & RPL_DAOACK_FLAG_D); proto_tree_add_uint(icmp6_tree, hf_icmpv6_daoack_flag_rsv, tvb, offset, 1, flags & RPL_DAOACK_FLAG_RESERVED); offset += 1; /* DAO Sequence */ proto_tree_add_item(icmp6_tree, hf_icmpv6_daoack_seqnum, tvb, offset, 1, FALSE); offset += 1; /* DAO Status */ proto_tree_add_item(icmp6_tree, hf_icmpv6_daoack_status, tvb, offset, 1, FALSE); offset += 1; if(flags & RPL_DAOACK_FLAG_D) { tvb_memcpy(tvb, addr6.bytes, offset, 16); proto_tree_add_ipv6(icmp6_tree, hf_icmpv6_daoack_dodagid, tvb, offset, 16, addr6.bytes); offset += 16; } return; } /* Options */ dissect_icmpv6_rpl_opt(tvb, offset, pinfo, icmp6_tree); break; default: next_tvb = tvb_new_subset(tvb, offset + sizeof(*dp), -1, -1); call_dissector(data_handle,next_tvb, pinfo, tree); break; } /* switch (dp->icmp6_type) */ } /* if (tree) */ } void proto_register_icmpv6(void) { static hf_register_info hf[] = { { &hf_icmpv6_type, { "Type", "icmpv6.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_code, { "Code", "icmpv6.code", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_checksum, { "Checksum", "icmpv6.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_checksum_bad, { "Bad Checksum", "icmpv6.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_reserved, { "Reserved", "icmpv6.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, "Must be Zero", HFILL }}, /* RFC2710: Multicast Listener Discovery for IPv6 */ { &hf_icmpv6_mld_mrd, { "Maximum Response Delay [ms]", "icmpv6.mld.maximum_response_delay", FT_UINT16, BASE_DEC, NULL, 0x0, "Specifies the maximum allowed delay before sending a responding Report, in units of milliseconds", HFILL }}, { &hf_icmpv6_mld_multicast_address, { "Multicast Address", "icmpv6.mld.multicast_address", FT_IPv6, BASE_NONE, NULL, 0x0, "Specific IPv6 multicast address", HFILL }}, /* RFC3810: Multicast Listener Discovery Version 2 (MLDv2) for IPv6 */ { &hf_icmpv6_mld_mrc, { "Maximum Response Code", "icmpv6.mld.maximum_response_code", FT_UINT16, BASE_DEC, NULL, 0x0, "Specifies the maximum allowed delay before sending a responding Report", HFILL }}, { &hf_icmpv6_mld_flag, { "Flags", "icmpv6.mld.flag", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_mld_flag_s, { "Suppress Router-Side Processing", "icmpv6.mld.flag.s", FT_BOOLEAN, 8, NULL, MLD_FLAG_S, "Indicates to any receiving multicast routers that they have to suppress the normal timer updates they perform upon hearing a Query", HFILL }}, { &hf_icmpv6_mld_flag_qrv, { "QRV (Querier's Robustness Variable)", "icmpv6.mld.flag.qrv", FT_UINT8, BASE_DEC, NULL, MLD_FLAG_QRV, "Contains the RV (Robustness Variable) value used by the Querier", HFILL }}, { &hf_icmpv6_mld_flag_rsv, { "Reserved", "icmpv6.mld.flag.reserved", FT_UINT8, BASE_DEC, NULL, MLD_FLAG_RSV, "Must Be Zero", HFILL }}, { &hf_icmpv6_mld_qqi, { "QQIC (Querier's Query Interval Code)", "icmpv6.mld.qqi", FT_UINT8, BASE_DEC, NULL, 0x0, "Specifies the QI (Query Interval) used by the Querier", HFILL }}, { &hf_icmpv6_mld_nb_sources, { "Number of Sources", "icmpv6.mld.nb_sources", FT_UINT16, BASE_DEC, NULL, 0x0, "Specifies how many source addresses are present in the Query", HFILL }}, { &hf_icmpv6_mld_source_address, { "Source Address", "icmpv6.mld.source_address", FT_IPv6, BASE_NONE, NULL, 0x0, "The Source Address fields are a vector of unicast addresses", HFILL }}, { &hf_icmpv6_mldr_nb_mcast_records, { "Number of Multicast Address Records", "icmpv6.mldr.nb_mcast_records", FT_UINT16, BASE_DEC, NULL, 0x0, "Specifies how many Multicast Address Records are present in this Report", HFILL }}, { &hf_icmpv6_mldr_mar, { "Multicast Address Record", "icmpv6.mldr.mar", FT_NONE, BASE_NONE, NULL, 0x0, "Each Multicast Address Record is a block of fields that contain information on the sender listening to a single multicast address on the interface from which the Report is sent", HFILL }}, { &hf_icmpv6_mldr_mar_record_type, { "Record Type", "icmpv6.mldr.mar.record_type", FT_UINT8, BASE_DEC, VALS(mldr_record_type_val), 0x0, "It specifies the type of the Multicast Address Record", HFILL }}, { &hf_icmpv6_mldr_mar_aux_data_len, { "Aux Data Len", "icmpv6.mldr.mar.aux_data_len", FT_UINT8, BASE_DEC, NULL, 0x0, "The Aux Data Len field contains the length (in units of 32-bit words) of the Auxiliary Data Field in this Multicast Address Record", HFILL }}, { &hf_icmpv6_mldr_mar_nb_sources, { "Number of Sources", "icmpv6.mldr.mar.nb_sources", FT_UINT16, BASE_DEC, NULL, 0x0, "The Number of Sources field specifies how many source addresses are present in this Multicast Address Record", HFILL }}, { &hf_icmpv6_mldr_mar_multicast_address, { "Multicast Address", "icmpv6.mldr.mar.multicast_address", FT_IPv6, BASE_NONE, NULL, 0x0, "The Multicast Address field contains the multicast address to which this Multicast Address Record pertains", HFILL }}, { &hf_icmpv6_mldr_mar_source_address, { "Source Address", "icmpv6.mldr.mar.source_address", FT_IPv6, BASE_NONE, NULL, 0x0, "The Source Address fields are a vector of unicast addresses", HFILL }}, { &hf_icmpv6_mldr_mar_auxiliary_data, { "Auxiliary Data", "icmpv6.mldr.mar.auxiliary_data", FT_BYTES, BASE_NONE, NULL, 0x0, "Contains additional information that pertain to this Multicast Address Record", HFILL }}, { &hf_icmpv6_haad_ha_addrs, { "Home Agent Addresses", "icmpv6.haad.ha_addrs", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_ra_cur_hop_limit, { "Cur hop limit", "icmpv6.ra.cur_hop_limit", FT_UINT8, BASE_DEC, NULL, 0x0, "Current hop limit", HFILL }}, { &hf_icmpv6_ra_router_lifetime, { "Router lifetime", "icmpv6.ra.router_lifetime", FT_UINT16, BASE_DEC, NULL, 0x0, "Router lifetime (s)", HFILL }}, { &hf_icmpv6_ra_reachable_time, { "Reachable time", "icmpv6.ra.reachable_time", FT_UINT32, BASE_DEC, NULL, 0x0, "Reachable time (ms)", HFILL }}, { &hf_icmpv6_ra_retrans_timer, { "Retrans timer", "icmpv6.ra.retrans_timer", FT_UINT32, BASE_DEC, NULL, 0x0, "Retrans timer (ms)", HFILL }}, { &hf_icmpv6_opt, { "ICMPv6 Option", "icmpv6.opt", FT_NONE, BASE_NONE, NULL, 0x0, "Option", HFILL }}, { &hf_icmpv6_opt_type, { "Type", "icmpv6.opt.type", FT_UINT8, BASE_DEC, VALS(option_vals), 0x0, "Options type", HFILL }}, { &hf_icmpv6_opt_length, { "Length", "icmpv6.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0, "The length (in units of 8 bytes) of the option (including the Type and Length fields)", HFILL }}, { &hf_icmpv6_opt_reserved, { "Reserved", "icmpv6.opt.reserved", FT_NONE, BASE_NONE, NULL, 0x0, "Reserved (Must be 0)", HFILL }}, { &hf_icmpv6_opt_padding, { "Padding", "icmpv6.opt.padding", FT_NONE, BASE_NONE, NULL, 0x0, "Padding (Must be 0)", HFILL }}, { &hf_icmpv6_opt_linkaddr, { "Link-layer address", "icmpv6.opt.linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_src_linkaddr, { "Source Link-layer address", "icmpv6.opt.src_linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_target_linkaddr, { "Target Link-layer address", "icmpv6.opt.target_linkaddr", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_linkaddr_mac, { "Link-layer address", "icmpv6.opt.linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_src_linkaddr_mac, { "Source Link-layer address", "icmpv6.opt.src_linkaddr", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &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, { "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, { "Flag", "icmpv6.opt.prefix.flag", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL }}, { &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, { "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, { "Reserved", "icmpv6.opt.prefix.flag.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f, NULL, HFILL }}, { &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, { "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, { "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, { "Pad Length", "icmpv6.opt.cga.pad_length", FT_UINT8, BASE_DEC, NULL, 0x0, "Pad Length (in bytes)", HFILL }}, { &hf_icmpv6_opt_cga, { "CGA", "icmpv6.opt.cga", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_cga_modifier, { "Modifier", "icmpv6.opt.cga.modifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_cga_subnet_prefix, { "Subnet Prefix", "icmpv6.opt.cga.subnet_prefix", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_cga_count, { "Count", "icmpv6.opt.cga.count", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_cga_ext_type, { "Ext Type", "icmpv6.opt.cga.ext_type", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_cga_ext_length, { "Ext Length", "icmpv6.opt.cga.ext_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_cga_ext_data, { "Ext Data", "icmpv6.opt.cga.ext_length", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_rsa_key_hash, { "Key Hash", "icmpv6.opt.rsa.key_hash", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_digital_signature_padding, { "Digital Signature and Padding", "icmpv6.opt.digital_signature_padding", FT_NONE, BASE_NONE, NULL, 0x0, "TO DO FIX ME !!", HFILL }}, { &hf_icmpv6_opt_timestamp, { "Timestamp", "icmpv6.opt.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, "The value indicates the number of seconds since January 1, 1970, 00:00 UTC", HFILL }}, { &hf_icmpv6_opt_nonce, { "Nonce", "icmpv6.opt.nonce", FT_BYTES, BASE_NONE, NULL, 0x0, "A field containing a random number selected by the sender of the solicitation message", HFILL }}, { &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, { "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, { "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, { "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, { "Option-code", "icmpv6.opt.nrpi.option_code", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL }}, { &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, { "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, { "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, { "Link-Layer Address", "icmpv6.opt.lla.bytes", FT_BYTES, BASE_NONE, NULL, 0x00, "(in Bytes Format)", HFILL }}, { &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, { "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, { "Supplied NCoA", "icmpv6.opt.naack.supplied_ncoa", FT_IPv6, BASE_NONE, NULL, 0x00, 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 }}, { &hf_icmpv6_opt_map_pref, { "Preference", "icmpv6.opt.map.preference", FT_UINT8, BASE_DEC, NULL, 0x0F, "Used as an indicator of operator preference (Highest is better)", HFILL }}, { &hf_icmpv6_opt_map_flag, { "Flag", "icmpv6.opt.map.flag", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL }}, { &hf_icmpv6_opt_map_flag_r, { "RCoA Flag", "icmpv6.opt.map.flag.r", FT_BOOLEAN, 8, NULL, 0x80, "It indicates that the mobile node is allocated the RCoA by the MAP", HFILL }}, { &hf_icmpv6_opt_map_flag_reserved, { "Reserved", "icmpv6.opt.map.flag.reserved", FT_UINT8, BASE_DEC, NULL, 0x7F, "Must be 0", HFILL }}, { &hf_icmpv6_opt_map_valid_lifetime, { "Valid Lifetime", "icmpv6.opt.map.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "This value indicates the validity of the MAP's address and the RCoA.", HFILL }}, { &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, { "Flag", "icmpv6.opt.route_info.flag", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL }}, { &hf_icmpv6_opt_route_info_flag_route_preference, { "Route Preference", "icmpv6.opt.route_info.flag.route_preference", FT_UINT8, BASE_DEC, VALS(names_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, { "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, { "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, { "Name Type", "icmpv6.opt.name_type", FT_UINT8, BASE_DEC, VALS(icmpv6_option_name_type_vals), 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_name_x501, { "DER Encoded X.501 Name", "icmpv6.opt.name_x501", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_name_fqdn, { "FQDN", "icmpv6.opt.name_type.fqdn", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_cert_type, { "Cert Type", "icmpv6.opt.name_type", FT_UINT8, BASE_DEC, VALS(icmpv6_option_cert_type_vals), 0x0, NULL, HFILL }}, { &hf_icmpv6_identifier, { "Identifier", "icmpv6.identifier", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_all_comp, { "All Components", "icmpv6.all_comp", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_comp, { "Component", "icmpv6.comp", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_x509if_Name, { "Name", "icmpv6.x509_Name", FT_UINT32, BASE_DEC, VALS(x509if_Name_vals), 0x0, NULL, HFILL }}, { &hf_icmpv6_x509af_Certificate, { "Certificate", "icmpv6.x509_Certificate", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_redirected_packet, { "Redirected Packet", "icmpv6.opt.redirected_packet", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_mtu, { "MTU", "icmpv6.opt.mtu", FT_UINT32, BASE_DEC, NULL, 0x0, "The recommended MTU for the link", HFILL }}, { &hf_icmpv6_opt_nbma_shortcut_limit, { "Shortcut Limit", "icmpv6.opt.nbma.shortcut_limit", FT_UINT8, BASE_DEC, NULL, 0x0, "Hop limit for shortcut attempt", HFILL }}, { &hf_icmpv6_opt_advertisement_interval, { "Advertisement Interval", "icmpv6.opt.advertisement_interval", FT_UINT32, BASE_DEC, NULL, 0x0, "The maximum time (in milliseconds) between successive unsolicited Router Advertisement messages sent by this router on this network interface", HFILL }}, { &hf_icmpv6_opt_home_agent_preference, { "Home Agent Preference", "icmpv6.opt.home_agent_preference", FT_UINT16, BASE_DEC, NULL, 0x0, "The preference for the home agent sending this Router Advertisement", HFILL }}, { &hf_icmpv6_opt_home_agent_lifetime, { "Home Agent Preference", "icmpv6.opt.home_agent_lifetime", FT_UINT16, BASE_DEC, NULL, 0x0, "The lifetime associated with the home agent in units of seconds.", HFILL }}, { &hf_icmpv6_opt_ipv6_address, { "IPv6 Address", "icmpv6.opt.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x0, "IPv6 addresses of the interface", HFILL }}, { &hf_icmpv6_opt_rdnss_lifetime, { "Lifetime", "icmpv6.opt.rdnss.lifetime", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_rdnss, { "Recursive DNS Servers", "icmpv6.opt.rdnss", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_efo, { "Flags Expansion Option", "icmpv6.opt.efo", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_efo_m, { "Managed address configuration", "icmpv6.opt.efo.m", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_M, "When set, it indicates that addresses are available via DHCPv6", HFILL }}, { &hf_icmpv6_opt_efo_o, { "Other configuration", "icmpv6.opt.efo.o", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_O, "When set, it indicates that other configuration information is available via DHCPv6", HFILL }}, { &hf_icmpv6_opt_efo_h, { "Home Agent", "icmpv6.opt.efo.h", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_H, "When set, it indicate that the router sending this Router Advertisement is also functioning as a Mobile IPv6 home agent on this link", HFILL }}, { &hf_icmpv6_opt_efo_prf, { "Prf (Default Router Preference)", "icmpv6.opt.efo.prf", FT_UINT16, BASE_DEC, VALS(names_router_pref), FLAGS_EO_PRF, "Indicates whether to prefer this router over other default routers", HFILL }}, { &hf_icmpv6_opt_efo_p, { "Proxy", "icmpv6.opt.efo.p", FT_BOOLEAN, 16, TFS(&tfs_set_notset), FLAGS_EO_P, NULL, HFILL }}, { &hf_icmpv6_opt_efo_rsv, { "Reserved (Must be Zero)", "icmpv6.opt.efo.rsv", FT_UINT16, BASE_DEC, NULL, FLAGS_EO_RSV, NULL, HFILL }}, { &hf_icmpv6_opt_hkr_pad_length, { "Pad Length", "icmpv6.opt.hkr.pad_length", FT_UINT8, BASE_DEC, NULL, 0x0, "The number of padding octets beyond the end of the Handover Key", HFILL }}, { &hf_icmpv6_opt_hkr_at, { "AT", "icmpv6.opt.hkr.at", FT_UINT8, BASE_DEC, NULL, 0xF0, "The algorithm type field describing the algorithm used by FMIPv6 to calculate the authenticator", HFILL }}, { &hf_icmpv6_opt_hkr_reserved, { "Reserved", "icmpv6.opt.hkr.reserved", FT_UINT8, BASE_DEC, NULL, 0x0F, "Reserved (Must be Zero)", HFILL }}, { &hf_icmpv6_opt_hkr_encryption_public_key, { "Handover Key Encryption Public Key", "icmpv6.opt.hkr.encryption_public_key", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_hkr_padding, { "Padding", "icmpv6.opt.hkr.padding", FT_BYTES, BASE_NONE, NULL, 0x0, "A variable-length field making the option length a multiple of 8", HFILL }}, { &hf_icmpv6_opt_hkr_lifetime, { "Padding", "icmpv6.opt.hkr.lifetime", FT_UINT16, BASE_DEC, NULL, 0x0, "Lifetime of the handover key (in seconds)", HFILL }}, { &hf_icmpv6_opt_hkr_encrypted_handover_key, { "Encrypted Handover Key", "icmpv6.opt.hkr.encrypted_handover_key", FT_BYTES, BASE_NONE, NULL, 0x0, "The shared handover key, encrypted with the MN's handover key encryption public key", HFILL }}, { &hf_icmpv6_opt_hai_option_code, { "Option-Code", "icmpv6.opt.hai.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_hai_option_code_val), 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_hai_length, { "HAI-Length", "icmpv6.opt.hai.length", FT_UINT8, BASE_DEC, NULL, 0x0, "The size of the HAI-Value field in octets", HFILL }}, { &hf_icmpv6_opt_hai_value, { "HAI-Value", "icmpv6.opt.hai.value", FT_BYTES, BASE_NONE, NULL, 0x0, "The value specified by the Option-Code", HFILL }}, { &hf_icmpv6_opt_mn_option_code, { "Option-Code", "icmpv6.opt.mn.option_code", FT_UINT8, BASE_DEC, VALS(nd_opt_mn_option_code_val), 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_mn_length, { "MN-Length", "icmpv6.opt.mn.length", FT_UINT8, BASE_DEC, NULL, 0x0, "The size of the MN-Value field in octets", HFILL }}, { &hf_icmpv6_opt_mn_value, { "MN-Value", "icmpv6.opt.mn.value", FT_BYTES, BASE_NONE, NULL, 0x0, "The value specified by the Option-Code", HFILL }}, { &hf_icmpv6_opt_dnssl_lifetime, { "Lifetime", "icmpv6.opt.dnssl.lifetime", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_dnssl, { "Domain Names", "icmpv6.opt.dnssl", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_opt_aro_status, { "Status", "icmpv6.opt.aro.status", FT_UINT8, BASE_DEC, VALS(names_6lowpannd_aro_status_str), 0x00, "The amount of time (in a unit of 10 seconds) that the router should retain the Neighbor Cache entry", HFILL }}, { &hf_icmpv6_opt_aro_registration_lifetime, { "Registration Lifetime", "icmpv6.opt.aro.registration_lifetime", FT_UINT16, BASE_DEC, NULL, 0x00, "The amount of time (in a unit of 10 seconds) that the router should retain the Neighbor Cache entry", HFILL }}, { &hf_icmpv6_opt_aro_eui64, /* TODO: add a FT_EUI64 Type ? */ { "EUI-64", "icmpv6.opt.aro.eui64", FT_BYTES, BASE_NONE, NULL, 0x00, "This field is used to uniquely identify the interface of the registered address", HFILL }}, { &hf_icmpv6_opt_6co_context_length, { "Context Length", "icmpv6.opt.6co.context_length", FT_UINT8, BASE_DEC, NULL, 0x00, "The number of leading bits in the Context Prefix field that are valid", HFILL }}, { &hf_icmpv6_opt_6co_flag, { "Flag", "icmpv6.opt.6co.flag", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL }}, { &hf_icmpv6_opt_6co_flag_c, { "Compression Flag", "icmpv6.opt.6co.flag.c", FT_BOOLEAN, 8, TFS(&tfs_set_notset), ND_OPT_6CO_FLAG_C, "This flag indicates if the context is valid for use in compression", HFILL }}, { &hf_icmpv6_opt_6co_flag_cid, { "CID", "icmpv6.opt.6co.flag.cid", FT_UINT8, BASE_DEC, NULL, ND_OPT_6CO_FLAG_CID, "Context Identifier for this prefix information", HFILL }}, { &hf_icmpv6_opt_6co_flag_reserved, { "Reserved", "icmpv6.opt.6co.flag.reserved", FT_UINT8, BASE_DEC, NULL, ND_OPT_6CO_FLAG_RESERVED, "Must be zero", HFILL }}, { &hf_icmpv6_opt_6co_valid_lifetime, { "Lifetime", "icmpv6.opt.6co.valid_lifetime", FT_UINT16, BASE_DEC, NULL, 0x00, "The length of time in a unit of 10 seconds that the context is valid for the purpose of header compression or decompression", HFILL }}, { &hf_icmpv6_opt_6co_context_prefix, { "Context Prefix", "icmpv6.opt.6co.context_prefix", FT_IPv6, BASE_NONE, NULL, 0x00, "The IPv6 prefix or address corresponding to the Context ID (CID) field", HFILL }}, { &hf_icmpv6_opt_abro_version, { "Version", "icmpv6.opt.abro.version", FT_UINT16, BASE_DEC, NULL, 0x00, "The version number corresponding to this set of information contained in the RA message", HFILL }}, { &hf_icmpv6_opt_abro_6lbr_address, { "6LBR Address", "icmpv6.opt.abro.6lbr_address", FT_IPv6, BASE_NONE, NULL, 0x00, "IPv6 address of the 6LBR that is the origin of the included version number", HFILL }}, /* RPL: draft-ietf-roll-rpl-12.txt: Routing over Low-Power and Lossy Networks. */ { &hf_icmpv6_dis_reserved, { "Grounded", "icmpv6.rpl.dis.reserved", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dio_grounded, { "Grounded", "icmpv6.rpl.dio.grounded", FT_BOOLEAN, 8, NULL, RPL_DIO_FLAG_GROUNDED, NULL, HFILL }}, { &hf_icmpv6_dio_zero, { "Zero", "icmpv6.rpl.dio.zero", FT_BOOLEAN, 8, NULL, RPL_DIO_FLAG_ZERO, NULL, HFILL }}, { &hf_icmpv6_dio_mop, { "MOP", "icmpv6.rpl.dio.mop", FT_UINT8, BASE_HEX, NULL, RPL_DIO_FLAG_MOP, NULL, HFILL }}, { &hf_icmpv6_dio_preference, { "DAG Preference", "icmpv6.rpl.dio.preference", FT_UINT8, BASE_DEC, NULL, RPL_DIO_FLAG_PREFERENCE, NULL, HFILL }}, { &hf_icmpv6_dio_rank, { "Rank", "icmpv6.rpl.dio.rank", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dio_instance, { "RPLInstanceID", "icmpv6.rpl.dio.instance", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dio_version, { "version", "icmpv6.rpl.dio.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dio_trigger_seqnum, { "DTSN", "icmpv6.rpl.dio.dtsn", FT_UINT8, BASE_DEC, NULL, 0x0, "Destination advertisement trigger sequence number", HFILL }}, { &hf_icmpv6_dao_instance, { "DAO Instance", "icmpv6.rpl.dao.instance", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dio_dagid, { "DODAGID", "icmpv6.rpl.dio.dagid", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dao_seqnum, { "DAO Sequence", "icmpv6.rpl.dao.sequence", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dao_reserved, { "Reserved", "icmpv6.rpl.dao.reserved", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_dao_flag_k, { "DAO-ACK Request", "icmpv6.rpl.dao.flag_k", FT_BOOLEAN, 8, NULL, RPL_DAO_FLAG_K, NULL, HFILL }}, { &hf_icmpv6_dao_flag_d, { "DODAGID Present", "icmpv6.rpl.dao.flag_d", FT_BOOLEAN, 8, NULL, RPL_DAO_FLAG_D, NULL, HFILL }}, { &hf_icmpv6_dao_flag_rsv, { "Reserved", "icmpv6.rpl.dao.flag_rsv", FT_UINT8, BASE_DEC, NULL, RPL_DAO_FLAG_RESERVED, NULL, HFILL }}, { &hf_icmpv6_dao_dodagid, { "DODAGID", "icmpv6.rpl.dao.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_daoack_instance, { "Instance", "icmpv6.rpl.daoack.instance", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_daoack_seqnum, { "DAO-ACK Sequence", "icmpv6.rpl.daoack.sequence", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_daoack_status, { "Status", "icmpv6.rpl.daoack.status", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_daoack_flag_d, { "DODAGID Present", "icmpv6.rpl.daoack.flag_d", FT_BOOLEAN, 8, NULL, RPL_DAOACK_FLAG_D, NULL, HFILL }}, { &hf_icmpv6_daoack_flag_rsv, { "Reserved", "icmpv6.rpl.daoack.flag_rsv", FT_UINT8, BASE_DEC, NULL, RPL_DAOACK_FLAG_RESERVED, NULL, HFILL }}, { &hf_icmpv6_daoack_dodagid, { "DODAGID", "icmpv6.rpl.daoack.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rpl_opt, { "ICMPv6 RPL Option", "icmpv6.opt", FT_NONE, BASE_NONE, NULL, 0x0, "Option", HFILL }}, { &hf_icmpv6_rpl_opt_type, { "Type", "icmpv6.rpl.opt.type", FT_UINT8, BASE_DEC, VALS(rpl_option_vals), 0x0, "Options type", HFILL }}, { &hf_icmpv6_rpl_opt_length, { "Length", "icmpv6.rpl.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0, "The length of the option in octets excluding the Type and Length fields", HFILL }}, { &hf_icmpv6_rpl_opt_reserved, { "Reserved", "icmpv6.rpl.opt.reserved", FT_NONE, BASE_NONE, NULL, 0x0, "Reserved (Must be 0)", HFILL }}, { &hf_icmpv6_rpl_opt_padn, { "Paddn", "icmpv6.rpl.opt.padn", FT_NONE, BASE_NONE, NULL, 0x0, "Padding (Must be 0)", HFILL }}, { &hf_icmpv6_rpl_opt_route_prefix_length, { "Prefix Length", "icmpv6.rpl.opt.route.prefix_length", FT_UINT8, BASE_DEC, NULL, 0x0, "The number of leading bits in the Prefix that are valid", HFILL }}, { &hf_icmpv6_rpl_opt_route_flag, { "Flag","icmpv6.rpl.opt.route.flag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rpl_opt_route_pref, { "Preference","icmpv6.rpl.opt.route.pref", FT_UINT8, BASE_DEC, VALS(names_router_pref), RPL_OPT_ROUTE_PREFERENCE, "The Route Preference indicates whether to prefer the router associated with this prefix over others, when multiple identical prefixes (for different routers) have been received", HFILL }}, { &hf_icmpv6_rpl_opt_route_reserved, { "Reserved","icmpv6.rpl.opt.route.reserved", FT_UINT8, BASE_DEC, NULL, RPL_OPT_ROUTE_RESERVED, "Reserved (Must be Zero)", HFILL }}, { &hf_icmpv6_rpl_opt_route_lifetime, { "Route Lifetime", "icmpv6.rpl.opt.route.lifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "The length of time in seconds (relative to the time the packet is sent) that the prefix is valid for route determination", HFILL }}, { &hf_icmpv6_rpl_opt_route_prefix, { "Prefix", "icmpv6.rpl.opt.route.prefix", FT_IPv6, BASE_NONE, NULL, 0x0, "Variable-length field containing an IP address or a prefix of an IPv6 address", HFILL }}, { &hf_icmpv6_rpl_opt_config_flag, { "Flag","icmpv6.rpl.opt.config.flag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rpl_opt_config_reserved, { "Reserved","icmpv6.rpl.opt.config.reserved", FT_UINT8, BASE_DEC, NULL, RPL_OPT_CONFIG_FLAG_RESERVED, "Must be Zero", HFILL }}, { &hf_icmpv6_rpl_opt_config_auth, { "Authentication Enabled","icmpv6.rpl.opt.config.auth", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_CONFIG_FLAG_AUTH, "One bit flag describing the security mode of the network", HFILL }}, { &hf_icmpv6_rpl_opt_config_pcs, { "Path Control Size", "icmpv6.rpl.opt.config.pcs", FT_UINT8, BASE_DEC, NULL, RPL_OPT_CONFIG_FLAG_PCS, "Used to configure the number of bits that may be allocated to the Path Control field", HFILL }}, { &hf_icmpv6_rpl_opt_config_doublings, { "DIOIntervalDoublings","icmpv6.rpl.opt.config.interval_double", FT_UINT8, BASE_DEC, NULL, 0x0, "Used to configure Imax of the DIO trickle timer", HFILL }}, { &hf_icmpv6_rpl_opt_config_min_interval, { "DIOIntervalMin", "icmpv6.rpl.opt.config.interval_min", FT_UINT16, BASE_DEC, NULL, 0x0, "Used to configure Imin of the DIO trickle timer", HFILL }}, { &hf_icmpv6_rpl_opt_config_redundancy, { "DIORedundancyConstant", "icmpv6.rpl.opt.config.redundancy", FT_UINT8, BASE_DEC, NULL, 0x0, "Used to configure k of the DIO trickle timer", HFILL }}, { &hf_icmpv6_rpl_opt_config_rank_incr, { "MaxRankInc", "icmpv6.rpl.opt.config.max_rank_inc", FT_UINT16, BASE_DEC, NULL, 0x0, "Used to configure DAGMaxRankIncrease", HFILL }}, { &hf_icmpv6_rpl_opt_config_hop_rank_inc, { "MinHopRankInc", "icmpv6.rpl.opt.config.min_hop_rank_inc", FT_UINT16, BASE_DEC, NULL, 0x0, "Used to configure MinHopRankIncrease", HFILL }}, { &hf_icmpv6_rpl_opt_config_ocp, { "OCP (Objective Code Point)","icmpv6.rpl.opt.config.ocp", FT_UINT16, BASE_DEC, NULL, 0x0, "The OCP field identifies the OF and is managed by the IANA", HFILL }}, { &hf_icmpv6_rpl_opt_config_rsv, { "Reserved", "icmpv6.rpl.opt.config.rsv", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rpl_opt_config_def_lifetime, { "Default Lifetime", "icmpv6.rpl.opt.config.def_lifetime", FT_UINT8, BASE_DEC, NULL, 0x0, "This is the lifetime that is used as default for all RPL routes", HFILL }}, { &hf_icmpv6_rpl_opt_config_lifetime_unit, { "Lifetime Unit", "icmpv6.rpl.opt.config.lifetime_unit", FT_UINT16, BASE_DEC, NULL, 0x0, "Provides the unit in seconds that is used to express route lifetimes in RPL", HFILL }}, { &hf_icmpv6_rpl_opt_target_flag, { "Reserved", "icmpv6.rpl.opt.target.flag", FT_NONE, BASE_NONE, NULL, 0x0, "Unused field reserved for flags", HFILL }}, { &hf_icmpv6_rpl_opt_target_prefix_length, { "Target Length", "icmpv6.rpl.opt.target.prefix_length", FT_UINT8, BASE_DEC, NULL, 0x0, "Number of valid leading bits in the IPv6 Prefix", HFILL }}, { &hf_icmpv6_rpl_opt_target_prefix, { "Target", "icmpv6.rpl.opt.target.prefix", FT_IPv6, BASE_NONE, NULL, 0x0, "Identifying an IPv6 destination address, prefix, or multicast group", HFILL }}, { &hf_icmpv6_rpl_opt_transit_flag, { "Flags", "icmpv6.rpl.opt.transit.flag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rpl_opt_transit_flag_e, { "External", "icmpv6.rpl.opt.transit.flag.e", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_TRANSIT_FLAG_E, "Indicate that the parent router redistributes external targets into the RPL network", HFILL }}, { &hf_icmpv6_rpl_opt_transit_flag_rsv, { "Reserved", "icmpv6.rpl.opt.transit.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_TRANSIT_FLAG_RSV, "Must be Zero", HFILL }}, { &hf_icmpv6_rpl_opt_transit_pathctl, { "Path Control", "icmpv6.rpl.opt.transit.pathctl", FT_UINT8, BASE_DEC, NULL, 0x0, "Limits the number of DAO-Parents to which a DAO message advertising connectivity", HFILL }}, { &hf_icmpv6_rpl_opt_transit_pathseq, { "Path Sequence", "icmpv6.rpl.opt.transit.pathseq", FT_UINT8, BASE_DEC, NULL, 0x0, "Increments the Path Sequence each time it issues a RPL Target option with updated information", HFILL }}, { &hf_icmpv6_rpl_opt_transit_pathlifetime, { "Path Lifetime", "icmpv6.rpl.opt.transit.pathlifetime", FT_UINT8, BASE_DEC, NULL, 0x0, "The length of time in Lifetime Units that the prefix is valid for route determination", HFILL }}, { &hf_icmpv6_rpl_opt_transit_parent, { "Parent Address", "icmpv6.rpl.opt.transit.parent", FT_IPv6, BASE_NONE, NULL, 0x0, "IPv6 Address of the DODAG Parent of the node originally issuing the Transit Information Option", HFILL }}, { &hf_icmpv6_rpl_opt_solicited_instance, { "Instance", "icmpv6.rpl.opt.solicited.instance", FT_UINT8, BASE_DEC, NULL, 0x0, "Containing the RPLInstanceID that is being solicited when valid", HFILL }}, { &hf_icmpv6_rpl_opt_solicited_flag, { "Flag", "icmpv6.rpl.opt.solicited.flag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rpl_opt_solicited_flag_v, { "Version predicate", "icmpv6.rpl.opt.solicited.flag.v", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_V, "The Version predicate is true if the receiver's DODAGVersionNumber matches the requested Version Number", HFILL }}, { &hf_icmpv6_rpl_opt_solicited_flag_i, { "InstanceID predicate","icmpv6.rpl.opt.solicited.flag.i", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_I, "The InstanceID predicate is true when the RPL node's current RPLInstanceID matches the requested RPLInstanceID", HFILL }}, { &hf_icmpv6_rpl_opt_solicited_flag_d, { "DODAGID predicate", "icmpv6.rpl.opt.solicited.flag.d", FT_BOOLEAN, 8, TFS(&tfs_true_false), RPL_OPT_SOLICITED_FLAG_D, "The DODAGID predicate is true if the RPL node's parent set has the same DODAGID as the DODAGID field", HFILL }}, { &hf_icmpv6_rpl_opt_solicited_flag_rsv, { "Reserved", "icmpv6.rpl.opt.solicited.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_SOLICITED_FLAG_RSV, "Must be Zero", HFILL }}, { &hf_icmpv6_rpl_opt_solicited_dodagid, { "DODAGID", "icmpv6.rpl.opt.solicited.dodagid", FT_IPv6, BASE_NONE, NULL, 0x0, "the DODAGID that is being solicited when valid", HFILL }}, { &hf_icmpv6_rpl_opt_solicited_version, { "Version", "icmpv6.rpl.opt.solicited.version", FT_UINT8, BASE_DEC, NULL, 0x0, "the value of DODAGVersionNumber that is being solicited when valid", HFILL }}, { &hf_icmpv6_rpl_opt_prefix_length, { "Prefix Length", "icmpv6.rpl.opt.prefix.length", FT_UINT8, BASE_DEC, NULL, 0x0, "The number of leading bits in the Prefix that are valid", HFILL }}, { &hf_icmpv6_rpl_opt_prefix_flag, { "Flag", "icmpv6.rpl.opt.prefix.flag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rpl_opt_prefix_flag_l, { "On Link", "icmpv6.rpl.opt.prefix.flag.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_L, "When set, indicates that this prefix can be used for on-link determination", HFILL }}, { &hf_icmpv6_rpl_opt_prefix_flag_a, { "Auto Address Config","icmpv6.rpl.opt.config.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_A, "When set indicates that this prefix can be used for stateless address configuration", HFILL }}, { &hf_icmpv6_rpl_opt_prefix_flag_r, { "Router Address", "icmpv6.rpl.opt.config.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RPL_OPT_PREFIX_FLAG_R, "When set, indicates that the Prefix field contains a complete IPv6 address assigned to the sending router that can be used as parent in a target option", HFILL }}, { &hf_icmpv6_rpl_opt_prefix_flag_rsv, { "Reserved", "icmpv6.rpl.opt.config.flag.rsv", FT_UINT8, BASE_DEC, NULL, RPL_OPT_PREFIX_FLAG_RSV, "Must Be Zero", HFILL }}, { &hf_icmpv6_rpl_opt_prefix_vlifetime, { "Valid Lifetime", "icmpv6.rpl.opt.prefix.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "The length of time in seconds that the prefix is valid for the purpose of on-link determination", HFILL }}, { &hf_icmpv6_rpl_opt_prefix_plifetime, { "Preferred Lifetime", "icmpv6.rpl.opt.prefix.preferred_lifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "The length of time in seconds that addresses generated from the prefix via stateless address autoconfiguration remain preferred", HFILL }}, { &hf_icmpv6_rpl_opt_prefix, { "Destination Prefix", "icmpv6.rpl.opt.prefix", FT_IPv6, BASE_NONE, NULL, 0x0, "An IPv6 address or a prefix of an IPv6 address", HFILL }}, { &hf_icmpv6_rpl_opt_targetdesc, { "Descriptor", "icmpv6.rpl.opt.targetdesc.descriptor", FT_UINT32, BASE_HEX, NULL, 0x0, "Opaque Data", HFILL }}, /* RFC 4620 IPv6 Node Information Queries */ { &hf_icmpv6_ni_qtype, { "Qtype", "icmpv6.ni.qtype", FT_UINT16, BASE_DEC, VALS(ni_qtype_val), 0x0, "Designates the type of information", HFILL }}, { &hf_icmpv6_ni_flag, { "Flags", "icmpv6.ni.flag", FT_UINT16, BASE_HEX, NULL, 0x0, "Qtype-specific flags that may be defined for certain Query types and their Replies", HFILL }}, { &hf_icmpv6_ni_flag_g, { "Global-scope addresses", "icmpv6.ni.flag.g", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_G, "Global-scope addresses are requested", HFILL }}, { &hf_icmpv6_ni_flag_s, { "Site-local addresses", "icmpv6.ni.flag.s", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_S, "Site-local addresses are requested", HFILL }}, { &hf_icmpv6_ni_flag_l, { "Link-local addresses", "icmpv6.ni.flag.l", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_L, "Link-local addresses are requested", HFILL }}, { &hf_icmpv6_ni_flag_c, { "Compression", "icmpv6.ni.flag.c", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_C, "IPv4-compatible (now deprecated) and IPv4-mapped addresses are requested", HFILL }}, { &hf_icmpv6_ni_flag_a, { "Unicast Addresses", "icmpv6.ni.flag.a", FT_BOOLEAN, 16, TFS(&tfs_ni_flag_a), NI_FLAG_A, "Responder's unicast addresses", HFILL }}, { &hf_icmpv6_ni_flag_t, { "Truncated", "icmpv6.ni.flag.t", FT_BOOLEAN, 16, TFS(&tfs_set_notset), NI_FLAG_T, "Defined in a Reply only, indicates that the set of addresses is incomplete for space reasons", HFILL }}, { &hf_icmpv6_ni_flag_rsv, { "Reserved", "icmpv6.ni.flag.rsv", FT_UINT16, BASE_HEX, NULL, NI_FLAG_RSV, "Must be Zero", HFILL }}, { &hf_icmpv6_ni_nonce, { "Nonce", "icmpv6.ni.nonce", FT_UINT64, BASE_HEX, NULL, 0x0, "An opaque 64-bit field", HFILL }}, { &hf_icmpv6_ni_query_subject_ipv6, { "IPv6 subject address", "icmpv6.ni.query.subject_ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_ni_query_subject_fqdn, { "FQDN subject", "icmpv6.ni.query.subject_fqdn", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_ni_query_subject_ipv4, { "IPv4 subject address", "icmpv6.ni.query.subject_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_ni_reply_node_ttl, { "TTL", "icmpv6.ni.query.subject_ipv4", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_ni_reply_node_name, { "Name Node", "icmpv6.ni.query.node_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_ni_reply_node_address, { "IPv6 Node address", "icmpv6.ni.query.node_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_ni_reply_ipv4_address, { "IPv4 Node address", "icmpv6.ni.query.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }}, /* RFC 2894: Router Renumbering for IPv6 */ { &hf_icmpv6_rr_sequencenumber, { "Sequence Number", "icmpv6.rr.sequence_number", FT_UINT32, BASE_DEC, NULL, 0x0, "The sequence number MUST be non-decreasing between Sequence Number Resets", HFILL }}, { &hf_icmpv6_rr_segmentnumber, { "Segment Number", "icmpv6.rr.segment_number", FT_UINT8, BASE_DEC, NULL, 0x0, "Enumerates different valid RR messages having the same Sequence Number", HFILL }}, { &hf_icmpv6_rr_flag, { "Flags", "icmpv6.rr.flag", FT_UINT8, BASE_HEX, NULL, 0x0, "Five are defined and three bits are reserved", HFILL }}, { &hf_icmpv6_rr_flag_t, { "Test Command", "icmpv6.rr.flag.t", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_T, "Indicates a Test message: processing is to be simulated and no configuration changes are to be made", HFILL }}, { &hf_icmpv6_rr_flag_r, { "Result requested", "icmpv6.rr.flag.r", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_R, "Indicates that the router send a Result message upon completion of processing the Command message", HFILL }}, { &hf_icmpv6_rr_flag_a, { "All Interfaces", "icmpv6.rr.flag.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_A, "Indicates that the Command be applied to all interfaces regardless of administrative shutdown status", HFILL }}, { &hf_icmpv6_rr_flag_s, { "Site-specific", "icmpv6.rr.flag.s", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_S, "Indicates that the Command be applied only to interfaces which belong to the same site as the interface to which the Command is addressed", HFILL }}, { &hf_icmpv6_rr_flag_p, { "Processed previously", "icmpv6.rr.flag.p", FT_BOOLEAN, 8, TFS(&tfs_set_notset), RR_FLAG_P, "Indicates that the Command message was previously processed (and is not a Test) and the responding router is not processing it again", HFILL }}, { &hf_icmpv6_rr_flag_rsv, { "Reserved", "icmpv6.rr.flag.rsv", FT_UINT8, BASE_DEC, NULL, RR_FLAG_RSV, "Must be Zero", HFILL }}, { &hf_icmpv6_rr_maxdelay, { "Max Delay", "icmpv6.rr.maxdelay", FT_UINT16, BASE_DEC, NULL, 0x0, "Specifying the maximum time (in milliseconds) by which a router MUST delay sending any reply to this Command", HFILL }}, { &hf_icmpv6_rr_pco_mp_part, { "Match-Prefix Part", "icmpv6.rr.pco.mp", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rr_pco_mp_opcode, { "OpCode", "icmpv6.rr.pco.mp.opcode", FT_UINT8, BASE_DEC, VALS(rr_pco_mp_opcode_val), 0x0, "Specifying the operation to be performed when the associated MatchPrefix matches an interface's prefix or address", HFILL }}, { &hf_icmpv6_rr_pco_mp_oplength, { "OpLength", "icmpv6.rr.pco.mp.oplength", FT_UINT8, BASE_DEC, NULL, 0x0, "The total length of this Prefix Control Operation (in units of 8 octets)", HFILL }}, { &hf_icmpv6_rr_pco_mp_ordinal, { "Ordinal", "icmpv6.rr.pco.mp.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0, "The value is otherwise unconstrained", HFILL }}, { &hf_icmpv6_rr_pco_mp_matchlen, { "MatchLen", "icmpv6.rr.pco.mp.matchlen", FT_UINT8, BASE_DEC, NULL, 0x0, "Between 0 and 128 inclusive specifying the number of initial bits of MatchPrefix which are significant in matching", HFILL }}, { &hf_icmpv6_rr_pco_mp_minlen, { "MinLen", "icmpv6.rr.pco.mp.minlen", FT_UINT8, BASE_DEC, NULL, 0x0, "Specifying the minimum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }}, { &hf_icmpv6_rr_pco_mp_maxlen, { "MaxLen", "icmpv6.rr.pco.mp.maxlen", FT_UINT8, BASE_DEC, NULL, 0x0, "Specifying the maximum length which any configured prefix must have in order to be eligible for testing against the MatchPrefix", HFILL }}, { &hf_icmpv6_rr_pco_mp_matchprefix, { "MatchPrefix", "icmpv6.rr.pco.mp.matchprefix", FT_IPv6, BASE_NONE, NULL, 0x0, "The 128-bit prefix to be compared with each interface's prefix or address", HFILL }}, { &hf_icmpv6_rr_pco_up_part, { "Use-Prefix Part", "icmpv6.rr.pco.up", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rr_pco_up_uselen, { "UseLen", "icmpv6.rr.pco.up.uselen", FT_UINT8, BASE_DEC, NULL, 0x0, "specifying the number of initial bits of UsePrefix to use in creating a new prefix for an interface", HFILL }}, { &hf_icmpv6_rr_pco_up_keeplen, { "KeepLen", "icmpv6.rr.pco.up.keeplen", FT_UINT8, BASE_DEC, NULL, 0x0, "Specifying the number of bits of the prefix or address which matched the associated Match-Prefix which should be retained in the new prefix", HFILL }}, { &hf_icmpv6_rr_pco_up_flagmask, { "FlagMask", "icmpv6.rr.pco.up.flagmask", FT_UINT8, BASE_HEX, NULL, 0x0, "A 1 bit in any position means that the corresponding flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }}, { &hf_icmpv6_rr_pco_up_flagmask_l, { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, "When set, indicates the On-link (L) flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }}, { &hf_icmpv6_rr_pco_up_flagmask_a, { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, "When set, indicates the Autonomous address-configuration (A) flag bit in a Router Advertisement (RA) Prefix Information Option for the New Prefix should be set from the RAFlags field in this Use-Prefix Part", HFILL }}, { &hf_icmpv6_rr_pco_up_flagmask_reserved, { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f, NULL, HFILL }}, { &hf_icmpv6_rr_pco_up_raflags, { "RAFlags", "icmpv6.rr.pco.up.raflags", FT_UINT8, BASE_HEX, NULL, 0x0, "Under control of the FlagMask field, may be used to initialize the flags in Router Advertisement Prefix Information Options which advertise the New Prefix", HFILL }}, { &hf_icmpv6_rr_pco_up_raflags_l, { "On-link flag(L)", "icmpv6.rr.pco.up.flagmask.l", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, "When set, indicates that this prefix can be used for on-link determination", HFILL }}, { &hf_icmpv6_rr_pco_up_raflags_a, { "Autonomous address-configuration flag(A)", "icmpv6.rr.pco.up.flagmask.a", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, "When set indicates that this prefix can be used for stateless address configuration", HFILL }}, { &hf_icmpv6_rr_pco_up_raflags_reserved, { "Reserved", "icmpv6.rr.pco.up.flagmask.reserved", FT_UINT8, BASE_DEC, NULL, 0x3f, NULL, HFILL }}, { &hf_icmpv6_rr_pco_up_validlifetime, { "Valid Lifetime", "icmpv6.rr.pco.up.validlifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "The number of seconds for which the New Prefix will be valid", HFILL }}, { &hf_icmpv6_rr_pco_up_preferredlifetime, { "Preferred Lifetime", "icmpv6.rr.pco.up.preferredlifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "The number of seconds for which the New Prefix will be preferred", HFILL }}, { &hf_icmpv6_rr_pco_up_flag, { "Flags", "icmpv6.rr.pco.up.flag", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rr_pco_up_flag_v, { "Decrement valid lifetime", "icmpv6.rr.pco.up.flag.v", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x80000000, "When set, indicating that the valid lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }}, { &hf_icmpv6_rr_pco_up_flag_p, { "Decrement preferred lifetime", "icmpv6.rr.pco.up.flag.p", FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x40000000, "When set, indicating that the preferred lifetime of the New Prefix MUST be effectively decremented in real time", HFILL }}, { &hf_icmpv6_rr_pco_up_flag_reserved, { "Reserved", "icmpv6.rr.pco.up.flag.reserved", FT_UINT32, BASE_DEC, NULL, 0x3FFFFFFF, NULL, HFILL }}, { &hf_icmpv6_rr_pco_up_useprefix, { "UsePrefix", "icmpv6.rr.pco.up.useprefix", FT_IPv6, BASE_NONE, NULL, 0x0, "The 128-bit Use-prefix which either becomes or is used in forming (if KeepLen is nonzero) the New Prefix", HFILL }}, { &hf_icmpv6_rr_rm, { "Result Message", "icmpv6.rr.rm", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rr_rm_flag, { "Flags", "icmpv6.rr.rm.flag", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_icmpv6_rr_rm_flag_b, { "Bounds", "icmpv6.rr.rm.flag.b", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002, "When set, indicates that one or more fields in the associated PCO were out of bounds", HFILL }}, { &hf_icmpv6_rr_rm_flag_f, { "Forbidden", "icmpv6.rr.rm.flag.f", FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001, "When set, indicates that one or more Use-Prefix parts from the associated PCO were not honored by the router because of attempted formation of a forbidden prefix format, such as a multicast or loopback address", HFILL }}, { &hf_icmpv6_rr_rm_flag_reserved, { "Reserved", "icmpv6.rr.rm.flag.reserved", FT_UINT16, BASE_DEC, NULL, 0xFFFD, "Must be Zero", HFILL }}, { &hf_icmpv6_rr_rm_ordinal, { "Ordinal", "icmpv6.rr.rm.ordinal", FT_UINT8, BASE_HEX, NULL, 0x0, "The value is otherwise unconstrained", HFILL }}, { &hf_icmpv6_rr_rm_matchedlen, { "MatchedLen", "icmpv6.rr.rm.matchedlen", FT_UINT8, BASE_DEC, NULL, 0x0, "The length of the Matched Prefix", HFILL }}, { &hf_icmpv6_rr_rm_interfaceindex, { "InterfaceIndex", "icmpv6.rr.rm.interfaceindex", FT_UINT32, BASE_DEC, NULL, 0x0, "The router's numeric designation of the interface on which the MatchedPrefix was configured", HFILL }}, { &hf_icmpv6_rr_rm_matchedprefix, { "MatchedPrefix", "icmpv6.rr.rm.matchedprefix", FT_IPv6, BASE_NONE, NULL, 0x0, "The 128 Bits MatchedPrefix", HFILL }}, }; static gint *ett[] = { &ett_icmpv6, &ett_icmpv6opt, &ett_icmpv6flag, &ett_icmpv6mar, &ett_icmpv6opt_name, &ett_cga_param_name, &ett_dao_rr_stack }; proto_icmpv6 = proto_register_protocol("Internet Control Message Protocol v6", "ICMPv6", "icmpv6"); proto_register_field_array(proto_icmpv6, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); register_dissector("icmpv6", dissect_icmpv6, proto_icmpv6); } void proto_reg_handoff_icmpv6(void) { dissector_handle_t icmpv6_handle; icmpv6_handle = create_dissector_handle(dissect_icmpv6, proto_icmpv6); dissector_add_uint("ip.proto", IP_PROTO_ICMPV6, icmpv6_handle); /* * Get a handle for the IPv6 dissector. */ ipv6_handle = find_dissector("ipv6"); data_handle = find_dissector("data"); } /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * vi: set shiftwidth=4 tabstop=8 expandtab * :indentSize=4:tabSize=8:noTabs=true: */