Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-awdl.c
Line
Count
Source
1
/* packet-awdl.c
2
 * Routines for Apple Wireless Direct Link (AWDL) dissection
3
 *
4
 * Copyright 2017 David Kreitschmann <dkreitschmann@seemoo.tu-darmstadt.de>
5
 * Copyright 2018 Milan Stute <mstute@seemoo.tu-darmstadt.de>
6
 *
7
 * Released as part of:
8
 *   Milan Stute, David Kreitschmann, and Matthias Hollick. "One Billion Apples'
9
 *   Secret Sauce: Recipe for the Apple Wireless Direct Link Ad hoc Protocol"
10
 *   in ACM MobiCom '18. https://doi.org/10.1145/3241539.3241566
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
#include <config.h>
16
17
#include <math.h>
18
19
#include <epan/packet.h>
20
#include <epan/expert.h>
21
#include <epan/oui.h>
22
#include <epan/tfs.h>
23
#include <epan/unit_strings.h>
24
#include "packet-llc.h"
25
#include "packet-ieee80211.h"
26
#include "packet-dns.h"
27
28
void proto_register_awdl(void);
29
void proto_reg_handoff_awdl(void);
30
31
static dissector_handle_t awdl_action_handle;
32
static dissector_handle_t awdl_data_handle;
33
34
typedef struct awdl_tagged_field_data
35
{
36
  proto_item* item_tag;
37
  proto_item* item_tag_length;
38
} awdl_tagged_field_data_t;
39
40
static const unit_name_string units_ieee80211_tu = { " TU", NULL }; /* 1 TU = 1024 microseconds */
41
42
static int proto_awdl;
43
static int proto_awdl_data;
44
45
static int hf_awdl_unknown;
46
47
static int hf_awdl_fixed_parameters;
48
static int hf_awdl_tagged_parameters;
49
50
static int hf_awdl_data_seq;
51
static int hf_awdl_data_header;
52
static int hf_awdl_data_ethertype;
53
54
static int hf_awdl_type;
55
static int hf_awdl_subtype;
56
static int hf_awdl_rsvd;
57
static int hf_awdl_phytime;
58
static int hf_awdl_targettime;
59
static int hf_awdl_txdelay;
60
61
static int hf_awdl_tag;
62
static int hf_awdl_tag_number;
63
static int hf_awdl_tag_length;
64
static int hf_awdl_tag_data;
65
static int hf_awdl_tag_padding;
66
67
static int hf_awdl_version;
68
static int hf_awdl_version_minor;
69
static int hf_awdl_version_major;
70
static int hf_awdl_version_devclass;
71
72
static int hf_awdl_datastate_flags;
73
static int hf_awdl_datastate_flags_0;
74
static int hf_awdl_datastate_flags_1;
75
static int hf_awdl_datastate_flags_2;
76
static int hf_awdl_datastate_flags_3;
77
static int hf_awdl_datastate_flags_4;
78
static int hf_awdl_datastate_flags_5;
79
static int hf_awdl_datastate_flags_6;
80
static int hf_awdl_datastate_flags_7;
81
static int hf_awdl_datastate_flags_8;
82
static int hf_awdl_datastate_flags_9;
83
static int hf_awdl_datastate_flags_10;
84
static int hf_awdl_datastate_flags_11;
85
static int hf_awdl_datastate_flags_12;
86
static int hf_awdl_datastate_flags_13;
87
static int hf_awdl_datastate_flags_14;
88
static int hf_awdl_datastate_flags_15;
89
static int hf_awdl_datastate_extflags;
90
static int hf_awdl_datastate_extflags_0;
91
static int hf_awdl_datastate_extflags_1;
92
static int hf_awdl_datastate_extflags_2;
93
static int hf_awdl_datastate_extflags_3;
94
static int hf_awdl_datastate_extflags_4;
95
static int hf_awdl_datastate_extflags_5;
96
static int hf_awdl_datastate_extflags_6;
97
static int hf_awdl_datastate_extflags_7;
98
static int hf_awdl_datastate_extflags_8;
99
static int hf_awdl_datastate_extflags_9;
100
static int hf_awdl_datastate_extflags_10;
101
static int hf_awdl_datastate_extflags_11;
102
static int hf_awdl_datastate_extflags_12;
103
static int hf_awdl_datastate_extflags_13;
104
static int hf_awdl_datastate_extflags_14to15;
105
static int hf_awdl_datastate_infra_channel;
106
static int hf_awdl_datastate_countrycode;
107
static int hf_awdl_datastate_social_channel;
108
static int hf_awdl_datastate_social_channel_map;
109
static int hf_awdl_datastate_social_channel_map_6;
110
static int hf_awdl_datastate_social_channel_map_44;
111
static int hf_awdl_datastate_social_channel_map_149;
112
static int hf_awdl_datastate_social_channel_map_unused;
113
static int hf_awdl_datastate_infra_bssid;
114
static int hf_awdl_datastate_infra_address;
115
static int hf_awdl_datastate_awdl_address;
116
static int hf_awdl_datastate_umi;
117
static int hf_awdl_datastate_umioptions;
118
static int hf_awdl_datastate_umioptions_length;
119
static int hf_awdl_datastate_logtrigger;
120
static int hf_awdl_datastate_rlfc;
121
static int hf_awdl_datastate_active_time;
122
static int hf_awdl_datastate_aw_sequence_counter;
123
static int hf_awdl_datastate_update_counter;
124
125
static int hf_awdl_synctree_addr;
126
127
static int hf_awdl_syncparams_master;
128
static int hf_awdl_syncparams_awcounter;
129
static int hf_awdl_syncparams_apbeaconalignment;
130
static int hf_awdl_syncparams_tx_chan;
131
static int hf_awdl_syncparams_tx_counter;
132
static int hf_awdl_syncparams_master_chan;
133
static int hf_awdl_syncparams_guard_time;
134
static int hf_awdl_syncparams_aw_period;
135
static int hf_awdl_syncparams_action_frame_period;
136
static int hf_awdl_syncparams_awdl_flags;
137
static int hf_awdl_syncparams_aw_ext_length;
138
static int hf_awdl_syncparams_aw_cmn_length;
139
static int hf_awdl_syncparams_aw_remaining;
140
static int hf_awdl_syncparams_ext_min;
141
static int hf_awdl_syncparams_ext_max_multi;
142
static int hf_awdl_syncparams_ext_max_uni;
143
static int hf_awdl_syncparams_ext_max_af;
144
static int hf_awdl_syncparams_presence_mode;
145
146
static int hf_awdl_channelseq_enc;
147
static int hf_awdl_channelseq_duplicate;
148
static int hf_awdl_channelseq_step_count;
149
static int hf_awdl_channelseq_fill_chan;
150
static int hf_awdl_channelseq_channel_count;
151
static int hf_awdl_channelseq_channel_list;
152
static int hf_awdl_channelseq_channel;
153
static int hf_awdl_channelseq_channel_number;
154
static int hf_awdl_channelseq_channel_flags;
155
static int hf_awdl_channelseq_channel_operating_class;
156
/* legacy encoding flags */
157
static int hf_awdl_channelseq_legacy_unused;
158
static int hf_awdl_channelseq_legacy_band;
159
static int hf_awdl_channelseq_legacy_bandwidth;
160
static int hf_awdl_channelseq_legacy_control_channel;
161
162
static int hf_awdl_electionparams_master;
163
static int hf_awdl_electionparams_flags;
164
static int hf_awdl_electionparams_id;
165
static int hf_awdl_electionparams_distance;
166
static int hf_awdl_electionparams_mastermetric;
167
static int hf_awdl_electionparams_selfmetric;
168
static int hf_awdl_electionparams_unknown;
169
static int hf_awdl_electionparams_private_master;
170
static int hf_awdl_electionparams_private_mastermetric;
171
static int hf_awdl_electionparams_private_id;
172
static int hf_awdl_electionparams_private_phc;
173
174
static int hf_awdl_electionparams2_master;
175
static int hf_awdl_electionparams2_other;
176
static int hf_awdl_electionparams2_mastermetric;
177
static int hf_awdl_electionparams2_selfmetric;
178
static int hf_awdl_electionparams2_mastercounter;
179
static int hf_awdl_electionparams2_selfcounter;
180
static int hf_awdl_electionparams2_distance;
181
static int hf_awdl_electionparams2_unknown;
182
static int hf_awdl_electionparams2_reserved;
183
184
static int hf_awdl_dns_name_len;
185
static int hf_awdl_dns_name;
186
static int hf_awdl_dns_name_label;
187
static int hf_awdl_dns_name_short;
188
static int hf_awdl_dns_type;
189
static int hf_awdl_dns_data_len;
190
static int hf_awdl_dns_txt;
191
static int hf_awdl_dns_ptr;
192
static int hf_awdl_dns_ptr_label;
193
static int hf_awdl_dns_ptr_short;
194
static int hf_awdl_dns_target;
195
static int hf_awdl_dns_target_label;
196
static int hf_awdl_dns_target_short;
197
static int hf_awdl_dns_unknown;
198
static int hf_awdl_dns_priority;
199
static int hf_awdl_dns_weight;
200
static int hf_awdl_dns_port;
201
202
static int hf_awdl_serviceparams_sui;
203
static int hf_awdl_serviceparams_enc_values;
204
static int hf_awdl_serviceparams_bitmask;
205
static int hf_awdl_serviceparams_bitmask_0;
206
static int hf_awdl_serviceparams_bitmask_1;
207
static int hf_awdl_serviceparams_bitmask_2;
208
static int hf_awdl_serviceparams_bitmask_3;
209
static int hf_awdl_serviceparams_bitmask_4;
210
static int hf_awdl_serviceparams_bitmask_5;
211
static int hf_awdl_serviceparams_bitmask_6;
212
static int hf_awdl_serviceparams_bitmask_7;
213
static int hf_awdl_serviceparams_bitmask_8;
214
static int hf_awdl_serviceparams_bitmask_9;
215
static int hf_awdl_serviceparams_bitmask_10;
216
static int hf_awdl_serviceparams_bitmask_11;
217
static int hf_awdl_serviceparams_bitmask_12;
218
static int hf_awdl_serviceparams_bitmask_13;
219
static int hf_awdl_serviceparams_bitmask_14;
220
static int hf_awdl_serviceparams_bitmask_15;
221
static int hf_awdl_serviceparams_bitmask_16;
222
static int hf_awdl_serviceparams_bitmask_17;
223
static int hf_awdl_serviceparams_bitmask_18;
224
static int hf_awdl_serviceparams_bitmask_19;
225
static int hf_awdl_serviceparams_bitmask_20;
226
static int hf_awdl_serviceparams_bitmask_21;
227
static int hf_awdl_serviceparams_bitmask_22;
228
static int hf_awdl_serviceparams_bitmask_23;
229
static int hf_awdl_serviceparams_bitmask_24;
230
static int hf_awdl_serviceparams_bitmask_25;
231
static int hf_awdl_serviceparams_bitmask_26;
232
static int hf_awdl_serviceparams_bitmask_27;
233
static int hf_awdl_serviceparams_bitmask_28;
234
static int hf_awdl_serviceparams_bitmask_29;
235
static int hf_awdl_serviceparams_bitmask_30;
236
static int hf_awdl_serviceparams_bitmask_31;
237
static int hf_awdl_serviceparams_values;
238
static int hf_awdl_serviceparams_values_0;
239
static int hf_awdl_serviceparams_values_1;
240
static int hf_awdl_serviceparams_values_2;
241
static int hf_awdl_serviceparams_values_3;
242
static int hf_awdl_serviceparams_values_4;
243
static int hf_awdl_serviceparams_values_5;
244
static int hf_awdl_serviceparams_values_6;
245
static int hf_awdl_serviceparams_values_7;
246
247
static int hf_awdl_arpa;
248
static int hf_awdl_arpa_flags;
249
static int hf_awdl_arpa_name;
250
static int hf_awdl_arpa_short;
251
252
static int hf_awdl_ht_unknown;
253
/* from hf_ieee80211_* from packet-ieee80211.c */
254
static int hf_awdl_ht_cap;
255
static int hf_awdl_ht_ldpc_coding;
256
static int hf_awdl_ht_chan_width;
257
static int hf_awdl_ht_sm_pwsave;
258
static int hf_awdl_ht_green;
259
static int hf_awdl_ht_short20;
260
static int hf_awdl_ht_short40;
261
static int hf_awdl_ht_tx_stbc;
262
static int hf_awdl_ht_rx_stbc;
263
static int hf_awdl_ht_delayed_block_ack;
264
static int hf_awdl_ht_max_amsdu;
265
static int hf_awdl_ht_dss_cck_40;
266
static int hf_awdl_ht_psmp;
267
static int hf_awdl_ht_40_mhz_intolerant;
268
static int hf_awdl_ht_l_sig;
269
static int hf_awdl_ampduparam;
270
static int hf_awdl_ampduparam_mpdu;
271
static int hf_awdl_ampduparam_mpdu_start_spacing;
272
static int hf_awdl_ampduparam_reserved;
273
static int hf_awdl_mcsset;
274
static int hf_awdl_mcsset_rx_bitmask;
275
static int hf_awdl_mcsset_rx_bitmask_0to7;
276
static int hf_awdl_mcsset_rx_bitmask_8to15;
277
static int hf_awdl_mcsset_rx_bitmask_16to23;
278
static int hf_awdl_mcsset_rx_bitmask_24to31;
279
280
static int hf_llc_apple_awdl_pid;
281
282
static int ett_awdl_data;
283
static int ett_awdl;
284
static int ett_awdl_fixed_parameters;
285
static int ett_awdl_tagged_parameters;
286
static int ett_awdl_unknown;
287
static int ett_awdl_tag;
288
static int ett_awdl_channelseq_flags;
289
static int ett_awdl_version;
290
static int ett_awdl_dns_record;
291
static int ett_awdl_dns_name;
292
static int ett_awdl_channelseq_channel_list;
293
static int ett_awdl_channelseq_channel;
294
static int ett_awdl_datastate_flags;
295
static int ett_awdl_datastate_social_channel_map;
296
static int ett_awdl_datastate_extflags;
297
static int ett_awdl_ht_capabilities;
298
static int ett_awdl_ht_ampduparam;
299
static int ett_awdl_ht_mcsset_tree;
300
static int ett_awdl_ht_mcsbit_tree;
301
static int ett_awdl_serviceparams_bitmask;
302
static int ett_awdl_serviceparams_values;
303
static int ett_awdl_serviceparams_value;
304
305
static expert_field ei_awdl_tag_length;
306
static expert_field ei_awdl_tag_data;
307
static expert_field ei_awdl_dns_data_len;
308
309
static dissector_table_t ethertype_subdissector_table;
310
static dissector_table_t tagged_field_table;
311
312
enum tag_length {
313
  TAG_LENGTH_SHORT = 2, /* short tag header length, used in legacy data frames */
314
  TAG_LENGTH       = 3, /* normal tag header length */
315
};
316
317
enum {
318
  AWDL_SSTH_REQUEST_TLV = 0,
319
  AWDL_SERVICE_REQUEST_TLV = 1,
320
  AWDL_SERVICE_RESPONSE_TLV = 2,
321
  AWDL_UNKNOWN_3_TLV = 3,
322
  AWDL_SYNCHRONIZATON_PARAMETERS_TLV = 4,
323
  AWDL_ELECTION_PARAMETERS_TLV = 5,
324
  AWDL_SERVICE_PARAMETERS_TLV = 6,
325
  AWDL_ENHANCED_DATA_RATE_CAPABILITIES_TLV = 7,
326
  AWDL_ENHANCED_DATA_RATE_OPERATION_TLV = 8,
327
  AWDL_INFRA_TLV = 9,
328
  AWDL_INVITE_TLV = 10,
329
  AWDL_DBG_STRING_TLV = 11,
330
  AWDL_DATA_PATH_STATE_TLV = 12,
331
  AWDL_ENCAPSULATED_IP_TLV = 13,
332
  AWDL_DATAPATH_DEBUG_PACKET_LIVE_TLV = 14,
333
  AWDL_DATAPATH_DEBUG_AF_LIVE_TLV = 15,
334
  AWDL_ARPA_TLV = 16,
335
  AWDL_IEEE80211_CONTAINER_TLV = 17,
336
  AWDL_CHAN_SEQ_TLV = 18,
337
  AWDL_UNKNOWN_19_TLV = 19,
338
  AWDL_SYNCHRONIZATION_TREE_TLV = 20,
339
  AWDL_VERSION_TLV = 21,
340
  AWDL_BLOOM_FILTER_TLV = 22,
341
  AWDL_NAN_SYNC_TLV = 23,
342
  AWDL_ELECTION_PARAMETERS_V2_TLV = 24,
343
};
344
345
static const value_string tag_num_vals[] = {
346
  { AWDL_SSTH_REQUEST_TLV, "SSTH Request" },
347
  { AWDL_SERVICE_REQUEST_TLV, "Service Request" },
348
  { AWDL_SERVICE_RESPONSE_TLV, "Service Response" },
349
  { AWDL_UNKNOWN_3_TLV, "Unknown" },
350
  { AWDL_SYNCHRONIZATON_PARAMETERS_TLV, "Synchronization Parameters" },
351
  { AWDL_ELECTION_PARAMETERS_TLV, "Election Parameters" },
352
  { AWDL_SERVICE_PARAMETERS_TLV, "Service Parameters" },
353
  { AWDL_ENHANCED_DATA_RATE_CAPABILITIES_TLV, "HT Capabilities (IEEE 802.11 subset)" },
354
  { AWDL_ENHANCED_DATA_RATE_OPERATION_TLV, "Enhanced Data Rate Operation" },
355
  { AWDL_INFRA_TLV, "Infra" },
356
  { AWDL_INVITE_TLV, "Invite" },
357
  { AWDL_DBG_STRING_TLV, "Debug String" },
358
  { AWDL_DATA_PATH_STATE_TLV, "Data Path State" },
359
  { AWDL_ENCAPSULATED_IP_TLV, "Encapsulated IP" },
360
  { AWDL_DATAPATH_DEBUG_PACKET_LIVE_TLV, "Datapath Debug Packet Live" },
361
  { AWDL_DATAPATH_DEBUG_AF_LIVE_TLV, "Datapath Debug AF Live" },
362
  { AWDL_ARPA_TLV, "Arpa" },
363
  { AWDL_IEEE80211_CONTAINER_TLV, "IEEE 802.11 Container" },
364
  { AWDL_CHAN_SEQ_TLV, "Channel Sequence" },
365
  { AWDL_UNKNOWN_19_TLV, "Unknown" },
366
  { AWDL_SYNCHRONIZATION_TREE_TLV, "Synchronization Tree" },
367
  { AWDL_VERSION_TLV, "Version" },
368
  { AWDL_BLOOM_FILTER_TLV, "Bloom Filter" },
369
  { AWDL_NAN_SYNC_TLV, "NAN Sync" },
370
  { AWDL_ELECTION_PARAMETERS_V2_TLV, "Election Parameters v2" },
371
  { 0, NULL }
372
};
373
static value_string_ext tag_num_vals_ext = VALUE_STRING_EXT_INIT(tag_num_vals);
374
375
static const value_string awdl_type[] = {
376
  { 8, "AWDL" },
377
  { 0, NULL }
378
};
379
380
enum {
381
  AWDL_SUBTYPE_PSF = 0,
382
  AWDL_SUBTYPE_MIF = 3
383
};
384
385
static const value_string awdl_subtype[] = {
386
  { AWDL_SUBTYPE_PSF, "Periodic Synchronization Frame (PSF)" },
387
  { AWDL_SUBTYPE_MIF, "Master Indication Frame (MIF)" },
388
  { 0, NULL }
389
};
390
391
static const value_string awdl_subtype_col[] = {
392
  { AWDL_SUBTYPE_PSF, "Periodic Synchronization" },
393
  { AWDL_SUBTYPE_MIF, "Master Indication" },
394
  { 0, NULL }
395
};
396
397
static const value_string awdl_subtype_short[] = {
398
  { AWDL_SUBTYPE_PSF, "PSF" },
399
  { AWDL_SUBTYPE_MIF, "MIF" },
400
  { 0, NULL }
401
};
402
403
enum {
404
  AWDL_CHANSEQ_ENC_CHANNELNUMBER = 0,
405
  AWDL_CHANSEQ_ENC_LEGACY = 1,
406
  AWDL_CHANSEQ_ENC_OPCLASS = 3,
407
};
408
409
static const value_string awdl_chanseq_enc[] = {
410
  { AWDL_CHANSEQ_ENC_CHANNELNUMBER, "Channelnumber" },
411
  { AWDL_CHANSEQ_ENC_LEGACY, "Legacy" },
412
  { AWDL_CHANSEQ_ENC_OPCLASS, "Opclass" },
413
  { 0, NULL }
414
};
415
416
static const value_string awdl_chanseq_control_channel[] = {
417
  { 1, "Lower" },
418
  { 2, "Upper" },
419
  { 3, "Primary" },
420
  { 0, NULL }
421
};
422
423
static const value_string awdl_chanseq_bandwidth[] = {
424
  { 1, "20 MHz" },
425
  { 3, "40 MHz" },
426
  { 0, NULL }
427
};
428
429
static const value_string awdl_chanseq_band[] = {
430
  { 2, "2.4 GHz" },
431
  { 1, "5 GHz" },
432
  { 0, NULL }
433
};
434
435
static const value_string awdl_chanseq_fill_chan[] = {
436
  { 0xffff, "Repeat Current" },
437
  { 0, NULL }
438
};
439
440
enum {
441
  AWDL_VERSION_MACOS = 1,
442
  AWDL_VERSION_IOS = 2,
443
  AWDL_VERSION_WATCHOS = 4,
444
  AWDL_VERSION_TVOS = 8,
445
};
446
447
static const value_string awdl_version_devclass[] = {
448
  { AWDL_VERSION_MACOS, "macOS" },
449
  { AWDL_VERSION_IOS, "iOS" },
450
  { AWDL_VERSION_WATCHOS, "watchOS" },
451
  { AWDL_VERSION_TVOS, "tvOS" },
452
  { 0, NULL }
453
};
454
455
enum {
456
  T_PTR = 12, /* domain name pointer */
457
  T_TXT = 16, /* text strings */
458
  T_SRV = 33, /* service location (RFC 2052) */
459
};
460
461
static const value_string dns_types_vals[] = {
462
  { T_PTR, "PTR" },
463
  { T_TXT, "TXT" },
464
  { T_SRV, "SRV" }, /* RFC 2052 */
465
  { 0,     NULL }
466
};
467
468
static const value_string awdl_dns_compression[] = {
469
  { 0xC000, "NULL" },
470
  { 0xC001, "_airplay._tcp.local" },
471
  { 0xC002, "_airplay._udp.local" },
472
  { 0xC003, "_airplay" },
473
  { 0xC004, "_raop._tcp.local" },
474
  { 0xC005, "_raop._udp.local" },
475
  { 0xC006, "_raop" },
476
  { 0xC007, "_airdrop._tcp.local" },
477
  { 0xC008, "_airdrop._udp.local" },
478
  { 0xC009, "_airdrop" },
479
  { 0xC00A, "_tcp.local" },
480
  { 0xC00B, "_udp.local" },
481
  { 0xC00C, "local" },
482
  { 0xC00D, "ip6.arpa" },
483
  { 0xC00E, "ip4.arpa" },
484
  { 0,      NULL }
485
};
486
487
/* from packet-ieee80211.c */
488
static const true_false_string ht_ldpc_coding_flag = {
489
  "Transmitter supports receiving LDPC coded packets",
490
  "Transmitter does not support receiving LDPC coded packets"
491
};
492
493
/* from packet-ieee80211.c */
494
static const true_false_string ht_chan_width_flag = {
495
  "Transmitter supports 20MHz and 40MHz operation",
496
  "Transmitter only supports 20MHz operation"
497
};
498
499
/* from packet-ieee80211.c */
500
static const value_string ht_sm_pwsave_flag[] = {
501
  { 0x00, "Static SM Power Save mode" },
502
  { 0x01, "Dynamic SM Power Save mode" },
503
  { 0x02, "Reserved" },
504
  { 0x03, "SM Power Save disabled" },
505
  { 0x00, NULL}
506
};
507
508
/* from packet-ieee80211.c */
509
static const true_false_string ht_green_flag = {
510
  "Transmitter is able to receive PPDUs with Green Field (GF) preamble",
511
  "Transmitter is not able to receive PPDUs with Green Field (GF) preamble"
512
};
513
514
/* from packet-ieee80211.c */
515
static const value_string ht_rx_stbc_flag[] = {
516
  {0x00, "No Rx STBC support"},
517
  {0x01, "Rx support of one spatial stream"},
518
  {0x02, "Rx support of one and two spatial streams"},
519
  {0x03, "Rx support of one, two, and three spatial streams"},
520
  {0x00, NULL}
521
};
522
523
/* from packet-ieee80211.c */
524
static const true_false_string ht_delayed_block_ack_flag = {
525
  "Transmitter supports HT-Delayed BlockAck",
526
  "Transmitter does not support HT-Delayed BlockAck"
527
};
528
529
/* from packet-ieee80211.c */
530
static const true_false_string ht_max_amsdu_flag = {
531
  "7935 bytes",
532
  "3839 bytes"
533
};
534
535
/* from packet-ieee80211.c */
536
static const true_false_string ht_dss_cck_40_flag = {
537
  "Will/Can use DSSS/CCK in 40 MHz",
538
  "Won't/Can't use of DSSS/CCK in 40 MHz"
539
};
540
541
/* from packet-ieee80211.c */
542
static const true_false_string ht_psmp_flag = {
543
  "Will/Can support PSMP operation",
544
  "Won't/Can't support PSMP operation"
545
};
546
547
/* from packet-ieee80211.c */
548
static const true_false_string ht_40_mhz_intolerant_flag = {
549
  "Use of 40 MHz transmissions restricted/disallowed",
550
  "Use of 40 MHz transmissions unrestricted/allowed"
551
};
552
553
/* from packet-ieee80211.c */
554
static const value_string ampduparam_mpdu_start_spacing_flags[] = {
555
  {0x00, "no restriction"},
556
  {0x01, "1/4 [usec]"},
557
  {0x02, "1/2 [usec]"},
558
  {0x03, "1 [usec]"},
559
  {0x04, "2 [usec]"},
560
  {0x05, "4 [usec]"},
561
  {0x06, "8 [usec]"},
562
  {0x07, "16 [usec]"},
563
  {0x00, NULL}
564
};
565
566
/* from packet-ieee80211.c */
567
static const value_string mcsset_tx_max_spatial_streams_flags[] = {
568
  { 0x00, "1 spatial stream" },
569
  { 0x01, "2 spatial streams" },
570
  { 0x02, "3 spatial streams" },
571
  { 0x03, "4 spatial streams" },
572
  { 0x04, "TX MCS Set Not Defined" },
573
  { 0x00, NULL}
574
};
575
576
static const value_string apple_awdl_pid_vals[] = {
577
  { 0x0800, "AWDL" },
578
  { 0,      NULL }
579
};
580
581
static proto_item *
582
0
add_awdl_version(tvbuff_t *tvb, int offset, proto_tree *tree) {
583
0
  proto_item *version_item;
584
0
  uint64_t version;
585
0
  static int * const fields[] = {
586
0
    &hf_awdl_version_major,
587
0
    &hf_awdl_version_minor,
588
0
    NULL
589
0
  };
590
591
0
  version_item = proto_tree_add_bitmask_with_flags_ret_uint64(tree, tvb, offset, hf_awdl_version, ett_awdl_version,
592
0
                                                              fields, ENC_LITTLE_ENDIAN, BMT_NO_APPEND, &version);
593
0
  proto_item_append_text(version_item, " (%u.%u)", (uint8_t) ((version >> 4) & 0xf), (uint8_t) (version & 0xf));
594
595
0
  return version_item;
596
0
}
597
598
static int
599
0
awdl_tag_version(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) {
600
0
  int offset = 0;
601
602
0
  add_awdl_version(tvb, offset, tree);
603
0
  offset += 1;
604
0
  proto_tree_add_item(tree, hf_awdl_version_devclass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
605
0
  offset += 1;
606
607
0
  return offset;
608
0
}
609
610
static int
611
0
awdl_tag_sync_tree(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) {
612
0
  int tag_len = tvb_reported_length(tvb);
613
0
  int offset = 0;
614
615
0
  for (; offset <= tag_len - 6; offset += 6) {
616
0
    proto_tree_add_item(tree, hf_awdl_synctree_addr, tvb, offset, 6, ENC_NA);
617
0
  }
618
619
0
  return offset;
620
0
}
621
622
inline static bool
623
0
test_bit_uint32(unsigned i, uint32_t n) {
624
0
  return ((n >> i) & 1) == 1;
625
0
}
626
627
static int
628
0
awdl_tag_service_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) {
629
0
  proto_item *values_item, *offset_item;
630
0
  proto_tree *values_tree;
631
0
  int offset = 0;
632
633
0
  static int * const bitmask_fields[] = {
634
0
    &hf_awdl_serviceparams_bitmask_0,
635
0
    &hf_awdl_serviceparams_bitmask_1,
636
0
    &hf_awdl_serviceparams_bitmask_2,
637
0
    &hf_awdl_serviceparams_bitmask_3,
638
0
    &hf_awdl_serviceparams_bitmask_4,
639
0
    &hf_awdl_serviceparams_bitmask_5,
640
0
    &hf_awdl_serviceparams_bitmask_6,
641
0
    &hf_awdl_serviceparams_bitmask_7,
642
0
    &hf_awdl_serviceparams_bitmask_8,
643
0
    &hf_awdl_serviceparams_bitmask_9,
644
0
    &hf_awdl_serviceparams_bitmask_10,
645
0
    &hf_awdl_serviceparams_bitmask_11,
646
0
    &hf_awdl_serviceparams_bitmask_12,
647
0
    &hf_awdl_serviceparams_bitmask_13,
648
0
    &hf_awdl_serviceparams_bitmask_14,
649
0
    &hf_awdl_serviceparams_bitmask_15,
650
0
    &hf_awdl_serviceparams_bitmask_16,
651
0
    &hf_awdl_serviceparams_bitmask_17,
652
0
    &hf_awdl_serviceparams_bitmask_18,
653
0
    &hf_awdl_serviceparams_bitmask_19,
654
0
    &hf_awdl_serviceparams_bitmask_20,
655
0
    &hf_awdl_serviceparams_bitmask_21,
656
0
    &hf_awdl_serviceparams_bitmask_22,
657
0
    &hf_awdl_serviceparams_bitmask_23,
658
0
    &hf_awdl_serviceparams_bitmask_24,
659
0
    &hf_awdl_serviceparams_bitmask_25,
660
0
    &hf_awdl_serviceparams_bitmask_26,
661
0
    &hf_awdl_serviceparams_bitmask_27,
662
0
    &hf_awdl_serviceparams_bitmask_28,
663
0
    &hf_awdl_serviceparams_bitmask_29,
664
0
    &hf_awdl_serviceparams_bitmask_30,
665
0
    &hf_awdl_serviceparams_bitmask_31,
666
0
    NULL
667
0
  };
668
669
0
  static int * const value_fields[] = {
670
0
    &hf_awdl_serviceparams_values_0,
671
0
    &hf_awdl_serviceparams_values_1,
672
0
    &hf_awdl_serviceparams_values_2,
673
0
    &hf_awdl_serviceparams_values_3,
674
0
    &hf_awdl_serviceparams_values_4,
675
0
    &hf_awdl_serviceparams_values_5,
676
0
    &hf_awdl_serviceparams_values_6,
677
0
    &hf_awdl_serviceparams_values_7,
678
0
    NULL
679
0
  };
680
681
0
  proto_tree_add_item(tree, hf_awdl_unknown, tvb, offset, 3, ENC_NA);
682
0
  offset += 3;
683
0
  proto_tree_add_item(tree, hf_awdl_serviceparams_sui, tvb, offset, 2, ENC_LITTLE_ENDIAN);
684
0
  offset += 2;
685
686
0
  values_item = proto_tree_add_item(tree, hf_awdl_serviceparams_enc_values, tvb, offset, 0, ENC_NA); /* set length later */
687
0
  values_tree = proto_item_add_subtree(values_item, ett_awdl_serviceparams_values);
688
689
0
  offset_item = proto_tree_add_bitmask_with_flags(values_tree, tvb, offset, hf_awdl_serviceparams_bitmask, ett_awdl_serviceparams_bitmask, bitmask_fields, ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
690
0
  uint32_t bitmask = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
691
0
  offset += 4;
692
693
0
  if (bitmask != 0) {
694
0
    unsigned count = 0;
695
0
    for (unsigned i = 0; i < 32; i++) {
696
0
      if (test_bit_uint32(i, bitmask)) {
697
0
        proto_item *value_item;
698
0
        unsigned shift = i << 3;
699
0
        value_item = proto_tree_add_bitmask(values_tree, tvb, offset, hf_awdl_serviceparams_values,
700
0
                               ett_awdl_serviceparams_value, value_fields, ENC_LITTLE_ENDIAN);
701
0
        uint8_t value = tvb_get_uint8(tvb, offset);
702
0
        for (unsigned k = 0; k < 8; k++) {
703
0
          if (test_bit_uint32(k, value)) {
704
0
            if (count == 0) {
705
0
              proto_item_append_text(values_item, ": %u", k + shift);
706
0
            } else {
707
0
              proto_item_append_text(values_item, ", %u", k + shift);
708
0
            }
709
0
            count++;
710
0
          }
711
0
        }
712
0
        proto_item_append_text(offset_item, ", %u", shift);
713
0
        proto_item_append_text(value_item, " (offset %u)", shift);
714
0
        offset++;
715
0
      }
716
0
    }
717
0
    proto_item_set_end(values_item, tvb, offset);
718
0
  }
719
720
0
  return offset;
721
0
}
722
723
static int
724
0
awdl_tag_channel_sequence(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
725
0
  proto_item *chanlist_item, *channel_item;
726
0
  proto_tree *chanlist_tree, *channel_tree;
727
0
  unsigned channels;
728
0
  uint32_t chan_number;
729
0
  wmem_strbuf_t *strbuf;
730
0
  int offset = 0;
731
732
0
  static int * const flags_fields[] = {
733
0
    &hf_awdl_channelseq_legacy_control_channel,
734
0
    &hf_awdl_channelseq_legacy_bandwidth,
735
0
    &hf_awdl_channelseq_legacy_band,
736
0
    &hf_awdl_channelseq_legacy_unused,
737
0
    NULL
738
0
  };
739
740
0
  proto_tree_add_item_ret_uint(tree, hf_awdl_channelseq_channel_count, tvb, offset, 1, ENC_LITTLE_ENDIAN, &channels);
741
0
  channels += 1; /* channel list length is +1 */
742
0
  offset += 1;
743
744
0
  uint8_t seq_enc = tvb_get_uint8(tvb, offset);
745
0
  proto_tree_add_item(tree, hf_awdl_channelseq_enc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
746
0
  offset += 1;
747
0
  proto_tree_add_item(tree, hf_awdl_channelseq_duplicate, tvb, offset, 1, ENC_LITTLE_ENDIAN);
748
0
  offset += 1;
749
0
  proto_tree_add_item(tree, hf_awdl_channelseq_step_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
750
0
  offset += 1;
751
0
  proto_tree_add_item(tree, hf_awdl_channelseq_fill_chan, tvb, offset, 2, ENC_LITTLE_ENDIAN);
752
0
  offset += 2;
753
754
  /* make sufficient space for channel decodings: 5 chars/channel (3-digit number + ', ') */
755
0
  strbuf = wmem_strbuf_new_sized(pinfo->pool, 5 * channels);
756
757
0
  switch (seq_enc) {
758
0
  case AWDL_CHANSEQ_ENC_CHANNELNUMBER:
759
0
    chanlist_item = proto_tree_add_item(tree, hf_awdl_channelseq_channel_list, tvb, offset, channels, ENC_NA);
760
0
    chanlist_tree = proto_item_add_subtree(chanlist_item, ett_awdl_channelseq_channel_list);
761
0
    for (unsigned i = 0; i < channels; i++) {
762
0
      proto_tree_add_item_ret_uint(chanlist_tree, hf_awdl_channelseq_channel_number, tvb, offset, 1, ENC_LITTLE_ENDIAN, &chan_number);
763
0
      offset += 1;
764
765
0
      if (i != 0) {
766
        /* not the first */
767
0
        wmem_strbuf_append_printf(strbuf, ", %u", chan_number);
768
0
      } else {
769
0
        wmem_strbuf_append_printf(strbuf, "%u", chan_number);
770
0
      }
771
0
    }
772
0
    break;
773
0
  case AWDL_CHANSEQ_ENC_LEGACY:
774
0
    chanlist_item = proto_tree_add_item(tree, hf_awdl_channelseq_channel_list, tvb, offset, 2 * channels, ENC_NA);
775
0
    chanlist_tree = proto_item_add_subtree(chanlist_item, ett_awdl_channelseq_channel_list);
776
0
    for (unsigned i = 0; i < channels; i++) {
777
      /* channel number is 2nd byte */
778
0
      channel_item = proto_tree_add_item_ret_uint(chanlist_tree, hf_awdl_channelseq_channel, tvb, offset + 1, 1,
779
0
                                                  ENC_LITTLE_ENDIAN, &chan_number);
780
0
      channel_tree = proto_item_add_subtree(channel_item, ett_awdl_channelseq_channel);
781
0
      proto_tree_add_bitmask(channel_tree, tvb, offset, hf_awdl_channelseq_channel_flags,
782
0
                             ett_awdl_channelseq_flags, flags_fields, ENC_LITTLE_ENDIAN);
783
0
      offset += 1;
784
0
      proto_tree_add_item(channel_tree, hf_awdl_channelseq_channel_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
785
0
      offset += 1;
786
787
0
      if (i != 0) {
788
        /* not the first */
789
0
        wmem_strbuf_append_printf(strbuf, ", %u", chan_number);
790
0
      } else {
791
0
        wmem_strbuf_append_printf(strbuf, "%u", chan_number);
792
0
      }
793
0
    }
794
0
    break;
795
0
  case AWDL_CHANSEQ_ENC_OPCLASS:
796
0
    chanlist_item = proto_tree_add_item(tree, hf_awdl_channelseq_channel_list, tvb, offset, 2 * channels, ENC_NA);
797
0
    chanlist_tree = proto_item_add_subtree(chanlist_item, ett_awdl_channelseq_channel_list);
798
0
    for (unsigned i = 0; i < channels; i++) {
799
      /* channel number is 1st byte */
800
0
      channel_item = proto_tree_add_item_ret_uint(chanlist_tree, hf_awdl_channelseq_channel, tvb, offset, 1,
801
0
                                                  ENC_LITTLE_ENDIAN, &chan_number);
802
0
      channel_tree = proto_item_add_subtree(channel_item, ett_awdl_channelseq_channel);
803
0
      proto_tree_add_item(channel_tree, hf_awdl_channelseq_channel_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
804
0
      offset += 1;
805
0
      proto_tree_add_item(channel_tree, hf_awdl_channelseq_channel_operating_class, tvb, offset, 1, ENC_LITTLE_ENDIAN);
806
0
      offset += 1;
807
808
0
      if (i != 0) {
809
        /* not the first */
810
0
        wmem_strbuf_append_printf(strbuf, ", %u", chan_number);
811
0
      } else {
812
0
        wmem_strbuf_append_printf(strbuf, "%u", chan_number);
813
0
      }
814
0
    }
815
0
    break;
816
0
  default:
817
    /* TODO error handling */
818
0
    chanlist_item = NULL;
819
0
    break;
820
0
  }
821
822
0
  if (chanlist_item) {
823
    /* finally, append channel list as string */
824
0
    proto_item_append_text(chanlist_item, ": %s", wmem_strbuf_get_str(strbuf));
825
0
  }
826
827
0
  return offset;
828
0
}
829
830
static int
831
0
awdl_tag_sync_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) {
832
0
  int tag_len = tvb_reported_length(tvb);
833
0
  tvbuff_t *chanseq_tvb;
834
0
  int offset = 0;
835
836
0
  proto_tree_add_item(tree, hf_awdl_syncparams_tx_chan, tvb, offset, 1, ENC_LITTLE_ENDIAN);
837
0
  offset += 1;
838
0
  proto_tree_add_item(tree, hf_awdl_syncparams_tx_counter, tvb, offset, 2, ENC_LITTLE_ENDIAN);
839
0
  offset += 2;
840
0
  proto_tree_add_item(tree, hf_awdl_syncparams_master_chan, tvb, offset, 1, ENC_LITTLE_ENDIAN);
841
0
  offset += 1;
842
0
  proto_tree_add_item(tree, hf_awdl_syncparams_guard_time, tvb, offset, 1, ENC_LITTLE_ENDIAN);
843
0
  offset += 1;
844
0
  proto_tree_add_item(tree, hf_awdl_syncparams_aw_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
845
0
  offset += 2;
846
0
  proto_tree_add_item(tree, hf_awdl_syncparams_action_frame_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
847
0
  offset += 2;
848
0
  proto_tree_add_item(tree, hf_awdl_syncparams_awdl_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
849
0
  offset += 2;
850
0
  proto_tree_add_item(tree, hf_awdl_syncparams_aw_ext_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
851
0
  offset += 2;
852
0
  proto_tree_add_item(tree, hf_awdl_syncparams_aw_cmn_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
853
0
  offset += 2;
854
0
  proto_tree_add_item(tree, hf_awdl_syncparams_aw_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
855
0
  offset += 2;
856
0
  proto_tree_add_item(tree, hf_awdl_syncparams_ext_min, tvb, offset, 1, ENC_LITTLE_ENDIAN);
857
0
  offset += 1;
858
0
  proto_tree_add_item(tree, hf_awdl_syncparams_ext_max_multi, tvb, offset, 1, ENC_LITTLE_ENDIAN);
859
0
  offset += 1;
860
0
  proto_tree_add_item(tree, hf_awdl_syncparams_ext_max_uni, tvb, offset, 1, ENC_LITTLE_ENDIAN);
861
0
  offset += 1;
862
0
  proto_tree_add_item(tree, hf_awdl_syncparams_ext_max_af, tvb, offset, 1, ENC_LITTLE_ENDIAN);
863
0
  offset += 1;
864
865
  //the following values are also used in IOFamily
866
0
  proto_tree_add_item(tree, hf_awdl_syncparams_master, tvb, offset, 6, ENC_NA);
867
0
  offset += 6;
868
0
  proto_tree_add_item(tree, hf_awdl_syncparams_presence_mode, tvb, offset, 1, ENC_NA);
869
0
  offset += 1;
870
0
  proto_tree_add_item(tree, hf_awdl_unknown, tvb, offset, 1, ENC_NA);
871
0
  offset += 1;
872
0
  proto_tree_add_item(tree, hf_awdl_syncparams_awcounter, tvb, offset, 2, ENC_LITTLE_ENDIAN);
873
0
  offset += 2;
874
0
  proto_tree_add_item(tree, hf_awdl_syncparams_apbeaconalignment, tvb, offset, 2, ENC_LITTLE_ENDIAN);
875
0
  offset += 2;
876
877
0
  chanseq_tvb = tvb_new_subset_length(tvb, offset, tag_len - offset);
878
0
  offset += awdl_tag_channel_sequence(chanseq_tvb, pinfo, tree, data);
879
880
0
  return offset;
881
0
}
882
883
static int
884
0
awdl_tag_election_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) {
885
0
  int offset = 0;
886
887
0
  uint8_t private_election = tvb_get_uint8(tvb, offset);
888
889
0
  proto_tree_add_item(tree, hf_awdl_electionparams_flags, tvb, offset, 1, ENC_NA);
890
0
  offset += 1;
891
0
  proto_tree_add_item(tree, hf_awdl_electionparams_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
892
0
  offset += 2;
893
0
  proto_tree_add_item(tree, hf_awdl_electionparams_distance, tvb, offset, 1, ENC_NA);
894
0
  offset += 1;
895
0
  proto_tree_add_item(tree, hf_awdl_electionparams_unknown, tvb, offset, 1, ENC_NA);
896
0
  offset += 1;
897
0
  proto_tree_add_item(tree, hf_awdl_electionparams_master, tvb, offset, 6, ENC_NA);
898
0
  offset += 6;
899
0
  proto_tree_add_item(tree, hf_awdl_electionparams_mastermetric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
900
0
  offset += 4;
901
0
  proto_tree_add_item(tree, hf_awdl_electionparams_selfmetric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
902
0
  offset += 4;
903
904
0
  if (private_election) {
905
0
    proto_tree_add_item(tree, hf_awdl_unknown, tvb, offset, 2, ENC_NA);
906
0
    offset += 2;
907
0
    proto_tree_add_item(tree, hf_awdl_electionparams_private_master, tvb, offset, 6, ENC_NA);
908
0
    offset += 6;
909
0
    proto_tree_add_item(tree, hf_awdl_electionparams_private_mastermetric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
910
0
    offset += 4;
911
0
    proto_tree_add_item(tree, hf_awdl_electionparams_private_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
912
0
    offset += 4;
913
0
    proto_tree_add_item(tree, hf_awdl_electionparams_private_phc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
914
0
    offset += 2;
915
0
  }
916
917
0
  return offset;
918
0
}
919
920
static int
921
0
awdl_tag_election_params_v2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) {
922
0
  int offset = 0;
923
924
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_master, tvb, offset, 6, ENC_NA);
925
0
  offset += 6;
926
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_other, tvb, offset, 6, ENC_NA);
927
0
  offset += 6;
928
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_mastercounter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
929
0
  offset += 4;
930
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_distance, tvb, offset, 4, ENC_LITTLE_ENDIAN);
931
0
  offset += 4;
932
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_mastermetric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
933
0
  offset += 4;
934
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_selfmetric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
935
0
  offset += 4;
936
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_unknown, tvb, offset, 4, ENC_LITTLE_ENDIAN);
937
0
  offset += 4;
938
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
939
0
  offset += 4;
940
0
  proto_tree_add_item(tree, hf_awdl_electionparams2_selfcounter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
941
0
  offset += 4;
942
943
0
  return offset;
944
0
}
945
946
static int
947
0
awdl_tag_datapath_state(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) {
948
0
  int offset = 0;
949
0
  uint16_t flags;
950
951
0
  static int * const flags_fields[] = {
952
0
    &hf_awdl_datastate_flags_0,
953
0
    &hf_awdl_datastate_flags_1,
954
0
    &hf_awdl_datastate_flags_2,
955
0
    &hf_awdl_datastate_flags_3,
956
0
    &hf_awdl_datastate_flags_4,
957
0
    &hf_awdl_datastate_flags_5,
958
0
    &hf_awdl_datastate_flags_6,
959
0
    &hf_awdl_datastate_flags_7,
960
0
    &hf_awdl_datastate_flags_8,
961
0
    &hf_awdl_datastate_flags_9,
962
0
    &hf_awdl_datastate_flags_10,
963
0
    &hf_awdl_datastate_flags_11,
964
0
    &hf_awdl_datastate_flags_12,
965
0
    &hf_awdl_datastate_flags_13,
966
0
    &hf_awdl_datastate_flags_14,
967
0
    &hf_awdl_datastate_flags_15,
968
0
    NULL
969
0
  };
970
971
0
  static int * const channel_map_fields[] = {
972
0
    &hf_awdl_datastate_social_channel_map_6,
973
0
    &hf_awdl_datastate_social_channel_map_44,
974
0
    &hf_awdl_datastate_social_channel_map_149,
975
0
    &hf_awdl_datastate_social_channel_map_unused,
976
0
    NULL
977
0
  };
978
979
0
  static int * const extflags_fields[] = {
980
0
    &hf_awdl_datastate_extflags_0,
981
0
    &hf_awdl_datastate_extflags_1,
982
0
    &hf_awdl_datastate_extflags_2,
983
0
    &hf_awdl_datastate_extflags_3,
984
0
    &hf_awdl_datastate_extflags_4,
985
0
    &hf_awdl_datastate_extflags_5,
986
0
    &hf_awdl_datastate_extflags_6,
987
0
    &hf_awdl_datastate_extflags_7,
988
0
    &hf_awdl_datastate_extflags_8,
989
0
    &hf_awdl_datastate_extflags_9,
990
0
    &hf_awdl_datastate_extflags_10,
991
0
    &hf_awdl_datastate_extflags_11,
992
0
    &hf_awdl_datastate_extflags_12,
993
0
    &hf_awdl_datastate_extflags_13,
994
0
    &hf_awdl_datastate_extflags_14to15,
995
0
    NULL
996
0
  };
997
998
0
  flags = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
999
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_awdl_datastate_flags,
1000
0
                         ett_awdl_datastate_flags, flags_fields, ENC_LITTLE_ENDIAN);
1001
0
  offset += 2;
1002
1003
0
  if (flags & 0x0100) {
1004
0
    proto_tree_add_item(tree, hf_awdl_datastate_countrycode, tvb, offset, 3, ENC_ASCII);
1005
0
    offset += 3;
1006
0
  }
1007
0
  if (flags & 0x0200) {
1008
    /* this can either be a channel or a map indicating which channels this node supports */
1009
0
    uint16_t map = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1010
    /* TODO unverified heuristic to decide whether this is a map or number */
1011
0
    if (map & 1) {
1012
0
      proto_tree_add_bitmask(tree, tvb, offset, hf_awdl_datastate_social_channel_map,
1013
0
                             ett_awdl_datastate_social_channel_map, channel_map_fields, ENC_LITTLE_ENDIAN);
1014
0
    } else {
1015
      /* a single channel number */
1016
0
      proto_tree_add_item(tree, hf_awdl_datastate_social_channel, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1017
0
    }
1018
0
    offset += 2;
1019
0
  }
1020
0
  if (flags & 0x0001) {
1021
0
    proto_tree_add_item(tree, hf_awdl_datastate_infra_bssid, tvb, offset, 6, ENC_NA);
1022
0
    proto_tree_add_item(tree, hf_awdl_datastate_infra_channel, tvb, offset + 6, 2, ENC_LITTLE_ENDIAN);
1023
0
    offset += 8;
1024
0
  }
1025
0
  if (flags & 0x0002) {
1026
    // if not set, this will be the same as 0x1
1027
0
    proto_tree_add_item(tree, hf_awdl_datastate_infra_address, tvb, offset, 6, ENC_NA);
1028
0
    offset += 6;
1029
0
  }
1030
0
  if (flags & 0x0004) {
1031
0
    proto_tree_add_item(tree, hf_awdl_datastate_awdl_address, tvb, offset, 6, ENC_NA);
1032
0
    offset += 6;
1033
0
  }
1034
0
  if (flags & 0x0010) {
1035
0
    proto_tree_add_item(tree, hf_awdl_datastate_umi, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1036
0
    offset += 2;
1037
0
  }
1038
0
  if (flags & 0x1000) {
1039
0
    uint16_t optionlength = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1040
0
    proto_tree_add_item(tree, hf_awdl_datastate_umioptions_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1041
0
    offset += 2;
1042
0
    proto_tree_add_item(tree, hf_awdl_datastate_umioptions, tvb, offset, optionlength, ENC_NA);
1043
0
    offset += optionlength;
1044
0
  }
1045
  /* now come the extended parameters */
1046
0
  if (flags & 0x8000) {
1047
0
    uint16_t extflags = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1048
0
    proto_tree_add_bitmask(tree, tvb, offset, hf_awdl_datastate_extflags,
1049
0
                           ett_awdl_datastate_extflags, extflags_fields, ENC_LITTLE_ENDIAN);
1050
0
    offset += 2;
1051
1052
0
    if (extflags & 0x1) {
1053
      /* The logtrigger is actually two bytes. */
1054
0
      proto_tree_add_item(tree, hf_awdl_datastate_logtrigger, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1055
0
      offset += 2;
1056
0
    }
1057
0
    if (extflags & 0x4) {
1058
      /* Meaning unknown. */
1059
0
      proto_tree_add_item(tree, hf_awdl_datastate_rlfc, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1060
0
      offset += 4;
1061
0
    }
1062
0
    if (extflags & 0x40) {
1063
0
      proto_tree_add_item(tree, hf_awdl_datastate_active_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1064
0
      offset += 4;
1065
0
      proto_tree_add_item(tree, hf_awdl_datastate_aw_sequence_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1066
0
      offset += 4;
1067
0
      proto_tree_add_item(tree, hf_awdl_datastate_update_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1068
0
      offset += 4;
1069
0
    }
1070
0
  }
1071
1072
0
  return offset;
1073
0
}
1074
1075
static int
1076
0
awdl_tag_ieee80211_container(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
1077
0
  int offset = 0;
1078
1079
0
  const uint8_t ids[] = {
1080
0
    191, // VHT Capability
1081
0
  };
1082
0
  offset += add_tagged_field(pinfo, tree, tvb, offset, MGT_ACTION, ids, G_N_ELEMENTS(ids), NULL);
1083
1084
0
  return offset;
1085
0
}
1086
1087
static int
1088
0
awdl_tag_ht_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
1089
0
  proto_item *ti, *cap_item;
1090
0
  proto_tree *mcs_tree, *bit_tree, *cap_tree;
1091
0
  uint8_t streams; /* 0-4 for HT and 0-8 for VHT*/
1092
0
  int mcs_len;
1093
0
  int offset = 0;
1094
0
  int tag_len = tvb_reported_length(tvb);
1095
1096
0
  static int * const awdl_ht[] = {
1097
0
    &hf_awdl_ht_ldpc_coding,
1098
0
    &hf_awdl_ht_chan_width,
1099
0
    &hf_awdl_ht_sm_pwsave,
1100
0
    &hf_awdl_ht_green,
1101
0
    &hf_awdl_ht_short20,
1102
0
    &hf_awdl_ht_short40,
1103
0
    &hf_awdl_ht_tx_stbc,
1104
0
    &hf_awdl_ht_rx_stbc,
1105
0
    &hf_awdl_ht_delayed_block_ack,
1106
0
    &hf_awdl_ht_max_amsdu,
1107
0
    &hf_awdl_ht_dss_cck_40,
1108
0
    &hf_awdl_ht_psmp,
1109
0
    &hf_awdl_ht_40_mhz_intolerant,
1110
0
    &hf_awdl_ht_l_sig,
1111
0
    NULL
1112
0
  };
1113
1114
0
  proto_tree_add_item(tree, hf_awdl_ht_unknown, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1115
0
  offset += 2;
1116
1117
0
  proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_awdl_ht_cap, ett_awdl_ht_capabilities,
1118
0
                                    awdl_ht, ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
1119
0
  offset += 2;
1120
1121
0
  cap_item = proto_tree_add_item(tree, hf_awdl_ampduparam, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1122
0
  cap_tree = proto_item_add_subtree(cap_item, ett_awdl_ht_ampduparam);
1123
0
  ti = proto_tree_add_item(cap_tree, hf_awdl_ampduparam_mpdu, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1124
0
  proto_item_append_text(ti, " (%04.0f[Bytes])", pow(2, 13 + (tvb_get_uint8(tvb, offset) & 0x3)) - 1);
1125
0
  proto_tree_add_item(cap_tree, hf_awdl_ampduparam_mpdu_start_spacing, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1126
0
  proto_tree_add_item(cap_tree, hf_awdl_ampduparam_reserved, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1127
0
  offset += 1;
1128
1129
  /* Check how many streams are supported */
1130
0
  for (streams = 0; streams < 4 /* max streams */ && tvb_get_uint8(tvb, offset + streams) != 0; streams++) {
1131
0
  }
1132
  /* the first octet of the Rx MCS bitmask is there even when it is zero */
1133
0
  mcs_len = streams ? streams : 1;
1134
1135
0
  ti = proto_tree_add_item(tree, hf_awdl_mcsset, tvb, offset, mcs_len, ENC_NA);
1136
0
  mcs_tree = proto_item_add_subtree(ti, ett_awdl_ht_mcsset_tree);
1137
1138
  /* Rx MCS Bitmask */
1139
0
  ti = proto_tree_add_item(mcs_tree, hf_awdl_mcsset_rx_bitmask, tvb, offset, mcs_len, ENC_NA);
1140
0
  bit_tree = proto_item_add_subtree(ti, ett_awdl_ht_mcsbit_tree);
1141
1142
0
  proto_tree_add_item(bit_tree, hf_awdl_mcsset_rx_bitmask_0to7, tvb, offset, mcs_len, ENC_LITTLE_ENDIAN);
1143
0
  offset += 1;
1144
0
  if (offset < tag_len - 2) {
1145
0
    proto_tree_add_item(bit_tree, hf_awdl_mcsset_rx_bitmask_8to15, tvb, offset - 1, mcs_len, ENC_LITTLE_ENDIAN);
1146
0
    offset += 1;
1147
0
  }
1148
0
  if (offset < tag_len - 2) {
1149
0
    proto_tree_add_item(bit_tree, hf_awdl_mcsset_rx_bitmask_16to23, tvb, offset - 2, mcs_len, ENC_LITTLE_ENDIAN);
1150
0
    offset += 1;
1151
0
  }
1152
0
  if (offset < tag_len - 2) {
1153
0
    proto_tree_add_item(bit_tree, hf_awdl_mcsset_rx_bitmask_24to31, tvb, offset - 3, mcs_len, ENC_LITTLE_ENDIAN);
1154
0
    offset += 1;
1155
0
  }
1156
1157
0
  proto_item_append_text(ti, ": %s", val_to_str(pinfo->pool, streams - 1, mcsset_tx_max_spatial_streams_flags, "Reserved: %d" ) );
1158
1159
  // Some padding at the end
1160
0
  proto_tree_add_item(tree, hf_awdl_ht_unknown, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1161
0
  offset += 2;
1162
1163
0
  return offset;
1164
0
}
1165
1166
/*
1167
 * Decodes a AWDL-variant DNS name.
1168
 *
1169
 * 'hfindex_regular' needs to registered as
1170
 * 'hfindex_compressed' assumes a field that can be decoded with the 'awdl_dns_compression' value_string
1171
 */
1172
static int
1173
add_awdl_dns_name(proto_tree *tree, int hfindex_regular, int hfindex_compressed,
1174
0
                  tvbuff_t *tvb, int offset, int len, wmem_allocator_t *scope, const char **name) {
1175
0
  int start_offset = offset;
1176
0
  uint8_t component_len;
1177
0
  const char *component;
1178
0
  wmem_strbuf_t *strbuf;
1179
1180
0
  strbuf = wmem_strbuf_new_sized(scope, MAX_DNAME_LEN);
1181
1182
0
  while (offset < (len + start_offset)) {
1183
0
    component_len = tvb_get_uint8(tvb, offset);
1184
0
    if (component_len & 0xC0) {
1185
      /* compressed label */
1186
0
      unsigned compressed_value;
1187
0
      proto_tree_add_item_ret_uint(tree, hfindex_compressed, tvb, offset, 2, ENC_BIG_ENDIAN, &compressed_value);
1188
0
      if (compressed_value == 0xC000) {
1189
        // 'NULL' compression -> ignore in printed string
1190
0
        component = NULL;
1191
0
      } else {
1192
0
        component = val_to_str_const(compressed_value, awdl_dns_compression, "<UNKNOWN>");
1193
0
      }
1194
0
      offset += 2;
1195
0
    } else {
1196
      /* regular label */
1197
0
      unsigned label_len;
1198
0
      proto_tree_add_item_ret_string_and_length(tree, hfindex_regular, tvb, offset, 1, ENC_ASCII, scope, (const uint8_t**)&component, &label_len);
1199
0
      offset += label_len;
1200
0
    }
1201
0
    if (component) {
1202
0
      if (wmem_strbuf_get_len(strbuf))
1203
        /* not the first entry */
1204
0
        wmem_strbuf_append_c(strbuf, '.');
1205
0
      wmem_strbuf_append(strbuf, component);
1206
0
    }
1207
0
  }
1208
1209
0
  *name = wmem_strbuf_get_str(strbuf);
1210
1211
0
  return offset - start_offset;
1212
0
}
1213
1214
static int
1215
add_awdl_dns_entry(packet_info *pinfo, proto_tree *tree, int ett,
1216
                   int hfindex_entry, int hfindex_regular, int hfindex_compressed,
1217
0
                   tvbuff_t *tvb, int offset, int len, const char **name) {
1218
0
  int start_offset = offset;
1219
0
  proto_item *entry_item;
1220
0
  proto_tree *entry_tree;
1221
0
  const char *n;
1222
1223
0
  entry_item = proto_tree_add_item(tree, hfindex_entry, tvb, offset, 0, ENC_NA);
1224
0
  entry_tree = proto_item_add_subtree(entry_item, ett);
1225
0
  offset += add_awdl_dns_name(entry_tree, hfindex_regular, hfindex_compressed, tvb, offset, len, pinfo->pool, &n);
1226
0
  proto_item_set_end(entry_item, tvb, offset);
1227
0
  proto_item_append_text(entry_item, ": %s", n);
1228
1229
0
  if (name)
1230
0
    (*name) = n;
1231
1232
0
  return offset - start_offset;
1233
0
}
1234
1235
static int
1236
0
awdl_tag_arpa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
1237
0
  int offset = 0;
1238
0
  int tag_len = tvb_reported_length(tvb);
1239
1240
0
  proto_tree_add_item(tree, hf_awdl_arpa_flags, tvb, offset, 1, ENC_NA);
1241
0
  offset += 1;
1242
0
  offset += add_awdl_dns_entry(pinfo, tree, ett_awdl_dns_name, hf_awdl_arpa, hf_awdl_arpa_name,
1243
0
                               hf_awdl_arpa_short, tvb, offset, tag_len - offset, NULL);
1244
1245
0
  return offset;
1246
0
}
1247
1248
static int
1249
0
awdl_tag_service_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
1250
0
  proto_item *rr_item;
1251
0
  proto_tree *rr_tree, *data_len;
1252
0
  const char *name;
1253
0
  int offset = 0;
1254
0
  unsigned len, type;
1255
0
  unsigned prio, weight, port;
1256
1257
0
  rr_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_awdl_dns_record, &rr_item, "");
1258
1259
0
  proto_tree_add_item_ret_uint(rr_tree, hf_awdl_dns_name_len, tvb, offset, 2, ENC_LITTLE_ENDIAN, &len);
1260
0
  offset += 2;
1261
1262
  // len field includes the following type value
1263
0
  len -= 1;
1264
0
  offset += add_awdl_dns_entry(pinfo, rr_tree, ett_awdl_dns_name, hf_awdl_dns_name, hf_awdl_dns_name_label,
1265
0
                               hf_awdl_dns_name_short, tvb, offset, len, &name);
1266
1267
0
  proto_tree_add_item_ret_uint(rr_tree, hf_awdl_dns_type, tvb, offset, 1, ENC_LITTLE_ENDIAN, &type);
1268
0
  offset += 1;
1269
1270
0
  proto_item_set_text(rr_item, "%s: type %s", name, val_to_str_const(type, dns_types_vals, "UNKNOWN"));
1271
1272
0
  data_len = proto_tree_add_item_ret_uint(rr_tree, hf_awdl_dns_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN, &len);
1273
0
  offset += 2;
1274
  // TODO could be that len field is actually uint32?
1275
0
  proto_tree_add_item(rr_tree, hf_awdl_dns_unknown, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1276
0
  offset += 2;
1277
1278
0
  switch (type) {
1279
0
  case T_TXT:
1280
0
    while (len > 0) {
1281
0
      const unsigned char *txt;
1282
0
      unsigned label_len;
1283
0
      proto_tree_add_item_ret_string_and_length(rr_tree, hf_awdl_dns_txt, tvb, offset, 1, ENC_ASCII,
1284
0
                                                pinfo->pool, &txt, &label_len);
1285
0
      offset += label_len;
1286
0
      proto_item_append_text(rr_item, ", %s", txt);
1287
0
      if (label_len > len) {
1288
0
        expert_add_info_format(pinfo, data_len, &ei_awdl_tag_length,
1289
0
                               "DNS data length is too short");
1290
0
        break;
1291
0
      }
1292
0
      len -= label_len;
1293
0
    }
1294
0
    break;
1295
0
  case T_SRV:
1296
0
    proto_tree_add_item_ret_uint(rr_tree, hf_awdl_dns_priority, tvb, offset, 2, ENC_BIG_ENDIAN, &prio);
1297
0
    offset += 2;
1298
0
    proto_tree_add_item_ret_uint(rr_tree, hf_awdl_dns_weight, tvb, offset, 2, ENC_BIG_ENDIAN, &weight);
1299
0
    offset += 2;
1300
0
    proto_tree_add_item_ret_uint(rr_tree, hf_awdl_dns_port, tvb, offset, 2, ENC_BIG_ENDIAN, &port);
1301
0
    offset += 2;
1302
    // length field includes above fields
1303
0
    len -= 6;
1304
0
    offset += add_awdl_dns_entry(pinfo, rr_tree, ett_awdl_dns_name, hf_awdl_dns_target, hf_awdl_dns_target_label,
1305
0
                                 hf_awdl_dns_target_short, tvb, offset, len, &name);
1306
0
    proto_item_append_text(rr_item, ", priority %u, weight %u, port %u, target %s", prio, weight, port, name);
1307
0
    break;
1308
0
  case T_PTR:
1309
0
    offset += add_awdl_dns_entry(pinfo, rr_tree, ett_awdl_dns_name, hf_awdl_dns_ptr, hf_awdl_dns_ptr_label,
1310
0
                                 hf_awdl_dns_ptr_short, tvb, offset, len, &name);
1311
0
    proto_item_append_text(rr_item, ", %s", name);
1312
0
    break;
1313
0
  default:
1314
0
    break;
1315
0
  }
1316
1317
0
  return offset;
1318
0
}
1319
1320
static int
1321
0
awdl_add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, enum tag_length hdr_len) {
1322
0
  tvbuff_t     *tag_tvb;
1323
0
  uint32_t      tag_no, tag_len;
1324
0
  proto_tree   *orig_tree = tree;
1325
0
  proto_item   *ti        = NULL;
1326
0
  proto_item   *ti_len, *ti_tag;
1327
0
  awdl_tagged_field_data_t field_data;
1328
0
  int parsed;
1329
1330
0
  tag_no = tvb_get_uint8(tvb, offset);
1331
0
  if (hdr_len == TAG_LENGTH_SHORT) {
1332
0
    tag_len = tvb_get_uint8(tvb, offset + 1);
1333
0
  } else {
1334
0
    tag_len = tvb_get_uint16(tvb, offset + 1, ENC_LITTLE_ENDIAN);
1335
0
  }
1336
1337
0
  if (tree) {
1338
0
    ti = proto_tree_add_item(orig_tree, hf_awdl_tag, tvb, offset, tag_len + hdr_len, ENC_NA);
1339
0
    proto_item_append_text(ti, ": %s", val_to_str_ext(pinfo->pool, tag_no, &tag_num_vals_ext, "Unknown (%d)"));
1340
0
    tree = proto_item_add_subtree(ti, ett_awdl_tag);
1341
0
  }
1342
1343
0
  ti_tag = proto_tree_add_uint(tree, hf_awdl_tag_number, tvb, offset, 1, tag_no);
1344
0
  ti_len = proto_tree_add_uint(tree, hf_awdl_tag_length, tvb, offset + 1, hdr_len - 1, tag_len);
1345
0
  offset += hdr_len;
1346
0
  if (tag_len > (unsigned)tvb_reported_length_remaining(tvb, offset)) {
1347
0
    expert_add_info_format(pinfo, ti_len, &ei_awdl_tag_length,
1348
0
                           "Tag Length is longer than remaining payload");
1349
0
  }
1350
1351
0
  tag_tvb = tvb_new_subset_length(tvb, offset, tag_len);
1352
0
  field_data.item_tag = ti;
1353
0
  field_data.item_tag_length = ti_len;
1354
0
  if (!(parsed = dissector_try_uint_with_data(tagged_field_table, tag_no, tag_tvb, pinfo, tree, false, &field_data)))
1355
0
  {
1356
0
    proto_tree_add_item(tree, hf_awdl_tag_data, tag_tvb, 0, tag_len, ENC_NA);
1357
0
    expert_add_info_format(pinfo, ti_tag, &ei_awdl_tag_data,
1358
0
                           "Dissector for AWDL tag (%s) code not implemented",
1359
0
                           val_to_str_ext(pinfo->pool, tag_no, &tag_num_vals_ext, "(%d)"));
1360
0
    proto_item_append_text(ti, ": Undecoded");
1361
0
  }
1362
0
  else if (parsed > 0 && (unsigned int) parsed < tag_len)
1363
0
  {
1364
0
    proto_tree_add_item(tree, hf_awdl_tag_padding, tag_tvb, parsed, tag_len - parsed, ENC_NA);
1365
0
  }
1366
1367
0
  return tag_len + hdr_len;
1368
0
}
1369
1370
static void
1371
awdl_add_tagged_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int tagged_parameters_len)
1372
0
{
1373
0
  int next_len;
1374
0
  while (tagged_parameters_len > 0) {
1375
0
    if ((next_len = awdl_add_tagged_field(pinfo, tree, tvb, offset, TAG_LENGTH)) == 0)
1376
0
      break;
1377
0
    if (next_len > tagged_parameters_len) {
1378
      /* XXX - flag this as an error? */
1379
0
      next_len = tagged_parameters_len;
1380
0
    }
1381
0
    offset                += next_len;
1382
0
    tagged_parameters_len -= next_len;
1383
0
  }
1384
0
}
1385
1386
static proto_tree *
1387
get_tagged_parameter_tree(proto_tree * tree, tvbuff_t *tvb, int start, int size)
1388
0
{
1389
0
  proto_item *tagged_fields;
1390
1391
0
  tagged_fields = proto_tree_add_item(tree, hf_awdl_tagged_parameters, tvb, start, -1, ENC_NA);
1392
0
  proto_item_append_text(tagged_fields, " (%d bytes)", size);
1393
1394
0
  return proto_item_add_subtree(tagged_fields, ett_awdl_tagged_parameters);
1395
0
}
1396
1397
static int
1398
dissect_awdl_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1399
0
{
1400
0
  int        offset = 0;
1401
0
  int        tagged_parameter_tree_len;
1402
0
  proto_tree *parent, *af_tree, *fixed_tree, *tag_tree;
1403
0
  proto_item *ti, *item, *fixed_fields;
1404
0
  uint32_t phytime, targettime;
1405
0
  uint8_t subtype;
1406
1407
0
  parent = proto_tree_get_parent_tree(proto_tree_get_parent_tree(tree));
1408
0
  ti = proto_tree_add_item(parent, proto_awdl, tvb, offset, -1, ENC_NA);
1409
0
  af_tree = proto_item_add_subtree(ti, ett_awdl);
1410
1411
0
  fixed_fields = proto_tree_add_item(af_tree, hf_awdl_fixed_parameters, tvb, offset, 12, ENC_NA);
1412
0
  fixed_tree =  proto_item_add_subtree(fixed_fields, ett_awdl_fixed_parameters);
1413
0
  proto_tree_add_item(fixed_tree, hf_awdl_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1414
0
  offset += 1;
1415
0
  add_awdl_version(tvb, offset, fixed_tree);
1416
0
  offset += 1;
1417
0
  proto_tree_add_item_ret_uint8(fixed_tree, hf_awdl_subtype, tvb, offset, 1, ENC_LITTLE_ENDIAN, &subtype);
1418
0
  offset += 1;
1419
0
  proto_tree_add_item(fixed_tree, hf_awdl_rsvd, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1420
0
  offset += 1;
1421
0
  proto_tree_add_item_ret_uint(fixed_tree, hf_awdl_phytime, tvb, offset, 4, ENC_LITTLE_ENDIAN, &phytime);
1422
0
  offset += 4;
1423
0
  proto_tree_add_item_ret_uint(fixed_tree, hf_awdl_targettime, tvb, offset, 4, ENC_LITTLE_ENDIAN, &targettime);
1424
0
  offset += 4;
1425
0
  item = proto_tree_add_uint(fixed_tree, hf_awdl_txdelay, tvb, 0, 0, phytime - targettime);
1426
0
  proto_item_set_generated(item);
1427
1428
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "AWDL");
1429
0
  col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(subtype, awdl_subtype_col, "Unknown"));
1430
0
  proto_item_append_text(ti, ", Subtype: %s", val_to_str_const(subtype, awdl_subtype_short, "Unknown"));
1431
1432
0
  tagged_parameter_tree_len = tvb_reported_length_remaining(tvb, offset);
1433
0
  tag_tree = get_tagged_parameter_tree(af_tree, tvb, offset, tagged_parameter_tree_len);
1434
0
  awdl_add_tagged_parameters(tvb, offset, pinfo, tag_tree, tagged_parameter_tree_len);
1435
0
  offset += tagged_parameter_tree_len;
1436
1437
0
  return offset;
1438
0
}
1439
1440
static int
1441
dissect_awdl_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1442
0
{
1443
0
  int       offset = 0;
1444
0
  unsigned  etype;
1445
0
  tvbuff_t *next_tvb;
1446
0
  proto_item *ti;
1447
0
  proto_tree *awdl_tree;
1448
0
  unsigned seq;
1449
1450
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "AWDL Data");
1451
0
  col_clear(pinfo->cinfo, COL_INFO);
1452
1453
0
  ti = proto_tree_add_item(tree, proto_awdl_data, tvb, 0, -1, ENC_NA);
1454
1455
0
  awdl_tree = proto_item_add_subtree(ti, ett_awdl_data);
1456
1457
0
  proto_tree_add_item(awdl_tree, hf_awdl_data_header, tvb, offset, 2, ENC_NA);
1458
0
  offset += 2;
1459
1460
0
  proto_tree_add_item_ret_uint(awdl_tree, hf_awdl_data_seq, tvb, offset, 2, ENC_LITTLE_ENDIAN, &seq);
1461
0
  col_add_fstr(pinfo->cinfo, COL_INFO, "Seq=%u", seq);
1462
0
  proto_item_append_text(ti, ", Seq: %u", seq);
1463
0
  offset += 2;
1464
1465
0
  if (tvb_get_uint8(tvb, offset) == 3) {
1466
      // 0x0300 ("long format")
1467
0
      proto_item *tagged_item;
1468
0
      proto_tree *tagged_tree;
1469
0
      int         start_offset;
1470
0
      uint8_t     slen;
1471
1472
0
      slen = tvb_get_uint8(tvb, offset + 1);
1473
0
      proto_tree_add_item(awdl_tree, hf_awdl_data_header, tvb, offset, 2 + slen, ENC_NA);
1474
0
      offset += 2 + slen;
1475
1476
0
      tagged_item = proto_tree_add_item(awdl_tree, hf_awdl_tagged_parameters, tvb, offset, 0, ENC_NA); /* set length later */
1477
0
      tagged_tree = proto_item_add_subtree(tagged_item, ett_awdl_tagged_parameters);
1478
1479
0
      start_offset = offset;
1480
1481
0
      while (tvb_get_uint8(tvb, offset) != 3) {
1482
0
          offset += awdl_add_tagged_field(pinfo, tagged_tree, tvb, offset, TAG_LENGTH_SHORT);
1483
0
      }
1484
1485
0
      slen = tvb_get_uint8(tvb, offset + 1);
1486
0
      proto_tree_add_item(awdl_tree, hf_awdl_data_header, tvb, offset, 2 + slen, ENC_NA);
1487
0
      offset += 2 + slen;
1488
1489
0
      proto_item_set_len(tagged_item, offset - start_offset);
1490
0
      proto_item_append_text(tagged_item, " (%d bytes)", offset - start_offset);
1491
1492
0
  }
1493
0
  else {
1494
      // 0x0000
1495
      // TODO: should have some sanity check.
1496
0
      proto_tree_add_item(awdl_tree, hf_awdl_data_header, tvb, offset, 2, ENC_NA);
1497
0
      offset += 2;
1498
0
  }
1499
1500
  /* Last is some ethertype */
1501
0
  proto_tree_add_item_ret_uint(awdl_tree, hf_awdl_data_ethertype, tvb, offset, 2, ENC_BIG_ENDIAN, &etype);
1502
0
  offset += 2;
1503
1504
0
  proto_item_set_len(awdl_tree, offset);
1505
1506
0
  next_tvb = tvb_new_subset_remaining(tvb, offset);
1507
0
  if (!dissector_try_uint(ethertype_subdissector_table, etype, next_tvb, pinfo, tree))
1508
0
      call_data_dissector(next_tvb, pinfo, tree);
1509
1510
0
  return tvb_captured_length(tvb);
1511
0
}
1512
1513
static void
1514
awdl_register_tags(void)
1515
16
{
1516
16
  dissector_add_uint("awdl.tag.number", AWDL_SERVICE_RESPONSE_TLV, create_dissector_handle(awdl_tag_service_response, proto_awdl));
1517
16
  dissector_add_uint("awdl.tag.number", AWDL_SYNCHRONIZATON_PARAMETERS_TLV, create_dissector_handle(awdl_tag_sync_params, proto_awdl));
1518
16
  dissector_add_uint("awdl.tag.number", AWDL_ELECTION_PARAMETERS_TLV, create_dissector_handle(awdl_tag_election_params, proto_awdl));
1519
16
  dissector_add_uint("awdl.tag.number", AWDL_SERVICE_PARAMETERS_TLV, create_dissector_handle(awdl_tag_service_params, proto_awdl));
1520
16
  dissector_add_uint("awdl.tag.number", AWDL_ENHANCED_DATA_RATE_CAPABILITIES_TLV, create_dissector_handle(awdl_tag_ht_capabilities, proto_awdl));
1521
16
  dissector_add_uint("awdl.tag.number", AWDL_DATA_PATH_STATE_TLV, create_dissector_handle(awdl_tag_datapath_state, proto_awdl));
1522
16
  dissector_add_uint("awdl.tag.number", AWDL_ARPA_TLV, create_dissector_handle(awdl_tag_arpa, proto_awdl));
1523
16
  dissector_add_uint("awdl.tag.number", AWDL_IEEE80211_CONTAINER_TLV, create_dissector_handle(awdl_tag_ieee80211_container, proto_awdl));
1524
16
  dissector_add_uint("awdl.tag.number", AWDL_CHAN_SEQ_TLV, create_dissector_handle(awdl_tag_channel_sequence, proto_awdl));
1525
16
  dissector_add_uint("awdl.tag.number", AWDL_SYNCHRONIZATION_TREE_TLV, create_dissector_handle(awdl_tag_sync_tree, proto_awdl));
1526
16
  dissector_add_uint("awdl.tag.number", AWDL_VERSION_TLV, create_dissector_handle(awdl_tag_version, proto_awdl));
1527
16
  dissector_add_uint("awdl.tag.number", AWDL_ELECTION_PARAMETERS_V2_TLV, create_dissector_handle(awdl_tag_election_params_v2, proto_awdl));
1528
16
}
1529
1530
void proto_register_awdl(void)
1531
16
{
1532
16
  static hf_register_info hf[] = {
1533
    /* Default for unknown fields */
1534
16
    { &hf_awdl_unknown,
1535
16
      { "Unknown", "awdl.unknown",
1536
16
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1537
16
      }
1538
16
    },
1539
1540
    /* LLC */
1541
16
    { &hf_awdl_data_seq,
1542
16
      { "Sequence number", "awdl_data.seq",
1543
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
1544
16
      }
1545
16
    },
1546
16
    { &hf_awdl_data_header,
1547
16
      { "Header data", "awdl_data.header",
1548
16
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1549
16
      }
1550
16
    },
1551
16
    { &hf_awdl_data_ethertype,
1552
16
      { "EtherType", "awdl_data.ethertype",
1553
16
        FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
1554
16
      }
1555
16
    },
1556
1557
    /* Action Frame */
1558
16
    { &hf_awdl_fixed_parameters,
1559
16
      { "Fixed parameters", "awdl.fixed.all",
1560
16
        FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1561
16
      }
1562
16
    },
1563
16
    { &hf_awdl_tagged_parameters,
1564
16
      { "Tagged parameters", "awdl.tagged.all",
1565
16
        FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1566
16
      }
1567
16
    },
1568
1569
    /* Fixed parameters */
1570
16
    { &hf_awdl_type,
1571
16
      { "Type", "awdl.type",
1572
16
        FT_UINT8, BASE_DEC, VALS(awdl_type), 0x0, NULL, HFILL
1573
16
      }
1574
16
    },
1575
16
    { &hf_awdl_subtype,
1576
16
      { "Subtype", "awdl.subtype",
1577
16
        FT_UINT8, BASE_DEC, VALS(awdl_subtype), 0x0, NULL, HFILL
1578
16
      }
1579
16
    },
1580
16
    { &hf_awdl_rsvd,
1581
16
      { "Reserved", "awdl.reserved",
1582
16
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
1583
16
      }
1584
16
    },
1585
16
    { &hf_awdl_phytime,
1586
16
      { "PHY Tx Time", "awdl.phytime",
1587
16
        FT_UINT32, BASE_DEC | BASE_UNIT_STRING, UNS(&units_microseconds), 0x0,
1588
16
        "Time shortly before the frame was sent out by the radio", HFILL
1589
16
      }
1590
16
    },
1591
16
    { &hf_awdl_targettime,
1592
16
      { "Target Tx Time", "awdl.targettime",
1593
16
        FT_UINT32, BASE_DEC | BASE_UNIT_STRING, UNS(&units_microseconds), 0x0,
1594
16
        "Time when the frame was created.", HFILL
1595
16
      }
1596
16
    },
1597
16
    { &hf_awdl_txdelay,
1598
16
      { "Tx Delay", "awdl.txdelay",
1599
16
        FT_UINT32, BASE_DEC | BASE_UNIT_STRING, UNS(&units_microseconds), 0x0,
1600
16
        "Difference between the PHY and target time stamps", HFILL
1601
16
      }
1602
16
    },
1603
1604
    /* TLV */
1605
16
    { &hf_awdl_tag,
1606
16
      { "Tag", "awdl.tag",
1607
16
        FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL
1608
16
      }
1609
16
    },
1610
16
    { &hf_awdl_tag_number,
1611
16
      { "Tag Number", "awdl.tag.number",
1612
16
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &tag_num_vals_ext, 0x0, NULL, HFILL
1613
16
      }
1614
16
    },
1615
16
    { &hf_awdl_tag_length,
1616
16
      { "Tag Length", "awdl.tag.length",
1617
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
1618
16
      }
1619
16
    },
1620
16
    { &hf_awdl_tag_data,
1621
16
      { "Tag Data", "awdl.tag.data",
1622
16
        FT_BYTES, BASE_NONE, NULL, 0,
1623
16
        "Data Interpretation of tag", HFILL
1624
16
      }
1625
16
    },
1626
16
    { &hf_awdl_tag_padding,
1627
16
      { "Padding (?)", "awdl.tag.padding",
1628
16
        FT_BYTES, BASE_NONE, NULL, 0,
1629
16
        "Unused (?) bytes at the end of the tag", HFILL
1630
16
      }
1631
16
    },
1632
1633
    /* Version */
1634
16
    { &hf_awdl_version,
1635
16
      { "AWDL Version", "awdl.version",
1636
16
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL
1637
16
      }
1638
16
    },
1639
16
    { &hf_awdl_version_major,
1640
16
      { "AWDL Version Major", "awdl.version.major",
1641
16
        FT_UINT8, BASE_DEC, NULL, 0xf0, NULL, HFILL
1642
16
      }
1643
16
    },
1644
16
    { &hf_awdl_version_minor,
1645
16
      { "AWDL Version Minor", "awdl.version.minor",
1646
16
        FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL
1647
16
      }
1648
16
    },
1649
16
    { &hf_awdl_version_devclass,
1650
16
      { "Device Class", "awdl.version.device_class",
1651
16
        FT_UINT8, BASE_DEC, VALS(awdl_version_devclass), 0, NULL, HFILL
1652
16
      }
1653
16
    },
1654
1655
    /* Synchronization Tree */
1656
16
    { &hf_awdl_synctree_addr,
1657
16
      { "Address", "awdl.synctree.addr",
1658
16
        FT_ETHER, BASE_NONE, NULL, 0x0,
1659
16
        "From tree root to leaf", HFILL
1660
16
      }
1661
16
    },
1662
1663
    /* Data Path State */
1664
16
    { &hf_awdl_datastate_flags,
1665
16
      { "Flags", "awdl.datastate.flags",
1666
16
        FT_UINT16, BASE_HEX, NULL, 0,
1667
16
        "Subsequent fields do not follow the order in which they appear in this bitmask", HFILL
1668
16
      }
1669
16
    },
1670
16
    { &hf_awdl_datastate_flags_0,
1671
16
      { "Infrastructure BSSID and Channel", "awdl.datastate.flags.0",
1672
16
        FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL
1673
16
      }
1674
16
    },
1675
16
    { &hf_awdl_datastate_flags_1,
1676
16
      { "Infrastructure Address", "awdl.datastate.flags.1",
1677
16
        FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL
1678
16
      }
1679
16
    },
1680
16
    { &hf_awdl_datastate_flags_2,
1681
16
      { "AWDL Address", "awdl.datastate.flags.2",
1682
16
        FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL
1683
16
      }
1684
16
    },
1685
16
    { &hf_awdl_datastate_flags_3,
1686
16
      { "RSDB Support", "awdl.datastate.flags.3",
1687
16
        FT_BOOLEAN, 16, NULL, 0x0008, NULL, HFILL
1688
16
      }
1689
16
    },
1690
16
    { &hf_awdl_datastate_flags_4,
1691
16
      { "UMI", "awdl.datastate.flags.4",
1692
16
        FT_BOOLEAN, 16, NULL, 0x0010, NULL, HFILL
1693
16
      }
1694
16
    },
1695
16
    { &hf_awdl_datastate_flags_5,
1696
16
      { "Dualband Support", "awdl.datastate.flags.5",
1697
16
        FT_BOOLEAN, 16, NULL, 0x0020, NULL, HFILL
1698
16
      }
1699
16
    },
1700
16
    { &hf_awdl_datastate_flags_6,
1701
16
      { "AirPlay Sink", "awdl.datastate.flags.6",
1702
16
        FT_BOOLEAN, 16, NULL, 0x0040, NULL, HFILL
1703
16
      }
1704
16
    },
1705
16
    { &hf_awdl_datastate_flags_7,
1706
16
      { "Follow Channel Sequence", "awdl.datastate.flags.7",
1707
16
        FT_BOOLEAN, 16, NULL, 0x0080, NULL, HFILL
1708
16
      }
1709
16
    },
1710
16
    { &hf_awdl_datastate_flags_8,
1711
16
      { "Country Code", "awdl.datastate.flags.8",
1712
16
        FT_BOOLEAN, 16, NULL, 0x0100, NULL, HFILL
1713
16
      }
1714
16
    },
1715
16
    { &hf_awdl_datastate_flags_9,
1716
16
      { "Social Channels", "awdl.datastate.flags.9",
1717
16
        FT_BOOLEAN, 16, NULL, 0x0200, NULL, HFILL
1718
16
      }
1719
16
    },
1720
16
    { &hf_awdl_datastate_flags_10,
1721
16
      { "AirPlay Solo Mode", "awdl.datastate.flags.10",
1722
16
        FT_BOOLEAN, 16, NULL, 0x0400, NULL, HFILL
1723
16
      }
1724
16
    },
1725
16
    { &hf_awdl_datastate_flags_11,
1726
16
      { "UMI Supported", "awdl.datastate.flags.11",
1727
16
        FT_BOOLEAN, 16, NULL, 0x0800, NULL, HFILL
1728
16
      }
1729
16
    },
1730
16
    { &hf_awdl_datastate_flags_12,
1731
16
      { "Unicast Options", "awdl.datastate.flags.12",
1732
16
        FT_BOOLEAN, 16, NULL, 0x1000, NULL, HFILL
1733
16
      }
1734
16
    },
1735
16
    { &hf_awdl_datastate_flags_13,
1736
16
      { "Real-Time", "awdl.datastate.flags.13",
1737
16
        FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL
1738
16
      }
1739
16
    },
1740
16
    { &hf_awdl_datastate_flags_14,
1741
16
      { "Rangeable", "awdl.datastate.flags.14",
1742
16
        FT_BOOLEAN, 16, NULL, 0x4000, NULL, HFILL
1743
16
      }
1744
16
    },
1745
16
    { &hf_awdl_datastate_flags_15,
1746
16
      { "Extension Flags", "awdl.datastate.flags.15",
1747
16
        FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL
1748
16
      }
1749
16
    },
1750
16
    { &hf_awdl_datastate_countrycode,
1751
16
      { "Country Code", "awdl.datastate.countrycode",
1752
16
        FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL
1753
16
      }
1754
16
    },
1755
16
    { &hf_awdl_datastate_social_channel,
1756
16
      { "Social Channel", "awdl.datastate.social_channel",
1757
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
1758
16
      }
1759
16
    },
1760
16
    { &hf_awdl_datastate_social_channel_map,
1761
16
      { "Social Channel Map", "awdl.datastate.social_channel_map",
1762
16
        FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
1763
16
      }
1764
16
    },
1765
16
    { &hf_awdl_datastate_social_channel_map_6,
1766
16
      { "Channel 6", "awdl.datastate.social_channel_map.ch6",
1767
16
        FT_BOOLEAN, 16, NULL, 0x1, NULL, HFILL
1768
16
      }
1769
16
    },
1770
16
    { &hf_awdl_datastate_social_channel_map_44,
1771
16
      { "Channel 44", "awdl.datastate.social_channel_map.ch44",
1772
16
        FT_BOOLEAN, 16, NULL, 0x2, NULL, HFILL
1773
16
      }
1774
16
    },
1775
16
    { &hf_awdl_datastate_social_channel_map_149,
1776
16
      { "Channel 149", "awdl.datastate.social_channel_map.ch149",
1777
16
        FT_BOOLEAN, 16, NULL, 0x4, NULL, HFILL
1778
16
      }
1779
16
    },
1780
16
    { &hf_awdl_datastate_social_channel_map_unused,
1781
16
      { "Unused", "awdl.datastate.social_channel_map.unused",
1782
16
        FT_UINT16, BASE_HEX, NULL, 0xfff8, NULL, HFILL
1783
16
      }
1784
16
    },
1785
16
    { &hf_awdl_datastate_infra_bssid,
1786
16
      { "Infrastructure BSSID", "awdl.datastate.infra_bssid",
1787
16
        FT_ETHER, BASE_NONE, NULL, 0x0,
1788
16
        "Address of the AP currently connected to", HFILL
1789
16
      }
1790
16
    },
1791
16
    { &hf_awdl_datastate_infra_channel,
1792
16
      { "Infrastructure Channel", "awdl.datastate.infra_channel",
1793
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
1794
16
      }
1795
16
    },
1796
16
    { &hf_awdl_datastate_infra_address,
1797
16
      { "Infrastructure Address", "awdl.datastate.infra_addr",
1798
16
        FT_ETHER, BASE_NONE, NULL, 0x0,
1799
16
        "MAC address of this device", HFILL
1800
16
      }
1801
16
    },
1802
16
    { &hf_awdl_datastate_awdl_address,
1803
16
      { "AWDL Address", "awdl.datastate.own_awdladdr",
1804
16
        FT_ETHER, BASE_NONE, NULL, 0x0,
1805
16
        "Randomized Address used for AWDL", HFILL
1806
16
      }
1807
16
    },
1808
16
    { &hf_awdl_datastate_umi,
1809
16
      { "UMI (Airplay?)", "awdl.datastate.umi",
1810
16
        FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL
1811
16
      }
1812
16
    },
1813
16
    { &hf_awdl_datastate_umioptions,
1814
16
      { "Unicast Options", "awdl.datastate.unicast_options",
1815
16
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1816
16
      }
1817
16
    },
1818
16
    { &hf_awdl_datastate_umioptions_length,
1819
16
      { "Unicast Options Length", "awdl.datastate.unicast_options_length",
1820
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
1821
16
      }
1822
16
    },
1823
16
    { &hf_awdl_datastate_extflags,
1824
16
      { "Extended Flags", "awdl.datastate.extflags",
1825
16
        FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL
1826
16
      }
1827
16
    },
1828
16
    { &hf_awdl_datastate_extflags_0,
1829
16
      { "Logtrigger ID", "awdl.datastate.extflags.0",
1830
16
        FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL
1831
16
      }
1832
16
    },
1833
16
    { &hf_awdl_datastate_extflags_1,
1834
16
      { "Ranging Discovery", "awdl.datastate.extflags.1",
1835
16
        FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL
1836
16
      }
1837
16
    },
1838
16
    { &hf_awdl_datastate_extflags_2,
1839
16
      { "RLFC", "awdl.datastate.extflags.2",
1840
16
        FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL
1841
16
      }
1842
16
    },
1843
16
    { &hf_awdl_datastate_extflags_3,
1844
16
      { "Is Social Channel Map Supported", "awdl.datastate.extflags.3",
1845
16
        FT_BOOLEAN, 16, NULL, 0x0008, NULL, HFILL
1846
16
      }
1847
16
    },
1848
16
    { &hf_awdl_datastate_extflags_4,
1849
16
      { "Dynamic SDB Support", "awdl.datastate.extflags.4",
1850
16
        FT_BOOLEAN, 16, NULL, 0x0010, NULL, HFILL
1851
16
      }
1852
16
    },
1853
16
    { &hf_awdl_datastate_extflags_5,
1854
16
      { "Misc", "awdl.datastate.extflags.5",
1855
16
        FT_BOOLEAN, 16, NULL, 0x0020,
1856
16
        "Indicates the presence of the rlfc, active_time and update_counter fields.", HFILL
1857
16
      }
1858
16
    },
1859
16
    { &hf_awdl_datastate_extflags_6,
1860
16
      { "DFS Proxy Support", "awdl.datastate.extflags.6",
1861
16
        FT_BOOLEAN, 16, NULL, 0x0040, NULL, HFILL
1862
16
      }
1863
16
    },
1864
16
    { &hf_awdl_datastate_extflags_7,
1865
16
      { "Unknown", "awdl.datastate.extflags.7",
1866
16
        FT_BOOLEAN, 16, NULL, 0x0080, NULL, HFILL
1867
16
      }
1868
16
    },
1869
16
    { &hf_awdl_datastate_extflags_8,
1870
16
      { "High Efficiency Support", "awdl.datastate.extflags.8",
1871
16
        FT_BOOLEAN, 16, NULL, 0x0100, NULL, HFILL
1872
16
      }
1873
16
    },
1874
16
    { &hf_awdl_datastate_extflags_9,
1875
16
      { "Sidekick Hub", "awdl.datastate.extflags.9",
1876
16
        FT_BOOLEAN, 16, NULL, 0x0200, NULL, HFILL
1877
16
      }
1878
16
    },
1879
16
    { &hf_awdl_datastate_extflags_10,
1880
16
      { "Fast Discovery Enabled", "awdl.datastate.extflags.10",
1881
16
        FT_BOOLEAN, 16, NULL, 0x0400, NULL, HFILL
1882
16
      }
1883
16
    },
1884
16
    { &hf_awdl_datastate_extflags_11,
1885
16
      { "WiFi 6E Support", "awdl.datastate.extflags.11",
1886
16
        FT_BOOLEAN, 16, NULL, 0x0800, NULL, HFILL
1887
16
      }
1888
16
    },
1889
16
    { &hf_awdl_datastate_extflags_12,
1890
16
      { "Ultra Low Latency Infra Supported", "awdl.datastate.extflags.12",
1891
16
        FT_BOOLEAN, 16, NULL, 0x1000, NULL, HFILL
1892
16
      }
1893
16
    },
1894
16
    { &hf_awdl_datastate_extflags_13,
1895
16
      { "In Pro Mode", "awdl.datastate.extflags.13",
1896
16
        FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL
1897
16
      }
1898
16
    },
1899
16
    { &hf_awdl_datastate_extflags_14to15,
1900
16
      { "Unknown", "awdl.datastate.extflags.14to15",
1901
16
        FT_UINT16, BASE_HEX_DEC, NULL, 0xc000, NULL, HFILL
1902
16
      }
1903
16
    },
1904
16
    { &hf_awdl_datastate_logtrigger,
1905
16
      { "Logtrigger ID", "awdl.datastate.logtrigger",
1906
16
        FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL
1907
16
      }
1908
16
    },
1909
16
    { &hf_awdl_datastate_rlfc,
1910
16
      { "RLFC", "awdl.datastate.rlfc",
1911
16
        FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL
1912
16
      }
1913
16
    },
1914
16
    { &hf_awdl_datastate_active_time,
1915
16
      { "Active Time", "awdl.datastate.active_time",
1916
16
        FT_UINT32, BASE_DEC, NULL, 0,
1917
16
        "The amount of milliseconds, which have passed since the activation of the peer.", HFILL
1918
16
      }
1919
16
    },
1920
16
    { &hf_awdl_datastate_aw_sequence_counter,
1921
16
      { "AW Sequence Counter", "awdl.datastate.aw_sequence_counter",
1922
16
        FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL
1923
16
      }
1924
16
    },
1925
16
    { &hf_awdl_datastate_update_counter,
1926
16
      { "Update Counter", "awdl.datastate.update_counter",
1927
16
        FT_UINT32, BASE_DEC, NULL, 0,
1928
16
        "Incremented by one on every AF change.", HFILL
1929
16
      }
1930
16
    },
1931
1932
    /* Arpa */
1933
16
    { &hf_awdl_arpa,
1934
16
      { "Arpa", "awdl.arpa",
1935
16
        FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1936
16
      }
1937
16
    },
1938
16
    { &hf_awdl_arpa_name,
1939
16
      { "Host", "awdl.arpa.host",
1940
16
        FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
1941
16
      }
1942
16
    },
1943
16
    { &hf_awdl_arpa_flags,
1944
16
      { "Flags", "awdl.arpa.flags",
1945
16
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL
1946
16
      }
1947
16
    },
1948
16
    { &hf_awdl_arpa_short,
1949
16
      { "Domain (compressed)", "awdl.arpa.domain",
1950
16
        FT_UINT16, BASE_HEX, VALS(awdl_dns_compression), 0, NULL, HFILL
1951
16
      }
1952
16
    },
1953
1954
    /* Synchronization Parameters */
1955
16
    { &hf_awdl_syncparams_awcounter,
1956
16
      { "AW Sequence Number", "awdl.syncparams.awseqcounter",
1957
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
1958
16
      }
1959
16
    },
1960
16
    { &hf_awdl_syncparams_apbeaconalignment,
1961
16
      { "AP Beacon alignment delta", "awdl.syncparams.apbeaconalignment",
1962
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
1963
16
      }
1964
16
    },
1965
16
    { &hf_awdl_syncparams_master,
1966
16
      { "Master Address", "awdl.syncparams.master",
1967
16
        FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL
1968
16
      }
1969
16
    },
1970
16
    { &hf_awdl_syncparams_tx_chan,
1971
16
      { "Next AW Channel", "awdl.syncparams.txchannel",
1972
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
1973
16
      }
1974
16
    },
1975
16
    { &hf_awdl_syncparams_tx_counter,
1976
16
      { "Tx Counter", "awdl.syncparams.txcounter",
1977
16
        FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_ieee80211_tu), 0x0,
1978
16
        "Time until next AW starts", HFILL
1979
16
      }
1980
16
    },
1981
16
    { &hf_awdl_syncparams_master_chan,
1982
16
      { "Master Channel", "awdl.syncparams.masterchan",
1983
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
1984
16
      }
1985
16
    },
1986
16
    { &hf_awdl_syncparams_guard_time,
1987
16
      { "Guard Time", "awdl.syncparams.guardtime",
1988
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
1989
16
      }
1990
16
    },
1991
16
    { &hf_awdl_syncparams_aw_period,
1992
16
      { "Availability Window Period", "awdl.syncparams.awperiod",
1993
16
        FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_ieee80211_tu), 0x0, NULL, HFILL
1994
16
      }
1995
16
    },
1996
16
    { &hf_awdl_syncparams_action_frame_period,
1997
16
      { "Action Frame Period", "awdl.syncparams.afperiod",
1998
16
        FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_ieee80211_tu), 0x0, NULL, HFILL
1999
16
      }
2000
16
    },
2001
16
    { &hf_awdl_syncparams_awdl_flags,
2002
16
      { "AWDL Flags", "awdl.syncparams.awdlflags",
2003
16
        FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
2004
16
      }
2005
16
    },
2006
16
    { &hf_awdl_syncparams_aw_ext_length,
2007
16
      { "Availability Window Extension Length", "awdl.syncparams.aw.ext_len",
2008
16
        FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_ieee80211_tu), 0x0, NULL, HFILL
2009
16
      }
2010
16
    },
2011
16
    { &hf_awdl_syncparams_aw_cmn_length,
2012
16
      { "Availability Window Common Length", "awdl.syncparams.aw.common_len",
2013
16
        FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_ieee80211_tu), 0x0, NULL, HFILL
2014
16
      }
2015
16
    },
2016
16
    { &hf_awdl_syncparams_aw_remaining,
2017
16
      { "Remaining Availability Window Length", "awdl.syncparams.aw.remaining",
2018
16
        FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_ieee80211_tu), 0x0, NULL, HFILL
2019
16
      }
2020
16
    },
2021
16
    { &hf_awdl_syncparams_ext_min,
2022
16
      { "Minimum Extension Count", "awdl.syncparams.ext.min",
2023
16
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
2024
16
      }
2025
16
    },
2026
16
    { &hf_awdl_syncparams_ext_max_multi,
2027
16
      { "Maximum Extension Count for Multicast", "awdl.syncparams.ext.max_multicast",
2028
16
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
2029
16
      }
2030
16
    },
2031
16
    { &hf_awdl_syncparams_ext_max_uni,
2032
16
      { "Maximum Extension Count for Unicast", "awdl.syncparams.ext.max_unicast",
2033
16
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
2034
16
      }
2035
16
    },
2036
16
    { &hf_awdl_syncparams_ext_max_af,
2037
16
      { "Maximum Extension Count for Action Frame", "awdl.syncparams.ext.max_af",
2038
16
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
2039
16
      }
2040
16
    },
2041
16
    { &hf_awdl_syncparams_presence_mode,
2042
16
      { "Presence Mode", "awdl.syncparams.presencemode",
2043
16
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
2044
16
      }
2045
16
    },
2046
2047
    /* Channel Sequence */
2048
16
    { &hf_awdl_channelseq_channel_count,
2049
16
      { "Number of Channels (+1)", "awdl.channelseq.channels",
2050
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2051
16
      }
2052
16
    },
2053
16
    { &hf_awdl_channelseq_enc,
2054
16
      { "Encoding", "awdl.channelseq.encoding",
2055
16
        FT_UINT8, BASE_DEC, VALS(awdl_chanseq_enc), 0x0, NULL, HFILL
2056
16
      }
2057
16
    },
2058
16
    { &hf_awdl_channelseq_duplicate,
2059
16
      { "Duplicate", "awdl.channelseq.duplicate",
2060
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2061
16
      }
2062
16
    },
2063
16
    { &hf_awdl_channelseq_step_count,
2064
16
      { "Step Count (+1)", "awdl.channelseq.step_count",
2065
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2066
16
      }
2067
16
    },
2068
16
    { &hf_awdl_channelseq_fill_chan,
2069
16
      { "Fill Channel", "awdl.channelseq.fill_channel",
2070
16
        FT_UINT16, BASE_HEX, VALS(awdl_chanseq_fill_chan), 0x0, NULL, HFILL
2071
16
      }
2072
16
    },
2073
16
    { &hf_awdl_channelseq_channel_list,
2074
16
      { "Channel List", "awdl.channelseq.channel_list",
2075
16
        FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
2076
16
      }
2077
16
    },
2078
16
    { &hf_awdl_channelseq_channel,
2079
16
      { "Channel", "awdl.channelseq.channel",
2080
16
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
2081
16
      }
2082
16
    },
2083
16
    { &hf_awdl_channelseq_channel_number,
2084
16
      { "Channel Number", "awdl.channelseq.channel.number",
2085
16
        FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL
2086
16
      }
2087
16
    },
2088
16
    { &hf_awdl_channelseq_channel_operating_class,
2089
16
      { "Operating Class", "awdl.channelseq.channel.operating_class",
2090
16
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL
2091
16
      }
2092
16
    },
2093
16
    { &hf_awdl_channelseq_channel_flags,
2094
16
      { "Channel Flags", "awdl.channelseq.channel.flags",
2095
16
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL
2096
16
      }
2097
16
    },
2098
16
    { &hf_awdl_channelseq_legacy_unused,
2099
16
      { "Unused", "awdl.channelseq.channel.unused",
2100
16
        FT_UINT8, BASE_DEC, NULL, 0xc0, NULL, HFILL
2101
16
      }
2102
16
    },
2103
16
    { &hf_awdl_channelseq_legacy_band,
2104
16
      { "Band", "awdl.channelseq.channel.band",
2105
16
        FT_UINT8, BASE_DEC, VALS(awdl_chanseq_band), 0x30, NULL, HFILL
2106
16
      }
2107
16
    },
2108
16
    { &hf_awdl_channelseq_legacy_bandwidth,
2109
16
      { "Bandwidth", "awdl.channelseq.channel.bandwidth",
2110
16
        FT_UINT8, BASE_DEC, VALS(awdl_chanseq_bandwidth), 0x0c, NULL, HFILL
2111
16
      }
2112
16
    },
2113
16
    { &hf_awdl_channelseq_legacy_control_channel,
2114
16
      { "Control Channel", "awdl.channelseq.channel.control_channel",
2115
16
        FT_UINT8, BASE_DEC, VALS(awdl_chanseq_control_channel), 0x03, NULL, HFILL
2116
16
      }
2117
16
    },
2118
2119
    /* Election Parameters */
2120
16
    { &hf_awdl_electionparams_private_master,
2121
16
      { "Private Master Address", "awdl.electionparams.private.master",
2122
16
        FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL
2123
16
      }
2124
16
    },
2125
16
    { &hf_awdl_electionparams_master,
2126
16
      { "Master Address", "awdl.electionparams.master",
2127
16
        FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL
2128
16
      }
2129
16
    },
2130
16
    { &hf_awdl_electionparams_flags,
2131
16
      { "Flags", "awdl.electionparams.flags",
2132
16
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL
2133
16
      }
2134
16
    },
2135
16
    { &hf_awdl_electionparams_id,
2136
16
      { "ID", "awdl.electionparams.id",
2137
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2138
16
      }
2139
16
    },
2140
16
    { &hf_awdl_electionparams_distance,
2141
16
      { "Distance to Master", "awdl.electionparams.distance",
2142
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2143
16
      }
2144
16
    },
2145
16
    { &hf_awdl_electionparams_mastermetric,
2146
16
      { "Master Metric", "awdl.electionparams.mastermetric",
2147
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2148
16
      }
2149
16
    },
2150
16
    { &hf_awdl_electionparams_selfmetric,
2151
16
      { "Self Metric", "awdl.electionparams.selfmetric",
2152
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2153
16
      }
2154
16
    },
2155
16
    { &hf_awdl_electionparams_unknown,
2156
16
      { "Unknown", "awdl.electionparams.unknown",
2157
16
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
2158
16
      }
2159
16
    },
2160
16
    { &hf_awdl_electionparams_private_mastermetric,
2161
16
      { "Private Master Metric", "awdl.electionparams.private.mastermetric",
2162
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2163
16
      }
2164
16
    },
2165
16
    { &hf_awdl_electionparams_private_id,
2166
16
      { "Private ID", "awdl.electionparams.private.id",
2167
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2168
16
      }
2169
16
    },
2170
16
    { &hf_awdl_electionparams_private_phc,
2171
16
      { "PHC", "awdl.electionparams.private.phc",
2172
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2173
16
      }
2174
16
    },
2175
2176
    /* Election Parameter v2 */
2177
16
    { &hf_awdl_electionparams2_master,
2178
16
      { "Master Address", "awdl.electionparams2.master",
2179
16
        FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL
2180
16
      }
2181
16
    },
2182
16
    { &hf_awdl_electionparams2_other,
2183
16
      { "Other Address", "awdl.electionparams2.other",
2184
16
        FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL
2185
16
      }
2186
16
    },
2187
16
    { &hf_awdl_electionparams2_mastermetric,
2188
16
      { "Master Metric", "awdl.electionparams2.mastermetric",
2189
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2190
16
      }
2191
16
    },
2192
16
    { &hf_awdl_electionparams2_selfmetric,
2193
16
      { "Self Metric", "awdl.electionparams2.selfmetric",
2194
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2195
16
      }
2196
16
    },
2197
16
    { &hf_awdl_electionparams2_mastercounter,
2198
16
      { "Master Counter", "awdl.electionparams2.mastercounter",
2199
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2200
16
      }
2201
16
    },
2202
16
    { &hf_awdl_electionparams2_selfcounter,
2203
16
      { "Self Counter", "awdl.electionparams2.selfcounter",
2204
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2205
16
      }
2206
16
    },
2207
16
    { &hf_awdl_electionparams2_distance,
2208
16
      { "Distance to Master", "awdl.electionparams2.disstance",
2209
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2210
16
      }
2211
16
    },
2212
16
    { &hf_awdl_electionparams2_reserved,
2213
16
      { "Reserved", "awdl.electionparams2.reserved",
2214
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2215
16
      }
2216
16
    },
2217
16
    { &hf_awdl_electionparams2_unknown,
2218
16
      { "Unknown", "awdl.electionparams2.unknown",
2219
16
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
2220
16
      }
2221
16
    },
2222
2223
    /* Service Response */
2224
16
    { &hf_awdl_dns_name_len,
2225
16
      { "Name Length", "awdl.dns.name.len",
2226
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
2227
16
        "Includes length of type field", HFILL
2228
16
      }
2229
16
    },
2230
16
    { &hf_awdl_dns_name,
2231
16
      { "Name", "awdl.dns.name",
2232
16
        FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL
2233
16
      }
2234
16
    },
2235
16
    { &hf_awdl_dns_name_label,
2236
16
      { "Label", "awdl.dns.name.label",
2237
16
        FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2238
16
        "Part of a name", HFILL
2239
16
      }
2240
16
    },
2241
16
    { &hf_awdl_dns_name_short,
2242
16
      { "Label (compressed)", "awdl.dns.name.compressed",
2243
16
        FT_UINT16, BASE_HEX, VALS(awdl_dns_compression), 0x0,
2244
16
        "Part of a name", HFILL
2245
16
      }
2246
16
    },
2247
16
    { &hf_awdl_dns_type,
2248
16
      { "Type", "awdl.dns.type",
2249
16
        FT_UINT8, BASE_DEC, VALS(dns_types_vals), 0x0, NULL, HFILL
2250
16
      }
2251
16
    },
2252
16
    { &hf_awdl_dns_data_len,
2253
16
      { "Data Length", "awdl.dns.data_len",
2254
16
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL
2255
16
      }
2256
16
    },
2257
16
    { &hf_awdl_dns_txt,
2258
16
      { "TXT", "awdl.dns.txt",
2259
16
        FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL
2260
16
      }
2261
16
    },
2262
16
    { &hf_awdl_dns_ptr,
2263
16
      { "Domain Name", "awdl.dns.ptr",
2264
16
        FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL
2265
16
      }
2266
16
    },
2267
16
    { &hf_awdl_dns_ptr_label,
2268
16
      { "Label", "awdl.dns.ptr.label",
2269
16
        FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2270
16
        "Part of a domain name", HFILL
2271
16
      }
2272
16
    },
2273
16
    { &hf_awdl_dns_ptr_short,
2274
16
      { "Label (compressed)", "awdl.dns.ptr.short",
2275
16
        FT_UINT16, BASE_HEX, VALS(awdl_dns_compression), 0x0,
2276
16
        "Part of a domain name", HFILL
2277
16
      }
2278
16
    },
2279
16
    { &hf_awdl_dns_target,
2280
16
      { "Target", "awdl.dns.target",
2281
16
        FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL
2282
16
      }
2283
16
    },
2284
16
    { &hf_awdl_dns_target_label,
2285
16
      { "Label", "awdl.dns.target.label",
2286
16
        FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2287
16
        "Part of a target", HFILL
2288
16
      }
2289
16
    },
2290
16
    { &hf_awdl_dns_target_short,
2291
16
      { "Label (compressed)", "awdl.dns.target.compressed",
2292
16
        FT_UINT16, BASE_HEX, VALS(awdl_dns_compression), 0x0,
2293
16
        "Part of a target", HFILL
2294
16
      }
2295
16
    },
2296
16
    { &hf_awdl_dns_unknown,
2297
16
      { "Unknown", "awdl.dns.unknown",
2298
16
        FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL
2299
16
      }
2300
16
    },
2301
16
    { &hf_awdl_dns_priority,
2302
16
      { "Priority", "awdl.dns.priority",
2303
16
        FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL
2304
16
      }
2305
16
    },
2306
16
    { &hf_awdl_dns_weight,
2307
16
      { "Weight", "awdl.dns.weight",
2308
16
        FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL
2309
16
      }
2310
16
    },
2311
16
    { &hf_awdl_dns_port,
2312
16
      { "Port", "awdl.dns.port",
2313
16
        FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL
2314
16
      }
2315
16
    },
2316
2317
    /* Service Parameters */
2318
16
    { &hf_awdl_serviceparams_sui,
2319
16
      { "SUI", "awdl.serviceparams.sui",
2320
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
2321
16
        "Incremented by 1 for every service announcement change (should cause cache flush at receivers)", HFILL
2322
16
      }
2323
16
    },
2324
16
    { &hf_awdl_serviceparams_enc_values,
2325
16
      { "Encoded Values", "awdl.serviceparams.enc_values",
2326
16
        FT_NONE, BASE_NONE, NULL, 0,
2327
16
        "Encodes up to 256 unique 1-byte values. Calculation adds offsets to values.", HFILL
2328
16
      }
2329
16
    },
2330
16
    { &hf_awdl_serviceparams_bitmask,
2331
16
      { "Offsets", "awdl.serviceparams.bitmask",
2332
16
        FT_UINT32, BASE_HEX, NULL, 0x0,
2333
16
        "Offset is 8*i if i-th bit is set", HFILL
2334
16
      }
2335
16
    },
2336
    /* Generate with Python
2337
     * size = 32
2338
     * for i in range(size):
2339
     *   print('{{ &hf_awdl_serviceparams_bitmask_{},'.format(i))
2340
     *   print('  {{ "{}", "awdl.serviceparams.bitmask.{}",'.format(i, i))
2341
     *   print('    FT_BOOLEAN, {}, NULL, {}, NULL, HFILL'.format(size, hex(1 << i)))
2342
     *   print('  }}'.format())
2343
     *   print('}},'.format())
2344
     */
2345
16
    { &hf_awdl_serviceparams_bitmask_0,
2346
16
      { "0", "awdl.serviceparams.bitmask.0",
2347
16
        FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL
2348
16
      }
2349
16
    },
2350
16
    { &hf_awdl_serviceparams_bitmask_1,
2351
16
      { "1", "awdl.serviceparams.bitmask.1",
2352
16
        FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL
2353
16
      }
2354
16
    },
2355
16
    { &hf_awdl_serviceparams_bitmask_2,
2356
16
      { "2", "awdl.serviceparams.bitmask.2",
2357
16
        FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL
2358
16
      }
2359
16
    },
2360
16
    { &hf_awdl_serviceparams_bitmask_3,
2361
16
      { "3", "awdl.serviceparams.bitmask.3",
2362
16
        FT_BOOLEAN, 32, NULL, 0x00000008, NULL, HFILL
2363
16
      }
2364
16
    },
2365
16
    { &hf_awdl_serviceparams_bitmask_4,
2366
16
      { "4", "awdl.serviceparams.bitmask.4",
2367
16
        FT_BOOLEAN, 32, NULL, 0x00000010, NULL, HFILL
2368
16
      }
2369
16
    },
2370
16
    { &hf_awdl_serviceparams_bitmask_5,
2371
16
      { "5", "awdl.serviceparams.bitmask.5",
2372
16
        FT_BOOLEAN, 32, NULL, 0x00000020, NULL, HFILL
2373
16
      }
2374
16
    },
2375
16
    { &hf_awdl_serviceparams_bitmask_6,
2376
16
      { "6", "awdl.serviceparams.bitmask.6",
2377
16
        FT_BOOLEAN, 32, NULL, 0x00000040, NULL, HFILL
2378
16
      }
2379
16
    },
2380
16
    { &hf_awdl_serviceparams_bitmask_7,
2381
16
      { "7", "awdl.serviceparams.bitmask.7",
2382
16
        FT_BOOLEAN, 32, NULL, 0x00000080, NULL, HFILL
2383
16
      }
2384
16
    },
2385
16
    { &hf_awdl_serviceparams_bitmask_8,
2386
16
      { "8", "awdl.serviceparams.bitmask.8",
2387
16
        FT_BOOLEAN, 32, NULL, 0x00000100, NULL, HFILL
2388
16
      }
2389
16
    },
2390
16
    { &hf_awdl_serviceparams_bitmask_9,
2391
16
      { "9", "awdl.serviceparams.bitmask.9",
2392
16
        FT_BOOLEAN, 32, NULL, 0x00000200, NULL, HFILL
2393
16
      }
2394
16
    },
2395
16
    { &hf_awdl_serviceparams_bitmask_10,
2396
16
      { "10", "awdl.serviceparams.bitmask.10",
2397
16
        FT_BOOLEAN, 32, NULL, 0x00000400, NULL, HFILL
2398
16
      }
2399
16
    },
2400
16
    { &hf_awdl_serviceparams_bitmask_11,
2401
16
      { "11", "awdl.serviceparams.bitmask.11",
2402
16
        FT_BOOLEAN, 32, NULL, 0x00000800, NULL, HFILL
2403
16
      }
2404
16
    },
2405
16
    { &hf_awdl_serviceparams_bitmask_12,
2406
16
      { "12", "awdl.serviceparams.bitmask.12",
2407
16
        FT_BOOLEAN, 32, NULL, 0x00001000, NULL, HFILL
2408
16
      }
2409
16
    },
2410
16
    { &hf_awdl_serviceparams_bitmask_13,
2411
16
      { "13", "awdl.serviceparams.bitmask.13",
2412
16
        FT_BOOLEAN, 32, NULL, 0x00002000, NULL, HFILL
2413
16
      }
2414
16
    },
2415
16
    { &hf_awdl_serviceparams_bitmask_14,
2416
16
      { "14", "awdl.serviceparams.bitmask.14",
2417
16
        FT_BOOLEAN, 32, NULL, 0x00004000, NULL, HFILL
2418
16
      }
2419
16
    },
2420
16
    { &hf_awdl_serviceparams_bitmask_15,
2421
16
      { "15", "awdl.serviceparams.bitmask.15",
2422
16
        FT_BOOLEAN, 32, NULL, 0x00008000, NULL, HFILL
2423
16
      }
2424
16
    },
2425
16
    { &hf_awdl_serviceparams_bitmask_16,
2426
16
      { "16", "awdl.serviceparams.bitmask.16",
2427
16
        FT_BOOLEAN, 32, NULL, 0x00010000, NULL, HFILL
2428
16
      }
2429
16
    },
2430
16
    { &hf_awdl_serviceparams_bitmask_17,
2431
16
      { "17", "awdl.serviceparams.bitmask.17",
2432
16
        FT_BOOLEAN, 32, NULL, 0x00020000, NULL, HFILL
2433
16
      }
2434
16
    },
2435
16
    { &hf_awdl_serviceparams_bitmask_18,
2436
16
      { "18", "awdl.serviceparams.bitmask.18",
2437
16
        FT_BOOLEAN, 32, NULL, 0x00040000, NULL, HFILL
2438
16
      }
2439
16
    },
2440
16
    { &hf_awdl_serviceparams_bitmask_19,
2441
16
      { "19", "awdl.serviceparams.bitmask.19",
2442
16
        FT_BOOLEAN, 32, NULL, 0x00080000, NULL, HFILL
2443
16
      }
2444
16
    },
2445
16
    { &hf_awdl_serviceparams_bitmask_20,
2446
16
      { "20", "awdl.serviceparams.bitmask.20",
2447
16
        FT_BOOLEAN, 32, NULL, 0x00100000, NULL, HFILL
2448
16
      }
2449
16
    },
2450
16
    { &hf_awdl_serviceparams_bitmask_21,
2451
16
      { "21", "awdl.serviceparams.bitmask.21",
2452
16
        FT_BOOLEAN, 32, NULL, 0x00200000, NULL, HFILL
2453
16
      }
2454
16
    },
2455
16
    { &hf_awdl_serviceparams_bitmask_22,
2456
16
      { "22", "awdl.serviceparams.bitmask.22",
2457
16
        FT_BOOLEAN, 32, NULL, 0x00400000, NULL, HFILL
2458
16
      }
2459
16
    },
2460
16
    { &hf_awdl_serviceparams_bitmask_23,
2461
16
      { "23", "awdl.serviceparams.bitmask.23",
2462
16
        FT_BOOLEAN, 32, NULL, 0x00800000, NULL, HFILL
2463
16
      }
2464
16
    },
2465
16
    { &hf_awdl_serviceparams_bitmask_24,
2466
16
      { "24", "awdl.serviceparams.bitmask.24",
2467
16
        FT_BOOLEAN, 32, NULL, 0x01000000, NULL, HFILL
2468
16
      }
2469
16
    },
2470
16
    { &hf_awdl_serviceparams_bitmask_25,
2471
16
      { "25", "awdl.serviceparams.bitmask.25",
2472
16
        FT_BOOLEAN, 32, NULL, 0x02000000, NULL, HFILL
2473
16
      }
2474
16
    },
2475
16
    { &hf_awdl_serviceparams_bitmask_26,
2476
16
      { "26", "awdl.serviceparams.bitmask.26",
2477
16
        FT_BOOLEAN, 32, NULL, 0x04000000, NULL, HFILL
2478
16
      }
2479
16
    },
2480
16
    { &hf_awdl_serviceparams_bitmask_27,
2481
16
      { "27", "awdl.serviceparams.bitmask.27",
2482
16
        FT_BOOLEAN, 32, NULL, 0x08000000, NULL, HFILL
2483
16
      }
2484
16
    },
2485
16
    { &hf_awdl_serviceparams_bitmask_28,
2486
16
      { "28", "awdl.serviceparams.bitmask.28",
2487
16
        FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL
2488
16
      }
2489
16
    },
2490
16
    { &hf_awdl_serviceparams_bitmask_29,
2491
16
      { "29", "awdl.serviceparams.bitmask.29",
2492
16
        FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL
2493
16
      }
2494
16
    },
2495
16
    { &hf_awdl_serviceparams_bitmask_30,
2496
16
      { "30", "awdl.serviceparams.bitmask.30",
2497
16
        FT_BOOLEAN, 32, NULL, 0x40000000, NULL, HFILL
2498
16
      }
2499
16
    },
2500
16
    { &hf_awdl_serviceparams_bitmask_31,
2501
16
      { "31", "awdl.serviceparams.bitmask.31",
2502
16
        FT_BOOLEAN, 32, NULL, 0x80000000, NULL, HFILL
2503
16
      }
2504
16
    },
2505
16
    { &hf_awdl_serviceparams_values,
2506
16
      { "Values", "awdl.serviceparams.values",
2507
16
        FT_UINT8, BASE_HEX, NULL, 0,
2508
16
        "Value is i if i-th bit is set", HFILL
2509
16
      }
2510
16
    },
2511
16
    { &hf_awdl_serviceparams_values_0,
2512
16
      { "0", "awdl.serviceparams.values.0",
2513
16
        FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL
2514
16
      }
2515
16
    },
2516
16
    { &hf_awdl_serviceparams_values_1,
2517
16
      { "1", "awdl.serviceparams.values.1",
2518
16
        FT_BOOLEAN, 8, NULL, 0x2, NULL, HFILL
2519
16
      }
2520
16
    },
2521
16
    { &hf_awdl_serviceparams_values_2,
2522
16
      { "2", "awdl.serviceparams.values.2",
2523
16
        FT_BOOLEAN, 8, NULL, 0x4, NULL, HFILL
2524
16
      }
2525
16
    },
2526
16
    { &hf_awdl_serviceparams_values_3,
2527
16
      { "3", "awdl.serviceparams.values.3",
2528
16
        FT_BOOLEAN, 8, NULL, 0x8, NULL, HFILL
2529
16
      }
2530
16
    },
2531
16
    { &hf_awdl_serviceparams_values_4,
2532
16
      { "4", "awdl.serviceparams.values.4",
2533
16
        FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL
2534
16
      }
2535
16
    },
2536
16
    { &hf_awdl_serviceparams_values_5,
2537
16
      { "5", "awdl.serviceparams.values.5",
2538
16
        FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL
2539
16
      }
2540
16
    },
2541
16
    { &hf_awdl_serviceparams_values_6,
2542
16
      { "6", "awdl.serviceparams.values.6",
2543
16
        FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL
2544
16
      }
2545
16
    },
2546
16
    { &hf_awdl_serviceparams_values_7,
2547
16
      { "7", "awdl.serviceparams.values.7",
2548
16
        FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL
2549
16
      }
2550
16
    },
2551
2552
    /* HT Capabilities */
2553
16
    { &hf_awdl_ht_unknown,
2554
16
      { "Unknown", "awdl.ht.unknown",
2555
16
        FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL
2556
16
      }
2557
16
    },
2558
    /* hf_ieee80211_* from packet-ieee80211.c */
2559
16
    { &hf_awdl_ht_cap,
2560
16
      { "HT Capabilities Info", "awdl.ht.capabilities",
2561
16
        FT_UINT16, BASE_HEX, NULL, 0, "HT Capabilities information", HFILL
2562
16
      }
2563
16
    },
2564
16
    { &hf_awdl_ht_ldpc_coding,
2565
16
      { "HT LDPC coding capability", "awdl.ht.capabilities.ldpccoding",
2566
16
        FT_BOOLEAN, 16, TFS(&ht_ldpc_coding_flag), 0x0001, NULL, HFILL
2567
16
      }
2568
16
    },
2569
16
    { &hf_awdl_ht_chan_width,
2570
16
      { "HT Support channel width", "awdl.ht.capabilities.width",
2571
16
        FT_BOOLEAN, 16, TFS(&ht_chan_width_flag), 0x0002, NULL, HFILL
2572
16
      }
2573
16
    },
2574
16
    { &hf_awdl_ht_sm_pwsave,
2575
16
      { "HT SM Power Save", "awdl.ht.capabilities.sm",
2576
16
        FT_UINT16, BASE_HEX, VALS(ht_sm_pwsave_flag), 0x000c, NULL, HFILL
2577
16
      }
2578
16
    },
2579
16
    { &hf_awdl_ht_green,
2580
16
      { "HT Green Field", "awdl.ht.capabilities.green",
2581
16
        FT_BOOLEAN, 16, TFS(&ht_green_flag), 0x0010, NULL, HFILL
2582
16
      }
2583
16
    },
2584
16
    { &hf_awdl_ht_short20,
2585
16
      { "HT Short GI for 20MHz", "awdl.ht.capabilities.short20",
2586
16
        FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0020, NULL, HFILL
2587
16
      }
2588
16
    },
2589
16
    { &hf_awdl_ht_short40,
2590
16
      { "HT Short GI for 40MHz", "awdl.ht.capabilities.short40",
2591
16
        FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0040, NULL, HFILL
2592
16
      }
2593
16
    },
2594
16
    { &hf_awdl_ht_tx_stbc,
2595
16
      { "HT Tx STBC", "awdl.ht.capabilities.txstbc",
2596
16
        FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0080, NULL, HFILL
2597
16
      }
2598
16
    },
2599
16
    { &hf_awdl_ht_rx_stbc,
2600
16
      { "HT Rx STBC", "awdl.ht.capabilities.rxstbc",
2601
16
        FT_UINT16, BASE_HEX, VALS(ht_rx_stbc_flag), 0x0300, "HT Tx STBC", HFILL
2602
16
      }
2603
16
    },
2604
16
    { &hf_awdl_ht_delayed_block_ack,
2605
16
      { "HT Delayed Block ACK", "awdl.ht.capabilities.delayedblockack",
2606
16
        FT_BOOLEAN, 16, TFS(&ht_delayed_block_ack_flag), 0x0400, NULL, HFILL
2607
16
      }
2608
16
    },
2609
16
    { &hf_awdl_ht_max_amsdu,
2610
16
      { "HT Max A-MSDU length", "awdl.ht.capabilities.amsdu",
2611
16
        FT_BOOLEAN, 16, TFS(&ht_max_amsdu_flag), 0x0800, NULL, HFILL
2612
16
      }
2613
16
    },
2614
16
    { &hf_awdl_ht_dss_cck_40,
2615
16
      { "HT DSSS/CCK mode in 40MHz", "awdl.ht.capabilities.dsscck",
2616
16
        FT_BOOLEAN, 16, TFS(&ht_dss_cck_40_flag), 0x1000, "HT DSS/CCK mode in 40MHz", HFILL
2617
16
      }
2618
16
    },
2619
16
    { &hf_awdl_ht_psmp,
2620
16
      { "HT PSMP Support", "awdl.ht.capabilities.psmp",
2621
16
        FT_BOOLEAN, 16, TFS(&ht_psmp_flag), 0x2000, NULL, HFILL
2622
16
      }
2623
16
    },
2624
16
    { &hf_awdl_ht_40_mhz_intolerant,
2625
16
      { "HT Forty MHz Intolerant", "awdl.ht.capabilities.40mhzintolerant",
2626
16
        FT_BOOLEAN, 16, TFS(&ht_40_mhz_intolerant_flag), 0x4000, NULL, HFILL
2627
16
      }
2628
16
    },
2629
16
    { &hf_awdl_ht_l_sig,
2630
16
      { "HT L-SIG TXOP Protection support", "awdl.ht.capabilities.lsig",
2631
16
        FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x8000, NULL, HFILL
2632
16
      }
2633
16
    },
2634
16
    { &hf_awdl_ampduparam,
2635
16
      { "A-MPDU Parameters", "awdl.ht.ampduparam",
2636
16
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL
2637
16
      }
2638
16
    },
2639
16
    { &hf_awdl_ampduparam_mpdu,
2640
16
      { "Maximum Rx A-MPDU Length", "awdl.ht.ampduparam.maxlength",
2641
16
        FT_UINT8, BASE_HEX, 0, 0x03, NULL, HFILL
2642
16
      }
2643
16
    },
2644
16
    { &hf_awdl_ampduparam_mpdu_start_spacing,
2645
16
      { "MPDU Density", "awdl.ht.ampduparam.mpdudensity",
2646
16
        FT_UINT8, BASE_HEX, VALS(ampduparam_mpdu_start_spacing_flags), 0x1c, NULL, HFILL
2647
16
      }
2648
16
    },
2649
16
    { &hf_awdl_ampduparam_reserved,
2650
16
      { "Reserved", "awdl.ht.ampduparam.reserved",
2651
16
        FT_UINT8, BASE_HEX, NULL, 0xE0, NULL, HFILL
2652
16
      }
2653
16
    },
2654
16
    { &hf_awdl_mcsset,
2655
16
      { "Rx Supported Modulation and Coding Scheme Set", "awdl.ht.mcsset",
2656
16
        FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
2657
16
      }
2658
16
    },
2659
16
    { &hf_awdl_mcsset_rx_bitmask,
2660
16
      { "Rx Modulation and Coding Scheme (One bit per modulation)", "awdl.ht.mcsset.rxbitmask",
2661
16
        FT_NONE, BASE_NONE, NULL, 0, "One bit per modulation", HFILL
2662
16
      }
2663
16
    },
2664
16
    { &hf_awdl_mcsset_rx_bitmask_0to7,
2665
16
      { "Rx Bitmask Bits 0-7", "awdl.ht.mcsset.rxbitmask.0to7",
2666
16
        FT_UINT32, BASE_HEX, 0, 0x000000ff, NULL, HFILL
2667
16
      }
2668
16
    },
2669
16
    { &hf_awdl_mcsset_rx_bitmask_8to15,
2670
16
      { "Rx Bitmask Bits 8-15", "awdl.ht.mcsset.rxbitmask.8to15",
2671
16
        FT_UINT32, BASE_HEX, 0, 0x0000ff00, NULL, HFILL
2672
16
      }
2673
16
    },
2674
16
    { &hf_awdl_mcsset_rx_bitmask_16to23,
2675
16
      { "Rx Bitmask Bits 16-23", "awdl.ht.mcsset.rxbitmask.16to23",
2676
16
        FT_UINT32, BASE_HEX, 0, 0x00ff0000, NULL, HFILL
2677
16
      }
2678
16
    },
2679
16
    { &hf_awdl_mcsset_rx_bitmask_24to31,
2680
16
      { "Rx Bitmask Bits 24-31", "awdl.ht.mcsset.rxbitmask.24to31",
2681
16
        FT_UINT32, BASE_HEX, 0, 0xff000000, NULL, HFILL
2682
16
      }
2683
16
    },
2684
16
  };
2685
2686
16
  static hf_register_info hf_apple_awdl_pid[] = {
2687
16
    { &hf_llc_apple_awdl_pid,
2688
16
      { "PID", "llc.apple_awdl_pid",
2689
16
        FT_UINT16, BASE_HEX, VALS(apple_awdl_pid_vals), 0x0, "Protocol ID", HFILL }
2690
16
    }
2691
16
  };
2692
2693
  /* Setup protocol subtree array */
2694
16
  static int *ett[] = {
2695
16
    &ett_awdl_data,
2696
16
    &ett_awdl,
2697
16
    &ett_awdl_fixed_parameters,
2698
16
    &ett_awdl_tagged_parameters,
2699
16
    &ett_awdl_unknown,
2700
16
    &ett_awdl_tag,
2701
16
    &ett_awdl_channelseq_flags,
2702
16
    &ett_awdl_version,
2703
16
    &ett_awdl_dns_record,
2704
16
    &ett_awdl_dns_name,
2705
16
    &ett_awdl_channelseq_channel_list,
2706
16
    &ett_awdl_channelseq_channel,
2707
16
    &ett_awdl_datastate_flags,
2708
16
    &ett_awdl_datastate_social_channel_map,
2709
16
    &ett_awdl_datastate_extflags,
2710
16
    &ett_awdl_ht_capabilities,
2711
16
    &ett_awdl_ht_ampduparam,
2712
16
    &ett_awdl_ht_mcsset_tree,
2713
16
    &ett_awdl_ht_mcsbit_tree,
2714
16
    &ett_awdl_serviceparams_bitmask,
2715
16
    &ett_awdl_serviceparams_values,
2716
16
    &ett_awdl_serviceparams_value,
2717
16
  };
2718
2719
16
  static ei_register_info ei[] = {
2720
16
    { &ei_awdl_tag_length,
2721
16
      { "awdl.tag.length.bad", PI_MALFORMED, PI_ERROR,
2722
16
        "Bad tag length", EXPFILL
2723
16
      }
2724
16
    },
2725
16
    { &ei_awdl_tag_data,
2726
16
      { "awdl.tag.data.undecoded", PI_UNDECODED, PI_NOTE,
2727
16
        "Dissector for AWDL tag code not implemented", EXPFILL
2728
16
      }
2729
16
    },
2730
16
    { &ei_awdl_dns_data_len,
2731
16
      { "awdl.dns.data_len.bad", PI_MALFORMED, PI_ERROR,
2732
16
        "Bad DNS data length", EXPFILL
2733
16
      }
2734
16
    },
2735
16
  };
2736
2737
16
  expert_module_t *expert_awdl;
2738
2739
16
  proto_awdl_data = proto_register_protocol("Apple Wireless Direct Link data frame", "AWDL data", "awdl_data");
2740
16
  awdl_data_handle = register_dissector("awdl_data", dissect_awdl_data, proto_awdl_data);
2741
2742
16
  proto_awdl = proto_register_protocol("Apple Wireless Direct Link action frame", "AWDL", "awdl");
2743
16
  awdl_action_handle = register_dissector("awdl", dissect_awdl_action, proto_awdl);
2744
2745
16
  expert_awdl = expert_register_protocol(proto_awdl);
2746
16
  expert_register_field_array(expert_awdl, ei, array_length(ei));
2747
2748
16
  tagged_field_table = register_dissector_table("awdl.tag.number", "AWDL Tags", proto_awdl, FT_UINT8, BASE_DEC);
2749
16
  awdl_register_tags();
2750
2751
16
  proto_register_field_array(proto_awdl_data, hf, array_length(hf));
2752
16
  proto_register_subtree_array(ett, array_length(ett));
2753
2754
16
  llc_add_oui(OUI_APPLE_AWDL, "llc.apple_awdl_pid", "LLC Apple AWDL OUI PID", hf_apple_awdl_pid, -1);
2755
16
}
2756
2757
16
void proto_reg_handoff_awdl(void) {
2758
16
  dissector_add_uint("wlan.action.vendor_specific", OUI_APPLE_AWDL, awdl_action_handle);
2759
16
  dissector_add_uint("llc.apple_awdl_pid", 0x0800, awdl_data_handle);
2760
2761
16
  ethertype_subdissector_table = find_dissector_table("ethertype");
2762
16
}
2763
2764
/*
2765
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2766
 *
2767
 * Local variables:
2768
 * c-basic-offset: 2
2769
 * tab-width: 8
2770
 * indent-tabs-mode: nil
2771
 * End:
2772
 *
2773
 * vi: set shiftwidth=2 tabstop=8 expandtab:
2774
 * :indentSize=2:tabSize=8:noTabs=true:
2775
 */