1 /* packet-wifi-nan.c
2  *
3  * Wi-Fi Neighbour Awareness Networking (NAN)
4  *
5  * Copyright 2019 Samsung Electronics
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9 
10 #include <config.h>
11 #include <epan/packet.h>
12 #include <epan/expert.h>
13 #include <epan/dissectors/packet-ieee80211.h>
14 
15 void proto_reg_handoff_nan(void);
16 void proto_register_nan(void);
17 
18 static dissector_table_t ie_handle_table;
19 
20 #define WFA_ACTION_OUI_TYPE 0x18
21 #define WFA_NAN_IE_OUI_TYPE 0x13
22 #define WFA_SERVICE_DISCOVERY_SUBTYPE 0x13
23 
24 #define NAN_MASTER_IND_LENGTH 2
25 #define NAN_CLUSTER_LENGTH 13
26 #define NAN_SDA_MIN_LENGTH 9
27 #define NAN_SDEA_MIN_LENGTH 3
28 #define NAN_CONNECTION_CAP_LENGTH 2
29 #define NAN_WLAN_INFRA_MIN_LENGTH 15
30 #define NAN_P2P_OP_MIN_LENGTH 9
31 #define NAN_IBSS_MIN_LENGTH 14
32 #define NAN_MESH_MIN_LENGTH 8
33 #define NAN_RANGING_MIN_LENGTH 8
34 #define NAN_CLUSTER_DISC_LENGTH 22
35 #define NAN_DEVICE_CAP_LENGTH 9
36 #define NAN_NDP_MIN_LENGTH 11
37 #define NAN_NDPE_MIN_LENGTH 11
38 #define NAN_AVAILABILITY_MIN_LENGTH 8
39 #define NAN_NDC_MIN_LENGTH 11
40 #define NAN_NDL_MIN_LENGTH 4
41 #define NAN_NDL_QOS_LENGTH 3
42 #define NAN_UNALIGNED_SCH_MIN_LENGTH 16
43 #define NAN_RANGING_SETUP_MIN_LENGTH 4
44 #define NAN_EXTENDED_WLAN_INFRA_LENGTH 20
45 #define NAN_EXTENDED_P2P_OP_LENGTH 14
46 #define NAN_EXTENDED_IBSS_LENGTH 19
47 #define NAN_EXTENDED_MESH_MIN_LENGTH 13
48 #define NAN_CIPHER_SUITE_INFO_MIN_LENGTH 3
49 #define NAN_SECURITY_CONTEXT_INFO_MIN_LENGTH 4
50 #define NAN_PUBLIC_AVAIL_MIN_LENGTH 4
51 #define NAN_VENDOR_SPECIFIC_MIN_LENGTH 3
52 
53 #define NAN_UNALIGNED_SCH_BAND_ID_EXIST 0
54 #define NAN_UNALIGNED_SCH_CHANNEL_ENTRY_EXIST 1
55 #define NAN_UNALIGNED_SCH_CHANNEL_ENTRY_W_AUX_EXIST 2
56 
57 static int proto_nan = -1;
58 
59 static expert_field ei_nan_elem_len_invalid = EI_INIT;
60 static expert_field ei_nan_unknown_attr_id = EI_INIT;
61 static expert_field ei_nan_unknown_op_class = EI_INIT;
62 static expert_field ei_nan_unknown_beacon_type = EI_INIT;
63 
64 static gint ett_nan = -1;
65 static gint ett_attributes = -1;
66 static gint ett_map_control = -1;
67 static gint ett_type_status = -1;
68 static gint ett_time_bitmap_ctrl = -1;
69 static gint ett_non_nan_op_channel = -1;
70 static gint ett_non_nan_beacon = -1;
71 static gint ett_cluster_anchor_master_info = -1;
72 static gint ett_sda_service_ctr = -1;
73 static gint ett_sda_srf_ctr = -1;
74 static gint ett_sdea_ctr = -1;
75 static gint ett_sdea_range_limit = -1;
76 static gint ett_sdea_service_info = -1;
77 static gint ett_connection_cap_field = -1;
78 static gint ett_further_av_map_entry_ctrl = -1;
79 static gint ett_device_cap_map_id = -1;
80 static gint ett_device_cap_committed_dw = -1;
81 static gint ett_device_cap_supported_bands = -1;
82 static gint ett_device_cap_op_mode = -1;
83 static gint ett_device_cap_antennas = -1;
84 static gint ett_device_cap_capabilities = -1;
85 static gint ett_ndp_control = -1;
86 static gint ett_ndpe_tlv = -1;
87 static gint ett_availability_ctr = -1;
88 static gint ett_availability_entry = -1;
89 static gint ett_availability_entry_ctr = -1;
90 static gint ett_availability_entry_entries = -1;
91 static gint ett_availability_entry_entries_channel = -1;
92 static gint ett_ndc_ctr = -1;
93 static gint ett_ndc_entries = -1;
94 static gint ett_device_ndc_map_id = -1;
95 static gint ett_ndl_control = -1;
96 static gint ett_ndl_schedule_entries = -1;
97 static gint ett_unaligned_sch_ctrl = -1;
98 static gint ett_unaligned_sch_ulw_overwrite = -1;
99 static gint ett_unaligned_sch_ulw_ctrl = -1;
100 static gint ett_ranging_setup_ftm_params = -1;
101 static gint ett_ranging_setup_ctrl = -1;
102 static gint ett_ranging_setup_schedule_entries = -1;
103 static gint ett_ranging_info_location_info_availability = -1;
104 static gint ett_p2p_device_role = -1;
105 static gint ett_cipher_suite_info_list = -1;
106 static gint ett_security_context_identifiers = -1;
107 static gint ett_public_availability_sch_entries = -1;
108 static gint ett_ie_tree = -1;
109 static gint ett_availability_op_class = -1;
110 
111 static int hf_nan_attribute_type = -1;
112 static int hf_nan_attribute_len = -1;
113 static int hf_nan_action_subtype = -1;
114 static int hf_nan_instance_id = -1;
115 static int hf_nan_service_id = -1;
116 static int hf_nan_map_id = -1;
117 static int hf_nan_oui = -1;
118 static int hf_nan_type_status = -1;
119 static int hf_nan_reason_code = -1;
120 static int hf_nan_status_1 = -1;
121 static int hf_nan_status_2 = -1;
122 static int hf_nan_bss_id = -1;
123 static int hf_nan_availability_intervals_bitmap = -1;
124 static int hf_nan_mac_address = -1;
125 static int hf_nan_publish_id = -1;
126 static int hf_nan_dialog_tokens = -1;
127 static int hf_nan_time_bitmap = -1;
128 static int hf_nan_time_bitmap_len = -1;
129 static int hf_nan_time_bitmap_ctrl = -1;
130 static int hf_nan_time_bitmap_ctrl_bit_duration = -1;
131 static int hf_nan_time_bitmap_ctrl_period = -1;
132 static int hf_nan_time_bitmap_ctrl_start_offset = -1;
133 static int hf_nan_map_ctrl_map_id = -1;
134 static int hf_nan_map_ctrl_availability_interval_duration = -1;
135 static int hf_nan_map_ctrl_repeat = -1;
136 static int hf_nan_map_ctrl_field = -1;
137 static int hf_nan_non_op_channel_global_op_class = -1;
138 static int hf_nan_non_op_channel_channel = -1;
139 static int hf_nan_non_op_channel_center_freq = -1;
140 static int hf_nan_non_beacon_tbtt_offset = -1;
141 static int hf_nan_non_beacon_interval = -1;
142 static int hf_nan_attr_master_preference = -1;
143 static int hf_nan_attr_master_random_factor = -1;
144 static int hf_nan_attr_cluster_anchor_master_rank = -1;
145 static int hf_nan_attr_cluster_hop_count = -1;
146 static int hf_nan_attr_cluster_beacon_transmission_time = -1;
147 static int hf_nan_attr_sda_requestor_instance_id = -1;
148 static int hf_nan_attr_sda_sc = -1;
149 static int hf_nan_attr_sda_sc_type = -1;
150 static int hf_nan_attr_sda_sc_matching_filter = -1;
151 static int hf_nan_attr_sda_sc_service_response = -1;
152 static int hf_nan_attr_sda_sc_service_info = -1;
153 static int hf_nan_attr_sda_sc_discovery_range = -1;
154 static int hf_nan_attr_sda_sc_binding_bitmap = -1;
155 static int hf_nan_attr_sda_binding_bitmap = -1;
156 static int hf_nan_attr_sda_matching_filter_len = -1;
157 static int hf_nan_attr_sda_matching_filter_val = -1;
158 static int hf_nan_attr_sda_service_response_filter_len = -1;
159 static int hf_nan_attr_sda_srf_ctr = -1;
160 static int hf_nan_attr_sda_srf_ctr_type = -1;
161 static int hf_nan_attr_sda_srf_ctr_include = -1;
162 static int hf_nan_attr_sda_srf_ctr_bloom_filter_index = -1;
163 static int hf_nan_attr_sda_srf_address_set = -1;
164 static int hf_nan_attr_sda_service_info_len = -1;
165 static int hf_nan_attr_sda_service_info = -1;
166 static int hf_nan_attr_sdea_ctr = -1;
167 static int hf_nan_attr_sdea_ctr_fsd = -1;
168 static int hf_nan_attr_sdea_ctr_fsd_w_gas = -1;
169 static int hf_nan_attr_sdea_ctr_data_path = -1;
170 static int hf_nan_attr_sdea_ctr_data_path_type = -1;
171 static int hf_nan_attr_sdea_ctr_reserved_multicast_type = -1;
172 static int hf_nan_attr_sdea_ctr_qos = -1;
173 static int hf_nan_attr_sdea_ctr_security = -1;
174 static int hf_nan_attr_sdea_ctr_ranging = -1;
175 static int hf_nan_attr_sdea_ctr_range_limit = -1;
176 static int hf_nan_attr_sdea_ctr_service_update_indicator = -1;
177 static int hf_nan_attr_sdea_ingress_range_limit = -1;
178 static int hf_nan_attr_sdea_egress_range_limit = -1;
179 static int hf_nan_attr_sdea_service_update_indicator = -1;
180 static int hf_nan_attr_sdea_service_info_length = -1;
181 static int hf_nan_attr_sdea_service_info_protocol_type = -1;
182 static int hf_nan_attr_sdea_service_info_specific = -1;
183 static int hf_nan_attr_connection_cap_bitmap = -1;
184 static int hf_nan_attr_connection_cap_wifi_direct = -1;
185 static int hf_nan_attr_connection_cap_p2ps = -1;
186 static int hf_nan_attr_connection_cap_tdls = -1;
187 static int hf_nan_attr_connection_cap_wlan_infra = -1;
188 static int hf_nan_attr_connection_cap_ibss = -1;
189 static int hf_nan_attr_connection_cap_mesh = -1;
190 static int hf_nan_attr_wlan_infra_device_role = -1;
191 static int hf_nan_attr_p2p_device_role_device = -1;
192 static int hf_nan_attr_p2p_device_role_group_owner = -1;
193 static int hf_nan_attr_p2p_device_role_client = -1;
194 static int hf_nan_attr_p2p_device_role = -1;
195 static int hf_nan_attr_mesh_id = -1;
196 static int hf_nan_attr_further_av_map_entry_av_interval_duration = -1;
197 static int hf_nan_attr_further_av_map_op_class = -1;
198 static int hf_nan_attr_further_av_map_channel_num = -1;
199 static int hf_nan_attr_further_av_map_entry_ctrl = -1;
200 static int hf_nan_attr_further_av_map_id = -1;
201 static int hf_nan_attr_country_code = -1;
202 static int hf_nan_attr_ranging_protocol = -1;
203 static int hf_nan_attr_cluster_disc_id = -1;
204 static int hf_nan_attr_cluster_disc_time_offset = -1;
205 static int hf_nan_attr_cluster_disc_anchor_master_rank = -1;
206 static int hf_nan_attr_device_cap_map_id_apply_to = -1;
207 static int hf_nan_attr_device_cap_map_id_associated_maps = -1;
208 static int hf_nan_attr_device_cap_committed_dw = -1;
209 static int hf_nan_attr_device_cap_committed_dw_24ghz = -1;
210 static int hf_nan_attr_device_cap_committed_dw_5ghz = -1;
211 static int hf_nan_attr_device_cap_committed_dw_24ghz_overwrite = -1;
212 static int hf_nan_attr_device_cap_committed_dw_5ghz_overwrite = -1;
213 static int hf_nan_attr_device_cap_supported_bands = -1;
214 static int hf_nan_attr_device_cap_supported_bands_reserved_tv_whitespaces = -1;
215 static int hf_nan_attr_device_cap_supported_bands_sub_1ghz = -1;
216 static int hf_nan_attr_device_cap_supported_bands_24ghz = -1;
217 static int hf_nan_attr_device_cap_supported_bands_reserved_36ghz = -1;
218 static int hf_nan_attr_device_cap_supported_bands_5ghz = -1;
219 static int hf_nan_attr_device_cap_supported_bands_reserved_60ghz = -1;
220 static int hf_nan_attr_device_cap_op_mode = -1;
221 static int hf_nan_attr_device_cap_op_mode_phy = -1;
222 static int hf_nan_attr_device_cap_op_mode_vht8080 = -1;
223 static int hf_nan_attr_device_cap_op_mode_vht160 = -1;
224 static int hf_nan_attr_device_cap_op_mode_reserved_paging_ndl = -1;
225 static int hf_nan_attr_device_cap_antennas = -1;
226 static int hf_nan_attr_device_cap_antennas_tx = -1;
227 static int hf_nan_attr_device_cap_antennas_rx = -1;
228 static int hf_nan_attr_device_cap_max_channel_switch_time = -1;
229 static int hf_nan_attr_device_cap_capabilities = -1;
230 static int hf_nan_attr_device_cap_capabilities_dfs_master = -1;
231 static int hf_nan_attr_device_cap_capabilities_extended_key_id = -1;
232 static int hf_nan_attr_device_cap_capabilities_simul_ndp_reception = -1;
233 static int hf_nan_attr_device_cap_capabilities_ndpe_attr_support = -1;
234 static int hf_nan_attr_ndp_type = -1;
235 static int hf_nan_attr_ndp_initiator = -1;
236 static int hf_nan_attr_ndp_id = -1;
237 static int hf_nan_attr_ndp_ctrl_confirm = -1;
238 static int hf_nan_attr_ndp_ctrl_security_pres = -1;
239 static int hf_nan_attr_ndp_ctrl_publish_id_pres = -1;
240 static int hf_nan_attr_ndp_ctrl_responder_ndi_pres = -1;
241 static int hf_nan_attr_ndp_ctrl_sepcific_info_pres = -1;
242 static int hf_nan_attr_ndp_control = -1;
243 static int hf_nan_attr_ndp_responder_ndi = -1;
244 static int hf_nan_attr_ndp_specific_info = -1;
245 static int hf_nan_attr_ndpe_tlv_type = -1;
246 static int hf_nan_attr_ndpe_tlv_len = -1;
247 static int hf_nan_attr_ndpe_tlv_ipv6_interface_identifier = -1;
248 static int hf_nan_attr_availability_sequence_id = -1;
249 static int hf_nan_attr_availability_ctr = -1;
250 static int hf_nan_attr_availability_map_id = -1;
251 static int hf_nan_attr_availability_committed_changed = -1;
252 static int hf_nan_attr_availability_potential_changed = -1;
253 static int hf_nan_attr_availability_public_availability_changed = -1;
254 static int hf_nan_attr_availability_ndc_changed = -1;
255 static int hf_nan_attr_availability_reserved_multicast_schedule_changed = -1;
256 static int hf_nan_attr_availability_reserved_multicast_schedule_change_changed = -1;
257 static int hf_nan_attr_availability_entry_len = -1;
258 static int hf_nan_attr_availability_entry_ctr = -1;
259 static int hf_nan_attr_availability_entry_ctr_type = -1;
260 static int hf_nan_attr_availability_entry_ctr_pref = -1;
261 static int hf_nan_attr_availability_entry_ctr_utilization = -1;
262 static int hf_nan_attr_availability_entry_ctr_rx_nss = -1;
263 static int hf_nan_attr_availability_entry_ctr_time_bitmap = -1;
264 static int hf_nan_attr_availability_entry_entries_type = -1;
265 static int hf_nan_attr_availability_entry_entries_non_contiguous_bw = -1;
266 static int hf_nan_attr_availability_entry_entries_num_entries = -1;
267 static int hf_nan_attr_availability_entry_entries_band = -1;
268 static int hf_nan_attr_availability_entry_entries_channel_op_class = -1;
269 static int hf_nan_attr_availability_entry_entries_channel_bitmap = -1;
270 static int hf_nan_attr_availability_entry_entries_primary_channel_bitmap = -1;
271 static int hf_nan_attr_availability_entry_entries_aux_channel_bitmap = -1;
272 static int hf_nan_attr_availability_entry_entries_channel_set = -1;
273 static int hf_nan_attr_availability_entry_entries_start_freq = -1;
274 static int hf_nan_attr_availability_entry_entries_bandwidth = -1;
275 static int hf_nan_attr_ndc_id = -1;
276 static int hf_nan_attr_ndc_ctrl = -1;
277 static int hf_nan_attr_ndc_ctrl_selected = -1;
278 static int hf_nan_attr_ndc_map_id_related_sch = -1;
279 static int hf_nan_attr_ndl_type = -1;
280 static int hf_nan_attr_ndl_control = -1;
281 static int hf_nan_attr_ndl_ctrl_peer_id = -1;
282 static int hf_nan_attr_ndl_ctrl_immutable_schedule_pres = -1;
283 static int hf_nan_attr_ndl_ctrl_ndc_pres = -1;
284 static int hf_nan_attr_ndl_ctrl_qos = -1;
285 static int hf_nan_attr_ndl_ctrl_type = -1;
286 static int hf_nan_attr_ndl_ctrl_setup_reason = -1;
287 static int hf_nan_attr_ndl_ctrl_max_idle_pres = -1;
288 static int hf_nan_attr_ndl_reserved_peer_id = -1;
289 static int hf_nan_attr_ndl_max_idle = -1;
290 static int hf_nan_attr_ndlqos_min_time_slots = -1;
291 static int hf_nan_attr_ndlqos_max_latency = -1;
292 static int hf_nan_attr_unaligned_sch_ctrl = -1;
293 static int hf_nan_attr_unaligned_sch_ctrl_schedule_id = -1;
294 static int hf_nan_attr_unaligned_sch_ctrl_seq_id = -1;
295 static int hf_nan_attr_unaligned_sch_starting_time = -1;
296 static int hf_nan_attr_unaligned_sch_duration = -1;
297 static int hf_nan_attr_unaligned_sch_period = -1;
298 static int hf_nan_attr_unaligned_sch_count_down = -1;
299 static int hf_nan_attr_unaligned_sch_ulw_overwrite = -1;
300 static int hf_nan_attr_unaligned_sch_ulw_overwrite_all = -1;
301 static int hf_nan_attr_unaligned_sch_ulw_overwrite_map_id = -1;
302 static int hf_nan_attr_unaligned_sch_ulw_ctrl = -1;
303 static int hf_nan_attr_unaligned_sch_ulw_ctrl_type = -1;
304 static int hf_nan_attr_unaligned_sch_ulw_ctrl_channel_av = -1;
305 static int hf_nan_attr_unaligned_sch_ulw_ctrl_rxnss = -1;
306 static int hf_nan_attr_ranging_info_location_info_avail = -1;
307 static int hf_nan_attr_ranging_info_location_info_avail_lci = -1;
308 static int hf_nan_attr_ranging_info_location_info_avail_geospatial = -1;
309 static int hf_nan_attr_ranging_info_location_info_avail_civic_location = -1;
310 static int hf_nan_attr_ranging_info_location_info_avail_last_movement_pres = -1;
311 static int hf_nan_attr_ranging_info_last_movement_indication = -1;
312 static int hf_nan_attr_ranging_setup_type = -1;
313 static int hf_nan_attr_ranging_setup_ctrl = -1;
314 static int hf_nan_attr_ranging_setup_ctrl_report_req = -1;
315 static int hf_nan_attr_ranging_setup_ctrl_ftm_params = -1;
316 static int hf_nan_attr_ranging_setup_ctrl_entry_list = -1;
317 static int hf_nan_attr_ranging_setup_ftm_params = -1;
318 static int hf_nan_attr_ranging_setup_ftm_max_per_burst = -1;
319 static int hf_nan_attr_ranging_setup_ftm_min_delta = -1;
320 static int hf_nan_attr_ranging_setup_ftm_max_burst_duration = -1;
321 static int hf_nan_attr_ranging_setup_ftm_format_bw = -1;
322 static int hf_nan_attr_ftm_range_report = -1;
323 static int hf_nan_attr_cipher_suite_capabilities = -1;
324 static int hf_nan_attr_cipher_suite_id = -1;
325 static int hf_nan_attr_security_context_identifier = -1;
326 static int hf_nan_attr_security_context_identifier_len = -1;
327 static int hf_nan_attr_security_context_identifier_type = -1;
328 static int hf_nan_attr_shared_key_rsna_descriptor = -1;
329 static int hf_nan_attr_vendor_specific_body = -1;
330 static int hf_nan_attr_container_element_id = -1;
331 static int hf_nan_attr_container_element_len = -1;
332 
333 enum {
334     NAN_ATTR_MASTER_INDICATION = 0x00,
335     NAN_ATTR_CLUSTER = 0x01,
336     NAN_ATTR_SERVICE_ID_LIST = 0x02,
337     NAN_ATTR_SERVICE_DESCRIPTOR = 0x03,
338     NAN_ATTR_CONNECTION_CAPABILITY = 0x04,
339     NAN_ATTR_WLAN_INFRA = 0x05,
340     NAN_ATTR_P2P_OPERATION = 0x06,
341     NAN_ATTR_IBSS = 0x07,
342     NAN_ATTR_MESH = 0x08,
343     NAN_ATTR_FURTHER_SERVICE_DISCOVERY = 0x09,
344     NAN_ATTR_FURTHER_AVAILABILITY_MAP = 0x0A,
345     NAN_ATTR_COUNTRY_CODE = 0x0B,
346     NAN_ATTR_RANGING = 0x0C,
347     NAN_ATTR_CLUSTER_DISCOVERY = 0x0D,
348     NAN_ATTR_SERVICE_DESCRIPTOR_EXTENSION = 0x0E,
349     NAN_ATTR_DEVICE_CAPABILITY = 0x0F,
350     NAN_ATTR_NDP = 0x10,
351     NAN_ATTR_RESERVED_NMSG = 0x11,
352     NAN_ATTR_AVAILABILITY = 0x12,
353     NAN_ATTR_NDC = 0x13,
354     NAN_ATTR_NDL = 0x14,
355     NAN_ATTR_NDL_QOS = 0x15,
356     NAN_ATTR_RESERVED_MULTICAST_SCHEDULE = 0x16,
357     NAN_ATTR_UNALIGNED_SCHEDULE = 0x17,
358     NAN_ATTR_RESERVED_UNICAST_PAGING = 0x18,
359     NAN_ATTR_RESERVED_MULTICAST_PAGING = 0x19,
360     NAN_ATTR_RANGING_INFORMATION = 0x1A,
361     NAN_ATTR_RANGING_SETUP = 0x1B,
362     NAN_ATTR_FTM_RANGING_REPORT = 0x1C,
363     NAN_ATTR_ELEMENT_CONTAINER = 0x1D,
364     NAN_ATTR_EXTENDED_WLAN_INFRA = 0x1E,
365     NAN_ATTR_EXTENDED_P2P_OPERATION = 0x1F,
366     NAN_ATTR_EXTENDED_IBSS = 0x20,
367     NAN_ATTR_EXTENDED_MESH = 0x21,
368     NAN_ATTR_CIPHER_SUITE_INFO = 0x22,
369     NAN_ATTR_SECURITY_CONTEXT_INFO = 0x23,
370     NAN_ATTR_SHARED_KEY_DESCRIPTOR = 0x24,
371     NAN_ATTR_RESERVED_MULTICAST_SCHEDULE_CHANGE = 0x25,
372     NAN_ATTR_RESERVED_MULTICAST_SCHEDULE_OWNER_CHANGE = 0x26,
373     NAN_ATTR_PUBLIC_AVAILABILITY = 0x27,
374     NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST = 0x28,
375     NAN_ATTR_NDP_EXTENSION = 0x29,
376     NAN_ATTR_VENDOR_SPECIFIC = 0xDD
377 };
378 
379 static const value_string attribute_types[] = {
380     { NAN_ATTR_MASTER_INDICATION, "Master Indication Attribute" },
381     { NAN_ATTR_CLUSTER, "Cluster Attribute" },
382     { NAN_ATTR_SERVICE_ID_LIST, "Service ID List Attribute" },
383     { NAN_ATTR_SERVICE_DESCRIPTOR, "Service Descriptor Attribute" },
384     { NAN_ATTR_CONNECTION_CAPABILITY, "NAN Connection Capability Attribute" },
385     { NAN_ATTR_WLAN_INFRA, "WLAN Infrastructure Attribute" },
386     { NAN_ATTR_P2P_OPERATION, "P2P Operation Attribute" },
387     { NAN_ATTR_IBSS, "IBSS Attribute" },
388     { NAN_ATTR_MESH, "Mesh Attribute" },
389     { NAN_ATTR_FURTHER_SERVICE_DISCOVERY, "Further NAN Service Discovery Attribute" },
390     { NAN_ATTR_FURTHER_AVAILABILITY_MAP, "Further Availability Map Attribute" },
391     { NAN_ATTR_COUNTRY_CODE, "Country Code Attribute" },
392     { NAN_ATTR_RANGING, "Ranging Attribute" },
393     { NAN_ATTR_CLUSTER_DISCOVERY, "Cluster Discovery Attribute" },
394     { NAN_ATTR_SERVICE_DESCRIPTOR_EXTENSION, "Service Descriptor Extension Attribute" },
395     { NAN_ATTR_DEVICE_CAPABILITY, "Device Capability" },
396     { NAN_ATTR_NDP, "NDP Attribute" },
397     { NAN_ATTR_RESERVED_NMSG, "Reserved (NMSG)" },
398     { NAN_ATTR_AVAILABILITY, "NAN Availability" },
399     { NAN_ATTR_NDC, "NDC Attribute" },
400     { NAN_ATTR_NDL, "NDL Attribute" },
401     { NAN_ATTR_NDL_QOS, "NDL QoS Attribute" },
402     { NAN_ATTR_RESERVED_MULTICAST_SCHEDULE, "Reserved (Multicast Schedule)" },
403     { NAN_ATTR_UNALIGNED_SCHEDULE, "Unaligned Schedule Attribute" },
404     { NAN_ATTR_RESERVED_UNICAST_PAGING, "Reserved (Unicast Paging)" },
405     { NAN_ATTR_RESERVED_MULTICAST_PAGING, "Reserved (Multicast Paging)" },
406     { NAN_ATTR_RANGING_INFORMATION, "Ranging Information Attribute" },
407     { NAN_ATTR_RANGING_SETUP, "Ranging Setup Attribute" },
408     { NAN_ATTR_FTM_RANGING_REPORT, "FTM Ranging Report Attribute" },
409     { NAN_ATTR_ELEMENT_CONTAINER, "Element Container Attribute" },
410     { NAN_ATTR_EXTENDED_WLAN_INFRA, "Extended WLAN Infrastructure Attribute" },
411     { NAN_ATTR_EXTENDED_P2P_OPERATION, "Extended P2P Operation Attribute" },
412     { NAN_ATTR_EXTENDED_IBSS, "Extended IBSS Attribute" },
413     { NAN_ATTR_EXTENDED_MESH, "Extended Mesh Attribute" },
414     { NAN_ATTR_CIPHER_SUITE_INFO, "Cipher Suite Info Attribute" },
415     { NAN_ATTR_SECURITY_CONTEXT_INFO, "Security Context Info Attribute" },
416     { NAN_ATTR_SHARED_KEY_DESCRIPTOR, "Shared-Key Descriptor Attribute" },
417     { NAN_ATTR_RESERVED_MULTICAST_SCHEDULE_CHANGE, "Reserved (Multicast Schedule Change)" },
418     { NAN_ATTR_RESERVED_MULTICAST_SCHEDULE_OWNER_CHANGE, "Reserved (Multicast Schedule Owner Change)" },
419     { NAN_ATTR_PUBLIC_AVAILABILITY, "Public Availability Attribute" },
420     { NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST, "Subscribe Service ID List Attribute" },
421     { NAN_ATTR_NDP_EXTENSION, "NDP Extension Attribute" },
422     { NAN_ATTR_VENDOR_SPECIFIC, "Vendor Specific Attribute" },
423     { 0, NULL }
424 };
425 
426 // Bitmask fields shared by multiple attributes
427 static int* const map_control_fields[] = {
428     &hf_nan_map_ctrl_map_id,
429     &hf_nan_map_ctrl_availability_interval_duration,
430     &hf_nan_map_ctrl_repeat,
431     NULL
432 };
433 
434 static int* const time_bitmap_ctr_fields[] = {
435     &hf_nan_time_bitmap_ctrl_bit_duration,
436     &hf_nan_time_bitmap_ctrl_period,
437     &hf_nan_time_bitmap_ctrl_start_offset,
438     NULL
439 };
440 
441 static const true_false_string srf_type_flags = {
442     "Address Set is a Bloom filter",
443     "Address Set is a sequence of MAC Addresses"
444 };
445 
446 static const true_false_string srf_include_flags = {
447     "Only STAs Present in Address Set shall send a response",
448     "STAs present in Address Set shall not send responses"
449 };
450 
451 static const true_false_string sdea_ctr_data_path_type_flags = {
452     "Reserved",
453     "Unicast NDP required (Reserved if NDP is not required)"
454 };
455 
456 static const true_false_string sdea_ctr_reserved_multicast_type_flags = {
457     "Many to many (Reserved if NDP is not required)",
458     "One to many (Reserved if NDP is not required)"
459 };
460 
461 static const true_false_string device_cap_map_id_apply_to_flags = {
462     "Only specified map",
463     "All maps"
464 };
465 
466 static const true_false_string device_cap_op_mode_phy_flags = {
467     "VHT",
468     "HT only"
469 };
470 
471 static const true_false_string availability_entry_entries_type_flags = {
472     "Operating Classes and channel entries",
473     "Indicated bands"
474 };
475 
476 static const true_false_string ndc_ctr_selected_flags = {
477     "Selected NDC for a NDL Schedule",
478     "NDC included for the peer's information"
479 };
480 
481 static const value_string map_ctrl_availability_interval_duration[] = {
482     { 0, "16 TU" },
483     { 1, "32 TU" },
484     { 2, "64 TU" },
485     { 3, "Reserved" },
486     { 0, NULL }
487 };
488 
489 static const value_string service_ctr_type[] = {
490     { 0, "Publish" },
491     { 1, "Subscribe" },
492     { 2, "Follow up" },
493     { 3, "Reserved" },
494     { 0, NULL }
495 };
496 
497 static const range_string service_info_protocol_type[] = {
498     { 0, 0, "Reserved" },
499     { 1, 1, "Bonjour" },
500     { 2, 2, "Generic" },
501     { 3, 255, "Reserved" },
502     { 0, 0, NULL }
503 };
504 
505 static const value_string availability_entry_type[] = {
506     { 0, "Reserved" },
507     { 1, "Committed" },
508     { 2, "Potential" },
509     { 3, "Committed + Potential" },
510     { 4, "Conditional" },
511     { 5, "Reserved" },
512     { 6, "Potential + Conditional" },
513     { 7, "Reserved" },
514     { 0, NULL }
515 };
516 
517 static const range_string availability_entry_time_bitmap_ctr_bit_duration_type[] = {
518     { 0, 0, "16 TU" },
519     { 1, 1, "32 TU" },
520     { 2, 2, "64 TU" },
521     { 3, 3, "128 TU" },
522     { 4, 7, "Reserved" },
523     { 0, 0, NULL }
524 };
525 
526 static const value_string availability_entry_time_bitmap_ctr_period_type[] = {
527     { 1, "128 TU" },
528     { 2, "256 TU" },
529     { 3, "512 TU" },
530     { 4, "1024 TU" },
531     { 5, "2048 TU" },
532     { 6, "4096 TU" },
533     { 7, "8192 TU" },
534     { 0, NULL }
535 };
536 
537 static const range_string availability_entry_entries_band_type[] = {
538     { 0, 0, "Reserved (for TV white spaces)" },
539     { 1, 1, "Sub-1 GHz" },
540     { 2, 2, "2.4 GHz" },
541     { 3, 3, "Reserved (for 3.6 GHz)" },
542     { 4, 4, "4.9 and 5 GHz" },
543     { 5, 5, "Reserved (for 60 GHz)" },
544     { 6, 255, "Reserved" },
545     { 0, 0, NULL }
546 };
547 
548 static const range_string ndp_type_values[] = {
549     { 0, 0, "Request" },
550     { 1, 1, "Response" },
551     { 2, 2, "Confirm" },
552     { 3, 3, "Security Install" },
553     { 4, 4, "Terminate" },
554     { 5, 15, "Reserved" },
555     { 0, 0, NULL }
556 };
557 
558 static const range_string ndpe_tlv_type_values[] = {
559     { 0, 0, "IPv6 Link Local" },
560     { 1, 1, "Service Info" },
561     { 2, 255, "Reserved" },
562     { 0, 0, NULL }
563 };
564 
565 static const range_string ndl_type_values[] = {
566     { 0, 0, "Request" },
567     { 1, 1, "Response" },
568     { 2, 2, "Confirm" },
569     { 3, 15, "Reserved" },
570     { 0, 0, NULL }
571 };
572 
573 static const range_string ranging_setup_type_values[] = {
574     { 0, 0, "Request" },
575     { 1, 1, "Response" },
576     { 2, 2, "Termination" },
577     { 3, 15, "Reserved" },
578     { 0, 0, NULL }
579 };
580 
581 static const range_string status_type1_values[] = {
582     { 0, 0, "Continue" },
583     { 1, 1, "Accepted" },
584     { 2, 2, "Rejected" },
585     { 3, 15, "Reserved" },
586     { 0, 0, NULL }
587 };
588 
589 static const range_string status_type2_values[] = {
590     { 0, 0, "Accepted" },
591     { 1, 1, "Rejected" },
592     { 2, 15, "Reserved" },
593     { 0, 0, NULL }
594 };
595 
596 static const range_string reason_code_values[] = {
597     { 0, 0, "Reserved" },
598     { 1, 1, "UNSPECIFIED_REASON" },
599     { 2, 2, "RESOURCE_LIMITATION" },
600     { 3, 3, "INVALID_PARAMETERS" },
601     { 4, 4, "FTM_PARAMETERS_INCAPABLE" },
602     { 5, 5, "NO_MOVEMENT" },
603     { 6, 6, "INVALID_AVAILABILITY" },
604     { 7, 7, "IMMUTABLE_UNACCEPTABLE" },
605     { 8, 8, "SECURITY_POLICY" },
606     { 9, 9, "QoS_UNACCEPTABLE" },
607     { 10, 10, "NDP_REJECTED" },
608     { 11, 11, "NDL_UNACCEPTABLE" },
609     { 12, 12, "Ranging Schedule unacceptable" },
610     { 13, 255, "Reserved" },
611     { 0, 0, NULL }
612 };
613 
614 static const range_string action_frame_type_values[] = {
615     { 0, 0, "Reserved " },
616     { 1, 1, "Ranging Request " },
617     { 2, 2, "Ranging Response " },
618     { 3, 3, "Ranging Termination " },
619     { 4, 4, "Ranging Report " },
620     { 5, 5, "Data Path Request " },
621     { 6, 6, "Data Path Response " },
622     { 7, 7, "Data Path Confirm " },
623     { 8, 8, "Data Path Key Installment " },
624     { 9, 9, "Data Path Termination " },
625     { 10, 10, "Schedule Request " },
626     { 11, 11, "Schedule Response " },
627     { 12, 12, "Schedule Confirm " },
628     { 13, 13, "Schedule Update Notification " },
629     { 14, 255, "Reserved " },
630     { 0, 0, NULL }
631 };
632 
633 static const value_string ndl_type_string[] = {
634     { 0, "S-NDL" },
635     { 1, "Reserved (P-NDL)" },
636     { 0, NULL }
637 };
638 
639 static const value_string ndl_setup_reason[] = {
640     { 0, "NDP" },
641     { 1, "FSD using GAS" },
642     { 2, "Reserved" },
643     { 3, "Reserved" },
644     { 0, NULL }
645 };
646 
647 static const value_string unaligned_sch_ulw_type[] = {
648     { 0, "Followed by a Band ID field" },
649     { 1, "Followed by a Channel Entry field without Auxiliary Channel" },
650     { 2, "Followed by a Channel Entry field with Auxiliary Channel" },
651     { 3, "Reserved" },
652     { 0, NULL }
653 };
654 
655 static const range_string security_context_iden_type[] = {
656     { 0, 0, "Reserved" },
657     { 1, 1, "PMKID" },
658     { 2, 255, "Reserved" },
659     { 0, 0, NULL }
660 };
661 
662 static const value_string device_role[] = {
663     { 0, "AP" },
664     { 1, "Non-AP STA associated with AP" },
665     { 2, "Non-AP STA listening to AP" },
666     { 0, NULL }
667 };
668 
669 static const range_string furth_av_map_id[] = {
670     {0, 15, "Identify Further Availability attribute"},
671     {16, 255, "Reserved"},
672     {0, 0, NULL}
673 };
674 
675 typedef struct _range_channel_set {
676     guint32    value_min;
677     guint32    value_max;
678     const gint channel_set[16];
679 } range_channel_set;
680 
681 static const gint *
rval_to_channel_set(const guint32 val,const range_channel_set * ra)682 rval_to_channel_set(const guint32 val, const range_channel_set* ra)
683 {
684     gint i = 0;
685     if (ra)
686     {
687         while (*ra[i].channel_set) /* no such thing as channel 0 - end of list */
688         {
689             if ((val >= ra[i].value_min) && (val <= ra[i].value_max))
690             {
691                 return ra[i].channel_set;
692             }
693             i++;
694         }
695     }
696     return NULL;
697 }
698 
699 // TODO: this table corresponds to the 802.11 global operating classes.
700 //   it's probably in the 802.11 dissector somewhere and ideally this
701 //   should be used instead...
702 static const range_channel_set op_class_channel[] = {
703     {1, 80, {-1}},
704     {81, 81, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
705     {82, 82, {14}},
706     {83, 83, {1, 2, 3, 4, 5, 6, 7, 8, 9}},
707     {84, 84, {5, 6, 7, 8, 9, 10, 11, 12, 13}},
708     {85, 85, {-3}},
709     {86, 86, {-3}},
710     {87, 87, {-3}},
711     {88, 93, {-1}},
712     {94, 94, {133, 137}},
713     {95, 95, {136, 138}},
714     {96, 96, {131, 132, 133, 134, 135, 136, 137, 138}},
715     {97, 100, {-1}},
716     {101, 101, {21, 25}},
717     {102, 102, {11, 13, 15, 17, 19}},
718     {103, 103, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
719     {104, 104, {184, 192}},
720     {105, 105, {188, 196}},
721     {106, 106, {191, 195}},
722     {107, 107, {189, 191, 193, 195, 197}},
723     {108, 108, {188, 189, 190, 191, 192, 193, 194, 195, 196, 197}},
724     {109, 109, {184, 188, 192, 196}},
725     {110, 110, {183, 184, 185, 186, 187, 188, 189}},
726     {111, 111, {182, 183, 184, 185, 186, 187, 188, 189}},
727     {112, 112, {8, 12, 16}},
728     {113, 113, {7, 8, 9, 10, 11}},
729     {114, 114, {6, 7, 8, 9, 10, 11}},
730     {115, 115, {36, 40, 44, 48}},
731     {116, 116, {36, 44}},
732     {117, 117, {40, 48}},
733     {118, 118, {52, 56, 60, 64}},
734     {119, 119, {52, 60}},
735     {120, 120, {56, 64}},
736     {121, 121, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144}},
737     {122, 122, {100, 108, 116, 124, 132, 140}},
738     {123, 123, {103, 112, 120, 128, 136, 144}},
739     {124, 124, {149, 153, 157, 161}},
740     {125, 125, {149, 153, 157, 161,165, 169}},
741     {126, 126, {149, 157}},
742     {127, 127, {153, 161}},
743     {128, 128, {42, 58, 106, 122, 138, 155}},
744     {129, 129, {50, 114}},
745     {130, 130, {42, 58, 106, 122, 138, 155}},
746     {131, 179, {-1}},
747     {180, 180, {1, 2, 3, 4, 5, 6}},
748     {181, 191, {-1}},
749     {192, 254, {-2}},
750     {255, 255, {-1}},
751     {0, 0, {0}}, /* no such thing as channel 1 - end of list */
752 };
753 
754 static const range_string op_channel_spacing[] = {
755     {1, 80, "Reserved"},
756     {81, 82, "25"},
757     {83, 84, "40"},
758     {85, 85, "6, 7, 8"},
759     {86, 86, "12, 14, 16"},
760     {87, 87, "24, 28, 32"},
761     {88, 93, "Reserved"},
762     {94, 94, "20"},
763     {95, 95, "10"},
764     {96, 96, "5"},
765     {97, 100, "Reserved"},
766     {101, 101, "20"},
767     {102, 102, "10"},
768     {103, 103, "5"},
769     {104, 105, "40"},
770     {106, 106, "20"},
771     {107, 107, "10"},
772     {108, 108, "5"},
773     {109, 109, "20"},
774     {110, 110, "10"},
775     {111, 111, "5"},
776     {112, 112, "20"},
777     {113, 113, "10"},
778     {114, 114, "5"},
779     {115, 115, "20"},
780     {116, 117, "40"},
781     {118, 118, "20"},
782     {119, 120, "40"},
783     {121, 121, "20"},
784     {122, 123, "40"},
785     {124, 125, "20"},
786     {126, 127, "40"},
787     {128, 128, "80"},
788     {129, 129, "160"},
789     {130, 130, "80"},
790     {131, 179, "Reserved"},
791     {180, 180, "2160"},
792     {181, 191, "Reserved"},
793     {255, 255, "Reserved"},
794     {0, 0, NULL}
795 };
796 
797 static const range_string op_starting_freq[] = {
798     {1, 80, "Reserved"},
799     {81, 81, "2.407"},
800     {82, 82, "2.414"},
801     {83, 83, "2.407"},
802     {84, 84, "2.407"},
803     {88, 93, "Reserved"},
804     {94, 95, "3"},
805     {96, 96, "3.0025"},
806     {97, 100, "Reserved"},
807     {101, 101, "4.85"},
808     {102, 102, "4.89"},
809     {103, 103, "4.9375"},
810     {104, 104, "4"},
811     {105, 107, "4"},
812     {108, 108, "4.0025"},
813     {109, 110, "4"},
814     {111, 111, "4.0025"},
815     {112, 113, "5"},
816     {114, 114, "5.0025"},
817     {115, 130, "5"},
818     {131, 179, "Reserved"},
819     {180, 180, "56.16"},
820     {181, 191, "Reserved"},
821     {255, 255, "Reserved"},
822     {0, 0, NULL}
823 };
824 
825 static void
dissect_attr_master_indication(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)826 dissect_attr_master_indication(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
827 {
828     if (attr_len != NAN_MASTER_IND_LENGTH)
829     {
830         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
831         return;
832     }
833 
834     proto_tree_add_item(attr_tree, hf_nan_attr_master_preference, tvb,
835         offset + 3, 1, ENC_BIG_ENDIAN);
836     proto_tree_add_item(attr_tree, hf_nan_attr_master_random_factor, tvb,
837         offset + 4, 1, ENC_BIG_ENDIAN);
838 }
839 
840 static void
dissect_attr_cluster(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)841 dissect_attr_cluster(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
842 {
843     if (attr_len != NAN_CLUSTER_LENGTH)
844     {
845         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
846         return;
847     }
848 
849     proto_tree* anchor_master_tree = proto_tree_add_subtree(attr_tree, tvb, offset + 3, 13,
850         ett_cluster_anchor_master_info, NULL, "Anchor Master Information");
851     proto_tree_add_item(anchor_master_tree, hf_nan_attr_cluster_anchor_master_rank, tvb,
852         offset + 3, 8, ENC_BIG_ENDIAN);
853     proto_tree_add_item(anchor_master_tree, hf_nan_attr_cluster_hop_count, tvb,
854         offset + 11, 1, ENC_BIG_ENDIAN);
855     proto_tree_add_item(anchor_master_tree, hf_nan_attr_cluster_beacon_transmission_time, tvb,
856         offset + 12, 4, ENC_BIG_ENDIAN);
857 }
858 
859 static void
dissect_attr_service_id_list(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)860 dissect_attr_service_id_list(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
861 {
862     if (attr_len % 6 != 0 || attr_len == 0)
863     {
864         expert_add_info_format(pinfo, attr_tree, &ei_nan_elem_len_invalid, "Invalid Service ID length");
865         return;
866     }
867 
868     int num_service_ids = attr_len / 6;
869     offset += 3;
870     for (int i = 1; i <= num_service_ids; ++i)
871     {
872         proto_tree_add_item(attr_tree, hf_nan_service_id, tvb, offset, 6, ENC_NA);
873         offset += 6;
874     }
875 }
876 
877 static void
dissect_attr_sda(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)878 dissect_attr_sda(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
879 {
880     if (attr_len < NAN_SDA_MIN_LENGTH)
881     {
882         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
883         return;
884     }
885 
886     proto_tree_add_item(attr_tree, hf_nan_service_id, tvb,
887         offset + 3, 6, ENC_NA);
888     proto_tree_add_item(attr_tree, hf_nan_instance_id, tvb,
889         offset + 9, 1, ENC_BIG_ENDIAN);
890     proto_tree_add_item(attr_tree, hf_nan_attr_sda_requestor_instance_id, tvb,
891         offset + 10, 1, ENC_BIG_ENDIAN);
892     offset += 11;
893 
894     static int* const service_ctr_fields[] = {
895         &hf_nan_attr_sda_sc_type,
896         &hf_nan_attr_sda_sc_matching_filter,
897         &hf_nan_attr_sda_sc_service_response,
898         &hf_nan_attr_sda_sc_service_info,
899         &hf_nan_attr_sda_sc_discovery_range,
900         &hf_nan_attr_sda_sc_binding_bitmap,
901         NULL
902     };
903 
904     proto_tree_add_bitmask(attr_tree, tvb, offset, hf_nan_attr_sda_sc,
905         ett_sda_service_ctr, service_ctr_fields, ENC_LITTLE_ENDIAN);
906 
907     guint8 service_ctr_byte = tvb_get_guint8(tvb, offset);
908     offset += 1;
909 
910     const guint8 BITMASK_TYPE_SUBSCRIBE = 0x01;
911     const guint8 BITMASK_TYPE_FOLLOW_UP = 0x02;
912     const guint8 BITMASK_MATCHING_FILTER_PRESENT = 0x04;
913     const guint8 BITMASK_SERVICE_RESPONSE_FILTER_PRESENT = 0x08;
914     const guint8 BITMASK_SERVICE_INFO_PRESENT = 0x10;
915     const guint8 BITMASK_BITMAP_PRESENT = 0x40;
916 
917     if (service_ctr_byte & BITMASK_TYPE_SUBSCRIBE)
918     {
919         col_prepend_fstr(pinfo->cinfo, COL_INFO, "SDF Subscribe, ");
920     }
921     else if (service_ctr_byte & BITMASK_TYPE_FOLLOW_UP)
922     {
923         col_prepend_fstr(pinfo->cinfo, COL_INFO, "SDF Follow up, ");
924     }
925     else
926     {
927         col_prepend_fstr(pinfo->cinfo, COL_INFO, "SDF Publish, ");
928     }
929 
930     if (service_ctr_byte & BITMASK_BITMAP_PRESENT)
931     {
932         proto_tree_add_item(attr_tree, hf_nan_attr_sda_binding_bitmap, tvb,
933             offset, 2, ENC_LITTLE_ENDIAN);
934         offset += 2;
935     }
936 
937     if (service_ctr_byte & BITMASK_MATCHING_FILTER_PRESENT)
938     {
939         proto_tree_add_item(attr_tree, hf_nan_attr_sda_matching_filter_len, tvb,
940             offset, 1, ENC_LITTLE_ENDIAN);
941         gint mf_len = tvb_get_guint8(tvb, offset);
942         gint dissected_mf_len = 0;
943         offset += 1;
944         while (dissected_mf_len < mf_len)
945         {
946             gint filter_len = tvb_get_guint8(tvb, offset);
947             proto_tree_add_item(attr_tree, hf_nan_attr_sda_matching_filter_val, tvb,
948                 offset + 1, filter_len, ENC_NA);
949             offset += filter_len + 1;
950             dissected_mf_len += filter_len + 1;
951         }
952     }
953 
954     if (service_ctr_byte & BITMASK_SERVICE_RESPONSE_FILTER_PRESENT)
955     {
956         proto_tree_add_item(attr_tree, hf_nan_attr_sda_service_response_filter_len, tvb,
957             offset, 1, ENC_LITTLE_ENDIAN);
958         gint srf_len = tvb_get_guint8(tvb, offset);
959 
960         static int* const srf_ctr_fields[] = {
961             &hf_nan_attr_sda_srf_ctr_type,
962             &hf_nan_attr_sda_srf_ctr_include,
963             &hf_nan_attr_sda_srf_ctr_bloom_filter_index,
964             NULL
965         };
966 
967         proto_tree_add_bitmask(attr_tree, tvb, offset + 1, hf_nan_attr_sda_srf_ctr,
968             ett_sda_service_ctr, srf_ctr_fields, ENC_LITTLE_ENDIAN);
969         proto_tree_add_item(attr_tree, hf_nan_attr_sda_srf_address_set, tvb,
970             offset + 2, srf_len - 1, ENC_NA);
971         offset += srf_len + 1;
972     }
973 
974     if (service_ctr_byte & BITMASK_SERVICE_INFO_PRESENT)
975     {
976         guint32 service_info_len;
977 
978         /* XXX - use FT_UINT_BYTES? */
979         proto_tree_add_item_ret_uint(attr_tree, hf_nan_attr_sda_service_info_len, tvb,
980             offset, 1, ENC_BIG_ENDIAN, &service_info_len);
981         proto_tree_add_item(attr_tree, hf_nan_attr_sda_service_info, tvb,
982             offset + 1, service_info_len, ENC_NA);
983         // offset += service_info_len + 1;
984     }
985 }
986 
987 static void
dissect_attr_sdea(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)988 dissect_attr_sdea(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
989 {
990     if (attr_len < NAN_SDEA_MIN_LENGTH)
991     {
992         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
993         return;
994     }
995 
996     proto_tree_add_item(attr_tree, hf_nan_instance_id, tvb,
997         offset + 3, 1, ENC_LITTLE_ENDIAN);
998     offset += 4;
999     guint16 dissected_len = 1;
1000 
1001     static int* const sdea_ctr_fields[] = {
1002         &hf_nan_attr_sdea_ctr_fsd,
1003         &hf_nan_attr_sdea_ctr_fsd_w_gas,
1004         &hf_nan_attr_sdea_ctr_data_path,
1005         &hf_nan_attr_sdea_ctr_data_path_type,
1006         &hf_nan_attr_sdea_ctr_reserved_multicast_type,
1007         &hf_nan_attr_sdea_ctr_qos,
1008         &hf_nan_attr_sdea_ctr_security,
1009         &hf_nan_attr_sdea_ctr_ranging,
1010         &hf_nan_attr_sdea_ctr_range_limit,
1011         &hf_nan_attr_sdea_ctr_service_update_indicator,
1012         NULL
1013     };
1014 
1015     proto_tree_add_bitmask(attr_tree, tvb, offset, hf_nan_attr_sdea_ctr, ett_sdea_ctr,
1016         sdea_ctr_fields, ENC_LITTLE_ENDIAN);
1017 
1018     guint16 sdea_ctr_byte = tvb_get_letohs(tvb, offset);
1019     offset += 2;
1020     dissected_len += 2;
1021 
1022     if (sdea_ctr_byte & 0x100)
1023     {
1024         proto_tree* range_lim_tree = proto_tree_add_subtree(attr_tree, tvb, offset, 4,
1025             ett_sdea_range_limit, NULL, "Range Limit");
1026         proto_tree_add_item(range_lim_tree, hf_nan_attr_sdea_ingress_range_limit, tvb,
1027             offset, 2, ENC_LITTLE_ENDIAN);
1028         proto_tree_add_item(range_lim_tree, hf_nan_attr_sdea_egress_range_limit, tvb,
1029             offset + 2, 2, ENC_LITTLE_ENDIAN);
1030         offset += 4;
1031         dissected_len += 4;
1032     }
1033 
1034     if (sdea_ctr_byte & 0x200)
1035     {
1036         proto_tree_add_item(attr_tree, hf_nan_attr_sdea_service_update_indicator, tvb,
1037             offset, 1, ENC_LITTLE_ENDIAN);
1038         offset += 1;
1039         dissected_len += 1;
1040     }
1041 
1042     // If Service Info field is present
1043     if (dissected_len < attr_len)
1044     {
1045         proto_tree_add_item(attr_tree, hf_nan_attr_sdea_service_info_length, tvb,
1046             offset, 2, ENC_LITTLE_ENDIAN);
1047         proto_tree* service_info_tree = proto_tree_add_subtree(attr_tree, tvb, offset + 2,
1048             attr_len - dissected_len - 2, ett_sdea_service_info, NULL, "Service Info");
1049         proto_tree_add_item(service_info_tree, hf_nan_oui, tvb,
1050             offset + 2, 3, ENC_NA);
1051         proto_tree_add_item(service_info_tree, hf_nan_attr_sdea_service_info_protocol_type, tvb,
1052             offset + 5, 1, ENC_BIG_ENDIAN);
1053         proto_tree_add_item(service_info_tree, hf_nan_attr_sdea_service_info_specific, tvb,
1054             offset + 6, attr_len - dissected_len - 6, ENC_NA);
1055     }
1056 }
1057 
1058 static void
dissect_attr_connection_capability(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1059 dissect_attr_connection_capability(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1060 {
1061     if (attr_len != NAN_CONNECTION_CAP_LENGTH)
1062     {
1063         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1064         return;
1065     }
1066 
1067     static int* const connection_cap_bitmap_fields[] = {
1068         &hf_nan_attr_connection_cap_wifi_direct,
1069         &hf_nan_attr_connection_cap_p2ps,
1070         &hf_nan_attr_connection_cap_tdls,
1071         &hf_nan_attr_connection_cap_wlan_infra,
1072         &hf_nan_attr_connection_cap_ibss,
1073         &hf_nan_attr_connection_cap_mesh,
1074         NULL
1075     };
1076 
1077     proto_tree_add_bitmask(attr_tree, tvb, offset + 3, hf_nan_attr_connection_cap_bitmap,
1078         ett_connection_cap_field, connection_cap_bitmap_fields, ENC_LITTLE_ENDIAN);
1079 }
1080 
1081 static void
dissect_attr_wlan_infra(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1082 dissect_attr_wlan_infra(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1083 {
1084     if (attr_len < NAN_WLAN_INFRA_MIN_LENGTH)
1085     {
1086         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1087         return;
1088     }
1089 
1090     guint sub_offset = offset + 3;
1091     proto_tree_add_item(attr_tree, hf_nan_bss_id, tvb, sub_offset, 6, ENC_LITTLE_ENDIAN);
1092     sub_offset += 6;
1093     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
1094     sub_offset += 6;
1095     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_map_ctrl_field,
1096         ett_map_control, map_control_fields, ENC_LITTLE_ENDIAN);
1097     sub_offset++;
1098     gint bitmap_length = attr_len - 14;
1099     proto_tree_add_item(attr_tree, hf_nan_availability_intervals_bitmap, tvb, sub_offset, bitmap_length, ENC_NA);
1100     sub_offset += bitmap_length;
1101     proto_tree_add_item(attr_tree, hf_nan_attr_wlan_infra_device_role, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1102 }
1103 
1104 static void
dissect_attr_p2p_operation(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1105 dissect_attr_p2p_operation(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1106 {
1107     if (attr_len < NAN_P2P_OP_MIN_LENGTH)
1108     {
1109         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1110         return;
1111     }
1112 
1113     guint sub_offset = offset + 3;
1114     static int* const p2p_bitmap_fields[] = {
1115         &hf_nan_attr_p2p_device_role_device,
1116         &hf_nan_attr_p2p_device_role_group_owner,
1117         &hf_nan_attr_p2p_device_role_client,
1118         NULL
1119     };
1120 
1121     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_p2p_device_role,
1122         ett_p2p_device_role, p2p_bitmap_fields, ENC_LITTLE_ENDIAN);
1123     sub_offset++;
1124     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
1125     sub_offset += 6;
1126     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_map_ctrl_field,
1127         ett_map_control, map_control_fields, ENC_LITTLE_ENDIAN);
1128     sub_offset++;
1129     proto_tree_add_item(attr_tree, hf_nan_availability_intervals_bitmap, tvb, sub_offset, -1, ENC_NA);
1130 }
1131 
1132 static void
dissect_attr_ibss(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1133 dissect_attr_ibss(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1134 {
1135     if (attr_len < NAN_IBSS_MIN_LENGTH)
1136     {
1137         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1138         return;
1139     }
1140 
1141     guint sub_offset = offset + 3;
1142     proto_tree_add_item(attr_tree, hf_nan_bss_id, tvb, sub_offset, 6, ENC_LITTLE_ENDIAN);
1143     sub_offset += 6;
1144     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
1145     sub_offset += 6;
1146     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_map_ctrl_field,
1147         ett_map_control, map_control_fields, ENC_LITTLE_ENDIAN);
1148     sub_offset++;
1149     proto_tree_add_item(attr_tree, hf_nan_availability_intervals_bitmap, tvb, sub_offset, -1, ENC_NA);
1150 }
1151 
1152 static void
dissect_attr_mesh(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1153 dissect_attr_mesh(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1154 {
1155     if (attr_len < NAN_MESH_MIN_LENGTH)
1156     {
1157         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1158         return;
1159     }
1160 
1161     guint sub_offset = offset + 3;
1162     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
1163     sub_offset += 6;
1164 
1165     guint8 duration = tvb_get_bits8(tvb, sub_offset * 8 + 5, 2);
1166     guint bitmap_length;
1167     switch (duration) {
1168     case 0:
1169         bitmap_length = 4;
1170         break;
1171     case 1:
1172         bitmap_length = 2;
1173         break;
1174     case 2:
1175         bitmap_length = 1;
1176         break;
1177     default:
1178         bitmap_length = 0;
1179     }
1180 
1181     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_map_ctrl_field,
1182         ett_map_control, map_control_fields, ENC_LITTLE_ENDIAN);
1183     sub_offset++;
1184     proto_tree_add_item(attr_tree, hf_nan_availability_intervals_bitmap, tvb, sub_offset, bitmap_length, ENC_NA);
1185     sub_offset += bitmap_length;
1186     proto_tree_add_item(attr_tree, hf_nan_attr_mesh_id, tvb, sub_offset, -1, ENC_NA);
1187 }
1188 
1189 static void
dissect_attr_further_service_discovery(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len)1190 dissect_attr_further_service_discovery(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len)
1191 {
1192     guint sub_offset = offset + 3;
1193     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_map_ctrl_field,
1194         ett_map_control, map_control_fields, ENC_LITTLE_ENDIAN);
1195     sub_offset++;
1196     gint bitmap_length = attr_len - 1;
1197     proto_tree_add_item(attr_tree, hf_nan_availability_intervals_bitmap, tvb, sub_offset, bitmap_length, ENC_NA);
1198 }
1199 
1200 static void
dissect_attr_further_availability_map(proto_tree * attr_tree,tvbuff_t * tvb,gint offset)1201 dissect_attr_further_availability_map(proto_tree* attr_tree, tvbuff_t* tvb, gint offset)
1202 {
1203     guint sub_offset = offset + 3;
1204     proto_tree_add_item(attr_tree, hf_nan_attr_further_av_map_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1205     sub_offset++;
1206 
1207     static int* const availability_entry_control_fields[] = {
1208         &hf_nan_attr_further_av_map_entry_av_interval_duration,
1209         NULL
1210     };
1211 
1212     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_further_av_map_entry_ctrl,
1213         ett_further_av_map_entry_ctrl, availability_entry_control_fields, ENC_LITTLE_ENDIAN);
1214     sub_offset++;
1215     proto_tree_add_item(attr_tree, hf_nan_attr_further_av_map_op_class, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1216     sub_offset++;
1217     proto_tree_add_item(attr_tree, hf_nan_attr_further_av_map_channel_num, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1218     sub_offset++;
1219     proto_tree_add_item(attr_tree, hf_nan_availability_intervals_bitmap, tvb, sub_offset, -1, ENC_NA);
1220 }
1221 
1222 static void
dissect_attr_country_code(proto_tree * attr_tree,tvbuff_t * tvb,gint offset)1223 dissect_attr_country_code(proto_tree* attr_tree, tvbuff_t* tvb, gint offset)
1224 {
1225     guint sub_offset = offset + 3;
1226     proto_tree_add_item(attr_tree, hf_nan_attr_country_code, tvb, sub_offset, 2, ENC_ASCII|ENC_NA);
1227 }
1228 
1229 static void
dissect_attr_ranging(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1230 dissect_attr_ranging(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1231 {
1232     if (attr_len < NAN_RANGING_MIN_LENGTH)
1233     {
1234         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1235         return;
1236     }
1237 
1238     guint sub_offset = offset + 3;
1239     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
1240     sub_offset += 6;
1241     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_map_ctrl_field,
1242         ett_map_control, map_control_fields, ENC_LITTLE_ENDIAN);
1243     sub_offset++;
1244     proto_tree_add_item(attr_tree, hf_nan_attr_ranging_protocol, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1245     sub_offset++;
1246     proto_tree_add_item(attr_tree, hf_nan_availability_intervals_bitmap, tvb, sub_offset, -1, ENC_NA);
1247 }
1248 
1249 static void
dissect_attr_cluter_discovery(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1250 dissect_attr_cluter_discovery(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1251 {
1252     if (attr_len != NAN_CLUSTER_DISC_LENGTH)
1253     {
1254         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1255         return;
1256     }
1257 
1258     guint sub_offset = offset + 3;
1259     proto_tree_add_item(attr_tree, hf_nan_attr_cluster_disc_id, tvb, sub_offset, 6, ENC_LITTLE_ENDIAN);
1260     sub_offset += 6;
1261     proto_tree_add_item(attr_tree, hf_nan_attr_cluster_disc_time_offset, tvb, sub_offset, 8, ENC_LITTLE_ENDIAN);
1262     sub_offset += 8;
1263     proto_tree_add_item(attr_tree, hf_nan_attr_cluster_disc_anchor_master_rank, tvb, sub_offset, 8, ENC_LITTLE_ENDIAN);
1264 }
1265 
1266 static void
dissect_attr_device_capability(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1267 dissect_attr_device_capability(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1268 {
1269     if (attr_len != NAN_DEVICE_CAP_LENGTH)
1270     {
1271         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1272         return;
1273     }
1274 
1275     static int* const device_cap_map_id_fields[] = {
1276         &hf_nan_attr_device_cap_map_id_apply_to,
1277         &hf_nan_attr_device_cap_map_id_associated_maps,
1278         NULL
1279     };
1280     static int* const device_cap_committed_dw_fields[] = {
1281         &hf_nan_attr_device_cap_committed_dw_24ghz,
1282         &hf_nan_attr_device_cap_committed_dw_5ghz,
1283         &hf_nan_attr_device_cap_committed_dw_24ghz_overwrite,
1284         &hf_nan_attr_device_cap_committed_dw_5ghz_overwrite,
1285         NULL
1286     };
1287     static int* const device_cap_supported_bands_fields[] = {
1288         &hf_nan_attr_device_cap_supported_bands_reserved_tv_whitespaces,
1289         &hf_nan_attr_device_cap_supported_bands_sub_1ghz,
1290         &hf_nan_attr_device_cap_supported_bands_24ghz,
1291         &hf_nan_attr_device_cap_supported_bands_reserved_36ghz,
1292         &hf_nan_attr_device_cap_supported_bands_5ghz,
1293         &hf_nan_attr_device_cap_supported_bands_reserved_60ghz,
1294         NULL
1295     };
1296     static int* const device_cap_op_mode_fields[] = {
1297         &hf_nan_attr_device_cap_op_mode_phy,
1298         &hf_nan_attr_device_cap_op_mode_vht8080,
1299         &hf_nan_attr_device_cap_op_mode_vht160,
1300         &hf_nan_attr_device_cap_op_mode_reserved_paging_ndl,
1301         NULL
1302     };
1303     static int* const device_cap_antennas_fields[] = {
1304         &hf_nan_attr_device_cap_antennas_tx,
1305         &hf_nan_attr_device_cap_antennas_rx,
1306         NULL
1307     };
1308     static int* const device_cap_capabilities_fields[] = {
1309         &hf_nan_attr_device_cap_capabilities_dfs_master,
1310         &hf_nan_attr_device_cap_capabilities_extended_key_id,
1311         &hf_nan_attr_device_cap_capabilities_simul_ndp_reception,
1312         &hf_nan_attr_device_cap_capabilities_ndpe_attr_support,
1313         NULL
1314     };
1315 
1316     proto_tree_add_bitmask(attr_tree, tvb, offset + 3, hf_nan_map_id,
1317         ett_device_cap_map_id, device_cap_map_id_fields, ENC_LITTLE_ENDIAN);
1318     proto_tree_add_bitmask(attr_tree, tvb, offset + 4, hf_nan_attr_device_cap_committed_dw,
1319         ett_device_cap_committed_dw, device_cap_committed_dw_fields, ENC_LITTLE_ENDIAN);
1320     proto_tree_add_bitmask(attr_tree, tvb, offset + 6, hf_nan_attr_device_cap_supported_bands,
1321         ett_device_cap_supported_bands, device_cap_supported_bands_fields, ENC_LITTLE_ENDIAN);
1322     proto_tree_add_bitmask(attr_tree, tvb, offset + 7, hf_nan_attr_device_cap_op_mode,
1323         ett_device_cap_op_mode, device_cap_op_mode_fields, ENC_LITTLE_ENDIAN);
1324     proto_tree_add_bitmask(attr_tree, tvb, offset + 8, hf_nan_attr_device_cap_antennas,
1325         ett_device_cap_antennas, device_cap_antennas_fields, ENC_LITTLE_ENDIAN);
1326     proto_tree_add_item(attr_tree, hf_nan_attr_device_cap_max_channel_switch_time, tvb,
1327         offset + 9, 2, ENC_LITTLE_ENDIAN);
1328     proto_tree_add_bitmask(attr_tree, tvb, offset + 11, hf_nan_attr_device_cap_capabilities,
1329         ett_device_cap_capabilities, device_cap_capabilities_fields, ENC_LITTLE_ENDIAN);
1330 }
1331 
1332 static void
dissect_attr_ndp(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1333 dissect_attr_ndp(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1334 {
1335     if (attr_len < NAN_NDP_MIN_LENGTH)
1336     {
1337         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1338         return;
1339     }
1340 
1341     guint sub_offset = offset + 3;
1342     proto_tree_add_item(attr_tree, hf_nan_dialog_tokens, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1343     sub_offset++;
1344 
1345     static int* const ndp_type_status_fields[] = {
1346         &hf_nan_attr_ndp_type,
1347         &hf_nan_status_1,
1348         NULL
1349     };
1350     static int* const ndp_control_fields[] = {
1351         &hf_nan_attr_ndp_ctrl_confirm,
1352         &hf_nan_attr_ndp_ctrl_security_pres,
1353         &hf_nan_attr_ndp_ctrl_publish_id_pres,
1354         &hf_nan_attr_ndp_ctrl_responder_ndi_pres,
1355         &hf_nan_attr_ndp_ctrl_sepcific_info_pres,
1356         NULL
1357     };
1358 
1359     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_type_status,
1360         ett_type_status, ndp_type_status_fields, ENC_LITTLE_ENDIAN);
1361 
1362     guint8 bits_type = tvb_get_bits8(tvb, sub_offset * 8 + 4, 4);
1363     guint8 bit_offset = (sub_offset * 8) + 4;
1364     guint8 bits_status = tvb_get_bits8(tvb, bit_offset, 4);
1365     sub_offset++;
1366     proto_tree_add_item(attr_tree, hf_nan_reason_code, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1367     sub_offset++;
1368     proto_tree_add_item(attr_tree, hf_nan_attr_ndp_initiator, tvb, sub_offset, 6, ENC_NA);
1369     sub_offset += 6;
1370     proto_tree_add_item(attr_tree, hf_nan_attr_ndp_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1371     sub_offset++;
1372     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_ndp_control,
1373         ett_ndp_control, ndp_control_fields, ENC_LITTLE_ENDIAN);
1374 
1375     guint8 bits_ndp_info = tvb_get_bits8(tvb, (sub_offset * 8) + 2, 1);
1376     guint8 bits_publish_id = tvb_get_bits8(tvb, (sub_offset * 8) + 4, 1);
1377     sub_offset++;
1378 
1379     if (bits_publish_id == 1 && bits_type == 0)
1380     {
1381         proto_tree_add_item(attr_tree, hf_nan_publish_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1382         sub_offset++;
1383     }
1384     if (bits_type == 1 && (bits_status == 0 || bits_status == 1))
1385     {
1386         proto_tree_add_item(attr_tree, hf_nan_attr_ndp_responder_ndi, tvb, sub_offset, 6, ENC_NA);
1387         sub_offset += 6;
1388     }
1389     if (bits_ndp_info)
1390     {
1391         proto_tree_add_item(attr_tree, hf_nan_attr_ndp_specific_info, tvb, sub_offset, -1, ENC_NA);
1392     }
1393 }
1394 
1395 static void
dissect_attr_ndpe(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1396 dissect_attr_ndpe(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1397 {
1398     if (attr_len < NAN_NDPE_MIN_LENGTH)
1399     {
1400         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1401         return;
1402     }
1403 
1404     static int* const ndp_type_status_fields[] = {
1405         &hf_nan_attr_ndp_type,
1406         &hf_nan_status_1,
1407         NULL
1408     };
1409     static int* const ndp_control_fields[] = {
1410         &hf_nan_attr_ndp_ctrl_confirm,
1411         &hf_nan_attr_ndp_ctrl_security_pres,
1412         &hf_nan_attr_ndp_ctrl_publish_id_pres,
1413         &hf_nan_attr_ndp_ctrl_responder_ndi_pres,
1414         NULL
1415     };
1416 
1417     gint dissected_len = 0;
1418     proto_tree_add_item(attr_tree, hf_nan_dialog_tokens, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1419     proto_tree_add_bitmask(attr_tree, tvb, offset + 4, hf_nan_type_status,
1420         ett_type_status, ndp_type_status_fields, ENC_LITTLE_ENDIAN);
1421 
1422     offset += 4;
1423     dissected_len += 4;
1424     guint8 bits_type = tvb_get_bits8(tvb, offset * 8 + 4, 4);
1425     guint32 bit_offset = (offset * 8) + 4;
1426     guint8 bits_status = tvb_get_bits8(tvb, bit_offset, 4);
1427 
1428     proto_tree_add_item(attr_tree, hf_nan_reason_code, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
1429     proto_tree_add_item(attr_tree, hf_nan_attr_ndp_initiator, tvb, offset + 2, 6, ENC_NA);
1430     proto_tree_add_item(attr_tree, hf_nan_attr_ndp_id, tvb, offset + 8, 1, ENC_BIG_ENDIAN);
1431     proto_tree_add_bitmask(attr_tree, tvb, offset + 9, hf_nan_attr_ndp_control,
1432         ett_ndp_control, ndp_control_fields, ENC_LITTLE_ENDIAN);
1433     offset += 9;
1434     dissected_len += 9;
1435 
1436     guint8 bits_publish_id = tvb_get_bits8(tvb, (offset * 8) + 4, 1);
1437     offset++;
1438     dissected_len++;
1439 
1440     if (bits_publish_id == 1 && bits_type == 0)
1441     {
1442         proto_tree_add_item(attr_tree, hf_nan_publish_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1443         offset++;
1444         dissected_len++;
1445     }
1446     if (bits_type == 1 && (bits_status == 0 || bits_status == 1))
1447     {
1448         proto_tree_add_item(attr_tree, hf_nan_attr_ndp_responder_ndi, tvb, offset, 6, ENC_NA);
1449         offset += 6;
1450         dissected_len += 6;
1451     }
1452 
1453     while (dissected_len < attr_len)
1454     {
1455         guint8 tlv_type = tvb_get_guint8(tvb, offset);
1456         guint16 tlv_len = tvb_get_letohs(tvb, offset + 1);
1457         proto_tree* tlv_tree = proto_tree_add_subtree(attr_tree, tvb, offset, tlv_len + 3,
1458             ett_ndpe_tlv, NULL, "TLV entry");
1459         proto_tree_add_item(tlv_tree, hf_nan_attr_ndpe_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1460         proto_tree_add_item(tlv_tree, hf_nan_attr_ndpe_tlv_len, tvb, offset + 1, 2, ENC_LITTLE_ENDIAN);
1461 
1462         switch (tlv_type)
1463         {
1464         case 0:
1465             proto_tree_add_item(tlv_tree, hf_nan_attr_ndpe_tlv_ipv6_interface_identifier, tvb, offset + 3, 8, ENC_NA);
1466             offset += 11;
1467             dissected_len += 11;
1468             break;
1469         case 1:
1470             proto_tree_add_item(tlv_tree, hf_nan_oui, tvb, offset + 3, 3, ENC_NA);
1471             proto_tree_add_item(tlv_tree, hf_nan_attr_vendor_specific_body, tvb, offset + 6, tlv_len - 3, ENC_NA);
1472             offset += tlv_len + 3;
1473             dissected_len += tlv_len + 3;
1474             break;
1475         default:
1476             proto_tree_add_item(tlv_tree, hf_nan_attr_vendor_specific_body, tvb, offset + 3, tlv_len, ENC_NA);
1477             offset += tlv_len + 3;
1478             dissected_len += tlv_len + 3;
1479             break;
1480         }
1481     }
1482 }
1483 
1484 static void
dissect_attr_availability(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1485 dissect_attr_availability(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1486 {
1487     if (attr_len < NAN_AVAILABILITY_MIN_LENGTH)
1488     {
1489         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1490         return;
1491     }
1492 
1493     static int* const availability_ctr_fields[] = {
1494         &hf_nan_attr_availability_map_id,
1495         &hf_nan_attr_availability_committed_changed,
1496         &hf_nan_attr_availability_potential_changed,
1497         &hf_nan_attr_availability_public_availability_changed,
1498         &hf_nan_attr_availability_ndc_changed,
1499         &hf_nan_attr_availability_reserved_multicast_schedule_changed,
1500         &hf_nan_attr_availability_reserved_multicast_schedule_change_changed,
1501         NULL
1502     };
1503     static int* const availability_entry_ctr_fields[] = {
1504         &hf_nan_attr_availability_entry_ctr_type,
1505         &hf_nan_attr_availability_entry_ctr_pref,
1506         &hf_nan_attr_availability_entry_ctr_utilization,
1507         &hf_nan_attr_availability_entry_ctr_rx_nss,
1508         &hf_nan_attr_availability_entry_ctr_time_bitmap,
1509         NULL
1510     };
1511 
1512     proto_tree_add_item(attr_tree, hf_nan_attr_availability_sequence_id, tvb,
1513         offset + 3, 1, ENC_LITTLE_ENDIAN);
1514     proto_tree_add_bitmask(attr_tree, tvb, offset + 4, hf_nan_attr_availability_ctr,
1515         ett_device_cap_capabilities, availability_ctr_fields, ENC_LITTLE_ENDIAN);
1516     offset += 6;
1517 
1518     gint dissected_len = 3;
1519     while (dissected_len < attr_len)
1520     {
1521         guint16 entry_len = tvb_get_letohs(tvb, offset);
1522         guint8 entry_type = tvb_get_bits8(tvb, offset * 8 + 21, 3);
1523         guint8 hdr_len = 2;
1524         guint32 time_bitmap_len = 0;
1525         guint64 avail_entry;
1526         const gchar* entry_type_msg = val_to_str(entry_type, availability_entry_type,
1527             "Unknown type (%u)");
1528         gchar* info_msg = g_strconcat("Availability Type : ", entry_type_msg, NULL);
1529         proto_tree* entry_tree = proto_tree_add_subtree(attr_tree, tvb, offset, entry_len + 2,
1530             ett_availability_entry, NULL, info_msg);
1531         proto_tree_add_item(entry_tree, hf_nan_attr_availability_entry_len, tvb,
1532             offset, 2, ENC_LITTLE_ENDIAN);
1533         proto_tree_add_bitmask_ret_uint64(entry_tree, tvb, offset + 2, hf_nan_attr_availability_entry_ctr,
1534             ett_availability_entry_ctr, availability_entry_ctr_fields, ENC_LITTLE_ENDIAN, &avail_entry);
1535         offset += 4;
1536 
1537         gboolean time_bitmap_present = avail_entry & (1 << 12);
1538         if (time_bitmap_present)
1539         {
1540             proto_tree_add_bitmask(entry_tree, tvb, offset,
1541                 hf_nan_time_bitmap_ctrl, ett_time_bitmap_ctrl,
1542                 time_bitmap_ctr_fields, ENC_LITTLE_ENDIAN);
1543             proto_tree_add_item_ret_uint(entry_tree, hf_nan_time_bitmap_len, tvb,
1544                 offset + 2, 1, ENC_LITTLE_ENDIAN, &time_bitmap_len);
1545             proto_tree_add_item(entry_tree, hf_nan_time_bitmap, tvb,
1546                 offset + 3, time_bitmap_len, ENC_NA);
1547             hdr_len = 5;
1548             offset += 3 + time_bitmap_len;
1549         }
1550 
1551         gint entries_len = entry_len - hdr_len - time_bitmap_len;
1552         proto_tree* entries_tree = proto_tree_add_subtree(entry_tree, tvb, offset, entries_len,
1553             ett_availability_entry_entries, NULL, "Band/Channel Entries");
1554 
1555         guint64 entries_type, non_contiguous_bw, num_entries;
1556         proto_tree_add_bits_ret_val(entries_tree, hf_nan_attr_availability_entry_entries_type, tvb,
1557             offset * 8 + 7, 1, &entries_type, ENC_LITTLE_ENDIAN);
1558         proto_tree_add_bits_ret_val(entries_tree,
1559             hf_nan_attr_availability_entry_entries_non_contiguous_bw, tvb, offset * 8 + 6, 1,
1560             &non_contiguous_bw, ENC_LITTLE_ENDIAN);
1561         proto_tree_add_bits_ret_val(entries_tree, hf_nan_attr_availability_entry_entries_num_entries,
1562             tvb, offset * 8, 4, &num_entries, ENC_LITTLE_ENDIAN);
1563 
1564         offset += 1;
1565         for (guint8 i = 0; i < num_entries; i++)
1566         {
1567             switch (entries_type) {
1568             case 0:
1569             {
1570                 proto_tree_add_item(entries_tree, hf_nan_attr_availability_entry_entries_band, tvb,
1571                     offset, 1, ENC_LITTLE_ENDIAN);
1572                 offset += 1;
1573                 break;
1574             }
1575             case 1:
1576             {
1577                 int channel_entry_len = (non_contiguous_bw == 0) ? 4 : 6;
1578                 proto_tree* channel_tree = proto_tree_add_subtree(entries_tree, tvb, offset,
1579                     channel_entry_len, ett_availability_entry_entries_channel, NULL, "Channel Entry");
1580                 guint8 op_class = tvb_get_guint8(tvb, offset);
1581                 guint16 bitmap = tvb_get_guint16(tvb, offset + 1, ENC_LITTLE_ENDIAN);
1582                 proto_tree* op_class_tree = proto_tree_add_subtree(channel_tree, tvb, offset, 1, ett_availability_op_class, NULL, "Operating Class");
1583                 proto_tree_add_item(op_class_tree, hf_nan_attr_availability_entry_entries_start_freq, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1584                 proto_tree_add_item(op_class_tree, hf_nan_attr_availability_entry_entries_bandwidth, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1585                 wmem_strbuf_t* str;
1586                 str = wmem_strbuf_new(pinfo->pool, "");
1587                 for(unsigned i_bitmap = 0; i_bitmap < 16; ++i_bitmap)
1588                 {
1589                     if (bitmap & (1u << i_bitmap))
1590                     {
1591 
1592                         const gint *channel_set = rval_to_channel_set(op_class, op_class_channel);
1593                         if (channel_set == NULL)
1594                         {
1595                             expert_add_info(pinfo, channel_tree, &ei_nan_unknown_op_class);
1596                             break;
1597                         }
1598                         gint channel = channel_set[i_bitmap];
1599 
1600                         switch (channel)
1601                         {
1602                         // TODO: replace these magic numbers (or use 802.11 dissector for this)
1603                         case -3:
1604                             wmem_strbuf_append_printf(str, "%s", "Derived from regulation ");
1605                             break;
1606                         case -2:
1607                             wmem_strbuf_append_printf(str, "%s", "Vendor Specific ");
1608                             break;
1609                         case -1:
1610                             wmem_strbuf_append_printf(str, "%s", "Reserved ");
1611                             break;
1612                         default:
1613                             wmem_strbuf_append_printf(str, "%d ", channel);
1614                         }
1615                     }
1616                 }
1617                 proto_tree_add_string(channel_tree, hf_nan_attr_availability_entry_entries_channel_set, tvb, offset + 1, 2, wmem_strbuf_finalize(str));
1618                 proto_tree_add_item(channel_tree,
1619                     hf_nan_attr_availability_entry_entries_primary_channel_bitmap, tvb,
1620                     offset + 3, 1, ENC_LITTLE_ENDIAN);
1621 
1622                 if (non_contiguous_bw == 1)
1623                 {
1624                     proto_tree_add_item(channel_tree,
1625                         hf_nan_attr_availability_entry_entries_aux_channel_bitmap, tvb,
1626                         offset + 4, 2, ENC_LITTLE_ENDIAN);
1627                 }
1628                 offset += channel_entry_len;
1629                 break;
1630             }
1631             }
1632         }
1633         dissected_len += entry_len + 2;
1634     }
1635 }
1636 
1637 static void
dissect_attr_ndc(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1638 dissect_attr_ndc(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1639 {
1640     if (attr_len < NAN_NDC_MIN_LENGTH)
1641     {
1642         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1643         return;
1644     }
1645 
1646     static int* const ndc_ctr_fields[] = {
1647         &hf_nan_attr_ndc_ctrl_selected,
1648         NULL
1649     };
1650 
1651     static int* const ndc_map_id_fields[] = {
1652         &hf_nan_attr_ndc_map_id_related_sch,
1653         NULL
1654     };
1655 
1656     proto_tree_add_item(attr_tree, hf_nan_attr_ndc_id, tvb, offset + 3, 6, ENC_NA);
1657     proto_tree_add_bitmask(attr_tree, tvb, offset + 9, hf_nan_attr_ndc_ctrl,
1658         ett_ndc_ctr, ndc_ctr_fields, ENC_LITTLE_ENDIAN);
1659 
1660     offset += 10;
1661     gint dissected_len = 7;
1662     while (dissected_len < attr_len)
1663     {
1664         guint8 time_bitmap_len = tvb_get_guint8(tvb, offset + 3);
1665         proto_tree* entry_tree = proto_tree_add_subtree(attr_tree, tvb, offset,
1666             time_bitmap_len + 4, ett_ndc_entries, NULL, "Schedule Entry");
1667         proto_tree_add_bitmask(entry_tree, tvb, offset, hf_nan_map_id,
1668             ett_device_ndc_map_id, ndc_map_id_fields, ENC_LITTLE_ENDIAN);
1669         proto_tree_add_bitmask(entry_tree, tvb, offset + 1,
1670             hf_nan_time_bitmap_ctrl, ett_time_bitmap_ctrl,
1671             time_bitmap_ctr_fields, ENC_LITTLE_ENDIAN);
1672         proto_tree_add_item(entry_tree, hf_nan_time_bitmap_len, tvb,
1673             offset + 3, 1, ENC_BIG_ENDIAN);
1674         proto_tree_add_item(entry_tree, hf_nan_time_bitmap, tvb,
1675             offset + 4, time_bitmap_len, ENC_NA);
1676 
1677         offset += time_bitmap_len + 4;
1678         dissected_len += time_bitmap_len + 4;
1679     }
1680 }
1681 
1682 static void
dissect_attr_ndl(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1683 dissect_attr_ndl(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1684 {
1685     if (attr_len < NAN_NDL_MIN_LENGTH)
1686     {
1687         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1688         return;
1689     }
1690 
1691     guint sub_offset = offset + 3;
1692     guint dissected_len = 0;
1693     proto_tree_add_item(attr_tree, hf_nan_dialog_tokens, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1694     sub_offset++;
1695 
1696     static int* const ndl_type_status_fields[] = {
1697         &hf_nan_attr_ndl_type,
1698         &hf_nan_status_1,
1699         NULL
1700     };
1701     static int* const ndl_control_fields[] = {
1702         &hf_nan_attr_ndl_ctrl_peer_id,
1703         &hf_nan_attr_ndl_ctrl_immutable_schedule_pres,
1704         &hf_nan_attr_ndl_ctrl_ndc_pres,
1705         &hf_nan_attr_ndl_ctrl_qos,
1706         &hf_nan_attr_ndl_ctrl_max_idle_pres,
1707         &hf_nan_attr_ndl_ctrl_type,
1708         &hf_nan_attr_ndl_ctrl_setup_reason,
1709         NULL
1710     };
1711 
1712     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_type_status,
1713         ett_type_status, ndl_type_status_fields, ENC_LITTLE_ENDIAN);
1714     sub_offset++;
1715     proto_tree_add_item(attr_tree, hf_nan_reason_code, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1716     sub_offset++;
1717     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_ndl_control,
1718         ett_ndl_control, ndl_control_fields, ENC_LITTLE_ENDIAN);
1719 
1720     guint8 peer_id_pres = tvb_get_bits8(tvb, sub_offset * 8 + 7, 1);
1721     guint8 immutable_sched_pres = tvb_get_bits8(tvb, sub_offset * 8 + 6, 1);
1722     guint8 idle_per = tvb_get_bits8(tvb, sub_offset * 8 + 3, 1);
1723     sub_offset++;
1724     dissected_len += 4;
1725 
1726     if (peer_id_pres)
1727     {
1728         proto_tree_add_item(attr_tree, hf_nan_attr_ndl_reserved_peer_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1729         sub_offset++;
1730         dissected_len++;
1731     }
1732     if (idle_per)
1733     {
1734         proto_tree_add_item(attr_tree, hf_nan_attr_ndl_max_idle, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
1735         sub_offset += 2;
1736         dissected_len += 2;
1737     }
1738     if (immutable_sched_pres)
1739     {
1740         char* info_msg = "Immutable Schedule entry list";
1741         proto_tree* sub_attr_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, attr_len - dissected_len,
1742             ett_ndl_schedule_entries, NULL, info_msg);
1743         while (dissected_len < attr_len)
1744         {
1745             proto_tree_add_item(sub_attr_tree, hf_nan_map_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1746             sub_offset++;
1747             proto_tree_add_bitmask(sub_attr_tree, tvb, sub_offset, hf_nan_time_bitmap_ctrl, ett_time_bitmap_ctrl,
1748                 time_bitmap_ctr_fields, ENC_LITTLE_ENDIAN);
1749             sub_offset += 2;
1750             guint field_length = tvb_get_guint8(tvb, sub_offset);
1751             proto_tree_add_item(sub_attr_tree, hf_nan_time_bitmap_len, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1752             sub_offset++;
1753             proto_tree_add_item(sub_attr_tree, hf_nan_time_bitmap, tvb, sub_offset, field_length, ENC_NA);
1754             sub_offset += field_length;
1755             dissected_len += field_length + 4;
1756         }
1757     }
1758 }
1759 
1760 static void
dissect_attr_ndl_qos(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1761 dissect_attr_ndl_qos(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1762 {
1763     if (attr_len != NAN_NDL_QOS_LENGTH)
1764     {
1765         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1766         return;
1767     }
1768 
1769     guint sub_offset = offset + 3;
1770     proto_tree_add_item(attr_tree, hf_nan_attr_ndlqos_min_time_slots, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1771     sub_offset++;
1772     proto_tree_add_item(attr_tree, hf_nan_attr_ndlqos_max_latency, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
1773 }
1774 
1775 static void
dissect_attr_unaligned_schedule(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1776 dissect_attr_unaligned_schedule(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1777 {
1778     if (attr_len < NAN_UNALIGNED_SCH_MIN_LENGTH)
1779     {
1780         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1781         return;
1782     }
1783 
1784     guint sub_offset = offset + 3;
1785     guint dissected_len = 0;
1786     static int* const control_fields[] = {
1787         &hf_nan_attr_unaligned_sch_ctrl_schedule_id,
1788         &hf_nan_attr_unaligned_sch_ctrl_seq_id,
1789         NULL
1790     };
1791 
1792     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_unaligned_sch_ctrl,
1793         ett_unaligned_sch_ctrl, control_fields, ENC_LITTLE_ENDIAN);
1794     sub_offset += 2;
1795     proto_tree_add_item(attr_tree, hf_nan_attr_unaligned_sch_starting_time, tvb, sub_offset, 4, ENC_LITTLE_ENDIAN);
1796     sub_offset += 4;
1797     proto_tree_add_item(attr_tree, hf_nan_attr_unaligned_sch_duration, tvb, sub_offset, 4, ENC_LITTLE_ENDIAN);
1798     sub_offset += 4;
1799     proto_tree_add_item(attr_tree, hf_nan_attr_unaligned_sch_period, tvb, sub_offset, 4, ENC_LITTLE_ENDIAN);
1800     sub_offset += 4;
1801     proto_tree_add_item(attr_tree, hf_nan_attr_unaligned_sch_count_down, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1802     sub_offset++;
1803 
1804     static int* const ulw_overwrite_fields[] = {
1805         &hf_nan_attr_unaligned_sch_ulw_overwrite_all,
1806         &hf_nan_attr_unaligned_sch_ulw_overwrite_map_id,
1807         NULL
1808     };
1809 
1810     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_unaligned_sch_ulw_overwrite,
1811         ett_unaligned_sch_ulw_overwrite, ulw_overwrite_fields, ENC_LITTLE_ENDIAN);
1812     sub_offset++;
1813     dissected_len += 16;
1814 
1815     // ULW Control and Band ID or Channel Entry present
1816     if (dissected_len < attr_len)
1817     {
1818         static int* const ulw_control_fields[] = {
1819             &hf_nan_attr_unaligned_sch_ulw_ctrl_type,
1820             &hf_nan_attr_unaligned_sch_ulw_ctrl_channel_av,
1821             &hf_nan_attr_unaligned_sch_ulw_ctrl_rxnss,
1822             NULL
1823         };
1824 
1825         proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_unaligned_sch_ulw_ctrl,
1826             ett_unaligned_sch_ulw_ctrl, ulw_control_fields, ENC_LITTLE_ENDIAN);
1827         guint8 entry_type = tvb_get_bits8(tvb, sub_offset * 8 + 6, 2);
1828         sub_offset++;
1829 
1830         switch (entry_type)
1831         {
1832         case NAN_UNALIGNED_SCH_BAND_ID_EXIST:
1833             proto_tree_add_item(attr_tree, hf_nan_attr_availability_entry_entries_band,
1834                 tvb, sub_offset, 1, ENC_LITTLE_ENDIAN);
1835             sub_offset++;
1836             break;
1837         case NAN_UNALIGNED_SCH_CHANNEL_ENTRY_EXIST:
1838         {
1839             proto_tree* channel_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 4,
1840                 ett_availability_entry_entries_channel, NULL, "Channel Entry");
1841             proto_tree_add_item(channel_tree, hf_nan_attr_availability_entry_entries_channel_op_class,
1842                 tvb, sub_offset, 1, ENC_LITTLE_ENDIAN);
1843             sub_offset++;
1844             proto_tree_add_item(channel_tree, hf_nan_attr_availability_entry_entries_channel_bitmap,
1845                 tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
1846             sub_offset += 2;
1847             proto_tree_add_item(channel_tree, hf_nan_attr_availability_entry_entries_primary_channel_bitmap,
1848                 tvb, sub_offset, 1, ENC_LITTLE_ENDIAN);
1849             break;
1850         }
1851         case NAN_UNALIGNED_SCH_CHANNEL_ENTRY_W_AUX_EXIST:
1852         {
1853             proto_tree* channel_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 4,
1854                 ett_availability_entry_entries_channel, NULL, "Channel Entry");
1855             proto_tree_add_item(channel_tree, hf_nan_attr_availability_entry_entries_channel_op_class,
1856                 tvb, sub_offset, 1, ENC_LITTLE_ENDIAN);
1857             sub_offset++;
1858             proto_tree_add_item(channel_tree, hf_nan_attr_availability_entry_entries_channel_bitmap,
1859                 tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
1860             sub_offset += 2;
1861             proto_tree_add_item(channel_tree, hf_nan_attr_availability_entry_entries_primary_channel_bitmap,
1862                 tvb, sub_offset, 1, ENC_LITTLE_ENDIAN);
1863             sub_offset++;
1864             proto_tree_add_item(channel_tree, hf_nan_attr_availability_entry_entries_aux_channel_bitmap,
1865                 tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
1866             break;
1867         }
1868         }
1869     }
1870 }
1871 
1872 static void
dissect_attr_ranging_info(proto_tree * attr_tree,tvbuff_t * tvb,gint offset)1873 dissect_attr_ranging_info(proto_tree* attr_tree, tvbuff_t* tvb, gint offset)
1874 {
1875     guint sub_offset = offset + 3;
1876     static int* const location_info_availability_fields[] = {
1877         &hf_nan_attr_ranging_info_location_info_avail_lci,
1878         &hf_nan_attr_ranging_info_location_info_avail_geospatial,
1879         &hf_nan_attr_ranging_info_location_info_avail_civic_location,
1880         &hf_nan_attr_ranging_info_location_info_avail_last_movement_pres,
1881         NULL
1882     };
1883 
1884     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_ranging_info_location_info_avail,
1885         ett_ranging_info_location_info_availability, location_info_availability_fields, ENC_LITTLE_ENDIAN);
1886     gboolean loc_exists = tvb_get_bits8(tvb, sub_offset * 8 + 4, 1);
1887     sub_offset++;
1888     if (loc_exists)
1889     {
1890         proto_tree_add_item(attr_tree, hf_nan_attr_ranging_info_last_movement_indication, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
1891     }
1892 }
1893 
1894 static void
dissect_attr_ranging_setup(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1895 dissect_attr_ranging_setup(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1896 {
1897     if (attr_len < NAN_RANGING_SETUP_MIN_LENGTH)
1898     {
1899         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
1900         return;
1901     }
1902 
1903     guint sub_offset = offset + 3;
1904     guint dissected_len = 0;
1905     proto_tree_add_item(attr_tree, hf_nan_dialog_tokens, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1906     sub_offset++;
1907 
1908     static int* const ranging_setup_type_status_fields[] = {
1909         &hf_nan_attr_ranging_setup_type,
1910         &hf_nan_status_2,
1911         NULL
1912     };
1913     static int* const ranging_setup_ctrl_fields[] = {
1914         &hf_nan_attr_ranging_setup_ctrl_report_req,
1915         &hf_nan_attr_ranging_setup_ctrl_ftm_params,
1916         &hf_nan_attr_ranging_setup_ctrl_entry_list,
1917         NULL
1918     };
1919 
1920     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_type_status,
1921         ett_type_status, ranging_setup_type_status_fields, ENC_LITTLE_ENDIAN);
1922     sub_offset++;
1923     proto_tree_add_item(attr_tree, hf_nan_reason_code, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1924     sub_offset++;
1925     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_ranging_setup_ctrl,
1926         ett_ranging_setup_ctrl, ranging_setup_ctrl_fields, ENC_LITTLE_ENDIAN);
1927     guint8 ftm_check = tvb_get_bits8(tvb, sub_offset * 8 + 6, 1);
1928     guint8 ranging_entry_check = tvb_get_bits8(tvb, sub_offset * 8 + 5, 1);
1929     sub_offset++;
1930     dissected_len += 4;
1931 
1932     if (ftm_check)
1933     {
1934         static int* const ranging_setup_ftm_param_fields[] = {
1935             &hf_nan_attr_ranging_setup_ftm_max_burst_duration,
1936             &hf_nan_attr_ranging_setup_ftm_min_delta,
1937             &hf_nan_attr_ranging_setup_ftm_max_per_burst,
1938             &hf_nan_attr_ranging_setup_ftm_format_bw,
1939             NULL
1940         };
1941 
1942         proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_ranging_setup_ftm_params,
1943             ett_ranging_setup_ftm_params, ranging_setup_ftm_param_fields, ENC_LITTLE_ENDIAN);
1944         sub_offset += 3;
1945         dissected_len += 3;
1946     }
1947     if (ranging_entry_check)
1948     {
1949         char* info_msg = "Ranging Schedule Entry List";
1950         proto_tree* sub_attr_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, attr_len - dissected_len,
1951             ett_ranging_setup_schedule_entries, NULL, info_msg);
1952 
1953         while (dissected_len < attr_len)
1954         {
1955             proto_tree_add_item(sub_attr_tree, hf_nan_map_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1956             sub_offset++;
1957             proto_tree_add_bitmask(sub_attr_tree, tvb, sub_offset, hf_nan_time_bitmap_ctrl, ett_time_bitmap_ctrl,
1958                 time_bitmap_ctr_fields, ENC_LITTLE_ENDIAN);
1959             sub_offset += 2;
1960             guint field_length = tvb_get_guint8(tvb, sub_offset);
1961             proto_tree_add_item(sub_attr_tree, hf_nan_time_bitmap_len, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
1962             sub_offset++;
1963             proto_tree_add_item(sub_attr_tree, hf_nan_time_bitmap, tvb, sub_offset, field_length, ENC_NA);
1964             sub_offset += field_length;
1965             dissected_len += field_length + 4;
1966         }
1967     }
1968 }
1969 
1970 static void
dissect_attr_ftm_report(proto_tree * attr_tree,tvbuff_t * tvb,gint offset)1971 dissect_attr_ftm_report(proto_tree* attr_tree, tvbuff_t* tvb, gint offset)
1972 {
1973     guint sub_offset = offset + 3;
1974     proto_tree_add_item(attr_tree, hf_nan_attr_ftm_range_report, tvb, sub_offset, -1, ENC_NA);
1975 }
1976 
1977 static void
dissect_attr_element_container(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)1978 dissect_attr_element_container(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
1979 {
1980     guint sub_offset = offset + 3;
1981 
1982     // Some header fields and trees are reused.
1983     static int* const container_map_id_fields[] = {
1984         &hf_nan_attr_device_cap_map_id_apply_to,
1985         &hf_nan_attr_device_cap_map_id_associated_maps,
1986         NULL
1987     };
1988     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_map_id,
1989         ett_device_cap_map_id, container_map_id_fields, ENC_LITTLE_ENDIAN);
1990     sub_offset += 1;
1991     guint dissected_length = 1;
1992     proto_tree* sub_tree;
1993     while (dissected_length < attr_len)
1994     {
1995         guint element_id = tvb_get_guint8(tvb, sub_offset);
1996         guint element_len = tvb_get_guint8(tvb, sub_offset + 1);
1997         const char* msg = val_to_str(element_id, ie_tag_num_vals, "Unknown element ID (%u)");
1998 
1999         sub_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, element_len + 2, ett_ie_tree, NULL, msg);
2000         proto_tree_add_item(sub_tree, hf_nan_attr_container_element_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2001         sub_offset++;
2002         proto_tree_add_item(sub_tree, hf_nan_attr_container_element_len, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2003         sub_offset++;
2004 
2005         ieee80211_tagged_field_data_t field_data = { 0 };
2006         tvbuff_t* ie_tvb = tvb_new_subset_length_caplen(tvb, sub_offset, element_len, element_len);
2007         field_data.item_tag = sub_tree;
2008         dissector_try_uint_new(ie_handle_table, element_id, ie_tvb, pinfo, sub_tree, TRUE, &field_data);
2009         sub_offset += element_len;
2010         dissected_length += element_len + 2;
2011     }
2012 }
2013 
2014 static void
dissect_attr_extended_wlan_infra(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2015 dissect_attr_extended_wlan_infra(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2016 {
2017     if (attr_len != NAN_EXTENDED_WLAN_INFRA_LENGTH)
2018     {
2019         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2020         return;
2021     }
2022 
2023     guint sub_offset = offset + 3;
2024     proto_tree_add_item(attr_tree, hf_nan_bss_id, tvb, sub_offset, 6, ENC_LITTLE_ENDIAN);
2025     sub_offset += 6;
2026     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
2027     sub_offset += 6;
2028     proto_tree_add_item(attr_tree, hf_nan_attr_wlan_infra_device_role, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2029     sub_offset += 1;
2030 
2031     char* info_msg = "Non-NAN Operating Channel Information";
2032     proto_tree* sub_attr_tree_op = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 3,
2033         ett_non_nan_op_channel, NULL, info_msg);
2034     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_global_op_class, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2035     sub_offset++;
2036     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_channel, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2037     sub_offset++;
2038     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_center_freq, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2039     sub_offset++;
2040 
2041     char* info_msg_beacon = "Non-NAN Beacon Information";
2042     proto_tree* sub_attr_tree_beacon = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 4,
2043         ett_non_nan_beacon, NULL, info_msg_beacon);
2044     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_tbtt_offset, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2045     sub_offset += 2;
2046     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_interval, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2047     // sub_offset += 2;
2048 }
2049 
2050 static void
dissect_attr_extended_p2p_operation(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2051 dissect_attr_extended_p2p_operation(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2052 {
2053     if (attr_len != NAN_EXTENDED_P2P_OP_LENGTH)
2054     {
2055         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2056         return;
2057     }
2058 
2059     guint sub_offset = offset + 3;
2060     static int* const ext_p2p_bitmap_fields[] = {
2061         &hf_nan_attr_p2p_device_role_device,
2062         &hf_nan_attr_p2p_device_role_group_owner,
2063         &hf_nan_attr_p2p_device_role_client,
2064         NULL
2065     };
2066 
2067     proto_tree_add_bitmask(attr_tree, tvb, sub_offset, hf_nan_attr_p2p_device_role,
2068         ett_p2p_device_role, ext_p2p_bitmap_fields, ENC_LITTLE_ENDIAN);
2069     sub_offset += 1;
2070     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
2071     sub_offset += 6;
2072 
2073     char* info_msg = "Non-NAN Operating Channel Information";
2074     proto_tree* sub_attr_tree_op = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 3,
2075         ett_non_nan_op_channel, NULL, info_msg);
2076     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_global_op_class, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2077     sub_offset++;
2078     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_channel, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2079     sub_offset++;
2080     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_center_freq, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2081     sub_offset++;
2082 
2083     char* info_msg_beacon = "Non-NAN Beacon Information";
2084     proto_tree* sub_attr_tree_beacon = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 4,
2085         ett_non_nan_beacon, NULL, info_msg_beacon);
2086     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_tbtt_offset, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2087     sub_offset += 2;
2088     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_interval, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2089     // sub_offset += 2;
2090 }
2091 
2092 static void
dissect_attr_extended_ibss(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2093 dissect_attr_extended_ibss(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2094 {
2095     if (attr_len != NAN_EXTENDED_IBSS_LENGTH)
2096     {
2097         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2098         return;
2099     }
2100 
2101     guint sub_offset = offset + 3;
2102     proto_tree_add_item(attr_tree, hf_nan_bss_id, tvb, sub_offset, 6, ENC_LITTLE_ENDIAN);
2103     sub_offset += 6;
2104     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
2105     sub_offset += 6;
2106 
2107     char* info_msg = "Non-NAN Operating Channel Information";
2108     proto_tree* sub_attr_tree_op = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 3,
2109         ett_non_nan_op_channel, NULL, info_msg);
2110     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_global_op_class, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2111     sub_offset++;
2112     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_channel, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2113     sub_offset++;
2114     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_center_freq, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2115     sub_offset++;
2116 
2117     char* info_msg_beacon = "Non-NAN Beacon Information";
2118     proto_tree* sub_attr_tree_beacon = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 4,
2119         ett_non_nan_beacon, NULL, info_msg_beacon);
2120     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_tbtt_offset, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2121     sub_offset += 2;
2122     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_interval, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2123     // sub_offset += 2;
2124 }
2125 
2126 static void
dissect_attr_extended_mesh(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2127 dissect_attr_extended_mesh(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2128 {
2129     if (attr_len < NAN_EXTENDED_MESH_MIN_LENGTH)
2130     {
2131         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2132         return;
2133     }
2134 
2135     guint sub_offset = offset + 3;
2136     guint length = tvb_get_guint16(tvb, sub_offset - 2, ENC_LITTLE_ENDIAN);
2137     proto_tree_add_item(attr_tree, hf_nan_mac_address, tvb, sub_offset, 6, ENC_NA);
2138     sub_offset += 6;
2139 
2140     char* info_msg = "Non-NAN Operating Channel Information";
2141     proto_tree* sub_attr_tree_op = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 3,
2142         ett_non_nan_op_channel, NULL, info_msg);
2143     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_global_op_class, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2144     sub_offset++;
2145     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_channel, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2146     sub_offset++;
2147     proto_tree_add_item(sub_attr_tree_op, hf_nan_non_op_channel_center_freq, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2148     sub_offset++;
2149 
2150     char* info_msg_beacon = "Non-NAN Beacon Information";
2151     proto_tree* sub_attr_tree_beacon = proto_tree_add_subtree(attr_tree, tvb, sub_offset, 4,
2152         ett_non_nan_beacon, NULL, info_msg_beacon);
2153     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_tbtt_offset, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2154     sub_offset += 2;
2155     proto_tree_add_item(sub_attr_tree_beacon, hf_nan_non_beacon_interval, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2156     sub_offset += 2;
2157 
2158     proto_tree_add_item(attr_tree, hf_nan_attr_mesh_id, tvb, sub_offset, length - sub_offset + 3, ENC_NA);
2159 }
2160 
2161 static void
dissect_attr_cipher_suite_info(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2162 dissect_attr_cipher_suite_info(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2163 {
2164     if (attr_len < NAN_CIPHER_SUITE_INFO_MIN_LENGTH)
2165     {
2166         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2167         return;
2168     }
2169 
2170     guint sub_offset = offset + 3;
2171     guint dissected_len = 0;
2172     proto_tree_add_item(attr_tree, hf_nan_attr_cipher_suite_capabilities, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2173     sub_offset++;
2174     dissected_len++;
2175 
2176     char* info_msg = "Cipher Suite List";
2177     proto_tree* sub_attr_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, attr_len - dissected_len,
2178         ett_cipher_suite_info_list, NULL, info_msg);
2179 
2180     while (dissected_len < attr_len)
2181     {
2182         proto_tree_add_item(sub_attr_tree, hf_nan_attr_cipher_suite_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2183         sub_offset++;
2184         proto_tree_add_item(sub_attr_tree, hf_nan_publish_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2185         sub_offset++;
2186         dissected_len += 2;
2187     }
2188 }
2189 
2190 static void
dissect_attr_security_context_info(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2191 dissect_attr_security_context_info(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2192 {
2193     if (attr_len < NAN_CIPHER_SUITE_INFO_MIN_LENGTH)
2194     {
2195         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2196         return;
2197     }
2198 
2199     guint sub_offset = offset + 3;
2200     guint dissected_len = 0;
2201 
2202     while (dissected_len < attr_len)
2203     {
2204         guint field_length = tvb_get_guint16(tvb, sub_offset, ENC_LITTLE_ENDIAN);
2205         proto_item* sub_attr_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, field_length + 4,
2206             ett_attributes, NULL, "Security Context Identifier");
2207         proto_tree_add_item(sub_attr_tree, hf_nan_attr_security_context_identifier_len, tvb, sub_offset, 2, ENC_LITTLE_ENDIAN);
2208         sub_offset += 2;
2209         proto_tree_add_item(sub_attr_tree, hf_nan_attr_security_context_identifier_type, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2210         sub_offset++;
2211         proto_tree_add_item(sub_attr_tree, hf_nan_publish_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2212         sub_offset++;
2213         proto_tree_add_item(sub_attr_tree, hf_nan_attr_security_context_identifier, tvb, sub_offset, field_length, ENC_NA);
2214         sub_offset += field_length;
2215         dissected_len += field_length + 4;
2216     }
2217 }
2218 
2219 static void
dissect_attr_shared_key_descriptor(proto_tree * attr_tree,tvbuff_t * tvb,gint offset)2220 dissect_attr_shared_key_descriptor(proto_tree* attr_tree, tvbuff_t* tvb, gint offset)
2221 {
2222     guint sub_offset = offset + 3;
2223     proto_tree_add_item(attr_tree, hf_nan_publish_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2224     sub_offset += 1;
2225     proto_tree_add_item(attr_tree, hf_nan_attr_shared_key_rsna_descriptor, tvb, sub_offset, -1, ENC_NA);
2226 }
2227 
2228 static void
dissect_attr_public_availability(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2229 dissect_attr_public_availability(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2230 {
2231     if (attr_len < NAN_PUBLIC_AVAIL_MIN_LENGTH)
2232     {
2233         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2234         return;
2235     }
2236 
2237     guint sub_offset = offset + 3;
2238     guint dissected_len = 0;
2239 
2240     proto_tree* sub_attr_tree = proto_tree_add_subtree(attr_tree, tvb, sub_offset, attr_len,
2241         ett_public_availability_sch_entries, NULL, "Public Availability Schedule Entry List");
2242     while (dissected_len < attr_len)
2243     {
2244         proto_tree_add_item(sub_attr_tree, hf_nan_map_id, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2245         sub_offset++;
2246         proto_tree_add_bitmask(sub_attr_tree, tvb, sub_offset, hf_nan_time_bitmap_ctrl, ett_time_bitmap_ctrl,
2247             time_bitmap_ctr_fields, ENC_LITTLE_ENDIAN);
2248         sub_offset += 2;
2249         guint field_length = tvb_get_guint8(tvb, sub_offset);
2250         proto_tree_add_item(sub_attr_tree, hf_nan_time_bitmap_len, tvb, sub_offset, 1, ENC_BIG_ENDIAN);
2251         sub_offset++;
2252         proto_tree_add_item(sub_attr_tree, hf_nan_time_bitmap, tvb, sub_offset, field_length, ENC_NA);
2253         sub_offset += field_length;
2254         dissected_len += field_length + 4;
2255     }
2256 }
2257 
2258 static void
dissect_attr_vendor_specific(proto_tree * attr_tree,tvbuff_t * tvb,gint offset,guint16 attr_len,packet_info * pinfo)2259 dissect_attr_vendor_specific(proto_tree* attr_tree, tvbuff_t* tvb, gint offset, guint16 attr_len, packet_info* pinfo)
2260 {
2261     if (attr_len < NAN_VENDOR_SPECIFIC_MIN_LENGTH)
2262     {
2263         expert_add_info(pinfo, attr_tree, &ei_nan_elem_len_invalid);
2264         return;
2265     }
2266 
2267     guint sub_offset = offset + 3;
2268     tvbuff_t* ie_tvb = tvb_new_subset_length_caplen(tvb, sub_offset, -1, -1);
2269     ieee80211_tagged_field_data_t field_data = { 0 };
2270     field_data.item_tag = attr_tree;
2271     dissector_try_uint_new(ie_handle_table, TAG_VENDOR_SPECIFIC_IE, ie_tvb, pinfo, attr_tree, TRUE, &field_data);
2272 }
2273 
2274 static void
find_attribute_field(proto_tree * nan_tree,tvbuff_t * tvb,guint tvb_len,guint * offset,packet_info * pinfo)2275 find_attribute_field(proto_tree* nan_tree, tvbuff_t* tvb, guint tvb_len, guint* offset, packet_info* pinfo)
2276 {
2277     if ((tvb_len - *offset) < 3)
2278     {
2279         proto_tree_add_expert_format(nan_tree, pinfo, &ei_nan_elem_len_invalid, tvb, *offset, -1,
2280             "Insufficient remaining packet bytes for NAN attribute");
2281         *offset = tvb_len;
2282         return;
2283     }
2284 
2285     gint attr_id = tvb_get_guint8(tvb, *offset);
2286     guint16 attr_len = tvb_get_letohs(tvb, *offset + 1);
2287 
2288     if ((*offset + 3 + attr_len) > tvb_len)
2289     {
2290         proto_tree_add_expert_format(nan_tree, pinfo, &ei_nan_elem_len_invalid, tvb, *offset, -1,
2291             "Attribute length (%u) exceeds remaining packet length. Attribute id: %u", attr_len, attr_id);
2292         *offset = tvb_len;
2293         return;
2294     }
2295 
2296     proto_tree* attr_tree = proto_tree_add_subtree(nan_tree, tvb, *offset, attr_len + 3,
2297         ett_attributes, NULL, val_to_str(attr_id, attribute_types, "Unknown attribute ID (%u)"));
2298 
2299     proto_tree_add_item(attr_tree, hf_nan_attribute_type, tvb, *offset, 1, ENC_NA);
2300     proto_tree_add_item(attr_tree, hf_nan_attribute_len, tvb, *offset + 1, 2, ENC_LITTLE_ENDIAN);
2301 
2302     switch (attr_id) {
2303     case NAN_ATTR_SERVICE_DESCRIPTOR:
2304         dissect_attr_sda(attr_tree, tvb, *offset, attr_len, pinfo);
2305         break;
2306     case NAN_ATTR_MASTER_INDICATION:
2307         dissect_attr_master_indication(attr_tree, tvb, *offset, attr_len, pinfo);
2308         break;
2309     case NAN_ATTR_CLUSTER:
2310         dissect_attr_cluster(attr_tree, tvb, *offset, attr_len, pinfo);
2311         break;
2312     case NAN_ATTR_CIPHER_SUITE_INFO:
2313         dissect_attr_cipher_suite_info(attr_tree, tvb, *offset, attr_len, pinfo);
2314         break;
2315     case NAN_ATTR_SECURITY_CONTEXT_INFO:
2316         dissect_attr_security_context_info(attr_tree, tvb, *offset, attr_len, pinfo);
2317         break;
2318     case NAN_ATTR_SHARED_KEY_DESCRIPTOR:
2319         dissect_attr_shared_key_descriptor(attr_tree, tvb, *offset);
2320         break;
2321     case NAN_ATTR_PUBLIC_AVAILABILITY:
2322         dissect_attr_public_availability(attr_tree, tvb, *offset, attr_len, pinfo);
2323         break;
2324     case NAN_ATTR_ELEMENT_CONTAINER:
2325         dissect_attr_element_container(attr_tree, tvb, *offset, attr_len, pinfo);
2326         break;
2327     case NAN_ATTR_FTM_RANGING_REPORT:
2328         dissect_attr_ftm_report(attr_tree, tvb, *offset);
2329         break;
2330     case NAN_ATTR_RANGING_SETUP:
2331         dissect_attr_ranging_setup(attr_tree, tvb, *offset, attr_len, pinfo);
2332         break;
2333     case NAN_ATTR_RANGING_INFORMATION:
2334         dissect_attr_ranging_info(attr_tree, tvb, *offset);
2335         break;
2336     case NAN_ATTR_UNALIGNED_SCHEDULE:
2337         dissect_attr_unaligned_schedule(attr_tree, tvb, *offset, attr_len, pinfo);
2338         break;
2339     case NAN_ATTR_NDL_QOS:
2340         dissect_attr_ndl_qos(attr_tree, tvb, *offset, attr_len, pinfo);
2341         break;
2342     case NAN_ATTR_EXTENDED_WLAN_INFRA:
2343         dissect_attr_extended_wlan_infra(attr_tree, tvb, *offset, attr_len, pinfo);
2344         break;
2345     case NAN_ATTR_EXTENDED_P2P_OPERATION:
2346         dissect_attr_extended_p2p_operation(attr_tree, tvb, *offset, attr_len, pinfo);
2347         break;
2348     case NAN_ATTR_EXTENDED_IBSS:
2349         dissect_attr_extended_ibss(attr_tree, tvb, *offset, attr_len, pinfo);
2350         break;
2351     case NAN_ATTR_EXTENDED_MESH:
2352         dissect_attr_extended_mesh(attr_tree, tvb, *offset, attr_len, pinfo);
2353         break;
2354     case NAN_ATTR_CONNECTION_CAPABILITY:
2355         dissect_attr_connection_capability(attr_tree, tvb, *offset, attr_len, pinfo);
2356         break;
2357     case NAN_ATTR_CLUSTER_DISCOVERY:
2358         dissect_attr_cluter_discovery(attr_tree, tvb, *offset, attr_len, pinfo);
2359         break;
2360     case NAN_ATTR_RANGING:
2361         dissect_attr_ranging(attr_tree, tvb, *offset, attr_len, pinfo);
2362         break;
2363     case NAN_ATTR_COUNTRY_CODE:
2364         dissect_attr_country_code(attr_tree, tvb, *offset);
2365         break;
2366     case NAN_ATTR_FURTHER_AVAILABILITY_MAP:
2367         dissect_attr_further_availability_map(attr_tree, tvb, *offset);
2368         break;
2369     case NAN_ATTR_FURTHER_SERVICE_DISCOVERY:
2370         dissect_attr_further_service_discovery(attr_tree, tvb, *offset, attr_len);
2371         break;
2372     case NAN_ATTR_MESH:
2373         dissect_attr_mesh(attr_tree, tvb, *offset, attr_len, pinfo);
2374         break;
2375     case NAN_ATTR_IBSS:
2376         dissect_attr_ibss(attr_tree, tvb, *offset, attr_len, pinfo);
2377         break;
2378     case NAN_ATTR_P2P_OPERATION:
2379         dissect_attr_p2p_operation(attr_tree, tvb, *offset, attr_len, pinfo);
2380         break;
2381     case NAN_ATTR_WLAN_INFRA:
2382         dissect_attr_wlan_infra(attr_tree, tvb, *offset, attr_len, pinfo);
2383         break;
2384     case NAN_ATTR_NDP:
2385         dissect_attr_ndp(attr_tree, tvb, *offset, attr_len, pinfo);
2386         break;
2387     case NAN_ATTR_NDP_EXTENSION:
2388         dissect_attr_ndpe(attr_tree, tvb, *offset, attr_len, pinfo);
2389         break;
2390     case NAN_ATTR_SERVICE_DESCRIPTOR_EXTENSION:
2391         dissect_attr_sdea(attr_tree, tvb, *offset, attr_len, pinfo);
2392         break;
2393     case NAN_ATTR_DEVICE_CAPABILITY:
2394         dissect_attr_device_capability(attr_tree, tvb, *offset, attr_len, pinfo);
2395         break;
2396     case NAN_ATTR_AVAILABILITY:
2397         dissect_attr_availability(attr_tree, tvb, *offset, attr_len, pinfo);
2398         break;
2399     case NAN_ATTR_NDC:
2400         dissect_attr_ndc(attr_tree, tvb, *offset, attr_len, pinfo);
2401         break;
2402     case NAN_ATTR_SERVICE_ID_LIST:
2403     case NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST:
2404         dissect_attr_service_id_list(attr_tree, tvb, *offset, attr_len, pinfo);
2405         break;
2406     case NAN_ATTR_VENDOR_SPECIFIC:
2407         dissect_attr_vendor_specific(attr_tree, tvb, *offset, attr_len, pinfo);
2408         break;
2409     case NAN_ATTR_NDL:
2410         dissect_attr_ndl(attr_tree, tvb, *offset, attr_len, pinfo);
2411         break;
2412     default:
2413         expert_add_info(pinfo, attr_tree, &ei_nan_unknown_attr_id);
2414     }
2415 
2416     *offset += attr_len + 3;
2417 }
2418 
2419 static int
dissect_nan_beacon(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2420 dissect_nan_beacon(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
2421 {
2422     guint offset = 0;
2423 
2424     col_set_str(pinfo->cinfo, COL_PROTOCOL, "NAN");
2425 
2426     //
2427     // Workaround to identify NAN Discovery vs Synchronization beacon frames.
2428     //
2429     // We have to determine the beacon interval, but there is, unfortunately,
2430     // no mechanism by which a subdissector can request that an arbitrary
2431     // field value be provided to it by the calling dissector, so we can't
2432     // just ask for "wlan.fixed.beacon".
2433     //
2434     // Fortunaely, we are currently putting the Discovery vs. Sync information
2435     // only in the Info column, and the beacon interval is put at the end
2436     // of the Info column, as "BI={interval}", by the 802.11 dissector, so
2437     // we can just fetch the Info column string and, if it's present, extract
2438     // that value.
2439     //
2440     // An interval of 100, meaning .1024 seconds, means it's a Discovery
2441     // beacon, and an interval of 512, meaning .524288 seconds, means
2442     // it's a Sync beacon.
2443     //
2444     const gchar* info_text = col_get_text(pinfo->cinfo, COL_INFO);
2445     if (info_text != NULL && g_str_has_suffix(info_text, "100"))
2446     {
2447         col_prepend_fstr(pinfo->cinfo, COL_INFO, "Discovery ");
2448     }
2449     else if (info_text != NULL && g_str_has_suffix(info_text, "512"))
2450     {
2451         col_prepend_fstr(pinfo->cinfo, COL_INFO, "Sync ");
2452     }
2453     else
2454     {
2455         expert_add_info(pinfo, tree, &ei_nan_unknown_beacon_type);
2456         col_prepend_fstr(pinfo->cinfo, COL_INFO, "[Unknown] ");
2457     }
2458 
2459     proto_item* ti = proto_tree_add_item(tree, proto_nan, tvb, 0, -1, ENC_NA);
2460     proto_tree* nan_tree = proto_item_add_subtree(ti, ett_nan);
2461 
2462     guint tvb_len = tvb_reported_length(tvb);
2463     while (offset < tvb_len)
2464     {
2465         find_attribute_field(nan_tree, tvb, tvb_len, &offset, pinfo);
2466     }
2467     return tvb_captured_length(tvb);
2468 }
2469 
2470 static int
dissect_nan_action(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2471 dissect_nan_action(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
2472 {
2473     guint offset = 0;
2474 
2475     col_set_str(pinfo->cinfo, COL_PROTOCOL, "NAN");
2476 
2477     proto_tree* upper_tree = proto_tree_get_parent_tree(tree);
2478     proto_item* ti = proto_tree_add_item(upper_tree, proto_nan, tvb, 0, -1, ENC_NA);
2479     proto_tree* nan_tree = proto_item_add_subtree(ti, ett_nan);
2480 
2481     guint8 subtype = tvb_get_guint8(tvb, offset);
2482     const gchar* subtype_text = rval_to_str(subtype, action_frame_type_values, "Unknown type (%u)");
2483     proto_item_set_text(ti, "%s", subtype_text);
2484     proto_tree_add_item(nan_tree, hf_nan_action_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
2485 
2486     col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s", subtype_text);
2487     offset++;
2488 
2489     guint tvb_len = tvb_reported_length(tvb);
2490     while (offset < tvb_len)
2491     {
2492         find_attribute_field(nan_tree, tvb, tvb_len, &offset, pinfo);
2493     }
2494     return tvb_captured_length(tvb);
2495 }
2496 
2497 static int
dissect_nan_service_discovery(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2498 dissect_nan_service_discovery(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
2499 {
2500     guint offset = 0;
2501     col_set_str(pinfo->cinfo, COL_PROTOCOL, "NAN");
2502     proto_item* ti = proto_tree_add_item(tree, proto_nan, tvb, 0, -1, ENC_NA);
2503     proto_tree* nan_tree = proto_item_add_subtree(ti, ett_nan);
2504 
2505     guint tvb_len = tvb_reported_length(tvb);
2506     while (offset < tvb_len)
2507     {
2508         find_attribute_field(nan_tree, tvb, tvb_len, &offset, pinfo);
2509     }
2510     return tvb_captured_length(tvb);
2511 }
2512 
2513 void
proto_register_nan(void)2514 proto_register_nan(void)
2515 {
2516     static hf_register_info hf[] = {
2517         { &hf_nan_attribute_type,
2518             {
2519             "Attribute Type",
2520             "nan.attribute.type",
2521             FT_UINT8, BASE_DEC, VALS(attribute_types), 0x0, NULL, HFILL
2522             }
2523         },
2524         { &hf_nan_attribute_len,
2525             {
2526             "Attribute Length",
2527             "nan.attribute.len",
2528             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2529             }
2530         },
2531         { &hf_nan_action_subtype,
2532             {
2533             "Subtype",
2534             "nan.action.subtype",
2535             FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(action_frame_type_values), 0x0, NULL, HFILL
2536             }
2537         },
2538         { &hf_nan_instance_id,
2539             {
2540             "Instance ID",
2541             "nan.instance_id",
2542             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
2543             }
2544         },
2545         { &hf_nan_service_id,
2546             {
2547             "Service ID",
2548             "nan.service_id",
2549             FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL
2550             }
2551         },
2552         { &hf_nan_map_id,
2553             {
2554             "Map ID",
2555             "nan.map_id",
2556             FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
2557             }
2558         },
2559         { &hf_nan_oui,
2560             {
2561             "OUI",
2562             "nan.oui",
2563             FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL
2564             }
2565         },
2566         { &hf_nan_type_status,
2567             {
2568             "Type and Status",
2569             "nan.type_status",
2570             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2571             }
2572         },
2573         { &hf_nan_reason_code,
2574             {
2575             "Reason Code",
2576             "nan.reason_code",
2577             FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(reason_code_values), 0x0, NULL, HFILL
2578             }
2579         },
2580         { &hf_nan_status_1,
2581              {
2582              "Status",
2583              "nan.status",
2584              FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(status_type1_values), 0xF0, NULL, HFILL
2585              }
2586         },
2587         { &hf_nan_status_2,
2588              {
2589              "Status",
2590              "nan.status",
2591              FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(status_type2_values), 0xF0, NULL, HFILL
2592              }
2593         },
2594         { &hf_nan_bss_id,
2595             {
2596             "BSS ID",
2597             "nan.bss_id",
2598             FT_UINT48, BASE_DEC, NULL, 0x0, NULL, HFILL
2599             }
2600         },
2601         { &hf_nan_availability_intervals_bitmap,
2602              {
2603              "Availability Intervals Bitmap",
2604              "nan.availability_intervals_bitmap",
2605              FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
2606              }
2607         },
2608         { &hf_nan_mac_address,
2609             {
2610             "MAC Address",
2611             "nan.mac_address",
2612             FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL
2613             }
2614         },
2615         { &hf_nan_publish_id,
2616             {
2617             "Publish ID",
2618             "nan.publish_id",
2619             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2620             }
2621         },
2622         { &hf_nan_dialog_tokens,
2623             {
2624             "Dialog Token",
2625             "nan.dialog_token",
2626             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2627             }
2628         },
2629         { &hf_nan_time_bitmap,
2630             {
2631             "Time Bitmap",
2632             "nan.time_bitmap",
2633             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
2634             }
2635         },
2636         { &hf_nan_time_bitmap_len,
2637             {
2638             "Time Bitmap Length",
2639             "nan.time_bitmap.len",
2640             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2641             }
2642         },
2643         { &hf_nan_time_bitmap_ctrl,
2644             {
2645             "Time Bitmap Control",
2646             "nan.time_bitmap.ctrl",
2647             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
2648             }
2649         },
2650         { &hf_nan_time_bitmap_ctrl_bit_duration,
2651             {
2652             "Bit Duration",
2653             "nan.time_bitmap.ctrl.bit_duration",
2654             FT_UINT16, BASE_DEC | BASE_RANGE_STRING, RVALS(availability_entry_time_bitmap_ctr_bit_duration_type),
2655             0x0007, NULL, HFILL
2656             }
2657         },
2658         { &hf_nan_time_bitmap_ctrl_period,
2659             {
2660             "Period",
2661             "nan.time_bitmap.ctrl.period",
2662             FT_UINT16, BASE_DEC, VALS(availability_entry_time_bitmap_ctr_period_type),
2663             0x0038, NULL, HFILL
2664             }
2665         },
2666         { &hf_nan_time_bitmap_ctrl_start_offset,
2667             {
2668             "Start Offset",
2669             "nan.time_bitmap.ctrl.start_offset",
2670             FT_UINT16, BASE_DEC, NULL, 0x7FC0, NULL, HFILL
2671             }
2672         },
2673         { &hf_nan_map_ctrl_map_id,
2674              {
2675              "Map ID",
2676              "nan.map_ctrl.map_id",
2677              FT_UINT8, BASE_HEX_DEC, NULL, 0xF, NULL, HFILL
2678              }
2679         },
2680         { &hf_nan_map_ctrl_availability_interval_duration,
2681              {
2682              "Availability Interval Duration",
2683              "nan.map_ctrl.interval_duration",
2684              FT_UINT8, BASE_DEC, VALS(map_ctrl_availability_interval_duration), 0x30, NULL, HFILL
2685              }
2686         },
2687         { &hf_nan_map_ctrl_repeat,
2688              {
2689              "Repeat",
2690              "nan.map_ctrl.repeat",
2691              FT_UINT8, BASE_DEC, NULL, 0x40, NULL, HFILL
2692              }
2693         },
2694         { &hf_nan_map_ctrl_field,
2695              {
2696              "Map Control",
2697              "nan.map_ctrl",
2698              FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2699              }
2700         },
2701         { &hf_nan_non_op_channel_global_op_class,
2702             {
2703             "Global Operation Class",
2704             "nan.non_op_channel.global_op_class",
2705             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2706             }
2707         },
2708         { &hf_nan_non_op_channel_channel,
2709             {
2710             "Channel",
2711             "nan.non_op_channel.channel",
2712             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2713             }
2714         },
2715         { &hf_nan_non_op_channel_center_freq,
2716             {
2717             "Channel Center Frequency",
2718             "nan.non_op_channel.center_freq",
2719             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2720             }
2721         },
2722         { &hf_nan_non_beacon_tbtt_offset,
2723             {
2724             "TBTT Offset",
2725             "nan.non_beacon.tbtt_offset",
2726             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2727             }
2728         },
2729         { &hf_nan_non_beacon_interval,
2730             {
2731             "Beacon Interval",
2732             "nan.non_beacon.interval",
2733             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2734             }
2735         },
2736         { &hf_nan_attr_master_preference,
2737             {
2738             "Master Preference",
2739             "nan.master_indication.preference",
2740             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
2741             }
2742         },
2743         { &hf_nan_attr_master_random_factor,
2744             {
2745             "Random Factor",
2746             "nan.master_indication.random_factor",
2747             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2748             }
2749         },
2750         { &hf_nan_attr_cluster_anchor_master_rank,
2751             {
2752             "Anchor Master Rank",
2753             "nan.cluster.anchor_master_rank",
2754             FT_UINT64, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL
2755             }
2756         },
2757         { &hf_nan_attr_cluster_hop_count,
2758             {
2759             "Hop Count to Anchor Master",
2760             "nan.cluster.hop_count",
2761             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2762             }
2763         },
2764         { &hf_nan_attr_cluster_beacon_transmission_time,
2765             {
2766             "Anchor Master Beacon Transmission Time",
2767             "nan.cluster.beacon_transmission_time",
2768             FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
2769             }
2770         },
2771         { &hf_nan_attr_sda_requestor_instance_id,
2772             {
2773             "Requestor Instance ID",
2774             "nan.sda.requestor_instance_id",
2775             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
2776             }
2777         },
2778         { &hf_nan_attr_sda_sc,
2779             {
2780             "Service Control",
2781             "nan.sda.sc",
2782             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
2783             }
2784         },
2785         { &hf_nan_attr_sda_sc_type,
2786             {
2787             "Service Control Type",
2788             "nan.sda.sc.type",
2789             FT_UINT8, BASE_HEX, VALS(service_ctr_type), 0x03, NULL, HFILL
2790             }
2791         },
2792         { &hf_nan_attr_sda_sc_matching_filter,
2793             {
2794             "Matching Filter Present",
2795             "nan.sda.sc.matching_filter",
2796             FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL
2797             }
2798         },
2799         { &hf_nan_attr_sda_sc_service_response,
2800             {
2801             "Service Response Filter Present",
2802             "nan.sda.sc.service_response",
2803             FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL
2804             }
2805         },
2806         { &hf_nan_attr_sda_sc_service_info,
2807             {
2808             "Service Info Present",
2809             "nan.sda.sc.service_info",
2810             FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL
2811             }
2812         },
2813         { &hf_nan_attr_sda_sc_discovery_range,
2814             {
2815             "Discovery Range Limited",
2816             "nan.sda.sc.discovery_range",
2817             FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL
2818             }
2819         },
2820         { &hf_nan_attr_sda_sc_binding_bitmap,
2821             {
2822             "Binding Bitmap Present",
2823             "nan.sda.sc.binding_bitmap",
2824             FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL
2825             }
2826         },
2827         { &hf_nan_attr_sda_binding_bitmap,
2828             {
2829             "Binding Bitmap",
2830             "nan.sda.binding_bitmap",
2831             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
2832             }
2833         },
2834         { &hf_nan_attr_sda_matching_filter_len,
2835             {
2836             "Matching Filter Length",
2837             "nan.sda.matching_filter_len",
2838             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2839             }
2840         },
2841         { &hf_nan_attr_sda_matching_filter_val,
2842             {
2843             "Matching Filter Value",
2844             "nan.sda.matching_filter_val",
2845             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
2846             }
2847         },
2848         { &hf_nan_attr_sda_service_response_filter_len,
2849             {
2850             "Service Response Filter Length",
2851             "nan.sda.service_response_filter_len",
2852             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2853             }
2854         },
2855         { &hf_nan_attr_sda_srf_ctr,
2856             {
2857             "SRF Control",
2858             "nan.sda.srf_ctr",
2859             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
2860             }
2861         },
2862         { &hf_nan_attr_sda_srf_ctr_type,
2863             {
2864             "SRF Type",
2865             "nan.sda.srf_type",
2866             FT_BOOLEAN, 8, TFS(&srf_type_flags), 0x01, NULL, HFILL
2867             }
2868         },
2869         { &hf_nan_attr_sda_srf_ctr_include,
2870             {
2871             "Include",
2872             "nan.sda.srf_include",
2873             FT_BOOLEAN, 8, TFS(&srf_include_flags), 0x02, NULL, HFILL
2874             }
2875         },
2876         { &hf_nan_attr_sda_srf_ctr_bloom_filter_index,
2877             {
2878             "Bloom Filter Index",
2879             "nan.sda.srf_bloom_filter_index",
2880             FT_UINT8, BASE_DEC_HEX, NULL, 0x0C, NULL, HFILL
2881             }
2882         },
2883         { &hf_nan_attr_sda_srf_address_set,
2884             {
2885             "Address Set",
2886             "nan.sda.srf_address_set",
2887             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
2888             }
2889         },
2890         { &hf_nan_attr_sda_service_info_len,
2891             {
2892             "Service Info Length",
2893             "nan.sda.service_info_len",
2894             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2895             }
2896         },
2897         { &hf_nan_attr_sda_service_info,
2898             {
2899             "Service Info",
2900             "nan.sda.service_info",
2901             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
2902             }
2903         },
2904         { &hf_nan_attr_sdea_ctr,
2905             {
2906             "SDEA Control",
2907             "nan.sdea.ctr",
2908             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
2909             }
2910         },
2911         { &hf_nan_attr_sdea_ctr_fsd,
2912             {
2913             "FSD Required",
2914             "nan.sdea.ctr_fsd",
2915             FT_BOOLEAN, 16, NULL, 0x001, NULL, HFILL
2916             }
2917         },
2918         { &hf_nan_attr_sdea_ctr_fsd_w_gas,
2919             {
2920             "FSD with GAS",
2921             "nan.sdea.ctr_fsd_w_gas",
2922             FT_BOOLEAN, 16, NULL, 0x002, NULL, HFILL
2923             }
2924         },
2925         { &hf_nan_attr_sdea_ctr_data_path,
2926             {
2927             "Data Path Required",
2928             "nan.sdea.ctr_data_path",
2929             FT_BOOLEAN, 16, NULL, 0x004, NULL, HFILL
2930             }
2931         },
2932         { &hf_nan_attr_sdea_ctr_data_path_type,
2933             {
2934             "Data Path Type",
2935             "nan.sdea.ctr_data_path_type",
2936             FT_BOOLEAN, 16, TFS(&sdea_ctr_data_path_type_flags), 0x008, NULL, HFILL
2937             }
2938         },
2939         { &hf_nan_attr_sdea_ctr_reserved_multicast_type,
2940             {
2941             "Reserved (Multicast Type)",
2942             "nan.sdea.ctr_reserved_multicast_type",
2943             FT_BOOLEAN, 16, TFS(&sdea_ctr_reserved_multicast_type_flags), 0x010, NULL, HFILL
2944             }
2945         },
2946         { &hf_nan_attr_sdea_ctr_qos,
2947             {
2948             "QoS Required",
2949             "nan.sdea.ctr_qos",
2950             FT_BOOLEAN, 16, NULL, 0x020, NULL, HFILL
2951             }
2952         },
2953         { &hf_nan_attr_sdea_ctr_security,
2954             {
2955             "Security Required",
2956             "nan.sdea.ctr_security",
2957             FT_BOOLEAN, 16, NULL, 0x040, NULL, HFILL
2958             }
2959         },
2960         { &hf_nan_attr_sdea_ctr_ranging,
2961             {
2962             "Ranging Required",
2963             "nan.sdea.ctr_ranging",
2964             FT_BOOLEAN, 16, NULL, 0x080, NULL, HFILL
2965             }
2966         },
2967         { &hf_nan_attr_sdea_ctr_range_limit,
2968             {
2969             "Range Limit Present",
2970             "nan.sdea.ctr_range_limit",
2971             FT_BOOLEAN, 16, NULL, 0x100, NULL, HFILL
2972             }
2973         },
2974         { &hf_nan_attr_sdea_ctr_service_update_indicator,
2975             {
2976             "Service Update Indicator Present",
2977             "nan.sdea.ctr_service_update_indicator",
2978             FT_BOOLEAN, 16, NULL, 0x200, NULL, HFILL
2979             }
2980         },
2981         { &hf_nan_attr_sdea_ingress_range_limit,
2982             {
2983             "Ingress Range Limit",
2984             "nan.sdea.range_limit_ingress",
2985             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2986             }
2987         },
2988         { &hf_nan_attr_sdea_egress_range_limit,
2989             {
2990             "Egress Range Limit",
2991             "nan.sdea.range_limit_egress",
2992             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2993             }
2994         },
2995         { &hf_nan_attr_sdea_service_update_indicator,
2996             {
2997             "Service Update Indicator",
2998             "nan.sdea.service_update_indicator",
2999             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3000             }
3001         },
3002         { &hf_nan_attr_sdea_service_info_length,
3003             {
3004             "Service Info Length",
3005             "nan.sdea.service_info_len",
3006             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3007             }
3008         },
3009         { &hf_nan_attr_sdea_service_info_protocol_type,
3010             {
3011             "Service Protocol Type",
3012             "nan.sdea.service_info_protocol_type",
3013             FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(service_info_protocol_type), 0x0, NULL, HFILL
3014             }
3015         },
3016         { &hf_nan_attr_sdea_service_info_specific,
3017             {
3018             "Service Specific info",
3019             "nan.sdea.service_info_specific",
3020             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
3021             }
3022         },
3023         { &hf_nan_attr_connection_cap_bitmap,
3024              {
3025              "Connection Capability Bitmap",
3026              "nan.connection_cap.bitmap",
3027              FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3028              }
3029         },
3030         { &hf_nan_attr_connection_cap_wifi_direct,
3031              {
3032              "Wifi Direct",
3033              "nan.connection_cap.wifi_direct",
3034              FT_BOOLEAN, 16, NULL, 0x1, NULL, HFILL
3035              }
3036         },
3037         { &hf_nan_attr_connection_cap_p2ps,
3038              {
3039              "P2Ps",
3040              "nan.connection_cap.p2ps",
3041              FT_BOOLEAN, 16, NULL, 0x2, NULL, HFILL
3042              }
3043         },
3044         { &hf_nan_attr_connection_cap_tdls,
3045              {
3046              "TDLS",
3047              "nan.connection_cap.tdls",
3048              FT_BOOLEAN, 16, NULL, 0x4, NULL, HFILL
3049              }
3050         },
3051         { &hf_nan_attr_connection_cap_wlan_infra,
3052              {
3053              "WLAN Infrastructure",
3054              "nan.connection_cap.wlan_infra",
3055              FT_BOOLEAN, 16, NULL, 0x8, NULL, HFILL
3056              }
3057         },
3058         { &hf_nan_attr_connection_cap_ibss,
3059              {
3060              "IBSS",
3061              "nan.connection_cap.ibss",
3062              FT_BOOLEAN, 16, NULL, 0x10, NULL, HFILL
3063              }
3064         },
3065         { &hf_nan_attr_connection_cap_mesh,
3066              {
3067              "Mesh",
3068              "nan.connection_cap.mesh",
3069              FT_BOOLEAN, 16, NULL, 0x20, NULL, HFILL
3070              }
3071         },
3072         { &hf_nan_attr_wlan_infra_device_role,
3073             {
3074             "Device Role",
3075             "nan.wlan_infra.device_role",
3076             FT_UINT8, BASE_DEC, VALS(device_role), 0x0, NULL, HFILL
3077             }
3078         },
3079         { &hf_nan_attr_p2p_device_role_device,
3080              {
3081              "P2P Device",
3082              "nan.p2p.device",
3083              FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL
3084              }
3085         },
3086         { &hf_nan_attr_p2p_device_role_group_owner,
3087              {
3088              "P2P Group Owner",
3089              "nan.p2p.group_owner",
3090              FT_BOOLEAN, 8, NULL, 0x2, NULL, HFILL
3091              }
3092         },
3093         { &hf_nan_attr_p2p_device_role_client,
3094              {
3095              "P2P Client",
3096              "nan.p2p.client",
3097              FT_BOOLEAN, 8, NULL, 0x4, NULL, HFILL
3098              }
3099         },
3100         { &hf_nan_attr_p2p_device_role,
3101              {
3102              "P2P Device Role",
3103              "nan.p2p.device_role",
3104              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3105              }
3106         },
3107         { &hf_nan_attr_mesh_id,
3108             {
3109             "Mesh ID",
3110             "nan.mesh.id",
3111             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
3112             }
3113         },
3114         { &hf_nan_attr_further_av_map_id,
3115             {
3116             "Map ID",
3117             "nan.furth.av.map.id",
3118             FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(furth_av_map_id), 0x0, NULL, HFILL
3119             }
3120         },
3121         { &hf_nan_attr_further_av_map_entry_av_interval_duration,
3122             {
3123             "Availability Interval Duration",
3124             "nan.further_av_map.entry.av_interval_duration",
3125             FT_UINT8, BASE_DEC, VALS(map_ctrl_availability_interval_duration), 0x03, NULL, HFILL
3126             }
3127         },
3128         { &hf_nan_attr_further_av_map_op_class,
3129              {
3130              "Operating Class",
3131              "nan.further_av_map.entry.op_class",
3132              FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3133              }
3134         },
3135         { &hf_nan_attr_further_av_map_channel_num,
3136              {
3137              "Channel Number",
3138              "nan.further_av_map.entry.channel_number",
3139              FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3140              }
3141         },
3142         { &hf_nan_attr_further_av_map_entry_ctrl,
3143              {
3144              "Entry Control Fields",
3145              "nan.further_av_map.entry.ctrl",
3146              FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3147              }
3148         },
3149         { &hf_nan_attr_country_code,
3150              {
3151              "Condensed Country String",
3152              "nan.country_code",
3153              FT_STRINGZ, STR_ASCII, NULL, 0x0, NULL, HFILL
3154              }
3155         },
3156         { &hf_nan_attr_ranging_protocol,
3157              {
3158              "Ranging Protocol",
3159              "nan.ranging.protocol",
3160              FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3161              }
3162         },
3163         { &hf_nan_attr_cluster_disc_id,
3164              {
3165              "Cluster ID",
3166              "nan.cluster_disc.id",
3167              FT_UINT48, BASE_HEX, NULL, 0x0, NULL, HFILL
3168              }
3169         },
3170         { &hf_nan_attr_cluster_disc_time_offset,
3171              {
3172              "Cluster Time Offset",
3173              "nan.cluster_disc.time_offset",
3174              FT_UINT64, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL
3175              }
3176         },
3177         { &hf_nan_attr_cluster_disc_anchor_master_rank,
3178              {
3179              "Anchor Master Rank",
3180              "nan.cluster_disc.anchor_master_rank",
3181              FT_UINT64, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL
3182              }
3183         },
3184         { &hf_nan_attr_device_cap_map_id_apply_to,
3185             {
3186             "Apply to",
3187             "nan.device_cap.map_id_apply_to",
3188             FT_BOOLEAN, 8, TFS(&device_cap_map_id_apply_to_flags), 0x01, NULL, HFILL
3189             }
3190         },
3191         { &hf_nan_attr_device_cap_map_id_associated_maps,
3192             {
3193             "Map ID",
3194             "nan.device_cap.map_id_associated_maps",
3195             FT_UINT8, BASE_HEX_DEC, NULL, 0x1E, NULL, HFILL
3196             }
3197         },
3198         { &hf_nan_attr_device_cap_committed_dw,
3199             {
3200             "Committed DW Info",
3201             "nan.device_cap.committed_dw_info",
3202             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3203             }
3204         },
3205         { &hf_nan_attr_device_cap_committed_dw_24ghz,
3206             {
3207             "2.4 GHz DW",
3208             "nan.device_cap.committed_dw_info.24ghz",
3209             FT_UINT16, BASE_DEC, NULL, 0x0007, NULL, HFILL
3210             }
3211         },
3212         { &hf_nan_attr_device_cap_committed_dw_5ghz,
3213             {
3214             "5 GHz DW",
3215             "nan.device_cap.committed_dw_info.5ghz",
3216             FT_UINT16, BASE_DEC, NULL, 0x0038, NULL, HFILL
3217             }
3218         },
3219         { &hf_nan_attr_device_cap_committed_dw_24ghz_overwrite,
3220             {
3221             "2.4 GHz DW Overwrite",
3222             "nan.device_cap.committed_dw_info.24ghz_overwrite",
3223             FT_UINT16, BASE_DEC, NULL, 0x03C0, NULL, HFILL
3224             }
3225         },
3226         { &hf_nan_attr_device_cap_committed_dw_5ghz_overwrite,
3227             {
3228             "5 GHz DW Overwrite",
3229             "nan.device_cap.committed_dw_info.5ghz_overwrite",
3230             FT_UINT16, BASE_DEC, NULL, 0x3C00, NULL, HFILL
3231             }
3232         },
3233         { &hf_nan_attr_device_cap_supported_bands,
3234             {
3235             "Supported Bands",
3236             "nan.device_cap.supported_bands",
3237             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3238             }
3239         },
3240         { &hf_nan_attr_device_cap_supported_bands_reserved_tv_whitespaces,
3241             {
3242             "Reserved (for TV white spaces)",
3243             "nan.device_cap.supported_bands.tv_whitespaces",
3244             FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL
3245             }
3246         },
3247         { &hf_nan_attr_device_cap_supported_bands_sub_1ghz,
3248             {
3249             "Sub-1 GHz",
3250             "nan.device_cap.supported_bands.sub_1ghz",
3251             FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL
3252             }
3253         },
3254         { &hf_nan_attr_device_cap_supported_bands_24ghz,
3255             {
3256             "2.4 GHz",
3257             "nan.device_cap.supported_bands.24ghz",
3258             FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL
3259             }
3260         },
3261         { &hf_nan_attr_device_cap_supported_bands_reserved_36ghz,
3262             {
3263             "Reserved (for 3.6 GHz)",
3264             "nan.device_cap.supported_bands.reserved_36ghz",
3265             FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL
3266             }
3267         },
3268         { &hf_nan_attr_device_cap_supported_bands_5ghz,
3269             {
3270             "4.9 and 5 GHz",
3271             "nan.device_cap.supported_bands.5ghz",
3272             FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL
3273             }
3274         },
3275         { &hf_nan_attr_device_cap_supported_bands_reserved_60ghz,
3276             {
3277             "Reserved (for 60 GHz)",
3278             "nan.device_cap.supported_bands.reserved_60ghz",
3279             FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL
3280             }
3281         },
3282         { &hf_nan_attr_device_cap_op_mode,
3283             {
3284             "Operation Mode",
3285             "nan.device_cap.op_mode",
3286             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3287             }
3288         },
3289         { &hf_nan_attr_device_cap_op_mode_phy,
3290             {
3291             "PHY Mode",
3292             "nan.device_cap.op_mode.phy",
3293             FT_BOOLEAN, 8, TFS(&device_cap_op_mode_phy_flags), 0x01, NULL, HFILL
3294             }
3295         },
3296         { &hf_nan_attr_device_cap_op_mode_vht8080,
3297             {
3298             "VHT 80+80",
3299             "nan.device_cap.op_mode.vht8080",
3300             FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL
3301             }
3302         },
3303         { &hf_nan_attr_device_cap_op_mode_vht160,
3304             {
3305             "VHT 160",
3306             "nan.device_cap.op_mode.vht160",
3307             FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL
3308             }
3309         },
3310         { &hf_nan_attr_device_cap_op_mode_reserved_paging_ndl,
3311             {
3312             "Reserved (Paging NDL Support)",
3313             "nan.device_cap.op_mode.reserved_paging_ndl",
3314             FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL
3315             }
3316         },
3317         { &hf_nan_attr_device_cap_antennas,
3318             {
3319             "Antennas",
3320             "nan.device_cap.antennas",
3321             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3322             }
3323         },
3324         { &hf_nan_attr_device_cap_antennas_tx,
3325             {
3326             "Number of TX antennas",
3327             "nan.device_cap.antennas.tx",
3328             FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL
3329             }
3330         },
3331         { &hf_nan_attr_device_cap_antennas_rx,
3332             {
3333             "Number of RX antennas",
3334             "nan.device_cap.antennas.rx",
3335             FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL
3336             }
3337         },
3338         { &hf_nan_attr_device_cap_max_channel_switch_time,
3339             {
3340             "Max Channel Switch Time (us)",
3341             "nan.device_cap.max_channel_switch_time",
3342             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3343             }
3344         },
3345         { &hf_nan_attr_device_cap_capabilities,
3346             {
3347             "Capabilities",
3348             "nan.device_cap.capabilities",
3349             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3350             }
3351         },
3352         { &hf_nan_attr_device_cap_capabilities_dfs_master,
3353             {
3354             "DFS Master",
3355             "nan.device_cap.capabilities.dfs_master",
3356             FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL
3357             }
3358         },
3359         { &hf_nan_attr_device_cap_capabilities_extended_key_id,
3360             {
3361             "Extended key ID",
3362             "nan.device_cap.capabilities.extended_key_id",
3363             FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL
3364             }
3365         },
3366         { &hf_nan_attr_device_cap_capabilities_simul_ndp_reception,
3367             {
3368             "Simultaneous NDP data reception",
3369             "nan.device_cap.capabilities.simul_ndp_reception",
3370             FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL
3371             }
3372         },
3373         { &hf_nan_attr_device_cap_capabilities_ndpe_attr_support,
3374             {
3375             "NDPE attribute support",
3376             "nan.device_cap.capabilities.ndpe_attr_support",
3377             FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL
3378             }
3379         },
3380         { &hf_nan_attr_ndp_type,
3381              {
3382              "Type",
3383              "nan.ndp.type",
3384              FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(ndp_type_values), 0xF, NULL, HFILL
3385              }
3386         },
3387         { &hf_nan_attr_ndp_initiator,
3388             {
3389             "Initiator NDI",
3390             "nan.ndp.initiator_ndi",
3391             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
3392             }
3393         },
3394         { &hf_nan_attr_ndp_id,
3395              {
3396              "NDP ID",
3397              "nan.ndp.id",
3398              FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3399              }
3400         },
3401         { &hf_nan_attr_ndp_ctrl_confirm,
3402              {
3403              "Confirm Required",
3404              "nan.ndp.ctrl.confirm",
3405              FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL
3406              }
3407         },
3408         { &hf_nan_attr_ndp_ctrl_security_pres,
3409              {
3410              "Security Present",
3411              "nan.ndp.ctrl.security_pres",
3412              FT_BOOLEAN, 8, NULL, 0x4, NULL, HFILL
3413              }
3414         },
3415         { &hf_nan_attr_ndp_ctrl_publish_id_pres,
3416              {
3417              "Publish ID Present",
3418              "nan.ndp.ctrl.publish_id_pres",
3419              FT_BOOLEAN, 8, NULL, 0x8, NULL, HFILL
3420              }
3421         },
3422         { &hf_nan_attr_ndp_ctrl_responder_ndi_pres,
3423              {
3424              "Responder NDI Present",
3425              "nan.ndp.ctrl.responder_ndi_pres",
3426              FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL
3427              }
3428         },
3429         { &hf_nan_attr_ndp_ctrl_sepcific_info_pres,
3430              {
3431              "NDP Specific Info Present",
3432              "nan.ndp.ctrl.specific_info_pres",
3433              FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL
3434              }
3435         },
3436         { &hf_nan_attr_ndp_control,
3437              {
3438              "NDP Control",
3439              "nan.ndp.ctrl",
3440              FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3441              }
3442         },
3443         { &hf_nan_attr_ndp_responder_ndi,
3444              {
3445              "Responder NDI",
3446              "nan.ndp.responder.ndi",
3447              FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
3448              }
3449         },
3450         { &hf_nan_attr_ndp_specific_info,
3451              {
3452              "NDP Specific Info",
3453              "nan.ndp.specific_info",
3454              FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
3455              }
3456         },
3457         { &hf_nan_attr_ndpe_tlv_type,
3458              {
3459              "Type",
3460              "nan.ndpe.tlv.type",
3461              FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(ndpe_tlv_type_values), 0x0, NULL, HFILL
3462              }
3463         },
3464         { &hf_nan_attr_ndpe_tlv_len,
3465              {
3466              "Length",
3467              "nan.ndpe.tlv.len",
3468              FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3469              }
3470         },
3471         { &hf_nan_attr_ndpe_tlv_ipv6_interface_identifier,
3472              {
3473              "Interface Identifier",
3474              "nan.ndpe.tlv.ipv6_interface_identifier",
3475              FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL
3476              }
3477         },
3478         { &hf_nan_attr_availability_sequence_id,
3479             {
3480             "Sequence ID",
3481             "nan.availability.sequence_id",
3482             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3483             }
3484         },
3485         { &hf_nan_attr_availability_ctr,
3486             {
3487             "Attribute Control",
3488             "nan.availability.ctr",
3489             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
3490             }
3491         },
3492         { &hf_nan_attr_availability_map_id,
3493             {
3494             "Map ID",
3495             "nan.availability.map_id",
3496             FT_UINT16, BASE_HEX_DEC, NULL, 0x00F, NULL, HFILL
3497             }
3498         },
3499         { &hf_nan_attr_availability_committed_changed,
3500             {
3501             "Committed Changed",
3502             "nan.availability.committed_changed",
3503             FT_BOOLEAN, 16, NULL, 0x010, NULL, HFILL
3504             }
3505         },
3506         { &hf_nan_attr_availability_potential_changed,
3507             {
3508             "Potential Changed",
3509             "nan.availability.potential_changed",
3510             FT_BOOLEAN, 16, NULL, 0x020, NULL, HFILL
3511             }
3512         },
3513         { &hf_nan_attr_availability_public_availability_changed,
3514             {
3515             "Public Availability Attribute Changed",
3516             "nan.availability.public_availability_changed",
3517             FT_BOOLEAN, 16, NULL, 0x040, NULL, HFILL
3518             }
3519         },
3520         { &hf_nan_attr_availability_ndc_changed,
3521             {
3522             "NDC Attribute Changed",
3523             "nan.availability.ndc_changed",
3524             FT_BOOLEAN, 16, NULL, 0x080, NULL, HFILL
3525             }
3526         },
3527         { &hf_nan_attr_availability_reserved_multicast_schedule_changed,
3528             {
3529             "Reserved (Multicast Schedule Attribute Changed)",
3530             "nan.availability.reserved_multicast_schedule_changed",
3531             FT_BOOLEAN, 16, NULL, 0x100, NULL, HFILL
3532             }
3533         },
3534         { &hf_nan_attr_availability_reserved_multicast_schedule_change_changed,
3535             {
3536             "Reserved (Multicast Schedule Change Attribute Change Changed)",
3537             "nan.availability.reserved_multicast_schedule_change_changed",
3538             FT_BOOLEAN, 16, NULL, 0x200, NULL, HFILL
3539             }
3540         },
3541         { &hf_nan_attr_availability_entry_len,
3542             {
3543             "Length",
3544             "nan.availability.entry.len",
3545             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3546             }
3547         },
3548         { &hf_nan_attr_availability_entry_ctr,
3549             {
3550             "Entry Control",
3551             "nan.availability.entry.ctr",
3552             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
3553             }
3554         },
3555         { &hf_nan_attr_availability_entry_ctr_type,
3556             {
3557             "Availability Type",
3558             "nan.availability.entry.ctr.type",
3559             FT_UINT16, BASE_HEX, VALS(availability_entry_type), 0x0007, NULL, HFILL
3560             }
3561         },
3562         { &hf_nan_attr_availability_entry_ctr_pref,
3563             {
3564             "Usage Preference",
3565             "nan.availability.entry.ctr.pref",
3566             FT_UINT16, BASE_DEC, NULL, 0x0018, NULL, HFILL
3567             }
3568         },
3569         { &hf_nan_attr_availability_entry_ctr_utilization,
3570             {
3571             "Utilization",
3572             "nan.availability.entry.ctr.utilization",
3573             FT_UINT16, BASE_DEC, NULL, 0x00E0, NULL, HFILL
3574             }
3575         },
3576         { &hf_nan_attr_availability_entry_ctr_rx_nss,
3577             {
3578             "Rx Nss",
3579             "nan.availability.entry.ctr.rx_nss",
3580             FT_UINT16, BASE_DEC, NULL, 0x0F00, NULL, HFILL
3581             }
3582         },
3583         { &hf_nan_attr_availability_entry_ctr_time_bitmap,
3584             {
3585             "Time Bitmap Present",
3586             "nan.availability.entry.ctr.time_bitmap",
3587             FT_BOOLEAN, 16, NULL, 0x1000, NULL, HFILL
3588             }
3589         },
3590         { &hf_nan_attr_availability_entry_entries_type,
3591             {
3592             "Type",
3593             "nan.availability.entry.entries.type",
3594             FT_BOOLEAN, 8, TFS(&availability_entry_entries_type_flags), 0x0, NULL, HFILL
3595             }
3596         },
3597         { &hf_nan_attr_availability_entry_entries_non_contiguous_bw,
3598             {
3599             "Non-contiguous Bandwidth",
3600             "nan.availability.entry.entries.non_contiguous_bw",
3601             FT_BOOLEAN, 8, NULL, 0x0, NULL, HFILL
3602             }
3603         },
3604         { &hf_nan_attr_availability_entry_entries_num_entries,
3605             {
3606             "Number of Entries",
3607             "nan.availability.entry.entries.num_entries",
3608             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3609             }
3610         },
3611         { &hf_nan_attr_availability_entry_entries_band,
3612             {
3613             "Band Entry",
3614             "nan.availability.entry.entries.band",
3615             FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(availability_entry_entries_band_type), 0x0, NULL, HFILL
3616             }
3617         },
3618         { &hf_nan_attr_availability_entry_entries_channel_op_class,
3619             {
3620             "Operating Class",
3621             "nan.availability.entry.entries.channel.op_class",
3622             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3623             }
3624         },
3625         { &hf_nan_attr_availability_entry_entries_channel_bitmap,
3626             {
3627             "Channel Bitmap",
3628             "nan.availability.entry.entries.channel.bitmap",
3629             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
3630             }
3631         },
3632         { &hf_nan_attr_availability_entry_entries_primary_channel_bitmap,
3633             {
3634             "Primary Channel Bitmap",
3635             "nan.availability.entry.entries.channel.primary_bitmap",
3636             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3637             }
3638         },
3639         { &hf_nan_attr_availability_entry_entries_aux_channel_bitmap,
3640             {
3641             "Auxiliary Channel Bitmap",
3642             "nan.availability.entry.entries.channel.aux_bitmap",
3643             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
3644             }
3645         },
3646         { &hf_nan_attr_availability_entry_entries_channel_set,
3647             {
3648             "Channel Bitmap - Channel Set",
3649             "nan.ava.chan.set",
3650             FT_STRING, STR_ASCII, NULL, 0x00, NULL, HFILL
3651             }
3652         },
3653         { &hf_nan_attr_availability_entry_entries_start_freq,
3654             {
3655             "Starting Frequency",
3656             "nan.av.entry.start.freq",
3657             FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(op_starting_freq), 0x0, NULL, HFILL
3658             }
3659         },
3660         { &hf_nan_attr_availability_entry_entries_bandwidth,
3661             {
3662             "Bandwidth",
3663             "nan.av.entry.bandwidth",
3664             FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(op_channel_spacing), 0x0, NULL, HFILL
3665             }
3666         },
3667         { &hf_nan_attr_ndc_id,
3668             {
3669             "NDC ID",
3670             "nan.ndc.id",
3671             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
3672             }
3673         },
3674         { &hf_nan_attr_ndc_ctrl,
3675             {
3676             "Control",
3677             "nan.ndc.ctrl",
3678             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3679             }
3680         },
3681         { &hf_nan_attr_ndc_ctrl_selected,
3682             {
3683             "Selected NDC",
3684             "nan.ndc.ctrl.selected",
3685             FT_BOOLEAN, 8, TFS(&ndc_ctr_selected_flags), 0x01, NULL, HFILL
3686             }
3687         },
3688         { &hf_nan_attr_ndc_map_id_related_sch,
3689             {
3690             "NAN Availability associated with schedule time bitmap",
3691             "nan.ndc.map.id.rel",
3692             FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL
3693             }
3694         },
3695         { &hf_nan_attr_ndl_type,
3696              {
3697              "Type",
3698              "nan.ndl.type",
3699              FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(ndl_type_values), 0xF, NULL, HFILL
3700              }
3701         },
3702         { &hf_nan_attr_ndl_control,
3703              {
3704              "NDL Control",
3705              "nan.ndl.ctrl",
3706              FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3707              }
3708         },
3709         { &hf_nan_attr_ndl_ctrl_peer_id,
3710             {
3711             "NDL Peer ID Present",
3712             "nan.ndl.ctrl.peer_id",
3713             FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL
3714             }
3715         },
3716         { &hf_nan_attr_ndl_ctrl_immutable_schedule_pres,
3717             {
3718             "Immutable Schedule Present",
3719             "nan.ndl.ctrl.immutable_schedule_pres",
3720             FT_BOOLEAN, 8, NULL, 0x2, NULL, HFILL
3721             }
3722         },
3723         { &hf_nan_attr_ndl_ctrl_ndc_pres,
3724             {
3725             "NDC Attribute Present",
3726             "nan.ndl.ctrl.ndc_pres",
3727             FT_BOOLEAN, 8, NULL, 0x4, NULL, HFILL
3728             }
3729         },
3730         { &hf_nan_attr_ndl_ctrl_qos,
3731             {
3732             "NDL QoS Present",
3733             "nan.ndl.ctrl.qos_pres",
3734             FT_BOOLEAN, 8, NULL, 0x8, NULL, HFILL
3735             }
3736         },
3737         { &hf_nan_attr_ndl_ctrl_max_idle_pres,
3738             {
3739             "Max Idle period Present",
3740             "nan.ndl.ctrl.max_idle_period_pres",
3741             FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL
3742             }
3743         },
3744         { &hf_nan_attr_ndl_ctrl_type,
3745             {
3746             "NDL Type",
3747             "nan.ndl.ctrl.type",
3748             FT_UINT8, BASE_DEC, VALS(ndl_type_string), 0x20, NULL, HFILL
3749             }
3750         },
3751         { &hf_nan_attr_ndl_ctrl_setup_reason,
3752             {
3753             "NDL Setup Reason",
3754             "nan.ndl.ctrl.setup_reason",
3755             FT_UINT8, BASE_DEC, VALS(ndl_setup_reason), 0xC0, NULL, HFILL
3756             }
3757         },
3758         { &hf_nan_attr_ndl_reserved_peer_id,
3759             {
3760             "Reserved (NDL Peer ID)",
3761             "nan.ndl.peer_id",
3762             FT_UINT8, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL
3763             }
3764         },
3765         { &hf_nan_attr_ndl_max_idle,
3766             {
3767             "Max Idle Period",
3768             "nan.ndl.max.idle",
3769             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3770             }
3771         },
3772         { &hf_nan_attr_ndlqos_min_time_slots,
3773             {
3774             "Minimum Time Slots",
3775             "nan.ndl_qos.min_time_slots",
3776             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3777             }
3778         },
3779         { &hf_nan_attr_ndlqos_max_latency,
3780             {
3781             "Maximum Latency",
3782             "nan.ndl_qos.max_latency",
3783             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3784             }
3785         },
3786         { &hf_nan_attr_unaligned_sch_ctrl,
3787              {
3788              "Attribute Control",
3789              "nan.unaligned_schedule.ctrl",
3790              FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3791              }
3792         },
3793         { &hf_nan_attr_unaligned_sch_ctrl_schedule_id,
3794             {
3795             "Schedule ID",
3796             "nan.unaligned_schedule.ctrl.schedule_id",
3797             FT_UINT16, BASE_HEX_DEC, NULL, 0xF, NULL, HFILL
3798             }
3799         },
3800         { &hf_nan_attr_unaligned_sch_ctrl_seq_id,
3801             {
3802             "Sequence ID",
3803             "nan.unaligned_schedule.ctrl.sequence_id",
3804             FT_UINT16, BASE_HEX_DEC, NULL, 0xF00, NULL, HFILL
3805             }
3806         },
3807         { &hf_nan_attr_unaligned_sch_starting_time,
3808             {
3809             "Starting Time",
3810             "nan.unaligned_schedule.starting_time",
3811             FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3812             }
3813         },
3814         { &hf_nan_attr_unaligned_sch_duration,
3815             {
3816             "Duration",
3817             "nan.unaligned_schedule.duration",
3818             FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
3819             }
3820         },
3821         { &hf_nan_attr_unaligned_sch_period,
3822             {
3823             "Period",
3824             "nan.unaligned_schedule.period",
3825             FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
3826             }
3827         },
3828         { &hf_nan_attr_unaligned_sch_count_down,
3829             {
3830             "Count Down",
3831             "nan.unaligned_schedule.count_down",
3832             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3833             }
3834         },
3835         { &hf_nan_attr_unaligned_sch_ulw_overwrite,
3836              {
3837              "ULW Overwrite",
3838              "nan.unaligned_schedule.ulw_overwrite",
3839              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3840              }
3841         },
3842         { &hf_nan_attr_unaligned_sch_ulw_overwrite_all,
3843              {
3844              "Overwrite All",
3845              "nan.unaligned_schedule.ulw_overwrite.overwrite_all",
3846              FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL
3847              }
3848         },
3849         { &hf_nan_attr_unaligned_sch_ulw_overwrite_map_id,
3850              {
3851              "Map ID",
3852              "nan.unaligned_schedule.ulw_overwrite.map_id",
3853              FT_UINT16, BASE_HEX_DEC, NULL, 0x1E, NULL, HFILL
3854              }
3855         },
3856         { &hf_nan_attr_unaligned_sch_ulw_ctrl,
3857              {
3858              "ULW Control Field",
3859              "nan.attribute.ulw.ctrl",
3860              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3861              }
3862         },
3863         { &hf_nan_attr_unaligned_sch_ulw_ctrl_type,
3864              {
3865              "Type",
3866              "nan.unaligned_schedule.ulw_ctrl.type",
3867              FT_UINT8, BASE_DEC_HEX, VALS(unaligned_sch_ulw_type), 0x3, NULL, HFILL
3868              }
3869         },
3870         { &hf_nan_attr_unaligned_sch_ulw_ctrl_channel_av,
3871              {
3872              "Channel Availability",
3873              "nan.unaligned_schedule.ulw_ctrl.channel_availability",
3874              FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL
3875              }
3876         },
3877         { &hf_nan_attr_unaligned_sch_ulw_ctrl_rxnss,
3878              {
3879              "Rx Nss",
3880              "nan.unaligned_schedule.ulw_ctrl.rx_nss",
3881              FT_UINT8, BASE_HEX, NULL, 0x78, NULL, HFILL
3882              }
3883         },
3884         { &hf_nan_attr_ranging_info_location_info_avail,
3885             {
3886             "Location Info Availability",
3887             "nan.ranging_info.location_info_availability",
3888             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
3889             }
3890         },
3891         { &hf_nan_attr_ranging_info_location_info_avail_lci,
3892              {
3893              "LCI Local Coordinates",
3894              "nan.ranging_info.location_info_availability.local_coord",
3895              FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL
3896              }
3897         },
3898         { &hf_nan_attr_ranging_info_location_info_avail_geospatial,
3899              {
3900              "Geospatial LCI WGS84",
3901              "nan.ranging_info.location_info_availability.geospatial",
3902              FT_BOOLEAN, 8, NULL, 0x2, NULL, HFILL
3903              }
3904         },
3905         { &hf_nan_attr_ranging_info_location_info_avail_civic_location,
3906              {
3907              "Civic Location",
3908              "nan.ranging_info.location_info_availability.civic_location",
3909              FT_BOOLEAN, 8, NULL, 0x4, NULL, HFILL
3910              }
3911         },
3912         { &hf_nan_attr_ranging_info_location_info_avail_last_movement_pres,
3913              {
3914              "Last Movement Indication",
3915              "nan.ranging_info.location_info_availability.last_movement_indication",
3916              FT_BOOLEAN, 8, NULL, 0x8, NULL, HFILL
3917              }
3918         },
3919         { &hf_nan_attr_ranging_info_last_movement_indication,
3920             {
3921             "Last Movement Indication",
3922             "nan.ranging_info.last_movement_indication",
3923             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
3924             }
3925         },
3926         { &hf_nan_attr_ranging_setup_type,
3927              {
3928              "Type",
3929              "nan.ranging_setup.type",
3930              FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(ranging_setup_type_values), 0xF, NULL, HFILL
3931              }
3932         },
3933         { &hf_nan_attr_ranging_setup_ctrl,
3934             {
3935             "Ranging Control",
3936             "nan.ranging_setup.ctrl",
3937             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
3938             }
3939         },
3940         { &hf_nan_attr_ranging_setup_ctrl_report_req,
3941             {
3942             "Ranging Report Required",
3943             "nan.ranging_setup.ctrl.report_required",
3944             FT_BOOLEAN, 3, NULL, 0x1, NULL, HFILL
3945             }
3946         },
3947         { &hf_nan_attr_ranging_setup_ctrl_ftm_params,
3948             {
3949             "FTM Parameters Present",
3950             "nan.ranging_setup.ctrl.ftm_params",
3951             FT_BOOLEAN, 3, NULL, 0x2, NULL, HFILL
3952             }
3953         },
3954         { &hf_nan_attr_ranging_setup_ctrl_entry_list,
3955             {
3956             "Ranging Schedule Entry List Present",
3957             "nan.ranging_setup.ctrl.sch_entry_pres",
3958             FT_BOOLEAN, 3, NULL, 0x4, NULL, HFILL
3959             }
3960         },
3961         { &hf_nan_attr_ranging_setup_ftm_params,
3962             {
3963             "FTM Parameters",
3964             "nan.ranging_setup.ftm",
3965             FT_UINT24, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
3966             }
3967         },
3968         { &hf_nan_attr_ranging_setup_ftm_max_burst_duration,
3969              {
3970              "Max Burst Duration",
3971              "nan.ranging_setup.ftm.max_burst_duration",
3972              FT_UINT24, BASE_HEX_DEC, NULL, 0xF, NULL, HFILL
3973              }
3974         },
3975         { &hf_nan_attr_ranging_setup_ftm_min_delta,
3976              {
3977              "Min Delta FTM",
3978              "nan.ranging_setup.ftm.min_delta_ftm",
3979              FT_UINT24, BASE_HEX_DEC, NULL, 0x3F0, NULL, HFILL
3980              }
3981         },
3982         { &hf_nan_attr_ranging_setup_ftm_max_per_burst,
3983              {
3984              "Max FTMs per Burst",
3985              "nan.ranging_setup.ftm.max_ftms_per_burst",
3986              FT_UINT24, BASE_HEX_DEC, NULL, 0x7C00, NULL, HFILL
3987              }
3988         },
3989         { &hf_nan_attr_ranging_setup_ftm_format_bw,
3990              {
3991              "FTM Format and Bandwidth",
3992              "nan.ranging_setup.ftm.format_bw",
3993              FT_UINT24, BASE_HEX_DEC, NULL, 0x1F8000, NULL, HFILL
3994              }
3995         },
3996         { &hf_nan_attr_ftm_range_report,
3997              {
3998              "FTM Range Report",
3999              "nan.ftm.range_report",
4000              FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
4001              }
4002         },
4003         { &hf_nan_attr_cipher_suite_capabilities,
4004             {
4005             "Capabilities",
4006             "nan.cipher_suite.capabilities",
4007             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
4008             }
4009         },
4010         { &hf_nan_attr_cipher_suite_id,
4011             {
4012             "Cipher Suite ID",
4013             "nan.cipher_suite.id",
4014             FT_UINT8, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL
4015             }
4016         },
4017         { &hf_nan_attr_security_context_identifier,
4018             {
4019             "Security Context Identifier",
4020             "nan.security_context.identifier",
4021             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
4022             }
4023         },
4024         { &hf_nan_attr_security_context_identifier_len,
4025             {
4026             "Security Context Identifier Length",
4027             "nan.security_context.identifier_len",
4028             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
4029             }
4030         },
4031         { &hf_nan_attr_security_context_identifier_type,
4032             {
4033             "Security Context Identifier Type",
4034             "nan.security_context.identifier_type",
4035             FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(security_context_iden_type), 0x0, NULL, HFILL
4036             }
4037         },
4038         { &hf_nan_attr_shared_key_rsna_descriptor,
4039              {
4040              "IEEE 802.11 RSNA Key Descriptor",
4041              "nan.shared_key.rsna_key_descriptor",
4042              FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
4043              }
4044         },
4045         { &hf_nan_attr_vendor_specific_body,
4046             {
4047             "Body",
4048             "nan.vendor_specific.body",
4049             FT_BYTES, SEP_DASH, NULL, 0x0, NULL, HFILL
4050             }
4051         },
4052         { &hf_nan_attr_container_element_id,
4053             {
4054             "Element Id",
4055             "nan.container.element.id",
4056             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
4057             }
4058         },
4059         { &hf_nan_attr_container_element_len,
4060             {
4061             "Element Length",
4062             "nan.container.element.len",
4063             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
4064             }
4065         },
4066     };
4067 
4068     static gint* ett[] = {
4069         &ett_nan,
4070         &ett_attributes,
4071         &ett_type_status,
4072         &ett_map_control,
4073         &ett_time_bitmap_ctrl,
4074         &ett_non_nan_op_channel,
4075         &ett_non_nan_beacon,
4076         &ett_cluster_anchor_master_info,
4077         &ett_sda_service_ctr,
4078         &ett_sda_srf_ctr,
4079         &ett_sdea_ctr,
4080         &ett_sdea_range_limit,
4081         &ett_sdea_service_info,
4082         &ett_connection_cap_field,
4083         &ett_further_av_map_entry_ctrl,
4084         &ett_p2p_device_role,
4085         &ett_device_cap_map_id,
4086         &ett_device_cap_committed_dw,
4087         &ett_device_cap_supported_bands,
4088         &ett_device_cap_op_mode,
4089         &ett_device_cap_antennas,
4090         &ett_device_cap_capabilities,
4091         &ett_ndp_control,
4092         &ett_ndpe_tlv,
4093         &ett_availability_ctr,
4094         &ett_availability_entry,
4095         &ett_availability_entry_ctr,
4096         &ett_availability_entry_entries,
4097         &ett_availability_entry_entries_channel,
4098         &ett_availability_op_class,
4099         &ett_ndc_ctr,
4100         &ett_ndc_entries,
4101         &ett_device_ndc_map_id,
4102         &ett_ndl_control,
4103         &ett_ndl_schedule_entries,
4104         &ett_unaligned_sch_ctrl,
4105         &ett_unaligned_sch_ulw_overwrite,
4106         &ett_unaligned_sch_ulw_ctrl,
4107         &ett_ranging_info_location_info_availability,
4108         &ett_ranging_setup_ctrl,
4109         &ett_ranging_setup_ftm_params,
4110         &ett_ranging_setup_schedule_entries,
4111         &ett_cipher_suite_info_list,
4112         &ett_security_context_identifiers,
4113         &ett_public_availability_sch_entries,
4114         &ett_ie_tree,
4115     };
4116 
4117     static ei_register_info ei[] = {
4118         { &ei_nan_elem_len_invalid,
4119             {
4120             "nan.expert.elem_len_invalid",
4121             PI_MALFORMED, PI_ERROR,
4122             "Element length invalid",
4123             EXPFILL
4124             }
4125         },
4126         { &ei_nan_unknown_attr_id,
4127             {
4128             "nan.expert.unknown_attr_id",
4129             PI_PROTOCOL, PI_ERROR,
4130             "Unknown attribute ID",
4131             EXPFILL
4132             }
4133         },
4134         { &ei_nan_unknown_op_class,
4135             {
4136             "nan.expert.unknown_op_class",
4137             PI_PROTOCOL, PI_COMMENT,
4138             "Unknown Operating Class - Channel Set unavailable",
4139             EXPFILL
4140             }
4141         },
4142         { &ei_nan_unknown_beacon_type,
4143             {
4144             "nan.expert.unknown_beacon_type",
4145             PI_PROTOCOL, PI_WARN,
4146             "Unknown beacon type - Beacon type detection error",
4147             EXPFILL
4148             }
4149         },
4150     };
4151 
4152     proto_nan = proto_register_protocol(
4153         "NAN protocol",
4154         "NAN",
4155         "nan");
4156 
4157     proto_register_field_array(proto_nan, hf, array_length(hf));
4158     proto_register_subtree_array(ett, array_length(ett));
4159 
4160     expert_module_t* expert_nan = expert_register_protocol(proto_nan);
4161     expert_register_field_array(expert_nan, ei, array_length(ei));
4162 
4163     ie_handle_table = find_dissector_table("wlan.tag.number");
4164 }
4165 
4166 void
proto_reg_handoff_nan(void)4167 proto_reg_handoff_nan(void)
4168 {
4169     dissector_add_uint("wlan.pa.wifi_alliance.subtype", WFA_ACTION_OUI_TYPE, create_dissector_handle(dissect_nan_action, proto_nan));
4170     dissector_add_uint("wlan.pa.wifi_alliance.subtype", WFA_SERVICE_DISCOVERY_SUBTYPE, create_dissector_handle(dissect_nan_service_discovery, proto_nan));
4171     dissector_add_uint("wlan.ie.wifi_alliance.subtype", WFA_NAN_IE_OUI_TYPE, create_dissector_handle(dissect_nan_beacon, proto_nan));
4172 }
4173 
4174 /*
4175  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4176  *
4177  * Local variables:
4178  * c-basic-offset: 4
4179  * tab-width: 8
4180  * indent-tabs-mode: nil
4181  * End:
4182  *
4183  * vi: set shiftwidth=4 tabstop=8 expandtab:
4184  * :indentSize=4:tabSize=8:noTabs=true:
4185  */
4186