1 /*
2 * packet-ieee80211-radiotap.c
3 * Decode packets with a Radiotap header
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
8 *
9 * Copied from README.developer
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
14 #include "config.h"
15
16 #include <errno.h>
17
18 #include <epan/packet.h>
19 #include <epan/capture_dissectors.h>
20 #include <wsutil/pint.h>
21 #include <epan/crc32-tvb.h>
22 #include <wsutil/802_11-utils.h>
23 #include <epan/tap.h>
24 #include <epan/prefs.h>
25 #include <epan/addr_resolv.h>
26 #include <epan/expert.h>
27 #include <epan/arptypes.h>
28 #include "packet-ieee80211.h"
29 #include "packet-ieee80211-radiotap-iter.h"
30
31 void proto_register_radiotap(void);
32 void proto_reg_handoff_radiotap(void);
33
34 /* protocol */
35 static int proto_radiotap = -1;
36
37 static int hf_radiotap_version = -1;
38 static int hf_radiotap_pad = -1;
39 static int hf_radiotap_length = -1;
40 static int hf_radiotap_present = -1;
41
42 static int hf_radiotap_tlv_type = -1;
43 static int hf_radiotap_tlv_datalen = -1;
44 static int hf_radiotap_unknown_tlv_data = -1;
45
46 static int hf_radiotap_mactime = -1;
47 /* static int hf_radiotap_channel = -1; */
48 static int hf_radiotap_channel_frequency = -1;
49 static int hf_radiotap_channel_flags = -1;
50 static int hf_radiotap_channel_flags_700mhz = -1;
51 static int hf_radiotap_channel_flags_800mhz = -1;
52 static int hf_radiotap_channel_flags_900mhz = -1;
53 static int hf_radiotap_channel_flags_turbo = -1;
54 static int hf_radiotap_channel_flags_cck = -1;
55 static int hf_radiotap_channel_flags_ofdm = -1;
56 static int hf_radiotap_channel_flags_2ghz = -1;
57 static int hf_radiotap_channel_flags_5ghz = -1;
58 static int hf_radiotap_channel_flags_passive = -1;
59 static int hf_radiotap_channel_flags_dynamic = -1;
60 static int hf_radiotap_channel_flags_gfsk = -1;
61 static int hf_radiotap_channel_flags_gsm = -1;
62 static int hf_radiotap_channel_flags_sturbo = -1;
63 static int hf_radiotap_channel_flags_half = -1;
64 static int hf_radiotap_channel_flags_quarter = -1;
65 static int hf_radiotap_rxflags = -1;
66 static int hf_radiotap_rxflags_badplcp = -1;
67 static int hf_radiotap_txflags = -1;
68 static int hf_radiotap_txflags_fail = -1;
69 static int hf_radiotap_txflags_cts = -1;
70 static int hf_radiotap_txflags_rts = -1;
71 static int hf_radiotap_txflags_noack = -1;
72 static int hf_radiotap_txflags_noseqno = -1;
73 static int hf_radiotap_txflags_order = -1;
74 static int hf_radiotap_xchannel_channel = -1;
75 static int hf_radiotap_xchannel_frequency = -1;
76 static int hf_radiotap_xchannel_flags = -1;
77 static int hf_radiotap_xchannel_flags_turbo = -1;
78 static int hf_radiotap_xchannel_flags_cck = -1;
79 static int hf_radiotap_xchannel_flags_ofdm = -1;
80 static int hf_radiotap_xchannel_flags_2ghz = -1;
81 static int hf_radiotap_xchannel_flags_5ghz = -1;
82 static int hf_radiotap_xchannel_flags_passive = -1;
83 static int hf_radiotap_xchannel_flags_dynamic = -1;
84 static int hf_radiotap_xchannel_flags_gfsk = -1;
85 static int hf_radiotap_xchannel_flags_gsm = -1;
86 static int hf_radiotap_xchannel_flags_sturbo = -1;
87 static int hf_radiotap_xchannel_flags_half = -1;
88 static int hf_radiotap_xchannel_flags_quarter = -1;
89 static int hf_radiotap_xchannel_flags_ht20 = -1;
90 static int hf_radiotap_xchannel_flags_ht40u = -1;
91 static int hf_radiotap_xchannel_flags_ht40d = -1;
92 #if 0
93 static int hf_radiotap_xchannel_maxpower = -1;
94 #endif
95 static int hf_radiotap_fhss_hopset = -1;
96 static int hf_radiotap_fhss_pattern = -1;
97 static int hf_radiotap_datarate = -1;
98 static int hf_radiotap_antenna = -1;
99 static int hf_radiotap_dbm_antsignal = -1;
100 static int hf_radiotap_db_antsignal = -1;
101 static int hf_radiotap_dbm_antnoise = -1;
102 static int hf_radiotap_db_antnoise = -1;
103 static int hf_radiotap_tx_attenuation = -1;
104 static int hf_radiotap_db_tx_attenuation = -1;
105 static int hf_radiotap_txpower = -1;
106 static int hf_radiotap_data_retries = -1;
107 static int hf_radiotap_vendor_ns = -1;
108 static int hf_radiotap_ven_oui = -1;
109 static int hf_radiotap_ven_subns = -1;
110 static int hf_radiotap_ven_skip = -1;
111 static int hf_radiotap_ven_item = -1;
112 static int hf_radiotap_ven_data = -1;
113 static int hf_radiotap_mcs = -1;
114 static int hf_radiotap_mcs_known = -1;
115 static int hf_radiotap_mcs_have_bw = -1;
116 static int hf_radiotap_mcs_have_index = -1;
117 static int hf_radiotap_mcs_have_gi = -1;
118 static int hf_radiotap_mcs_have_format = -1;
119 static int hf_radiotap_mcs_have_fec = -1;
120 static int hf_radiotap_mcs_have_stbc = -1;
121 static int hf_radiotap_mcs_have_ness = -1;
122 static int hf_radiotap_mcs_ness_bit1 = -1;
123 static int hf_radiotap_mcs_bw = -1;
124 static int hf_radiotap_mcs_index = -1;
125 static int hf_radiotap_mcs_gi = -1;
126 static int hf_radiotap_mcs_format = -1;
127 static int hf_radiotap_mcs_fec = -1;
128 static int hf_radiotap_mcs_stbc = -1;
129 static int hf_radiotap_mcs_ness_bit0 = -1;
130 static int hf_radiotap_ampdu = -1;
131 static int hf_radiotap_ampdu_ref = -1;
132 static int hf_radiotap_ampdu_flags = -1;
133 static int hf_radiotap_ampdu_flags_report_zerolen = -1;
134 static int hf_radiotap_ampdu_flags_is_zerolen = -1;
135 static int hf_radiotap_ampdu_flags_last_known = -1;
136 static int hf_radiotap_ampdu_flags_is_last = -1;
137 static int hf_radiotap_ampdu_flags_delim_crc_error = -1;
138 static int hf_radiotap_ampdu_delim_crc = -1;
139 static int hf_radiotap_ampdu_flags_eof_known = -1;
140 static int hf_radiotap_ampdu_flags_eof = -1;
141 static int hf_radiotap_vht = -1;
142 static int hf_radiotap_vht_known = -1;
143 static int hf_radiotap_vht_have_stbc = -1;
144 static int hf_radiotap_vht_have_txop_ps = -1;
145 static int hf_radiotap_vht_have_gi = -1;
146 static int hf_radiotap_vht_have_sgi_nsym_da = -1;
147 static int hf_radiotap_vht_have_ldpc_extra = -1;
148 static int hf_radiotap_vht_have_bf = -1;
149 static int hf_radiotap_vht_have_bw = -1;
150 static int hf_radiotap_vht_have_gid = -1;
151 static int hf_radiotap_vht_have_p_aid = -1;
152 static int hf_radiotap_vht_stbc = -1;
153 static int hf_radiotap_vht_txop_ps = -1;
154 static int hf_radiotap_vht_gi = -1;
155 static int hf_radiotap_vht_sgi_nsym_da = -1;
156 static int hf_radiotap_vht_ldpc_extra = -1;
157 static int hf_radiotap_vht_bf = -1;
158 static int hf_radiotap_vht_bw = -1;
159 static int hf_radiotap_vht_nsts[4] = { -1, -1, -1, -1 };
160 static int hf_radiotap_vht_mcs[4] = { -1, -1, -1, -1 };
161 static int hf_radiotap_vht_nss[4] = { -1, -1, -1, -1 };
162 static int hf_radiotap_vht_coding[4] = { -1, -1, -1, -1 };
163 static int hf_radiotap_vht_datarate[4] = { -1, -1, -1, -1 };
164 static int hf_radiotap_vht_gid = -1;
165 static int hf_radiotap_vht_p_aid = -1;
166 static int hf_radiotap_vht_user = -1;
167 static int hf_radiotap_timestamp = -1;
168 static int hf_radiotap_timestamp_ts = -1;
169 static int hf_radiotap_timestamp_accuracy = -1;
170 static int hf_radiotap_timestamp_unit = -1;
171 static int hf_radiotap_timestamp_spos = -1;
172 static int hf_radiotap_timestamp_flags_32bit = -1;
173 static int hf_radiotap_timestamp_flags_accuracy = -1;
174
175 /* "Present" flags */
176 static int hf_radiotap_present_word = -1;
177 static int hf_radiotap_present_tsft = -1;
178 static int hf_radiotap_present_flags = -1;
179 static int hf_radiotap_present_rate = -1;
180 static int hf_radiotap_present_channel = -1;
181 static int hf_radiotap_present_fhss = -1;
182 static int hf_radiotap_present_dbm_antsignal = -1;
183 static int hf_radiotap_present_dbm_antnoise = -1;
184 static int hf_radiotap_present_lock_quality = -1;
185 static int hf_radiotap_present_tx_attenuation = -1;
186 static int hf_radiotap_present_db_tx_attenuation = -1;
187 static int hf_radiotap_present_dbm_tx_power = -1;
188 static int hf_radiotap_present_antenna = -1;
189 static int hf_radiotap_present_db_antsignal = -1;
190 static int hf_radiotap_present_db_antnoise = -1;
191 static int hf_radiotap_present_hdrfcs = -1;
192 static int hf_radiotap_present_rxflags = -1;
193 static int hf_radiotap_present_txflags = -1;
194 static int hf_radiotap_present_data_retries = -1;
195 static int hf_radiotap_present_xchannel = -1;
196 static int hf_radiotap_present_mcs = -1;
197 static int hf_radiotap_present_ampdu = -1;
198 static int hf_radiotap_present_vht = -1;
199 static int hf_radiotap_present_timestamp = -1;
200 static int hf_radiotap_present_he = -1;
201 static int hf_radiotap_present_he_mu = -1;
202 static int hf_radiotap_present_0_length_psdu = -1;
203 static int hf_radiotap_present_l_sig = -1;
204 static int hf_radiotap_present_tlv = -1;
205 static int hf_radiotap_present_rtap_ns = -1;
206 static int hf_radiotap_present_vendor_ns = -1;
207 static int hf_radiotap_present_ext = -1;
208
209 /* "present.flags" flags */
210 static int hf_radiotap_flags = -1;
211 static int hf_radiotap_flags_cfp = -1;
212 static int hf_radiotap_flags_preamble = -1;
213 static int hf_radiotap_flags_wep = -1;
214 static int hf_radiotap_flags_frag = -1;
215 static int hf_radiotap_flags_fcs = -1;
216 static int hf_radiotap_flags_datapad = -1;
217 static int hf_radiotap_flags_badfcs = -1;
218 static int hf_radiotap_flags_shortgi = -1;
219
220 static int hf_radiotap_quality = -1;
221 static int hf_radiotap_fcs = -1;
222 static int hf_radiotap_fcs_bad = -1;
223
224 /* HE Info fields */
225 static int hf_radiotap_he_ppdu_format = -1;
226 static int hf_radiotap_he_bss_color_known = -1;
227 static int hf_radiotap_he_beam_change_known = -1;
228 static int hf_radiotap_he_ul_dl_known = -1;
229 static int hf_radiotap_he_data_mcs_known = -1;
230 static int hf_radiotap_he_data_dcm_known = -1;
231 static int hf_radiotap_he_coding_known = -1;
232 static int hf_radiotap_he_ldpc_extra_symbol_segment_known = -1;
233 static int hf_radiotap_he_stbc_known = -1;
234 static int hf_radiotap_he_spatial_reuse_1_known = -1;
235 static int hf_radiotap_he_spatial_reuse_2_known = -1;
236 static int hf_radiotap_he_spatial_reuse_3_known = -1;
237 static int hf_radiotap_he_spatial_reuse_4_known = -1;
238 static int hf_radiotap_he_data_bw_ru_allocation_known = -1;
239 static int hf_radiotap_he_doppler_known = -1;
240 static int hf_radiotap_he_pri_sec_80_mhz_known = -1;
241 static int hf_radiotap_he_gi_known = -1;
242 static int hf_radiotap_he_num_ltf_symbols_known = -1;
243 static int hf_radiotap_he_pre_fec_padding_factor_known = -1;
244 static int hf_radiotap_he_txbf_known = -1;
245 static int hf_radiotap_he_pe_disambiguity_known = -1;
246 static int hf_radiotap_he_txop_known = -1;
247 static int hf_radiotap_he_midamble_periodicity_known = -1;
248 static int hf_radiotap_he_ru_allocation_offset = -1;
249 static int hf_radiotap_he_ru_allocation_offset_known = -1;
250 static int hf_radiotap_he_pri_sec_80_mhz = -1;
251 static int hf_radiotap_he_bss_color = -1;
252 static int hf_radiotap_he_bss_color_unknown = -1;
253 static int hf_radiotap_he_beam_change = -1;
254 static int hf_radiotap_he_beam_change_unknown = -1;
255 static int hf_radiotap_he_ul_dl = -1;
256 static int hf_radiotap_he_ul_dl_unknown = -1;
257 static int hf_radiotap_he_data_mcs = -1;
258 static int hf_radiotap_he_data_mcs_unknown = -1;
259 static int hf_radiotap_he_data_dcm = -1;
260 static int hf_radiotap_he_data_dcm_unknown = -1;
261 static int hf_radiotap_he_coding = -1;
262 static int hf_radiotap_he_coding_unknown = -1;
263 static int hf_radiotap_he_ldpc_extra_symbol_segment = -1;
264 static int hf_radiotap_he_ldpc_extra_symbol_segment_unknown = -1;
265 static int hf_radiotap_he_stbc = -1;
266 static int hf_radiotap_he_stbc_unknown = -1;
267 static int hf_radiotap_spatial_reuse = -1;
268 static int hf_radiotap_spatial_reuse_unknown = -1;
269 static int hf_radiotap_he_su_reserved = -1;
270 static int hf_radiotap_spatial_reuse_1 = -1;
271 static int hf_radiotap_spatial_reuse_1_unknown = -1;
272 static int hf_radiotap_spatial_reuse_2 = -1;
273 static int hf_radiotap_spatial_reuse_2_unknown = -1;
274 static int hf_radiotap_spatial_reuse_3 = -1;
275 static int hf_radiotap_spatial_reuse_3_unknown = -1;
276 static int hf_radiotap_spatial_reuse_4 = -1;
277 static int hf_radiotap_spatial_reuse_4_unknown = -1;
278 static int hf_radiotap_sta_id_user_captured = -1;
279 static int hf_radiotap_he_mu_reserved = -1;
280 static int hf_radiotap_data_bandwidth_ru_allocation = -1;
281 static int hf_radiotap_data_bandwidth_ru_allocation_unknown = -1;
282 static int hf_radiotap_gi = -1;
283 static int hf_radiotap_gi_unknown = -1;
284 static int hf_radiotap_ltf_symbol_size = -1;
285 static int hf_radiotap_ltf_symbol_size_unknown = -1;
286 static int hf_radiotap_num_ltf_symbols = -1;
287 static int hf_radiotap_num_ltf_symbols_unknown = -1;
288 static int hf_radiotap_d5_reserved_b11 = -1;
289 static int hf_radiotap_pre_fec_padding_factor = -1;
290 static int hf_radiotap_pre_fec_padding_factor_unknown = -1;
291 static int hf_radiotap_txbf = -1;
292 static int hf_radiotap_txbf_unknown = -1;
293 static int hf_radiotap_pe_disambiguity = -1;
294 static int hf_radiotap_pe_disambiguity_unknown = -1;
295 static int hf_radiotap_he_nsts = -1;
296 static int hf_radiotap_he_doppler_value = -1;
297 static int hf_radiotap_he_doppler_value_unknown = -1;
298 static int hf_radiotap_he_d6_reserved_00e0 = -1;
299 static int hf_radiotap_he_txop_value = -1;
300 static int hf_radiotap_he_txop_value_unknown = -1;
301 static int hf_radiotap_midamble_periodicity = -1;
302 static int hf_radiotap_midamble_periodicity_unknown = -1;
303 static int hf_radiotap_he_info_data_1 = -1;
304 static int hf_radiotap_he_info_data_2 = -1;
305 static int hf_radiotap_he_info_data_3 = -1;
306 static int hf_radiotap_he_info_data_4 = -1;
307 static int hf_radiotap_he_info_data_5 = -1;
308 static int hf_radiotap_he_info_data_6 = -1;
309 static int hf_radiotap_he_mu_sig_b_mcs = -1;
310 static int hf_radiotap_he_mu_sig_b_mcs_unknown = -1;
311 static int hf_radiotap_he_mu_sig_b_mcs_known = -1;
312 static int hf_radiotap_he_mu_sig_b_dcm = -1;
313 static int hf_radiotap_he_mu_sig_b_dcm_unknown = -1;
314 static int hf_radiotap_he_mu_sig_b_dcm_known = -1;
315 static int hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_known = -1;
316 static int hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_unknown = -1;
317 static int hf_radiotap_he_mu_chan1_rus_known = -1;
318 static int hf_radiotap_he_mu_chan1_rus_unknown = -1;
319 static int hf_radiotap_he_mu_chan2_rus_known = -1;
320 static int hf_radiotap_he_mu_chan2_rus_unknown = -1;
321 static int hf_radiotap_he_mu_reserved_f1_b10_b11 = -1;
322 static int hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_known = -1;
323 static int hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_unknown = -1;
324 static int hf_radiotap_he_mu_chan1_center_26_tone_ru_value = -1;
325 static int hf_radiotap_he_mu_sig_b_compression_known = -1;
326 static int hf_radiotap_he_mu_sig_b_compression_unknown = -1;
327 static int hf_radiotap_he_mu_sig_b_compression_from_sig_a = -1;
328 static int hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_known = -1;
329 static int hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_unknown = -1;
330 static int hf_radiotap_he_mu_info_flags_1 = -1;
331 static int hf_radiotap_he_mu_bw_from_bw_in_sig_a = -1;
332 static int hf_radiotap_he_mu_bw_from_bw_in_sig_a_unknown = -1;
333 static int hf_radiotap_he_mu_bw_from_bw_in_sig_a_known = -1;
334 static int hf_radiotap_he_mu_sig_b_syms_mu_mimo_users = -1;
335 static int hf_radiotap_he_mu_preamble_puncturing = -1;
336 static int hf_radiotap_he_mu_preamble_puncturing_unknown = -1;
337 static int hf_radiotap_he_mu_preamble_puncturing_known = -1;
338 static int hf_radiotap_he_mu_chan2_center_26_tone_ru_value = -1;
339 static int hf_radiotap_he_mu_reserved_f2_b12_b15 = -1;
340 static int hf_radiotap_he_mu_info_flags_2 = -1;
341 static int hf_radiotap_he_mu_chan1_rus_0 = -1;
342 static int hf_radiotap_he_mu_chan1_rus_0_unknown = -1;
343 static int hf_radiotap_he_mu_chan1_rus_1 = -1;
344 static int hf_radiotap_he_mu_chan1_rus_1_unknown = -1;
345 static int hf_radiotap_he_mu_chan1_rus_2 = -1;
346 static int hf_radiotap_he_mu_chan1_rus_2_unknown = -1;
347 static int hf_radiotap_he_mu_chan1_rus_3 = -1;
348 static int hf_radiotap_he_mu_chan1_rus_3_unknown = -1;
349 static int hf_radiotap_he_mu_chan2_rus_0 = -1;
350 static int hf_radiotap_he_mu_chan2_rus_0_unknown = -1;
351 static int hf_radiotap_he_mu_chan2_rus_1 = -1;
352 static int hf_radiotap_he_mu_chan2_rus_1_unknown = -1;
353 static int hf_radiotap_he_mu_chan2_rus_2 = -1;
354 static int hf_radiotap_he_mu_chan2_rus_2_unknown = -1;
355 static int hf_radiotap_he_mu_chan2_rus_3 = -1;
356 static int hf_radiotap_he_mu_chan2_rus_3_unknown = -1;
357
358 /* 0-length-psdu */
359 static int hf_radiotap_0_length_psdu_type = -1;
360
361 /* L-SIG */
362 static int hf_radiotap_l_sig_data_1 = -1;
363 static int hf_radiotap_l_sig_rate_known = -1;
364 static int hf_radiotap_l_sig_length_known = -1;
365 static int hf_radiotap_l_sig_reserved = -1;
366 static int hf_radiotap_l_sig_data_2 = -1;
367 static int hf_radiotap_l_sig_rate = -1;
368 static int hf_radiotap_l_sig_length = -1;
369
370 /* S1G */
371 static int hf_radiotap_s1g_known = -1;
372 static int hf_radiotap_s1g_s1g_ppdu_format_known = -1;
373 static int hf_radiotap_s1g_response_indication_known = -1;
374 static int hf_radiotap_s1g_guard_interval_known = -1;
375 static int hf_radiotap_s1g_nss_known = -1;
376 static int hf_radiotap_s1g_bandwidth_known = -1;
377 static int hf_radiotap_s1g_mcs_known = -1;
378 static int hf_radiotap_s1g_color_known = -1;
379 static int hf_radiotap_s1g_uplink_indication_known = -1;
380 static int hf_radiotap_s1g_reserved_1 = -1;
381 static int hf_radiotap_s1g_data_1 = -1;
382 static int hf_radiotap_s1g_s1g_ppdu_format = -1;
383 static int hf_radiotap_s1g_response_indication = -1;
384 static int hf_radiotap_s1g_reserved_2 = -1;
385 static int hf_radiotap_s1g_guard_interval = -1;
386 static int hf_radiotap_s1g_nss = -1;
387 static int hf_radiotap_s1g_bandwidth = -1;
388 static int hf_radiotap_s1g_mcs = -1;
389 static int hf_radiotap_s1g_data_2 = -1;
390 static int hf_radiotap_s1g_color = -1;
391 static int hf_radiotap_s1g_uplink_indication = -1;
392 static int hf_radiotap_s1g_rssi = -1;
393 static int hf_radiotap_s1g_reserved_3 = -1;
394
395 /* S1G NDP */
396 static int hf_radiotap_s1g_ndp_bytes = -1;
397 static int hf_radiotap_s1g_ndp_ctrl = -1;
398 static int hf_radiotap_s1g_ndp_mgmt = -1;
399 static int hf_radiotap_s1g_ndp_type_3bit = -1;
400 static int hf_radiotap_s1g_ndp_ack_1m = -1;
401 static int hf_radiotap_s1g_ndp_ack_1m_ack_id = -1;
402 static int hf_radiotap_s1g_ndp_ack_1m_more_data = -1;
403 static int hf_radiotap_s1g_ndp_ack_1m_idle_indication = -1;
404 static int hf_radiotap_s1g_ndp_ack_1m_duration = -1;
405 static int hf_radiotap_s1g_ndp_ack_1m_relayed_frame = -1;
406 static int hf_radiotap_s1g_ndp_ack_2m = -1;
407 static int hf_radiotap_s1g_ndp_ack_2m_ack_id = -1;
408 static int hf_radiotap_s1g_ndp_ack_2m_more_data = -1;
409 static int hf_radiotap_s1g_ndp_ack_2m_idle_indication = -1;
410 static int hf_radiotap_s1g_ndp_ack_2m_duration = -1;
411 static int hf_radiotap_s1g_ndp_ack_2m_relayed_frame = -1;
412 static int hf_radiotap_s1g_ndp_ack_2m_reserved = -1;
413 static int hf_radiotap_s1g_ndp_cts_1m = -1;
414 static int hf_radiotap_s1g_ndp_cts_cf_end_indic = -1;
415 static int hf_radiotap_s1g_ndp_cts_address_indic = -1;
416 static int hf_radiotap_s1g_ndp_cts_ra_partial_bssid = -1;
417 static int hf_radiotap_s1g_ndp_cts_duration_1m = -1;
418 static int hf_radiotap_s1g_ndp_cts_duration_2m = -1;
419 static int hf_radiotap_s1g_ndp_cts_early_sector_indic_1m = -1;
420 static int hf_radiotap_s1g_ndp_cts_2m = -1;
421 static int hf_radiotap_s1g_ndp_cts_early_sector_indic_2m = -1;
422 static int hf_radiotap_s1g_ndp_cts_bandwidth_indic_2m = -1;
423 static int hf_radiotap_s1g_ndp_cts_reserved = -1;
424 static int hf_radiotap_s1g_ndp_cf_end_1m = -1;
425 static int hf_radiotap_s1g_ndp_cf_end_partial_bssid = -1;
426 static int hf_radiotap_s1g_ndp_cf_end_duration_1m = -1;
427 static int hf_radiotap_s1g_ndp_cf_end_reserved_1m = -1;
428 static int hf_radiotap_s1g_ndp_cf_end_2m = -1;
429 static int hf_radiotap_s1g_ndp_cf_end_duration_2m = -1;
430 static int hf_radiotap_s1g_ndp_cf_end_reserved_2m = -1;
431 static int hf_radiotap_s1g_ndp_ps_poll_1m = -1;
432 static int hf_radiotap_s1g_ndp_ps_poll_ra = -1;
433 static int hf_radiotap_s1g_ndp_ps_poll_ta = -1;
434 static int hf_radiotap_s1g_ndp_ps_poll_preferred_mcs_1m = -1;
435 static int hf_radiotap_s1g_ndp_ps_poll_udi_1m = -1;
436 static int hf_radiotap_s1g_ndp_ps_poll_2m = -1;
437 static int hf_radiotap_s1g_ndp_ps_poll_preferred_mcs_2m = -1;
438 static int hf_radiotap_s1g_ndp_ps_poll_udi_2m = -1;
439 static int hf_radiotap_s1g_ndp_ps_poll_ack_1m = -1;
440 static int hf_radiotap_s1g_ndp_ps_poll_ack_id = -1;
441 static int hf_radiotap_s1g_ndp_ps_poll_ack_more_data = -1;
442 static int hf_radiotap_s1g_ndp_ps_poll_ack_idle_indication = -1;
443 static int hf_radiotap_s1g_ndp_ps_poll_ack_duration_1m = -1;
444 static int hf_radiotap_s1g_ndp_ps_poll_ack_reserved_1m = -1;
445 static int hf_radiotap_s1g_ndp_ps_poll_ack_2m = -1;
446 static int hf_radiotap_s1g_ndp_ps_poll_ack_id_2m = -1;
447 static int hf_radiotap_s1g_ndp_ps_poll_ack_more_data_2m = -1;
448 static int hf_radiotap_s1g_ndp_ps_poll_ack_idle_indication_2m = -1;
449 static int hf_radiotap_s1g_ndp_ps_poll_ack_duration_2m = -1;
450 static int hf_radiotap_s1g_ndp_ps_poll_ack_reserved_2m = -1;
451 static int hf_radiotap_s1g_ndp_block_ack_1m = -1;
452 static int hf_radiotap_s1g_ndp_block_ack_id_1m = -1;
453 static int hf_radiotap_s1g_ndp_block_ack_starting_sequence_control_1m = -1;
454 static int hf_radiotap_s1g_ndp_block_ack_bitmap_1m = -1;
455 static int hf_radiotap_s1g_ndp_block_ack_unused_1m = -1;
456 static int hf_radiotap_s1g_ndp_block_ack_2m = -1;
457 static int hf_radiotap_s1g_ndp_block_ack_id_2m = -1;
458 static int hf_radiotap_s1g_ndp_block_ack_starting_sequence_control_2m = -1;
459 static int hf_radiotap_s1g_ndp_block_ack_bitmap_2m = -1;
460 static int hf_radiotap_s1g_ndp_beamforming_report_poll = -1;
461 static int hf_radiotap_s1g_ndp_beamforming_ap_address = -1;
462 static int hf_radiotap_s1g_ndp_beamforming_non_ap_sta_address = -1;
463 static int hf_radiotap_s1g_ndp_beamforming_feedback_segment_bitmap = -1;
464 static int hf_radiotap_s1g_ndp_beamforming_reserved = -1;
465 static int hf_radiotap_s1g_ndp_paging_1m = -1;
466 static int hf_radiotap_s1g_ndp_paging_p_id = -1;
467 static int hf_radiotap_s1g_ndp_paging_apdi_partial_aid = -1;
468 static int hf_radiotap_s1g_ndp_paging_direction = -1;
469 static int hf_radiotap_s1g_ndp_paging_reserved_1m = -1;
470 static int hf_radiotap_s1g_ndp_paging_2m = -1;
471 static int hf_radiotap_s1g_ndp_paging_reserved_2m = -1;
472 static int hf_radiotap_s1g_ndp_probe_1m = -1;
473 static int hf_radiotap_s1g_ndp_probe_cssid_ano_present = -1;
474 static int hf_radiotap_s1g_ndp_probe_1m_cssid_ano = -1;
475 static int hf_radiotap_s1g_ndp_probe_1m_requested_response_type = -1;
476 static int hf_radiotap_s1g_ndp_probe_1m_reserved = -1;
477 static int hf_radiotap_s1g_ndp_probe_2m = -1;
478 static int hf_radiotap_s1g_ndp_probe_2m_cssid_ano = -1;
479 static int hf_radiotap_s1g_ndp_probe_2m_requested_response_type = -1;
480 static int hf_radiotap_s1g_ndp_1m_unused = -1;
481 static int hf_radiotap_s1g_ndp_2m_unused = -1;
482 static int hf_radiotap_s1g_ndp_bw = -1;
483
484 static gint ett_radiotap = -1;
485 static gint ett_radiotap_tlv = -1;
486 static gint ett_radiotap_present = -1;
487 static gint ett_radiotap_present_word = -1;
488 static gint ett_radiotap_flags = -1;
489 static gint ett_radiotap_rxflags = -1;
490 static gint ett_radiotap_txflags = -1;
491 static gint ett_radiotap_channel_flags = -1;
492 static gint ett_radiotap_xchannel_flags = -1;
493 static gint ett_radiotap_vendor = -1;
494 static gint ett_radiotap_mcs = -1;
495 static gint ett_radiotap_mcs_known = -1;
496 static gint ett_radiotap_ampdu = -1;
497 static gint ett_radiotap_ampdu_flags = -1;
498 static gint ett_radiotap_vht = -1;
499 static gint ett_radiotap_vht_known = -1;
500 static gint ett_radiotap_vht_user = -1;
501 static gint ett_radiotap_timestamp = -1;
502 static gint ett_radiotap_timestamp_flags = -1;
503 static gint ett_radiotap_he_info = -1;
504 static gint ett_radiotap_he_info_data_1 = -1;
505 static gint ett_radiotap_he_info_data_2 = -1;
506 static gint ett_radiotap_he_info_data_3 = -1;
507 static gint ett_radiotap_he_info_data_4 = -1;
508 static gint ett_radiotap_he_info_data_5 = -1;
509 static gint ett_radiotap_he_info_data_6 = -1;
510 static gint ett_radiotap_he_mu_info = -1;
511 static gint ett_radiotap_he_mu_info_flags_1 = -1;
512 static gint ett_radiotap_he_mu_info_flags_2 = -1;
513 static gint ett_radiotap_he_mu_chan_rus = -1;
514 static gint ett_radiotap_0_length_psdu = -1;
515 static gint ett_radiotap_l_sig = -1;
516 static gint ett_radiotap_l_sig_data_1 = -1;
517 static gint ett_radiotap_l_sig_data_2 = -1;
518 static gint ett_radiotap_unknown_tlv = -1;
519 /* S1G */
520 static gint ett_radiotap_s1g = -1;
521 static gint ett_radiotap_s1g_known = -1;
522 static gint ett_radiotap_s1g_data_1 = -1;
523 static gint ett_radiotap_s1g_data_2 = -1;
524
525 /* S1G NDP */
526 static gint ett_s1g_ndp = -1;
527 static gint ett_s1g_ndp_ack = -1;
528 static gint ett_s1g_ndp_cts = -1;
529 static gint ett_s1g_ndp_cf_end = -1;
530 static gint ett_s1g_ndp_ps_poll = -1;
531 static gint ett_s1g_ndp_ps_poll_ack = -1;
532 static gint ett_s1g_ndp_block_ack = -1;
533 static gint ett_s1g_ndp_beamforming_report_poll = -1;
534 static gint ett_s1g_ndp_paging = -1;
535 static gint ett_s1g_ndp_probe = -1;
536
537 static expert_field ei_radiotap_invalid_header_length = EI_INIT;
538 static expert_field ei_radiotap_data_past_header = EI_INIT;
539 static expert_field ei_radiotap_present = EI_INIT;
540 static expert_field ei_radiotap_invalid_data_rate = EI_INIT;
541
542 static dissector_handle_t ieee80211_radio_handle;
543
544 static capture_dissector_handle_t ieee80211_cap_handle;
545 static capture_dissector_handle_t ieee80211_datapad_cap_handle;
546
547 static dissector_table_t vendor_dissector_table;
548
549 /* Settings */
550 static gboolean radiotap_bit14_fcs = FALSE;
551 static gboolean radiotap_interpret_high_rates_as_mcs = FALSE;
552
553 #define USE_FCS_BIT 0
554 #define ASSUME_FCS_PRESENT 1
555 #define ASSUME_FCS_ABSENT 2
556 static const enum_val_t fcs_handling[] = {
557 { "use_fcs_bit", "Use the FCS bit", USE_FCS_BIT },
558 { "assume_fcs_present", "Assume all packets have an FCS at the end", ASSUME_FCS_PRESENT },
559 { "assume_fcs_absent", "Assume all packets don't have an FCS at the end", ASSUME_FCS_ABSENT },
560 { NULL, NULL, 0 }
561 };
562 static int radiotap_fcs_handling = USE_FCS_BIT;
563
564 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
565 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
566 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
567 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
568 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
569 #define BIT(n) (1U << n)
570
571 /* not officially defined (yet) */
572 #define IEEE80211_RADIOTAP_F_SHORTGI 0x80
573 #define IEEE80211_RADIOTAP_XCHANNEL 18
574
575 /* Official specifcation:
576 *
577 * http://www.radiotap.org/
578 *
579 * Unofficial and historical specifications:
580 * http://madwifi-project.org/wiki/DevDocs/RadiotapHeader
581 * NetBSD's ieee80211_radiotap.h file
582 */
583
584 /*
585 * Useful combinations of channel characteristics.
586 */
587 #define IEEE80211_CHAN_FHSS \
588 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
589 #define IEEE80211_CHAN_DSSS \
590 (IEEE80211_CHAN_2GHZ)
591 #define IEEE80211_CHAN_A \
592 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
593 #define IEEE80211_CHAN_B \
594 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
595 #define IEEE80211_CHAN_PUREG \
596 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
597 #define IEEE80211_CHAN_G \
598 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
599 #define IEEE80211_CHAN_108A \
600 (IEEE80211_CHAN_A | IEEE80211_CHAN_TURBO)
601 #define IEEE80211_CHAN_108G \
602 (IEEE80211_CHAN_G | IEEE80211_CHAN_TURBO)
603 #define IEEE80211_CHAN_108PUREG \
604 (IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO)
605 #define IEEE80211_CHAN_ST \
606 (IEEE80211_CHAN_108A | IEEE80211_CHAN_STURBO)
607
608 #define MAX_MCS_VHT_INDEX 9
609 #define MAX_VHT_NSS 8
610
611 /*
612 * Maps a VHT bandwidth index to ieee80211_vhtinfo.rates index.
613 */
614 static const int ieee80211_vht_bw2rate_index[] = {
615 /* 20Mhz total */ 0,
616 /* 40Mhz total */ 1, 0, 0,
617 /* 80Mhz total */ 2, 1, 1, 0, 0, 0, 0,
618 /* 160Mhz total */ 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
619 };
620
621 struct mcs_vht_valid {
622 gboolean valid[4][MAX_VHT_NSS]; /* indexed by bandwidth and NSS-1 */
623 };
624
625 static const struct mcs_vht_valid ieee80211_vhtvalid[MAX_MCS_VHT_INDEX+1] = {
626 /* MCS 0 */
627 {
628 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
629 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
630 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
631 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
632 }
633 },
634 /* MCS 1 */
635 {
636 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
637 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
638 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
639 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
640 }
641 },
642 /* MCS 2 */
643 {
644 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
645 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
646 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
647 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
648 }
649 },
650 /* MCS 3 */
651 {
652 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
653 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
654 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
655 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
656 }
657 },
658 /* MCS 4 */
659 {
660 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
661 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
662 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
663 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
664 }
665 },
666 /* MCS 5 */
667 {
668 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
669 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
670 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
671 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
672 }
673 },
674 /* MCS 6 */
675 {
676 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
677 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
678 /* 80 Mhz */ { TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE },
679 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
680 }
681 },
682 /* MCS 7 */
683 {
684 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
685 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
686 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
687 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
688 }
689 },
690 /* MCS 8 */
691 {
692 { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
693 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
694 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
695 /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
696 }
697 },
698 /* MCS 9 */
699 {
700 { /* 20 Mhz */ { FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE },
701 /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
702 /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE },
703 /* 160 Mhz */ { TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE },
704 }
705 }
706 };
707
708 struct mcs_vht_info {
709 const char *modulation;
710 const char *coding_rate;
711 float rates[4][2]; /* indexed by bandwidth and GI length */
712 };
713
714 static const struct mcs_vht_info ieee80211_vhtinfo[MAX_MCS_VHT_INDEX+1] = {
715 /* MCS 0 */
716 { "BPSK", "1/2",
717 { /* 20 Mhz */ { 6.5f, /* SGI */ 7.2f, },
718 /* 40 Mhz */ { 13.5f, /* SGI */ 15.0f, },
719 /* 80 Mhz */ { 29.3f, /* SGI */ 32.5f, },
720 /* 160 Mhz */ { 58.5f, /* SGI */ 65.0f, }
721 }
722 },
723 /* MCS 1 */
724 { "QPSK", "1/2",
725 { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, },
726 /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, },
727 /* 80 Mhz */ { 58.5f, /* SGI */ 65.0f, },
728 /* 160 Mhz */ { 117.0f, /* SGI */ 130.0f, }
729 }
730 },
731 /* MCS 2 */
732 { "QPSK", "3/4",
733 { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, },
734 /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, },
735 /* 80 Mhz */ { 87.8f, /* SGI */ 97.5f, },
736 /* 160 Mhz */ { 175.5f, /* SGI */ 195.0f, }
737 }
738 },
739 /* MCS 3 */
740 { "16-QAM", "1/2",
741 { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, },
742 /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, },
743 /* 80 Mhz */ { 117.0f, /* SGI */ 130.0f, },
744 /* 160 Mhz */ { 234.0f, /* SGI */ 260.0f, }
745 }
746 },
747 /* MCS 4 */
748 { "16-QAM", "3/4",
749 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, },
750 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, },
751 /* 80 Mhz */ { 175.5f, /* SGI */ 195.0f, },
752 /* 160 Mhz */ { 351.0f, /* SGI */ 390.0f, }
753 }
754 },
755 /* MCS 5 */
756 { "64-QAM", "2/3",
757 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, },
758 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, },
759 /* 80 Mhz */ { 234.0f, /* SGI */ 260.0f, },
760 /* 160 Mhz */ { 468.0f, /* SGI */ 520.0f, }
761 }
762 },
763 /* MCS 6 */
764 { "64-QAM", "3/4",
765 { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, },
766 /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, },
767 /* 80 Mhz */ { 263.3f, /* SGI */ 292.5f, },
768 /* 160 Mhz */ { 526.5f, /* SGI */ 585.0f, }
769 }
770 },
771 /* MCS 7 */
772 { "64-QAM", "5/6",
773 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, },
774 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, },
775 /* 80 Mhz */ { 292.5f, /* SGI */ 325.0f, },
776 /* 160 Mhz */ { 585.0f, /* SGI */ 650.0f, }
777 }
778 },
779 /* MCS 8 */
780 { "256-QAM", "3/4",
781 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
782 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
783 /* 80 Mhz */ { 351.0f, /* SGI */ 390.0f, },
784 /* 160 Mhz */ { 702.0f, /* SGI */ 780.0f, }
785 }
786 },
787 /* MCS 9 */
788 { "256-QAM", "5/6",
789 { /* 20 Mhz */ { 86.7f, /* SGI */ 96.3f, },
790 /* 40 Mhz */ { 180.0f, /* SGI */ 200.0f, },
791 /* 80 Mhz */ { 390.0f, /* SGI */ 433.3f, },
792 /* 160 Mhz */ { 780.0f, /* SGI */ 866.7f, }
793 }
794 }
795 };
796
797 /* In order by value */
798 static const value_string vht_bandwidth[] = {
799 { IEEE80211_RADIOTAP_VHT_BW_20, "20 MHz" },
800 { IEEE80211_RADIOTAP_VHT_BW_40, "40 MHz" },
801 { IEEE80211_RADIOTAP_VHT_BW_20L, "20 MHz lower" },
802 { IEEE80211_RADIOTAP_VHT_BW_20U, "20 MHz upper" },
803 { IEEE80211_RADIOTAP_VHT_BW_80, "80 MHz" },
804 { IEEE80211_RADIOTAP_VHT_BW_40L, "40 MHz lower" },
805 { IEEE80211_RADIOTAP_VHT_BW_40U, "40 MHz upper" },
806 { IEEE80211_RADIOTAP_VHT_BW_20LL, "20 MHz, channel 1/4" },
807 { IEEE80211_RADIOTAP_VHT_BW_20LU, "20 MHz, channel 2/4" },
808 { IEEE80211_RADIOTAP_VHT_BW_20UL, "20 MHz, channel 3/4" },
809 { IEEE80211_RADIOTAP_VHT_BW_20UU, "20 MHz, channel 4/4" },
810 { IEEE80211_RADIOTAP_VHT_BW_160, "160 MHz" },
811 { IEEE80211_RADIOTAP_VHT_BW_80L, "80 MHz lower" },
812 { IEEE80211_RADIOTAP_VHT_BW_80U, "80 MHz upper" },
813 { IEEE80211_RADIOTAP_VHT_BW_40LL, "40 MHz, channel 1/4" },
814 { IEEE80211_RADIOTAP_VHT_BW_40LU, "40 MHz, channel 2/4" },
815 { IEEE80211_RADIOTAP_VHT_BW_40UL, "40 MHz, channel 3/4" },
816 { IEEE80211_RADIOTAP_VHT_BW_40UU, "40 MHz, channel 4/4" },
817 { IEEE80211_RADIOTAP_VHT_BW_20LLL, "20 MHz, channel 1/8" },
818 { IEEE80211_RADIOTAP_VHT_BW_20LLU, "20 MHz, channel 2/8" },
819 { IEEE80211_RADIOTAP_VHT_BW_20LUL, "20 MHz, channel 3/8" },
820 { IEEE80211_RADIOTAP_VHT_BW_20LUU, "20 MHz, channel 4/8" },
821 { IEEE80211_RADIOTAP_VHT_BW_20ULL, "20 MHz, channel 5/8" },
822 { IEEE80211_RADIOTAP_VHT_BW_20ULU, "20 MHz, channel 6/8" },
823 { IEEE80211_RADIOTAP_VHT_BW_20UUL, "20 MHz, channel 7/8" },
824 { IEEE80211_RADIOTAP_VHT_BW_20UUU, "20 MHz, channel 8/8" },
825 { 0, NULL }
826 };
827 static value_string_ext vht_bandwidth_ext = VALUE_STRING_EXT_INIT(vht_bandwidth);
828
829 static const value_string mcs_bandwidth[] = {
830 { IEEE80211_RADIOTAP_MCS_BW_20, "20 MHz" },
831 { IEEE80211_RADIOTAP_MCS_BW_40, "40 MHz" },
832 { IEEE80211_RADIOTAP_MCS_BW_20L, "20 MHz lower" },
833 { IEEE80211_RADIOTAP_MCS_BW_20U, "20 MHz upper" },
834 {0, NULL}
835 };
836
837 static const value_string mcs_format[] = {
838 { 0, "mixed" },
839 { 1, "greenfield" },
840 {0, NULL},
841 };
842
843 static const value_string mcs_fec[] = {
844 { 0, "BCC" },
845 { 1, "LDPC" },
846 {0, NULL}
847 };
848
849 static const value_string mcs_gi[] = {
850 { 0, "long" },
851 { 1, "short" },
852 {0, NULL}
853 };
854
855 static const true_false_string preamble_type = {
856 "Short",
857 "Long",
858 };
859
860 static const value_string timestamp_unit[] = {
861 { IEEE80211_RADIOTAP_TS_UNIT_MSEC, "msec" },
862 { IEEE80211_RADIOTAP_TS_UNIT_USEC, "usec" },
863 { IEEE80211_RADIOTAP_TS_UNIT_NSEC, "nsec" },
864 { 0, NULL }
865 };
866
867 static const value_string timestamp_spos[] = {
868 { IEEE80211_RADIOTAP_TS_SPOS_MPDU, "first MPDU bit/symbol" },
869 { IEEE80211_RADIOTAP_TS_SPOS_ACQ, "signal acquisition" },
870 { IEEE80211_RADIOTAP_TS_SPOS_EOF, "end of frame" },
871 { IEEE80211_RADIOTAP_TS_SPOS_UNDEF, "undefined" },
872 { 0, NULL }
873 };
874
875 /* S1G */
876 static const value_string s1g_ppdu_format[] = {
877 { 0, "S1G 1M" },
878 { 1, "S1G Short" },
879 { 2, "S1G Long" },
880 { 0, NULL},
881 };
882
883 static const value_string s1g_response_indication[] = {
884 { 0, "No response" },
885 { 1, "NDP response" },
886 { 2, "Normal response" },
887 { 3, "Long response" },
888 { 0, NULL},
889 };
890
891 static const value_string s1g_guard_interval[] = {
892 { 0, "Long GI" },
893 { 1, "Short GI" },
894 { 0, NULL},
895 };
896
897 static const value_string s1g_nss[] = {
898 { 0, "1" },
899 { 1, "2" },
900 { 2, "3" },
901 { 3, "4" },
902 { 0, NULL},
903 };
904
905 static const value_string s1g_bandwidth[] = {
906 { 0, "1MHz channel" },
907 { 1, "2MHz channel" },
908 { 2, "4MHz channel" },
909 { 3, "8MHz channel" },
910 { 4, "16MHz channel" },
911 { 0, NULL},
912 };
913
914 static const value_string s1g_mcs[] = {
915 { 0, "0" },
916 { 1, "1" },
917 { 2, "2" },
918 { 3, "3" },
919 { 4, "4" },
920 { 5, "5" },
921 { 6, "6" },
922 { 7, "7" },
923 { 8, "8" },
924 { 9, "9" },
925 { 10, "10" },
926 { 0, NULL},
927 };
928
929 static const value_string s1g_color[] = {
930 { 0, "0" },
931 { 1, "1" },
932 { 2, "2" },
933 { 3, "3" },
934 { 4, "4" },
935 { 5, "5" },
936 { 6, "6" },
937 { 7, "7" },
938 { 0, NULL},
939 };
940
941 /*
942 * The NetBSD ieee80211_radiotap man page
943 * (http://netbsd.gw.com/cgi-bin/man-cgi?ieee80211_radiotap+9+NetBSD-current)
944 * says:
945 *
946 * Radiotap capture fields must be naturally aligned. That is, 16-, 32-,
947 * and 64-bit fields must begin on 16-, 32-, and 64-bit boundaries, respec-
948 * tively. In this way, drivers can avoid unaligned accesses to radiotap
949 * capture fields. radiotap-compliant drivers must insert padding before a
950 * capture field to ensure its natural alignment. radiotap-compliant packet
951 * dissectors, such as tcpdump(8), expect the padding.
952 */
953
954 static gboolean
capture_radiotap(const guchar * pd,int offset,int len,capture_packet_info_t * cpinfo,const union wtap_pseudo_header * pseudo_header _U_)955 capture_radiotap(const guchar * pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
956 {
957 guint16 it_len;
958 guint32 present, xpresent;
959 guint8 rflags;
960 const struct ieee80211_radiotap_header *hdr;
961
962 if (!BYTES_ARE_IN_FRAME(offset, len,
963 sizeof(struct ieee80211_radiotap_header))) {
964 return FALSE;
965 }
966 hdr = (const struct ieee80211_radiotap_header *)pd;
967 it_len = pletoh16(&hdr->it_len);
968 if (!BYTES_ARE_IN_FRAME(offset, len, it_len))
969 return FALSE;
970
971 if (it_len > len) {
972 /* Header length is bigger than total packet length */
973 return FALSE;
974 }
975
976 if (it_len < sizeof(struct ieee80211_radiotap_header)) {
977 /* Header length is shorter than fixed-length portion of header */
978 return FALSE;
979 }
980
981 present = pletoh32(&hdr->it_present);
982 offset += (int)sizeof(struct ieee80211_radiotap_header);
983 it_len -= (int)sizeof(struct ieee80211_radiotap_header);
984
985 /* skip over other present bitmaps */
986 xpresent = present;
987 while (xpresent & BIT(IEEE80211_RADIOTAP_EXT)) {
988 if (!BYTES_ARE_IN_FRAME(offset, 4, it_len)) {
989 return FALSE;
990 }
991 xpresent = pletoh32(pd + offset);
992 offset += 4;
993 it_len -= 4;
994 }
995
996 rflags = 0;
997
998 /*
999 * IEEE80211_RADIOTAP_TSFT is the lowest-order bit,
1000 * just skip over it.
1001 */
1002 if (present & BIT(IEEE80211_RADIOTAP_TSFT)) {
1003 /* align it properly */
1004 if (offset & 7) {
1005 int pad = 8 - (offset & 7);
1006 offset += pad;
1007 it_len -= pad;
1008 }
1009
1010 if (it_len < 8) {
1011 /* No room in header for this field. */
1012 return FALSE;
1013 }
1014 /* That field is present, and it's 8 bytes long. */
1015 offset += 8;
1016 it_len -= 8;
1017 }
1018
1019 /*
1020 * IEEE80211_RADIOTAP_FLAGS is the next bit.
1021 */
1022 if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
1023 if (it_len < 1) {
1024 /* No room in header for this field. */
1025 return FALSE;
1026 }
1027 /* That field is present; fetch it. */
1028 if (!BYTES_ARE_IN_FRAME(offset, len, 1)) {
1029 return FALSE;
1030 }
1031 rflags = pd[offset];
1032 }
1033
1034 /* 802.11 header follows */
1035 if (rflags & IEEE80211_RADIOTAP_F_DATAPAD)
1036 return call_capture_dissector(ieee80211_datapad_cap_handle, pd, offset + it_len, len, cpinfo, pseudo_header);
1037
1038 return call_capture_dissector(ieee80211_cap_handle, pd, offset + it_len, len, cpinfo, pseudo_header);
1039 }
1040
1041 static const true_false_string tfs_known_unknown = {
1042 "Known",
1043 "Unknown"
1044 };
1045
1046 static int * const data1_headers[] = {
1047 &hf_radiotap_he_ppdu_format,
1048 &hf_radiotap_he_bss_color_known,
1049 &hf_radiotap_he_beam_change_known,
1050 &hf_radiotap_he_ul_dl_known,
1051 &hf_radiotap_he_data_mcs_known,
1052 &hf_radiotap_he_data_dcm_known,
1053 &hf_radiotap_he_coding_known,
1054 &hf_radiotap_he_ldpc_extra_symbol_segment_known,
1055 &hf_radiotap_he_stbc_known,
1056 &hf_radiotap_he_spatial_reuse_1_known,
1057 &hf_radiotap_he_spatial_reuse_2_known,
1058 &hf_radiotap_he_spatial_reuse_3_known,
1059 &hf_radiotap_he_spatial_reuse_4_known,
1060 &hf_radiotap_he_data_bw_ru_allocation_known,
1061 &hf_radiotap_he_doppler_known,
1062 NULL
1063 };
1064
1065 static const value_string he_pdu_format_vals[] = {
1066 { IEEE80211_RADIOTAP_HE_PPDU_FORMAT_HE_SU, "HE_SU" },
1067 { IEEE80211_RADIOTAP_HE_PPDU_FORMAT_HE_EXT_SU, "HE_EXT_SU" },
1068 { IEEE80211_RADIOTAP_HE_PPDU_FORMAT_HE_MU, "HE_MU" },
1069 { IEEE80211_RADIOTAP_HE_PPDU_FORMAT_HE_TRIG, "HE_TRIG" },
1070 { 0, NULL }
1071 };
1072
1073 static int * const data2_headers[] = {
1074 &hf_radiotap_he_pri_sec_80_mhz_known,
1075 &hf_radiotap_he_gi_known,
1076 &hf_radiotap_he_num_ltf_symbols_known,
1077 &hf_radiotap_he_pre_fec_padding_factor_known,
1078 &hf_radiotap_he_txbf_known,
1079 &hf_radiotap_he_pe_disambiguity_known,
1080 &hf_radiotap_he_txop_known,
1081 &hf_radiotap_he_midamble_periodicity_known,
1082 &hf_radiotap_he_ru_allocation_offset,
1083 &hf_radiotap_he_ru_allocation_offset_known,
1084 &hf_radiotap_he_pri_sec_80_mhz,
1085 NULL
1086 };
1087
1088 static const true_false_string tfs_pri_sec_80_mhz = {
1089 "secondary",
1090 "primary"
1091 };
1092
1093 static const value_string he_coding_vals[] = {
1094 { 0, "BCC" },
1095 { 1, "LDPC" },
1096 { 0, NULL }
1097 };
1098
1099 static const value_string he_data_bw_ru_alloc_vals[] = {
1100 { 0, "20" },
1101 { 1, "40" },
1102 { 2, "80" },
1103 { 3, "160/80+80" },
1104 { 4, "26-tone RU" },
1105 { 5, "52-tone RU" },
1106 { 6, "106-tone RU" },
1107 { 7, "242-tone RU" },
1108 { 8, "484-tone RU" },
1109 { 9, "996-tone RU" },
1110 { 10, "2x996-tone RU" },
1111 { 11, "reserved" },
1112 { 12, "reserved" },
1113 { 13, "reserved" },
1114 { 14, "reserved" },
1115 { 15, "reserved" },
1116 { 0, NULL }
1117 };
1118
1119 static const value_string he_gi_vals[] = {
1120 { 0, "0.8us" },
1121 { 1, "1.6us" },
1122 { 2, "3.2us" },
1123 { 3, "reserved" },
1124 { 0, NULL }
1125 };
1126
1127 static const value_string he_ltf_symbol_size_vals[] = {
1128 { 0, "unknown" },
1129 { 1, "1x" },
1130 { 2, "2x" },
1131 { 3, "4x" },
1132 { 0, NULL }
1133 };
1134
1135 static const value_string he_num_ltf_symbols_vals[] = {
1136 { 0, "1x" },
1137 { 1, "2x" },
1138 { 2, "4x" },
1139 { 3, "6x" },
1140 { 4, "8x" },
1141 { 5, "reserved" },
1142 { 6, "reserved" },
1143 { 7, "reserved" },
1144 { 0, NULL }
1145 };
1146
1147 static const value_string he_nsts_vals[] = {
1148 { 0, "Unknown" },
1149 { 1, "1 space-time stream" },
1150 { 2, "2 space-time streams" },
1151 { 3, "3 space-time streams" },
1152 { 4, "4 space-time streams" },
1153 { 5, "5 space-time streams" },
1154 { 6, "6 space-time streams" },
1155 { 7, "7 space-time streams" },
1156 { 8, "8 space-time streams" },
1157 { 9, "9 space-time streams" },
1158 { 10, "10 space-time streams" },
1159 { 11, "11 space-time streams" },
1160 { 12, "12 space-time streams" },
1161 { 13, "13 space-time streams" },
1162 { 14, "14 space-time streams" },
1163 { 15, "15 space-time streams" },
1164 { 0, NULL }
1165 };
1166
1167 static const value_string he_midamble_periodicity_vals[] = {
1168 { 0, "10" },
1169 { 1, "20" },
1170 { 0, NULL }
1171 };
1172
1173 static void
dissect_radiotap_he_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11ax * info_11ax)1174 dissect_radiotap_he_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1175 int offset, struct ieee_802_11ax *info_11ax)
1176 {
1177 guint16 ppdu_format = tvb_get_letohs(tvb, offset) &
1178 IEEE80211_RADIOTAP_HE_PPDU_FORMAT_MASK;
1179 proto_tree *he_info_tree = NULL;
1180 gboolean bss_color_known = FALSE;
1181 gboolean beam_change_known = FALSE;
1182 gboolean ul_dl_known = FALSE;
1183 gboolean data_mcs_known = FALSE;
1184 gboolean data_dcm_known = FALSE;
1185 gboolean coding_known = FALSE;
1186 gboolean ldpc_extra_symbol_segment_known = FALSE;
1187 gboolean stbc_known = FALSE;
1188 gboolean spatial_reuse_1_known = FALSE;
1189 gboolean spatial_reuse_2_known = FALSE;
1190 gboolean spatial_reuse_3_known = FALSE;
1191 gboolean spatial_reuse_4_known = FALSE;
1192 gboolean data_bw_ru_alloc_known = FALSE;
1193 gboolean doppler_known = FALSE;
1194 gboolean gi_known = FALSE;
1195 gboolean num_ltf_symbols_known = FALSE;
1196 gboolean ltf_symbol_size_known = FALSE;
1197 gboolean pre_fec_padding_factor_known = FALSE;
1198 gboolean txbf_known = FALSE;
1199 gboolean pe_disambiguity_known = FALSE;
1200 gboolean txop_known = FALSE;
1201 gboolean midamble_periodicity_known = FALSE;
1202 guint16 data1 = tvb_get_letohs(tvb, offset);
1203 guint16 data2 = 0;
1204 guint16 data3 = 0;
1205 guint16 data5 = 0;
1206 guint16 data6 = 0;
1207
1208 guint8 ltf_symbol_size = 0;
1209
1210 /*
1211 * This is set differetly for each packet, depending on
1212 * which values in data3 are known. It thus will not
1213 * work if it's static.
1214 */
1215 int *data3_headers[] = {
1216 &hf_radiotap_he_bss_color,
1217 &hf_radiotap_he_beam_change,
1218 &hf_radiotap_he_ul_dl,
1219 &hf_radiotap_he_data_mcs,
1220 &hf_radiotap_he_data_dcm,
1221 &hf_radiotap_he_coding,
1222 &hf_radiotap_he_ldpc_extra_symbol_segment,
1223 &hf_radiotap_he_stbc,
1224 NULL
1225 };
1226
1227 /*
1228 * Same story but for data4.
1229 */
1230 int *data4_he_trig_headers[] = {
1231 &hf_radiotap_spatial_reuse_1,
1232 &hf_radiotap_spatial_reuse_2,
1233 &hf_radiotap_spatial_reuse_3,
1234 &hf_radiotap_spatial_reuse_4,
1235 NULL
1236 };
1237 int *data4_he_su_and_he_ext_su_headers[] = {
1238 &hf_radiotap_spatial_reuse,
1239 &hf_radiotap_he_su_reserved,
1240 NULL
1241 };
1242 int *data4_he_mu_headers[] = {
1243 &hf_radiotap_spatial_reuse,
1244 &hf_radiotap_sta_id_user_captured,
1245 &hf_radiotap_he_mu_reserved,
1246 NULL
1247 };
1248 int *data5_headers[] = {
1249 &hf_radiotap_data_bandwidth_ru_allocation,
1250 &hf_radiotap_gi,
1251 &hf_radiotap_ltf_symbol_size,
1252 &hf_radiotap_num_ltf_symbols,
1253 &hf_radiotap_d5_reserved_b11,
1254 &hf_radiotap_pre_fec_padding_factor,
1255 &hf_radiotap_txbf,
1256 &hf_radiotap_pe_disambiguity,
1257 NULL
1258 };
1259
1260 /*
1261 * Same story, but for data6.
1262 */
1263 int *data6_headers[] = {
1264 &hf_radiotap_he_nsts,
1265 &hf_radiotap_he_doppler_value,
1266 &hf_radiotap_he_d6_reserved_00e0,
1267 &hf_radiotap_he_txop_value,
1268 &hf_radiotap_midamble_periodicity,
1269 NULL
1270 };
1271
1272 /*
1273 * Determine what is known.
1274 */
1275 if (data1 & IEEE80211_RADIOTAP_HE_BSS_COLOR_KNOWN)
1276 bss_color_known = TRUE;
1277 if (data1 & IEEE80211_RADIOTAP_HE_BEAM_CHANGE_KNOWN)
1278 beam_change_known = TRUE;
1279 if (data1 & IEEE80211_RADIOTAP_HE_UL_DL_KNOWN)
1280 ul_dl_known = TRUE;
1281 if (data1 & IEEE80211_RADIOTAP_HE_DATA_MCS_KNOWN)
1282 data_mcs_known = TRUE;
1283 if (data1 & IEEE80211_RADIOTAP_HE_DATA_DCM_KNOWN)
1284 data_dcm_known = TRUE;
1285 if (data1 & IEEE80211_RADIOTAP_HE_CODING_KNOWN)
1286 coding_known = TRUE;
1287 if (data1 & IEEE80211_RADIOTAP_HE_LDPC_EXTRA_SYMBOL_SEGMENT_KNOWN)
1288 ldpc_extra_symbol_segment_known = TRUE;
1289 if (data1 & IEEE80211_RADIOTAP_HE_STBC_KNOWN)
1290 stbc_known = TRUE;
1291 if (data1 & IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_KNOWN)
1292 spatial_reuse_1_known = TRUE;
1293 if (data1 & IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_2_KNOWN)
1294 spatial_reuse_2_known = TRUE;
1295 if (data1 & IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_3_KNOWN)
1296 spatial_reuse_3_known = TRUE;
1297 if (data1 & IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_4_KNOWN)
1298 spatial_reuse_4_known = TRUE;
1299 if (data1 & IEEE80211_RADIOTAP_HE_DATA_BW_RU_ALLOCATION_KNOWN)
1300 data_bw_ru_alloc_known = TRUE;
1301 if (data1 & IEEE80211_RADIOTAP_HE_DOPPLER_KNOWN)
1302 doppler_known = TRUE;
1303
1304 he_info_tree = proto_tree_add_subtree(tree, tvb, offset, 12,
1305 ett_radiotap_he_info, NULL, "HE information");
1306
1307 /* Add the bitmasks for each of D1 through D6 */
1308 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1309 hf_radiotap_he_info_data_1, ett_radiotap_he_info_data_1,
1310 data1_headers, ENC_LITTLE_ENDIAN);
1311 offset += 2;
1312
1313 data2 = tvb_get_letohs(tvb, offset);
1314 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1315 hf_radiotap_he_info_data_2, ett_radiotap_he_info_data_2,
1316 data2_headers, ENC_LITTLE_ENDIAN);
1317 offset += 2;
1318
1319 /*
1320 * Second lot of what is known
1321 */
1322 if (data2 & IEEE80211_RADIOTAP_HE_GI_KNOWN)
1323 gi_known = TRUE;
1324 if (data2 & IEEE80211_RADIOTAP_HE_NUM_LTF_SYMBOLS_KNOWN)
1325 num_ltf_symbols_known = TRUE;
1326 if (data2 & IEEE80211_RADIOTAP_HE_PRE_FEC_PADDING_FACTOR_KNOWN)
1327 pre_fec_padding_factor_known = TRUE;
1328 if (data2 & IEEE80211_RADIOTAP_HE_TXBF_KNOWN)
1329 txbf_known = TRUE;
1330 if (data2 & IEEE80211_RADIOTAP_HE_PE_DISAMBIGUITY_KNOWN)
1331 pe_disambiguity_known = TRUE;
1332 if (data2 & IEEE80211_RADIOTAP_HE_TXOP_KNOWN)
1333 txop_known = TRUE;
1334 if (data2 & IEEE80211_RADIOTAP_HE_MIDAMBLE_PERIODICITY_KNOWN)
1335 midamble_periodicity_known = TRUE;
1336
1337 /*
1338 * Set those fields that should be reserved
1339 */
1340 if (!bss_color_known)
1341 data3_headers[0] = &hf_radiotap_he_bss_color_unknown;
1342 if (!beam_change_known)
1343 data3_headers[1] = &hf_radiotap_he_beam_change_unknown;
1344 if (!ul_dl_known)
1345 data3_headers[2] = &hf_radiotap_he_ul_dl_unknown;
1346 if (!data_mcs_known)
1347 data3_headers[3] = &hf_radiotap_he_data_mcs_unknown;
1348 if (!data_dcm_known)
1349 data3_headers[4] = &hf_radiotap_he_data_dcm_unknown;
1350 if (!coding_known)
1351 data3_headers[5] = &hf_radiotap_he_coding_unknown;
1352 if (!ldpc_extra_symbol_segment_known)
1353 data3_headers[6] = &hf_radiotap_he_ldpc_extra_symbol_segment_unknown;
1354 if (!stbc_known)
1355 data3_headers[7] = &hf_radiotap_he_stbc_unknown;
1356
1357 data3 = tvb_get_letohs(tvb, offset);
1358 if (data_mcs_known) {
1359 info_11ax->has_mcs_index = TRUE;
1360 info_11ax->mcs = (data3 & IEEE80211_RADIOTAP_HE_DATA_MCS_MASK) >> 8;
1361 }
1362 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1363 hf_radiotap_he_info_data_3, ett_radiotap_he_info_data_3,
1364 data3_headers, ENC_LITTLE_ENDIAN);
1365 offset += 2;
1366
1367 if (ppdu_format == IEEE80211_RADIOTAP_HE_PPDU_FORMAT_HE_SU ||
1368 ppdu_format == IEEE80211_RADIOTAP_HE_PPDU_FORMAT_HE_EXT_SU) {
1369 if (!spatial_reuse_1_known)
1370 data4_he_su_and_he_ext_su_headers[0] =
1371 &hf_radiotap_spatial_reuse_unknown;
1372 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1373 hf_radiotap_he_info_data_4, ett_radiotap_he_info_data_4,
1374 data4_he_su_and_he_ext_su_headers, ENC_LITTLE_ENDIAN);
1375 } else if (ppdu_format == IEEE80211_RADIOTAP_HE_PPDU_FORMAT_HE_TRIG) {
1376 if (!spatial_reuse_1_known)
1377 data4_he_trig_headers[0] =
1378 &hf_radiotap_spatial_reuse_1_unknown;
1379 if (!spatial_reuse_2_known)
1380 data4_he_trig_headers[1] =
1381 &hf_radiotap_spatial_reuse_2_unknown;
1382 if (!spatial_reuse_3_known)
1383 data4_he_trig_headers[2] =
1384 &hf_radiotap_spatial_reuse_3_unknown;
1385 if (!spatial_reuse_4_known)
1386 data4_he_trig_headers[3] =
1387 &hf_radiotap_spatial_reuse_4_unknown;
1388 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1389 hf_radiotap_he_info_data_4, ett_radiotap_he_info_data_4,
1390 data4_he_trig_headers, ENC_LITTLE_ENDIAN);
1391 } else {
1392 if (!spatial_reuse_1_known)
1393 data4_he_mu_headers[0] =
1394 &hf_radiotap_spatial_reuse_unknown;
1395 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1396 hf_radiotap_he_info_data_4, ett_radiotap_he_info_data_4,
1397 data4_he_mu_headers, ENC_LITTLE_ENDIAN);
1398 }
1399
1400 //data4 = tvb_get_letohs(tvb, offset);
1401 offset += 2;
1402
1403 /*
1404 * The LTF Symbol Size field is zero if LFT Symbol size is unknown
1405 */
1406 ltf_symbol_size = (tvb_get_letohs(tvb, offset) >> 6) & 0x03;
1407 if (ltf_symbol_size != 0)
1408 ltf_symbol_size_known = TRUE;
1409 if (!data_bw_ru_alloc_known)
1410 data5_headers[0] = &hf_radiotap_data_bandwidth_ru_allocation_unknown;
1411 if (!gi_known)
1412 data5_headers[1] = &hf_radiotap_gi_unknown;
1413 if (!ltf_symbol_size_known)
1414 data5_headers[2] = &hf_radiotap_ltf_symbol_size_unknown;
1415 if (!num_ltf_symbols_known)
1416 data5_headers[3] = &hf_radiotap_num_ltf_symbols_unknown;
1417 if (!pre_fec_padding_factor_known)
1418 data5_headers[5] = &hf_radiotap_pre_fec_padding_factor_unknown;
1419 if (!txbf_known)
1420 data5_headers[6] = &hf_radiotap_txbf_unknown;
1421 if (!pe_disambiguity_known)
1422 data5_headers[7] = &hf_radiotap_pe_disambiguity_unknown;
1423 data5 = tvb_get_letohs(tvb, offset);
1424 if (gi_known) {
1425 info_11ax->has_gi = TRUE;
1426 info_11ax->gi = (data5 & IEEE80211_RADIOTAP_HE_GI_MASK) >> 4;
1427 }
1428 if (data_bw_ru_alloc_known) {
1429 info_11ax->has_bwru = TRUE;
1430 info_11ax->bwru = (data5 & IEEE80211_RADIOTAP_HE_DATA_BANDWIDTH_RU_ALLOC_MASK);
1431 }
1432 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1433 hf_radiotap_he_info_data_5, ett_radiotap_he_info_data_5,
1434 data5_headers, ENC_LITTLE_ENDIAN);
1435 offset += 2;
1436
1437 if (!doppler_known)
1438 data6_headers[1] = &hf_radiotap_he_doppler_value_unknown;
1439 if (!txop_known)
1440 data6_headers[3] = &hf_radiotap_he_txop_value_unknown;
1441 if (!midamble_periodicity_known)
1442 data6_headers[4] = &hf_radiotap_midamble_periodicity_unknown;
1443 proto_tree_add_bitmask(he_info_tree, tvb, offset,
1444 hf_radiotap_he_info_data_6, ett_radiotap_he_info_data_6,
1445 data6_headers, ENC_LITTLE_ENDIAN);
1446 data6 = tvb_get_letohs(tvb, offset);
1447
1448 info_11ax->nsts = data6 & IEEE80211_RADIOTAP_HE_NSTS_MASK;
1449
1450 }
1451
1452 static void
not_captured_custom(gchar * result,guint32 value _U_)1453 not_captured_custom(gchar *result, guint32 value _U_)
1454 {
1455 g_snprintf(result, ITEM_LABEL_LENGTH,
1456 "NOT CAPTURED BY CAPTURE SOFTWARE");
1457 }
1458
1459 static void
he_sig_b_symbols_custom(gchar * result,guint32 value)1460 he_sig_b_symbols_custom(gchar *result, guint32 value)
1461 {
1462 g_snprintf(result, ITEM_LABEL_LENGTH, "%d", value+1);
1463 }
1464
1465 static void
dissect_radiotap_he_mu_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1466 dissect_radiotap_he_mu_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1467 int offset)
1468 {
1469 proto_tree *he_mu_info_tree = NULL;
1470 guint16 flags1 = tvb_get_letohs(tvb, offset);
1471 gboolean sig_b_mcs_known = FALSE;
1472 gboolean sig_b_dcm_known = FALSE;
1473 proto_tree *mu_chan1_rus = NULL;
1474 proto_tree *mu_chan2_rus = NULL;
1475 int mu_rus_chan1_rus_0 = -1;
1476 int mu_rus_chan1_rus_1 = -1;
1477 int mu_rus_chan1_rus_2 = -1;
1478 int mu_rus_chan1_rus_3 = -1;
1479 int mu_rus_chan2_rus_0 = -1;
1480 int mu_rus_chan2_rus_1 = -1;
1481 int mu_rus_chan2_rus_2 = -1;
1482 int mu_rus_chan2_rus_3 = -1;
1483 gboolean mu_chan2_center_26_tone_ru_bit_known = FALSE;
1484 gboolean mu_chan1_rus_known = FALSE;
1485 gboolean mu_chan2_rus_known = FALSE;
1486 gboolean mu_chan1_center_26_tone_ru_bit_known = FALSE;
1487 gboolean mu_sig_b_compression_known = FALSE;
1488 gboolean mu_symbol_cnt_or_user_cnt_known = FALSE;
1489 gboolean mu_preamble_puncturing_known = FALSE;
1490 gboolean mu_bw_from_bw_sig_a_known = FALSE;
1491 guint8 bw_from_sig_a = 0;
1492 guint16 flags2;
1493
1494 /*
1495 * This is set differetly for each packet, depending on
1496 * which values in flags1 are known. It thus will not
1497 * work if it's static.
1498 */
1499 int *flags1_headers[] = {
1500 &hf_radiotap_he_mu_sig_b_mcs,
1501 &hf_radiotap_he_mu_sig_b_mcs_known,
1502 &hf_radiotap_he_mu_sig_b_dcm,
1503 &hf_radiotap_he_mu_sig_b_dcm_known,
1504 &hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_known,
1505 &hf_radiotap_he_mu_chan1_rus_known,
1506 &hf_radiotap_he_mu_chan2_rus_known,
1507 &hf_radiotap_he_mu_reserved_f1_b10_b11,
1508 &hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_known,
1509 &hf_radiotap_he_mu_chan1_center_26_tone_ru_value,
1510 &hf_radiotap_he_mu_sig_b_compression_known,
1511 &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_known,
1512 NULL
1513 };
1514
1515 /*
1516 * Same story but for flags2.
1517 */
1518 int *flags2_headers[] = {
1519 &hf_radiotap_he_mu_bw_from_bw_in_sig_a,
1520 &hf_radiotap_he_mu_bw_from_bw_in_sig_a_known,
1521 &hf_radiotap_he_mu_sig_b_compression_from_sig_a,
1522 &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users,
1523 &hf_radiotap_he_mu_preamble_puncturing,
1524 &hf_radiotap_he_mu_preamble_puncturing_known,
1525 &hf_radiotap_he_mu_chan2_center_26_tone_ru_value,
1526 &hf_radiotap_he_mu_reserved_f2_b12_b15,
1527 NULL
1528 };
1529
1530 if (flags1 & IEEE80211_RADIOTAP_HE_MU_SIG_B_MCS_KNOWN)
1531 sig_b_mcs_known = TRUE;
1532 if (flags1 & IEEE80211_RADIOTAP_HE_MU_SIG_B_DCM_KNOWN)
1533 sig_b_dcm_known = TRUE;
1534 if (flags1 & IEEE80211_RADIOTAP_HE_MU_CHAN2_CENTER_26_TONE_RU_BIT_KNOWN)
1535 mu_chan2_center_26_tone_ru_bit_known = TRUE;
1536 if (flags1 & IEEE80211_RADIOTAP_HE_MU_CHAN1_RUS_KNOWN)
1537 mu_chan1_rus_known = TRUE;
1538 if (flags1 & IEEE80211_RADIOTAP_HE_MU_CHAN2_RUS_KNOWN)
1539 mu_chan2_rus_known = TRUE;
1540 if (flags1 & IEEE80211_RADIOTAP_HE_MU_CHAN1_CENTER_26_TONE_RU_BIT_KNOWN)
1541 mu_chan1_center_26_tone_ru_bit_known = TRUE;
1542 if (flags1 & IEEE80211_RADIOTAP_HE_MU_SIG_B_COMPRESSION_KNOWN)
1543 mu_sig_b_compression_known = TRUE;
1544 if (flags1 & IEEE80211_RADIOTAP_HE_MU_SYMBOL_CNT_OR_USER_CNT_KNOWN)
1545 mu_symbol_cnt_or_user_cnt_known = TRUE;
1546
1547 if (!sig_b_mcs_known) {
1548 flags1_headers[1] = &hf_radiotap_he_mu_sig_b_mcs_unknown;
1549 } else {
1550 flags1_headers[1] = &hf_radiotap_he_mu_sig_b_mcs_known;
1551 }
1552 if (!sig_b_dcm_known) {
1553 flags1_headers[3] = &hf_radiotap_he_mu_sig_b_dcm_unknown;
1554 } else {
1555 flags1_headers[3] = &hf_radiotap_he_mu_sig_b_dcm_known;
1556 }
1557 if (!mu_chan2_center_26_tone_ru_bit_known) {
1558 flags1_headers[4] = &hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_unknown;
1559 } else {
1560 flags1_headers[4] = &hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_known;
1561 }
1562 if (!mu_chan1_rus_known) {
1563 flags1_headers[5] = &hf_radiotap_he_mu_chan1_rus_unknown;
1564 } else {
1565 flags1_headers[5] = &hf_radiotap_he_mu_chan1_rus_known;
1566 }
1567 if (!mu_chan2_rus_known) {
1568 flags1_headers[6] = &hf_radiotap_he_mu_chan2_rus_unknown;
1569 } else {
1570 flags1_headers[6] = &hf_radiotap_he_mu_chan2_rus_known;
1571 }
1572 if (!mu_chan1_center_26_tone_ru_bit_known) {
1573 flags1_headers[8] = &hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_unknown;
1574 } else {
1575 flags1_headers[8] = &hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_known;
1576 }
1577 if (!mu_symbol_cnt_or_user_cnt_known) {
1578 flags1_headers[11] = &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_unknown;
1579 } else {
1580 flags1_headers[11] = &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_known;
1581 }
1582
1583 if (!mu_chan1_center_26_tone_ru_bit_known) {
1584 flags1_headers[9] = &hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_unknown;
1585 } else {
1586 flags1_headers[9] = &hf_radiotap_he_mu_chan1_center_26_tone_ru_value;
1587 }
1588 if (!mu_symbol_cnt_or_user_cnt_known) {
1589 flags1_headers[11] = &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_unknown;
1590 } else {
1591 flags1_headers[11] = &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_known;
1592 }
1593
1594 flags2 = tvb_get_letohs(tvb, offset + 2);
1595 if (flags2 & IEEE80211_RADIOTAP_HE_MU_BW_FROM_BW_IN_SIG_A_KNOWN)
1596 mu_bw_from_bw_sig_a_known = TRUE;
1597 if (flags2 & IEEE80211_RADIOTAP_HE_MU_PREAMBLE_PUNCTURING_KNOWN)
1598 mu_preamble_puncturing_known = TRUE;
1599
1600 if (!mu_bw_from_bw_sig_a_known) {
1601 flags2_headers[0] = &hf_radiotap_he_mu_bw_from_bw_in_sig_a_unknown;
1602 } else {
1603 flags2_headers[0] = &hf_radiotap_he_mu_bw_from_bw_in_sig_a;
1604 }
1605 if (!mu_sig_b_compression_known) {
1606 flags2_headers[2] = &hf_radiotap_he_mu_sig_b_compression_unknown;
1607 } else {
1608 flags2_headers[2] = &hf_radiotap_he_mu_sig_b_compression_from_sig_a;
1609 }
1610 if (!mu_symbol_cnt_or_user_cnt_known) {
1611 flags2_headers[3] = &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_unknown;
1612 } else {
1613 flags2_headers[3] = &hf_radiotap_he_mu_sig_b_syms_mu_mimo_users;
1614 }
1615 if (!mu_preamble_puncturing_known) {
1616 flags2_headers[4] = &hf_radiotap_he_mu_preamble_puncturing_unknown;
1617 } else {
1618 flags2_headers[4] = &hf_radiotap_he_mu_preamble_puncturing;
1619 }
1620 if (!mu_chan2_center_26_tone_ru_bit_known) {
1621 flags2_headers[6] = &hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_unknown;
1622 } else {
1623 flags2_headers[6] = &hf_radiotap_he_mu_chan2_center_26_tone_ru_value;
1624 }
1625
1626 bw_from_sig_a = flags2 & IEEE80211_RADIOTAP_HE_MU_BW_FROM_BW_IN_SIG_A_MASK;
1627
1628 /*
1629 * We have to hold of on displaying stuff until we have figured
1630 * everything out because the display of fields in flags1 depends
1631 * on bandwidth from flags2.
1632 */
1633
1634 /* Set the header fields depending on the bw and known fields */
1635 if (bw_from_sig_a < 3) {
1636 if (mu_chan1_rus_known) {
1637 mu_rus_chan1_rus_0 = hf_radiotap_he_mu_chan1_rus_0;
1638 mu_rus_chan1_rus_1 = hf_radiotap_he_mu_chan1_rus_1;
1639 mu_rus_chan1_rus_2 = hf_radiotap_he_mu_chan1_rus_2;
1640 mu_rus_chan1_rus_3 = hf_radiotap_he_mu_chan1_rus_3;
1641 } else {
1642 mu_rus_chan1_rus_0 = hf_radiotap_he_mu_chan1_rus_0_unknown;
1643 mu_rus_chan1_rus_1 = hf_radiotap_he_mu_chan1_rus_1_unknown;
1644 mu_rus_chan1_rus_2 = hf_radiotap_he_mu_chan1_rus_2_unknown;
1645 mu_rus_chan1_rus_3 = hf_radiotap_he_mu_chan1_rus_3_unknown;
1646 }
1647 if (mu_chan2_rus_known) {
1648 mu_rus_chan2_rus_0 = hf_radiotap_he_mu_chan2_rus_0;
1649 mu_rus_chan2_rus_1 = hf_radiotap_he_mu_chan2_rus_1;
1650 mu_rus_chan2_rus_2 = hf_radiotap_he_mu_chan2_rus_2;
1651 mu_rus_chan2_rus_3 = hf_radiotap_he_mu_chan2_rus_3;
1652 } else {
1653 mu_rus_chan2_rus_0 = hf_radiotap_he_mu_chan2_rus_0_unknown;
1654 mu_rus_chan2_rus_1 = hf_radiotap_he_mu_chan2_rus_1_unknown;
1655 mu_rus_chan2_rus_2 = hf_radiotap_he_mu_chan2_rus_2_unknown;
1656 mu_rus_chan2_rus_3 = hf_radiotap_he_mu_chan2_rus_3_unknown;
1657 }
1658 } else {
1659 mu_rus_chan1_rus_0 = hf_radiotap_he_mu_chan1_rus_0;
1660 mu_rus_chan1_rus_1 = hf_radiotap_he_mu_chan1_rus_1;
1661 mu_rus_chan1_rus_2 = hf_radiotap_he_mu_chan1_rus_2;
1662 mu_rus_chan1_rus_3 = hf_radiotap_he_mu_chan1_rus_3;
1663 mu_rus_chan2_rus_0 = hf_radiotap_he_mu_chan2_rus_0;
1664 mu_rus_chan2_rus_1 = hf_radiotap_he_mu_chan2_rus_1;
1665 mu_rus_chan2_rus_2 = hf_radiotap_he_mu_chan2_rus_2;
1666 mu_rus_chan2_rus_3 = hf_radiotap_he_mu_chan2_rus_3;
1667 }
1668
1669 he_mu_info_tree = proto_tree_add_subtree(tree, tvb, offset, 12,
1670 ett_radiotap_he_mu_info, NULL, "HE-MU information");
1671
1672 proto_tree_add_bitmask(he_mu_info_tree, tvb, offset,
1673 hf_radiotap_he_mu_info_flags_1,
1674 ett_radiotap_he_mu_info_flags_1,
1675 flags1_headers, ENC_LITTLE_ENDIAN);
1676 offset += 2;
1677
1678 proto_tree_add_bitmask(he_mu_info_tree, tvb, offset,
1679 hf_radiotap_he_mu_info_flags_2,
1680 ett_radiotap_he_mu_info_flags_2,
1681 flags2_headers, ENC_LITTLE_ENDIAN);
1682 offset += 2;
1683
1684 mu_chan1_rus = proto_tree_add_subtree(he_mu_info_tree, tvb, offset, 4,
1685 ett_radiotap_he_mu_chan_rus, NULL,
1686 "Channel 1 RUs");
1687
1688 proto_tree_add_item(mu_chan1_rus, mu_rus_chan1_rus_0, tvb, offset, 1,
1689 ENC_NA);
1690 offset++;
1691
1692 proto_tree_add_item(mu_chan1_rus, mu_rus_chan1_rus_1, tvb, offset, 1,
1693 ENC_NA);
1694 offset++;
1695
1696 proto_tree_add_item(mu_chan1_rus, mu_rus_chan1_rus_2, tvb, offset, 1,
1697 ENC_NA);
1698 offset++;
1699
1700 proto_tree_add_item(mu_chan1_rus, mu_rus_chan1_rus_3, tvb, offset, 1,
1701 ENC_NA);
1702 offset++;
1703
1704 mu_chan2_rus = proto_tree_add_subtree(he_mu_info_tree, tvb, offset, 4,
1705 ett_radiotap_he_mu_chan_rus, NULL,
1706 "Channel 2 RUs");
1707
1708 proto_tree_add_item(mu_chan2_rus, mu_rus_chan2_rus_0, tvb, offset, 1,
1709 ENC_NA);
1710 offset++;
1711
1712 proto_tree_add_item(mu_chan2_rus, mu_rus_chan2_rus_1, tvb, offset, 1,
1713 ENC_NA);
1714 offset++;
1715
1716 proto_tree_add_item(mu_chan2_rus, mu_rus_chan2_rus_2, tvb, offset, 1,
1717 ENC_NA);
1718 offset++;
1719
1720 proto_tree_add_item(mu_chan2_rus, mu_rus_chan2_rus_3, tvb, offset, 1,
1721 ENC_NA);
1722 }
1723
1724 static const range_string zero_length_psdu_rsvals[] = {
1725 { 0, 0, "sounding PPDU" },
1726 { 1, 1, "reserved" },
1727 { 2, 2, "S1G NDP CMAC frame" },
1728 { 3, 254, "reserved" },
1729 { 255, 255, "vendor-specific" },
1730 { 0, 0, NULL }
1731 };
1732
1733 static int
1734 dissect_s1g_ndp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree);
1735
1736 static void
dissect_radiotap_0_length_psdu(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)1737 dissect_radiotap_0_length_psdu(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1738 int offset, struct ieee_802_11_phdr *phdr)
1739 {
1740 proto_tree *zero_len_tree = NULL;
1741 guint32 psdu_type;
1742 tvbuff_t *new_tvb = NULL;
1743
1744 zero_len_tree = proto_tree_add_subtree(tree, tvb, offset,
1745 tvb_captured_length_remaining(tvb, offset),
1746 ett_radiotap_0_length_psdu, NULL, "0-length PSDU");
1747
1748 proto_tree_add_item_ret_uint(zero_len_tree, hf_radiotap_0_length_psdu_type,
1749 tvb, offset, 1, ENC_NA, &psdu_type);
1750 offset += 1;
1751
1752 switch (psdu_type) {
1753
1754 case 0:
1755 phdr->has_zero_length_psdu_type = TRUE;
1756 phdr->zero_length_psdu_type = PHDR_802_11_SOUNDING_PSDU;
1757 break;
1758
1759 case 1:
1760 phdr->has_zero_length_psdu_type = TRUE;
1761 phdr->zero_length_psdu_type = PHDR_802_11_DATA_NOT_CAPTURED;
1762 break;
1763
1764 case 2:
1765 phdr->has_zero_length_psdu_type = TRUE;
1766 phdr->zero_length_psdu_type = PHDR_802_11_0_LENGTH_PSDU_S1G_NDP;
1767 new_tvb = tvb_new_subset_length(tvb, offset, 6);
1768 dissect_s1g_ndp(new_tvb, pinfo, zero_len_tree);
1769 break;
1770
1771 case 0xff:
1772 phdr->has_zero_length_psdu_type = TRUE;
1773 phdr->zero_length_psdu_type = PHDR_802_11_0_LENGTH_PSDU_VENDOR_SPECIFIC;
1774 break;
1775 }
1776 }
1777
1778 static int * const l_sig_data1_headers[] = {
1779 &hf_radiotap_l_sig_rate_known,
1780 &hf_radiotap_l_sig_length_known,
1781 &hf_radiotap_l_sig_reserved,
1782 NULL
1783 };
1784
1785 static int * const l_sig_data2_headers[] = {
1786 &hf_radiotap_l_sig_rate,
1787 &hf_radiotap_l_sig_length,
1788 NULL
1789 };
1790
1791 static void
dissect_radiotap_l_sig(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1792 dissect_radiotap_l_sig(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1793 int offset)
1794 {
1795 proto_tree *l_sig_tree = NULL;
1796
1797 l_sig_tree = proto_tree_add_subtree(tree, tvb, offset, 4,
1798 ett_radiotap_l_sig, NULL, "L-SIG");
1799
1800 proto_tree_add_bitmask(l_sig_tree, tvb, offset,
1801 hf_radiotap_l_sig_data_1, ett_radiotap_l_sig_data_1,
1802 l_sig_data1_headers, ENC_LITTLE_ENDIAN);
1803 offset += 2;
1804
1805 proto_tree_add_bitmask(l_sig_tree, tvb, offset,
1806 hf_radiotap_l_sig_data_2, ett_radiotap_l_sig_data_2,
1807 l_sig_data2_headers, ENC_LITTLE_ENDIAN);
1808 }
1809
1810 /*
1811 * Dissect an S1G NDP as it is currently. This is a 6-byte field, with the
1812 * first byte looking like the first byte of the FCF, and coded using
1813 * reserved values for the subtype. The remaining bytes are the NDP data,
1814 * with the last two bits distinguishing between 1M and 2M.
1815 */
1816
1817 #define S1G_NDP_CTS_CF_END 0x00
1818 #define S1G_NDP_PS_POLL 0x01
1819 #define S1G_NDP_ACK 0x02
1820 #define S1G_NDP_PS_POLL_ACK 0x03
1821 #define S1G_NDP_BLOCK_ACK 0x04
1822 #define S1G_NDP_BEAMFORMING_REPORT_POLL 0x05
1823 #define S1G_NDP_PAGING 0x06
1824 #define S1G_NDP_PROBE_REQ 0x07
1825
1826 static int * const ndp_ack_1m_headers[] = {
1827 &hf_radiotap_s1g_ndp_type_3bit,
1828 &hf_radiotap_s1g_ndp_ack_1m_ack_id,
1829 &hf_radiotap_s1g_ndp_ack_1m_more_data,
1830 &hf_radiotap_s1g_ndp_ack_1m_idle_indication,
1831 &hf_radiotap_s1g_ndp_ack_1m_duration,
1832 &hf_radiotap_s1g_ndp_ack_1m_relayed_frame,
1833 &hf_radiotap_s1g_ndp_1m_unused,
1834 &hf_radiotap_s1g_ndp_bw,
1835 NULL
1836 };
1837
1838 static int * const ndp_ack_2m_headers[] = {
1839 &hf_radiotap_s1g_ndp_type_3bit,
1840 &hf_radiotap_s1g_ndp_ack_2m_ack_id,
1841 &hf_radiotap_s1g_ndp_ack_2m_more_data,
1842 &hf_radiotap_s1g_ndp_ack_2m_idle_indication,
1843 &hf_radiotap_s1g_ndp_ack_2m_duration,
1844 &hf_radiotap_s1g_ndp_ack_2m_relayed_frame,
1845 &hf_radiotap_s1g_ndp_ack_2m_reserved,
1846 &hf_radiotap_s1g_ndp_2m_unused,
1847 &hf_radiotap_s1g_ndp_bw,
1848 NULL
1849 };
1850
1851 static int * const ndp_probe_1m_headers[] = {
1852 &hf_radiotap_s1g_ndp_type_3bit,
1853 &hf_radiotap_s1g_ndp_probe_cssid_ano_present,
1854 &hf_radiotap_s1g_ndp_probe_1m_cssid_ano,
1855 &hf_radiotap_s1g_ndp_probe_1m_requested_response_type,
1856 &hf_radiotap_s1g_ndp_probe_1m_reserved,
1857 &hf_radiotap_s1g_ndp_1m_unused,
1858 &hf_radiotap_s1g_ndp_bw,
1859 NULL
1860 };
1861
1862 static int * const ndp_probe_2m_headers[] = {
1863 &hf_radiotap_s1g_ndp_type_3bit,
1864 &hf_radiotap_s1g_ndp_probe_cssid_ano_present,
1865 &hf_radiotap_s1g_ndp_probe_2m_cssid_ano,
1866 &hf_radiotap_s1g_ndp_probe_2m_requested_response_type,
1867 &hf_radiotap_s1g_ndp_2m_unused,
1868 &hf_radiotap_s1g_ndp_bw,
1869 NULL
1870 };
1871
1872 static int * const ndp_cts_1m_headers[] = {
1873 &hf_radiotap_s1g_ndp_type_3bit,
1874 &hf_radiotap_s1g_ndp_cts_cf_end_indic,
1875 &hf_radiotap_s1g_ndp_cts_address_indic,
1876 &hf_radiotap_s1g_ndp_cts_ra_partial_bssid,
1877 &hf_radiotap_s1g_ndp_cts_duration_1m,
1878 &hf_radiotap_s1g_ndp_cts_early_sector_indic_1m,
1879 &hf_radiotap_s1g_ndp_1m_unused,
1880 &hf_radiotap_s1g_ndp_bw,
1881 NULL
1882 };
1883
1884 static int * const ndp_cts_2m_headers[] = {
1885 &hf_radiotap_s1g_ndp_type_3bit,
1886 &hf_radiotap_s1g_ndp_cts_cf_end_indic,
1887 &hf_radiotap_s1g_ndp_cts_address_indic,
1888 &hf_radiotap_s1g_ndp_cts_ra_partial_bssid,
1889 &hf_radiotap_s1g_ndp_cts_duration_2m,
1890 &hf_radiotap_s1g_ndp_cts_early_sector_indic_2m,
1891 &hf_radiotap_s1g_ndp_cts_bandwidth_indic_2m,
1892 &hf_radiotap_s1g_ndp_cts_reserved,
1893 &hf_radiotap_s1g_ndp_2m_unused,
1894 &hf_radiotap_s1g_ndp_bw,
1895 NULL
1896 };
1897
1898 static int * const ndp_cf_end_1m_headers[] = {
1899 &hf_radiotap_s1g_ndp_type_3bit,
1900 &hf_radiotap_s1g_ndp_cts_cf_end_indic,
1901 &hf_radiotap_s1g_ndp_cf_end_partial_bssid,
1902 &hf_radiotap_s1g_ndp_cf_end_duration_1m,
1903 &hf_radiotap_s1g_ndp_cf_end_reserved_1m,
1904 &hf_radiotap_s1g_ndp_1m_unused,
1905 &hf_radiotap_s1g_ndp_bw,
1906 NULL
1907 };
1908
1909 static int * const ndp_cf_end_2m_headers[] = {
1910 &hf_radiotap_s1g_ndp_type_3bit,
1911 &hf_radiotap_s1g_ndp_cts_cf_end_indic,
1912 &hf_radiotap_s1g_ndp_cf_end_partial_bssid,
1913 &hf_radiotap_s1g_ndp_cf_end_duration_2m,
1914 &hf_radiotap_s1g_ndp_cf_end_reserved_2m,
1915 &hf_radiotap_s1g_ndp_1m_unused,
1916 &hf_radiotap_s1g_ndp_bw,
1917 NULL
1918 };
1919
1920 static int * const ndp_ps_poll_1m_headers[] = {
1921 &hf_radiotap_s1g_ndp_type_3bit,
1922 &hf_radiotap_s1g_ndp_ps_poll_ra,
1923 &hf_radiotap_s1g_ndp_ps_poll_ta,
1924 &hf_radiotap_s1g_ndp_ps_poll_preferred_mcs_1m,
1925 &hf_radiotap_s1g_ndp_ps_poll_udi_1m,
1926 &hf_radiotap_s1g_ndp_1m_unused,
1927 &hf_radiotap_s1g_ndp_bw,
1928 NULL
1929 };
1930
1931 static int * const ndp_ps_poll_2m_headers[] = {
1932 &hf_radiotap_s1g_ndp_type_3bit,
1933 &hf_radiotap_s1g_ndp_ps_poll_ra,
1934 &hf_radiotap_s1g_ndp_ps_poll_ta,
1935 &hf_radiotap_s1g_ndp_ps_poll_preferred_mcs_2m,
1936 &hf_radiotap_s1g_ndp_ps_poll_udi_2m,
1937 &hf_radiotap_s1g_ndp_2m_unused,
1938 &hf_radiotap_s1g_ndp_bw,
1939 NULL
1940 };
1941
1942 static int * const ndp_ps_poll_ack_1m_headers[] = {
1943 &hf_radiotap_s1g_ndp_type_3bit,
1944 &hf_radiotap_s1g_ndp_ps_poll_ack_id,
1945 &hf_radiotap_s1g_ndp_ps_poll_ack_more_data,
1946 &hf_radiotap_s1g_ndp_ps_poll_ack_idle_indication,
1947 &hf_radiotap_s1g_ndp_ps_poll_ack_duration_1m,
1948 &hf_radiotap_s1g_ndp_ps_poll_ack_reserved_1m,
1949 &hf_radiotap_s1g_ndp_1m_unused,
1950 &hf_radiotap_s1g_ndp_bw,
1951 NULL
1952 };
1953
1954 static int * const ndp_ps_poll_ack_2m_headers[] = {
1955 &hf_radiotap_s1g_ndp_type_3bit,
1956 &hf_radiotap_s1g_ndp_ps_poll_ack_id_2m,
1957 &hf_radiotap_s1g_ndp_ps_poll_ack_more_data_2m,
1958 &hf_radiotap_s1g_ndp_ps_poll_ack_idle_indication_2m,
1959 &hf_radiotap_s1g_ndp_ps_poll_ack_duration_2m,
1960 &hf_radiotap_s1g_ndp_ps_poll_ack_reserved_2m,
1961 &hf_radiotap_s1g_ndp_2m_unused,
1962 &hf_radiotap_s1g_ndp_bw,
1963 NULL
1964 };
1965
1966 static int * const ndp_block_ack_1m_headers[] = {
1967 &hf_radiotap_s1g_ndp_type_3bit,
1968 &hf_radiotap_s1g_ndp_block_ack_id_1m,
1969 &hf_radiotap_s1g_ndp_block_ack_starting_sequence_control_1m,
1970 &hf_radiotap_s1g_ndp_block_ack_bitmap_1m,
1971 &hf_radiotap_s1g_ndp_block_ack_unused_1m,
1972 &hf_radiotap_s1g_ndp_bw,
1973 NULL
1974 };
1975
1976 static int * const ndp_block_ack_2m_headers[] = {
1977 &hf_radiotap_s1g_ndp_type_3bit,
1978 &hf_radiotap_s1g_ndp_block_ack_id_2m,
1979 &hf_radiotap_s1g_ndp_block_ack_starting_sequence_control_2m,
1980 &hf_radiotap_s1g_ndp_block_ack_bitmap_2m,
1981 &hf_radiotap_s1g_ndp_2m_unused,
1982 &hf_radiotap_s1g_ndp_bw,
1983 NULL
1984 };
1985
1986 static int * const ndp_beamforming_headers[] = {
1987 &hf_radiotap_s1g_ndp_type_3bit,
1988 &hf_radiotap_s1g_ndp_beamforming_ap_address,
1989 &hf_radiotap_s1g_ndp_beamforming_non_ap_sta_address,
1990 &hf_radiotap_s1g_ndp_beamforming_feedback_segment_bitmap,
1991 &hf_radiotap_s1g_ndp_beamforming_reserved,
1992 &hf_radiotap_s1g_ndp_2m_unused,
1993 &hf_radiotap_s1g_ndp_bw,
1994 NULL
1995 };
1996
1997 static int * const ndp_paging_1m_headers[] = {
1998 &hf_radiotap_s1g_ndp_type_3bit,
1999 &hf_radiotap_s1g_ndp_paging_p_id,
2000 &hf_radiotap_s1g_ndp_paging_apdi_partial_aid,
2001 &hf_radiotap_s1g_ndp_paging_direction,
2002 &hf_radiotap_s1g_ndp_paging_reserved_1m,
2003 &hf_radiotap_s1g_ndp_1m_unused,
2004 &hf_radiotap_s1g_ndp_bw,
2005 NULL
2006 };
2007
2008 static int * const ndp_paging_2m_headers[] = {
2009 &hf_radiotap_s1g_ndp_type_3bit,
2010 &hf_radiotap_s1g_ndp_paging_p_id,
2011 &hf_radiotap_s1g_ndp_paging_apdi_partial_aid,
2012 &hf_radiotap_s1g_ndp_paging_direction,
2013 &hf_radiotap_s1g_ndp_paging_reserved_2m,
2014 &hf_radiotap_s1g_ndp_2m_unused,
2015 &hf_radiotap_s1g_ndp_bw,
2016 NULL
2017 };
2018
2019 static int
dissect_s1g_ndp(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree)2020 dissect_s1g_ndp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
2021 {
2022 proto_tree *ndp_tree = NULL;
2023 proto_item *ndp_item = NULL;
2024 int offset = 0;
2025 guint8 ndp_type = tvb_get_guint8(tvb, 1);
2026 guint8 ndp_bw = tvb_get_guint8(tvb, 5) >> 7;
2027
2028 ndp_tree = proto_tree_add_subtree(tree, tvb, offset, 6, ett_s1g_ndp,
2029 &ndp_item, "S1G NDP");
2030
2031 switch (ndp_type & 0x07) {
2032 case S1G_NDP_PROBE_REQ:
2033 proto_tree_add_item(ndp_tree, hf_radiotap_s1g_ndp_mgmt, tvb, offset, 1,
2034 ENC_NA);
2035 break;
2036
2037 default:
2038 proto_tree_add_item(ndp_tree, hf_radiotap_s1g_ndp_ctrl, tvb, offset, 1,
2039 ENC_NA);
2040 }
2041 offset += 1;
2042
2043 col_append_str(pinfo->cinfo, COL_INFO, ", S1G");
2044
2045 switch (ndp_type & 0x07) {
2046 case S1G_NDP_CTS_CF_END: /* This uses an extra bit to distinguish */
2047 if (ndp_type & 0x8) { /* NDP CF-END */
2048 proto_item_append_text(ndp_item, " CF-End");
2049 if (ndp_bw == 0) {
2050 col_append_str(pinfo->cinfo, COL_INFO, " CF-End 1MHz");
2051 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2052 hf_radiotap_s1g_ndp_cf_end_1m,
2053 ett_s1g_ndp_cf_end, ndp_cf_end_1m_headers,
2054 ENC_LITTLE_ENDIAN);
2055 } else {
2056 col_append_str(pinfo->cinfo, COL_INFO, " CF-End 2MHz");
2057 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2058 hf_radiotap_s1g_ndp_cf_end_2m,
2059 ett_s1g_ndp_cf_end, ndp_cf_end_2m_headers,
2060 ENC_LITTLE_ENDIAN);
2061 }
2062 } else { /* NDP CTS */
2063 proto_item_append_text(ndp_item, " CTS");
2064 if (ndp_bw == 0) {
2065 col_append_str(pinfo->cinfo, COL_INFO, " CTS 1MHz");
2066 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2067 hf_radiotap_s1g_ndp_cts_1m,
2068 ett_s1g_ndp_cts, ndp_cts_1m_headers,
2069 ENC_LITTLE_ENDIAN);
2070 } else {
2071 col_append_str(pinfo->cinfo, COL_INFO, " CTS 2MHz");
2072 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2073 hf_radiotap_s1g_ndp_cts_2m,
2074 ett_s1g_ndp_cts, ndp_cts_2m_headers,
2075 ENC_LITTLE_ENDIAN);
2076 }
2077 }
2078 break;
2079
2080 case S1G_NDP_PS_POLL:
2081 proto_item_append_text(ndp_item, " PS-Poll");
2082 if (ndp_bw == 0) {
2083 col_append_str(pinfo->cinfo, COL_INFO, " PS-Poll 1MHz");
2084 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2085 hf_radiotap_s1g_ndp_ps_poll_1m,
2086 ett_s1g_ndp_ps_poll, ndp_ps_poll_1m_headers,
2087 ENC_LITTLE_ENDIAN);
2088 } else {
2089 col_append_str(pinfo->cinfo, COL_INFO, " PS-Poll 2MHz");
2090 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2091 hf_radiotap_s1g_ndp_ps_poll_2m,
2092 ett_s1g_ndp_ps_poll, ndp_ps_poll_2m_headers,
2093 ENC_LITTLE_ENDIAN);
2094 }
2095 break;
2096
2097 case S1G_NDP_ACK:
2098 proto_item_append_text(ndp_item, " Ack");
2099 if (ndp_bw == 0) {
2100 col_append_str(pinfo->cinfo, COL_INFO, " ACK 1MHz");
2101 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2102 hf_radiotap_s1g_ndp_ack_1m,
2103 ett_s1g_ndp_ack, ndp_ack_1m_headers,
2104 ENC_LITTLE_ENDIAN);
2105 } else {
2106 col_append_str(pinfo->cinfo, COL_INFO, " ACK 2MHz");
2107 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2108 hf_radiotap_s1g_ndp_ack_2m,
2109 ett_s1g_ndp_ack, ndp_ack_2m_headers,
2110 ENC_LITTLE_ENDIAN);
2111 }
2112 break;
2113
2114 case S1G_NDP_PS_POLL_ACK:
2115 proto_item_append_text(ndp_item, " PS-Poll-Ack");
2116 if (ndp_bw == 0) {
2117 col_append_str(pinfo->cinfo, COL_INFO, " PS-Poll-Ack 1MHz");
2118 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2119 hf_radiotap_s1g_ndp_ps_poll_ack_1m,
2120 ett_s1g_ndp_ps_poll_ack, ndp_ps_poll_ack_1m_headers,
2121 ENC_LITTLE_ENDIAN);
2122 } else {
2123 col_append_str(pinfo->cinfo, COL_INFO, " PS-Poll-Ack 2MHz");
2124 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2125 hf_radiotap_s1g_ndp_ps_poll_ack_2m,
2126 ett_s1g_ndp_ps_poll_ack, ndp_ps_poll_ack_2m_headers,
2127 ENC_LITTLE_ENDIAN);
2128 }
2129 break;
2130
2131 case S1G_NDP_BLOCK_ACK:
2132 proto_item_append_text(ndp_item, " BlockAck");
2133 if (ndp_bw == 0) {
2134 col_append_str(pinfo->cinfo, COL_INFO, " BlockAck 1MHz");
2135 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2136 hf_radiotap_s1g_ndp_block_ack_1m,
2137 ett_s1g_ndp_block_ack, ndp_block_ack_1m_headers,
2138 ENC_LITTLE_ENDIAN);
2139 } else {
2140 col_append_str(pinfo->cinfo, COL_INFO, " BlockAck 2MHz");
2141 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2142 hf_radiotap_s1g_ndp_block_ack_2m,
2143 ett_s1g_ndp_block_ack, ndp_block_ack_2m_headers,
2144 ENC_LITTLE_ENDIAN);
2145 }
2146 break;
2147
2148 case S1G_NDP_BEAMFORMING_REPORT_POLL:
2149 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2150 hf_radiotap_s1g_ndp_beamforming_report_poll,
2151 ett_s1g_ndp_beamforming_report_poll, ndp_beamforming_headers,
2152 ENC_LITTLE_ENDIAN);
2153 break;
2154
2155 case S1G_NDP_PAGING:
2156 proto_item_append_text(ndp_item, " NDP Paging");
2157 if (ndp_bw == 0) {
2158 col_append_str(pinfo->cinfo, COL_INFO, " NDP Paging 1MHz");
2159 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2160 hf_radiotap_s1g_ndp_paging_1m,
2161 ett_s1g_ndp_paging, ndp_paging_1m_headers,
2162 ENC_LITTLE_ENDIAN);
2163 } else {
2164 col_append_str(pinfo->cinfo, COL_INFO, " NDP Paging 2MHz");
2165 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2166 hf_radiotap_s1g_ndp_paging_2m,
2167 ett_s1g_ndp_paging, ndp_paging_2m_headers,
2168 ENC_LITTLE_ENDIAN);
2169 }
2170 break;
2171
2172 case S1G_NDP_PROBE_REQ:
2173 proto_item_append_text(ndp_item, " Probe Request");
2174 if (ndp_bw == 0) {
2175 col_append_str(pinfo->cinfo, COL_INFO, " Probe Request 1MHz");
2176 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2177 hf_radiotap_s1g_ndp_probe_1m,
2178 ett_s1g_ndp_probe, ndp_probe_1m_headers,
2179 ENC_LITTLE_ENDIAN);
2180 } else {
2181 col_append_str(pinfo->cinfo, COL_INFO, " Probe Request 2MHz");
2182 proto_tree_add_bitmask(ndp_tree, tvb, offset,
2183 hf_radiotap_s1g_ndp_probe_2m,
2184 ett_s1g_ndp_probe, ndp_probe_2m_headers,
2185 ENC_LITTLE_ENDIAN);
2186 }
2187 break;
2188 default:
2189 proto_item_append_text(ndp_item, ", Unknown NDP type");
2190 col_append_str(pinfo->cinfo, COL_INFO, " Unknown NDP type");
2191 proto_tree_add_item(ndp_tree, hf_radiotap_s1g_ndp_bytes, tvb, offset,
2192 5, ENC_NA);
2193 }
2194
2195 return tvb_captured_length(tvb);
2196 }
2197
2198 static int * const s1g_known_headers[] = {
2199 &hf_radiotap_s1g_s1g_ppdu_format_known,
2200 &hf_radiotap_s1g_response_indication_known,
2201 &hf_radiotap_s1g_guard_interval_known,
2202 &hf_radiotap_s1g_nss_known,
2203 &hf_radiotap_s1g_bandwidth_known,
2204 &hf_radiotap_s1g_mcs_known,
2205 &hf_radiotap_s1g_color_known,
2206 &hf_radiotap_s1g_uplink_indication_known,
2207 &hf_radiotap_s1g_reserved_1,
2208 NULL
2209 };
2210
2211 static int * const s1g_data1_headers[] = {
2212 &hf_radiotap_s1g_s1g_ppdu_format,
2213 &hf_radiotap_s1g_response_indication,
2214 &hf_radiotap_s1g_reserved_2,
2215 &hf_radiotap_s1g_guard_interval,
2216 &hf_radiotap_s1g_nss,
2217 &hf_radiotap_s1g_bandwidth,
2218 &hf_radiotap_s1g_mcs,
2219 NULL
2220 };
2221
2222 static int * const s1g_data2_headers[] = {
2223 &hf_radiotap_s1g_color,
2224 &hf_radiotap_s1g_uplink_indication,
2225 &hf_radiotap_s1g_reserved_3,
2226 &hf_radiotap_s1g_rssi,
2227 NULL
2228 };
2229
2230 static void
dissect_radiotap_tlv(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr _U_)2231 dissect_radiotap_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
2232 int offset, struct ieee_802_11_phdr *phdr _U_)
2233 {
2234 guint16 type = tvb_get_letohs(tvb, offset);
2235 guint16 length = tvb_get_letohs(tvb, offset + 2);
2236 proto_tree *unknown_tlv = NULL;
2237 proto_tree *s1g_tree = NULL;
2238
2239 /* Insert code here to call the dissector for your TLV type */
2240 switch (type) {
2241 case IEEE80211_RADIOTAP_TLV_S1G:
2242 phdr->phy = PHDR_802_11_PHY_11AH;
2243 s1g_tree = proto_tree_add_subtree(tree, tvb, offset, 6,
2244 ett_radiotap_s1g, NULL, "S1G");
2245
2246 proto_tree_add_item(s1g_tree, hf_radiotap_tlv_type, tvb,
2247 offset, 2, ENC_LITTLE_ENDIAN);
2248 offset += 2;
2249
2250 proto_tree_add_item(s1g_tree, hf_radiotap_tlv_datalen, tvb,
2251 offset, 2, ENC_LITTLE_ENDIAN);
2252 offset += 2;
2253
2254 proto_tree_add_bitmask(s1g_tree, tvb, offset,
2255 hf_radiotap_s1g_known, ett_radiotap_s1g_known,
2256 s1g_known_headers, ENC_LITTLE_ENDIAN);
2257 offset += 2;
2258
2259 proto_tree_add_bitmask(s1g_tree, tvb, offset,
2260 hf_radiotap_s1g_data_1, ett_radiotap_s1g_data_1,
2261 s1g_data1_headers, ENC_LITTLE_ENDIAN);
2262 offset += 2;
2263
2264 proto_tree_add_bitmask(s1g_tree, tvb, offset,
2265 hf_radiotap_s1g_data_2, ett_radiotap_s1g_data_2,
2266 s1g_data2_headers, ENC_LITTLE_ENDIAN);
2267 break;
2268
2269 default:
2270 unknown_tlv = proto_tree_add_subtree(tree, tvb, offset,
2271 length + 4,
2272 ett_radiotap_unknown_tlv,
2273 NULL, "Unknown TLV");
2274 proto_tree_add_item(unknown_tlv, hf_radiotap_tlv_type, tvb,
2275 offset, 2, ENC_LITTLE_ENDIAN);
2276 offset += 2;
2277
2278 proto_tree_add_item(unknown_tlv, hf_radiotap_tlv_datalen, tvb,
2279 offset, 2, ENC_LITTLE_ENDIAN);
2280 offset += 2;
2281
2282 proto_tree_add_item(unknown_tlv, hf_radiotap_unknown_tlv_data,
2283 tvb, offset, length, ENC_NA);
2284 break;
2285 }
2286 }
2287
2288 static void
dissect_radiotap_tsft(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2289 dissect_radiotap_tsft(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
2290 int offset, struct ieee_802_11_phdr *phdr)
2291 {
2292 phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset);
2293 phdr->has_tsf_timestamp = TRUE;
2294 proto_tree_add_uint64(tree, hf_radiotap_mactime, tvb, offset, 8,
2295 phdr->tsf_timestamp);
2296 }
2297
2298 static void
dissect_radiotap_flags(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint8 * rflags,struct ieee_802_11_phdr * phdr)2299 dissect_radiotap_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
2300 int offset, guint8 *rflags, struct ieee_802_11_phdr *phdr)
2301 {
2302 proto_tree *ft;
2303 proto_tree *flags_tree;
2304
2305 *rflags = tvb_get_guint8(tvb, offset);
2306 if (*rflags & IEEE80211_RADIOTAP_F_DATAPAD)
2307 phdr->datapad = TRUE;
2308 switch (radiotap_fcs_handling) {
2309
2310 case USE_FCS_BIT:
2311 if (*rflags & IEEE80211_RADIOTAP_F_FCS)
2312 phdr->fcs_len = 4;
2313 else
2314 phdr->fcs_len = 0;
2315 break;
2316
2317 case ASSUME_FCS_PRESENT:
2318 phdr->fcs_len = 4;
2319 break;
2320
2321 case ASSUME_FCS_ABSENT:
2322 phdr->fcs_len = 0;
2323 break;
2324 }
2325 ft = proto_tree_add_item(tree, hf_radiotap_flags, tvb, offset,
2326 1, ENC_LITTLE_ENDIAN);
2327 flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags);
2328
2329 proto_tree_add_item(flags_tree, hf_radiotap_flags_cfp, tvb, offset,
2330 1, ENC_LITTLE_ENDIAN);
2331 proto_tree_add_item(flags_tree, hf_radiotap_flags_preamble, tvb, offset,
2332 1, ENC_LITTLE_ENDIAN);
2333 proto_tree_add_item(flags_tree, hf_radiotap_flags_wep, tvb, offset, 1,
2334 ENC_LITTLE_ENDIAN);
2335 proto_tree_add_item(flags_tree, hf_radiotap_flags_frag, tvb, offset, 1,
2336 ENC_LITTLE_ENDIAN);
2337 proto_tree_add_item(flags_tree, hf_radiotap_flags_fcs, tvb, offset, 1,
2338 ENC_LITTLE_ENDIAN);
2339 proto_tree_add_item(flags_tree, hf_radiotap_flags_datapad, tvb, offset,
2340 1, ENC_LITTLE_ENDIAN);
2341 proto_tree_add_item(flags_tree, hf_radiotap_flags_badfcs, tvb, offset,
2342 1, ENC_LITTLE_ENDIAN);
2343 proto_tree_add_item(flags_tree, hf_radiotap_flags_shortgi, tvb, offset,
2344 1, ENC_LITTLE_ENDIAN);
2345 }
2346
2347 static void
dissect_radiotap_rate(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2348 dissect_radiotap_rate(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
2349 int offset, struct ieee_802_11_phdr *phdr)
2350 {
2351 guint32 rate;
2352
2353 rate = tvb_get_guint8(tvb, offset);
2354 /*
2355 * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2356 * Linux and AirPcap it does not. (What about
2357 * macOS, NetBSD, OpenBSD, and DragonFly BSD?)
2358 *
2359 * This is an issue either for proprietary extensions
2360 * to 11a or 11g, which do exist, or for 11n
2361 * implementations that stuff a rate value into
2362 * this field, which also appear to exist.
2363 */
2364 if (radiotap_interpret_high_rates_as_mcs &&
2365 rate >= 0x80 && rate <= (0x80+76)) {
2366 /*
2367 * XXX - we don't know the channel width
2368 * or guard interval length, so we can't
2369 * convert this to a data rate.
2370 *
2371 * If you want us to show a data rate,
2372 * use the MCS field, not the Rate field;
2373 * the MCS field includes not only the
2374 * MCS index, it also includes bandwidth
2375 * and guard interval information.
2376 *
2377 * XXX - can we get the channel width
2378 * from XChannel and the guard interval
2379 * information from Flags, at least on
2380 * FreeBSD?
2381 */
2382 proto_tree_add_uint(tree, hf_radiotap_mcs_index, tvb, offset,
2383 1, rate & 0x7f);
2384 } else {
2385 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d",
2386 rate / 2, rate & 1 ? 5 : 0);
2387 proto_tree_add_float_format(tree, hf_radiotap_datarate,
2388 tvb, offset, 1, (float)rate / 2,
2389 "Data Rate: %.1f Mb/s",
2390 (float)rate / 2);
2391 phdr->has_data_rate = TRUE;
2392 phdr->data_rate = rate;
2393 }
2394 }
2395
2396 static void
dissect_radiotap_channel(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2397 dissect_radiotap_channel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
2398 int offset, struct ieee_802_11_phdr *phdr)
2399 {
2400 guint32 freq;
2401 guint16 cflags;
2402
2403 freq = tvb_get_letohs(tvb, offset);
2404 if (freq != 0) {
2405 /*
2406 * XXX - some captures have 0, which is
2407 * obviously bogus.
2408 */
2409 gint calc_channel;
2410
2411 phdr->has_frequency = TRUE;
2412 phdr->frequency = freq;
2413 calc_channel = ieee80211_mhz_to_chan(freq);
2414 if (calc_channel != -1) {
2415 phdr->has_channel = TRUE;
2416 phdr->channel = calc_channel;
2417 }
2418 }
2419 memset(&phdr->phy_info, 0, sizeof(phdr->phy_info));
2420 cflags = tvb_get_letohs(tvb, offset + 2);
2421 switch (cflags & IEEE80211_CHAN_ALLTURBO) {
2422
2423 case IEEE80211_CHAN_FHSS:
2424 phdr->phy = PHDR_802_11_PHY_11_FHSS;
2425 break;
2426
2427 case IEEE80211_CHAN_DSSS:
2428 phdr->phy = PHDR_802_11_PHY_11_DSSS;
2429 break;
2430
2431 case IEEE80211_CHAN_A:
2432 phdr->phy = PHDR_802_11_PHY_11A;
2433 phdr->phy_info.info_11a.has_turbo_type = TRUE;
2434 phdr->phy_info.info_11a.turbo_type = PHDR_802_11A_TURBO_TYPE_NORMAL;
2435 break;
2436
2437 case IEEE80211_CHAN_B:
2438 phdr->phy = PHDR_802_11_PHY_11B;
2439 break;
2440
2441 case IEEE80211_CHAN_PUREG:
2442 case IEEE80211_CHAN_G:
2443 /*
2444 * One of those means, in theory, that there should
2445 * only be ERP-OFDM traffic, and the other means that
2446 * there could be both ERP-DSSS and ERP-OFDM traffic.
2447 *
2448 * For now, we treat it as 11g; later, we'll check
2449 * the rate and, if it's a DSSS rate, mark it as 11b,
2450 * instead.
2451 */
2452 phdr->phy = PHDR_802_11_PHY_11G;
2453 phdr->phy_info.info_11g.has_mode = TRUE;
2454 phdr->phy_info.info_11g.mode = PHDR_802_11G_MODE_NORMAL;
2455 break;
2456
2457 case IEEE80211_CHAN_108A:
2458 phdr->phy = PHDR_802_11_PHY_11A;
2459 phdr->phy_info.info_11a.has_turbo_type = TRUE;
2460 /* We assume non-STURBO is dynamic turbo */
2461 phdr->phy_info.info_11a.turbo_type = PHDR_802_11A_TURBO_TYPE_DYNAMIC_TURBO;
2462 break;
2463
2464 case IEEE80211_CHAN_108PUREG:
2465 phdr->phy = PHDR_802_11_PHY_11G;
2466 phdr->phy_info.info_11g.has_mode = TRUE;
2467 phdr->phy_info.info_11g.mode = PHDR_802_11G_MODE_SUPER_G;
2468 break;
2469 }
2470
2471 /*
2472 * XXX - special-case 11ad; there's no field to explicitly indicate
2473 * an 11ad packet. Anything with a frequency in the 802.11ad range
2474 * is treated as 11ad.
2475 */
2476 if (IS_80211AD(freq))
2477 phdr->phy = PHDR_802_11_PHY_11AD;
2478
2479 if (tree) {
2480 gchar *chan_str;
2481 static int * const channel_flags[] = {
2482 &hf_radiotap_channel_flags_700mhz,
2483 &hf_radiotap_channel_flags_800mhz,
2484 &hf_radiotap_channel_flags_900mhz,
2485 &hf_radiotap_channel_flags_turbo,
2486 &hf_radiotap_channel_flags_cck,
2487 &hf_radiotap_channel_flags_ofdm,
2488 &hf_radiotap_channel_flags_2ghz,
2489 &hf_radiotap_channel_flags_5ghz,
2490 &hf_radiotap_channel_flags_passive,
2491 &hf_radiotap_channel_flags_dynamic,
2492 &hf_radiotap_channel_flags_gfsk,
2493 &hf_radiotap_channel_flags_gsm,
2494 &hf_radiotap_channel_flags_sturbo,
2495 &hf_radiotap_channel_flags_half,
2496 &hf_radiotap_channel_flags_quarter,
2497 NULL
2498 };
2499
2500 chan_str = ieee80211_mhz_to_str(freq);
2501 col_add_fstr(pinfo->cinfo,
2502 COL_FREQ_CHAN, "%s", chan_str);
2503 proto_tree_add_uint_format_value(tree,
2504 hf_radiotap_channel_frequency,
2505 tvb, offset, 2, freq,
2506 "%s",
2507 chan_str);
2508 g_free(chan_str);
2509
2510 /* We're already 2-byte aligned. */
2511 proto_tree_add_bitmask(tree, tvb, offset + 2,
2512 hf_radiotap_channel_flags,
2513 ett_radiotap_channel_flags,
2514 channel_flags, ENC_LITTLE_ENDIAN);
2515 }
2516 }
2517
2518 static void
dissect_radiotap_fhss(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2519 dissect_radiotap_fhss(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
2520 int offset, struct ieee_802_11_phdr *phdr)
2521 {
2522 /*
2523 * Just in case we didn't have a Channel field or
2524 * it said this was something other than 11 legacy
2525 * FHSS.
2526 */
2527 phdr->phy = PHDR_802_11_PHY_11_FHSS;
2528 phdr->phy_info.info_11_fhss.has_hop_set = TRUE;
2529 phdr->phy_info.info_11_fhss.hop_set = tvb_get_guint8(tvb, offset);
2530 phdr->phy_info.info_11_fhss.has_hop_pattern = TRUE;
2531 phdr->phy_info.info_11_fhss.hop_pattern = tvb_get_guint8(tvb, offset + 1);
2532 proto_tree_add_item(tree, hf_radiotap_fhss_hopset, tvb, offset, 1,
2533 ENC_LITTLE_ENDIAN);
2534 proto_tree_add_item(tree, hf_radiotap_fhss_pattern, tvb, offset + 1, 1,
2535 ENC_LITTLE_ENDIAN);
2536 }
2537
2538 static void
dissect_radiotap_dbm_antsignal(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2539 dissect_radiotap_dbm_antsignal(tvbuff_t *tvb, packet_info *pinfo _U_,
2540 proto_tree *tree, int offset, struct ieee_802_11_phdr *phdr)
2541 {
2542 gint8 dbm = tvb_get_gint8(tvb, offset);
2543
2544 phdr->has_signal_dbm = TRUE;
2545 phdr->signal_dbm = dbm;
2546 col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
2547 proto_tree_add_int(tree, hf_radiotap_dbm_antsignal, tvb, offset, 1, dbm);
2548
2549 }
2550
2551 static void
dissect_radiotap_dbm_antnoise(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2552 dissect_radiotap_dbm_antnoise(tvbuff_t *tvb, packet_info *pinfo _U_,
2553 proto_tree *tree, int offset, struct ieee_802_11_phdr *phdr)
2554 {
2555 gint dbm = tvb_get_gint8(tvb, offset);
2556
2557 phdr->has_noise_dbm = TRUE;
2558 phdr->noise_dbm = dbm;
2559 if (tree) {
2560 proto_tree_add_int(tree, hf_radiotap_dbm_antnoise, tvb, offset,
2561 1, dbm);
2562 }
2563 }
2564
2565 static void
dissect_radiotap_db_antsignal(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2566 dissect_radiotap_db_antsignal(tvbuff_t *tvb, packet_info *pinfo _U_,
2567 proto_tree *tree, int offset, struct ieee_802_11_phdr *phdr)
2568 {
2569 guint8 db = tvb_get_guint8(tvb, offset);
2570
2571 phdr->has_signal_db = TRUE;
2572 phdr->signal_db = db;
2573 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db);
2574 proto_tree_add_uint(tree, hf_radiotap_db_antsignal, tvb, offset, 1, db);
2575 }
2576
2577 static void
dissect_radiotap_db_antnoise(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2578 dissect_radiotap_db_antnoise(tvbuff_t *tvb, packet_info *pinfo _U_,
2579 proto_tree *tree, int offset, struct ieee_802_11_phdr *phdr)
2580 {
2581 guint db = tvb_get_guint8(tvb, offset);
2582
2583 phdr->has_noise_db = TRUE;
2584 phdr->noise_db = db;
2585 if (tree) {
2586 proto_tree_add_uint(tree, hf_radiotap_db_antnoise, tvb, offset,
2587 1, db);
2588 }
2589 }
2590
2591 static void
dissect_radiotap_rx_flags(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,proto_item ** hdr_fcs_ti,int * hdr_fcs_offset,int * sent_fcs)2592 dissect_radiotap_rx_flags(tvbuff_t *tvb, packet_info *pinfo _U_,
2593 proto_tree *tree, int offset, proto_item **hdr_fcs_ti,
2594 int *hdr_fcs_offset, int *sent_fcs)
2595 {
2596 if (radiotap_bit14_fcs) {
2597 if (tree) {
2598 *sent_fcs = tvb_get_ntohl(tvb, offset);
2599 *hdr_fcs_ti = proto_tree_add_uint(tree,
2600 hf_radiotap_fcs, tvb,
2601 offset, 4, *sent_fcs);
2602 *hdr_fcs_offset = offset;
2603 }
2604 } else {
2605 static int * const rxflags[] = {
2606 &hf_radiotap_rxflags_badplcp,
2607 NULL
2608 };
2609
2610 proto_tree_add_bitmask(tree, tvb, offset,
2611 hf_radiotap_rxflags, ett_radiotap_rxflags,
2612 rxflags, ENC_LITTLE_ENDIAN);
2613 }
2614 }
2615
2616
2617 static void
dissect_radiotap_tx_flags(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)2618 dissect_radiotap_tx_flags(tvbuff_t *tvb, packet_info *pinfo _U_,
2619 proto_tree *tree, int offset)
2620 {
2621 static int * const txflags[] = {
2622 &hf_radiotap_txflags_fail,
2623 &hf_radiotap_txflags_cts,
2624 &hf_radiotap_txflags_rts,
2625 &hf_radiotap_txflags_noack,
2626 &hf_radiotap_txflags_noseqno,
2627 &hf_radiotap_txflags_order,
2628 NULL
2629 };
2630
2631 proto_tree_add_bitmask(tree, tvb, offset,
2632 hf_radiotap_txflags, ett_radiotap_txflags,
2633 txflags, ENC_LITTLE_ENDIAN);
2634 }
2635
2636 static void
dissect_radiotap_xchannel(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr)2637 dissect_radiotap_xchannel(tvbuff_t *tvb, packet_info *pinfo _U_,
2638 proto_tree *tree, int offset, struct ieee_802_11_phdr *phdr)
2639 {
2640 guint32 xcflags = tvb_get_letohl(tvb, offset);
2641 guint32 freq;
2642
2643 switch (xcflags & IEEE80211_CHAN_ALLTURBO) {
2644
2645 case IEEE80211_CHAN_FHSS:
2646 phdr->phy = PHDR_802_11_PHY_11_FHSS;
2647 break;
2648
2649 case IEEE80211_CHAN_DSSS:
2650 phdr->phy = PHDR_802_11_PHY_11_DSSS;
2651 break;
2652
2653 case IEEE80211_CHAN_A:
2654 phdr->phy = PHDR_802_11_PHY_11A;
2655 phdr->phy_info.info_11a.has_turbo_type = TRUE;
2656 phdr->phy_info.info_11a.turbo_type = PHDR_802_11A_TURBO_TYPE_NORMAL;
2657 break;
2658
2659 case IEEE80211_CHAN_B:
2660 phdr->phy = PHDR_802_11_PHY_11B;
2661 break;
2662
2663 case IEEE80211_CHAN_PUREG:
2664 case IEEE80211_CHAN_G:
2665 phdr->phy = PHDR_802_11_PHY_11G;
2666 phdr->phy_info.info_11g.has_mode = TRUE;
2667 phdr->phy_info.info_11g.mode = PHDR_802_11G_MODE_NORMAL;
2668 break;
2669
2670 case IEEE80211_CHAN_108A:
2671 phdr->phy = PHDR_802_11_PHY_11A;
2672 phdr->phy_info.info_11a.has_turbo_type = TRUE;
2673 /* We assume non-STURBO is dynamic turbo */
2674 phdr->phy_info.info_11a.turbo_type = PHDR_802_11A_TURBO_TYPE_DYNAMIC_TURBO;
2675 break;
2676
2677 case IEEE80211_CHAN_108PUREG:
2678 phdr->phy = PHDR_802_11_PHY_11G;
2679 phdr->phy_info.info_11g.has_mode = TRUE;
2680 phdr->phy_info.info_11g.mode = PHDR_802_11G_MODE_SUPER_G;
2681 break;
2682
2683 case IEEE80211_CHAN_ST:
2684 phdr->phy = PHDR_802_11_PHY_11A;
2685 phdr->phy_info.info_11a.has_turbo_type = TRUE;
2686 phdr->phy_info.info_11a.turbo_type = PHDR_802_11A_TURBO_TYPE_STATIC_TURBO;
2687 break;
2688
2689 case IEEE80211_CHAN_A|IEEE80211_CHAN_HT20:
2690 case IEEE80211_CHAN_A|IEEE80211_CHAN_HT40D:
2691 case IEEE80211_CHAN_A|IEEE80211_CHAN_HT40U:
2692 case IEEE80211_CHAN_G|IEEE80211_CHAN_HT20:
2693 case IEEE80211_CHAN_G|IEEE80211_CHAN_HT40U:
2694 case IEEE80211_CHAN_G|IEEE80211_CHAN_HT40D:
2695 phdr->phy = PHDR_802_11_PHY_11N;
2696 break;
2697 }
2698 freq = tvb_get_letohs(tvb, offset + 4);
2699 if (freq != 0) {
2700 /*
2701 * XXX - some captures have 0, which is
2702 * obviously bogus.
2703 */
2704 phdr->has_frequency = TRUE;
2705 phdr->frequency = freq;
2706
2707 /*
2708 * XXX - special-case 11ad; there's no field to explicitly
2709 * indicate an 11ad packet. Anything with a frequency in
2710 * the 802.11ad range is treated as 11ad.
2711 */
2712 if (IS_80211AD(freq))
2713 phdr->phy = PHDR_802_11_PHY_11AD;
2714 }
2715 phdr->has_channel = TRUE;
2716 phdr->channel = tvb_get_guint8(tvb, offset + 6);
2717 if (tree) {
2718 static int * const xchannel_flags[] = {
2719 &hf_radiotap_xchannel_flags_turbo,
2720 &hf_radiotap_xchannel_flags_cck,
2721 &hf_radiotap_xchannel_flags_ofdm,
2722 &hf_radiotap_xchannel_flags_2ghz,
2723 &hf_radiotap_xchannel_flags_5ghz,
2724 &hf_radiotap_xchannel_flags_passive,
2725 &hf_radiotap_xchannel_flags_dynamic,
2726 &hf_radiotap_xchannel_flags_gfsk,
2727 &hf_radiotap_xchannel_flags_gsm,
2728 &hf_radiotap_xchannel_flags_sturbo,
2729 &hf_radiotap_xchannel_flags_half,
2730 &hf_radiotap_xchannel_flags_quarter,
2731 &hf_radiotap_xchannel_flags_ht20,
2732 &hf_radiotap_xchannel_flags_ht40u,
2733 &hf_radiotap_xchannel_flags_ht40d,
2734 NULL
2735 };
2736
2737 proto_tree_add_item(tree, hf_radiotap_xchannel_channel,
2738 tvb, offset + 6, 1,
2739 ENC_LITTLE_ENDIAN);
2740 proto_tree_add_item(tree, hf_radiotap_xchannel_frequency,
2741 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
2742
2743 proto_tree_add_bitmask(tree, tvb, offset, hf_radiotap_xchannel_flags,
2744 ett_radiotap_xchannel_flags,
2745 xchannel_flags, ENC_LITTLE_ENDIAN);
2746
2747
2748 #if 0
2749 proto_tree_add_uint(tree, hf_radiotap_xchannel_maxpower,
2750 tvb, offset + 7, 1, maxpower);
2751 #endif
2752 }
2753 }
2754
2755 static void
dissect_radiotap_timestamp(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,struct ieee_802_11_phdr * phdr _U_)2756 dissect_radiotap_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_,
2757 proto_tree *tree, int offset, struct ieee_802_11_phdr *phdr _U_)
2758 {
2759 proto_item *it_root;
2760 proto_tree *ts_tree, *flg_tree;
2761
2762 it_root = proto_tree_add_item(tree, hf_radiotap_timestamp, tvb, offset,
2763 12, ENC_NA);
2764 ts_tree = proto_item_add_subtree(it_root, ett_radiotap_timestamp);
2765
2766 proto_tree_add_item(ts_tree, hf_radiotap_timestamp_ts, tvb, offset, 8,
2767 ENC_LITTLE_ENDIAN);
2768 if (tvb_get_letohs(tvb, offset + 11) & IEEE80211_RADIOTAP_TS_FLG_ACCURACY)
2769 proto_tree_add_item(ts_tree, hf_radiotap_timestamp_accuracy,
2770 tvb, offset + 8, 2, ENC_LITTLE_ENDIAN);
2771 proto_tree_add_item(ts_tree, hf_radiotap_timestamp_unit, tvb,
2772 offset + 10, 1, ENC_LITTLE_ENDIAN);
2773 proto_tree_add_item(ts_tree, hf_radiotap_timestamp_spos, tvb,
2774 offset + 10, 1, ENC_LITTLE_ENDIAN);
2775 flg_tree = proto_item_add_subtree(ts_tree, ett_radiotap_timestamp_flags);
2776 proto_tree_add_item(flg_tree, hf_radiotap_timestamp_flags_32bit, tvb,
2777 offset + 11, 1, ENC_LITTLE_ENDIAN);
2778 proto_tree_add_item(flg_tree, hf_radiotap_timestamp_flags_accuracy, tvb,
2779 offset + 11, 1, ENC_LITTLE_ENDIAN);
2780 }
2781
2782 static int
dissect_radiotap(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * unused_data _U_)2783 dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* unused_data _U_)
2784 {
2785 proto_tree *radiotap_tree = NULL;
2786 proto_item *length_item = NULL;
2787 proto_item *present_item = NULL;
2788 proto_tree *present_tree = NULL;
2789 proto_item *present_word_item = NULL;
2790 proto_tree *present_word_tree = NULL;
2791 proto_item *ti = NULL;
2792 proto_item *hidden_item;
2793 int offset;
2794 tvbuff_t *next_tvb;
2795 guint8 version;
2796 guint length;
2797 proto_item *rate_ti;
2798 gboolean have_rflags = FALSE;
2799 guint8 rflags = 0;
2800 /* backward compat with bit 14 == fcs in header */
2801 proto_item *hdr_fcs_ti = NULL;
2802 int hdr_fcs_offset = 0;
2803 guint32 sent_fcs = 0;
2804 guint32 calc_fcs;
2805 gint err = -ENOENT;
2806 void *data;
2807 struct ieee80211_radiotap_iterator iter;
2808 struct ieee_802_11_phdr phdr;
2809 guchar *bmap_start;
2810 guint n_bitmaps;
2811 guint i;
2812 gboolean rtap_ns;
2813 gboolean rtap_ns_next;
2814 guint rtap_ns_offset;
2815 guint rtap_ns_offset_next;
2816 gboolean zero_length_psdu = FALSE;
2817 guint32 ven_ns_id;
2818 tvbuff_t *ven_data_tvb;
2819
2820 /* our non-standard overrides */
2821 static struct radiotap_override overrides[] = {
2822 {IEEE80211_RADIOTAP_XCHANNEL, 4, 8}, /* xchannel */
2823
2824 /* keep last */
2825 {14, 4, 4}, /* FCS in header */
2826 };
2827 guint n_overrides = array_length(overrides);
2828
2829 if (!radiotap_bit14_fcs)
2830 n_overrides--;
2831
2832 /* We don't have any 802.11 metadata yet. */
2833 memset(&phdr, 0, sizeof(phdr));
2834 phdr.fcs_len = -1;
2835 phdr.decrypted = FALSE;
2836 phdr.datapad = FALSE;
2837 phdr.phy = PHDR_802_11_PHY_UNKNOWN;
2838
2839 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
2840 col_clear(pinfo->cinfo, COL_INFO);
2841
2842 version = tvb_get_guint8(tvb, 0);
2843 length = tvb_get_letohs(tvb, 2);
2844
2845 col_add_fstr(pinfo->cinfo, COL_INFO, "Radiotap Capture v%u, Length %u",
2846 version, length);
2847
2848 /* Dissect the packet */
2849 if (tree) {
2850 ti = proto_tree_add_protocol_format(tree, proto_radiotap,
2851 tvb, 0, length,
2852 "Radiotap Header v%u, Length %u",
2853 version, length);
2854 radiotap_tree = proto_item_add_subtree(ti, ett_radiotap);
2855 proto_tree_add_uint(radiotap_tree, hf_radiotap_version,
2856 tvb, 0, 1, version);
2857 proto_tree_add_item(radiotap_tree, hf_radiotap_pad,
2858 tvb, 1, 1, ENC_LITTLE_ENDIAN);
2859 length_item = proto_tree_add_uint(radiotap_tree, hf_radiotap_length,
2860 tvb, 2, 2, length);
2861 }
2862
2863 /*
2864 * The length is the length of the entire radiotap header, so it
2865 * must be at least 8, for the version, padding, length, and first
2866 * presence flags word.
2867 */
2868 if (length < 8) {
2869 expert_add_info(pinfo, length_item,
2870 &ei_radiotap_invalid_header_length);
2871 return tvb_captured_length(tvb);
2872 }
2873
2874 data = tvb_memdup(pinfo->pool, tvb, 0, length);
2875
2876 if (ieee80211_radiotap_iterator_init(&iter, (struct ieee80211_radiotap_header *)data, length, NULL)) {
2877 if (tree)
2878 proto_item_append_text(ti, " (invalid)");
2879 /* maybe the length was correct anyway ... */
2880 goto hand_off_to_80211;
2881 }
2882
2883 iter.overrides = overrides;
2884 iter.n_overrides = n_overrides;
2885
2886 /*
2887 * Check the "present flags" bitmaps, and add them if we're
2888 * building a tree.
2889 */
2890 bmap_start = (guchar *)data + 4;
2891 n_bitmaps = (guint)(iter.this_arg - bmap_start) / 4;
2892 rtap_ns_next = TRUE;
2893 rtap_ns_offset_next = 0;
2894 present_item = proto_tree_add_item(radiotap_tree,
2895 hf_radiotap_present, tvb, 4, n_bitmaps * 4, ENC_NA);
2896 present_tree = proto_item_add_subtree(present_item,
2897 ett_radiotap_present);
2898
2899 for (i = 0; i < n_bitmaps; i++) {
2900 guint32 bmap = pletoh32(bmap_start + 4 * i);
2901
2902 rtap_ns_offset = rtap_ns_offset_next;
2903 rtap_ns_offset_next += 32;
2904
2905 offset = 4 * i;
2906
2907 present_word_item =
2908 proto_tree_add_item(present_tree,
2909 hf_radiotap_present_word,
2910 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2911
2912 present_word_tree =
2913 proto_item_add_subtree(present_word_item,
2914 ett_radiotap_present_word);
2915
2916 rtap_ns = rtap_ns_next;
2917
2918 /* Evaluate what kind of namespaces will come next */
2919 if (bmap & BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)) {
2920 rtap_ns_next = TRUE;
2921 rtap_ns_offset_next = 0;
2922 }
2923 if (bmap & BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))
2924 rtap_ns_next = FALSE;
2925 if ((bmap & (BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) |
2926 BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)))
2927 == (BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) |
2928 BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) {
2929 expert_add_info_format(pinfo, present_word_item,
2930 &ei_radiotap_present,
2931 "Both radiotap and vendor namespace specified in bitmask word %u",
2932 i);
2933 goto malformed;
2934 }
2935
2936 if (!rtap_ns)
2937 goto always_bits;
2938
2939 /* Currently, we don't know anything about bits >= 32 */
2940 if (rtap_ns_offset)
2941 goto always_bits;
2942
2943 if (tree) {
2944 proto_tree_add_item(present_word_tree,
2945 hf_radiotap_present_tsft, tvb,
2946 offset + 4, 4, ENC_LITTLE_ENDIAN);
2947 proto_tree_add_item(present_word_tree,
2948 hf_radiotap_present_flags, tvb,
2949 offset + 4, 4, ENC_LITTLE_ENDIAN);
2950 proto_tree_add_item(present_word_tree,
2951 hf_radiotap_present_rate, tvb,
2952 offset + 4, 4, ENC_LITTLE_ENDIAN);
2953 proto_tree_add_item(present_word_tree,
2954 hf_radiotap_present_channel, tvb,
2955 offset + 4, 4, ENC_LITTLE_ENDIAN);
2956 proto_tree_add_item(present_word_tree,
2957 hf_radiotap_present_fhss, tvb,
2958 offset + 4, 4, ENC_LITTLE_ENDIAN);
2959 proto_tree_add_item(present_word_tree,
2960 hf_radiotap_present_dbm_antsignal,
2961 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2962 proto_tree_add_item(present_word_tree,
2963 hf_radiotap_present_dbm_antnoise,
2964 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2965 proto_tree_add_item(present_word_tree,
2966 hf_radiotap_present_lock_quality,
2967 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2968 proto_tree_add_item(present_word_tree,
2969 hf_radiotap_present_tx_attenuation,
2970 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2971 proto_tree_add_item(present_word_tree,
2972 hf_radiotap_present_db_tx_attenuation,
2973 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2974 proto_tree_add_item(present_word_tree,
2975 hf_radiotap_present_dbm_tx_power,
2976 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2977 proto_tree_add_item(present_word_tree,
2978 hf_radiotap_present_antenna, tvb,
2979 offset + 4, 4, ENC_LITTLE_ENDIAN);
2980 proto_tree_add_item(present_word_tree,
2981 hf_radiotap_present_db_antsignal,
2982 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2983 proto_tree_add_item(present_word_tree,
2984 hf_radiotap_present_db_antnoise,
2985 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2986 if (radiotap_bit14_fcs) {
2987 proto_tree_add_item(present_word_tree,
2988 hf_radiotap_present_hdrfcs,
2989 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2990 } else {
2991 proto_tree_add_item(present_word_tree,
2992 hf_radiotap_present_rxflags,
2993 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
2994 }
2995 proto_tree_add_item(present_word_tree,
2996 hf_radiotap_present_txflags, tvb,
2997 offset + 4, 4, ENC_LITTLE_ENDIAN);
2998 proto_tree_add_item(present_word_tree,
2999 hf_radiotap_present_data_retries, tvb,
3000 offset + 4, 4, ENC_LITTLE_ENDIAN);
3001 proto_tree_add_item(present_word_tree,
3002 hf_radiotap_present_xchannel, tvb,
3003 offset + 4, 4, ENC_LITTLE_ENDIAN);
3004
3005 proto_tree_add_item(present_word_tree,
3006 hf_radiotap_present_mcs, tvb,
3007 offset + 4, 4, ENC_LITTLE_ENDIAN);
3008 proto_tree_add_item(present_word_tree,
3009 hf_radiotap_present_ampdu, tvb,
3010 offset + 4, 4, ENC_LITTLE_ENDIAN);
3011 proto_tree_add_item(present_word_tree,
3012 hf_radiotap_present_vht, tvb,
3013 offset + 4, 4, ENC_LITTLE_ENDIAN);
3014 proto_tree_add_item(present_word_tree,
3015 hf_radiotap_present_timestamp, tvb,
3016 offset + 4, 4, ENC_LITTLE_ENDIAN);
3017 proto_tree_add_item(present_word_tree,
3018 hf_radiotap_present_he, tvb,
3019 offset + 4, 4, ENC_LITTLE_ENDIAN);
3020 proto_tree_add_item(present_word_tree,
3021 hf_radiotap_present_he_mu, tvb,
3022 offset + 4, 4, ENC_LITTLE_ENDIAN);
3023 proto_tree_add_item(present_word_tree,
3024 hf_radiotap_present_0_length_psdu,
3025 tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
3026 proto_tree_add_item(present_word_tree,
3027 hf_radiotap_present_l_sig, tvb,
3028 offset + 4, 4, ENC_LITTLE_ENDIAN);
3029 proto_tree_add_item(present_word_tree,
3030 hf_radiotap_present_tlv, tvb,
3031 offset + 4, 4, ENC_LITTLE_ENDIAN);
3032 }
3033 always_bits:
3034 if (tree) {
3035 proto_tree_add_item(present_word_tree,
3036 hf_radiotap_present_rtap_ns, tvb,
3037 offset + 4, 4, ENC_LITTLE_ENDIAN);
3038 proto_tree_add_item(present_word_tree,
3039 hf_radiotap_present_vendor_ns, tvb,
3040 offset + 4, 4, ENC_LITTLE_ENDIAN);
3041 proto_tree_add_item(present_word_tree,
3042 hf_radiotap_present_ext, tvb,
3043 offset + 4, 4, ENC_LITTLE_ENDIAN);
3044 }
3045 }
3046
3047 while (!(err = ieee80211_radiotap_iterator_next(&iter))) {
3048 proto_tree *item_tree = radiotap_tree;
3049
3050 offset = (int)((guchar *) iter.this_arg - (guchar *) data);
3051
3052 if (iter.tlv_mode) {
3053
3054 offset -= sizeof(struct ieee80211_radiotap_tlv);
3055
3056 dissect_radiotap_tlv(tvb, pinfo, radiotap_tree, offset,
3057 &phdr);
3058
3059 continue;
3060 }
3061
3062 if (iter.this_arg_index == IEEE80211_RADIOTAP_VENDOR_NAMESPACE
3063 && tree) {
3064 proto_tree *ven_tree;
3065 proto_item *vt;
3066 const gchar *manuf_name;
3067 guint8 subns;
3068
3069 manuf_name = tvb_get_manuf_name(tvb, offset);
3070 subns = tvb_get_guint8(tvb, offset+3);
3071
3072 vt = proto_tree_add_bytes_format_value(item_tree,
3073 hf_radiotap_vendor_ns,
3074 tvb, offset,
3075 iter.this_arg_size,
3076 NULL,
3077 "%s-%d",
3078 manuf_name, subns);
3079 ven_tree = proto_item_add_subtree(vt, ett_radiotap_vendor);
3080 /*
3081 * This is defined on the Radiotap site as an array
3082 * of 3 octets, containing an OUI, but we show fields
3083 * of that sort as a 24-bit big-endian field, so
3084 * ENC_BIG_ENDIAN is correct here.
3085 */
3086 proto_tree_add_item(ven_tree, hf_radiotap_ven_oui,
3087 tvb, offset, 3, ENC_BIG_ENDIAN);
3088 proto_tree_add_item(ven_tree, hf_radiotap_ven_subns,
3089 tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
3090 /* Get OUI and sub namespace as UINT32 */
3091 ven_ns_id = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
3092 if (iter.tlv_mode) {
3093 proto_tree_add_item(ven_tree, hf_radiotap_ven_item, tvb,
3094 offset + 4, 2, ENC_LITTLE_ENDIAN);
3095 ven_data_tvb = tvb_new_subset_length(tvb, offset + 8, iter.this_arg_size - 8);
3096 } else {
3097 proto_tree_add_item(ven_tree, hf_radiotap_ven_skip, tvb,
3098 offset + 4, 2, ENC_LITTLE_ENDIAN);
3099 ven_data_tvb = tvb_new_subset_length(tvb, offset + 6, iter.this_arg_size - 6);
3100 }
3101 if (!dissector_try_uint_new(vendor_dissector_table, ven_ns_id, ven_data_tvb, pinfo, ven_tree, TRUE, NULL)) {
3102 proto_tree_add_item(ven_tree, hf_radiotap_ven_data, ven_data_tvb, 0, -1, ENC_NA);
3103 }
3104 }
3105
3106 if (!iter.is_radiotap_ns)
3107 continue;
3108
3109 switch (iter.this_arg_index) {
3110
3111 case IEEE80211_RADIOTAP_TSFT:
3112 dissect_radiotap_tsft(tvb, pinfo, item_tree, offset,
3113 &phdr);
3114 break;
3115
3116 case IEEE80211_RADIOTAP_FLAGS:
3117 have_rflags = TRUE;
3118 dissect_radiotap_flags(tvb, pinfo, item_tree, offset,
3119 &rflags, &phdr);
3120 break;
3121
3122 case IEEE80211_RADIOTAP_RATE:
3123 dissect_radiotap_rate(tvb, pinfo, item_tree, offset,
3124 &phdr);
3125 break;
3126
3127 case IEEE80211_RADIOTAP_CHANNEL:
3128 dissect_radiotap_channel(tvb, pinfo, item_tree, offset,
3129 &phdr);
3130 break;
3131
3132 case IEEE80211_RADIOTAP_FHSS:
3133 dissect_radiotap_fhss(tvb, pinfo, item_tree, offset,
3134 &phdr);
3135 break;
3136
3137 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
3138 dissect_radiotap_dbm_antsignal(tvb, pinfo, item_tree,
3139 offset, &phdr);
3140 break;
3141
3142 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
3143 dissect_radiotap_dbm_antnoise(tvb, pinfo, item_tree,
3144 offset, &phdr);
3145 break;
3146
3147 case IEEE80211_RADIOTAP_LOCK_QUALITY:
3148 proto_tree_add_item(item_tree,
3149 hf_radiotap_quality, tvb,
3150 offset, 2, ENC_LITTLE_ENDIAN);
3151 break;
3152
3153 case IEEE80211_RADIOTAP_TX_ATTENUATION:
3154 proto_tree_add_item(item_tree,
3155 hf_radiotap_tx_attenuation, tvb,
3156 offset, 2, ENC_LITTLE_ENDIAN);
3157 break;
3158
3159 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
3160 proto_tree_add_item(item_tree,
3161 hf_radiotap_db_tx_attenuation, tvb,
3162 offset, 2, ENC_LITTLE_ENDIAN);
3163 break;
3164
3165 case IEEE80211_RADIOTAP_DBM_TX_POWER:
3166 proto_tree_add_item(item_tree,
3167 hf_radiotap_txpower, tvb,
3168 offset, 1, ENC_NA);
3169 break;
3170
3171 case IEEE80211_RADIOTAP_ANTENNA:
3172 proto_tree_add_item(item_tree,
3173 hf_radiotap_antenna, tvb,
3174 offset, 1, ENC_NA);
3175 break;
3176
3177 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
3178 dissect_radiotap_db_antsignal(tvb, pinfo, item_tree,
3179 offset, &phdr);
3180 break;
3181
3182 case IEEE80211_RADIOTAP_DB_ANTNOISE:
3183 dissect_radiotap_db_antnoise(tvb, pinfo, item_tree,
3184 offset, &phdr);
3185 break;
3186
3187 case IEEE80211_RADIOTAP_RX_FLAGS:
3188 dissect_radiotap_rx_flags(tvb, pinfo, item_tree,
3189 offset, &hdr_fcs_ti,
3190 &hdr_fcs_offset, &sent_fcs);
3191 break;
3192
3193 case IEEE80211_RADIOTAP_TX_FLAGS:
3194 dissect_radiotap_tx_flags(tvb, pinfo, item_tree,
3195 offset);
3196 break;
3197
3198 case IEEE80211_RADIOTAP_DATA_RETRIES:
3199 proto_tree_add_item(item_tree,
3200 hf_radiotap_data_retries, tvb,
3201 offset, 1, ENC_LITTLE_ENDIAN);
3202 break;
3203
3204 case IEEE80211_RADIOTAP_XCHANNEL:
3205 dissect_radiotap_xchannel(tvb, pinfo, item_tree,
3206 offset, &phdr);
3207 break;
3208
3209 case IEEE80211_RADIOTAP_MCS: {
3210 proto_tree *mcs_tree = NULL;
3211 guint8 mcs_known, mcs_flags;
3212 guint8 mcs;
3213 guint bandwidth;
3214 guint gi_length;
3215 gboolean can_calculate_rate;
3216
3217 /*
3218 * Start out assuming that we can calculate the rate;
3219 * if we are missing any of the MCS index, channel
3220 * width, or guard interval length, we can't.
3221 */
3222 can_calculate_rate = TRUE;
3223
3224 mcs_known = tvb_get_guint8(tvb, offset);
3225 /*
3226 * If there's actually any data here, not an
3227 * empty field, this is 802.11n - unless we've
3228 * seen a frequency >= 60 GHz and already set
3229 * it to 802.11ad.
3230 */
3231 if (mcs_known != 0 &&
3232 phdr.phy != PHDR_802_11_PHY_11AD) {
3233 phdr.phy = PHDR_802_11_PHY_11N;
3234 memset(&phdr.phy_info.info_11n, 0, sizeof(phdr.phy_info.info_11n));
3235 }
3236
3237 mcs_flags = tvb_get_guint8(tvb, offset + 1);
3238 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
3239 mcs = tvb_get_guint8(tvb, offset + 2);
3240 phdr.phy_info.info_11n.has_mcs_index = TRUE;
3241 phdr.phy_info.info_11n.mcs_index = mcs;
3242 } else {
3243 mcs = 0;
3244 can_calculate_rate = FALSE; /* no MCS index */
3245 }
3246 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW) {
3247 phdr.phy_info.info_11n.has_bandwidth = TRUE;
3248 phdr.phy_info.info_11n.bandwidth = (mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK);
3249 }
3250 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) {
3251 gi_length = (mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) ?
3252 1 : 0;
3253 phdr.phy_info.info_11n.has_short_gi = TRUE;
3254 phdr.phy_info.info_11n.short_gi = gi_length;
3255 } else {
3256 gi_length = 0;
3257 can_calculate_rate = FALSE; /* no GI width */
3258 }
3259 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) {
3260 phdr.phy_info.info_11n.has_greenfield = TRUE;
3261 phdr.phy_info.info_11n.greenfield = (mcs_flags & IEEE80211_RADIOTAP_MCS_FMT_GF) != 0;
3262 }
3263 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC) {
3264 phdr.phy_info.info_11n.has_fec = TRUE;
3265 phdr.phy_info.info_11n.fec = (mcs_flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? 1 : 0;
3266 }
3267 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_STBC) {
3268 phdr.phy_info.info_11n.has_stbc_streams = TRUE;
3269 phdr.phy_info.info_11n.stbc_streams = (mcs_flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT;
3270 }
3271 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_NESS) {
3272 phdr.phy_info.info_11n.has_ness = TRUE;
3273 /* This is stored a bit weirdly */
3274 phdr.phy_info.info_11n.ness =
3275 ((mcs_known & IEEE80211_RADIOTAP_MCS_NESS_BIT1) >> 6) |
3276 ((mcs_flags & IEEE80211_RADIOTAP_MCS_NESS_BIT0) >> 7);
3277 }
3278
3279 if (tree) {
3280 proto_item *it;
3281 static int * const mcs_haves_with_ness_bit1[] = {
3282 &hf_radiotap_mcs_have_bw,
3283 &hf_radiotap_mcs_have_index,
3284 &hf_radiotap_mcs_have_gi,
3285 &hf_radiotap_mcs_have_format,
3286 &hf_radiotap_mcs_have_fec,
3287 &hf_radiotap_mcs_have_stbc,
3288 &hf_radiotap_mcs_have_ness,
3289 &hf_radiotap_mcs_ness_bit1,
3290 NULL
3291 };
3292 static int * const mcs_haves_without_ness_bit1[] = {
3293 &hf_radiotap_mcs_have_bw,
3294 &hf_radiotap_mcs_have_index,
3295 &hf_radiotap_mcs_have_gi,
3296 &hf_radiotap_mcs_have_format,
3297 &hf_radiotap_mcs_have_fec,
3298 &hf_radiotap_mcs_have_stbc,
3299 &hf_radiotap_mcs_have_ness,
3300 NULL
3301 };
3302
3303 it = proto_tree_add_item(item_tree, hf_radiotap_mcs,
3304 tvb, offset, 3, ENC_NA);
3305 mcs_tree = proto_item_add_subtree(it, ett_radiotap_mcs);
3306
3307 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_NESS)
3308 proto_tree_add_bitmask(mcs_tree, tvb, offset, hf_radiotap_mcs_known, ett_radiotap_mcs_known, mcs_haves_with_ness_bit1, ENC_LITTLE_ENDIAN);
3309 else
3310 proto_tree_add_bitmask(mcs_tree, tvb, offset, hf_radiotap_mcs_known, ett_radiotap_mcs_known, mcs_haves_without_ness_bit1, ENC_LITTLE_ENDIAN);
3311 }
3312 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW) {
3313 bandwidth = ((mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK) == IEEE80211_RADIOTAP_MCS_BW_40) ?
3314 1 : 0;
3315 proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_bw,
3316 tvb, offset + 1, 1, mcs_flags);
3317 } else {
3318 bandwidth = 0;
3319 can_calculate_rate = FALSE; /* no bandwidth */
3320 }
3321 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) {
3322 proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_gi,
3323 tvb, offset + 1, 1, mcs_flags);
3324 }
3325 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) {
3326 proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_format,
3327 tvb, offset + 1, 1, mcs_flags);
3328 }
3329 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC) {
3330 proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_fec,
3331 tvb, offset + 1, 1, mcs_flags);
3332 }
3333 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_STBC) {
3334 proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_stbc,
3335 tvb, offset + 1, 1, mcs_flags);
3336 }
3337 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_NESS) {
3338 proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_ness_bit0,
3339 tvb, offset + 1, 1, mcs_flags);
3340 }
3341 if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
3342 proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_index,
3343 tvb, offset + 2, 1, mcs);
3344 }
3345
3346 /*
3347 * If we have the MCS index, channel width, and
3348 * guard interval length, and the MCS index is
3349 * valid, we can compute the rate. If the resulting
3350 * rate is non-zero, report it. (If it's zero,
3351 * it's an MCS/channel width/GI combination that
3352 * 802.11n doesn't support.)
3353 */
3354 if (can_calculate_rate && mcs <= MAX_MCS_INDEX
3355 && ieee80211_ht_Dbps[mcs] != 0) {
3356 float rate = ieee80211_htrate(mcs, bandwidth, gi_length);
3357 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f", rate);
3358 if (tree) {
3359 rate_ti = proto_tree_add_float_format(item_tree,
3360 hf_radiotap_datarate,
3361 tvb, offset, 3, rate,
3362 "Data Rate: %.1f Mb/s", rate);
3363 proto_item_set_generated(rate_ti);
3364 }
3365 }
3366 break;
3367 }
3368 case IEEE80211_RADIOTAP_AMPDU_STATUS: {
3369 proto_item *it;
3370 proto_tree *ampdu_tree = NULL, *ampdu_flags_tree;
3371 guint16 ampdu_flags;
3372
3373 phdr.has_aggregate_info = 1;
3374 phdr.aggregate_flags = 0;
3375 phdr.aggregate_id = tvb_get_letohl(tvb, offset);
3376
3377 ampdu_flags = tvb_get_letohs(tvb, offset + 4);
3378 if (ampdu_flags & IEEE80211_RADIOTAP_AMPDU_IS_LAST)
3379 phdr.aggregate_flags |= PHDR_802_11_LAST_PART_OF_A_MPDU;
3380 if (ampdu_flags & IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR)
3381 phdr.aggregate_flags |= PHDR_802_11_A_MPDU_DELIM_CRC_ERROR;
3382
3383 if (tree) {
3384 it = proto_tree_add_item(item_tree, hf_radiotap_ampdu,
3385 tvb, offset, 8, ENC_NA);
3386 ampdu_tree = proto_item_add_subtree(it, ett_radiotap_ampdu);
3387
3388 proto_tree_add_item(ampdu_tree, hf_radiotap_ampdu_ref,
3389 tvb, offset, 4, ENC_LITTLE_ENDIAN);
3390
3391 it = proto_tree_add_item(ampdu_tree, hf_radiotap_ampdu_flags,
3392 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3393 ampdu_flags_tree = proto_item_add_subtree(it, ett_radiotap_ampdu_flags);
3394 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_report_zerolen,
3395 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3396 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_is_zerolen,
3397 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3398 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_last_known,
3399 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3400 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_is_last,
3401 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3402 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_delim_crc_error,
3403 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3404 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_eof,
3405 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3406 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_eof_known,
3407 tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
3408 }
3409 if (ampdu_flags & IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN) {
3410 if (ampdu_tree)
3411 proto_tree_add_item(ampdu_tree, hf_radiotap_ampdu_delim_crc,
3412 tvb, offset + 6, 1, ENC_NA);
3413 }
3414 break;
3415 }
3416 case IEEE80211_RADIOTAP_VHT: {
3417 proto_item *it, *it_root = NULL;
3418 proto_tree *vht_tree = NULL, *vht_known_tree = NULL, *user_tree = NULL;
3419 guint16 known;
3420 guint8 vht_flags, bw, mcs_nss;
3421 guint bandwidth = 0;
3422 guint gi_length = 0;
3423 guint nss = 0;
3424 guint mcs = 0;
3425 gboolean can_calculate_rate;
3426 guint user;
3427
3428 /*
3429 * Start out assuming that we can calculate the rate;
3430 * if we are missing any of the MCS index, channel
3431 * width, or guard interval length, we can't.
3432 */
3433 can_calculate_rate = TRUE;
3434
3435 known = tvb_get_letohs(tvb, offset);
3436 /*
3437 * If there's actually any data here, not an
3438 * empty field, this is 802.11ac.
3439 */
3440 if (known != 0) {
3441 phdr.phy = PHDR_802_11_PHY_11AC;
3442 }
3443 vht_flags = tvb_get_guint8(tvb, offset + 2);
3444 if (tree) {
3445 it_root = proto_tree_add_item(item_tree, hf_radiotap_vht,
3446 tvb, offset, 12, ENC_NA);
3447 vht_tree = proto_item_add_subtree(it_root, ett_radiotap_vht);
3448 it = proto_tree_add_item(vht_tree, hf_radiotap_vht_known,
3449 tvb, offset, 2, known);
3450 vht_known_tree = proto_item_add_subtree(it, ett_radiotap_vht_known);
3451
3452 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_stbc,
3453 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3454 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_txop_ps,
3455 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3456 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_gi,
3457 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3458 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_sgi_nsym_da,
3459 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3460 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_ldpc_extra,
3461 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3462 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_bf,
3463 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3464 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_bw,
3465 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3466 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_gid,
3467 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3468 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_p_aid,
3469 tvb, offset, 2, ENC_LITTLE_ENDIAN);
3470 }
3471
3472 if (known & IEEE80211_RADIOTAP_VHT_HAVE_STBC) {
3473 phdr.phy_info.info_11ac.has_stbc = TRUE;
3474 phdr.phy_info.info_11ac.stbc = (vht_flags & IEEE80211_RADIOTAP_VHT_STBC) != 0;
3475 if (vht_tree)
3476 proto_tree_add_item(vht_tree, hf_radiotap_vht_stbc,
3477 tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
3478 }
3479
3480 if (known & IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS) {
3481 phdr.phy_info.info_11ac.has_txop_ps_not_allowed = TRUE;
3482 phdr.phy_info.info_11ac.txop_ps_not_allowed = (vht_flags & IEEE80211_RADIOTAP_VHT_TXOP_PS) != 0;
3483 if (vht_tree)
3484 proto_tree_add_item(vht_tree, hf_radiotap_vht_txop_ps,
3485 tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
3486 }
3487
3488 if (known & IEEE80211_RADIOTAP_VHT_HAVE_GI) {
3489 gi_length = (vht_flags & IEEE80211_RADIOTAP_VHT_SGI) ? 1 : 0;
3490 phdr.phy_info.info_11ac.has_short_gi = TRUE;
3491 phdr.phy_info.info_11ac.short_gi = gi_length;
3492 if (vht_tree) {
3493 proto_tree_add_item(vht_tree, hf_radiotap_vht_gi,
3494 tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
3495 }
3496 } else {
3497 can_calculate_rate = FALSE; /* no GI width */
3498 }
3499
3500 if (known & IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA) {
3501 phdr.phy_info.info_11ac.has_short_gi_nsym_disambig = TRUE;
3502 phdr.phy_info.info_11ac.short_gi_nsym_disambig = (vht_flags & IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA) != 0;
3503 if (vht_tree) {
3504 it = proto_tree_add_item(vht_tree, hf_radiotap_vht_sgi_nsym_da,
3505 tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
3506 if ((vht_flags & IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA) &&
3507 (known & IEEE80211_RADIOTAP_VHT_HAVE_GI) &&
3508 !(vht_flags & IEEE80211_RADIOTAP_VHT_SGI))
3509 proto_item_append_text(it, " (invalid)");
3510 }
3511 }
3512
3513 if (known & IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA) {
3514 phdr.phy_info.info_11ac.has_ldpc_extra_ofdm_symbol = TRUE;
3515 phdr.phy_info.info_11ac.ldpc_extra_ofdm_symbol = (vht_flags & IEEE80211_RADIOTAP_VHT_LDPC_EXTRA) != 0;
3516 if (vht_tree) {
3517 proto_tree_add_item(vht_tree, hf_radiotap_vht_ldpc_extra,
3518 tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
3519 }
3520 }
3521
3522 if (known & IEEE80211_RADIOTAP_VHT_HAVE_BF) {
3523 phdr.phy_info.info_11ac.has_beamformed = TRUE;
3524 phdr.phy_info.info_11ac.beamformed = (vht_flags & IEEE80211_RADIOTAP_VHT_BF) != 0;
3525 if (vht_tree)
3526 proto_tree_add_item(vht_tree, hf_radiotap_vht_bf,
3527 tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
3528 }
3529
3530 if (known & IEEE80211_RADIOTAP_VHT_HAVE_BW) {
3531 bw = tvb_get_guint8(tvb, offset + 3) & IEEE80211_RADIOTAP_VHT_BW_MASK;
3532 phdr.phy_info.info_11ac.has_bandwidth = TRUE;
3533 phdr.phy_info.info_11ac.bandwidth = bw;
3534 if (bw < sizeof(ieee80211_vht_bw2rate_index)/sizeof(ieee80211_vht_bw2rate_index[0]))
3535 bandwidth = ieee80211_vht_bw2rate_index[bw];
3536 else
3537 can_calculate_rate = FALSE; /* unknown bandwidth */
3538
3539 if (vht_tree)
3540 proto_tree_add_item(vht_tree, hf_radiotap_vht_bw,
3541 tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
3542 } else {
3543 can_calculate_rate = FALSE; /* no bandwidth */
3544 }
3545
3546 phdr.phy_info.info_11ac.has_fec = TRUE;
3547 phdr.phy_info.info_11ac.fec = tvb_get_guint8(tvb, offset + 8);
3548
3549 for (user = 0; user < 4; user++) {
3550 mcs_nss = tvb_get_guint8(tvb, offset + 4 + user);
3551 nss = (mcs_nss & IEEE80211_RADIOTAP_VHT_NSS);
3552 mcs = (mcs_nss & IEEE80211_RADIOTAP_VHT_MCS) >> 4;
3553 phdr.phy_info.info_11ac.mcs[user] = mcs;
3554 phdr.phy_info.info_11ac.nss[user] = nss;
3555
3556 if (nss) {
3557 /*
3558 * OK, there's some data here.
3559 * If we haven't already flagged this
3560 * as VHT, do so.
3561 */
3562 if (phdr.phy != PHDR_802_11_PHY_11AC) {
3563 phdr.phy = PHDR_802_11_PHY_11AC;
3564 }
3565 if (vht_tree) {
3566 it = proto_tree_add_item(vht_tree, hf_radiotap_vht_user,
3567 tvb, offset + 4, 5, ENC_NA);
3568 proto_item_append_text(it, " %d: MCS %u", user, mcs);
3569 user_tree = proto_item_add_subtree(it, ett_radiotap_vht_user);
3570
3571 it = proto_tree_add_item(user_tree, hf_radiotap_vht_mcs[user],
3572 tvb, offset + 4 + user, 1,
3573 ENC_LITTLE_ENDIAN);
3574 if (mcs > MAX_MCS_VHT_INDEX) {
3575 proto_item_append_text(it, " (invalid)");
3576 } else {
3577 proto_item_append_text(it, " (%s %s)",
3578 ieee80211_vhtinfo[mcs].modulation,
3579 ieee80211_vhtinfo[mcs].coding_rate);
3580 }
3581
3582 proto_tree_add_item(user_tree, hf_radiotap_vht_nss[user],
3583 tvb, offset + 4 + user, 1, ENC_LITTLE_ENDIAN);
3584 if (known & IEEE80211_RADIOTAP_VHT_HAVE_STBC) {
3585 guint nsts;
3586 proto_item *nsts_ti;
3587
3588 if (vht_flags & IEEE80211_RADIOTAP_VHT_STBC)
3589 nsts = 2 * nss;
3590 else
3591 nsts = nss;
3592 nsts_ti = proto_tree_add_uint(user_tree, hf_radiotap_vht_nsts[user],
3593 tvb, offset + 4 + user, 1, nsts);
3594 proto_item_set_generated(nsts_ti);
3595 }
3596 proto_tree_add_item(user_tree, hf_radiotap_vht_coding[user],
3597 tvb, offset + 8, 1,ENC_LITTLE_ENDIAN);
3598 }
3599
3600 if (can_calculate_rate && mcs <= MAX_MCS_VHT_INDEX &&
3601 nss <= MAX_VHT_NSS ) {
3602 float rate = ieee80211_vhtinfo[mcs].rates[bandwidth][gi_length] * nss;
3603 if (rate != 0.0f ) {
3604 rate_ti = proto_tree_add_float_format(user_tree,
3605 hf_radiotap_vht_datarate[user],
3606 tvb, offset, 12, rate,
3607 "Data Rate: %.1f Mb/s", rate);
3608 proto_item_set_generated(rate_ti);
3609 if (ieee80211_vhtvalid[mcs].valid[bandwidth][nss-1] == FALSE)
3610 expert_add_info(pinfo, rate_ti, &ei_radiotap_invalid_data_rate);
3611
3612 }
3613 }
3614 }
3615 }
3616
3617 if (known & IEEE80211_RADIOTAP_VHT_HAVE_GID) {
3618 phdr.phy_info.info_11ac.has_group_id = TRUE;
3619 phdr.phy_info.info_11ac.group_id = tvb_get_guint8(tvb, offset + 9);
3620 if (vht_tree)
3621 proto_tree_add_item(vht_tree, hf_radiotap_vht_gid,
3622 tvb, offset+9, 1, ENC_LITTLE_ENDIAN);
3623 }
3624
3625 if (known & IEEE80211_RADIOTAP_VHT_HAVE_PAID) {
3626 phdr.phy_info.info_11ac.has_partial_aid = TRUE;
3627 phdr.phy_info.info_11ac.partial_aid = tvb_get_letohs(tvb, offset + 10);
3628 if (vht_tree) {
3629 proto_tree_add_item(vht_tree, hf_radiotap_vht_p_aid,
3630 tvb, offset+10, 2, ENC_LITTLE_ENDIAN);
3631 }
3632 }
3633
3634 break;
3635 }
3636 case IEEE80211_RADIOTAP_TIMESTAMP: {
3637 dissect_radiotap_timestamp(tvb, pinfo, item_tree,
3638 offset, &phdr);
3639 break;
3640 }
3641 case IEEE80211_RADIOTAP_HE:
3642 /*
3643 * Presumably this is (whatever draft of) 802.11ax.
3644 * Also, presumably, you won't get the HE_MU field
3645 * without this field.
3646 */
3647 phdr.phy = PHDR_802_11_PHY_11AX;
3648 dissect_radiotap_he_info(tvb, pinfo, radiotap_tree, offset, &phdr.phy_info.info_11ax);
3649 break;
3650 case IEEE80211_RADIOTAP_HE_MU:
3651 dissect_radiotap_he_mu_info(tvb, pinfo, item_tree, offset);
3652 break;
3653 case IEEE80211_RADIOTAP_0_LENGTH_PSDU:
3654 dissect_radiotap_0_length_psdu(tvb, pinfo, item_tree, offset, &phdr);
3655 zero_length_psdu = TRUE;
3656 break;
3657 case IEEE80211_RADIOTAP_L_SIG:
3658 dissect_radiotap_l_sig(tvb, pinfo, item_tree, offset);
3659 break;
3660 case IEEE80211_RADIOTAP_TLVS:
3661 /* used for padding */
3662 break;
3663 default:
3664 proto_tree_add_item(item_tree, hf_radiotap_unknown_tlv_data, tvb,
3665 offset, iter.this_arg_size, ENC_NA);
3666 break;
3667 }
3668 }
3669
3670 if (err != -ENOENT) {
3671 expert_add_info(pinfo, present_item,
3672 &ei_radiotap_data_past_header);
3673 malformed:
3674 proto_item_append_text(ti, " (malformed)");
3675 }
3676
3677 /*
3678 * Is there any more there?
3679 */
3680 if (zero_length_psdu) {
3681 return tvb_captured_length(tvb);
3682 }
3683
3684 hand_off_to_80211:
3685 /*
3686 * The comment in the radiotap.org page about the suggested
3687 * xchannel field says:
3688 *
3689 * As used, this field conflates channel properties (which
3690 * need not be stored per packet but are more or less fixed)
3691 * with packet properties (like the modulation).
3692 *
3693 * The channel field, in practice, seems to be used, in some
3694 * cases, to indicate channel properties (from which the packet
3695 * modulation cannot be inferred) and, in other cases, to
3696 * indicate the packet's modulation.
3697 *
3698 * There is even a capture in which the channel field indicates
3699 * that the channel is an OFDM channel with a center frequency
3700 * of 2452 MHz, and the data rate field indicates a 1 Mb/s rate,
3701 * which means you can't rely on the CCK/OFDM/dynamic CCK/OFDM
3702 * bits in the channel field to indicate anything. (There are
3703 * also captures in which a 1 Mb/s packet has the CCK flag set,
3704 * so it clearly doesn't indicate how the packet was transmitted.)
3705 *
3706 * That makes the channel field unusable either for determining
3707 * the channel type or for determining the packet modulation,
3708 * as it cannot be determined how it's being used. The xchannel
3709 * field might well be used inconsistently as well.
3710 *
3711 * Fortunately, there are other ways to determine the packet
3712 * modulation:
3713 *
3714 * if there's an FHSS flag, the packet was transmitted
3715 * using the 802.11 legacy FHSS modulation;
3716 *
3717 * otherwise:
3718 *
3719 * if there's an HE field, the packet was transmitted
3720 * using one of the 11ax HE PHY's specified modulations;
3721 *
3722 * otherwise, if there's a VHT field, the packet was
3723 * transmitted using one of the 11ac VHT PHY's specified
3724 * modulations;
3725 *
3726 * otherwise, if there's an MCS field, the packet was
3727 * transmitted using one of the 11n HT PHY's specified
3728 * modulations;
3729 *
3730 * otherwise:
3731 *
3732 * if the data rate is 1 Mb/s or 2 Mb/s, the packet was
3733 * transmitted using the 802.11 legacy DSSS modulation
3734 * (we ignore the IR PHY - was it ever implemented?);
3735 *
3736 * if the data rate is 5 Mb/s or 11 Mb/s, the packet
3737 * was transmitted using the 802.11b DSSS/CCK modulation
3738 * (or the now-obsolete DSSS/PBCC modulation; *if* we can
3739 * rely on the channel/xchannel field's "CCK channel" and
3740 * "Dynamic CCK-OFDM channel" flags, the absence of either
3741 * flag would presumably indicate DSSS/PBCC);
3742 *
3743 * if the data rate is 22 Mb/s or 33 Mb/s, the packet was
3744 * transmitted using the 802.11b DSSS/PBCC modulation (as
3745 * those speeds aren't supported by DSSS/CCK);
3746 *
3747 * if the data rate is one of the OFDM rates for the 11a
3748 * OFDM PHY and the OFDM part of the 11g ERP PHY, the
3749 * packet was transmitted with the 11g/11a OFDM modulation.
3750 *
3751 * We've already handled the HE, VHT, and MCS fields, and may
3752 * have attempted to use the channel and xchannel fields to
3753 * guess the modulation. That guess might get the wrong answer
3754 * for 11g "Dynamic CCK-OFDM" channels.
3755 *
3756 * If we have the data rate, we use it to:
3757 *
3758 * fix up the 11g channels;
3759 *
3760 * determine the modulation if we haven't been able to
3761 * determine it any other way.
3762 */
3763 if (phdr.has_data_rate) {
3764 if (phdr.phy == PHDR_802_11_PHY_UNKNOWN) {
3765 /*
3766 * We don't know they PHY, but we do have the
3767 * data rate; try to guess it based on the
3768 * data rate and center frequency.
3769 */
3770 if (RATE_IS_DSSS(phdr.data_rate)) {
3771 /* 11b */
3772 phdr.phy = PHDR_802_11_PHY_11B;
3773 } else if (RATE_IS_OFDM(phdr.data_rate)) {
3774 /* 11a or 11g, depending on the band. */
3775 if (phdr.has_frequency) {
3776 if (FREQ_IS_BG(phdr.frequency)) {
3777 /* 11g */
3778 phdr.phy = PHDR_802_11_PHY_11G;
3779 } else {
3780 /* 11a */
3781 phdr.phy = PHDR_802_11_PHY_11A;
3782 }
3783 }
3784 }
3785 } else if (phdr.phy == PHDR_802_11_PHY_11G) {
3786 if (RATE_IS_DSSS(phdr.data_rate)) {
3787 /* DSSS, so 11b. */
3788 phdr.phy = PHDR_802_11_PHY_11B;
3789 }
3790 }
3791 }
3792
3793 switch (phdr.phy) {
3794
3795 case PHDR_802_11_PHY_11B:
3796 /*
3797 * We now know it's 11b, so set the "short preamble"
3798 * property.
3799 */
3800 if (have_rflags) {
3801 phdr.phy_info.info_11b.has_short_preamble = TRUE;
3802 phdr.phy_info.info_11b.short_preamble =
3803 (rflags & IEEE80211_RADIOTAP_F_SHORTPRE) ? TRUE : FALSE;;
3804 } else
3805 phdr.phy_info.info_11b.has_short_preamble = FALSE;
3806 break;
3807
3808 case PHDR_802_11_PHY_11N:
3809 /*
3810 * This doesn't supply "short GI" information,
3811 * so use the 0x80 bit in the Flags field,
3812 * if we have it; it's "Currently unspecified
3813 * but used" for that purpose, according to
3814 * the radiotap.org page for that field.
3815 */
3816 if (!phdr.phy_info.info_11n.has_short_gi && have_rflags) {
3817 phdr.phy_info.info_11n.has_short_gi = TRUE;
3818 if (rflags & 0x80)
3819 phdr.phy_info.info_11n.short_gi = 1;
3820 else
3821 phdr.phy_info.info_11n.short_gi = 0;
3822 }
3823 break;
3824 }
3825
3826 /* Grab the rest of the frame. */
3827 next_tvb = tvb_new_subset_remaining(tvb, length);
3828
3829 /* If we had an in-header FCS, check it.
3830 * This can only happen if the backward-compat configuration option
3831 * is chosen by the user. */
3832 if (hdr_fcs_ti) {
3833 guint captured_length = tvb_captured_length(next_tvb);
3834 guint reported_length = tvb_reported_length(next_tvb);
3835 guint fcs_len = (phdr.fcs_len > 0) ? phdr.fcs_len : 0;
3836
3837 /* It would be very strange for the header to have an FCS for the
3838 * frame *and* the frame to have the FCS at the end, but it's possible, so
3839 * take that into account by using the FCS length recorded in pinfo. */
3840
3841 /* Watch out for [erroneously] short frames */
3842 if (captured_length >= reported_length &&
3843 captured_length > fcs_len) {
3844 calc_fcs =
3845 crc32_802_tvb(next_tvb, tvb_captured_length(next_tvb) - fcs_len);
3846
3847 /* By virtue of hdr_fcs_ti being set, we know that 'tree' is set,
3848 * so there's no need to check it here. */
3849 if (calc_fcs == sent_fcs) {
3850 proto_item_append_text(hdr_fcs_ti,
3851 " [correct]");
3852 } else {
3853 proto_item_append_text(hdr_fcs_ti,
3854 " [incorrect, should be 0x%08x]",
3855 calc_fcs);
3856 hidden_item =
3857 proto_tree_add_boolean(radiotap_tree,
3858 hf_radiotap_fcs_bad,
3859 tvb, hdr_fcs_offset,
3860 4, TRUE);
3861 proto_item_set_hidden(hidden_item);
3862 }
3863 } else {
3864 proto_item_append_text(hdr_fcs_ti,
3865 " [cannot verify - not enough data]");
3866 }
3867 }
3868
3869 /* dissect the 802.11 packet next */
3870 call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo,
3871 tree, &phdr);
3872
3873 return tvb_captured_length(tvb);
3874 }
3875
proto_register_radiotap(void)3876 void proto_register_radiotap(void)
3877 {
3878
3879 static hf_register_info hf[] = {
3880 {&hf_radiotap_version,
3881 {"Header revision", "radiotap.version",
3882 FT_UINT8, BASE_DEC, NULL, 0x0,
3883 "Version of radiotap header format", HFILL}},
3884
3885 {&hf_radiotap_pad,
3886 {"Header pad", "radiotap.pad",
3887 FT_UINT8, BASE_DEC, NULL, 0x0,
3888 "Padding", HFILL}},
3889
3890 {&hf_radiotap_length,
3891 {"Header length", "radiotap.length",
3892 FT_UINT16, BASE_DEC, NULL, 0x0,
3893 "Length of header including version, pad, length and data fields", HFILL}},
3894
3895 {&hf_radiotap_present,
3896 {"Present flags", "radiotap.present",
3897 FT_NONE, BASE_NONE, NULL, 0x0,
3898 "Bitmask indicating which fields are present", HFILL}},
3899
3900 {&hf_radiotap_present_word,
3901 {"Present flags word", "radiotap.present.word",
3902 FT_UINT32, BASE_HEX, NULL, 0x0,
3903 "Word from present flags bitmask", HFILL}},
3904
3905 {&hf_radiotap_tlv_type,
3906 {"TLV type", "radiotap.tlv.type",
3907 FT_UINT32, BASE_DEC, NULL, 0x0,
3908 NULL, HFILL}},
3909
3910 {&hf_radiotap_tlv_datalen,
3911 {"TLV datalen", "radiotap.tlv.datalen",
3912 FT_UINT32, BASE_DEC, NULL, 0x0,
3913 NULL, HFILL}},
3914
3915 {&hf_radiotap_unknown_tlv_data,
3916 {"unknown TLV data", "radiotap.tlv.unknown_data",
3917 FT_BYTES, BASE_NONE, NULL, 0x0,
3918 NULL, HFILL}},
3919
3920 #define RADIOTAP_MASK(name) BIT(IEEE80211_RADIOTAP_ ##name)
3921
3922 /* Boolean 'present' flags */
3923 {&hf_radiotap_present_tsft,
3924 {"TSFT", "radiotap.present.tsft",
3925 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(TSFT),
3926 "Specifies if the Time Synchronization Function Timer field is present", HFILL}},
3927
3928 {&hf_radiotap_present_flags,
3929 {"Flags", "radiotap.present.flags",
3930 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(FLAGS),
3931 "Specifies if the channel flags field is present", HFILL}},
3932
3933 {&hf_radiotap_present_rate,
3934 {"Rate", "radiotap.present.rate",
3935 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(RATE),
3936 "Specifies if the transmit/receive rate field is present", HFILL}},
3937
3938 {&hf_radiotap_present_channel,
3939 {"Channel", "radiotap.present.channel",
3940 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(CHANNEL),
3941 "Specifies if the transmit/receive frequency field is present", HFILL}},
3942
3943 {&hf_radiotap_present_fhss,
3944 {"FHSS", "radiotap.present.fhss",
3945 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(FHSS),
3946 "Specifies if the hop set and pattern is present for frequency hopping radios", HFILL}},
3947
3948 {&hf_radiotap_present_dbm_antsignal,
3949 {"dBm Antenna Signal", "radiotap.present.dbm_antsignal",
3950 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(DBM_ANTSIGNAL),
3951 "Specifies if the antenna signal strength in dBm is present", HFILL}},
3952
3953 {&hf_radiotap_present_dbm_antnoise,
3954 {"dBm Antenna Noise", "radiotap.present.dbm_antnoise",
3955 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(DBM_ANTNOISE),
3956 "Specifies if the RF noise power at antenna field is present", HFILL}},
3957
3958 {&hf_radiotap_present_lock_quality,
3959 {"Lock Quality", "radiotap.present.lock_quality",
3960 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(LOCK_QUALITY),
3961 "Specifies if the signal quality field is present", HFILL}},
3962
3963 {&hf_radiotap_present_tx_attenuation,
3964 {"TX Attenuation", "radiotap.present.tx_attenuation",
3965 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(TX_ATTENUATION),
3966 "Specifies if the transmit power distance from max power field is present", HFILL}},
3967
3968 {&hf_radiotap_present_db_tx_attenuation,
3969 {"dB TX Attenuation", "radiotap.present.db_tx_attenuation",
3970 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(DB_TX_ATTENUATION),
3971 "Specifies if the transmit power distance from max power (in dB) field is present", HFILL}},
3972
3973 {&hf_radiotap_present_dbm_tx_power,
3974 {"dBm TX Power", "radiotap.present.dbm_tx_power",
3975 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(DBM_TX_POWER),
3976 "Specifies if the transmit power (in dBm) field is present", HFILL}},
3977
3978 {&hf_radiotap_present_antenna,
3979 {"Antenna", "radiotap.present.antenna",
3980 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(ANTENNA),
3981 "Specifies if the antenna number field is present", HFILL}},
3982
3983 {&hf_radiotap_present_db_antsignal,
3984 {"dB Antenna Signal", "radiotap.present.db_antsignal",
3985 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(DB_ANTSIGNAL),
3986 "Specifies if the RF signal power at antenna in dB field is present", HFILL}},
3987
3988 {&hf_radiotap_present_db_antnoise,
3989 {"dB Antenna Noise", "radiotap.present.db_antnoise",
3990 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(DB_ANTNOISE),
3991 "Specifies if the RF signal power at antenna in dBm field is present", HFILL}},
3992
3993 {&hf_radiotap_present_rxflags,
3994 {"RX flags", "radiotap.present.rxflags",
3995 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(RX_FLAGS),
3996 "Specifies if the RX flags field is present", HFILL}},
3997
3998 {&hf_radiotap_present_txflags,
3999 {"TX flags", "radiotap.present.txflags",
4000 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(TX_FLAGS),
4001 "Specifies if the TX flags field is present", HFILL}},
4002
4003 {&hf_radiotap_present_hdrfcs,
4004 {"FCS in header", "radiotap.present.fcs",
4005 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(RX_FLAGS),
4006 "Specifies if the FCS field is present", HFILL}},
4007
4008 { &hf_radiotap_present_data_retries,
4009 {"data retries", "radiotap.present.data_retries",
4010 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(DATA_RETRIES),
4011 "Specifies if the data retries field is present", HFILL}},
4012
4013 {&hf_radiotap_present_xchannel,
4014 {"Channel+", "radiotap.present.xchannel",
4015 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(XCHANNEL),
4016 "Specifies if the extended channel info field is present", HFILL}},
4017
4018 {&hf_radiotap_present_mcs,
4019 {"MCS information", "radiotap.present.mcs",
4020 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(MCS),
4021 "Specifies if the MCS field is present", HFILL}},
4022
4023 {&hf_radiotap_present_ampdu,
4024 {"A-MPDU Status", "radiotap.present.ampdu",
4025 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(AMPDU_STATUS),
4026 "Specifies if the A-MPDU status field is present", HFILL}},
4027
4028 {&hf_radiotap_present_vht,
4029 {"VHT information", "radiotap.present.vht",
4030 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(VHT),
4031 "Specifies if the VHT field is present", HFILL}},
4032
4033 {&hf_radiotap_present_timestamp,
4034 {"frame timestamp", "radiotap.present.timestamp",
4035 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(TIMESTAMP),
4036 "Specifies if the timestamp field is present", HFILL}},
4037
4038 {&hf_radiotap_present_he,
4039 {"HE information", "radiotap.present.he",
4040 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(HE),
4041 "Specifies if the HE field is present", HFILL}},
4042
4043 {&hf_radiotap_present_he_mu,
4044 {"HE-MU information", "radiotap.present.he_mu",
4045 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(HE_MU),
4046 "Specifies if the HE field is present", HFILL}},
4047
4048 {&hf_radiotap_present_0_length_psdu,
4049 {"0 Length PSDU", "radiotap.present.0_length.psdu",
4050 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(0_LENGTH_PSDU),
4051 "Specifies whether or not the 0-Length PSDU field is present", HFILL}},
4052
4053 {&hf_radiotap_present_l_sig,
4054 {"L-SIG", "radiotap.present.l_sig",
4055 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(L_SIG),
4056 "Specifies whether or not the L-SIG field is present", HFILL}},
4057
4058 {&hf_radiotap_present_tlv,
4059 {"TLVs", "radiotap.present.tlv",
4060 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(TLVS),
4061 "Specifies switch to TLV fields", HFILL}},
4062
4063 {&hf_radiotap_present_rtap_ns,
4064 {"Radiotap NS next", "radiotap.present.rtap_ns",
4065 FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RADIOTAP_NAMESPACE),
4066 "Specifies a reset to the radiotap namespace", HFILL}},
4067
4068 {&hf_radiotap_present_vendor_ns,
4069 {"Vendor NS next", "radiotap.present.vendor_ns",
4070 FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(VENDOR_NAMESPACE),
4071 "Specifies that the next bitmap is in a vendor namespace", HFILL}},
4072
4073 {&hf_radiotap_present_ext,
4074 {"Ext", "radiotap.present.ext",
4075 FT_BOOLEAN, 32, TFS(&tfs_present_absent), RADIOTAP_MASK(EXT),
4076 "Specifies if there are any extensions to the header present", HFILL}},
4077
4078 /* Boolean 'present.flags' flags */
4079 {&hf_radiotap_flags,
4080 {"Flags", "radiotap.flags",
4081 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
4082
4083 {&hf_radiotap_flags_cfp,
4084 {"CFP", "radiotap.flags.cfp",
4085 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_CFP,
4086 "Sent/Received during CFP", HFILL}},
4087
4088 {&hf_radiotap_flags_preamble,
4089 {"Preamble", "radiotap.flags.preamble",
4090 FT_BOOLEAN, 8, TFS(&preamble_type),
4091 IEEE80211_RADIOTAP_F_SHORTPRE,
4092 "Sent/Received with short preamble", HFILL}},
4093
4094 {&hf_radiotap_flags_wep,
4095 {"WEP", "radiotap.flags.wep",
4096 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_WEP,
4097 "Sent/Received with WEP encryption", HFILL}},
4098
4099 {&hf_radiotap_flags_frag,
4100 {"Fragmentation", "radiotap.flags.frag",
4101 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_FRAG,
4102 "Sent/Received with fragmentation", HFILL}},
4103
4104 {&hf_radiotap_flags_fcs,
4105 {"FCS at end", "radiotap.flags.fcs",
4106 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_FCS,
4107 "Frame includes FCS at end", HFILL}},
4108
4109 {&hf_radiotap_flags_datapad,
4110 {"Data Pad", "radiotap.flags.datapad",
4111 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_DATAPAD,
4112 "Frame has padding between 802.11 header and payload", HFILL}},
4113
4114 {&hf_radiotap_flags_badfcs,
4115 {"Bad FCS", "radiotap.flags.badfcs",
4116 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_BADFCS,
4117 "Frame received with bad FCS", HFILL}},
4118
4119 {&hf_radiotap_flags_shortgi,
4120 {"Short GI", "radiotap.flags.shortgi",
4121 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_SHORTGI,
4122 "Frame Sent/Received with HT short Guard Interval", HFILL}},
4123
4124 {&hf_radiotap_mactime,
4125 {"MAC timestamp", "radiotap.mactime",
4126 FT_UINT64, BASE_DEC, NULL, 0x0,
4127 "Value in microseconds of the MAC's Time Synchronization Function timer"
4128 " when the first bit of the MPDU arrived at the MAC.",
4129 HFILL}},
4130
4131 {&hf_radiotap_quality,
4132 {"Signal Quality", "radiotap.quality",
4133 FT_UINT16, BASE_DEC, NULL, 0x0,
4134 "Signal quality (unitless measure)", HFILL}},
4135
4136 {&hf_radiotap_fcs,
4137 {"802.11 FCS", "radiotap.fcs",
4138 FT_UINT32, BASE_HEX, NULL, 0x0,
4139 "Frame check sequence of this frame", HFILL}},
4140
4141 #if 0
4142 {&hf_radiotap_channel,
4143 {"Channel", "radiotap.channel",
4144 FT_UINT32, BASE_DEC, NULL, 0x0,
4145 "802.11 channel number that this frame was sent/received on", HFILL}},
4146 #endif
4147
4148 {&hf_radiotap_channel_frequency,
4149 {"Channel frequency", "radiotap.channel.freq",
4150 FT_UINT32, BASE_DEC, NULL, 0x0,
4151 "Channel frequency in megahertz that this frame was sent/received on", HFILL}},
4152
4153 {&hf_radiotap_channel_flags,
4154 {"Channel flags", "radiotap.channel.flags",
4155 FT_UINT16, BASE_HEX, NULL, 0x0,
4156 NULL, HFILL}},
4157
4158 {&hf_radiotap_channel_flags_turbo,
4159 {"Turbo", "radiotap.channel.flags.turbo",
4160 FT_BOOLEAN, 16, NULL, 0x0010, "Channel Flags Turbo", HFILL}},
4161
4162 {&hf_radiotap_channel_flags_700mhz,
4163 {"700 MHz spectrum", "radiotap.channel.flags.700mhz",
4164 FT_BOOLEAN, 16, NULL, 0x0001, "Channel Flags Turbo", HFILL}},
4165
4166 {&hf_radiotap_channel_flags_800mhz,
4167 {"800 MHz spectrum", "radiotap.channel.flags.800mhz",
4168 FT_BOOLEAN, 16, NULL, 0x0002, "Channel Flags Turbo", HFILL}},
4169
4170 {&hf_radiotap_channel_flags_900mhz,
4171 {"900 MHz spectrum", "radiotap.channel.flags.900mhz",
4172 FT_BOOLEAN, 16, NULL, 0x0004, "Channel Flags Turbo", HFILL}},
4173
4174 {&hf_radiotap_channel_flags_cck,
4175 {"Complementary Code Keying (CCK)", "radiotap.channel.flags.cck",
4176 FT_BOOLEAN, 16, NULL, 0x0020,
4177 "Channel Flags Complementary Code Keying (CCK) Modulation", HFILL}},
4178
4179 {&hf_radiotap_channel_flags_ofdm,
4180 {"Orthogonal Frequency-Division Multiplexing (OFDM)", "radiotap.channel.flags.ofdm",
4181 FT_BOOLEAN, 16, NULL, 0x0040,
4182 "Channel Flags Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL}},
4183
4184 {&hf_radiotap_channel_flags_2ghz,
4185 {"2 GHz spectrum", "radiotap.channel.flags.2ghz",
4186 FT_BOOLEAN, 16, NULL, 0x0080, "Channel Flags 2 GHz spectrum", HFILL}},
4187
4188 {&hf_radiotap_channel_flags_5ghz,
4189 {"5 GHz spectrum", "radiotap.channel.flags.5ghz",
4190 FT_BOOLEAN, 16, NULL, 0x0100, "Channel Flags 5 GHz spectrum", HFILL}},
4191
4192 {&hf_radiotap_channel_flags_passive,
4193 {"Passive", "radiotap.channel.flags.passive",
4194 FT_BOOLEAN, 16, NULL, 0x0200,
4195 "Channel Flags Passive", HFILL}},
4196
4197 {&hf_radiotap_channel_flags_dynamic,
4198 {"Dynamic CCK-OFDM", "radiotap.channel.flags.dynamic",
4199 FT_BOOLEAN, 16, NULL, 0x0400,
4200 "Channel Flags Dynamic CCK-OFDM Channel", HFILL}},
4201
4202 {&hf_radiotap_channel_flags_gfsk,
4203 {"Gaussian Frequency Shift Keying (GFSK)", "radiotap.channel.flags.gfsk",
4204 FT_BOOLEAN, 16, NULL, 0x0800,
4205 "Channel Flags Gaussian Frequency Shift Keying (GFSK) Modulation", HFILL}},
4206
4207 {&hf_radiotap_channel_flags_gsm,
4208 {"GSM (900MHz)", "radiotap.channel.flags.gsm",
4209 FT_BOOLEAN, 16, NULL, 0x1000,
4210 "Channel Flags GSM", HFILL}},
4211
4212 {&hf_radiotap_channel_flags_sturbo,
4213 {"Static Turbo", "radiotap.channel.flags.sturbo",
4214 FT_BOOLEAN, 16, NULL, 0x2000,
4215 "Channel Flags Status Turbo", HFILL}},
4216
4217 {&hf_radiotap_channel_flags_half,
4218 {"Half Rate Channel (10MHz Channel Width)", "radiotap.channel.flags.half",
4219 FT_BOOLEAN, 16, NULL, 0x4000,
4220 "Channel Flags Half Rate", HFILL}},
4221
4222 {&hf_radiotap_channel_flags_quarter,
4223 {"Quarter Rate Channel (5MHz Channel Width)", "radiotap.channel.flags.quarter",
4224 FT_BOOLEAN, 16, NULL, 0x8000,
4225 "Channel Flags Quarter Rate", HFILL}},
4226
4227 {&hf_radiotap_rxflags,
4228 {"RX flags", "radiotap.rxflags",
4229 FT_UINT16, BASE_HEX, NULL, 0x0,
4230 NULL, HFILL}},
4231
4232 {&hf_radiotap_rxflags_badplcp,
4233 {"Bad PLCP", "radiotap.rxflags.badplcp",
4234 FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_RX_BADPLCP,
4235 "Frame with bad PLCP", HFILL}},
4236
4237 {&hf_radiotap_txflags,
4238 {"TX flags", "radiotap.txflags",
4239 FT_UINT16, BASE_HEX, NULL, 0x0,
4240 NULL, HFILL}},
4241
4242 {&hf_radiotap_txflags_fail,
4243 {"Fail", "radiotap.rxflags.fail",
4244 FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_TX_FAIL,
4245 "Transmission failed due to excessive retries", HFILL}},
4246
4247 {&hf_radiotap_txflags_cts,
4248 {"CTS", "radiotap.rxflags.cts",
4249 FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_TX_CTS,
4250 "Transmission used CTS-to-self protection", HFILL}},
4251
4252 {&hf_radiotap_txflags_rts,
4253 {"RTS/CTS", "radiotap.rxflags.rts",
4254 FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_TX_RTS,
4255 "Transmission used RTS/CTS handshake", HFILL}},
4256
4257 {&hf_radiotap_txflags_noack,
4258 {"No ACK", "radiotap.rxflags.noack",
4259 FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_TX_NOACK,
4260 "Transmission shall not expect an ACK frame", HFILL}},
4261
4262 {&hf_radiotap_txflags_noseqno,
4263 {"Has Seqnum", "radiotap.rxflags.noseqno",
4264 FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_TX_NOSEQNO,
4265 "Frame includes a pre-configured sequence number", HFILL}},
4266
4267 {&hf_radiotap_txflags_order,
4268 {"Order", "radiotap.rxflags.order",
4269 FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_TX_ORDER,
4270 "Frame must not be reordered relative to others with this flag", HFILL}},
4271
4272 {&hf_radiotap_xchannel_channel,
4273 {"Channel number", "radiotap.xchannel.channel",
4274 FT_UINT32, BASE_DEC, NULL, 0x0,
4275 NULL, HFILL}},
4276
4277 {&hf_radiotap_xchannel_frequency,
4278 {"Channel frequency", "radiotap.xchannel.freq",
4279 FT_UINT32, BASE_DEC, NULL, 0x0,
4280 NULL, HFILL}},
4281
4282 {&hf_radiotap_xchannel_flags,
4283 {"Channel flags", "radiotap.xchannel.flags",
4284 FT_UINT32, BASE_HEX, NULL, 0x0,
4285 NULL, HFILL}},
4286
4287 {&hf_radiotap_xchannel_flags_turbo,
4288 {"Turbo", "radiotap.xchannel.flags.turbo",
4289 FT_BOOLEAN, 24, NULL, 0x0010,
4290 "Channel Flags Turbo", HFILL}},
4291
4292 {&hf_radiotap_xchannel_flags_cck,
4293 {"Complementary Code Keying (CCK)", "radiotap.xchannel.flags.cck",
4294 FT_BOOLEAN, 24, NULL, 0x0020,
4295 "Channel Flags Complementary Code Keying (CCK) Modulation", HFILL}},
4296
4297 {&hf_radiotap_xchannel_flags_ofdm,
4298 {"Orthogonal Frequency-Division Multiplexing (OFDM)", "radiotap.xchannel.flags.ofdm",
4299 FT_BOOLEAN, 24, NULL, 0x0040,
4300 "Channel Flags Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL}},
4301
4302 {&hf_radiotap_xchannel_flags_2ghz,
4303 {"2 GHz spectrum", "radiotap.xchannel.flags.2ghz",
4304 FT_BOOLEAN, 24, NULL, 0x0080,
4305 "Channel Flags 2 GHz spectrum", HFILL}},
4306
4307 {&hf_radiotap_xchannel_flags_5ghz,
4308 {"5 GHz spectrum", "radiotap.xchannel.flags.5ghz",
4309 FT_BOOLEAN, 24, NULL, 0x0100,
4310 "Channel Flags 5 GHz spectrum", HFILL}},
4311
4312 {&hf_radiotap_xchannel_flags_passive,
4313 {"Passive", "radiotap.channel.xtype.passive",
4314 FT_BOOLEAN, 24, NULL, 0x0200,
4315 "Channel Flags Passive", HFILL}},
4316
4317 {&hf_radiotap_xchannel_flags_dynamic,
4318 {"Dynamic CCK-OFDM", "radiotap.xchannel.flags.dynamic",
4319 FT_BOOLEAN, 24, NULL, 0x0400,
4320 "Channel Flags Dynamic CCK-OFDM Channel", HFILL}},
4321
4322 {&hf_radiotap_xchannel_flags_gfsk,
4323 {"Gaussian Frequency Shift Keying (GFSK)",
4324 "radiotap.xchannel.flags.gfsk",
4325 FT_BOOLEAN, 24, NULL, 0x0800,
4326 "Channel Flags Gaussian Frequency Shift Keying (GFSK) Modulation",
4327 HFILL}},
4328
4329 {&hf_radiotap_xchannel_flags_gsm,
4330 {"GSM (900MHz)", "radiotap.xchannel.flags.gsm",
4331 FT_BOOLEAN, 24, NULL, 0x1000,
4332 "Channel Flags GSM", HFILL}},
4333
4334 {&hf_radiotap_xchannel_flags_sturbo,
4335 {"Static Turbo", "radiotap.xchannel.flags.sturbo",
4336 FT_BOOLEAN, 24, NULL, 0x2000,
4337 "Channel Flags Status Turbo", HFILL}},
4338
4339 {&hf_radiotap_xchannel_flags_half,
4340 {"Half Rate Channel (10MHz Channel Width)", "radiotap.xchannel.flags.half",
4341 FT_BOOLEAN, 24, NULL, 0x4000,
4342 "Channel Flags Half Rate", HFILL}},
4343
4344 {&hf_radiotap_xchannel_flags_quarter,
4345 {"Quarter Rate Channel (5MHz Channel Width)", "radiotap.xchannel.flags.quarter",
4346 FT_BOOLEAN, 24, NULL, 0x8000,
4347 "Channel Flags Quarter Rate", HFILL}},
4348
4349 {&hf_radiotap_xchannel_flags_ht20,
4350 {"HT Channel (20MHz Channel Width)", "radiotap.xchannel.flags.ht20",
4351 FT_BOOLEAN, 24, NULL, 0x010000,
4352 "Channel Flags HT/20", HFILL}},
4353
4354 {&hf_radiotap_xchannel_flags_ht40u,
4355 {"HT Channel (40MHz Channel Width with Extension channel above)", "radiotap.xchannel.flags.ht40u",
4356 FT_BOOLEAN, 24, NULL, 0x020000,
4357 "Channel Flags HT/40+", HFILL}},
4358
4359 {&hf_radiotap_xchannel_flags_ht40d,
4360 {"HT Channel (40MHz Channel Width with Extension channel below)", "radiotap.xchannel.flags.ht40d",
4361 FT_BOOLEAN, 24, NULL, 0x40000,
4362 "Channel Flags HT/40-", HFILL}},
4363 #if 0
4364 {&hf_radiotap_xchannel_maxpower,
4365 {"Max transmit power", "radiotap.xchannel.maxpower",
4366 FT_UINT32, BASE_DEC, NULL, 0x0,
4367 NULL, HFILL}},
4368 #endif
4369 {&hf_radiotap_fhss_hopset,
4370 {"FHSS Hop Set", "radiotap.fhss.hopset",
4371 FT_UINT8, BASE_DEC, NULL, 0x0,
4372 "Frequency Hopping Spread Spectrum hopset", HFILL}},
4373
4374 {&hf_radiotap_fhss_pattern,
4375 {"FHSS Pattern", "radiotap.fhss.pattern",
4376 FT_UINT8, BASE_DEC, NULL, 0x0,
4377 "Frequency Hopping Spread Spectrum hop pattern", HFILL}},
4378
4379 {&hf_radiotap_datarate,
4380 {"Data rate (Mb/s)", "radiotap.datarate",
4381 FT_FLOAT, BASE_NONE, NULL, 0x0,
4382 "Speed this frame was sent/received at", HFILL}},
4383
4384 {&hf_radiotap_antenna,
4385 {"Antenna", "radiotap.antenna",
4386 FT_UINT32, BASE_DEC, NULL, 0x0,
4387 "Antenna number this frame was sent/received over (starting at 0)", HFILL}},
4388
4389 {&hf_radiotap_dbm_antsignal,
4390 {"Antenna signal", "radiotap.dbm_antsignal",
4391 FT_INT8, BASE_DEC|BASE_UNIT_STRING, &units_dbm, 0x0,
4392 "RF signal power at the antenna expressed as decibels"
4393 " from one milliwatt", HFILL}},
4394
4395 {&hf_radiotap_db_antsignal,
4396 {"dB antenna signal", "radiotap.db_antsignal",
4397 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_decibels, 0x0,
4398 "RF signal power at the antenna expressed as decibels"
4399 " from a fixed, arbitrary value", HFILL}},
4400
4401 {&hf_radiotap_dbm_antnoise,
4402 {"Antenna noise", "radiotap.dbm_antnoise",
4403 FT_INT8, BASE_DEC|BASE_UNIT_STRING, &units_dbm, 0x0,
4404 "RF noise power at the antenna expressed as decibels"
4405 " from one milliwatt", HFILL}},
4406
4407 {&hf_radiotap_db_antnoise,
4408 {"dB antenna noise", "radiotap.db_antnoise",
4409 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_decibels, 0x0,
4410 "RF noise power at the antenna expressed as decibels"
4411 " from a fixed, arbitrary value", HFILL}},
4412
4413 {&hf_radiotap_tx_attenuation,
4414 {"TX attenuation", "radiotap.txattenuation",
4415 FT_UINT16, BASE_DEC, NULL, 0x0,
4416 "Transmit power expressed as unitless distance from max power"
4417 " set at factory calibration (0 is max power)", HFILL}},
4418
4419 {&hf_radiotap_db_tx_attenuation,
4420 {"dB TX attenuation", "radiotap.db_txattenuation",
4421 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, &units_decibels, 0x0,
4422 "Transmit power expressed as decibels from max power"
4423 " set at factory calibration (0 is max power)", HFILL}},
4424
4425 {&hf_radiotap_txpower,
4426 {"Transmit power", "radiotap.txpower",
4427 FT_INT8, BASE_DEC|BASE_UNIT_STRING, &units_dbm, 0x0,
4428 "Transmit power at the antenna port expressed as decibels"
4429 " from one milliwatt", HFILL}},
4430
4431 { &hf_radiotap_data_retries,
4432 {"data retries", "radiotap.data_retries",
4433 FT_UINT8, BASE_DEC, NULL, 0x0,
4434 "Number of data retries a transmitted frame used", HFILL} },
4435
4436 {&hf_radiotap_mcs,
4437 {"MCS information", "radiotap.mcs",
4438 FT_NONE, BASE_NONE, NULL, 0x0,
4439 NULL, HFILL}},
4440
4441 {&hf_radiotap_mcs_known,
4442 {"Known MCS information", "radiotap.mcs.known",
4443 FT_UINT8, BASE_HEX, NULL, 0x0,
4444 "Bit mask indicating what MCS information is present", HFILL}},
4445
4446 {&hf_radiotap_mcs_have_bw,
4447 {"Bandwidth", "radiotap.mcs.have_bw",
4448 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_BW,
4449 "Bandwidth information present", HFILL}},
4450
4451 {&hf_radiotap_mcs_have_index,
4452 {"MCS index", "radiotap.mcs.have_index",
4453 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_MCS,
4454 "MCS index information present", HFILL}},
4455
4456 {&hf_radiotap_mcs_have_gi,
4457 {"Guard interval", "radiotap.mcs.have_gi",
4458 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_GI,
4459 "Sent/Received guard interval information present", HFILL}},
4460
4461 {&hf_radiotap_mcs_have_format,
4462 {"Format", "radiotap.mcs.have_format",
4463 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_FMT,
4464 "Format information present", HFILL}},
4465
4466 {&hf_radiotap_mcs_have_fec,
4467 {"FEC type", "radiotap.mcs.have_fec",
4468 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_FEC,
4469 "Forward error correction type information present", HFILL}},
4470
4471 {&hf_radiotap_mcs_have_stbc,
4472 {"STBC streams", "radiotap.mcs.have_stbc",
4473 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_STBC,
4474 "Space Time Block Coding streams information present", HFILL}},
4475
4476 {&hf_radiotap_mcs_have_ness,
4477 {"Number of extension spatial streams", "radiotap.mcs.have_ness",
4478 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_NESS,
4479 "Number of extension spatial streams information present", HFILL}},
4480
4481 {&hf_radiotap_mcs_ness_bit1,
4482 {"Number of extension spatial streams bit 1", "radiotap.mcs.ness_bit1",
4483 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_MCS_NESS_BIT1,
4484 "Bit 1 of number of extension spatial streams information", HFILL}},
4485
4486 {&hf_radiotap_mcs_bw,
4487 {"Bandwidth", "radiotap.mcs.bw",
4488 FT_UINT8, BASE_DEC, VALS(mcs_bandwidth),
4489 IEEE80211_RADIOTAP_MCS_BW_MASK, NULL, HFILL}},
4490
4491 {&hf_radiotap_mcs_gi,
4492 {"Guard interval", "radiotap.mcs.gi",
4493 FT_UINT8, BASE_DEC, VALS(mcs_gi), IEEE80211_RADIOTAP_MCS_SGI,
4494 "Sent/Received guard interval", HFILL}},
4495
4496 {&hf_radiotap_mcs_format,
4497 {"Format", "radiotap.mcs.format",
4498 FT_UINT8, BASE_DEC, VALS(mcs_format), IEEE80211_RADIOTAP_MCS_FMT_GF,
4499 NULL, HFILL}},
4500
4501 {&hf_radiotap_mcs_fec,
4502 {"FEC type", "radiotap.mcs.fec",
4503 FT_UINT8, BASE_DEC, VALS(mcs_fec), IEEE80211_RADIOTAP_MCS_FEC_LDPC,
4504 "Forward error correction type", HFILL}},
4505
4506 {&hf_radiotap_mcs_stbc,
4507 {"STBC streams", "radiotap.mcs.stbc",
4508 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_MCS_STBC_MASK,
4509 "Number of Space Time Block Code streams", HFILL}},
4510
4511 {&hf_radiotap_mcs_ness_bit0,
4512 {"Number of extension spatial streams bit 0", "radiotap.mcs.ness_bit1",
4513 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_MCS_NESS_BIT1,
4514 "Bit 0 of number of extension spatial streams information", HFILL}},
4515
4516 {&hf_radiotap_mcs_index,
4517 {"MCS index", "radiotap.mcs.index",
4518 FT_UINT8, BASE_DEC, NULL, 0x0,
4519 NULL, HFILL}},
4520
4521 {&hf_radiotap_ampdu,
4522 {"A-MPDU status", "radiotap.ampdu",
4523 FT_NONE, BASE_NONE, NULL, 0x0,
4524 NULL, HFILL}},
4525
4526 {&hf_radiotap_ampdu_ref,
4527 {"A-MPDU reference number", "radiotap.ampdu.reference",
4528 FT_UINT32, BASE_DEC, NULL, 0x0,
4529 NULL, HFILL}},
4530
4531 {&hf_radiotap_ampdu_flags,
4532 {"A-MPDU flags", "radiotap.ampdu.flags",
4533 FT_UINT16, BASE_HEX, NULL, 0x0,
4534 "A-MPDU status flags", HFILL}},
4535
4536 {&hf_radiotap_ampdu_flags_report_zerolen,
4537 {"Driver reports 0-length subframes in this A-MPDU", "radiotap.ampdu.flags.report_zerolen",
4538 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN,
4539 NULL, HFILL}},
4540
4541 {&hf_radiotap_ampdu_flags_is_zerolen,
4542 {"This is a 0-length subframe", "radiotap.ampdu.flags.is_zerolen",
4543 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN,
4544 NULL, HFILL}},
4545
4546 {&hf_radiotap_ampdu_flags_last_known,
4547 {"Last subframe of this A-MPDU is known", "radiotap.ampdu.flags.lastknown",
4548 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN,
4549 NULL, HFILL}},
4550
4551 {&hf_radiotap_ampdu_flags_is_last,
4552 {"This is the last subframe of this A-MPDU", "radiotap.ampdu.flags.last",
4553 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_IS_LAST,
4554 NULL, HFILL}},
4555
4556 {&hf_radiotap_ampdu_flags_delim_crc_error,
4557 {"Delimiter CRC error on this subframe", "radiotap.ampdu.flags.delim_crc_error",
4558 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR,
4559 NULL, HFILL}},
4560
4561 {&hf_radiotap_ampdu_flags_eof,
4562 {"EOF on this subframe", "radiotap.ampdu.flags.eof",
4563 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_EOF,
4564 NULL, HFILL}},
4565
4566 {&hf_radiotap_ampdu_flags_eof_known,
4567 {"EOF of this A-MPDU is known", "radiotap.ampdu.flags.eof_known",
4568 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN,
4569 NULL, HFILL}},
4570
4571 {&hf_radiotap_ampdu_delim_crc,
4572 {"A-MPDU subframe delimiter CRC", "radiotap.ampdu.delim_crc",
4573 FT_UINT8, BASE_HEX, NULL, 0x0,
4574 NULL, HFILL}},
4575
4576 {&hf_radiotap_vht,
4577 {"VHT information", "radiotap.vht",
4578 FT_NONE, BASE_NONE, NULL, 0x0,
4579 NULL, HFILL}},
4580
4581 {&hf_radiotap_vht_known,
4582 {"Known VHT information", "radiotap.vht.known",
4583 FT_UINT8, BASE_HEX, NULL, 0x0,
4584 "Bit mask indicating what VHT information is present", HFILL}},
4585
4586 {&hf_radiotap_vht_user,
4587 {"User", "radiotap.vht.user",
4588 FT_NONE, BASE_NONE, NULL, 0x0,
4589 NULL, HFILL}},
4590
4591 {&hf_radiotap_vht_have_stbc,
4592 {"STBC", "radiotap.vht.have_stbc",
4593 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_STBC,
4594 "Space Time Block Coding information present", HFILL}},
4595
4596 {&hf_radiotap_vht_have_txop_ps,
4597 {"TXOP_PS_NOT_ALLOWED", "radiotap.vht.have_txop_ps",
4598 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS,
4599 "TXOP_PS_NOT_ALLOWED information present", HFILL}},
4600
4601 {&hf_radiotap_vht_have_gi,
4602 {"Guard interval", "radiotap.vht.have_gi",
4603 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_GI,
4604 "Short/Long guard interval information present", HFILL}},
4605
4606 {&hf_radiotap_vht_have_sgi_nsym_da,
4607 {"SGI Nsym disambiguation", "radiotap.vht.have_sgi_nsym_da",
4608 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA,
4609 "Short guard interval Nsym disambiguation information present", HFILL}},
4610
4611 {&hf_radiotap_vht_have_ldpc_extra,
4612 {"LDPC extra OFDM symbol", "radiotap.vht.ldpc_extra",
4613 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA,
4614 NULL, HFILL}},
4615
4616 {&hf_radiotap_vht_have_bf,
4617 {"Beamformed", "radiotap.vht.have_beamformed",
4618 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_BF,
4619 NULL, HFILL}},
4620
4621 {&hf_radiotap_vht_have_bw,
4622 {"Bandwidth", "radiotap.mcs.have_bw",
4623 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_BW,
4624 NULL, HFILL}},
4625
4626 {&hf_radiotap_vht_have_gid,
4627 {"Group ID", "radiotap.mcs.have_gid",
4628 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_GID,
4629 NULL, HFILL}},
4630
4631 {&hf_radiotap_vht_have_p_aid,
4632 {"Partial AID", "radiotap.mcs.have_paid",
4633 FT_BOOLEAN, 16, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_VHT_HAVE_PAID,
4634 NULL, HFILL}},
4635
4636 {&hf_radiotap_vht_stbc,
4637 {"STBC", "radiotap.vht.stbc",
4638 FT_BOOLEAN, 8, TFS(&tfs_on_off), IEEE80211_RADIOTAP_VHT_STBC,
4639 "Space Time Block Coding flag", HFILL}},
4640
4641 {&hf_radiotap_vht_txop_ps,
4642 {"TXOP_PS_NOT_ALLOWED", "radiotap.vht.txop_ps",
4643 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_TXOP_PS,
4644 "Flag indicating whether STAs may doze during TXOP", HFILL}},
4645
4646 {&hf_radiotap_vht_gi,
4647 {"Guard interval", "radiotap.vht.gi",
4648 FT_UINT8, BASE_DEC, VALS(mcs_gi), IEEE80211_RADIOTAP_VHT_SGI,
4649 "Short/Long guard interval", HFILL}},
4650
4651 {&hf_radiotap_vht_sgi_nsym_da,
4652 {"SGI Nsym disambiguation", "radiotap.vht.sgi_nsym_da",
4653 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA,
4654 "Short Guard Interval Nsym disambiguation", HFILL}},
4655
4656 {&hf_radiotap_vht_ldpc_extra,
4657 {"LDPC extra OFDM symbol", "radiotap.vht.ldpc_extra",
4658 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_LDPC_EXTRA,
4659 NULL, HFILL}},
4660
4661 {&hf_radiotap_vht_bf,
4662 {"Beamformed", "radiotap.vht.beamformed",
4663 FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_BF,
4664 NULL, HFILL}},
4665
4666 {&hf_radiotap_vht_bw,
4667 {"Bandwidth", "radiotap.vht.bw",
4668 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &vht_bandwidth_ext, 0x0,
4669 NULL, HFILL}},
4670
4671 {&hf_radiotap_vht_nsts[0],
4672 {"Space-time streams 0", "radiotap.vht.nsts.0",
4673 FT_UINT8, BASE_DEC, NULL, 0x0,
4674 "Number of Space-time streams", HFILL}},
4675
4676 {&hf_radiotap_vht_nsts[1],
4677 {"Space-time streams 1", "radiotap.vht.nsts.1",
4678 FT_UINT8, BASE_DEC, NULL, 0x0,
4679 "Number of Space-time streams", HFILL}},
4680
4681 {&hf_radiotap_vht_nsts[2],
4682 {"Space-time streams 2", "radiotap.vht.nsts.2",
4683 FT_UINT8, BASE_DEC, NULL, 0x0,
4684 "Number of Space-time streams", HFILL}},
4685
4686 {&hf_radiotap_vht_nsts[3],
4687 {"Space-time streams 3", "radiotap.vht.nsts.3",
4688 FT_UINT8, BASE_DEC, NULL, 0x0,
4689 "Number of Space-time streams", HFILL}},
4690
4691 {&hf_radiotap_vht_mcs[0],
4692 {"MCS index 0", "radiotap.vht.mcs.0",
4693 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
4694 "MCS index", HFILL}},
4695
4696 {&hf_radiotap_vht_mcs[1],
4697 {"MCS index 1", "radiotap.vht.mcs.1",
4698 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
4699 "MCS index", HFILL}},
4700
4701 {&hf_radiotap_vht_mcs[2],
4702 {"MCS index 2", "radiotap.vht.mcs.2",
4703 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
4704 "MCS index", HFILL}},
4705
4706 {&hf_radiotap_vht_mcs[3],
4707 {"MCS index 3", "radiotap.vht.mcs.3",
4708 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
4709 "MCS index", HFILL}},
4710
4711 {&hf_radiotap_vht_nss[0],
4712 {"Spatial streams 0", "radiotap.vht.nss.0",
4713 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
4714 "Number of spatial streams", HFILL}},
4715
4716 {&hf_radiotap_vht_nss[1],
4717 {"Spatial streams 1", "radiotap.vht.nss.1",
4718 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
4719 "Number of spatial streams", HFILL}},
4720
4721 {&hf_radiotap_vht_nss[2],
4722 {"Spatial streams 2", "radiotap.vht.nss.2",
4723 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
4724 "Number of spatial streams", HFILL}},
4725
4726 {&hf_radiotap_vht_nss[3],
4727 {"Spatial streams 3", "radiotap.vht.nss.3",
4728 FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
4729 "Number of spatial streams", HFILL}},
4730
4731 {&hf_radiotap_vht_coding[0],
4732 {"Coding 0", "radiotap.vht.coding.0",
4733 FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x01,
4734 "Coding", HFILL}},
4735
4736 {&hf_radiotap_vht_coding[1],
4737 {"Coding 1", "radiotap.vht.coding.1",
4738 FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x02,
4739 "Coding", HFILL}},
4740
4741 {&hf_radiotap_vht_coding[2],
4742 {"Coding 2", "radiotap.vht.coding.2",
4743 FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x04,
4744 "Coding", HFILL}},
4745
4746 {&hf_radiotap_vht_coding[3],
4747 {"Coding 3", "radiotap.vht.coding.3",
4748 FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x08,
4749 "Coding", HFILL}},
4750
4751 {&hf_radiotap_vht_datarate[0],
4752 {"Data rate (Mb/s) 0", "radiotap.vht.datarate.0",
4753 FT_FLOAT, BASE_NONE, NULL, 0x0,
4754 "Speed this frame was sent/received at", HFILL}},
4755
4756 {&hf_radiotap_vht_datarate[1],
4757 {"Data rate (Mb/s) 1", "radiotap.vht.datarate.1",
4758 FT_FLOAT, BASE_NONE, NULL, 0x0,
4759 "Speed this frame was sent/received at", HFILL}},
4760
4761 {&hf_radiotap_vht_datarate[2],
4762 {"Data rate (Mb/s) 2", "radiotap.vht.datarate.2",
4763 FT_FLOAT, BASE_NONE, NULL, 0x0,
4764 "Speed this frame was sent/received at", HFILL}},
4765
4766 {&hf_radiotap_vht_datarate[3],
4767 {"Data rate (Mb/s) 3", "radiotap.vht.datarate.3",
4768 FT_FLOAT, BASE_NONE, NULL, 0x0,
4769 "Speed this frame was sent/received at", HFILL}},
4770
4771 {&hf_radiotap_vht_gid,
4772 {"Group Id", "radiotap.vht.gid",
4773 FT_UINT8, BASE_DEC, NULL, 0x0,
4774 NULL, HFILL}},
4775
4776 {&hf_radiotap_vht_p_aid,
4777 {"Partial AID", "radiotap.vht.paid",
4778 FT_UINT16, BASE_DEC, NULL, 0x0,
4779 NULL, HFILL}},
4780
4781 {&hf_radiotap_timestamp,
4782 {"timestamp information", "radiotap.timestamp",
4783 FT_NONE, BASE_NONE, NULL, 0x0,
4784 NULL, HFILL}},
4785
4786 {&hf_radiotap_timestamp_ts,
4787 {"timestamp", "radiotap.timestamp.ts",
4788 FT_UINT64, BASE_DEC, NULL, 0x0,
4789 NULL, HFILL}},
4790
4791 {&hf_radiotap_timestamp_accuracy,
4792 {"accuracy", "radiotap.timestamp.accuracy",
4793 FT_UINT16, BASE_DEC, NULL, 0x0,
4794 NULL, HFILL}},
4795
4796 {&hf_radiotap_timestamp_unit,
4797 {"time unit", "radiotap.timestamp.unit",
4798 FT_UINT8, BASE_DEC, VALS(timestamp_unit),
4799 IEEE80211_RADIOTAP_TS_UNIT_MASK,
4800 NULL, HFILL}},
4801
4802 {&hf_radiotap_timestamp_spos,
4803 {"sampling position", "radiotap.timestamp.samplingpos",
4804 FT_UINT8, BASE_DEC, VALS(timestamp_spos),
4805 IEEE80211_RADIOTAP_TS_SPOS_MASK,
4806 NULL, HFILL}},
4807
4808 {&hf_radiotap_timestamp_flags_32bit,
4809 {"32-bit counter", "radiotap.timestamp.flags.32bit",
4810 FT_BOOLEAN, 8, TFS(&tfs_yes_no), IEEE80211_RADIOTAP_TS_FLG_32BIT,
4811 NULL, HFILL}},
4812
4813 {&hf_radiotap_timestamp_flags_accuracy,
4814 {"accuracy field", "radiotap.timestamp.flags.accuracy",
4815 FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_TS_FLG_ACCURACY,
4816 NULL, HFILL}},
4817
4818 {&hf_radiotap_vendor_ns,
4819 {"Vendor namespace", "radiotap.vendor_namespace",
4820 FT_BYTES, BASE_NONE, NULL, 0x0,
4821 NULL, HFILL}},
4822
4823 {&hf_radiotap_ven_oui,
4824 {"Vendor OUI", "radiotap.vendor_oui",
4825 FT_UINT24, BASE_OUI, NULL, 0x0,
4826 NULL, HFILL}},
4827
4828 {&hf_radiotap_ven_subns,
4829 {"Vendor sub namespace", "radiotap.vendor_subns",
4830 FT_UINT8, BASE_DEC, NULL, 0x0,
4831 "Vendor-specified sub namespace", HFILL}},
4832
4833 {&hf_radiotap_ven_skip,
4834 {"Vendor data length", "radiotap.vendor_data_len",
4835 FT_UINT16, BASE_DEC, NULL, 0x0,
4836 "Length of vendor-specified data", HFILL}},
4837
4838 {&hf_radiotap_ven_item,
4839 {"Vendor data item type", "radiotap.vendor_data_item_type",
4840 FT_UINT16, BASE_DEC, NULL, 0x0,
4841 "Item type of vendor-specific data", HFILL}},
4842
4843 {&hf_radiotap_ven_data,
4844 {"Vendor data", "radiotap.vendor_data",
4845 FT_NONE, BASE_NONE, NULL, 0x0,
4846 "Vendor-specified data", HFILL}},
4847
4848 /* Special variables */
4849 {&hf_radiotap_fcs_bad,
4850 {"Bad FCS", "radiotap.fcs_bad",
4851 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4852 "Specifies if this frame has a bad frame check sequence", HFILL}},
4853
4854 {&hf_radiotap_he_info_data_1,
4855 {"HE Data 1", "radiotap.he.data_1",
4856 FT_UINT16, BASE_HEX, NULL, 0x0,
4857 "Data 1 of the HE Info field", HFILL}},
4858
4859 {&hf_radiotap_he_ppdu_format,
4860 {"PPDU Format", "radiotap.he.data_1.ppdu_format",
4861 FT_UINT16, BASE_HEX, VALS(he_pdu_format_vals),
4862 IEEE80211_RADIOTAP_HE_PPDU_FORMAT_MASK, NULL, HFILL}},
4863
4864 {&hf_radiotap_he_bss_color_known,
4865 {"BSS Color known", "radiotap.he.data_1.bss_color_known",
4866 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4867 IEEE80211_RADIOTAP_HE_BSS_COLOR_KNOWN, NULL, HFILL}},
4868
4869 {&hf_radiotap_he_beam_change_known,
4870 {"Beam Change known", "radiotap.he.data_1.beam_change_known",
4871 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4872 IEEE80211_RADIOTAP_HE_BEAM_CHANGE_KNOWN, NULL, HFILL}},
4873
4874 {&hf_radiotap_he_ul_dl_known,
4875 {"UL/DL known", "radiotap.he.data_1.ul_dl_known",
4876 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4877 IEEE80211_RADIOTAP_HE_UL_DL_KNOWN, NULL, HFILL}},
4878
4879 {&hf_radiotap_he_data_mcs_known,
4880 {"data MCS known", "radiotap.he.data_1.data_mcs_known",
4881 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4882 IEEE80211_RADIOTAP_HE_DATA_MCS_KNOWN, NULL, HFILL}},
4883
4884 {&hf_radiotap_he_data_dcm_known,
4885 {"data DCM known", "radiotap.he.data_1.data_dcm_known",
4886 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4887 IEEE80211_RADIOTAP_HE_DATA_DCM_KNOWN, NULL, HFILL}},
4888
4889 {&hf_radiotap_he_coding_known,
4890 {"Coding known", "radiotap.he.data_1.coding_known",
4891 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4892 IEEE80211_RADIOTAP_HE_CODING_KNOWN, NULL, HFILL}},
4893
4894 {&hf_radiotap_he_ldpc_extra_symbol_segment_known,
4895 {"LDPC extra symbol segment known", "radiotap.he.data_1.ldpc_extra_symbol_segment_known",
4896 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4897 IEEE80211_RADIOTAP_HE_LDPC_EXTRA_SYMBOL_SEGMENT_KNOWN, NULL, HFILL}},
4898
4899 {&hf_radiotap_he_stbc_known,
4900 {"STBC known", "radiotap.he.data_1.stbc_known",
4901 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4902 IEEE80211_RADIOTAP_HE_STBC_KNOWN, NULL, HFILL}},
4903
4904 {&hf_radiotap_he_spatial_reuse_1_known,
4905 {"Spatial Reuse 1 known", "radiotap.he.data_1.spatial_reuse_1_known",
4906 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4907 IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_KNOWN, NULL, HFILL}},
4908
4909 {&hf_radiotap_he_spatial_reuse_2_known,
4910 {"Spatial Reuse 2 known", "radiotap.he.data_1.spatial_reuse_2_known",
4911 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4912 IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_2_KNOWN, NULL, HFILL}},
4913
4914 {&hf_radiotap_he_spatial_reuse_3_known,
4915 {"Spatial Reuse 3 known", "radiotap.he.data_1.spatial_reuse_3_known",
4916 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4917 IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_3_KNOWN, NULL, HFILL}},
4918
4919 {&hf_radiotap_he_spatial_reuse_4_known,
4920 {"Spatial Reuse 4 known", "radiotap.he.data_1.spatial_reuse_4_known",
4921 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4922 IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_4_KNOWN, NULL, HFILL}},
4923
4924 {&hf_radiotap_he_data_bw_ru_allocation_known,
4925 {"dat BW/RU allocation known", "radiotap.he.data_1.data_bw_ru_allocation_known",
4926 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4927 IEEE80211_RADIOTAP_HE_DATA_BW_RU_ALLOCATION_KNOWN, NULL, HFILL}},
4928
4929 {&hf_radiotap_he_doppler_known,
4930 {"Doppler known", "radiotap.he.data_1.doppler_known",
4931 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4932 IEEE80211_RADIOTAP_HE_DOPPLER_KNOWN, NULL, HFILL}},
4933
4934 {&hf_radiotap_he_info_data_2,
4935 {"HE Data 2", "radiotap.he.data_2",
4936 FT_UINT16, BASE_HEX, NULL, 0x0,
4937 "Data 1 of the HE Info field", HFILL}},
4938
4939 {&hf_radiotap_he_pri_sec_80_mhz_known,
4940 {"pri/sec 80 MHz known", "radiotap.he.data_2.pri_sec_80_mhz_known",
4941 FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_HE_PRI_SEC_80_MHZ_KNOWN,
4942 NULL, HFILL}},
4943
4944 {&hf_radiotap_he_gi_known,
4945 {"GI known", "radiotap.he.data_2.gi_known",
4946 FT_BOOLEAN, 16, TFS(&tfs_known_unknown), IEEE80211_RADIOTAP_HE_GI_KNOWN,
4947 NULL, HFILL}},
4948
4949 {&hf_radiotap_he_num_ltf_symbols_known,
4950 {"LTF symbols known", "radiotap.he.data_2.num_ltf_symbols_known",
4951 FT_BOOLEAN, 16, TFS(&tfs_known_unknown), IEEE80211_RADIOTAP_HE_NUM_LTF_SYMBOLS_KNOWN,
4952 NULL, HFILL}},
4953
4954 {&hf_radiotap_he_pre_fec_padding_factor_known,
4955 {"Pre-FEC Padding Factor known", "radiotap.he.data_2.pre_fec_padding_factor_known",
4956 FT_BOOLEAN, 16, TFS(&tfs_known_unknown), IEEE80211_RADIOTAP_HE_PRE_FEC_PADDING_FACTOR_KNOWN,
4957 NULL, HFILL}},
4958
4959 {&hf_radiotap_he_txbf_known,
4960 {"TxBF known", "radiotap.he.data_2.txbf_known",
4961 FT_BOOLEAN, 16, TFS(&tfs_known_unknown), IEEE80211_RADIOTAP_HE_TXBF_KNOWN,
4962 NULL, HFILL}},
4963
4964 {&hf_radiotap_he_pe_disambiguity_known,
4965 {"PE Disambiguity known", "radiotap.he.data_2.pe_disambiguity_known",
4966 FT_BOOLEAN, 16, TFS(&tfs_known_unknown), IEEE80211_RADIOTAP_HE_PE_DISAMBIGUITY_KNOWN,
4967 NULL, HFILL}},
4968
4969 {&hf_radiotap_he_txop_known,
4970 {"TXOP known", "radiotap.he.data_2.txop_known",
4971 FT_BOOLEAN, 16, TFS(&tfs_known_unknown), IEEE80211_RADIOTAP_HE_TXOP_KNOWN,
4972 NULL, HFILL}},
4973
4974 {&hf_radiotap_he_midamble_periodicity_known,
4975 {"midamble periodicity known", "radiotap.he.data_2.midamble_periodicity_known",
4976 FT_BOOLEAN, 16, TFS(&tfs_known_unknown), IEEE80211_RADIOTAP_HE_MIDAMBLE_PERIODICITY_KNOWN,
4977 NULL, HFILL}},
4978
4979 {&hf_radiotap_he_ru_allocation_offset,
4980 {"RU allocation offset", "radiotap.he.data_2.ru_allocation_offset",
4981 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_RU_ALLOCATION_OFFSET,
4982 NULL, HFILL}},
4983
4984 {&hf_radiotap_he_ru_allocation_offset_known,
4985 {"RU allocation offset known", "radiotap.he.data_2.ru_allocation_offseti_known",
4986 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
4987 IEEE80211_RADIOTAP_HE_RU_ALLOCATION_OFFSET_KNOWN,
4988 NULL, HFILL}},
4989
4990 {&hf_radiotap_he_pri_sec_80_mhz,
4991 {"pri/sec 80 MHz", "radiotap.he.data_2.pri_sec_80_mhz",
4992 FT_BOOLEAN, 16, TFS(&tfs_pri_sec_80_mhz),
4993 IEEE80211_RADIOTAP_HE_PRI_SEC_80_MHZ,
4994 NULL, HFILL}},
4995
4996 {&hf_radiotap_he_bss_color,
4997 {"BSS Color", "radiotap.he.data_3.bss_color",
4998 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_BSS_COLOR_MASK,
4999 NULL, HFILL}},
5000
5001 {&hf_radiotap_he_bss_color_unknown,
5002 {"BSS Color unknown", "radiotap.he.data_3.bss_color_unknown",
5003 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_BSS_COLOR_MASK,
5004 NULL, HFILL}},
5005
5006 {&hf_radiotap_he_beam_change,
5007 {"Beam Change", "radiotap.he.data_3.beam_change",
5008 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_BEAM_CHANGE,
5009 NULL, HFILL}},
5010
5011 {&hf_radiotap_he_beam_change_unknown,
5012 {"Beam Change unknown", "radiotap.he.data_3.beam_change_unknown",
5013 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_BEAM_CHANGE,
5014 NULL, HFILL}},
5015
5016 {&hf_radiotap_he_ul_dl,
5017 {"UL/DL", "radiotap.he.data_3.ul_dl",
5018 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_UL_DL,
5019 NULL, HFILL}},
5020
5021 {&hf_radiotap_he_ul_dl_unknown,
5022 {"UL/DL unknown", "radiotap.he.data_3.ul_dl_unknown",
5023 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_UL_DL,
5024 NULL, HFILL}},
5025
5026 {&hf_radiotap_he_data_mcs,
5027 {"data MCS", "radiotap.he.data_3.data_mcs",
5028 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_DATA_MCS_MASK,
5029 NULL, HFILL}},
5030
5031 {&hf_radiotap_he_data_mcs_unknown,
5032 {"data MCS unknown", "radiotap.he.data_3.data_mcs_unknown",
5033 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_DATA_MCS_MASK,
5034 NULL, HFILL}},
5035
5036 {&hf_radiotap_he_data_dcm,
5037 {"data DCM", "radiotap.he.data_3.data_dcm",
5038 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_DATA_DCM,
5039 NULL, HFILL}},
5040
5041 {&hf_radiotap_he_data_dcm_unknown,
5042 {"data DCM unknown", "radiotap.he.data_3.data_dcm_unknown",
5043 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_DATA_DCM,
5044 NULL, HFILL}},
5045
5046 {&hf_radiotap_he_coding,
5047 {"Coding", "radiotap.he.data_3.coding",
5048 FT_UINT16, BASE_HEX, VALS(he_coding_vals),
5049 IEEE80211_RADIOTAP_HE_CODING, NULL, HFILL}},
5050
5051 {&hf_radiotap_he_coding_unknown,
5052 {"Coding unknown", "radiotap.he.data_3.coding_unknown",
5053 FT_UINT16, BASE_HEX, NULL,
5054 IEEE80211_RADIOTAP_HE_CODING, NULL, HFILL}},
5055
5056 {&hf_radiotap_he_ldpc_extra_symbol_segment,
5057 {"LDPC extra symbol segment", "radiotap.he.data_3.ldpc_extra_symbol_segment",
5058 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_LDPC_EXTRA_SYMBOL_SEGMENT,
5059 NULL, HFILL}},
5060
5061 {&hf_radiotap_he_ldpc_extra_symbol_segment_unknown,
5062 {"LDPC extra symbol segment unknown",
5063 "radiotap.he.data_3.ldpc_extra_symbol_segment_unknown",
5064 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_LDPC_EXTRA_SYMBOL_SEGMENT,
5065 NULL, HFILL}},
5066
5067 {&hf_radiotap_he_stbc,
5068 {"STBC", "radiotap.he.data_3.stbc",
5069 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_STBC,
5070 NULL, HFILL}},
5071
5072 {&hf_radiotap_he_stbc_unknown,
5073 {"STBC unknown", "radiotap.he.data_3.stbc_unknown",
5074 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_STBC,
5075 NULL, HFILL}},
5076
5077 {&hf_radiotap_he_info_data_3,
5078 {"HE Data 3", "radiotap.he.data_3",
5079 FT_UINT16, BASE_HEX, NULL, 0x0,
5080 "Data 1 of the HE Info field", HFILL}},
5081
5082 {&hf_radiotap_spatial_reuse,
5083 {"Spatial Reuse", "radiotap.he.data_4.spatial_reuse",
5084 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_MASK,
5085 NULL, HFILL}},
5086
5087 {&hf_radiotap_spatial_reuse_unknown,
5088 {"Spatial Reuse unknown", "radiotap.he.data_4.spatial_reuse_unknown",
5089 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_MASK,
5090 NULL, HFILL}},
5091
5092 {&hf_radiotap_he_su_reserved,
5093 {"Reserved", "radiotap.he.data_4.reserved_d4_fff0",
5094 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_D4_FFF0,
5095 NULL, HFILL}},
5096
5097 {&hf_radiotap_spatial_reuse_1,
5098 {"Spatial Reuse 1", "radiotap.he.data_4.spatial_reuse_1",
5099 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_1_MASK,
5100 NULL, HFILL}},
5101
5102 {&hf_radiotap_spatial_reuse_1_unknown,
5103 {"Spatial Reuse 1 unknown", "radiotap.he.data_4.spatial_reuse_1_unknown",
5104 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_1_MASK,
5105 NULL, HFILL}},
5106
5107 {&hf_radiotap_spatial_reuse_2,
5108 {"Spatial Reuse 2", "radiotap.he.data_4.spatial_reuse_2",
5109 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_2_MASK,
5110 NULL, HFILL}},
5111
5112 {&hf_radiotap_spatial_reuse_2_unknown,
5113 {"Spatial Reuse 2 unknown", "radiotap.he.data_4.spatial_reuse_2_unknown",
5114 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_2_MASK,
5115 NULL, HFILL}},
5116
5117 {&hf_radiotap_spatial_reuse_3,
5118 {"Spatial Reuse 3", "radiotap.he.data_4.spatial_reuse_3",
5119 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_3_MASK,
5120 NULL, HFILL}},
5121
5122 {&hf_radiotap_spatial_reuse_3_unknown,
5123 {"Spatial Reuse 3 unknown", "radiotap.he.data_4.spatial_reuse_3_unknown",
5124 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_3_MASK,
5125 NULL, HFILL}},
5126
5127 {&hf_radiotap_spatial_reuse_4,
5128 {"Spatial Reuse 4", "radiotap.he.data_4.spatial_reuse_4",
5129 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_4_MASK,
5130 NULL, HFILL}},
5131
5132 {&hf_radiotap_spatial_reuse_4_unknown,
5133 {"Spatial Reuse 4 unknown", "radiotap.he.data_4.spatial_reuse_4_unknown",
5134 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_SPATIAL_REUSE_4_MASK,
5135 NULL, HFILL}},
5136
5137 {&hf_radiotap_sta_id_user_captured,
5138 {"STA-ID of user data captured for", "radiotap.he.data_4.sta_id_user",
5139 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_STA_ID_MASK,
5140 NULL, HFILL}},
5141
5142 {&hf_radiotap_he_mu_reserved,
5143 {"Reserved", "radiotap.he.data_4.reserved_d4_b15",
5144 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_RESERVED_D4_B15,
5145 NULL, HFILL}},
5146
5147 {&hf_radiotap_he_info_data_4,
5148 {"HE Data 4", "radiotap.he.data_4",
5149 FT_UINT16, BASE_HEX, NULL, 0x0,
5150 "Data 1 of the HE Info field", HFILL}},
5151
5152 {&hf_radiotap_data_bandwidth_ru_allocation,
5153 {"data Bandwidth/RU allocation", "radiotap.he.data_5.data_bw_ru_allocation",
5154 FT_UINT16, BASE_HEX, VALS(he_data_bw_ru_alloc_vals),
5155 IEEE80211_RADIOTAP_HE_DATA_BANDWIDTH_RU_ALLOC_MASK, NULL, HFILL}},
5156
5157 {&hf_radiotap_data_bandwidth_ru_allocation_unknown,
5158 {"data Bandwidth/RU allocation unknown",
5159 "radiotap.he.data_5.data_bw_ru_allocation_unknown",
5160 FT_UINT16, BASE_HEX, NULL,
5161 IEEE80211_RADIOTAP_HE_DATA_BANDWIDTH_RU_ALLOC_MASK, NULL, HFILL}},
5162
5163 {&hf_radiotap_gi,
5164 {"GI", "radiotap.he.data_5.gi",
5165 FT_UINT16, BASE_HEX, VALS(he_gi_vals), IEEE80211_RADIOTAP_HE_GI_MASK,
5166 NULL, HFILL}},
5167
5168 {&hf_radiotap_gi_unknown,
5169 {"GI unknown", "radiotap.he.data_5.gi_unknown",
5170 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_GI_MASK,
5171 NULL, HFILL}},
5172
5173 {&hf_radiotap_ltf_symbol_size,
5174 {"LTF symbol size", "radiotap.he.data_5.ltf_symbol_size",
5175 FT_UINT16, BASE_HEX, VALS(he_ltf_symbol_size_vals),
5176 IEEE80211_RADIOTAP_HE_LTF_SYMBOL_SIZE, NULL, HFILL}},
5177
5178 {&hf_radiotap_ltf_symbol_size_unknown,
5179 {"LTF symbol size unknown", "radiotap.he.data_5.ltf_symbol_size_unknown",
5180 FT_UINT16, BASE_HEX, NULL,
5181 IEEE80211_RADIOTAP_HE_LTF_SYMBOL_SIZE, NULL, HFILL}},
5182
5183 {&hf_radiotap_num_ltf_symbols,
5184 {"LTF symbols", "radiotap.he.num_ltf_symbols",
5185 FT_UINT16, BASE_HEX, VALS(he_num_ltf_symbols_vals),
5186 IEEE80211_RADIOTAP_HE_NUM_LTF_SYMBOLS_MASK, NULL, HFILL}},
5187
5188 {&hf_radiotap_num_ltf_symbols_unknown,
5189 {"LTF symbols unknown", "radiotap.he.num_ltf_symbols_unknown",
5190 FT_UINT16, BASE_HEX, NULL,
5191 IEEE80211_RADIOTAP_HE_NUM_LTF_SYMBOLS_MASK, NULL, HFILL}},
5192
5193 {&hf_radiotap_d5_reserved_b11,
5194 {"reserved", "radiotap.he.data_5.reserved_d5_b11",
5195 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_RESERVED_D5_B11,
5196 NULL, HFILL}},
5197
5198 {&hf_radiotap_pre_fec_padding_factor,
5199 {"Pre-FEC Padding Factor", "radiotap.he.pre_fec_padding_factor",
5200 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_PRE_FEC_PADDING_FACTOR_MASK,
5201 NULL, HFILL}},
5202
5203 {&hf_radiotap_pre_fec_padding_factor_unknown,
5204 {"Pre-FEC Padding Factor unknown", "radiotap.he.pre_fec_padding_factor_unknown",
5205 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_PRE_FEC_PADDING_FACTOR_MASK,
5206 NULL, HFILL}},
5207
5208 {&hf_radiotap_txbf,
5209 {"TxBF", "radiotap.he.txbf",
5210 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_TXBF,
5211 NULL, HFILL}},
5212
5213 {&hf_radiotap_txbf_unknown,
5214 {"TxBF unknown", "radiotap.he.txbf_unknown",
5215 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_TXBF,
5216 NULL, HFILL}},
5217
5218 {&hf_radiotap_pe_disambiguity,
5219 {"PE Disambiguity", "radiotap.he.pe_disambiguity",
5220 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_PE_DISAMBIGUITY,
5221 NULL, HFILL}},
5222
5223 {&hf_radiotap_pe_disambiguity_unknown,
5224 {"PE Disambiguity unknown", "radiotap.he.pe_disambiguity_unknown",
5225 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_PE_DISAMBIGUITY,
5226 NULL, HFILL}},
5227
5228 {&hf_radiotap_he_info_data_5,
5229 {"HE Data 5", "radiotap.he.data_5",
5230 FT_UINT16, BASE_HEX, NULL, 0x0,
5231 "Data 1 of the HE Info field", HFILL}},
5232
5233 {&hf_radiotap_he_nsts,
5234 {"NSTS", "radiotap.he.data_6.nsts",
5235 FT_UINT16, BASE_HEX, VALS(he_nsts_vals),IEEE80211_RADIOTAP_HE_NSTS_MASK,
5236 NULL, HFILL}},
5237
5238 {&hf_radiotap_he_doppler_value,
5239 {"Doppler value", "radiotap.he.data_6.doppler_value",
5240 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_DOPLER_VALUE,
5241 NULL, HFILL}},
5242
5243 {&hf_radiotap_he_doppler_value_unknown,
5244 {"Doppler value unknown", "radiotap.he.data_6.doppler_value_unknown",
5245 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_DOPLER_VALUE,
5246 NULL, HFILL}},
5247
5248 {&hf_radiotap_he_d6_reserved_00e0,
5249 {"Reserved", "radiotap.he.data_6.reserved_d6_00e0",
5250 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_RESERVED_D6_00E0,
5251 NULL, HFILL}},
5252
5253 {&hf_radiotap_he_txop_value,
5254 {"TXOP value", "radiotap.he.data_6.txop_value",
5255 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_TXOP_VALUE_MASK,
5256 NULL, HFILL}},
5257
5258 {&hf_radiotap_he_txop_value_unknown,
5259 {"TXOP value unknown", "radiotap.he.data_6.txop_value_unknown",
5260 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_TXOP_VALUE_MASK,
5261 NULL, HFILL}},
5262
5263 {&hf_radiotap_midamble_periodicity,
5264 {"midamble periodicity", "radiotap.he.data_6.midamble_periodicity",
5265 FT_UINT16, BASE_HEX, VALS(he_midamble_periodicity_vals),
5266 IEEE80211_RADIOTAP_HE_MIDAMBLE_PERIODICITY, NULL, HFILL}},
5267
5268 {&hf_radiotap_midamble_periodicity_unknown,
5269 {"midamble periodicity unknown",
5270 "radiotap.he.data_6.midamble_periodicity_unknown",
5271 FT_UINT16, BASE_HEX, NULL,
5272 IEEE80211_RADIOTAP_HE_MIDAMBLE_PERIODICITY, NULL, HFILL}},
5273
5274 {&hf_radiotap_he_info_data_6,
5275 {"HE Data 6", "radiotap.he.data_6",
5276 FT_UINT16, BASE_HEX, NULL, 0x0,
5277 "Data 1 of the HE Info field", HFILL}},
5278
5279 {&hf_radiotap_he_mu_sig_b_mcs,
5280 {"SIG-B MCS (from SIG-A)", "radiotap.he_mu.sig_b_mcs",
5281 FT_UINT16, BASE_HEX, NULL,
5282 IEEE80211_RADIOTAP_HE_MU_SIG_B_MCS_MASK, NULL, HFILL}},
5283
5284 {&hf_radiotap_he_mu_sig_b_mcs_unknown,
5285 {"SIG-B MCS (from SIG-A) unknown",
5286 "radiotap.he_mu.sig_b_mcs_unknown",
5287 FT_UINT16, BASE_HEX, NULL,
5288 IEEE80211_RADIOTAP_HE_MU_SIG_B_MCS_MASK, NULL, HFILL}},
5289
5290 {&hf_radiotap_he_mu_sig_b_mcs_known,
5291 {"SIG-B MCS known", "radiotap.he_mu.sig_b_mcs_known",
5292 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5293 IEEE80211_RADIOTAP_HE_MU_SIG_B_MCS_KNOWN, NULL, HFILL}},
5294
5295 {&hf_radiotap_he_mu_sig_b_dcm,
5296 {"SIG-B DCM (from SIG-A)", "radiotap.he_mu.sig_b_dcm",
5297 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_MU_SIG_B_DCM,
5298 NULL, HFILL}},
5299
5300 {&hf_radiotap_he_mu_sig_b_dcm_unknown,
5301 {"SIG-B DCM (from SIG-A) unknown",
5302 "radiotap.he_mu.sig_b_dcm_unknown",
5303 FT_UINT16, BASE_HEX, NULL, IEEE80211_RADIOTAP_HE_MU_SIG_B_DCM,
5304 NULL, HFILL}},
5305
5306 {&hf_radiotap_he_mu_sig_b_dcm_known,
5307 {"SIG-B DCM known", "radiotap.he_mu.sig_b_dmc_known",
5308 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5309 IEEE80211_RADIOTAP_HE_MU_SIG_B_DCM_KNOWN, NULL, HFILL}},
5310
5311 {&hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_known,
5312 {"Channel2 center 26-tone RU bit known", "radiotap.he_mu.chan2_center_26_tone_ru_bit_known",
5313 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5314 IEEE80211_RADIOTAP_HE_MU_CHAN2_CENTER_26_TONE_RU_BIT_KNOWN, NULL, HFILL}},
5315
5316 {&hf_radiotap_he_mu_chan2_center_26_tone_ru_bit_unknown,
5317 {"Channel2 center 26-tone RU bit known", "radiotap.he_mu.chan2_center_26_tone_ru_bit_unknown",
5318 FT_UINT16, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5319 IEEE80211_RADIOTAP_HE_MU_CHAN2_CENTER_26_TONE_RU_BIT_KNOWN, NULL, HFILL}},
5320
5321 {&hf_radiotap_he_mu_chan1_rus_known,
5322 {"Channel 1 RUs known", "radiotap.he_mu.chan1_rus_known",
5323 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5324 IEEE80211_RADIOTAP_HE_MU_CHAN1_RUS_KNOWN, NULL, HFILL}},
5325
5326 {&hf_radiotap_he_mu_chan1_rus_unknown,
5327 {"Channel 1 RUs unknown", "radiotap.he_mu.chan1_rus_unknown",
5328 FT_UINT16, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5329 IEEE80211_RADIOTAP_HE_MU_CHAN1_RUS_KNOWN, NULL, HFILL}},
5330
5331 {&hf_radiotap_he_mu_chan2_rus_known,
5332 {"Channel 2 RUs known", "radiotap.he_mu.chan2_rus_known",
5333 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5334 IEEE80211_RADIOTAP_HE_MU_CHAN2_RUS_KNOWN, NULL, HFILL}},
5335
5336 {&hf_radiotap_he_mu_chan2_rus_unknown,
5337 {"Channel 2 RUs unknown", "radiotap.he_mu.chan2_rus_unknown",
5338 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5339 IEEE80211_RADIOTAP_HE_MU_CHAN2_RUS_KNOWN, NULL, HFILL}},
5340
5341 {&hf_radiotap_he_mu_reserved_f1_b10_b11,
5342 {"Reserved", "radiotap.he_mu.reserved_f1_b10_b11",
5343 FT_UINT16, BASE_HEX, NULL,
5344 IEEE80211_RADIOTAP_HE_MU_RESERVED_F1_B10_B11, NULL, HFILL}},
5345
5346 {&hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_known,
5347 {"Channel1 center 26-tone RU bit known", "radiotap.he_mu.chan1_center_26_tone_ru_bit_known",
5348 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5349 IEEE80211_RADIOTAP_HE_MU_CHAN1_CENTER_26_TONE_RU_BIT_KNOWN, NULL, HFILL}},
5350
5351 {&hf_radiotap_he_mu_chan1_center_26_tone_ru_bit_unknown,
5352 {"Channel1 center 26-tone RU bit known", "radiotap.he_mu.chan1_center_26_tone_ru_bit_unknown",
5353 FT_UINT16, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5354 IEEE80211_RADIOTAP_HE_MU_CHAN1_CENTER_26_TONE_RU_BIT_KNOWN, NULL, HFILL}},
5355
5356 {&hf_radiotap_he_mu_chan1_center_26_tone_ru_value,
5357 {"Channel1 center 26-tone RU value", "radiotap.he_mu.chan1_center_26_tone_ru_value",
5358 FT_UINT16, BASE_HEX, NULL,
5359 IEEE80211_RADIOTAP_HE_MU_CHAN1_CENTER_26_TONE_RU_VALUE, NULL, HFILL}},
5360
5361 {&hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_known,
5362 {"# of HE-SIG-B Symbols/MU-MINO users known",
5363 "radiotap.he_mu.symbol_cnt_or_user_cnt_known",
5364 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5365 IEEE80211_RADIOTAP_HE_MU_SYMBOL_CNT_OR_USER_CNT_KNOWN,
5366 NULL, HFILL}},
5367
5368 {&hf_radiotap_he_mu_info_flags_1,
5369 {"HE-MU Flags 1", "radiotap.he_mu.flags_1",
5370 FT_UINT16, BASE_HEX, NULL, 0x0,
5371 "Flags 1 of the HE-MU Info field", HFILL}},
5372
5373 {&hf_radiotap_he_mu_bw_from_bw_in_sig_a,
5374 {"bandwidth from Bandwidth field in SIG-A",
5375 "radiotap.he_mu.bw_from_sig_a",
5376 FT_UINT16, BASE_DEC, NULL,
5377 IEEE80211_RADIOTAP_HE_MU_BW_FROM_BW_IN_SIG_A_MASK, NULL, HFILL}},
5378
5379 {&hf_radiotap_he_mu_bw_from_bw_in_sig_a_unknown,
5380 {"bandwidth from Bandwidth field in SIG-A unknown",
5381 "radiotap.he_mu.bw_from_sig_a_unknown",
5382 FT_UINT16, BASE_DEC, NULL,
5383 IEEE80211_RADIOTAP_HE_MU_BW_FROM_BW_IN_SIG_A_MASK, NULL, HFILL}},
5384
5385 {&hf_radiotap_he_mu_bw_from_bw_in_sig_a_known,
5386 {"bandwidth from Bandwidth field in SIG-A known",
5387 "radiotap.he_mu.bw_from_sig_a_known",
5388 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5389 IEEE80211_RADIOTAP_HE_MU_BW_FROM_BW_IN_SIG_A_KNOWN, NULL, HFILL}},
5390
5391 {&hf_radiotap_he_mu_sig_b_compression_from_sig_a,
5392 {"SIG-B compression from SIG-A", "radiotap.he_mu.sig_b_compression",
5393 FT_BOOLEAN, 16, NULL,
5394 IEEE80211_RADIOTAP_HE_MU_SIG_B_COMPRESSION_FROM_SIG_A,
5395 NULL, HFILL}},
5396
5397 {&hf_radiotap_he_mu_sig_b_compression_known,
5398 {"SIG-B compression known", "radiotap.he_mu.sig_b_compression_known",
5399 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5400 IEEE80211_RADIOTAP_HE_MU_SIG_B_COMPRESSION_KNOWN, NULL, HFILL}},
5401
5402 {&hf_radiotap_he_mu_sig_b_compression_unknown,
5403 {"SIG-B compression unknown", "radiotap.he_mu.sig_b_compression_unknown",
5404 FT_UINT16, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5405 IEEE80211_RADIOTAP_HE_MU_SIG_B_COMPRESSION_FROM_SIG_A, NULL, HFILL}},
5406
5407 {&hf_radiotap_he_mu_sig_b_syms_mu_mimo_users,
5408 {"# of HE-SIG-B Symbols or # of MU-MIMO Users",
5409 "radiotap.he_mu.sig_b_syms_or_mu_mimo_users",
5410 FT_UINT16, BASE_CUSTOM, CF_FUNC(he_sig_b_symbols_custom),
5411 IEEE80211_RADIOTAP_HE_MU_SYMBOL_CNT_OR_USER_CNT, NULL, HFILL}},
5412
5413 {&hf_radiotap_he_mu_sig_b_syms_mu_mimo_users_unknown,
5414 {"# of HE-SIG-B Symbols or # of MU-MIMO Users unknown",
5415 "radiotap.he_mu.sig_b_syms_or_mu_mimo_users_unknown",
5416 FT_UINT16, BASE_DEC, NULL,
5417 IEEE80211_RADIOTAP_HE_MU_SYMBOL_CNT_OR_USER_CNT, NULL, HFILL}},
5418
5419 {&hf_radiotap_he_mu_preamble_puncturing,
5420 {"preamble puncturing from Bandwidth field in HE-SIG-A",
5421 "radiotap.he_mu.preamble_puncturing",
5422 FT_UINT16, BASE_HEX, NULL,
5423 IEEE80211_RADIOTAP_HE_MU_PREAMBLE_PUNCTURING_MASK, NULL, HFILL}},
5424
5425 {&hf_radiotap_he_mu_preamble_puncturing_unknown,
5426 {"preamble puncturing from Bandwidth field in HE-SIG-A unknown",
5427 "radiotap.he_mu.preamble_puncturing",
5428 FT_UINT16, BASE_HEX, NULL,
5429 IEEE80211_RADIOTAP_HE_MU_PREAMBLE_PUNCTURING_MASK, NULL, HFILL}},
5430
5431 {&hf_radiotap_he_mu_preamble_puncturing_known,
5432 {"preamble puncturing from Bandwidth field in HE-SIG-A known",
5433 "radiotap.he_mu.preamble_puncturing_known",
5434 FT_BOOLEAN, 16, TFS(&tfs_known_unknown),
5435 IEEE80211_RADIOTAP_HE_MU_PREAMBLE_PUNCTURING_KNOWN, NULL, HFILL}},
5436
5437 {&hf_radiotap_he_mu_chan2_center_26_tone_ru_value,
5438 {"Chan2 Center 26 Tone RU Value",
5439 "radiotap.he_mu.chan2_center_26_tone_ru_value",
5440 FT_UINT16, BASE_HEX, NULL,
5441 IEEE80211_RADIOTAP_HE_MU_CHAN2_CENTER_26_TONE_RU_VALUE,
5442 NULL, HFILL }},
5443
5444 {&hf_radiotap_he_mu_reserved_f2_b12_b15,
5445 {"Reserved", "radiotap.he_mu.reserved_f2_b12_b15",
5446 FT_UINT16, BASE_HEX, NULL,
5447 IEEE80211_RADIOTAP_HE_MU_RESERVED_F2_B12_B15, NULL, HFILL}},
5448
5449 {&hf_radiotap_he_mu_info_flags_2,
5450 {"HE-MU Flags 2", "radiotap.he_mu.flags_2",
5451 FT_UINT16, BASE_HEX, NULL, 0x0,
5452 "Flags 2 of the HE-MU Info field", HFILL}},
5453
5454 {&hf_radiotap_he_mu_chan1_rus_0,
5455 {"Chan1 RU[0] index", "radiotap.he_mu.chan1_rus_0_index",
5456 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5457
5458 {&hf_radiotap_he_mu_chan1_rus_0_unknown,
5459 {"Chan1 RU[0] index unknown",
5460 "radiotap.he_mu.chan1_rus_0_index_unknown",
5461 FT_UINT8, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5462 0x0, NULL, HFILL}},
5463
5464 {&hf_radiotap_he_mu_chan1_rus_1,
5465 {"Chan1 RU[1] index", "radiotap.he_mu.chan1_rus_1_index",
5466 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5467
5468 {&hf_radiotap_he_mu_chan1_rus_1_unknown,
5469 {"Chan1 RU[1] index unknown",
5470 "radiotap.he_mu.chan1_rus_1_index_unknown",
5471 FT_UINT8, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5472 0x0, NULL, HFILL}},
5473
5474 {&hf_radiotap_he_mu_chan1_rus_2,
5475 {"Chan1 RU[2] index", "radiotap.he_mu.chan1_rus_2_index",
5476 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5477
5478 {&hf_radiotap_he_mu_chan1_rus_2_unknown,
5479 {"Chan1 RU[2] index unknown",
5480 "radiotap.he_mu.chan1_rus_2_index_unknown",
5481 FT_UINT8, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5482 0x0, NULL, HFILL}},
5483
5484 {&hf_radiotap_he_mu_chan1_rus_3,
5485 {"Chan1 RU[3] index", "radiotap.he_mu.chan1_rus_3_index",
5486 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5487
5488 {&hf_radiotap_he_mu_chan1_rus_3_unknown,
5489 {"Chan1 RU[3] index unknown",
5490 "radiotap.he_mu.chan1_rus_3_index_unknown",
5491 FT_UINT8, BASE_CUSTOM, CF_FUNC(not_captured_custom),
5492 0x0, NULL, HFILL}},
5493
5494 {&hf_radiotap_he_mu_chan2_rus_0,
5495 {"Chan2 RU[0] index", "radiotap.he_mu.chan2_rus_0_index",
5496 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5497
5498 {&hf_radiotap_he_mu_chan2_rus_0_unknown,
5499 {"Chan2 RU[0] index unknown",
5500 "radiotap.he_mu.chan2_rus_0_index_unknown",
5501 FT_UINT8, BASE_CUSTOM,
5502 CF_FUNC(not_captured_custom), 0x0, NULL, HFILL}},
5503
5504 {&hf_radiotap_he_mu_chan2_rus_1,
5505 {"Chan2 RU[1] index", "radiotap.he_mu.chan2_rus_1_index",
5506 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5507
5508 {&hf_radiotap_he_mu_chan2_rus_1_unknown,
5509 {"Chan2 RU[1] index unknown",
5510 "radiotap.he_mu.chan2_rus_1_index_unknown",
5511 FT_UINT8, BASE_CUSTOM,
5512 CF_FUNC(not_captured_custom), 0x0, NULL, HFILL}},
5513
5514 {&hf_radiotap_he_mu_chan2_rus_2,
5515 {"Chan2 RU[2] index", "radiotap.he_mu.chan2_rus_2_index",
5516 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5517
5518 {&hf_radiotap_he_mu_chan2_rus_2_unknown,
5519 {"Chan2 RU[2] index unknown",
5520 "radiotap.he_mu.chan2_rus_2_index_unknown",
5521 FT_UINT8, BASE_CUSTOM,
5522 CF_FUNC(not_captured_custom), 0x0, NULL, HFILL}},
5523
5524 {&hf_radiotap_he_mu_chan2_rus_3,
5525 {"Chan2 RU[3] index", "radiotap.he_mu.chan2_rus_3_index",
5526 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
5527
5528 {&hf_radiotap_he_mu_chan2_rus_3_unknown,
5529 {"Chan2 RU[3] index unknown",
5530 "radiotap.he_mu.chan2_rus_3_index_unknown",
5531 FT_UINT8, BASE_CUSTOM,
5532 CF_FUNC(not_captured_custom), 0x0, NULL, HFILL}},
5533
5534 {&hf_radiotap_0_length_psdu_type,
5535 {"Type", "radiotap.0_len_psdu.type",
5536 FT_UINT8, BASE_HEX|BASE_RANGE_STRING,
5537 RVALS(zero_length_psdu_rsvals), 0x0, NULL, HFILL}},
5538
5539 {&hf_radiotap_l_sig_data_1,
5540 {"Data1", "radiotap.l_sig.data1",
5541 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL}},
5542
5543 {&hf_radiotap_l_sig_rate_known,
5544 {"rate known", "radiotap.l_sig.rate_known",
5545 FT_BOOLEAN, 16, NULL,
5546 IEEE80211_RADIOTAP_L_SIG_RATE_KNOWN, NULL, HFILL}},
5547
5548 {&hf_radiotap_l_sig_length_known,
5549 {"length known", "radiotap.l_sig.length_known",
5550 FT_BOOLEAN, 16, NULL,
5551 IEEE80211_RADIOTAP_L_SIG_LENGTH_KNOWN, NULL, HFILL}},
5552
5553 {&hf_radiotap_l_sig_reserved,
5554 {"reserved", "radiotap.l_sig.reserved",
5555 FT_UINT16, BASE_HEX, NULL,
5556 IEEE80211_RADIOTAP_L_SIG_RESERVED_MASK, NULL, HFILL}},
5557
5558 {&hf_radiotap_l_sig_data_2,
5559 {"Data2", "radiotap.l_sig.data2",
5560 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
5561
5562 {&hf_radiotap_l_sig_rate,
5563 {"rate", "radiotap.l_sig.rate",
5564 FT_UINT16, BASE_DEC, NULL,
5565 IEEE80211_RADIOTAP_L_SIG_RATE_MASK, NULL, HFILL}},
5566
5567 {&hf_radiotap_l_sig_length,
5568 {"length", "radiotap.l_sig.length",
5569 FT_UINT16, BASE_DEC, NULL,
5570 IEEE80211_RADIOTAP_L_SIG_LENGTH_MASK, NULL, HFILL}},
5571
5572 {&hf_radiotap_s1g_known,
5573 {"Known", "radiotap.s1g.known",
5574 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL}},
5575
5576 {&hf_radiotap_s1g_s1g_ppdu_format_known,
5577 {"S1G PPDU Format Known", "radiotap.s1g.s1g_ppdu_format_known",
5578 FT_BOOLEAN, 16, NULL,
5579 IEEE80211_RADIOTAP_TLV_S1G_S1G_PPDU_FORMAT_KNOWN, NULL, HFILL}},
5580
5581 {&hf_radiotap_s1g_response_indication_known,
5582 {"Response Indication Known", "radiotap.s1g.response_indication_known",
5583 FT_BOOLEAN, 16, NULL,
5584 IEEE80211_RADIOTAP_TLV_S1G_RESPONSE_INDICATION_KNOWN, NULL, HFILL}},
5585
5586 {&hf_radiotap_s1g_guard_interval_known,
5587 {"Guard Interval Known", "radiotap.s1g.guard_interval_known",
5588 FT_BOOLEAN, 16, NULL,
5589 IEEE80211_RADIOTAP_TLV_S1G_GUARD_INTERVAL_KNOWN, NULL, HFILL}},
5590
5591 {&hf_radiotap_s1g_nss_known,
5592 {"NSS Known", "radiotap.s1g.nss_known",
5593 FT_BOOLEAN, 16, NULL,
5594 IEEE80211_RADIOTAP_TLV_S1G_NSS_KNOWN, NULL, HFILL}},
5595
5596 {&hf_radiotap_s1g_bandwidth_known,
5597 {"Bandwidth Known", "radiotap.s1g.bandwidth_known",
5598 FT_BOOLEAN, 16, NULL,
5599 IEEE80211_RADIOTAP_TLV_S1G_BANDWIDTH_KNOWN, NULL, HFILL}},
5600
5601 {&hf_radiotap_s1g_mcs_known,
5602 {"MCS Known", "radiotap.s1g.mcs_known",
5603 FT_BOOLEAN, 16, NULL,
5604 IEEE80211_RADIOTAP_TLV_S1G_MCS_KNOWN, NULL, HFILL}},
5605
5606 {&hf_radiotap_s1g_color_known,
5607 {"Color Known", "radiotap.s1g.color_known",
5608 FT_BOOLEAN, 16, NULL,
5609 IEEE80211_RADIOTAP_TLV_S1G_COLOR_KNOWN, NULL, HFILL}},
5610
5611 {&hf_radiotap_s1g_uplink_indication_known,
5612 {"Uplink Indication Known",
5613 "radiotap.s1g.uplink_indication_known",
5614 FT_BOOLEAN, 16, NULL,
5615 IEEE80211_RADIOTAP_TLV_S1G_UPLINK_INDICATION_KNOWN,
5616 NULL, HFILL}},
5617
5618 {&hf_radiotap_s1g_reserved_1,
5619 {"Reserved 1", "radiotap.s1g.reserved_1",
5620 FT_UINT16, BASE_HEX, NULL,
5621 IEEE80211_RADIOTAP_TLV_S1G_RESERVED_1, NULL, HFILL}},
5622
5623 {&hf_radiotap_s1g_data_1,
5624 {"Data1", "radiotap.s1g.data_1",
5625 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL}},
5626
5627 {&hf_radiotap_s1g_s1g_ppdu_format,
5628 {"S1G PPDU Format", "radiotap.s1g.s1g_ppdu_format",
5629 FT_UINT16, BASE_DEC, VALS(s1g_ppdu_format),
5630 IEEE80211_RADIOTAP_TLV_S1G_S1G_PPDU_FORMAT, NULL, HFILL}},
5631
5632 {&hf_radiotap_s1g_response_indication,
5633 {"Response Indication", "radiotap.s1g.response_indication",
5634 FT_UINT16, BASE_DEC, VALS(s1g_response_indication),
5635 IEEE80211_RADIOTAP_TLV_S1G_RESPONSE_INDICATION, NULL, HFILL}},
5636
5637 {&hf_radiotap_s1g_reserved_2,
5638 {"Reserved 2", "radiotap.s1g.reserved_2",
5639 FT_UINT16, BASE_HEX, NULL,
5640 IEEE80211_RADIOTAP_TLV_S1G_RESERVED_2, NULL, HFILL}},
5641
5642 {&hf_radiotap_s1g_guard_interval,
5643 {"Guard Interval", "radiotap.s1g.guard_interval",
5644 FT_UINT16, BASE_DEC, VALS(s1g_guard_interval),
5645 IEEE80211_RADIOTAP_TLV_S1G_GUARD_INTERVAL, NULL, HFILL}},
5646
5647 {&hf_radiotap_s1g_nss,
5648 {"NSS", "radiotap.s1g.nss",
5649 FT_UINT16, BASE_DEC, VALS(s1g_nss),
5650 IEEE80211_RADIOTAP_TLV_S1G_NSS, NULL, HFILL}},
5651
5652 {&hf_radiotap_s1g_bandwidth,
5653 {"Bandwidth", "radiotap.s1g.bandwidth",
5654 FT_UINT16, BASE_DEC, VALS(s1g_bandwidth),
5655 IEEE80211_RADIOTAP_TLV_S1G_BANDWIDTH, NULL, HFILL}},
5656
5657 {&hf_radiotap_s1g_mcs,
5658 {"MCS", "radiotap.s1g.mcs",
5659 FT_UINT16, BASE_DEC, VALS(s1g_mcs),
5660 IEEE80211_RADIOTAP_TLV_S1G_MCS, NULL, HFILL}},
5661
5662 {&hf_radiotap_s1g_data_2,
5663 {"Data2", "radiotap.s1g.data_2",
5664 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL}},
5665
5666 {&hf_radiotap_s1g_color,
5667 {"Color", "radiotap.s1g.color",
5668 FT_UINT16, BASE_DEC, VALS(s1g_color),
5669 IEEE80211_RADIOTAP_TLV_S1G_COLOR, NULL, HFILL}},
5670
5671 {&hf_radiotap_s1g_uplink_indication,
5672 {"Uplink Indication", "radiotap.s1g.uplink_indication",
5673 FT_BOOLEAN, 16, NULL,
5674 IEEE80211_RADIOTAP_TLV_S1G_UPLINK_INDICATION, NULL, HFILL}},
5675
5676 {&hf_radiotap_s1g_reserved_3,
5677 {"Reserved 3", "radiotap.s1g.reserved_3",
5678 FT_UINT16, BASE_HEX, NULL,
5679 IEEE80211_RADIOTAP_TLV_S1G_RESERVED_3, NULL, HFILL}},
5680
5681 {&hf_radiotap_s1g_rssi,
5682 {"RSSI", "radiotap.s1g.rssi",
5683 FT_INT16, BASE_DEC, NULL,
5684 IEEE80211_RADIOTAP_TLV_S1G_RSSI, NULL, HFILL}},
5685
5686 {&hf_radiotap_s1g_ndp_bytes,
5687 {"NDP Bytes", "radiotap.s1g.ndp.bytes",
5688 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5689
5690 {&hf_radiotap_s1g_ndp_ctrl,
5691 {"NDP Control", "radiotap.s1g.ndp.control",
5692 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5693
5694 {&hf_radiotap_s1g_ndp_mgmt,
5695 {"NDP Management", "radiotap.s1g.ndp.management",
5696 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5697
5698 {&hf_radiotap_s1g_ndp_type_3bit,
5699 {"NDP Type", "radiotap.s1g.ndp.type",
5700 FT_UINT40, BASE_HEX, NULL, 0x0000000007, NULL, HFILL }},
5701
5702 {&hf_radiotap_s1g_ndp_ack_1m,
5703 {"NDP Ack 1MHz", "radiotap.s1g.ndp.ack_1m",
5704 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5705
5706 {&hf_radiotap_s1g_ndp_ack_1m_ack_id,
5707 {"ACK Id", "radiotap.s1g.ndp.ack.ack_id",
5708 FT_UINT40, BASE_HEX, NULL, 0x0000000FF8, NULL, HFILL }},
5709
5710 {&hf_radiotap_s1g_ndp_ack_1m_more_data,
5711 {"More Data", "radiotap.s1g.ndp.ack.more_data",
5712 FT_BOOLEAN, 40, NULL, 0x0000001000, NULL, HFILL }},
5713
5714 {&hf_radiotap_s1g_ndp_ack_1m_idle_indication,
5715 {"Idle Indication", "radiotap.s1g.ndp.ack.idle_indication",
5716 FT_BOOLEAN, 40, NULL, 0x0000002000, NULL, HFILL }},
5717
5718 {&hf_radiotap_s1g_ndp_ack_1m_duration,
5719 {"Duration", "radiotap.s1g.ndp.ack.duration",
5720 FT_UINT40, BASE_DEC, NULL, 0x0000FFC000, NULL, HFILL }},
5721
5722 {&hf_radiotap_s1g_ndp_ack_1m_relayed_frame,
5723 {"Relayed Frame", "radiotap.s1g.ndp.ack.relayed_frame",
5724 FT_BOOLEAN, 40, NULL, 0x0001000000, NULL, HFILL }},
5725
5726 {&hf_radiotap_s1g_ndp_ack_2m,
5727 {"NDP Ack 2MHz", "radiotap.s1g.ndp.ack_2m",
5728 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5729
5730 {&hf_radiotap_s1g_ndp_ack_2m_ack_id,
5731 {"ACK Id", "radiotap.s1g.ndp.ack.ack_id",
5732 FT_UINT40, BASE_HEX, NULL, 0x000007FFF8, NULL, HFILL }},
5733
5734 {&hf_radiotap_s1g_ndp_ack_2m_more_data,
5735 {"More Data", "radiotap.s1g.ndp.ack.more_data",
5736 FT_BOOLEAN, 40, NULL, 0x0000080000, NULL, HFILL }},
5737
5738 {&hf_radiotap_s1g_ndp_ack_2m_idle_indication,
5739 {"Idle Indication", "radiotap.s1g.ndp.ack.idle_indication",
5740 FT_BOOLEAN, 40, NULL, 0x0000100000, NULL, HFILL }},
5741
5742 {&hf_radiotap_s1g_ndp_ack_2m_duration,
5743 {"Duration", "radiotap.s1g.ndp.ack.duration",
5744 FT_UINT40, BASE_DEC, NULL, 0x07FFE00000, NULL, HFILL }},
5745
5746 {&hf_radiotap_s1g_ndp_ack_2m_relayed_frame,
5747 {"Relayed Frame", "radiotap.s1g.ndp.ack.relayed_frame",
5748 FT_BOOLEAN, 40, NULL, 0x0800000000, NULL, HFILL }},
5749
5750 {&hf_radiotap_s1g_ndp_ack_2m_reserved,
5751 {"Reserved", "radiotap.s1g.ndp.ack.reserved",
5752 FT_UINT40, BASE_HEX, NULL, 0x1000000000, NULL, HFILL }},
5753
5754 {&hf_radiotap_s1g_ndp_cts_1m,
5755 {"NDP CTS 1MHz", "radiotap.s1g.ndp.cts_1m",
5756 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5757
5758 {&hf_radiotap_s1g_ndp_cts_cf_end_indic,
5759 {"NDP CTS/CF_End Indicator", "radiotap.s1g.ndp.cts_cf_end_indic",
5760 FT_BOOLEAN, 40, NULL, 0x0000000008, NULL, HFILL }},
5761
5762 {&hf_radiotap_s1g_ndp_cts_address_indic,
5763 {"Address Indicator", "radiotap.s1g.ndp.cts.address_indic",
5764 FT_BOOLEAN, 40, NULL, 0x0000000010, NULL, HFILL }},
5765
5766 {&hf_radiotap_s1g_ndp_cts_ra_partial_bssid,
5767 {"RA/Partial BSSID", "radiotap.s1g.ndp.cts.ra_partial_bssid",
5768 FT_UINT40, BASE_HEX, NULL, 0x0000003FE0, NULL, HFILL }},
5769
5770 {&hf_radiotap_s1g_ndp_cts_duration_1m,
5771 {"Duration", "radiotap.s1g.ndp.cts.duration_1m",
5772 FT_UINT40, BASE_DEC, NULL, 0x0000FFC000, NULL, HFILL }},
5773
5774 {&hf_radiotap_s1g_ndp_cts_early_sector_indic_1m,
5775 {"Early Sector Indicator", "radiotap.s1g.ndp.cts.early_sector_indic_1m",
5776 FT_BOOLEAN, 40, NULL, 0x0001000000, NULL, HFILL }},
5777
5778 {&hf_radiotap_s1g_ndp_cts_2m,
5779 {"NDP CTS 2MHz", "radiotap.s1g.ndp.cts_2m",
5780 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5781
5782 {&hf_radiotap_s1g_ndp_cts_duration_2m,
5783 {"Duration", "radiotap.s1g.ndp.cts.duration_2m",
5784 FT_UINT40, BASE_DEC, NULL, 0x001FFFC000, NULL, HFILL }},
5785
5786 {&hf_radiotap_s1g_ndp_cts_early_sector_indic_2m,
5787 {"Early Sector Indicator", "radiotap.s1g.ndp.cts.early_sector_indic_2m",
5788 FT_BOOLEAN, 40, NULL, 0x0020000000, NULL, HFILL }},
5789
5790 {&hf_radiotap_s1g_ndp_cts_bandwidth_indic_2m,
5791 {"Address Indicator", "radiotap.s1g.ndp.cts.address_indic",
5792 FT_UINT40, BASE_DEC, NULL, 0x01C0000000, NULL, HFILL }},
5793
5794 {&hf_radiotap_s1g_ndp_cts_reserved,
5795 {"Reserved", "radiotap.s1g.ndp.cts.reserved",
5796 FT_UINT40, BASE_HEX, NULL, 0x1E00000000, NULL, HFILL }},
5797
5798 {&hf_radiotap_s1g_ndp_cf_end_1m,
5799 {"NDP CF-End 1MHz", "radiotap.s1g.ndp.cf_end_1m",
5800 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5801
5802 {&hf_radiotap_s1g_ndp_cf_end_partial_bssid,
5803 {"Partial BSSID (TA)", "radiotap.s1g.ndp.cf_end.partial_bssid",
5804 FT_UINT40, BASE_HEX, NULL, 0x0000001FF0, NULL, HFILL }},
5805
5806 {&hf_radiotap_s1g_ndp_cf_end_duration_1m,
5807 {"Duration", "radiotap.s1g.ndp.cf_end.duration_1m",
5808 FT_UINT40, BASE_HEX, NULL, 0x00007FE000, NULL, HFILL }},
5809
5810 {&hf_radiotap_s1g_ndp_cf_end_reserved_1m,
5811 {"Reserved", "radiotap.s1g.ndp.cf_end.reserved_1m",
5812 FT_UINT40, BASE_HEX, NULL, 0x0001800000, NULL, HFILL }},
5813
5814 {&hf_radiotap_s1g_ndp_cf_end_2m,
5815 {"NDP CF-End 2MHz", "radiotap.s1g.ndp.cf_end_2m",
5816 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5817
5818 {&hf_radiotap_s1g_ndp_cf_end_duration_2m,
5819 {"Duration", "radiotap.s1g.ndp.cf_end.duration_2m",
5820 FT_UINT40, BASE_HEX, NULL, 0x000FFFE000, NULL, HFILL }},
5821
5822 {&hf_radiotap_s1g_ndp_cf_end_reserved_2m,
5823 {"Reserved", "radiotap.s1g.ndp.cf_end.reserved_2m",
5824 FT_UINT40, BASE_HEX, NULL, 0x1FF0000000, NULL, HFILL }},
5825
5826 {&hf_radiotap_s1g_ndp_ps_poll_1m,
5827 {"NDP PS-Poll 1MHz", "radiotap.s1g.ndp.ps_poll_1m",
5828 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5829
5830 {&hf_radiotap_s1g_ndp_ps_poll_ra,
5831 {"RA", "radiotap.s1g.ndp.ps_poll.ra",
5832 FT_UINT40, BASE_HEX, NULL, 0x0000000FF8, NULL, HFILL }},
5833
5834 {&hf_radiotap_s1g_ndp_ps_poll_ta,
5835 {"TA", "radiotap.s1g.ndp.ps_poll.ta",
5836 FT_UINT40, BASE_HEX, NULL, 0x00001FF000, NULL, HFILL }},
5837
5838 {&hf_radiotap_s1g_ndp_ps_poll_preferred_mcs_1m,
5839 {"Preferred MCS", "radiotap.s1g.ndp.ps_poll.preferred_mcs",
5840 FT_UINT40, BASE_HEX, NULL, 0x0000E00000, NULL, HFILL }},
5841
5842 {&hf_radiotap_s1g_ndp_ps_poll_udi_1m,
5843 {"UDI", "radiotap.s1g.ndp.ps_poll.udi",
5844 FT_UINT40, BASE_HEX, NULL, 0x0001000000, NULL, HFILL }},
5845
5846 {&hf_radiotap_s1g_ndp_ps_poll_2m,
5847 {"NDP PS-Poll 2MHz", "radiotap.s1g.ndp.ps_poll_2m",
5848 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5849
5850 {&hf_radiotap_s1g_ndp_ps_poll_preferred_mcs_2m,
5851 {"Preferred MCS", "radiotap.s1g.ndp.ps_poll.preferred_mcs",
5852 FT_UINT40, BASE_HEX, NULL, 0x0001E00000, NULL, HFILL }},
5853
5854 {&hf_radiotap_s1g_ndp_ps_poll_udi_2m,
5855 {"UDI", "radiotap.s1g.ndp.ps_poll.udi",
5856 FT_UINT40, BASE_HEX, NULL, 0x1FFE00000, NULL, HFILL }},
5857
5858 {&hf_radiotap_s1g_ndp_ps_poll_ack_1m,
5859 {"NDP PS-Poll-Ack 1MHz", "radiotap.s1g.ndp.ndp_ps_poll_ack_1m",
5860 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5861
5862 {&hf_radiotap_s1g_ndp_ps_poll_ack_id,
5863 {"Ack ID", "radiotap.s1g.ndp.ps_poll.ack_id",
5864 FT_UINT40, BASE_HEX, NULL, 0x0000000FF8, NULL, HFILL }},
5865
5866 {&hf_radiotap_s1g_ndp_ps_poll_ack_more_data,
5867 {"More Data", "radiotap.s1g.ndp.ps_poll.more_data",
5868 FT_BOOLEAN, 40, NULL, 0x0000001000, NULL, HFILL }},
5869
5870 {&hf_radiotap_s1g_ndp_ps_poll_ack_idle_indication,
5871 {"Idle Indication", "radiotap.s1g.ndp.ps_poll.idle_indication",
5872 FT_BOOLEAN, 40, NULL, 0x0000002000, NULL, HFILL }},
5873
5874 {&hf_radiotap_s1g_ndp_ps_poll_ack_duration_1m,
5875 {"Duration", "radiotap.s1g.ndp.ps_poll.duration",
5876 FT_UINT40, BASE_HEX, NULL, 0x0000FFC000, NULL, HFILL }},
5877
5878 {&hf_radiotap_s1g_ndp_ps_poll_ack_reserved_1m,
5879 {"Reserved", "radiotap.s1g.ndp.ps_poll.reserved_1m",
5880 FT_UINT40, BASE_HEX, NULL, 0x0001000000, NULL, HFILL }},
5881
5882 {&hf_radiotap_s1g_ndp_ps_poll_ack_2m,
5883 {"NDP PS-Poll-Ack 2MHz", "radiotap.s1g.ndp.ndp_ps_poll_ack_2m",
5884 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5885
5886 {&hf_radiotap_s1g_ndp_ps_poll_ack_id_2m,
5887 {"Ack ID", "radiotap.s1g.ndp.ps_poll.ack_id",
5888 FT_UINT40, BASE_HEX, NULL, 0x000007FFF8, NULL, HFILL }},
5889
5890 {&hf_radiotap_s1g_ndp_ps_poll_ack_more_data_2m,
5891 {"More Data", "radiotap.s1g.ndp.ps_poll.more_data",
5892 FT_BOOLEAN, 40, NULL, 0x0000080000, NULL, HFILL }},
5893
5894 {&hf_radiotap_s1g_ndp_ps_poll_ack_idle_indication_2m,
5895 {"Idle Indication", "radiotap.s1g.ndp.ps_poll.idle_indication",
5896 FT_BOOLEAN, 40, NULL, 0x0000100000, NULL, HFILL }},
5897
5898 {&hf_radiotap_s1g_ndp_ps_poll_ack_duration_2m,
5899 {"Duration", "radiotap.s1g.ndp.ps_poll.duration",
5900 FT_UINT40, BASE_HEX, NULL, 0x07FFE00000, NULL, HFILL }},
5901
5902 {&hf_radiotap_s1g_ndp_ps_poll_ack_reserved_2m,
5903 {"Reserved", "radiotap.s1g.ndp.ps_poll.reserved",
5904 FT_UINT40, BASE_HEX, NULL, 0x1800000000, NULL, HFILL }},
5905
5906 {&hf_radiotap_s1g_ndp_block_ack_1m,
5907 {"NDP Block Ack 1MHz", "radiotap.s1g.ndp.block_ack_1m",
5908 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5909
5910 {&hf_radiotap_s1g_ndp_block_ack_id_1m,
5911 {"BlockAck ID", "radiotap.s1g.ndp.block_ack.blockack_id",
5912 FT_UINT40, BASE_HEX, NULL, 0x0000000018, NULL, HFILL }},
5913
5914 {&hf_radiotap_s1g_ndp_block_ack_starting_sequence_control_1m,
5915 {"Starting Sequence Control", "radiotap.s1g.ndp.ps_poll.starting_sequence_control",
5916 FT_UINT40, BASE_HEX, NULL, 0x000001FFE0, NULL, HFILL }},
5917
5918 {&hf_radiotap_s1g_ndp_block_ack_bitmap_1m,
5919 {"Block Ack Bitmap", "radiotap.s1g.ndp.ps_poll.block_ack_bitmap",
5920 FT_UINT40, BASE_HEX, NULL, 0x001FFE0000, NULL, HFILL }},
5921
5922 {&hf_radiotap_s1g_ndp_block_ack_unused_1m,
5923 {"Unused", "radiotap.s1g.ndp.ps_poll.block_ack_unused",
5924 FT_UINT40, BASE_HEX, NULL, 0x3FE0000000, NULL, HFILL }},
5925
5926 {&hf_radiotap_s1g_ndp_block_ack_2m,
5927 {"NDP Block Ack 2MHz", "radiotap.s1g.ndp.block_ack_2m",
5928 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5929
5930 {&hf_radiotap_s1g_ndp_block_ack_id_2m,
5931 {"BlockAck ID", "radiotap.s1g.ndp.ps_poll.blockack_id",
5932 FT_UINT40, BASE_HEX, NULL, 0x00000001F8, NULL, HFILL }},
5933
5934 {&hf_radiotap_s1g_ndp_block_ack_starting_sequence_control_2m,
5935 {"Starting Sequence Control", "radiotap.s1g.ndp.ps_poll.starting_sequence_control",
5936 FT_UINT40, BASE_HEX, NULL, 0x00001FFE00, NULL, HFILL }},
5937
5938 {&hf_radiotap_s1g_ndp_block_ack_bitmap_2m,
5939 {"Block Ack Bitmap", "radiotap.s1g.ndp.ps_poll.block_ack_bitmap",
5940 FT_UINT40, BASE_HEX, NULL, 0x1FFFE00000, NULL, HFILL }},
5941
5942 {&hf_radiotap_s1g_ndp_beamforming_report_poll,
5943 {"Beamforming Report Poll", "radiotap.s1g.ndp.beamforming_report_poll",
5944 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5945
5946 {&hf_radiotap_s1g_ndp_beamforming_ap_address,
5947 {"AP Address", "radiotap.s1g.ndp.beamforming_report_poll.ap_address",
5948 FT_UINT40, BASE_HEX, NULL, 0x0000000FF8, NULL, HFILL }},
5949
5950 {&hf_radiotap_s1g_ndp_beamforming_non_ap_sta_address,
5951 {"Non-AP STA Address", "radiotap.s1g.ndp.beamforming_report_poll.non_ap_sta_address",
5952 FT_UINT40, BASE_HEX, NULL, 0x0001FFF000, NULL, HFILL }},
5953
5954 {&hf_radiotap_s1g_ndp_beamforming_feedback_segment_bitmap,
5955 {"Retransmission Segment Retransmission Bitmap",
5956 "radiotap.s1g.ndp.beamforming_report_poll.feedback_segment_retransmission_bitmap",
5957 FT_UINT40, BASE_HEX, NULL, 0x01FE000000, NULL, HFILL }},
5958
5959 {&hf_radiotap_s1g_ndp_beamforming_reserved,
5960 {"Reserved", "radiotap.s1g.ndp.beamforming_report_poll.reserved",
5961 FT_UINT40, BASE_HEX, NULL, 0x1E00000000, NULL, HFILL }},
5962
5963 {&hf_radiotap_s1g_ndp_paging_1m,
5964 {"NDP Paging 1MHz", "radiotap.s1g.ndp.ndp_paging_1m",
5965 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5966
5967 {&hf_radiotap_s1g_ndp_paging_p_id,
5968 {"P-ID", "radiotap.s1g.ndp.ndp_paging.p_id",
5969 FT_BOOLEAN, 40, NULL, 0x0000000FF8, NULL, HFILL }},
5970
5971 {&hf_radiotap_s1g_ndp_paging_apdi_partial_aid,
5972 {"APDI/Partial AID", "radiotap.s1g.ndp.ndp_paging.apdi_partial_aid",
5973 FT_BOOLEAN, 40, NULL, 0x00001FF000, NULL, HFILL }},
5974
5975 {&hf_radiotap_s1g_ndp_paging_direction,
5976 {"Direction", "radiotap.s1g.ndp.ndp_paging.direction",
5977 FT_BOOLEAN, 40, NULL, 0x0000200000, NULL, HFILL }},
5978
5979 {&hf_radiotap_s1g_ndp_paging_reserved_1m,
5980 {"Reserved", "radiotap.s1g.ndp.ndp_paging.reserved",
5981 FT_BOOLEAN, 40, NULL, 0x0001C00000, NULL, HFILL }},
5982
5983 {&hf_radiotap_s1g_ndp_paging_2m,
5984 {"NDP Paging 2MHz", "radiotap.s1g.ndp.ndp_paging_2m",
5985 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5986
5987 {&hf_radiotap_s1g_ndp_paging_reserved_2m,
5988 {"Reserved", "radiotap.s1g.ndp.reserved",
5989 FT_BOOLEAN, 40, NULL, 0x1FFFC00000, NULL, HFILL }},
5990
5991 {&hf_radiotap_s1g_ndp_probe_1m,
5992 {"NDP Probe 1MHz", "radiotap.s1g.ndp.ndp_probe_1m",
5993 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5994
5995 {&hf_radiotap_s1g_ndp_probe_cssid_ano_present,
5996 {"CSSID/ANO Present", "radiotap.s1g.ndp.ndp_probe.cssid_ano_present",
5997 FT_BOOLEAN, 40, NULL, 0x0000000008, NULL, HFILL }},
5998
5999 {&hf_radiotap_s1g_ndp_probe_1m_cssid_ano,
6000 {"Compressed SSID/ANO", "radiotap.s1g.ndp.ndp_probe.compressed_ssid_ano",
6001 FT_UINT40, BASE_HEX, NULL, 0x00000FFFF0, NULL, HFILL }},
6002
6003 {&hf_radiotap_s1g_ndp_probe_1m_requested_response_type,
6004 {"Requested Response Type", "radiotap.s1g.ndp.ndp_probe.requested_response_type_1m",
6005 FT_UINT40, BASE_HEX, NULL, 0x0000100000, NULL, HFILL }},
6006
6007 {&hf_radiotap_s1g_ndp_probe_1m_reserved,
6008 {"Reserved", "radiotap.s1g.ndp.probe_1m.ndp_probe.reserved",
6009 FT_UINT40, BASE_HEX, NULL, 0x0001E00000, NULL, HFILL }},
6010
6011 {&hf_radiotap_s1g_ndp_probe_2m,
6012 {"NDP Probe 2MHz", "radiotap.s1g.ndp.probe_2m",
6013 FT_UINT40, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6014
6015 {&hf_radiotap_s1g_ndp_probe_2m_cssid_ano,
6016 {"Compressed SSID/ANO", "radiotap.s1g.ndp.ndp_probe.compressed_ssid_ano",
6017 FT_UINT40, BASE_HEX, NULL, 0x0FFFFFFFF0, NULL, HFILL }},
6018
6019 {&hf_radiotap_s1g_ndp_probe_2m_requested_response_type,
6020 {"Requested Response Type", "radiotap.s1g.ndp.ndp_probe.requested_response_type_2m",
6021 FT_UINT40, BASE_HEX, NULL, 0x1000000000, NULL, HFILL }},
6022
6023 {&hf_radiotap_s1g_ndp_1m_unused,
6024 {"Unused", "radiotap.s1g.ndp.ack.1m_unused",
6025 FT_UINT40, BASE_HEX, NULL, 0x3FFE000000, NULL, HFILL }},
6026
6027 {&hf_radiotap_s1g_ndp_2m_unused,
6028 {"Unused", "radiotap.s1g.ndp.ack.2m_unused",
6029 FT_UINT40, BASE_HEX, NULL, 0x2000000000, NULL, HFILL }},
6030
6031 {&hf_radiotap_s1g_ndp_bw,
6032 {"NDP BW", "radiotap.s1g.ndp.bw",
6033 FT_UINT40, BASE_HEX, NULL, 0xC000000000, NULL, HFILL }},
6034
6035 };
6036 static gint *ett[] = {
6037 &ett_radiotap,
6038 &ett_radiotap_tlv,
6039 &ett_radiotap_present,
6040 &ett_radiotap_present_word,
6041 &ett_radiotap_flags,
6042 &ett_radiotap_rxflags,
6043 &ett_radiotap_txflags,
6044 &ett_radiotap_channel_flags,
6045 &ett_radiotap_xchannel_flags,
6046 &ett_radiotap_vendor,
6047 &ett_radiotap_mcs,
6048 &ett_radiotap_mcs_known,
6049 &ett_radiotap_ampdu,
6050 &ett_radiotap_ampdu_flags,
6051 &ett_radiotap_vht,
6052 &ett_radiotap_vht_known,
6053 &ett_radiotap_vht_user,
6054 &ett_radiotap_timestamp,
6055 &ett_radiotap_timestamp_flags,
6056 &ett_radiotap_he_info,
6057 &ett_radiotap_he_info_data_1,
6058 &ett_radiotap_he_info_data_2,
6059 &ett_radiotap_he_info_data_3,
6060 &ett_radiotap_he_info_data_4,
6061 &ett_radiotap_he_info_data_5,
6062 &ett_radiotap_he_info_data_6,
6063 &ett_radiotap_he_mu_info,
6064 &ett_radiotap_he_mu_info_flags_1,
6065 &ett_radiotap_he_mu_info_flags_2,
6066 &ett_radiotap_he_mu_chan_rus,
6067 &ett_radiotap_0_length_psdu,
6068 &ett_radiotap_l_sig,
6069 &ett_radiotap_l_sig_data_1,
6070 &ett_radiotap_l_sig_data_2,
6071 &ett_radiotap_s1g,
6072 &ett_radiotap_s1g_known,
6073 &ett_radiotap_s1g_data_1,
6074 &ett_radiotap_s1g_data_2,
6075 &ett_s1g_ndp,
6076 &ett_s1g_ndp_ack,
6077 &ett_s1g_ndp_cts,
6078 &ett_s1g_ndp_cf_end,
6079 &ett_s1g_ndp_ps_poll,
6080 &ett_s1g_ndp_ps_poll_ack,
6081 &ett_s1g_ndp_block_ack,
6082 &ett_s1g_ndp_beamforming_report_poll,
6083 &ett_s1g_ndp_paging,
6084 &ett_s1g_ndp_probe,
6085 &ett_radiotap_unknown_tlv,
6086 };
6087 static ei_register_info ei[] = {
6088 { &ei_radiotap_invalid_header_length, { "radiotap.length.invalid", PI_MALFORMED, PI_ERROR, "The radiotap header length is less than 8 bytes", EXPFILL }},
6089 { &ei_radiotap_present, { "radiotap.present.radiotap_and_vendor", PI_MALFORMED, PI_ERROR, "Both radiotap and vendor namespace specified in bitmask word", EXPFILL }},
6090 { &ei_radiotap_data_past_header, { "radiotap.data_past_header", PI_MALFORMED, PI_ERROR, "Radiotap data goes past the end of the radiotap header", EXPFILL }},
6091 { &ei_radiotap_invalid_data_rate, { "radiotap.vht.datarate.invalid", PI_PROTOCOL, PI_WARN, "Data rate invalid", EXPFILL }},
6092 };
6093
6094 module_t *radiotap_module;
6095 expert_module_t* expert_radiotap;
6096
6097 proto_radiotap =
6098 proto_register_protocol("IEEE 802.11 Radiotap Capture header", "802.11 Radiotap", "radiotap");
6099 proto_register_field_array(proto_radiotap, hf, array_length(hf));
6100 proto_register_subtree_array(ett, array_length(ett));
6101 expert_radiotap = expert_register_protocol(proto_radiotap);
6102 expert_register_field_array(expert_radiotap, ei, array_length(ei));
6103 register_dissector("radiotap", dissect_radiotap, proto_radiotap);
6104
6105 /* Subdissector table for vendor namespace, the key is OUI with sub namespace (4 bytes) */
6106 vendor_dissector_table = register_dissector_table("radiotap.vendor",
6107 "Vendor namespace", proto_radiotap, FT_UINT32, BASE_HEX);
6108
6109 radiotap_module = prefs_register_protocol(proto_radiotap, NULL);
6110 prefs_register_bool_preference(radiotap_module, "bit14_fcs_in_header",
6111 "Assume bit 14 means FCS in header",
6112 "Radiotap has a bit to indicate whether the FCS is still on the frame or not. "
6113 "Some generators (e.g. AirPcap) use a non-standard radiotap flag 14 to put "
6114 "the FCS into the header.",
6115 &radiotap_bit14_fcs);
6116
6117 prefs_register_bool_preference(radiotap_module, "interpret_high_rates_as_mcs",
6118 "Interpret high rates as MCS",
6119 "Some generators use rates with bit 7 set to indicate an MCS, e.g. BSD. "
6120 "others (Linux, AirPcap) do not.",
6121 &radiotap_interpret_high_rates_as_mcs);
6122
6123 prefs_register_enum_preference(radiotap_module, "fcs_handling",
6124 "Whether and how to override the FCS bit",
6125 "Whether to use the FCS bit, assume the FCS is always present, "
6126 "or assume the FCS is never present.",
6127 &radiotap_fcs_handling,
6128 fcs_handling, FALSE);
6129 }
6130
proto_reg_handoff_radiotap(void)6131 void proto_reg_handoff_radiotap(void)
6132 {
6133 dissector_handle_t radiotap_handle;
6134 capture_dissector_handle_t radiotap_cap_handle;
6135
6136 /* handle for 802.11+radio information dissector */
6137 ieee80211_radio_handle = find_dissector_add_dependency("wlan_radio", proto_radiotap);
6138
6139 radiotap_handle = find_dissector_add_dependency("radiotap", proto_radiotap);
6140
6141 dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_RADIOTAP,
6142 radiotap_handle);
6143
6144 /*
6145 * The radiotap and 802.11 headers aren't stripped off for
6146 * monitor-mode packets in Linux cooked captures, so dissect
6147 * those frames.
6148 */
6149 dissector_add_uint("sll.hatype", ARPHRD_IEEE80211_RADIOTAP,
6150 radiotap_handle);
6151
6152 radiotap_cap_handle = create_capture_dissector_handle(capture_radiotap, proto_radiotap);
6153 capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_RADIOTAP, radiotap_cap_handle);
6154
6155 ieee80211_cap_handle = find_capture_dissector("ieee80211");
6156 ieee80211_datapad_cap_handle = find_capture_dissector("ieee80211_datapad");
6157 }
6158
6159 /*
6160 * Editor modelines - https://www.wireshark.org/tools/modelines.html
6161 *
6162 * Local variables:
6163 * c-basic-offset: 8
6164 * tab-width: 8
6165 * indent-tabs-mode: t
6166 * End:
6167 *
6168 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
6169 * :indentSize=8:tabSize=8:noTabs=false:
6170 */
6171