Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-wisun.c
Line
Count
Source
1
/* packet-wisun.c
2
 *
3
 * Wi-SUN IE Dissectors for Wireshark
4
 * By Owen Kirby <osk@exegin.com>
5
 * Copyright 2007 Exegin Technologies Limited
6
 * Copyright 2022-2023 Silicon Laboratories Inc.
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 *------------------------------------------------------------
10
 */
11
#include "config.h"
12
#include <epan/packet.h>
13
#include <epan/expert.h>
14
#include <epan/proto_data.h>
15
#include <wsutil/pint.h>
16
#include <epan/reassemble.h>
17
#include <epan/oids.h>
18
#include <epan/oui.h>
19
#include <epan/tfs.h>
20
#include <epan/unit_strings.h>
21
22
#include <wsutil/array.h>
23
#include "packet-ieee802154.h"
24
25
void proto_register_wisun(void);
26
void proto_reg_handoff_wisun(void);
27
28
/* EDFE support */
29
typedef struct {
30
    ieee802154_map_rec initiator;
31
    ieee802154_map_rec target;
32
    uint32_t second_fnum;
33
} edfe_exchange_t;
34
35
// for each exchange, maps both source address and destination address to a
36
// (distinct) tree that uses the frame number of the first exchange frame to
37
// map to the shared edfe_exchange_t
38
static wmem_map_t* edfe_byaddr;
39
40
static dissector_handle_t eapol_handle;  // for the eapol relay
41
42
static dissector_handle_t ieee802154_nofcs_handle;  // for Netricity Segment Control
43
44
static dissector_table_t vhie_dissector_table;
45
static dissector_table_t vpie_dissector_table;
46
47
static reassembly_table netricity_reassembly_table;
48
49
50
/* Wi-SUN Header IE Sub-ID Values. */
51
7
#define WISUN_SUBID_UTT    0x01
52
3
#define WISUN_SUBID_BT     0x02
53
4
#define WISUN_SUBID_FC     0x03
54
0
#define WISUN_SUBID_RSL    0x04
55
#define WISUN_SUBID_MHDS   0x05
56
0
#define WISUN_SUBID_VH     0x06
57
1
#define WISUN_SUBID_N_NFT  0x07
58
1
#define WISUN_SUBID_N_LQI  0x08
59
0
#define WISUN_SUBID_EA     0x09
60
61
/* Wi-SUN Header IE Sub-ID Values for FAN 1.1 */
62
6
#define WISUN_SUBID_LUTT   0x0A
63
0
#define WISUN_SUBID_LBT    0x0B
64
1
#define WISUN_SUBID_NR     0x0C
65
2
#define WISUN_SUBID_LUS    0x0D
66
0
#define WISUN_SUBID_FLUS   0x0E
67
0
#define WISUN_SUBID_LBS    0x0F
68
1
#define WISUN_SUBID_LND    0x10
69
1
#define WISUN_SUBID_LTO    0x11
70
2
#define WISUN_SUBID_PANID  0x12
71
1
#define WISUN_SUBID_RT     0x1D
72
0
#define WISUN_SUBID_LBC    0xC0
73
74
/* Wi-SUN Payload/Nested ID values. */
75
16
#define WISUN_PIE_SUBID_US       0x01
76
17
#define WISUN_PIE_SUBID_BS       0x02
77
5
#define WISUN_PIE_SUBID_VP       0x03
78
10
#define WISUN_PIE_SUBID_PAN      0x04
79
78
#define WISUN_PIE_SUBID_NETNAME  0x05
80
26
#define WISUN_PIE_SUBID_PANVER   0x06
81
1
#define WISUN_PIE_SUBID_GTKHASH  0x07
82
83
/* Wi-SUN Payload IE Sub-ID Values for FAN 1.1 */
84
26
#define WISUN_PIE_SUBID_POM      0x08
85
17
#define WISUN_PIE_SUBID_LCP      0x04
86
14
#define WISUN_PIE_SUBID_LFNVER   0x40
87
12
#define WISUN_PIE_SUBID_LGTKHASH 0x41
88
23
#define WISUN_PIE_SUBID_LBATS    0x09
89
52
#define WISUN_PIE_SUBID_JM       0x0a
90
91
12
#define WISUN_LGTKHASH_LGTK0_INCLUDED_MASK   0x01
92
12
#define WISUN_LGTKHASH_LGTK1_INCLUDED_MASK   0x02
93
12
#define WISUN_LGTKHASH_LGTK2_INCLUDED_MASK   0x04
94
95
64
#define WISUN_CHANNEL_PLAN      0x07
96
56
#define WISUN_CHANNEL_FUNCTION  0x38
97
53
#define WISUN_CHANNEL_EXCLUDE   0xc0
98
99
27
#define WISUN_CHANNEL_PLAN_REGULATORY     0
100
6
#define WISUN_CHANNEL_PLAN_EXPLICIT       1
101
9
#define WISUN_CHANNEL_PLAN_REGULATORY_ID  2
102
13
#define WISUN_CHANNEL_FUNCTION_FIXED      0
103
#define WISUN_CHANNEL_FUNCTION_TR51CF     1
104
#define WISUN_CHANNEL_FUNCTION_DH1CF      2
105
4
#define WISUN_CHANNEL_FUNCTION_VENDOR     3
106
#define WISUN_CHANNEL_EXCLUDE_NONE        0
107
4
#define WISUN_CHANNEL_EXCLUDE_RANGE       1
108
15
#define WISUN_CHANNEL_EXCLUDE_MASK        2
109
110
14
#define WISUN_CH_PLAN_EXPLICIT_FREQ     0x00ffffff
111
14
#define WISUN_CH_PLAN_EXPLICIT_RESERVED 0xf0000000
112
14
#define WISUN_CH_PLAN_EXPLICIT_SPACING  0x0f000000
113
114
14
#define WISUN_EAPOL_RELAY_UDP_PORT 10253
115
116
#define WISUN_WSIE_NODE_ROLE_ID_FFN_BR          0x00
117
#define WISUN_WSIE_NODE_ROLE_ID_FFN             0x01
118
1
#define WISUN_WSIE_NODE_ROLE_ID_LFN             0x02
119
16
#define WISUN_WSIE_NODE_ROLE_ID_MASK            0x07
120
14
#define WISUN_WSIE_NODE_ROLE_ID_RESERVED        0x78
121
15
#define WISUN_WSIE_NODE_ROLE_LBATS_IMPLEMENTED  0x80
122
123
82
#define WISUN_PIE_PHY_OPERATING_MODES_MASK   0x0F
124
171
#define WISUN_PIE_PHY_TYPE                   0xF0
125
126
80
#define WISUN_PIE_JM_ID_PLF      1
127
3.48k
#define WISUN_PIE_JM_ID_MASK  0x3f
128
3.48k
#define WISUN_PIE_JM_LEN_MASK 0xc0
129
130
0
#define WISUN_CMD_MDR 0x03
131
132
static int proto_wisun;
133
static int hf_wisun_subid;
134
static int hf_wisun_unknown_ie;
135
static int hf_wisun_uttie;
136
static int hf_wisun_uttie_type;
137
static int hf_wisun_uttie_ufsi;
138
static int hf_wisun_btie;
139
static int hf_wisun_btie_slot;
140
static int hf_wisun_btie_bio;
141
static int hf_wisun_fcie;
142
static int hf_wisun_fcie_tx;
143
static int hf_wisun_fcie_rx;
144
static int hf_wisun_fcie_src;
145
static int hf_wisun_fcie_initial_frame;
146
static int hf_wisun_rslie;
147
static int hf_wisun_rslie_rsl;
148
static int hf_wisun_vhie;
149
static int hf_wisun_vhie_vid;
150
static int hf_wisun_eaie;
151
static int hf_wisun_eaie_eui;
152
153
// LFN (FAN 1.1)
154
static int hf_wisun_luttie;
155
static int hf_wisun_luttie_usn;
156
static int hf_wisun_luttie_uio;
157
static int hf_wisun_lbtie;
158
static int hf_wisun_lbtie_slot;
159
static int hf_wisun_lbtie_bio;
160
static int hf_wisun_nrie;
161
static int hf_wisun_nrie_nr_id;
162
static int hf_wisun_nrie_reserved_bits;
163
static int hf_wisun_nrie_lbats;
164
static int hf_wisun_nrie_timing_accuracy;
165
static int hf_wisun_nrie_listening_interval_min;
166
static int hf_wisun_nrie_listening_interval_max;
167
static int hf_wisun_lusie;
168
static int hf_wisun_lusie_listen_interval;
169
static int hf_wisun_lusie_channel_plan_tag;
170
static int hf_wisun_flusie;
171
static int hf_wisun_flusie_dwell_interval;
172
static int hf_wisun_flusie_channel_plan_tag;
173
static int hf_wisun_lbsie;
174
static int hf_wisun_lbsie_broadcast_interval;
175
static int hf_wisun_lbsie_broadcast_id;
176
static int hf_wisun_lbsie_channel_plan_tag;
177
static int hf_wisun_lbsie_broadcast_sync_period;
178
static int hf_wisun_lndie;
179
static int hf_wisun_lndie_response_threshold;
180
static int hf_wisun_lndie_response_delay;
181
static int hf_wisun_lndie_discovery_slot_time;
182
static int hf_wisun_lndie_discovery_slots;
183
static int hf_wisun_lndie_discovery_first_slot;
184
static int hf_wisun_ltoie;
185
static int hf_wisun_ltoie_offset;
186
static int hf_wisun_ltoie_listening_interval;
187
static int hf_wisun_panidie;
188
static int hf_wisun_panidie_panid;
189
static int hf_wisun_rtie;
190
static int hf_wisun_rtie_rendezvous_time;
191
static int hf_wisun_rtie_wakeup_interval;
192
static int hf_wisun_lbcie;
193
static int hf_wisun_lbcie_broadcast_interval;
194
static int hf_wisun_lbcie_broadcast_sync_period;
195
196
static int hf_wisun_pie;
197
static int hf_wisun_wsie;
198
static int hf_wisun_wsie_type;
199
static int hf_wisun_wsie_id;
200
static int hf_wisun_wsie_length;
201
static int hf_wisun_wsie_id_short;
202
static int hf_wisun_wsie_length_short;
203
static int hf_wisun_usie;
204
static int hf_wisun_usie_dwell_interval;
205
static int hf_wisun_usie_clock_drift;
206
static int hf_wisun_usie_timing_accuracy;
207
static int hf_wisun_usie_channel_control;
208
static int hf_wisun_usie_channel_plan;
209
static int hf_wisun_usie_channel_function;
210
static int hf_wisun_usie_channel_exclude;
211
static int hf_wisun_usie_regulatory_domain;
212
static int hf_wisun_usie_operating_class;
213
static int hf_wisun_usie_channel_plan_id;
214
static int hf_wisun_usie_explicit;
215
static int hf_wisun_usie_explicit_frequency;
216
static int hf_wisun_usie_explicit_reserved;
217
static int hf_wisun_usie_explicit_spacing;
218
static int hf_wisun_usie_number_channels;
219
static int hf_wisun_usie_fixed_channel;
220
static int hf_wisun_usie_hop_count;
221
static int hf_wisun_usie_hop_list;
222
static int hf_wisun_usie_number_ranges;
223
static int hf_wisun_usie_exclude_range_start;
224
static int hf_wisun_usie_exclude_range_end;
225
static int hf_wisun_usie_exclude_mask;
226
static int hf_wisun_bsie;
227
static int hf_wisun_bsie_bcast_interval;
228
static int hf_wisun_bsie_bcast_schedule_id;
229
static int hf_wisun_vpie;
230
static int hf_wisun_vpie_vid;
231
static int hf_wisun_lcpie;
232
static int hf_wisun_lcpie_channel_plan_tag;
233
static int hf_wisun_panie;
234
static int hf_wisun_panie_size;
235
static int hf_wisun_panie_cost;
236
static int hf_wisun_panie_flags;
237
static int hf_wisun_panie_flag_parent_bsie;
238
static int hf_wisun_panie_flag_routing_method;
239
static int hf_wisun_panie_flag_lfn_window_style;
240
static int hf_wisun_panie_flag_version;
241
static int hf_wisun_netnameie;
242
static int hf_wisun_netnameie_name;
243
static int hf_wisun_panverie;
244
static int hf_wisun_panverie_version;
245
static int hf_wisun_gtkhashie;
246
static int hf_wisun_gtkhashie_gtk0;
247
static int hf_wisun_gtkhashie_gtk1;
248
static int hf_wisun_gtkhashie_gtk2;
249
static int hf_wisun_gtkhashie_gtk3;
250
static int hf_wisun_pomie;
251
static int hf_wisun_pomie_hdr;
252
static int hf_wisun_pomie_number_operating_modes;
253
static int hf_wisun_pomie_mdr_command_capable_flag;
254
static int hf_wisun_pomie_reserved;
255
static int hf_wisun_pomie_phy_mode_id;
256
static int hf_wisun_pomie_phy_type;
257
static int hf_wisun_pomie_phy_mode_fsk;
258
static int hf_wisun_pomie_phy_mode_ofdm;
259
static int hf_wisun_lfnverie;
260
static int hf_wisun_lfnverie_version;
261
static int hf_wisun_lgtkhashie;
262
static int hf_wisun_lgtkhashie_flags;
263
static int hf_wisun_lgtkhashie_flag_includes_lgtk0;
264
static int hf_wisun_lgtkhashie_flag_includes_lgtk1;
265
static int hf_wisun_lgtkhashie_flag_includes_lgtk2;
266
static int hf_wisun_lgtkhashie_flag_active_lgtk_index;
267
static int hf_wisun_lgtkhashie_gtk0;
268
static int hf_wisun_lgtkhashie_gtk1;
269
static int hf_wisun_lgtkhashie_gtk2;
270
static int hf_wisun_lbatsie;
271
static int hf_wisun_lbatsie_additional_tx;
272
static int hf_wisun_lbatsie_next_tx_delay;
273
static int hf_wisun_jmie;
274
static int hf_wisun_jmie_version;
275
static int hf_wisun_jmie_metric_hdr;
276
static int hf_wisun_jmie_metric_id;
277
static int hf_wisun_jmie_metric_len;
278
static int hf_wisun_jmie_metric_plf;
279
static int hf_wisun_jmie_metric_plf_data;
280
static int hf_wisun_jmie_metric_unknown;
281
282
static int proto_wisun_sec;
283
static int hf_wisun_sec_function;
284
static int hf_wisun_sec_error_type;
285
static int hf_wisun_sec_error_nonce;
286
287
// EAPOL Relay
288
static dissector_handle_t wisun_eapol_relay_handle;
289
static int proto_wisun_eapol_relay;
290
static int hf_wisun_eapol_relay_sup;
291
static int hf_wisun_eapol_relay_kmp_id;
292
static int hf_wisun_eapol_relay_direction;
293
294
static int hf_wisun_cmd_subid;
295
static int hf_wisun_cmd_mdr_phy_mode_id;
296
static int hf_wisun_cmd_mdr_phy_type;
297
static int hf_wisun_cmd_mdr_phy_mode_fsk;
298
static int hf_wisun_cmd_mdr_phy_mode_ofdm;
299
300
// Netricity
301
static int proto_wisun_netricity_sc;
302
static int hf_wisun_netricity_nftie;
303
static int hf_wisun_netricity_nftie_type;
304
static int hf_wisun_netricity_lqiie;
305
static int hf_wisun_netricity_lqiie_lqi;
306
static int hf_wisun_netricity_sc_flags;
307
static int hf_wisun_netricity_sc_reserved;
308
static int hf_wisun_netricity_sc_tone_map_request;
309
static int hf_wisun_netricity_sc_contention_control;
310
static int hf_wisun_netricity_sc_channel_access_priority;
311
static int hf_wisun_netricity_sc_last_segment;
312
static int hf_wisun_netricity_sc_segment_count;
313
static int hf_wisun_netricity_sc_segment_length;
314
// Reassembly
315
static int hf_wisun_netricity_scr_segments;
316
static int hf_wisun_netricity_scr_segment;
317
static int hf_wisun_netricity_scr_segment_overlap;
318
static int hf_wisun_netricity_scr_segment_overlap_conflicts;
319
static int hf_wisun_netricity_scr_segment_multiple_tails;
320
static int hf_wisun_netricity_scr_segment_too_long_segment;
321
static int hf_wisun_netricity_scr_segment_error;
322
static int hf_wisun_netricity_scr_segment_count;
323
static int hf_wisun_netricity_scr_reassembled_in;
324
static int hf_wisun_netricity_scr_reassembled_length;
325
326
static int ett_wisun_phy_mode_id;
327
static int ett_wisun_unknown_ie;
328
static int ett_wisun_uttie;
329
static int ett_wisun_btie;
330
static int ett_wisun_fcie;
331
static int ett_wisun_rslie;
332
static int ett_wisun_vhie;
333
static int ett_wisun_eaie;
334
static int ett_wisun_pie;
335
static int ett_wisun_wsie_bitmap;
336
static int ett_wisun_usie;
337
static int ett_wisun_bsie;
338
static int ett_wisun_vpie;
339
static int ett_wisun_lcpie;
340
static int ett_wisun_usie_channel_control;
341
static int ett_wisun_usie_explicit;
342
static int ett_wisun_luttie;
343
static int ett_wisun_nrie;
344
static int ett_wisun_lusie;
345
static int ett_wisun_flusie;
346
static int ett_wisun_lbsie;
347
static int ett_wisun_lndie;
348
static int ett_wisun_ltoie;
349
static int ett_wisun_panidie;
350
static int ett_wisun_rtie;
351
static int ett_wisun_lbcie;
352
static int ett_wisun_panie;
353
static int ett_wisun_panie_flags;
354
static int ett_wisun_netnameie;
355
static int ett_wisun_panverie;
356
static int ett_wisun_gtkhashie;
357
static int ett_wisun_pomie;
358
static int ett_wisun_pomie_hdr;
359
static int ett_wisun_lfnverie;
360
static int ett_wisun_lgtkhashie;
361
static int ett_wisun_lgtkhashie_flags;
362
static int ett_wisun_lbatsie;
363
static int ett_wisun_jmie;
364
static int ett_wisun_jmie_metric_hdr;
365
static int ett_wisun_jmie_metric_plf;
366
static int ett_wisun_jmie_metric_unknown;
367
static int ett_wisun_sec;
368
static int ett_wisun_eapol_relay;
369
// Netricity
370
static int ett_wisun_netricity_nftie;
371
static int ett_wisun_netricity_lqiie;
372
static int ett_wisun_netricity_sc;
373
static int ett_wisun_netricity_sc_bitmask;
374
static int ett_wisun_netricity_scr_segment;
375
static int ett_wisun_netricity_scr_segments;
376
377
/* Cached protocol identifier */
378
static int proto_ieee802154;
379
380
static const fragment_items netricity_scr_frag_items = {
381
        /* Fragment subtrees */
382
        &ett_wisun_netricity_scr_segment,
383
        &ett_wisun_netricity_scr_segments,
384
385
        /* Fragment fields */
386
        &hf_wisun_netricity_scr_segments,
387
        &hf_wisun_netricity_scr_segment,
388
        &hf_wisun_netricity_scr_segment_overlap,
389
        &hf_wisun_netricity_scr_segment_overlap_conflicts,
390
        &hf_wisun_netricity_scr_segment_multiple_tails,
391
        &hf_wisun_netricity_scr_segment_too_long_segment,
392
        &hf_wisun_netricity_scr_segment_error,
393
        &hf_wisun_netricity_scr_segment_count,
394
395
        /* Reassembled in field */
396
        &hf_wisun_netricity_scr_reassembled_in,
397
398
        /* Reassembled length field */
399
        &hf_wisun_netricity_scr_reassembled_length,
400
        /* Reassembled data field */
401
        NULL,
402
403
        /* Tag */
404
        "Netricity Segments"
405
};
406
407
static const value_string wisun_wsie_types[] = {
408
    { 0, "Short" },
409
    { 1, "Long" },
410
    { 0, NULL }
411
};
412
413
static const value_string wisun_subid_vals[] = {
414
    { WISUN_SUBID_UTT,      "Unicast Timing IE" },
415
    { WISUN_SUBID_BT,       "Broadcast Timing IE" },
416
    { WISUN_SUBID_FC,       "Flow Control IE" },
417
    { WISUN_SUBID_RSL,      "Received Signal Level IE" },
418
    { WISUN_SUBID_MHDS,     "Multi-Hop Delivery Service IE" },
419
    { WISUN_SUBID_VH,       "Vendor Header IE" },
420
    { WISUN_SUBID_N_NFT,    "Netricity Frame Type IE" },
421
    { WISUN_SUBID_N_LQI,    "Link Quality Index IE" },
422
    { WISUN_SUBID_EA,       "EAPOL Authenticator EUI-64 IE" },
423
    { WISUN_SUBID_LUTT,     "LFN Unicast Timing and Frame Type IE" },
424
    { WISUN_SUBID_LBT,      "LFN Broadcast Timing IE" },
425
    { WISUN_SUBID_NR,       "Node Role IE" },
426
    { WISUN_SUBID_LUS,      "LFN Unicast Schedule IE" },
427
    { WISUN_SUBID_FLUS,     "FFN for LFN Unicast Schedule IE" },
428
    { WISUN_SUBID_LBS,      "LFN Broadcast Schedule IE" },
429
    { WISUN_SUBID_LND,      "LFN Network Discovery IE" },
430
    { WISUN_SUBID_LTO,      "LFN Timing Offset IE" },
431
    { WISUN_SUBID_PANID,    "PAN Identifier IE" },
432
    { WISUN_SUBID_RT,       "Rendezvous Time IE" },
433
    { WISUN_SUBID_LBC,      "LFN Broadcast Configuration IE" },
434
    { 0, NULL }
435
};
436
437
static const value_string wisun_wsie_names[] = {
438
    { WISUN_PIE_SUBID_US,        "Unicast Schedule IE" },
439
    { WISUN_PIE_SUBID_BS,        "Broadcast Schedule IE" },
440
    { WISUN_PIE_SUBID_VP,        "Vendor Payload IE" },
441
    { WISUN_PIE_SUBID_LCP,       "LFN Channel Plan IE" },
442
    { 0, NULL }
443
};
444
445
static const value_string wisun_wsie_names_short[] = {
446
    { WISUN_PIE_SUBID_PAN,       "PAN Information IE" },
447
    { WISUN_PIE_SUBID_NETNAME,   "Network Name IE" },
448
    { WISUN_PIE_SUBID_PANVER,    "PAN Version IE" },
449
    { WISUN_PIE_SUBID_GTKHASH,   "GTK Hash IE" },
450
    { WISUN_PIE_SUBID_POM,       "PHY Operating Modes IE" },
451
    { WISUN_PIE_SUBID_LFNVER,    "LFN Version IE" },
452
    { WISUN_PIE_SUBID_LGTKHASH,  "LFN GTK Hash IE" },
453
    { WISUN_PIE_SUBID_LBATS,     "LFN Broadcast Additional Transmit Schedule IE" },
454
    { WISUN_PIE_SUBID_JM,        "Join Metrics IE" },
455
    { 0, NULL }
456
};
457
458
static const value_string wisun_frame_type_vals[] = {
459
    { 0,  "PAN Advertisement" },
460
    { 1,  "PAN Advertisement Solicit" },
461
    { 2,  "PAN Configuration" },
462
    { 3,  "PAN Configuration Solicit" },
463
    { 4,  "Data" },
464
    { 5,  "Acknowledgment" },
465
    { 6,  "EAPOL" },
466
    { 7,  "Reserved" },
467
    { 8,  "Reserved" },
468
    { 9,  "LFN PAN Advertisement" },
469
    { 10, "LFN PAN Advertisement Solicit" },
470
    { 11, "LFN PAN Configuration" },
471
    { 12, "LFN PAN Configuration Solicit" },
472
    { 13, "LFN Time Synchronization" },
473
    { 14, "Reserved" },
474
    { 15, "Reserved (Extended Type)" },
475
    { 0, NULL }
476
};
477
478
static const value_string wisun_usie_clock_drift_names[] = {
479
    { 0,   "Better than 1ppm" },
480
    { 255, "Not provided" },
481
    { 0, NULL }
482
};
483
484
static const value_string wisun_channel_plan_names[] = {
485
    { WISUN_CHANNEL_PLAN_REGULATORY,    "Regulatory Domain and Operating Class" },
486
    { WISUN_CHANNEL_PLAN_EXPLICIT,      "Explicit Spacing and Number" },
487
    { WISUN_CHANNEL_PLAN_REGULATORY_ID, "Regulatory Domain and Channel Plan ID" },
488
    { 0, NULL }
489
};
490
491
static const range_string wisun_channel_plan_id_names[] = {
492
    {  0,  0,    "Reserved" },
493
    {  1,  1,    "902_928_200" },
494
    {  2,  2,    "902_928_400" },
495
    {  3,  3,    "902_928_600" },
496
    {  4,  4,    "902_928_800" },
497
    {  5,  5,    "902_928_1200" },
498
    {  6, 20,    "Reserved" },
499
    { 21, 21,    "920_928_200" },
500
    { 22, 22,    "920_928_400" },
501
    { 23, 23,    "920_928_600" },
502
    { 24, 24,    "920_928_800" },
503
    { 25, 31,    "Reserved" },
504
    { 32, 32,    "863_870_100" },
505
    { 33, 33,    "863_870_200" },
506
    { 34, 34,    "870_876_100" },
507
    { 35, 35,    "870_876_200" },
508
    { 36, 36,    "863_876_100" },
509
    { 37, 37,    "863_876_200" },
510
    { 38, 63,    "Reserved" },
511
    { 0, 0, NULL }
512
};
513
514
static const value_string wisun_channel_function_names[] = {
515
    { WISUN_CHANNEL_FUNCTION_FIXED,     "Fixed Channel" },
516
    { WISUN_CHANNEL_FUNCTION_TR51CF,    "TR51 Channel Function" },
517
    { WISUN_CHANNEL_FUNCTION_DH1CF,     "Direct Hash Channel Function" },
518
    { WISUN_CHANNEL_FUNCTION_VENDOR,    "Vendor Defined Channel Function" },
519
    { 0, NULL }
520
};
521
522
static const value_string wisun_channel_exclude_names[] = {
523
    { WISUN_CHANNEL_EXCLUDE_NONE,       "None" },
524
    { WISUN_CHANNEL_EXCLUDE_RANGE,      "Ranges" },
525
    { WISUN_CHANNEL_EXCLUDE_MASK,       "Bitmask" },
526
    { 0, NULL }
527
};
528
529
static const value_string wisun_channel_regulatory_domains_names[] = {
530
    {  0, "World"          },
531
    {  1, "North America"  },
532
    {  2, "Japan"          },
533
    {  3, "Europe"         },
534
    {  4, "China"          },
535
    {  5, "India"          },
536
    {  6, "Mexico"         },
537
    {  7, "Brazil"         },
538
    {  8, "Australia / NZ" },
539
    {  9, "Korea"          },
540
    { 10, "Philippines"    },
541
    { 11, "Malaysia"       },
542
    { 12, "Hong Kong"      },
543
    { 13, "Singapore"      },
544
    { 14, "Thailand"       },
545
    { 15, "Vietnam"        },
546
    {  0, NULL             }
547
};
548
549
static const value_string wisun_channel_spacing_names[] = {
550
    { 0, "200 kHz" },
551
    { 1, "400 kHz" },
552
    { 2, "600 kHz" },
553
    { 3, "100 kHz" },
554
    { 4, "800 kHz" },
555
    { 5, "1000 kHz" },
556
    { 6, "1200 kHz" },
557
    { 7, "2400 kHz" },
558
    { 0, NULL }
559
};
560
561
static const value_string wisun_routing_methods[] = {
562
    { 0, "MHDS" },
563
    { 1, "RPL" },
564
    { 0, NULL }
565
};
566
567
static const value_string wisun_window_style[] = {
568
    { 0, "LFN Managed Transmission" },
569
    { 1, "FFN Managed Transmission" },
570
    { 0, NULL }
571
};
572
573
static const value_string wisun_metric_id[] = {
574
    { WISUN_PIE_JM_ID_PLF, "PAN Load Factor" },
575
    { 0, NULL }
576
};
577
578
static const value_string wisun_metric_len[] = {
579
    { 0, "0" },
580
    { 1, "1" },
581
    { 2, "2" },
582
    { 3, "4" },
583
    { 0, NULL }
584
};
585
586
static const value_string wisun_sec_functions[] = {
587
    { 0x01, "SM Error" },
588
    { 0, NULL }
589
};
590
591
static const value_string wisun_sec_sm_errors[] = {
592
    { 0x01, "No Session" },
593
    { 0x02, "Unavailable Key" },
594
    { 0x03, "Unsupported Security" },
595
    { 0x04, "Invalid Parameter" },
596
    { 0x06, "Unsupported Security" },
597
    { 0, NULL }
598
};
599
600
static const value_string wisun_wsie_node_role_vals[] = {
601
    { 0, "FFN Border Router" },
602
    { 1, "FFN Router" },
603
    { 2, "LFN" },
604
    { 3, "Reserved" },
605
    { 4, "Reserved" },
606
    { 5, "Reserved" },
607
    { 6, "Reserved" },
608
    { 7, "Reserved" },
609
    { 0, NULL }
610
};
611
612
static const value_string wisun_phy_type_vals[] = {
613
    { 0, "FSK without FEC" },
614
    { 1, "FSK with NRNSC FEC" },
615
    { 2, "OFDM Option1" },
616
    { 3, "OFDM Option2" },
617
    { 4, "OFDM Option3" },
618
    { 5, "OFDM Option4" },
619
    { 0, NULL }
620
};
621
622
static const range_string wisun_phy_mode_fsk_vals[] = {
623
    { 0,  0, "Reserved"     },
624
    { 1,  1, "FSK Mode 1a"  },
625
    { 2,  2, "FSK Mode 1b"  },
626
    { 3,  3, "FSK Mode 2a"  },
627
    { 4,  4, "FSK Mode 2b"  },
628
    { 5,  5, "FSK Mode 3"   },
629
    { 6,  6, "FSK Mode 4a"  },
630
    { 7,  7, "FSK Mode 4b"  },
631
    { 8,  8, "FSK Mode 5"   },
632
    { 9, 15, "Reserved"     },
633
    { 0,  0, NULL }
634
};
635
636
static const range_string wisun_phy_mode_ofdm_vals[] = {
637
    { 0,  0, "MCS0"         },
638
    { 1,  1, "MCS1"         },
639
    { 2,  2, "MCS2"         },
640
    { 3,  3, "MCS3"         },
641
    { 4,  4, "MCS4"         },
642
    { 5,  5, "MCS5"         },
643
    { 6,  6, "MCS6"         },
644
    { 7, 15, "Reserved"     },
645
    { 0,  0, NULL }
646
};
647
648
static const value_string wisun_cmd_vals[] = {
649
    { 3, "MDR Command" },
650
    { 0, NULL }
651
};
652
653
static const true_false_string wisun_netricity_sc_contention_control_tfs = {
654
    "Contention-free access",
655
    "Contention allowed in next contention state"
656
};
657
658
static int * const wisun_format_nested_ie[] = {
659
    &hf_wisun_wsie_type,
660
    &hf_wisun_wsie_id,
661
    &hf_wisun_wsie_length,
662
    NULL
663
};
664
665
static int * const wisun_format_nested_ie_short[] = {
666
    &hf_wisun_wsie_type,
667
    &hf_wisun_wsie_id_short,
668
    &hf_wisun_wsie_length_short,
669
    NULL
670
};
671
672
static expert_field ei_wisun_subid_unsupported;
673
static expert_field ei_wisun_wsie_unsupported;
674
static expert_field ei_wisun_usie_channel_plan_invalid;
675
static expert_field ei_wisun_edfe_start_not_found;
676
static expert_field ei_wisun_usie_explicit_reserved_bits_not_zero;
677
static expert_field ei_wisun_nrie_reserved_bits_not_zero;
678
static expert_field ei_wisun_jmie_metric_unsupported;
679
680
static unsigned
681
wisun_add_wbxml_uint(tvbuff_t *tvb, proto_tree *tree, int hf, unsigned offset)
682
5
{
683
5
    unsigned val = 0;
684
5
    unsigned len = 0;
685
5
    uint8_t b;
686
7
    do {
687
7
        b = tvb_get_uint8(tvb, offset + len++);
688
7
        val = (val << 7) | (b & 0x7f);
689
7
    } while (b & 0x80 && len < 2);
690
5
    proto_tree_add_uint(tree, hf, tvb, offset, len, val);
691
5
    return val;
692
5
}
693
694
static unsigned
695
wisun_vidlen(unsigned vid)
696
10
{
697
10
    return vid > 0x7f ? 2 : 1;
698
10
}
699
700
static void
701
wisun_add_phy_mode_id(tvbuff_t *tvb, proto_tree *tree,
702
                      const unsigned offset, const int hf, int *const hf_type,
703
                      int *const hf_fsk, int *const hf_ofdm)
704
143
{
705
143
    uint8_t phy_type = (tvb_get_uint8(tvb, offset) & WISUN_PIE_PHY_TYPE) >> 4;
706
143
    int *const wisun_phy_mode_fsk_fields[] = {
707
143
        hf_type,
708
143
        hf_fsk,
709
143
        NULL
710
143
    };
711
143
    int *const wisun_phy_mode_ofdm_fields[] = {
712
143
        hf_type,
713
143
        hf_ofdm,
714
143
        NULL
715
143
    };
716
717
143
    if (phy_type < 2) {
718
        // 0 and 1 are FSK modes
719
72
        proto_tree_add_bitmask(tree, tvb, offset, hf, ett_wisun_phy_mode_id, wisun_phy_mode_fsk_fields, ENC_NA);
720
72
    } else {
721
        // The rest are OFDM modes
722
71
        proto_tree_add_bitmask(tree, tvb, offset, hf, ett_wisun_phy_mode_id, wisun_phy_mode_ofdm_fields, ENC_NA);
723
71
    }
724
143
}
725
726
727
/*-----------------------------------------------
728
 * Wi-SUN Header IE Dissection
729
 *---------------------------------------------*/
730
static proto_tree *
731
wisun_create_hie_tree(tvbuff_t *tvb, proto_tree *tree, int hf, int ett)
732
101
{
733
101
    proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf, ett);
734
101
    proto_tree_add_item(subtree, hf_wisun_subid, tvb, 2, 1, ENC_LITTLE_ENDIAN);
735
101
    return subtree;
736
101
}
737
738
static int
739
dissect_wisun_uttie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
740
7
{
741
7
    const char *str = col_get_text(pinfo->cinfo, COL_INFO);
742
7
    uint8_t frame_type = tvb_get_uint8(tvb, offset);
743
7
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Wi-SUN");
744
7
    if (str && strncmp(str, "EDFE", 4))
745
0
        col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(frame_type, wisun_frame_type_vals, "Unknown Wi-SUN Frame"));
746
7
    proto_tree_add_item(tree, hf_wisun_uttie_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
747
7
    proto_tree_add_item(tree, hf_wisun_uttie_ufsi, tvb, offset+1, 3, ENC_LITTLE_ENDIAN);
748
7
    return 4;
749
7
}
750
751
static int
752
dissect_wisun_btie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
753
3
{
754
3
    proto_tree_add_item(tree, hf_wisun_btie_slot, tvb, offset, 2, ENC_LITTLE_ENDIAN);
755
    /* as of FAN TPS 1v14, this is 3 bytes instead of 4 */
756
3
    proto_tree_add_item(tree, hf_wisun_btie_bio, tvb, offset+2, 3, ENC_LITTLE_ENDIAN);
757
3
    return 5;
758
3
}
759
760
static void
761
edfe_insert_exchange(uint64_t* addr, edfe_exchange_t* exchange)
762
2
{
763
2
    wmem_tree_t* byframe = (wmem_tree_t *)wmem_map_lookup(edfe_byaddr, addr);
764
2
    if (!byframe) {
765
2
        byframe = wmem_tree_new(wmem_file_scope());
766
2
        wmem_map_insert(edfe_byaddr, addr, byframe);
767
2
    }
768
2
    wmem_tree_insert32(byframe, exchange->initiator.start_fnum, exchange);
769
2
}
770
771
static int
772
dissect_wisun_fcie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, ieee802154_packet *packet)
773
4
{
774
4
    uint32_t tx;
775
4
    proto_tree_add_item_ret_uint(tree, hf_wisun_fcie_tx, tvb, offset, 1, ENC_LITTLE_ENDIAN, &tx);
776
4
    uint32_t rx;
777
4
    proto_tree_add_item_ret_uint(tree, hf_wisun_fcie_rx, tvb, offset+1, 1, ENC_LITTLE_ENDIAN, &rx);
778
779
    // EDFE processing
780
4
    ieee802154_hints_t* hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0);
781
4
    if (!packet || !hints || packet->dst_addr_mode != IEEE802154_FCF_ADDR_EXT) {
782
3
        return 2;
783
3
    }
784
785
1
    wmem_tree_t* byframe = (wmem_tree_t *)wmem_map_lookup(edfe_byaddr, &packet->dst64);
786
1
    edfe_exchange_t *ex = NULL;
787
1
    if (byframe) {
788
0
        ex = (edfe_exchange_t *)wmem_tree_lookup32_le(byframe, pinfo->num);
789
0
    }
790
791
1
    if (!ex || ex->initiator.start_fnum == pinfo->num ||
792
0
        (!hints->map_rec && ex->initiator.end_fnum != ~(unsigned)0) ||
793
1
        (ex->second_fnum == ~(unsigned)0 && packet->src64 == ex->initiator.addr64)) {
794
1
        if (!hints->map_rec && packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
795
1
            ex = wmem_new(wmem_file_scope(), edfe_exchange_t);
796
1
            ex->initiator.proto = "Wi-SUN";
797
1
            ex->target.proto = "Wi-SUN";
798
1
            ex->initiator.start_fnum = pinfo->num;
799
1
            ex->target.start_fnum = pinfo->num;
800
1
            ex->second_fnum = ~(unsigned)0;
801
1
            ex->initiator.end_fnum = ~(unsigned)0;
802
1
            ex->target.end_fnum = ~(unsigned)0;
803
804
1
            ex->initiator.addr64 = packet->src64;
805
1
            ex->target.addr64 = packet->dst64;
806
1
            edfe_insert_exchange(&ex->initiator.addr64, ex);
807
1
            edfe_insert_exchange(&ex->target.addr64, ex);
808
1
            hints->map_rec = &ex->initiator;
809
1
        }
810
1
    } else {
811
0
        if (!hints->map_rec && pinfo->num <= ex->initiator.end_fnum) {
812
0
            hints->map_rec = ex->initiator.addr64 == packet->dst64 ? &ex->target : &ex->initiator;
813
0
            if (ex->second_fnum == ~(unsigned)0) {
814
0
                ex->second_fnum = pinfo->num;
815
0
            }
816
0
            if (tx == 0 && rx == 0) {
817
                // last frame
818
0
                ex->initiator.end_fnum = pinfo->num;
819
0
            }
820
0
        }
821
0
        if (hints->map_rec) {
822
            // Set address to ensure that 6LoWPAN reassembly works
823
            // Adapted from packet-ieee802.15.4.c
824
0
            uint64_t *p_addr = wmem_new(pinfo->pool, uint64_t);
825
            /* Copy and convert the address to network byte order. */
826
0
            *p_addr = pntohu64(&(hints->map_rec->addr64));
827
0
            set_address(&pinfo->dl_src, AT_EUI64, 8, p_addr);
828
0
            copy_address_shallow(&pinfo->src, &pinfo->dl_src);
829
0
            proto_item* src = proto_tree_add_eui64(tree, hf_wisun_fcie_src, tvb, 0, 0, hints->map_rec->addr64);
830
0
            proto_item_set_generated(src);
831
0
            proto_item* frm = proto_tree_add_uint(tree, hf_wisun_fcie_initial_frame, tvb, 0, 0, hints->map_rec->start_fnum);
832
0
            proto_item_set_generated(frm);
833
0
        } else {
834
0
            expert_add_info(pinfo, tree, &ei_wisun_edfe_start_not_found);
835
0
        }
836
0
    }
837
838
1
    if (ex) {
839
1
        if (pinfo->num == ex->initiator.start_fnum) {
840
1
            col_set_str(pinfo->cinfo, COL_INFO, "EDFE Initial Frame");
841
1
        } else if (pinfo->num == ex->initiator.end_fnum) {
842
0
            col_set_str(pinfo->cinfo, COL_INFO, "EDFE Final Frame");
843
0
        } else {
844
0
            col_set_str(pinfo->cinfo, COL_INFO, "EDFE Response Frame");
845
0
        }
846
1
    }
847
848
1
    return 2;
849
4
}
850
851
static int
852
dissect_wisun_rslie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
853
0
{
854
0
    uint32_t rsl = tvb_get_uint8(tvb, offset);
855
0
    if (rsl == 0xff) {
856
        // "A value of 255 MUST be used to indicate not measured" [FANTPS 1v21]
857
0
        proto_tree_add_uint_format_value(tree, hf_wisun_rslie_rsl, tvb, offset, 1, rsl, "not measured");
858
0
    } else {
859
        // "This provides a range of -174 (0) to +80 (254) dBm" [FANTPS 1v21]
860
0
        proto_tree_add_uint_format_value(tree, hf_wisun_rslie_rsl, tvb, offset, 1, rsl, "%d dBm", rsl-174);
861
0
    }
862
0
    return 1;
863
0
}
864
865
static int
866
dissect_wisun_vhie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
867
0
{
868
0
    unsigned vid = wisun_add_wbxml_uint(tvb, tree, hf_wisun_vhie_vid, offset);
869
0
    if (!dissector_try_uint(vhie_dissector_table, vid,
870
0
                            tvb_new_subset_remaining(tvb, offset + wisun_vidlen(vid)),
871
0
                            pinfo, tree))
872
0
        call_data_dissector(tvb_new_subset_remaining(tvb, offset + wisun_vidlen(vid)), pinfo, tree);
873
0
    return tvb_reported_length(tvb);
874
0
}
875
876
static int
877
dissect_wisun_eaie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
878
0
{
879
0
    proto_tree_add_item(tree, hf_wisun_eaie_eui, tvb, offset, 8, ENC_BIG_ENDIAN);
880
0
    return 8;
881
0
}
882
883
static int
884
dissect_wisun_luttie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
885
6
{
886
6
    uint8_t frame_type = tvb_get_uint8(tvb, offset);
887
6
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Wi-SUN");
888
6
    col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(frame_type, wisun_frame_type_vals, "Unknown LFN Wi-SUN Frame"));
889
6
    proto_tree_add_item(tree, hf_wisun_uttie_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
890
6
    proto_tree_add_item(tree, hf_wisun_luttie_usn, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
891
6
    proto_tree_add_item(tree, hf_wisun_luttie_uio, tvb, offset+3, 3, ENC_LITTLE_ENDIAN);
892
6
    return 6;
893
6
}
894
895
static int
896
dissect_wisun_nrie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
897
1
{
898
1
    unsigned start_offset = offset;
899
1
    uint8_t bitmask = tvb_get_uint8(tvb, offset);
900
1
    uint8_t node_role = bitmask & WISUN_WSIE_NODE_ROLE_ID_MASK;
901
1
    int *const nrie_bitmask[] = {
902
1
        &hf_wisun_nrie_lbats,
903
1
        &hf_wisun_nrie_reserved_bits,
904
1
        &hf_wisun_nrie_nr_id,
905
1
        NULL
906
1
    };
907
908
1
    proto_tree_add_bitmask_list(tree, tvb, offset, 1, nrie_bitmask, ENC_LITTLE_ENDIAN);
909
1
    if ((bitmask & ~(WISUN_WSIE_NODE_ROLE_LBATS_IMPLEMENTED|WISUN_WSIE_NODE_ROLE_ID_MASK)) != 0) {
910
1
        expert_add_info(pinfo, tree, &ei_wisun_nrie_reserved_bits_not_zero);
911
1
    }
912
1
    offset++;
913
914
1
    proto_tree_add_item(tree, hf_wisun_usie_clock_drift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
915
1
    offset++;
916
917
1
    unsigned clock_drift = tvb_get_uint8(tvb, offset);
918
    // "Resolution is 10 microseconds and the valid range of the field value is 0-255 (0 to 2.55msec)" [FANTPS 1v21]
919
1
    proto_tree_add_uint_format_value(tree, hf_wisun_nrie_timing_accuracy, tvb, offset, 1, clock_drift, "%1.2fms", clock_drift/100.0);
920
1
    offset++;
921
922
1
    if (node_role == WISUN_WSIE_NODE_ROLE_ID_LFN) {
923
0
        proto_tree_add_item(tree, hf_wisun_nrie_listening_interval_min, tvb, offset, 3, ENC_LITTLE_ENDIAN);
924
0
        offset += 3;
925
0
        proto_tree_add_item(tree, hf_wisun_nrie_listening_interval_max, tvb, offset, 3, ENC_LITTLE_ENDIAN);
926
0
        offset += 3;
927
0
    }
928
929
1
    return offset - start_offset;
930
1
}
931
932
static int
933
dissect_wisun_lusie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
934
2
{
935
2
    proto_tree_add_item(tree, hf_wisun_lusie_listen_interval, tvb, offset, 3, ENC_LITTLE_ENDIAN);
936
2
    proto_tree_add_item(tree, hf_wisun_lusie_channel_plan_tag, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
937
2
    return 4;
938
2
}
939
940
static int
941
dissect_wisun_lbtie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
942
0
{
943
0
    proto_tree_add_item(tree, hf_wisun_lbtie_slot, tvb, offset, 2, ENC_LITTLE_ENDIAN);
944
    /* as of FAN TPS 1v14, this is 3 bytes instead of 4 */
945
0
    proto_tree_add_item(tree, hf_wisun_lbtie_bio, tvb, offset+2, 3, ENC_LITTLE_ENDIAN);
946
0
    return 5;
947
0
}
948
949
static int
950
dissect_wisun_flusie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
951
0
{
952
0
    proto_tree_add_item(tree, hf_wisun_flusie_dwell_interval, tvb, offset, 1, ENC_LITTLE_ENDIAN);
953
0
    proto_tree_add_item(tree, hf_wisun_flusie_channel_plan_tag, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
954
0
    return 2;
955
0
}
956
957
static int
958
dissect_wisun_lbsie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
959
0
{
960
0
    proto_tree_add_item(tree, hf_wisun_lbsie_broadcast_interval, tvb, offset, 3, ENC_LITTLE_ENDIAN);
961
0
    proto_tree_add_item(tree, hf_wisun_lbsie_broadcast_id, tvb, offset+3, 2, ENC_LITTLE_ENDIAN);
962
0
    proto_tree_add_item(tree, hf_wisun_lbsie_channel_plan_tag, tvb, offset+5, 1, ENC_LITTLE_ENDIAN);
963
0
    proto_tree_add_item(tree, hf_wisun_lbsie_broadcast_sync_period, tvb, offset+6, 1, ENC_LITTLE_ENDIAN);
964
0
    return 7;
965
0
}
966
967
static int
968
dissect_wisun_lndie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
969
1
{
970
1
    proto_tree_add_item(tree, hf_wisun_lndie_response_threshold, tvb, offset, 1, ENC_LITTLE_ENDIAN);
971
1
    proto_tree_add_item(tree, hf_wisun_lndie_response_delay, tvb, offset+1, 3, ENC_LITTLE_ENDIAN);
972
1
    proto_tree_add_item(tree, hf_wisun_lndie_discovery_slot_time, tvb, offset+4, 1, ENC_LITTLE_ENDIAN);
973
1
    proto_tree_add_item(tree, hf_wisun_lndie_discovery_slots, tvb, offset+5, 1, ENC_LITTLE_ENDIAN);
974
1
    proto_tree_add_item(tree, hf_wisun_lndie_discovery_first_slot, tvb, offset+6, 2, ENC_LITTLE_ENDIAN);
975
1
    return 8;
976
1
}
977
978
static int
979
dissect_wisun_ltoie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
980
1
{
981
1
    proto_tree_add_item(tree, hf_wisun_ltoie_offset, tvb, offset, 3, ENC_LITTLE_ENDIAN);
982
1
    proto_tree_add_item(tree, hf_wisun_ltoie_listening_interval, tvb, offset+3, 3, ENC_LITTLE_ENDIAN);
983
1
    return 6;
984
1
}
985
986
static int
987
dissect_wisun_panidie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
988
2
{
989
2
    proto_tree_add_item(tree, hf_wisun_panidie_panid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
990
2
    return 2;
991
2
}
992
993
static int
994
dissect_wisun_rtie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
995
1
{
996
1
    proto_tree_add_item(tree, hf_wisun_rtie_rendezvous_time, tvb, offset, 2, ENC_LITTLE_ENDIAN);
997
1
    proto_tree_add_item(tree, hf_wisun_rtie_wakeup_interval, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
998
1
    return 4;
999
1
}
1000
1001
static int
1002
dissect_wisun_lbcie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
1003
0
{
1004
0
    proto_tree_add_item(tree, hf_wisun_lbcie_broadcast_interval, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1005
0
    proto_tree_add_item(tree, hf_wisun_lbcie_broadcast_sync_period, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
1006
0
    return 4;
1007
0
}
1008
1009
static int
1010
dissect_wisun_netricity_nftie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
1011
1
{
1012
1
    uint8_t frame_type = tvb_get_uint8(tvb, offset);
1013
1
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Wi-SUN Netricity");
1014
1
    col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(frame_type, wisun_frame_type_vals, "Unknown Wi-SUN Netricity Frame"));
1015
1
    proto_tree_add_item(tree, hf_wisun_netricity_nftie_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1016
1
    return 1;
1017
1
}
1018
1019
static int
1020
dissect_wisun_netricity_lqiie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
1021
1
{
1022
1
    uint8_t lqi = tvb_get_uint8(tvb, offset);
1023
1
    switch (lqi) {
1024
0
        case 0:
1025
            // "-10 dB or lower (0x00)" [IEEE1901.2-2013]
1026
0
            proto_tree_add_uint_format_value(tree, hf_wisun_netricity_lqiie_lqi, tvb, offset, 1, lqi, "0 (SNR -10 dB or lower)");
1027
0
            break;
1028
0
        case 255:
1029
            // "A value of 255 MUST be used to indicate 'not measured'" [NTPS 1v04]
1030
0
            proto_tree_add_uint_format_value(tree, hf_wisun_netricity_lqiie_lqi, tvb, offset, 1, lqi, "255 (not measured)");
1031
0
            break;
1032
1
        default:
1033
            // "where the value of -9.75 dB is represented as 0x01 and the value of 52.75 dB is represented as 0xFE" [IEEE1901.2-2013]
1034
1
            proto_tree_add_uint_format_value(tree, hf_wisun_netricity_lqiie_lqi, tvb, offset, 1, lqi, "%d (SNR %1.2f dB)", lqi,
1035
1
                                             (lqi-1) * (52.75+9.75) / (0xfe - 0x01) - 9.75);
1036
1
    }
1037
1
    return 1;
1038
1
}
1039
1040
static int
1041
dissect_wisun_hie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1042
103
{
1043
103
    unsigned offset;
1044
103
    proto_tree *subtree;
1045
103
    uint8_t subid = tvb_get_uint8(tvb, 2);
1046
103
    ieee802154_packet *packet = (ieee802154_packet*)data;
1047
1048
103
    offset = 3;
1049
103
    switch (subid) {
1050
7
        case WISUN_SUBID_UTT:
1051
7
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_uttie, ett_wisun_uttie);
1052
7
            offset += dissect_wisun_uttie(tvb, pinfo, subtree, offset);
1053
7
            break;
1054
1055
3
        case WISUN_SUBID_BT:
1056
3
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_btie, ett_wisun_btie);
1057
3
            offset += dissect_wisun_btie(tvb, pinfo, subtree, offset);
1058
3
            break;
1059
1060
4
        case WISUN_SUBID_FC:
1061
4
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_fcie, ett_wisun_fcie);
1062
4
            offset += dissect_wisun_fcie(tvb, pinfo, subtree, offset, packet);
1063
4
            break;
1064
1065
0
        case WISUN_SUBID_RSL:
1066
0
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_rslie, ett_wisun_rslie);
1067
0
            offset += dissect_wisun_rslie(tvb, pinfo, subtree, offset);
1068
0
            break;
1069
1070
0
        case WISUN_SUBID_VH:
1071
0
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_vhie, ett_wisun_vhie);
1072
0
            offset += dissect_wisun_vhie(tvb, pinfo, subtree, offset);
1073
0
            break;
1074
1075
1
        case WISUN_SUBID_N_NFT:
1076
1
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_netricity_nftie, ett_wisun_netricity_nftie);
1077
1
            offset += dissect_wisun_netricity_nftie(tvb, pinfo, subtree, offset);
1078
1
            break;
1079
1080
1
        case WISUN_SUBID_N_LQI:
1081
1
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_netricity_lqiie, ett_wisun_netricity_lqiie);
1082
1
            offset += dissect_wisun_netricity_lqiie(tvb, pinfo, subtree, offset);
1083
1
            break;
1084
1085
0
        case WISUN_SUBID_EA:
1086
0
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_eaie, ett_wisun_eaie);
1087
0
            offset += dissect_wisun_eaie(tvb, pinfo, subtree, offset);
1088
0
            break;
1089
1090
6
        case WISUN_SUBID_LUTT:
1091
6
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_luttie, ett_wisun_luttie);
1092
6
            offset += dissect_wisun_luttie(tvb, pinfo, subtree, offset);
1093
6
            break;
1094
1095
0
        case WISUN_SUBID_LBT:
1096
0
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_lbtie, ett_wisun_btie);
1097
0
            offset += dissect_wisun_lbtie(tvb, pinfo, subtree, offset);
1098
0
            break;
1099
1100
1
        case WISUN_SUBID_NR:
1101
1
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_nrie, ett_wisun_nrie);
1102
1
            offset += dissect_wisun_nrie(tvb, pinfo, subtree, offset);
1103
1
            break;
1104
1105
2
        case WISUN_SUBID_LUS:
1106
2
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_lusie, ett_wisun_lusie);
1107
2
            offset += dissect_wisun_lusie(tvb, pinfo, subtree, offset);
1108
2
            break;
1109
1110
0
        case WISUN_SUBID_FLUS:
1111
0
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_flusie, ett_wisun_flusie);
1112
0
            offset += dissect_wisun_flusie(tvb, pinfo, subtree, offset);
1113
0
            break;
1114
1115
0
        case WISUN_SUBID_LBS:
1116
0
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_lbsie, ett_wisun_lbsie);
1117
0
            offset += dissect_wisun_lbsie(tvb, pinfo, subtree, offset);
1118
0
            break;
1119
1120
1
        case WISUN_SUBID_LND:
1121
1
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_lndie, ett_wisun_lndie);
1122
1
            offset += dissect_wisun_lndie(tvb, pinfo, subtree, offset);
1123
1
            break;
1124
1125
1
        case WISUN_SUBID_LTO:
1126
1
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_ltoie, ett_wisun_ltoie);
1127
1
            offset += dissect_wisun_ltoie(tvb, pinfo, subtree, offset);
1128
1
            break;
1129
1130
2
        case WISUN_SUBID_PANID:
1131
2
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_panidie, ett_wisun_panidie);
1132
2
            offset += dissect_wisun_panidie(tvb, pinfo, subtree, offset);
1133
2
            break;
1134
1135
1
        case WISUN_SUBID_RT:
1136
1
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_rtie, ett_wisun_rtie);
1137
1
            offset += dissect_wisun_rtie(tvb, pinfo, subtree, offset);
1138
1
            break;
1139
1140
0
        case WISUN_SUBID_LBC:
1141
0
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_lbcie, ett_wisun_lbcie);
1142
0
            offset += dissect_wisun_lbcie(tvb, pinfo, subtree, offset);
1143
0
            break;
1144
1145
71
        default:
1146
71
            subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_unknown_ie, ett_wisun_unknown_ie);
1147
71
            expert_add_info(pinfo, subtree, &ei_wisun_subid_unsupported);
1148
71
            call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, subtree);
1149
71
            offset = tvb_reported_length(tvb);
1150
71
            break;
1151
103
    }
1152
98
    return offset;
1153
103
}
1154
1155
/*-----------------------------------------------
1156
 * Wi-SUN Payload IE Dissection
1157
 *---------------------------------------------*/
1158
static int
1159
dissect_wisun_schedule_common(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, proto_tree *tree)
1160
50
{
1161
50
    static int * const fields_usie_channel[] = {
1162
50
            &hf_wisun_usie_channel_plan,
1163
50
            &hf_wisun_usie_channel_function,
1164
50
            &hf_wisun_usie_channel_exclude,
1165
50
            NULL
1166
50
    };
1167
1168
50
    static int * const fields_usie_channel_plan_explicit[] = {
1169
50
            &hf_wisun_usie_explicit_frequency,
1170
50
            &hf_wisun_usie_explicit_spacing,
1171
50
            &hf_wisun_usie_explicit_reserved,
1172
50
            NULL
1173
50
    };
1174
50
    int count;
1175
50
    proto_item *ti;
1176
1177
50
    uint8_t control = tvb_get_uint8(tvb, offset);
1178
50
    proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_wisun_usie_channel_control, ett_wisun_usie_channel_control,
1179
50
                                      fields_usie_channel, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
1180
50
    offset++;
1181
1182
50
    switch ((control & WISUN_CHANNEL_PLAN) >> 0) {
1183
27
        case WISUN_CHANNEL_PLAN_REGULATORY:
1184
27
            proto_tree_add_item(tree, hf_wisun_usie_regulatory_domain, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1185
27
            offset++;
1186
27
            proto_tree_add_item(tree, hf_wisun_usie_operating_class, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1187
27
            offset++;
1188
27
            break;
1189
1190
6
        case WISUN_CHANNEL_PLAN_EXPLICIT:
1191
6
            ti = proto_tree_add_bitmask(tree, tvb, offset, hf_wisun_usie_explicit, ett_wisun_usie_explicit,
1192
6
                                        fields_usie_channel_plan_explicit, ENC_LITTLE_ENDIAN);
1193
6
            offset += 3;
1194
6
            if (tvb_get_uint8(tvb, offset) & 0xf0) {
1195
4
                expert_add_info(pinfo, ti, &ei_wisun_usie_explicit_reserved_bits_not_zero);
1196
4
            }
1197
6
            offset++;
1198
6
            proto_tree_add_item(tree, hf_wisun_usie_number_channels, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1199
6
            offset += 2;
1200
6
            break;
1201
1202
9
        case WISUN_CHANNEL_PLAN_REGULATORY_ID:
1203
9
            proto_tree_add_item(tree, hf_wisun_usie_regulatory_domain, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1204
9
            offset++;
1205
9
            proto_tree_add_item(tree, hf_wisun_usie_channel_plan_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1206
9
            offset++;
1207
9
            break;
1208
1209
8
        default:
1210
8
            expert_add_info(pinfo, tree, &ei_wisun_usie_channel_plan_invalid);
1211
8
            return tvb_reported_length(tvb);
1212
50
    }
1213
1214
42
    switch ((control & WISUN_CHANNEL_FUNCTION) >> 3) {
1215
13
        case WISUN_CHANNEL_FUNCTION_FIXED:
1216
13
            proto_tree_add_item(tree, hf_wisun_usie_fixed_channel, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1217
13
            offset += 2;
1218
13
            break;
1219
1220
4
        case WISUN_CHANNEL_FUNCTION_VENDOR:
1221
4
            count = tvb_get_uint8(tvb, offset);
1222
4
            proto_tree_add_item(tree, hf_wisun_usie_hop_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1223
4
            offset++;
1224
165
            while (count--) {
1225
161
                proto_tree_add_item(tree, hf_wisun_usie_hop_list, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1226
161
                offset++;
1227
161
            }
1228
4
            break;
1229
1230
25
        default:
1231
            /* Hopping list is implied by the hashing function. */
1232
25
            break;
1233
42
    }
1234
1235
39
    switch ((control & WISUN_CHANNEL_EXCLUDE) >> 6) {
1236
4
        case WISUN_CHANNEL_EXCLUDE_RANGE:
1237
4
            count = tvb_get_uint8(tvb, offset);
1238
4
            proto_tree_add_item(tree, hf_wisun_usie_number_ranges, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1239
4
            offset++;
1240
24
            while (count) {
1241
20
                proto_tree_add_item(tree, hf_wisun_usie_exclude_range_start, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1242
20
                offset += 2;
1243
20
                proto_tree_add_item(tree, hf_wisun_usie_exclude_range_end, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1244
20
                offset += 2;
1245
20
                count--;
1246
20
            }
1247
4
            break;
1248
1249
15
        case WISUN_CHANNEL_EXCLUDE_MASK:
1250
15
            count = tvb_reported_length_remaining(tvb, offset);
1251
15
            proto_tree_add_item(tree, hf_wisun_usie_exclude_mask, tvb, offset, count, ENC_NA);
1252
15
            offset += count;
1253
15
            break;
1254
1255
20
        default:
1256
            /* Assume there is nothing to exclude. */
1257
20
            break;
1258
39
    }
1259
33
    return offset;
1260
39
}
1261
1262
static int
1263
dissect_wisun_usie_btie_common(tvbuff_t *tvb, packet_info *pinfo _U_, unsigned offset, proto_tree *tree)
1264
33
{
1265
33
    proto_tree_add_item(tree, hf_wisun_usie_dwell_interval, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1266
33
    offset++;
1267
33
    proto_tree_add_item(tree, hf_wisun_usie_clock_drift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1268
33
    offset++;
1269
1270
33
    unsigned clock_drift = tvb_get_uint8(tvb, offset);
1271
    // "Resolution is 10 microseconds and the valid range of the field value is 0-255 (0 to 2.55msec)" [FANTPS 1v21]
1272
33
    proto_tree_add_uint_format_value(tree, hf_wisun_usie_timing_accuracy, tvb, offset, 1, clock_drift, "%1.2fms", clock_drift/100.0);
1273
33
    offset++;
1274
1275
33
    return offset;
1276
33
}
1277
1278
static int
1279
dissect_wisun_usie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1280
16
{
1281
16
    proto_item *item;
1282
16
    proto_tree *subtree;
1283
16
    unsigned offset = 0;
1284
1285
16
    item = proto_tree_add_item(tree, hf_wisun_usie, tvb, 0, tvb_reported_length_remaining(tvb, 0), ENC_NA);
1286
16
    subtree = proto_item_add_subtree(item, ett_wisun_usie);
1287
1288
16
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie, ENC_LITTLE_ENDIAN);
1289
16
    offset += 2;
1290
1291
16
    offset = dissect_wisun_usie_btie_common(tvb, pinfo, offset, subtree);
1292
1293
16
    return dissect_wisun_schedule_common(tvb, pinfo, offset, subtree);
1294
16
}
1295
1296
static int
1297
dissect_wisun_bsie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1298
17
{
1299
17
    proto_item *item;
1300
17
    proto_tree *subtree;
1301
17
    unsigned offset = 0;
1302
1303
17
    item = proto_tree_add_item(tree, hf_wisun_bsie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1304
17
    subtree = proto_item_add_subtree(item, ett_wisun_bsie);
1305
1306
17
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie, ENC_LITTLE_ENDIAN);
1307
17
    offset += 2;
1308
17
    proto_tree_add_item(subtree, hf_wisun_bsie_bcast_interval, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1309
17
    offset += 4;
1310
17
    proto_tree_add_item(subtree, hf_wisun_bsie_bcast_schedule_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1311
17
    offset += 2;
1312
1313
17
    offset = dissect_wisun_usie_btie_common(tvb, pinfo, offset, subtree);
1314
1315
17
    return dissect_wisun_schedule_common(tvb, pinfo, offset, subtree);
1316
17
}
1317
1318
static int
1319
dissect_wisun_vpie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1320
5
{
1321
5
    proto_item *item;
1322
5
    proto_tree *subtree;
1323
5
    unsigned vid;
1324
1325
5
    item = proto_tree_add_item(tree, hf_wisun_vpie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1326
5
    subtree = proto_item_add_subtree(item, ett_wisun_vpie);
1327
1328
5
    vid = wisun_add_wbxml_uint(tvb, subtree, hf_wisun_vpie_vid, 2);
1329
5
    if (!dissector_try_uint(vpie_dissector_table, vid,
1330
5
                            tvb_new_subset_remaining(tvb, 2 + wisun_vidlen(vid)),
1331
5
                            pinfo, subtree))
1332
5
        call_data_dissector(tvb_new_subset_remaining(tvb, 2 + wisun_vidlen(vid)), pinfo, subtree);
1333
5
    return tvb_reported_length(tvb);
1334
5
}
1335
1336
static int
1337
dissect_wisun_lcpie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1338
17
{
1339
17
    proto_item *item;
1340
17
    proto_tree *subtree;
1341
17
    unsigned offset = 0;
1342
1343
17
    item = proto_tree_add_item(tree, hf_wisun_lcpie, tvb, 0, tvb_reported_length_remaining(tvb, 0), ENC_NA);
1344
17
    subtree = proto_item_add_subtree(item, ett_wisun_lcpie);
1345
1346
17
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie, ENC_LITTLE_ENDIAN);
1347
17
    offset += 2;
1348
1349
17
    proto_tree_add_item(subtree, hf_wisun_lcpie_channel_plan_tag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1350
17
    offset += 1;
1351
1352
17
    return dissect_wisun_schedule_common(tvb, pinfo, offset, subtree);
1353
17
}
1354
1355
static int
1356
dissect_wisun_panie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1357
10
{
1358
10
    proto_item *item;
1359
10
    proto_tree *subtree;
1360
10
    unsigned offset = 0;
1361
10
    uint32_t routingCost;
1362
10
    static int * const fields_panie_flags[] = {
1363
10
        &hf_wisun_panie_flag_parent_bsie,
1364
10
        &hf_wisun_panie_flag_routing_method,
1365
10
        &hf_wisun_panie_flag_lfn_window_style,
1366
10
        &hf_wisun_panie_flag_version,
1367
10
        NULL
1368
10
    };
1369
1370
10
    item = proto_tree_add_item(tree, hf_wisun_panie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1371
10
    subtree = proto_item_add_subtree(item, ett_wisun_panie);
1372
1373
10
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1374
10
    offset += 2;
1375
10
    proto_tree_add_item(subtree, hf_wisun_panie_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1376
10
    offset += 2;
1377
10
    proto_tree_add_item_ret_uint(subtree, hf_wisun_panie_cost, tvb, offset, 2, ENC_LITTLE_ENDIAN, &routingCost);
1378
10
    offset += 2;
1379
10
    proto_tree_add_bitmask_with_flags(subtree, tvb, offset, hf_wisun_panie_flags, ett_wisun_panie_flags,
1380
10
                            fields_panie_flags, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
1381
10
    offset++;
1382
1383
10
    col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "Routing Cost: %d", routingCost);
1384
1385
10
    return offset;
1386
10
}
1387
1388
static int
1389
dissect_wisun_netnameie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1390
78
{
1391
78
    proto_item *item;
1392
78
    proto_tree *subtree;
1393
1394
78
    item = proto_tree_add_item(tree, hf_wisun_netnameie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1395
78
    subtree = proto_item_add_subtree(item, ett_wisun_netnameie);
1396
1397
78
    proto_tree_add_bitmask(subtree, tvb, 0, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1398
78
    proto_tree_add_item(subtree, hf_wisun_netnameie_name, tvb, 2, tvb_reported_length_remaining(tvb, 2), ENC_ASCII);
1399
1400
78
    col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "Netname: %s",
1401
78
                        tvb_get_string_enc(pinfo->pool, tvb, 2, tvb_reported_length_remaining(tvb, 2), ENC_ASCII));
1402
78
    return tvb_reported_length(tvb);
1403
78
}
1404
1405
static int
1406
dissect_wisun_panverie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1407
26
{
1408
26
    proto_item *item;
1409
26
    proto_tree *subtree;
1410
1411
26
    item = proto_tree_add_item(tree, hf_wisun_panverie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1412
26
    subtree = proto_item_add_subtree(item, ett_wisun_panverie);
1413
1414
26
    proto_tree_add_bitmask(subtree, tvb, 0, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1415
26
    proto_tree_add_item(subtree, hf_wisun_panverie_version, tvb, 2, 2, ENC_LITTLE_ENDIAN);
1416
1417
26
    col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "PAN Version: %d", tvb_get_uint16(tvb, 2, ENC_LITTLE_ENDIAN));
1418
1419
26
    return tvb_reported_length(tvb);
1420
26
}
1421
1422
static int
1423
dissect_wisun_gtkhashie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1424
1
{
1425
1
    proto_item *item;
1426
1
    proto_tree *subtree;
1427
1428
1
    item = proto_tree_add_item(tree, hf_wisun_gtkhashie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1429
1
    subtree = proto_item_add_subtree(item, ett_wisun_gtkhashie);
1430
1431
1
    proto_tree_add_bitmask(subtree, tvb, 0, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1432
1
    proto_tree_add_item(subtree, hf_wisun_gtkhashie_gtk0, tvb, 2, 8, ENC_NA);
1433
1
    proto_tree_add_item(subtree, hf_wisun_gtkhashie_gtk1, tvb, 10, 8, ENC_NA);
1434
1
    proto_tree_add_item(subtree, hf_wisun_gtkhashie_gtk2, tvb, 18, 8, ENC_NA);
1435
1
    proto_tree_add_item(subtree, hf_wisun_gtkhashie_gtk3, tvb, 26, 8, ENC_NA);
1436
1
    return 34;
1437
1
}
1438
1439
static int
1440
dissect_wisun_pomie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1441
26
{
1442
26
    proto_item *item;
1443
26
    proto_tree *subtree;
1444
26
    uint8_t number_operating_modes;
1445
26
    unsigned offset = 0;
1446
1447
26
    static int* const wisun_pomie_fields[] = {
1448
26
        &hf_wisun_pomie_number_operating_modes,
1449
26
        &hf_wisun_pomie_mdr_command_capable_flag,
1450
26
        &hf_wisun_pomie_reserved,
1451
26
        NULL
1452
26
    };
1453
1454
26
    item = proto_tree_add_item(tree, hf_wisun_pomie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1455
26
    subtree = proto_item_add_subtree(item, ett_wisun_pomie);
1456
1457
26
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1458
1459
26
    offset += 2;
1460
26
    number_operating_modes = tvb_get_uint8(tvb, offset) & WISUN_PIE_PHY_OPERATING_MODES_MASK;
1461
26
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_pomie_hdr, ett_wisun_pomie_hdr, wisun_pomie_fields, ENC_NA);
1462
1463
26
    offset++;
1464
169
    for (uint8_t i = 0; i < number_operating_modes; i++) {
1465
143
        wisun_add_phy_mode_id(tvb, subtree, offset, hf_wisun_pomie_phy_mode_id, &hf_wisun_pomie_phy_type,
1466
143
                              &hf_wisun_pomie_phy_mode_fsk, &hf_wisun_pomie_phy_mode_ofdm);
1467
143
        offset++;
1468
143
    }
1469
1470
26
    return tvb_reported_length(tvb);
1471
26
}
1472
1473
static int
1474
dissect_wisun_lfnverie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1475
14
{
1476
14
    proto_item *item;
1477
14
    proto_tree *subtree;
1478
1479
14
    item = proto_tree_add_item(tree, hf_wisun_lfnverie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1480
14
    subtree = proto_item_add_subtree(item, ett_wisun_lfnverie);
1481
1482
14
    proto_tree_add_bitmask(subtree, tvb, 0, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1483
14
    proto_tree_add_item(subtree, hf_wisun_lfnverie_version, tvb, 2, 2, ENC_LITTLE_ENDIAN);
1484
1485
14
    col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "LFN Version: %d", tvb_get_uint16(tvb, 2, ENC_LITTLE_ENDIAN));
1486
1487
14
    return tvb_reported_length(tvb);
1488
14
}
1489
1490
static int
1491
dissect_wisun_lgtkhashie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1492
12
{
1493
12
    proto_item *item;
1494
12
    proto_tree *subtree;
1495
12
    unsigned offset = 0;
1496
12
    uint8_t lgtkhash_control = 0;
1497
1498
12
    static int * const fields_lgtkhashie_flags[] = {
1499
12
        &hf_wisun_lgtkhashie_flag_includes_lgtk0,
1500
12
        &hf_wisun_lgtkhashie_flag_includes_lgtk1,
1501
12
        &hf_wisun_lgtkhashie_flag_includes_lgtk2,
1502
12
        &hf_wisun_lgtkhashie_flag_active_lgtk_index,
1503
12
        NULL
1504
12
    };
1505
1506
12
    item = proto_tree_add_item(tree, hf_wisun_lgtkhashie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1507
12
    subtree = proto_item_add_subtree(item, ett_wisun_lgtkhashie);
1508
1509
12
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1510
12
    offset += 2;
1511
1512
12
    lgtkhash_control = tvb_get_uint8(tvb, offset);
1513
12
    proto_tree_add_bitmask_with_flags(subtree, tvb, offset, hf_wisun_lgtkhashie_flags, ett_wisun_lgtkhashie_flags,
1514
12
                                      fields_lgtkhashie_flags, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
1515
12
    offset++;
1516
1517
12
    if (lgtkhash_control & WISUN_LGTKHASH_LGTK0_INCLUDED_MASK) {
1518
7
        proto_tree_add_item(subtree, hf_wisun_lgtkhashie_gtk0, tvb, offset, 8, ENC_NA);
1519
7
        offset += 8;
1520
7
    }
1521
1522
12
    if (lgtkhash_control & WISUN_LGTKHASH_LGTK1_INCLUDED_MASK) {
1523
3
        proto_tree_add_item(subtree, hf_wisun_lgtkhashie_gtk1, tvb, offset, 8, ENC_NA);
1524
3
        offset += 8;
1525
3
    }
1526
1527
12
    if (lgtkhash_control & WISUN_LGTKHASH_LGTK2_INCLUDED_MASK) {
1528
2
        proto_tree_add_item(subtree, hf_wisun_lgtkhashie_gtk2, tvb, offset, 8, ENC_NA);
1529
2
        offset += 8;
1530
2
    }
1531
1532
12
    return offset;
1533
12
}
1534
1535
static int
1536
dissect_wisun_lbatsie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1537
23
{
1538
23
    unsigned offset = 0;
1539
23
    proto_item *item;
1540
23
    proto_tree *subtree;
1541
1542
23
    item = proto_tree_add_item(tree, hf_wisun_lbatsie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1543
23
    subtree = proto_item_add_subtree(item, ett_wisun_lbatsie);
1544
1545
23
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1546
23
    offset += 2;
1547
23
    proto_tree_add_item(subtree, hf_wisun_lbatsie_additional_tx, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1548
23
    offset += 1;
1549
23
    proto_tree_add_item(subtree, hf_wisun_lbatsie_next_tx_delay, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1550
23
    offset += 2;
1551
23
    return offset;
1552
23
}
1553
1554
static int
1555
dissect_wisun_jmie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1556
52
{
1557
52
    static int * const fields_jmie_metric_hdr[] = {
1558
52
        &hf_wisun_jmie_metric_id,
1559
52
        &hf_wisun_jmie_metric_len,
1560
52
        NULL
1561
52
    };
1562
52
    unsigned offset = 0;
1563
52
    proto_item *item;
1564
52
    proto_tree *subtree;
1565
1566
52
    item = proto_tree_add_item(tree, hf_wisun_jmie, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1567
52
    subtree = proto_item_add_subtree(item, ett_wisun_jmie);
1568
1569
52
    proto_tree_add_bitmask(subtree, tvb, offset, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie_short, ENC_LITTLE_ENDIAN);
1570
52
    offset += 2;
1571
52
    proto_tree_add_item(subtree, hf_wisun_jmie_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1572
52
    offset += 1;
1573
3.50k
    while (tvb_reported_length_remaining(tvb, offset) > 0) {
1574
3.46k
        uint8_t metric_hdr = tvb_get_uint8(tvb, offset);
1575
3.46k
        uint8_t metric_len = (metric_hdr & WISUN_PIE_JM_LEN_MASK) >> 6;
1576
3.46k
        proto_tree *metric_subtree;
1577
1578
3.46k
        if (metric_len == 3)
1579
152
            metric_len = 4;
1580
1581
3.46k
        switch (metric_hdr & WISUN_PIE_JM_ID_MASK) {
1582
80
        case WISUN_PIE_JM_ID_PLF:
1583
80
            item = proto_tree_add_item(subtree, hf_wisun_jmie_metric_plf, tvb, offset, 1 + metric_len, ENC_NA);
1584
80
            metric_subtree = proto_item_add_subtree(item, ett_wisun_jmie_metric_plf);
1585
80
            proto_tree_add_bitmask(metric_subtree, tvb, offset, hf_wisun_jmie_metric_hdr, ett_wisun_jmie_metric_hdr, fields_jmie_metric_hdr, ENC_NA);
1586
80
            offset += 1;
1587
80
            proto_tree_add_item(metric_subtree, hf_wisun_jmie_metric_plf_data, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1588
80
            break;
1589
3.38k
        default:
1590
3.38k
            item = proto_tree_add_item(subtree, hf_wisun_jmie_metric_unknown, tvb, offset, 1 + metric_len, ENC_NA);
1591
3.38k
            metric_subtree = proto_item_add_subtree(item, ett_wisun_jmie_metric_unknown);
1592
3.38k
            proto_tree_add_bitmask(metric_subtree, tvb, offset, hf_wisun_jmie_metric_hdr, ett_wisun_jmie_metric_hdr, fields_jmie_metric_hdr, ENC_NA);
1593
3.38k
            offset += 1;
1594
3.38k
            expert_add_info(pinfo, metric_subtree, &ei_wisun_jmie_metric_unsupported);
1595
3.38k
            call_data_dissector(tvb_new_subset_length(tvb, offset, metric_len), pinfo, metric_subtree);
1596
3.38k
            break;
1597
3.46k
        }
1598
3.45k
        offset += metric_len;
1599
3.45k
    }
1600
40
    return offset;
1601
52
}
1602
1603
static int
1604
dissect_wisun_pie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ies_tree, void *data)
1605
152
{
1606
152
    proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_wisun_pie, ett_wisun_pie);
1607
152
    unsigned offset = 2;
1608
1.40k
    while (tvb_reported_length_remaining(tvb, offset) > 1) {
1609
        /* Wi-SUN Payload IE contains nested IE's using the same format as IEEE802.15.4 */
1610
1.29k
        uint16_t    wsie_ie = tvb_get_letohs(tvb, offset);
1611
1.29k
        uint16_t    wsie_len;
1612
1.29k
        tvbuff_t *  wsie_tvb;
1613
1614
1.29k
        if (wsie_ie & IEEE802154_PSIE_TYPE_MASK) {
1615
            /* long format: Table 7-17-Sub-ID allocation for long format */
1616
86
            wsie_len = (wsie_ie & IEEE802154_PSIE_LENGTH_MASK_LONG);
1617
86
            wsie_tvb = tvb_new_subset_length(tvb, offset, wsie_len + 2);
1618
86
            switch ((wsie_ie & IEEE802154_PSIE_ID_MASK_LONG) >> 11) {
1619
16
                case WISUN_PIE_SUBID_US:
1620
16
                    dissect_wisun_usie(wsie_tvb, pinfo, tree, data);
1621
16
                    break;
1622
17
                case WISUN_PIE_SUBID_BS:
1623
17
                    dissect_wisun_bsie(wsie_tvb, pinfo, tree, data);
1624
17
                    break;
1625
5
                case WISUN_PIE_SUBID_VP:
1626
5
                    dissect_wisun_vpie(wsie_tvb, pinfo, tree, data);
1627
5
                    break;
1628
17
                case WISUN_PIE_SUBID_LCP:
1629
17
                    dissect_wisun_lcpie(wsie_tvb, pinfo, tree, data);
1630
17
                    break;
1631
31
                default:{
1632
31
                    proto_item *item = proto_tree_add_item(tree, hf_wisun_unknown_ie, wsie_tvb, 0, tvb_reported_length(wsie_tvb), ENC_NA);
1633
31
                    proto_tree *subtree = proto_item_add_subtree(item, ett_wisun_unknown_ie);
1634
31
                    proto_tree_add_bitmask(subtree, wsie_tvb, 0, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie, ENC_LITTLE_ENDIAN);
1635
31
                    expert_add_info(pinfo, subtree, &ei_wisun_wsie_unsupported);
1636
31
                    call_data_dissector(tvb_new_subset_remaining(wsie_tvb, 2), pinfo, subtree);
1637
31
                    break;
1638
0
                }
1639
86
            }
1640
1.20k
        } else {
1641
            /* short format: Table 7-16-Sub-ID allocation for short format */
1642
1.20k
            wsie_len = (wsie_ie & IEEE802154_PSIE_LENGTH_MASK_SHORT);
1643
1.20k
            wsie_tvb = tvb_new_subset_length(tvb, offset, wsie_len + 2);
1644
1.20k
            switch ((wsie_ie & IEEE802154_PSIE_ID_MASK_SHORT) >> 8) {
1645
10
                case WISUN_PIE_SUBID_PAN:
1646
10
                    dissect_wisun_panie(wsie_tvb, pinfo, tree, data);
1647
10
                    break;
1648
78
                case WISUN_PIE_SUBID_NETNAME:
1649
78
                    dissect_wisun_netnameie(wsie_tvb, pinfo, tree, data);
1650
78
                    break;
1651
26
                case WISUN_PIE_SUBID_PANVER:
1652
26
                    dissect_wisun_panverie(wsie_tvb, pinfo, tree, data);
1653
26
                    break;
1654
1
                case WISUN_PIE_SUBID_GTKHASH:
1655
1
                    dissect_wisun_gtkhashie(wsie_tvb, pinfo, tree, data);
1656
1
                    break;
1657
26
                case WISUN_PIE_SUBID_POM:
1658
26
                    dissect_wisun_pomie(wsie_tvb, pinfo, tree, data);
1659
26
                    break;
1660
14
                case WISUN_PIE_SUBID_LFNVER:
1661
14
                    dissect_wisun_lfnverie(wsie_tvb, pinfo, tree, data);
1662
14
                    break;
1663
12
                case WISUN_PIE_SUBID_LGTKHASH:
1664
12
                    dissect_wisun_lgtkhashie(wsie_tvb, pinfo, tree, data);
1665
12
                    break;
1666
23
                case WISUN_PIE_SUBID_LBATS:
1667
23
                    dissect_wisun_lbatsie(wsie_tvb, pinfo, tree, data);
1668
23
                    break;
1669
52
                case WISUN_PIE_SUBID_JM:
1670
52
                    dissect_wisun_jmie(wsie_tvb, pinfo, tree, data);
1671
52
                    break;
1672
962
                default:{
1673
962
                    proto_item *item = proto_tree_add_item(tree, hf_wisun_unknown_ie, wsie_tvb, 0, tvb_reported_length(wsie_tvb), ENC_NA);
1674
962
                    proto_tree *subtree = proto_item_add_subtree(item, ett_wisun_unknown_ie);
1675
962
                    proto_tree_add_bitmask(subtree, wsie_tvb, 0, hf_wisun_wsie, ett_wisun_wsie_bitmap, wisun_format_nested_ie, ENC_LITTLE_ENDIAN);
1676
962
                    expert_add_info(pinfo, subtree, &ei_wisun_wsie_unsupported);
1677
962
                    call_data_dissector(tvb_new_subset_remaining(wsie_tvb, 2), pinfo, subtree);
1678
962
                    break;
1679
0
                }
1680
1.20k
            }
1681
1.20k
        }
1682
1.25k
        offset += tvb_reported_length(wsie_tvb);
1683
1.25k
    }
1684
116
    return offset;
1685
152
}
1686
1687
1688
static int
1689
dissect_wisun_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1690
0
{
1691
0
    unsigned offset = 0;
1692
0
    uint8_t cmd_subid;
1693
1694
0
    cmd_subid = tvb_get_uint8(tvb, offset);
1695
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Wi-SUN");
1696
0
    col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(cmd_subid, wisun_cmd_vals, "Unknown Wi-SUN MAC Command"));
1697
0
    proto_tree_add_item(tree, hf_wisun_cmd_subid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1698
0
    offset += 1;
1699
0
    switch (cmd_subid) {
1700
0
    case WISUN_CMD_MDR:
1701
0
        wisun_add_phy_mode_id(tvb, tree, offset, hf_wisun_cmd_mdr_phy_mode_id, &hf_wisun_cmd_mdr_phy_type,
1702
0
                              &hf_wisun_cmd_mdr_phy_mode_fsk, &hf_wisun_cmd_mdr_phy_mode_ofdm);
1703
0
        break;
1704
0
    default:
1705
0
        call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1706
0
        break;
1707
0
    }
1708
0
    return offset;
1709
0
}
1710
1711
/*-----------------------------------------------
1712
 * Wi-SUN FAN Security Extensions Dissection
1713
 *---------------------------------------------*/
1714
static int
1715
dissect_wisun_sec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1716
0
{
1717
0
    proto_item *ws_root;
1718
0
    proto_tree *ws_tree;
1719
0
    uint8_t function = tvb_get_uint8(tvb, 0);
1720
0
    const char *function_name = val_to_str_const(function, wisun_sec_functions, "Unknown Function");
1721
1722
    /* Create the protocol tree. */
1723
0
    ws_root = proto_tree_add_protocol_format(tree, proto_wisun_sec, tvb, 0, -1, "Wi-SUN %s", function_name);
1724
0
    ws_tree = proto_item_add_subtree(ws_root, ett_wisun_sec);
1725
1726
    /* Add the protocol name. */
1727
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Wi-SUN");
1728
0
    col_set_str(pinfo->cinfo, COL_INFO, function_name);
1729
1730
    /* Decode based on the function code. */
1731
0
    proto_tree_add_item(ws_tree, hf_wisun_sec_function, tvb, 0, 1, ENC_LITTLE_ENDIAN);
1732
0
    switch (function) {
1733
0
        case 0x01:{
1734
0
            const char *err_name = val_to_str_const(tvb_get_uint8(tvb, 1), wisun_sec_sm_errors, "Unknown Error");
1735
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", err_name);
1736
0
            proto_item_append_text(ws_root, ": %s", err_name);
1737
1738
0
            proto_tree_add_item(ws_tree, hf_wisun_sec_error_type, tvb, 1, 1, ENC_LITTLE_ENDIAN);
1739
0
            proto_tree_add_item(ws_tree, hf_wisun_sec_error_nonce, tvb, 2, tvb_reported_length_remaining(tvb, 2), ENC_NA);
1740
0
            return tvb_reported_length(tvb);
1741
0
        }
1742
1743
0
        default:
1744
0
            call_data_dissector(tvb_new_subset_remaining(tvb, 2), pinfo, ws_tree);
1745
0
            return tvb_reported_length(tvb);
1746
0
    }
1747
0
}
1748
1749
1750
/*-----------------------------------------------
1751
 * Wi-SUN FAN EAPOL Relay
1752
 *---------------------------------------------*/
1753
1754
static int dissect_wisun_eapol_relay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1755
43
{
1756
43
    unsigned offset = 0;
1757
43
    proto_item *subitem = proto_tree_add_item(tree, proto_wisun_eapol_relay, tvb, offset, 9, ENC_NA);
1758
43
    proto_tree *subtree = proto_item_add_subtree(subitem, ett_wisun_eapol_relay);
1759
1760
43
    proto_tree_add_item(subtree, hf_wisun_eapol_relay_sup, tvb, offset, 8, ENC_BIG_ENDIAN);
1761
43
    offset += 8;
1762
43
    proto_tree_add_item(subtree, hf_wisun_eapol_relay_kmp_id, tvb, offset, 1, ENC_NA);
1763
43
    offset += 1;
1764
1765
43
    int up = 0;
1766
    // eapol.type == EAP_PACKET?
1767
43
    if (tvb_get_uint8(tvb, offset+1) == 0) {
1768
11
        up = tvb_get_uint8(tvb, offset+4) == 2;  // eap.code == EAP_CODE_RESPONSE
1769
32
    } else {
1770
32
        up = (tvb_get_uint8(tvb, offset+6) & 0x80) == 0;  // Key Info ACK==0
1771
32
    }
1772
43
    proto_item* diritem = proto_tree_add_boolean(subtree, hf_wisun_eapol_relay_direction, tvb, offset, 0, (uint64_t) up);
1773
43
    proto_item_set_generated(diritem);
1774
1775
43
    int r = call_dissector(eapol_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1776
1777
    // UTF-8 arrow up or down
1778
43
    col_append_str(pinfo->cinfo, COL_INFO, up ? " [Relay \xe2\x86\x91]" : " [Relay \xe2\x86\x93]");
1779
1780
43
    return offset + r;
1781
43
}
1782
1783
/*-----------------------------------------------
1784
 * Wi-SUN Netricity Segment Control
1785
 *---------------------------------------------*/
1786
1787
static int dissect_wisun_netricity_sc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1788
0
{
1789
0
    static int * const fields_sc[] = {
1790
0
        &hf_wisun_netricity_sc_reserved,
1791
0
        &hf_wisun_netricity_sc_tone_map_request,
1792
0
        &hf_wisun_netricity_sc_contention_control,
1793
0
        &hf_wisun_netricity_sc_channel_access_priority,
1794
0
        &hf_wisun_netricity_sc_last_segment,
1795
0
        NULL
1796
0
    };
1797
1798
0
    unsigned offset = 0;
1799
1800
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Wi-SUN Netricity");
1801
1802
0
    proto_item *subitem = proto_tree_add_item(tree, proto_wisun_netricity_sc, tvb, offset, -1, ENC_NA);
1803
0
    proto_tree *subtree = proto_item_add_subtree(subitem, ett_wisun_netricity_sc);
1804
1805
0
    bool is_last = tvb_get_uint8(tvb, 0) & 1;
1806
0
    proto_tree_add_bitmask(subtree, tvb, offset++, hf_wisun_netricity_sc_flags, ett_wisun_netricity_sc_bitmask, fields_sc, ENC_BIG_ENDIAN);
1807
0
    uint32_t seg_count;
1808
0
    uint32_t seg_len;
1809
0
    proto_tree_add_item_ret_uint(subtree, hf_wisun_netricity_sc_segment_count, tvb, offset, 2, ENC_BIG_ENDIAN, &seg_count);
1810
0
    proto_tree_add_item_ret_uint(subtree, hf_wisun_netricity_sc_segment_length, tvb, offset, 2, ENC_BIG_ENDIAN, &seg_len);
1811
0
    offset += 2;
1812
1813
0
    bool is_segmented = !is_last || seg_count != 0;
1814
0
    proto_tree *ieee802154_tree;
1815
0
    ieee802154_packet *packet;
1816
0
    tvbuff_t *frame = tvb_new_subset_remaining(tvb, offset);
1817
    // if security is used, all segments have the flag set in the FCF, but only the first has the Auxiliary Security Header
1818
0
    unsigned mhr_len = ieee802154_dissect_header(frame, pinfo,
1819
0
                                              is_segmented ? subtree : tree,
1820
0
                                              seg_count == 0 ? 0 : IEEE802154_DISSECT_HEADER_OPTION_NO_AUX_SEC_HDR,
1821
0
                                              &ieee802154_tree, &packet);
1822
0
    if (!mhr_len) {
1823
0
        return tvb_captured_length(tvb);
1824
0
    }
1825
0
    frame = tvb_new_subset_length(frame, 0, mhr_len + seg_len);
1826
1827
0
    if (is_segmented) {
1828
0
        bool save_fragmented = pinfo->fragmented;
1829
0
        pinfo->fragmented = true;
1830
0
        fragment_head *frag_msg = fragment_add_seq_check(&netricity_reassembly_table,
1831
0
                                                         frame,
1832
0
                                                         seg_count == 0 ? 0 : mhr_len,
1833
0
                                                         pinfo,
1834
0
                                                         packet->seqno,
1835
0
                                                         NULL,
1836
0
                                                         seg_count,
1837
0
                                                         (seg_count == 0 ? mhr_len : 0) + seg_len,
1838
0
                                                         !is_last);
1839
0
        tvbuff_t *reframe = process_reassembled_data(tvb, offset, pinfo, "Reassembled segments", frag_msg, &netricity_scr_frag_items, NULL, subtree);
1840
1841
0
        if (reframe) {
1842
0
            call_dissector(ieee802154_nofcs_handle, reframe, pinfo, tree);
1843
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " (Reassembled %u segments)", seg_count + 1);
1844
0
        } else {
1845
0
            call_data_dissector(tvb_new_subset_remaining(frame, mhr_len), pinfo, subtree);
1846
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " (Segment %u)", seg_count);
1847
0
        }
1848
1849
0
        pinfo->fragmented = save_fragmented;
1850
0
    } else {
1851
0
        tvbuff_t *payload = ieee802154_decrypt_payload(frame, mhr_len, pinfo, ieee802154_tree, packet);
1852
0
        if (payload) {
1853
0
            unsigned pie_size = ieee802154_dissect_payload_ies(payload, pinfo, ieee802154_tree, packet);
1854
0
            payload = tvb_new_subset_remaining(payload, pie_size);
1855
0
            ieee802154_dissect_frame_payload(payload, pinfo, ieee802154_tree, packet, true);
1856
0
        }
1857
0
    }
1858
1859
0
    return tvb_captured_length(tvb);
1860
0
}
1861
1862
/*-----------------------------------------------
1863
 * Wi-SUN Protocol Registration
1864
 *---------------------------------------------*/
1865
void proto_register_wisun(void)
1866
14
{
1867
14
    static hf_register_info hf[] = {
1868
        /* Wi-SUN Header IEs */
1869
14
        { &hf_wisun_subid,
1870
14
          { "Header Sub ID", "wisun.subid", FT_UINT8, BASE_HEX|BASE_SPECIAL_VALS, VALS(wisun_subid_vals), 0x0,
1871
14
            NULL, HFILL }
1872
14
        },
1873
1874
14
        { &hf_wisun_unknown_ie,
1875
14
          { "Unknown IE", "wisun.unknown", FT_NONE, BASE_NONE, NULL, 0x0,
1876
14
            NULL, HFILL }
1877
14
        },
1878
1879
14
        { &hf_wisun_uttie,
1880
14
          { "UTT-IE", "wisun.uttie", FT_NONE, BASE_NONE, NULL, 0x0,
1881
14
            "Unicast Timing IE", HFILL }
1882
14
        },
1883
1884
14
        { &hf_wisun_uttie_type,
1885
14
          { "Frame Type", "wisun.uttie.type", FT_UINT8, BASE_DEC|BASE_SPECIAL_VALS, VALS(wisun_frame_type_vals), 0x0,
1886
14
            NULL, HFILL }
1887
14
        },
1888
1889
14
        { &hf_wisun_uttie_ufsi,
1890
14
          { "UFSI", "wisun.uttie.ufsi", FT_UINT24, BASE_DEC, NULL, 0x0,
1891
14
            "Unicast Fractional Sequence Interval", HFILL }
1892
14
        },
1893
1894
14
        { &hf_wisun_btie,
1895
14
          { "BT-IE", "wisun.btie", FT_NONE, BASE_NONE, NULL, 0x0,
1896
14
            "Broadcast Timing IE", HFILL }
1897
14
        },
1898
1899
14
        { &hf_wisun_btie_slot,
1900
14
          { "BSN", "wisun.btie.slot", FT_UINT24, BASE_DEC, NULL, 0x0,
1901
14
            "Broadcast Slot Number", HFILL }
1902
14
        },
1903
1904
14
        { &hf_wisun_btie_bio,
1905
14
          { "BIO", "wisun.btie.bio", FT_UINT24, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
1906
14
            "Broadcast Interval Offset", HFILL }
1907
14
        },
1908
1909
14
        { &hf_wisun_fcie,
1910
14
          { "FC-IE", "wisun.fcie", FT_NONE, BASE_NONE, NULL, 0x0,
1911
14
            "Flow Control IE", HFILL }
1912
14
        },
1913
1914
14
        { &hf_wisun_fcie_tx,
1915
14
          { "Transmit Flow Control", "wisun.fcie.tx", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
1916
14
            NULL, HFILL }
1917
14
        },
1918
1919
14
        { &hf_wisun_fcie_rx,
1920
14
          { "Receive Flow Control", "wisun.fcie.rx", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
1921
14
            NULL, HFILL }
1922
14
        },
1923
1924
14
        { &hf_wisun_fcie_src,
1925
14
          { "Source Address", "wisun.fcie.src", FT_EUI64, BASE_NONE, NULL, 0x0,
1926
14
            NULL, HFILL }
1927
14
        },
1928
1929
14
        { &hf_wisun_fcie_initial_frame,
1930
14
          { "Initial Frame", "wisun.fcie.initial_frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
1931
14
            NULL, HFILL }
1932
14
        },
1933
1934
14
        { &hf_wisun_rslie,
1935
14
          { "RSL-IE", "wisun.rslie", FT_NONE, BASE_NONE, NULL, 0x0,
1936
14
            "Received Signal Level IE", HFILL }
1937
14
        },
1938
1939
14
        { &hf_wisun_rslie_rsl,
1940
14
          { "Received Signal Level", "wisun.rslie.rsl", FT_UINT8, BASE_DEC, NULL, 0x0,
1941
14
            NULL, HFILL }
1942
14
        },
1943
1944
14
        { &hf_wisun_vhie,
1945
14
          { "VH-IE", "wisun.vhie", FT_NONE, BASE_NONE, NULL, 0x0,
1946
14
            "Vendor Header IE", HFILL }
1947
14
        },
1948
1949
14
        { &hf_wisun_vhie_vid,
1950
14
          { "Vendor ID", "wisun.vhie.vid", FT_UINT16, BASE_DEC, NULL, 0x0,
1951
14
            NULL, HFILL }
1952
14
        },
1953
1954
14
        { &hf_wisun_eaie,
1955
14
          { "EA-IE", "wisun.eaie", FT_NONE, BASE_NONE, NULL, 0x0,
1956
14
            "EAPOL Authenticator IE", HFILL }
1957
14
        },
1958
1959
14
        { &hf_wisun_eaie_eui,
1960
14
          { "Authenticator EUI-64", "wisun.eaie.eui", FT_EUI64, BASE_NONE, NULL, 0x0,
1961
14
            NULL, HFILL }
1962
14
        },
1963
1964
14
        { &hf_wisun_luttie,
1965
14
          { "LUTT-IE", "wisun.luttie", FT_NONE, BASE_NONE, NULL, 0x0,
1966
14
            "LFN Unicast Timing and Frame Type IE", HFILL }
1967
14
        },
1968
1969
14
        { &hf_wisun_luttie_usn,
1970
14
          { "USN", "wisun.luttie.usn", FT_UINT16, BASE_DEC, NULL, 0x0,
1971
14
            "Unicast Slot Number", HFILL }
1972
14
        },
1973
1974
14
        { &hf_wisun_luttie_uio,
1975
14
          { "UIO", "wisun.luttie.uio", FT_UINT24, BASE_DEC, NULL, 0x0,
1976
14
            "Unicast Interval Offset", HFILL }
1977
14
        },
1978
1979
14
        { &hf_wisun_lbtie,
1980
14
          { "LBT-IE", "wisun.lbtie", FT_NONE, BASE_NONE, NULL, 0x0,
1981
14
            "LFN Broadcast Timing IE", HFILL }
1982
14
        },
1983
1984
14
        { &hf_wisun_lbtie_slot,
1985
14
          { "LFN BSN", "wisun.lbtie.slot", FT_UINT24, BASE_DEC, NULL, 0x0,
1986
14
            "LFN Broadcast Slot Number", HFILL }
1987
14
        },
1988
1989
14
        { &hf_wisun_lbtie_bio,
1990
14
          { "LFN BIO", "wisun.lbtie.bio", FT_UINT24, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
1991
14
            "LFN Broadcast Interval Offset", HFILL }
1992
14
        },
1993
1994
14
        { &hf_wisun_nrie,
1995
14
          { "NR-IE", "wisun.nrie", FT_NONE, BASE_NONE, NULL, 0x0,
1996
14
            "Node Role IE", HFILL }
1997
14
        },
1998
1999
14
        { &hf_wisun_nrie_nr_id,
2000
14
          { "Node Role ID", "wisun.nrie.nr_id", FT_UINT8, BASE_DEC, VALS(wisun_wsie_node_role_vals), WISUN_WSIE_NODE_ROLE_ID_MASK,
2001
14
            NULL, HFILL }
2002
14
        },
2003
2004
14
        { &hf_wisun_nrie_reserved_bits,
2005
14
          { "Reserved", "wisun.nrie.reserved", FT_UINT8, BASE_DEC, NULL, WISUN_WSIE_NODE_ROLE_ID_RESERVED,
2006
14
            NULL, HFILL }
2007
14
        },
2008
2009
14
        { &hf_wisun_nrie_lbats,
2010
14
          { "LBATS Implemented", "wisun.nrie.lbats", FT_BOOLEAN, 8, NULL, WISUN_WSIE_NODE_ROLE_LBATS_IMPLEMENTED,
2011
14
            NULL, HFILL }
2012
14
        },
2013
2014
14
        { &hf_wisun_nrie_timing_accuracy,
2015
14
          { "Timing Accuracy", "wisun.nrie.timing_accuracy", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
2016
14
            NULL, HFILL }
2017
14
        },
2018
2019
14
        { &hf_wisun_nrie_listening_interval_min,
2020
14
          { "Listening Interval Min", "wisun.nrie.listening_interval_min", FT_UINT24, BASE_DEC, NULL, 0x0,
2021
14
            NULL, HFILL }
2022
14
        },
2023
2024
14
        { &hf_wisun_nrie_listening_interval_max,
2025
14
          { "Listening Interval Max", "wisun.nrie.listening_interval_max", FT_UINT24, BASE_DEC, NULL, 0x0,
2026
14
            NULL, HFILL }
2027
14
        },
2028
2029
14
        { &hf_wisun_lusie,
2030
14
          { "LUS-IE", "wisun.lusie", FT_NONE, BASE_NONE, NULL, 0x0,
2031
14
            "LFN Unicast Schedule IE", HFILL }
2032
14
        },
2033
2034
14
        { &hf_wisun_lusie_listen_interval,
2035
14
          { "Listen Interval", "wisun.lusie.listen", FT_UINT24, BASE_DEC, NULL, 0x0,
2036
14
            NULL, HFILL }
2037
14
        },
2038
2039
14
        { &hf_wisun_lusie_channel_plan_tag,
2040
14
          { "Channel Plan Tag", "wisun.lusie.channeltag", FT_UINT8, BASE_DEC, NULL, 0x0,
2041
14
            NULL, HFILL }
2042
14
        },
2043
2044
14
        { &hf_wisun_flusie,
2045
14
          { "FLUS-IE", "wisun.flusie", FT_NONE, BASE_NONE, NULL, 0x0,
2046
14
            "FFN for LFN Unicast Schedule IE", HFILL }
2047
14
        },
2048
2049
14
        { &hf_wisun_flusie_dwell_interval,
2050
14
          { "Dwell Interval", "wisun.flusie.dwell", FT_UINT8, BASE_DEC, NULL, 0x0,
2051
14
            NULL, HFILL }
2052
14
        },
2053
2054
14
        { &hf_wisun_flusie_channel_plan_tag,
2055
14
          { "Channel Plan Tag", "wisun.flusie.channeltag", FT_UINT8, BASE_DEC, NULL, 0x0,
2056
14
            NULL, HFILL }
2057
14
        },
2058
2059
14
        { &hf_wisun_lbsie,
2060
14
          { "LBS-IE", "wisun.lbsie", FT_NONE, BASE_NONE, NULL, 0x0,
2061
14
            "LFN Broadcast Schedule IE", HFILL }
2062
14
        },
2063
2064
14
        { &hf_wisun_lbsie_broadcast_interval,
2065
14
          { "Broadcast Interval", "wisun.lbsie.broadcast", FT_UINT24, BASE_DEC, NULL, 0x0,
2066
14
            NULL, HFILL }
2067
14
        },
2068
2069
14
        { &hf_wisun_lbsie_broadcast_id,
2070
14
          { "Broadcast Schedule Identifier", "wisun.lbsie.broadcast_id", FT_UINT16, BASE_DEC, NULL, 0x0,
2071
14
            NULL, HFILL }
2072
14
        },
2073
2074
14
        { &hf_wisun_lbsie_channel_plan_tag,
2075
14
          { "Channel Plan Tag", "wisun.lbsie.channeltag", FT_UINT8, BASE_DEC, NULL, 0x0,
2076
14
            NULL, HFILL }
2077
14
        },
2078
2079
14
        { &hf_wisun_lbsie_broadcast_sync_period,
2080
14
          { "Broadcast Sync Period", "wisun.lbsie.broadcast_sync_period", FT_UINT8, BASE_DEC, NULL, 0x0,
2081
14
            NULL, HFILL }
2082
14
        },
2083
2084
14
        { &hf_wisun_lndie,
2085
14
          { "LFN Network Discovery IE", "wisun.lndie", FT_NONE, BASE_NONE, NULL, 0x0,
2086
14
            NULL, HFILL }
2087
14
        },
2088
2089
14
        { &hf_wisun_lndie_response_threshold,
2090
14
          { "Response Threshold", "wisun.lndie.response_threshold", FT_UINT8, BASE_DEC, NULL, 0x0,
2091
14
            NULL, HFILL }
2092
14
        },
2093
2094
14
        { &hf_wisun_lndie_response_delay,
2095
14
          { "Response Delay", "wisun.lndie.response_delay", FT_UINT24, BASE_DEC, NULL, 0x0,
2096
14
            NULL, HFILL }
2097
14
        },
2098
2099
14
        { &hf_wisun_lndie_discovery_slot_time,
2100
14
          { "Discovery Slot Time (DST)", "wisun.lndie.discovery_slot_time", FT_UINT8, BASE_DEC, NULL, 0x0,
2101
14
            NULL, HFILL }
2102
14
        },
2103
2104
14
        { &hf_wisun_lndie_discovery_slots,
2105
14
          { "Discovery Slots", "wisun.lndie.discovery_slots", FT_UINT8, BASE_DEC, NULL, 0x0,
2106
14
            NULL, HFILL }
2107
14
        },
2108
2109
14
        { &hf_wisun_lndie_discovery_first_slot,
2110
14
          { "Discovery First Slot", "wisun.lndie.discovery_first_slot", FT_UINT16, BASE_DEC, NULL, 0x0,
2111
14
            NULL, HFILL }
2112
14
        },
2113
2114
14
        { &hf_wisun_ltoie,
2115
14
          { "LTO-IE", "wisun.ltoie", FT_NONE, BASE_NONE, NULL, 0x0,
2116
14
            "LFN Timing Offset IE", HFILL }
2117
14
        },
2118
2119
14
        { &hf_wisun_ltoie_offset,
2120
14
          { "Offset", "wisun.ltoie.offset", FT_UINT24, BASE_DEC, NULL, 0x0,
2121
14
            NULL, HFILL }
2122
14
        },
2123
2124
14
        { &hf_wisun_ltoie_listening_interval,
2125
14
          { "Adjusted Listening Interval", "wisun.ltoie.listening_interval", FT_UINT24, BASE_DEC, NULL, 0x0,
2126
14
            NULL, HFILL }
2127
14
        },
2128
2129
14
        { &hf_wisun_panidie,
2130
14
          { "PANID-IE", "wisun.panidie", FT_NONE, BASE_NONE, NULL, 0x0,
2131
14
            "PAN Identifier IE", HFILL }
2132
14
        },
2133
2134
14
        { &hf_wisun_panidie_panid,
2135
14
          { "PAN Identifier", "wisun.panidie.panid", FT_UINT16, BASE_DEC, NULL, 0x0,
2136
14
            NULL, HFILL }
2137
14
        },
2138
2139
14
        { &hf_wisun_rtie,
2140
14
          { "Rendezvous Time IE", "wisun.rtie", FT_NONE, BASE_NONE, NULL, 0x0,
2141
14
            NULL, HFILL }
2142
14
        },
2143
2144
14
        { &hf_wisun_rtie_rendezvous_time,
2145
14
          { "Rendezvous Time", "wisun.rtie.rendezvous", FT_UINT16, BASE_DEC, NULL, 0x0,
2146
14
            NULL, HFILL }
2147
14
        },
2148
2149
14
        { &hf_wisun_rtie_wakeup_interval,
2150
14
          { "Wake-up Interval", "wisun.rtie.wakeup", FT_UINT16, BASE_DEC, NULL, 0x0,
2151
14
            NULL, HFILL }
2152
14
        },
2153
2154
14
        { &hf_wisun_lbcie,
2155
14
          { "LFN Broadcast Configuration IE", "wisun.lbcie", FT_NONE, BASE_NONE, NULL, 0x0,
2156
14
            NULL, HFILL }
2157
14
        },
2158
2159
14
        { &hf_wisun_lbcie_broadcast_interval,
2160
14
          { "Broadcast Interval", "wisun.lbcie.broadcast", FT_UINT24, BASE_DEC, NULL, 0x0,
2161
14
            NULL, HFILL }
2162
14
        },
2163
2164
14
        { &hf_wisun_lbcie_broadcast_sync_period,
2165
14
          { "Broadcast Sync Period", "wisun.lbcie.broadcast_sync_period", FT_UINT8, BASE_DEC, NULL, 0x0,
2166
14
            NULL, HFILL }
2167
14
        },
2168
2169
        /* Wi-SUN Payload IE */
2170
14
        { &hf_wisun_pie,
2171
14
          { "Wi-SUN Payload IE", "wisun.pie", FT_NONE, BASE_NONE, NULL, 0x0,
2172
14
            NULL, HFILL }
2173
14
        },
2174
2175
14
        { &hf_wisun_wsie,
2176
14
          { "Wi-SUN Sub IE", "wisun.wsie", FT_UINT16, BASE_HEX, NULL, 0x0,
2177
14
            NULL, HFILL }
2178
14
        },
2179
2180
14
        { &hf_wisun_wsie_type,
2181
14
          { "Type", "wisun.wsie.type", FT_UINT16, BASE_DEC, VALS(wisun_wsie_types), IEEE802154_PSIE_TYPE_MASK,
2182
14
            NULL, HFILL }
2183
14
        },
2184
2185
14
        { &hf_wisun_wsie_id,
2186
14
          { "Sub ID", "wisun.wsie.id", FT_UINT16, BASE_HEX, VALS(wisun_wsie_names), IEEE802154_PSIE_ID_MASK_LONG,
2187
14
            NULL, HFILL }
2188
14
        },
2189
2190
14
        { &hf_wisun_wsie_length,
2191
14
          { "Length", "wisun.wsie.length", FT_UINT16, BASE_DEC, NULL, IEEE802154_PSIE_LENGTH_MASK_LONG,
2192
14
            NULL, HFILL }
2193
14
        },
2194
2195
14
        { &hf_wisun_wsie_id_short,
2196
14
          { "Sub ID", "wisun.wsie.id", FT_UINT16, BASE_HEX, VALS(wisun_wsie_names_short), IEEE802154_PSIE_ID_MASK_SHORT,
2197
14
            NULL, HFILL }
2198
14
        },
2199
2200
14
        { &hf_wisun_wsie_length_short,
2201
14
          { "Length", "wisun.wsie.length", FT_UINT16, BASE_DEC, NULL, IEEE802154_PSIE_LENGTH_MASK_SHORT,
2202
14
            NULL, HFILL }
2203
14
        },
2204
2205
14
        { &hf_wisun_usie,
2206
14
          { "Unicast Schedule IE", "wisun.usie", FT_NONE, BASE_NONE, NULL, 0x0,
2207
14
            NULL, HFILL }
2208
14
        },
2209
2210
14
        { &hf_wisun_usie_dwell_interval,
2211
14
          { "Dwell Interval", "wisun.usie.dwell", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
2212
14
            NULL, HFILL }
2213
14
        },
2214
2215
14
        { &hf_wisun_usie_clock_drift,
2216
14
          { "Clock Drift", "wisun.usie.drift", FT_UINT8, BASE_DEC|BASE_SPECIAL_VALS, VALS(wisun_usie_clock_drift_names), 0x0,
2217
14
            "Clock Drift in +/- ppm", HFILL }
2218
14
        },
2219
2220
14
        { &hf_wisun_usie_timing_accuracy,
2221
14
          { "Timing Accuracy", "wisun.usie.accuracy", FT_UINT8, BASE_DEC, NULL, 0x0,
2222
14
            NULL, HFILL }
2223
14
        },
2224
2225
14
        { &hf_wisun_usie_channel_control,
2226
14
          { "Channel Control", "wisun.usie.channel", FT_UINT8, BASE_HEX, NULL, 0x0,
2227
14
            NULL, HFILL }
2228
14
        },
2229
2230
14
        { &hf_wisun_usie_channel_plan,
2231
14
          { "Channel Plan", "wisun.usie.channel.plan", FT_UINT8, BASE_DEC, VALS(wisun_channel_plan_names), WISUN_CHANNEL_PLAN,
2232
14
            NULL, HFILL }
2233
14
        },
2234
2235
14
        { &hf_wisun_usie_channel_function,
2236
14
          { "Channel Function", "wisun.usie.channel.function", FT_UINT8, BASE_DEC, VALS(wisun_channel_function_names), WISUN_CHANNEL_FUNCTION,
2237
14
            NULL, HFILL }
2238
14
        },
2239
2240
14
        { &hf_wisun_usie_channel_exclude,
2241
14
          { "Excluded Channels", "wisun.usie.channel.exclude", FT_UINT8, BASE_DEC, VALS(wisun_channel_exclude_names), WISUN_CHANNEL_EXCLUDE,
2242
14
            NULL, HFILL }
2243
14
        },
2244
2245
14
        { &hf_wisun_usie_regulatory_domain,
2246
14
          { "Regulatory Domain", "wisun.usie.domain", FT_UINT8, BASE_DEC, VALS(wisun_channel_regulatory_domains_names), 0x0,
2247
14
            NULL, HFILL }
2248
14
        },
2249
2250
14
        { &hf_wisun_usie_operating_class,
2251
14
          { "Operating Class", "wisun.usie.class", FT_UINT8, BASE_DEC, NULL, 0x0,
2252
14
            NULL, HFILL }
2253
14
        },
2254
2255
14
        { &hf_wisun_usie_channel_plan_id,
2256
14
          { "Channel Plan ID", "wisun.usie.channel_plan_id", FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(wisun_channel_plan_id_names), 0x0,
2257
14
            NULL, HFILL }
2258
14
        },
2259
2260
14
        { &hf_wisun_usie_explicit,
2261
14
          { "Explicit Channel Plan", "wisun.usie.explicit", FT_UINT32, BASE_HEX, NULL, 0x0,
2262
14
            NULL, HFILL }
2263
14
        },
2264
2265
14
        { &hf_wisun_usie_explicit_frequency,
2266
14
          { "CH0 Frequency", "wisun.usie.explicit.frequency", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_khz), WISUN_CH_PLAN_EXPLICIT_FREQ,
2267
14
            NULL, HFILL }
2268
14
        },
2269
2270
14
        { &hf_wisun_usie_explicit_reserved,
2271
14
          { "Reserved", "wisun.usie.explicit.reserved", FT_UINT32, BASE_DEC, NULL, WISUN_CH_PLAN_EXPLICIT_RESERVED,
2272
14
            NULL, HFILL }
2273
14
        },
2274
2275
14
        { &hf_wisun_usie_explicit_spacing,
2276
14
          { "Channel Spacing", "wisun.usie.explicit.spacing", FT_UINT32, BASE_DEC, VALS(wisun_channel_spacing_names), WISUN_CH_PLAN_EXPLICIT_SPACING,
2277
14
            NULL, HFILL }
2278
14
        },
2279
2280
14
        { &hf_wisun_usie_number_channels,
2281
14
          { "Number of Channels", "wisun.usie.num_channels", FT_UINT16, BASE_DEC, NULL, 0x0,
2282
14
            NULL, HFILL }
2283
14
        },
2284
2285
14
        { &hf_wisun_usie_fixed_channel,
2286
14
          { "Fixed Channel", "wisun.usie.fixed_channel", FT_UINT16, BASE_DEC, NULL, 0x0,
2287
14
            NULL, HFILL }
2288
14
        },
2289
2290
14
        { &hf_wisun_usie_hop_count,
2291
14
          { "Channel Hop Count", "wisun.usie.hop_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2292
14
            NULL, HFILL }
2293
14
        },
2294
2295
14
        { &hf_wisun_usie_hop_list,
2296
14
          { "Channel Hop List", "wisun.usie.hop_list", FT_UINT8, BASE_DEC, NULL, 0x0,
2297
14
            NULL, HFILL }
2298
14
        },
2299
2300
14
        { &hf_wisun_usie_number_ranges,
2301
14
          { "Number of Excluded Ranges", "wisun.usie.num_ranges", FT_UINT8, BASE_DEC, NULL, 0x0,
2302
14
            NULL, HFILL }
2303
14
        },
2304
2305
14
        { &hf_wisun_usie_exclude_range_start,
2306
14
          { "Excluded Channel Range Start", "wisun.usie.exclude.range.start", FT_UINT16, BASE_DEC, NULL, 0x0,
2307
14
            NULL, HFILL }
2308
14
        },
2309
2310
14
        { &hf_wisun_usie_exclude_range_end,
2311
14
          { "Excluded Channel Range End", "wisun.usie.exclude.range.end", FT_UINT16, BASE_DEC, NULL, 0x0,
2312
14
            NULL, HFILL }
2313
14
        },
2314
2315
14
        { &hf_wisun_usie_exclude_mask,
2316
14
          { "Excluded Channel Mask", "wisun.usie.exclude.mask", FT_BYTES, BASE_NONE, NULL, 0x0,
2317
14
            NULL, HFILL }
2318
14
        },
2319
2320
14
        { &hf_wisun_bsie,
2321
14
          { "BS-IE", "wisun.bsie", FT_NONE, BASE_NONE, NULL, 0x0,
2322
14
            "Broadcast Schedule IE", HFILL }
2323
14
        },
2324
2325
14
        { &hf_wisun_bsie_bcast_interval,
2326
14
          { "Broadcast Interval", "wisun.bsie.interval", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
2327
14
            NULL, HFILL }
2328
14
        },
2329
2330
14
        { &hf_wisun_bsie_bcast_schedule_id,
2331
14
          { "Broadcast Schedule ID", "wisun.bsie.schedule", FT_UINT16, BASE_DEC, NULL, 0x0,
2332
14
            NULL, HFILL }
2333
14
        },
2334
2335
14
        { &hf_wisun_vpie,
2336
14
          { "Vendor Payload IE", "wisun.vpie", FT_NONE, BASE_NONE, NULL, 0x0,
2337
14
            NULL, HFILL }
2338
14
        },
2339
2340
14
        { &hf_wisun_vpie_vid,
2341
14
          { "Vendor ID", "wisun.vpie.vid", FT_UINT16, BASE_DEC, NULL, 0x0,
2342
14
            NULL, HFILL }
2343
14
        },
2344
2345
14
        { &hf_wisun_lcpie,
2346
14
          { "LCP-IE", "wisun.lcpie", FT_NONE, BASE_NONE, NULL, 0x0,
2347
14
            "LFN Channel Plan IE", HFILL }
2348
14
        },
2349
2350
14
        { &hf_wisun_lcpie_channel_plan_tag,
2351
14
          { "Channel Plan Tag", "wisun.lcpie.channeltag", FT_UINT8, BASE_DEC, NULL, 0x0,
2352
14
            NULL, HFILL }
2353
14
        },
2354
2355
14
        { &hf_wisun_panie,
2356
14
          { "PAN-IE", "wisun.panie", FT_NONE, BASE_NONE, NULL, 0x0,
2357
14
            "PAN Information IE", HFILL }
2358
14
        },
2359
2360
14
        { &hf_wisun_panie_size,
2361
14
          { "PAN Size", "wisun.panie.size", FT_UINT16, BASE_DEC, NULL, 0x0,
2362
14
            NULL, HFILL }
2363
14
        },
2364
2365
14
        { &hf_wisun_panie_cost,
2366
14
          { "Routing Cost", "wisun.panie.cost", FT_UINT16, BASE_DEC, NULL, 0x0,
2367
14
            NULL, HFILL }
2368
14
        },
2369
2370
14
        { &hf_wisun_panie_flags,
2371
14
          { "PAN Flags", "wisun.panie.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2372
14
            NULL, HFILL }
2373
14
        },
2374
2375
14
        { &hf_wisun_panie_flag_parent_bsie,
2376
14
          { "Use Parent BS-IE", "wisun.panie.flags.parent_bsie", FT_BOOLEAN, 8, NULL, 0x01,
2377
14
            NULL, HFILL }
2378
14
        },
2379
2380
14
        { &hf_wisun_panie_flag_routing_method,
2381
14
          { "Routing Method", "wisun.panie.flags.routing_method", FT_UINT8, BASE_HEX, VALS(wisun_routing_methods), 0x02,
2382
14
            NULL, HFILL }
2383
14
        },
2384
2385
14
        { &hf_wisun_panie_flag_lfn_window_style,
2386
14
          { "LFN Window Style", "wisun.panie.flags.lfn_window_style", FT_UINT8, BASE_DEC, VALS(wisun_window_style), 0x04,
2387
14
            NULL, HFILL }
2388
14
        },
2389
2390
14
        { &hf_wisun_panie_flag_version,
2391
14
          { "FAN TPS Version", "wisun.panie.flags.version", FT_UINT8, BASE_DEC, NULL, 0xe0,
2392
14
            NULL, HFILL }
2393
14
        },
2394
2395
14
        { &hf_wisun_netnameie,
2396
14
          { "Network Name IE", "wisun.netnameie", FT_NONE, BASE_NONE, NULL, 0x0,
2397
14
            NULL, HFILL }
2398
14
        },
2399
2400
14
        { &hf_wisun_netnameie_name,
2401
14
          { "Network Name", "wisun.netnameie.name", FT_STRING, BASE_NONE, NULL, 0x0,
2402
14
            NULL, HFILL }
2403
14
        },
2404
2405
14
        { &hf_wisun_panverie,
2406
14
          { "PAN Version IE", "wisun.panverie", FT_NONE, BASE_NONE, NULL, 0x0,
2407
14
            NULL, HFILL }
2408
14
        },
2409
2410
14
        { &hf_wisun_panverie_version,
2411
14
          { "PAN Version", "wisun.panverie.version", FT_UINT16, BASE_DEC, NULL, 0x0,
2412
14
            NULL, HFILL }
2413
14
        },
2414
2415
14
        { &hf_wisun_gtkhashie,
2416
14
          { "GTK Hash IE", "wisun.gtkhashie", FT_NONE, BASE_NONE, NULL, 0x0,
2417
14
            NULL, HFILL }
2418
14
        },
2419
2420
14
        { &hf_wisun_gtkhashie_gtk0,
2421
14
          { "GTK0 Hash", "wisun.gtkhashie.gtk0", FT_BYTES, BASE_NONE, NULL, 0x0,
2422
14
            NULL, HFILL }
2423
14
        },
2424
2425
14
        { &hf_wisun_gtkhashie_gtk1,
2426
14
          { "GTK1 Hash", "wisun.gtkhashie.gtk1", FT_BYTES, BASE_NONE, NULL, 0x0,
2427
14
            NULL, HFILL }
2428
14
        },
2429
2430
14
        { &hf_wisun_gtkhashie_gtk2,
2431
14
          { "GTK2 Hash", "wisun.gtkhashie.gtk2", FT_BYTES, BASE_NONE, NULL, 0x0,
2432
14
            NULL, HFILL }
2433
14
        },
2434
2435
14
        { &hf_wisun_gtkhashie_gtk3,
2436
14
          { "GTK3 Hash", "wisun.gtkhashie.gtk3", FT_BYTES, BASE_NONE, NULL, 0x0,
2437
14
            NULL, HFILL }
2438
14
        },
2439
2440
14
        { &hf_wisun_pomie,
2441
14
          { "POM-IE", "wisun.pomie", FT_NONE, BASE_NONE, NULL, 0x0,
2442
14
            "PHY Operating Modes IE", HFILL }
2443
14
        },
2444
2445
14
        { &hf_wisun_pomie_hdr,
2446
14
          { "PHY Operating Modes Header", "wisun.pomie.hdr", FT_UINT8, BASE_HEX | BASE_NO_DISPLAY_VALUE, NULL, 0x0,
2447
14
            NULL, HFILL }
2448
14
        },
2449
2450
14
        { &hf_wisun_pomie_number_operating_modes,
2451
14
          { "Number of PHY Operating Modes", "wisun.pomie.number_operating_modes", FT_UINT8, BASE_DEC, NULL, 0x0F,
2452
14
            NULL, HFILL }
2453
14
        },
2454
2455
14
        { &hf_wisun_pomie_mdr_command_capable_flag,
2456
14
          { "MDR Command Capable Flag", "wisun.pomie.mdr_command_capable_flag", FT_UINT8, BASE_DEC, NULL, 0x10,
2457
14
            NULL, HFILL }
2458
14
        },
2459
2460
14
        { &hf_wisun_pomie_reserved,
2461
14
          { "Reserved", "wisun.pomie.reserved", FT_UINT8, BASE_DEC, NULL, 0xE0,
2462
14
            NULL, HFILL }
2463
14
        },
2464
2465
14
        { &hf_wisun_pomie_phy_mode_id,
2466
14
          { "PHY Operating Modes ID", "wisun.pomie.phy_mode_id", FT_UINT8, BASE_HEX | BASE_NO_DISPLAY_VALUE, NULL, 0x0,
2467
14
            NULL, HFILL }
2468
14
        },
2469
2470
14
        { &hf_wisun_pomie_phy_type,
2471
14
          { "PHY Type", "wisun.pomie.phy_type", FT_UINT8, BASE_HEX, VALS(wisun_phy_type_vals), WISUN_PIE_PHY_TYPE,
2472
14
            NULL, HFILL }
2473
14
        },
2474
2475
14
        { &hf_wisun_pomie_phy_mode_fsk,
2476
14
          { "PHY Mode FSK", "wisun.pomie.phy_mode_fsk", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(wisun_phy_mode_fsk_vals), WISUN_PIE_PHY_OPERATING_MODES_MASK,
2477
14
            NULL, HFILL }
2478
14
        },
2479
2480
14
        { &hf_wisun_pomie_phy_mode_ofdm,
2481
14
          { "PHY Mode OFDM", "wisun.pomie.phy_mode_ofdm", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(wisun_phy_mode_ofdm_vals), WISUN_PIE_PHY_OPERATING_MODES_MASK,
2482
14
            NULL, HFILL }
2483
14
        },
2484
2485
14
        { &hf_wisun_lfnverie,
2486
14
          { "LFN Version IE", "wisun.lfnverie", FT_NONE, BASE_NONE, NULL, 0x0,
2487
14
            NULL, HFILL }
2488
14
        },
2489
2490
14
        { &hf_wisun_lfnverie_version,
2491
14
          { "LFN Version", "wisun.lfnverie.version", FT_UINT16, BASE_DEC, NULL, 0x0,
2492
14
            NULL, HFILL }
2493
14
        },
2494
2495
14
        { &hf_wisun_lgtkhashie,
2496
14
          { "LFN GTK Hash IE", "wisun.lgtkhashie", FT_NONE, BASE_NONE, NULL, 0x0,
2497
14
            NULL, HFILL }
2498
14
        },
2499
2500
14
        { &hf_wisun_lgtkhashie_flags,
2501
14
          { "LFN GTK Hash Flags", "wisun.lgtkhashie.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2502
14
            NULL, HFILL }
2503
14
        },
2504
2505
14
        { &hf_wisun_lgtkhashie_flag_includes_lgtk0,
2506
14
          { "LFN GTK Hash Flag Includes LGTK0", "wisun.lgtkhashie.flag.includes_lgtk0", FT_BOOLEAN, 8, NULL, 0x01,
2507
14
            NULL, HFILL }
2508
14
        },
2509
2510
14
        { &hf_wisun_lgtkhashie_flag_includes_lgtk1,
2511
14
          { "LFN GTK Hash Flag Includes LGTK1", "wisun.lgtkhashie.flag.includes_lgtk1", FT_BOOLEAN, 8, NULL, 0x02,
2512
14
            NULL, HFILL }
2513
14
        },
2514
2515
14
        { &hf_wisun_lgtkhashie_flag_includes_lgtk2,
2516
14
          { "LFN GTK Hash Flag Includes LGTK2", "wisun.lgtkhashie.flag.includes_lgtk2", FT_BOOLEAN, 8, NULL, 0x04,
2517
14
            NULL, HFILL }
2518
14
        },
2519
2520
14
        { &hf_wisun_lgtkhashie_flag_active_lgtk_index,
2521
14
          { "LFN GTK Hash Flag Active LGTK Index", "wisun.lgtkhashie.flag.active_lgtk_index", FT_UINT8, BASE_DEC, NULL, 0x18,
2522
14
            NULL, HFILL }
2523
14
        },
2524
2525
14
        { &hf_wisun_lgtkhashie_gtk0,
2526
14
          { "LGTK0 Hash", "wisun.lgtkhashie.lgtk0", FT_BYTES, BASE_NONE, NULL, 0x0,
2527
14
            NULL, HFILL }
2528
14
        },
2529
2530
14
        { &hf_wisun_lgtkhashie_gtk1,
2531
14
          { "LGTK1 Hash", "wisun.lgtkhashie.lgtk1", FT_BYTES, BASE_NONE, NULL, 0x0,
2532
14
            NULL, HFILL }
2533
14
        },
2534
2535
14
        { &hf_wisun_lgtkhashie_gtk2,
2536
14
          { "LGTK2 Hash", "wisun.lgtkhashie.lgtk2", FT_BYTES, BASE_NONE, NULL, 0x0,
2537
14
            NULL, HFILL }
2538
14
        },
2539
2540
14
        { &hf_wisun_lbatsie,
2541
14
          { "LBATS-IE", "wisun.lbatsie", FT_NONE, BASE_NONE, NULL, 0x0,
2542
14
            "LFN Broadcast Additional Transmit Schedule IE", HFILL }
2543
14
        },
2544
2545
14
        { &hf_wisun_lbatsie_additional_tx,
2546
14
          { "Additional Transmissions", "wisun.lbatsie.additional_tx", FT_UINT8, BASE_DEC, NULL, 0x0,
2547
14
            NULL, HFILL }
2548
14
        },
2549
2550
14
        { &hf_wisun_lbatsie_next_tx_delay,
2551
14
          { "Next Transmit Delay", "wisun.lbatsie.next_tx_delay", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0,
2552
14
            NULL, HFILL }
2553
14
        },
2554
2555
14
        { &hf_wisun_jmie,
2556
14
          { "JM-IE", "wisun.jmie", FT_NONE, BASE_NONE, NULL, 0x0,
2557
14
            "Join Metrics IE", HFILL }
2558
14
        },
2559
2560
14
        { &hf_wisun_jmie_version,
2561
14
          { "Content Version", "wisun.jmie.version", FT_UINT8, BASE_DEC, NULL, 0x0,
2562
14
            NULL, HFILL }
2563
14
        },
2564
2565
14
        { &hf_wisun_jmie_metric_hdr,
2566
14
          { "Metric Header", "wisun.jmie.metric.hdr", FT_UINT8, BASE_HEX, NULL, 0x0,
2567
14
            NULL, HFILL }
2568
14
        },
2569
2570
14
        { &hf_wisun_jmie_metric_id,
2571
14
          { "Metric ID", "wisun.jmie.metric.id", FT_UINT8, BASE_DEC, VALS(wisun_metric_id), WISUN_PIE_JM_ID_MASK,
2572
14
            NULL, HFILL }
2573
14
        },
2574
2575
14
        { &hf_wisun_jmie_metric_len,
2576
14
          { "Metric Length", "wisun.jmie.metric.len", FT_UINT8, BASE_DEC, VALS(wisun_metric_len), WISUN_PIE_JM_LEN_MASK,
2577
14
            NULL, HFILL }
2578
14
        },
2579
2580
14
        { &hf_wisun_jmie_metric_plf,
2581
14
          { "JM-PLF", "wisun.jmie.metric.plf", FT_NONE, BASE_NONE, NULL, 0x0,
2582
14
            NULL, HFILL }
2583
14
        },
2584
2585
14
        { &hf_wisun_jmie_metric_plf_data,
2586
14
          { "PAN Load Factor", "wisun.jmie.metric.plf.data", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_percent), 0x0,
2587
14
            NULL, HFILL }
2588
14
        },
2589
2590
14
        { &hf_wisun_jmie_metric_unknown,
2591
14
          { "Unknown Metric", "wisun.jmie.metric.unknown", FT_NONE, BASE_NONE, NULL, 0x0,
2592
14
            NULL, HFILL }
2593
14
        },
2594
2595
        /* Wi-SUN FAN Security Extension */
2596
14
        { &hf_wisun_sec_function,
2597
14
          { "Function Code", "wisun.sec.function", FT_UINT8, BASE_HEX, VALS(wisun_sec_functions), 0x0,
2598
14
            NULL, HFILL }
2599
14
        },
2600
2601
14
        { &hf_wisun_sec_error_type,
2602
14
          { "Error Type", "wisun.sec.error", FT_UINT8, BASE_HEX, VALS(wisun_sec_sm_errors), 0x0,
2603
14
            NULL, HFILL }
2604
14
        },
2605
2606
14
        { &hf_wisun_sec_error_nonce,
2607
14
          { "Initiator Nonce", "wisun.sec.nonce", FT_BYTES, BASE_NONE, NULL, 0x0,
2608
14
            NULL, HFILL }
2609
14
        },
2610
2611
        /* EAPOL Relay */
2612
14
        { &hf_wisun_eapol_relay_sup,
2613
14
          { "SUP EUI-64", "wisun.eapol_relay.sup", FT_EUI64, BASE_NONE, NULL, 0x0,
2614
14
          NULL, HFILL }},
2615
2616
14
        { &hf_wisun_eapol_relay_kmp_id,
2617
14
          { "KMP ID", "wisun.eapol_relay.kmp_id", FT_UINT8, BASE_DEC, VALS(ieee802154_mpx_kmp_id_vals), 0x0,
2618
14
          NULL, HFILL }},
2619
2620
14
        { &hf_wisun_eapol_relay_direction,
2621
14
          { "Direction", "wisun.eapol_relay.direction", FT_BOOLEAN, BASE_NONE, TFS(&tfs_up_down), 0x0,
2622
14
          NULL, HFILL }},
2623
2624
14
        { &hf_wisun_cmd_subid,
2625
14
          { "Command Sub-ID", "wisun.cmd", FT_UINT8, BASE_DEC, VALS(wisun_cmd_vals), 0x0,
2626
14
            "Wi-SUN MAC Command Sub-ID", HFILL }},
2627
2628
14
        { &hf_wisun_cmd_mdr_phy_mode_id,
2629
14
          { "PHY Mode ID", "wisun.cmd.mdr.phy_mode_id", FT_UINT8, BASE_DEC, NULL, 0x0,
2630
14
            NULL, HFILL }},
2631
2632
14
        { &hf_wisun_cmd_mdr_phy_type,
2633
14
          { "PHY Type", "wisun.cmd.mdr.phy_type", FT_UINT8, BASE_HEX, VALS(wisun_phy_type_vals), WISUN_PIE_PHY_TYPE,
2634
14
            NULL, HFILL }
2635
14
        },
2636
2637
14
        { &hf_wisun_cmd_mdr_phy_mode_fsk,
2638
14
          { "PHY Mode FSK", "wisun.cmd.mdr.phy_mode_fsk", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(wisun_phy_mode_fsk_vals), WISUN_PIE_PHY_OPERATING_MODES_MASK,
2639
14
            NULL, HFILL }
2640
14
        },
2641
2642
14
        { &hf_wisun_cmd_mdr_phy_mode_ofdm,
2643
14
          { "PHY Mode OFDM", "wisun.cmd.mdr.phy_mode_ofdm", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(wisun_phy_mode_ofdm_vals), WISUN_PIE_PHY_OPERATING_MODES_MASK,
2644
14
            NULL, HFILL }
2645
14
        },
2646
2647
        /* Wi-SUN Netricity */
2648
14
        { &hf_wisun_netricity_nftie,
2649
14
          { "Netricity Frame Type IE", "wisun.netricity.nftie", FT_NONE, BASE_NONE, NULL, 0x0,
2650
14
            NULL, HFILL }
2651
14
        },
2652
2653
14
        { &hf_wisun_netricity_nftie_type,
2654
14
          { "Frame Type", "wisun.netricity.nftie.type", FT_UINT8, BASE_DEC, VALS(wisun_frame_type_vals), 0x0,
2655
14
            NULL, HFILL }
2656
14
        },
2657
2658
14
        { &hf_wisun_netricity_lqiie,
2659
14
          { "Link Quality Index IE", "wisun.netricity.lqiie", FT_NONE, BASE_NONE, NULL, 0x0,
2660
14
            NULL, HFILL }
2661
14
        },
2662
2663
14
        { &hf_wisun_netricity_lqiie_lqi,
2664
14
          { "Link Quality Index", "wisun.netricity.lqiie.lqi", FT_UINT8, BASE_DEC, NULL, 0x0,
2665
14
            NULL, HFILL }
2666
14
        },
2667
2668
        /* Wi-SUN Netricity Segment Control Field and reassembly */
2669
14
        { &hf_wisun_netricity_sc_flags,
2670
14
          { "Segment Control", "wisun.netricity.sc.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2671
14
            NULL, HFILL }
2672
14
        },
2673
14
        { &hf_wisun_netricity_sc_reserved,
2674
14
          { "Reserved", "wisun.netricity.sc.reserved", FT_UINT8, BASE_DEC, NULL, 0xf0,
2675
14
            NULL, HFILL }
2676
14
        },
2677
14
        { &hf_wisun_netricity_sc_tone_map_request,
2678
14
          { "Tone Map Request", "wisun.netricity.sc.tone_map_request", FT_BOOLEAN, 8, NULL, 1<<3,
2679
14
            NULL, HFILL }
2680
14
        },
2681
14
        { &hf_wisun_netricity_sc_contention_control,
2682
14
          { "Contention Control", "wisun.netricity.sc.contention_control", FT_BOOLEAN, 8, TFS(&wisun_netricity_sc_contention_control_tfs), 1<<2,
2683
14
            NULL, HFILL }
2684
14
        },
2685
14
        { &hf_wisun_netricity_sc_channel_access_priority,
2686
14
          { "Channel access priority", "wisun.netricity.sc.channel_access_priority", FT_BOOLEAN, 8, TFS(&tfs_high_normal), 1<<1,
2687
14
            NULL, HFILL }
2688
14
        },
2689
14
        { &hf_wisun_netricity_sc_last_segment,
2690
14
          { "Last Segment", "wisun.netricity.sc.last_segment", FT_BOOLEAN, 8, NULL, 1<<0,
2691
14
            NULL, HFILL }
2692
14
        },
2693
14
        { &hf_wisun_netricity_sc_segment_count,
2694
14
          { "Segment Count", "wisun.netricity.sc.segment_count", FT_UINT16, BASE_DEC, NULL, 0xfc00,
2695
14
            NULL, HFILL }
2696
14
        },
2697
14
        { &hf_wisun_netricity_sc_segment_length,
2698
14
          { "Segment Length", "wisun.netricity.sc.segment_length", FT_UINT16, BASE_DEC, NULL, 0x03ff,
2699
14
            NULL, HFILL }
2700
14
        },
2701
2702
14
        { &hf_wisun_netricity_scr_segments,
2703
14
          { "Message segments", "wisun.netricity.scr.segments",
2704
14
            FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
2705
14
        },
2706
14
        { &hf_wisun_netricity_scr_segment,
2707
14
          { "Message segment", "wisun.netricity.scr.segment",
2708
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2709
14
        },
2710
14
        { &hf_wisun_netricity_scr_segment_overlap,
2711
14
          { "Message segment overlap", "wisun.netricity.scr.segment.overlap",
2712
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2713
14
        },
2714
14
        { &hf_wisun_netricity_scr_segment_overlap_conflicts,
2715
14
          { "Message segment overlapping with conflicting data", "wisun.netricity.scr.segment.overlap.conflicts",
2716
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2717
14
        },
2718
14
        { &hf_wisun_netricity_scr_segment_multiple_tails,
2719
14
          { "Message has multiple tail segments", "wisun.netricity.scr.segment.multiple_tails",
2720
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2721
14
        },
2722
14
        { &hf_wisun_netricity_scr_segment_too_long_segment,
2723
14
          { "Message segment too long", "wisun.netricity.scr.segment.too_long_segment",
2724
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2725
14
        },
2726
14
        { &hf_wisun_netricity_scr_segment_error,
2727
14
          { "Message segment reassembly error", "wisun.netricity.scr.segment.error",
2728
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2729
14
        },
2730
14
        { &hf_wisun_netricity_scr_segment_count,
2731
14
          { "Message segment count", "wisun.netricity.scr.segment.count",
2732
14
            FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
2733
14
        },
2734
14
        { &hf_wisun_netricity_scr_reassembled_in,
2735
14
          { "Reassembled in", "wisun.netricity.scr.reassembled.in",
2736
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2737
14
        },
2738
14
        { &hf_wisun_netricity_scr_reassembled_length,
2739
14
          { "Reassembled length", "wisun.netricity.scr.reassembled.length",
2740
14
            FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
2741
14
        },
2742
2743
2744
14
    };
2745
2746
    /* Subtrees */
2747
14
    static int *ett[] = {
2748
14
        &ett_wisun_phy_mode_id,
2749
14
        &ett_wisun_unknown_ie,
2750
14
        &ett_wisun_uttie,
2751
14
        &ett_wisun_btie,
2752
14
        &ett_wisun_fcie,
2753
14
        &ett_wisun_rslie,
2754
14
        &ett_wisun_vhie,
2755
14
        &ett_wisun_eaie,
2756
14
        &ett_wisun_pie,
2757
14
        &ett_wisun_wsie_bitmap,
2758
14
        &ett_wisun_usie,
2759
14
        &ett_wisun_bsie,
2760
14
        &ett_wisun_vpie,
2761
14
        &ett_wisun_lcpie,
2762
14
        &ett_wisun_usie_channel_control,
2763
14
        &ett_wisun_usie_explicit,
2764
14
        &ett_wisun_panie,
2765
14
        &ett_wisun_panie_flags,
2766
14
        &ett_wisun_netnameie,
2767
14
        &ett_wisun_panverie,
2768
14
        &ett_wisun_pomie,
2769
14
        &ett_wisun_pomie_hdr,
2770
14
        &ett_wisun_gtkhashie,
2771
14
        &ett_wisun_lfnverie,
2772
14
        &ett_wisun_lgtkhashie,
2773
14
        &ett_wisun_lgtkhashie_flags,
2774
14
        &ett_wisun_lbatsie,
2775
14
        &ett_wisun_jmie,
2776
14
        &ett_wisun_jmie_metric_hdr,
2777
14
        &ett_wisun_jmie_metric_plf,
2778
14
        &ett_wisun_jmie_metric_unknown,
2779
14
        &ett_wisun_sec,
2780
14
        &ett_wisun_eapol_relay,
2781
14
        &ett_wisun_netricity_nftie,
2782
14
        &ett_wisun_netricity_lqiie,
2783
14
        &ett_wisun_netricity_sc,
2784
14
        &ett_wisun_netricity_sc_bitmask,
2785
14
        &ett_wisun_netricity_scr_segment,
2786
14
        &ett_wisun_netricity_scr_segments,
2787
14
        &ett_wisun_luttie,
2788
14
        &ett_wisun_nrie,
2789
14
        &ett_wisun_lusie,
2790
14
        &ett_wisun_flusie,
2791
14
        &ett_wisun_lbsie,
2792
14
        &ett_wisun_lndie,
2793
14
        &ett_wisun_ltoie,
2794
14
        &ett_wisun_panidie,
2795
14
        &ett_wisun_rtie,
2796
14
        &ett_wisun_lbcie,
2797
14
    };
2798
2799
14
    static ei_register_info ei[] = {
2800
14
        { &ei_wisun_subid_unsupported, { "wisun.subid.unsupported", PI_PROTOCOL, PI_WARN,
2801
14
                "Unsupported Header Sub ID", EXPFILL }},
2802
14
        { &ei_wisun_usie_channel_plan_invalid, { "wisun.usie.channel.plan.invalid", PI_PROTOCOL, PI_WARN,
2803
14
                "Invalid Channel Plan", EXPFILL }},
2804
14
        { &ei_wisun_wsie_unsupported, { "wisun.wsie.unsupported", PI_PROTOCOL, PI_WARN,
2805
14
                "Unsupported Sub-IE ID", EXPFILL }},
2806
14
        { &ei_wisun_edfe_start_not_found, { "wisun.edfe.start_not_found", PI_SEQUENCE, PI_WARN,
2807
14
                "EDFE Transfer: start frame not found", EXPFILL }},
2808
14
        { &ei_wisun_usie_explicit_reserved_bits_not_zero, { "wisun.usie.explicit.reserved.invalid", PI_MALFORMED, PI_ERROR,
2809
14
                "Reserved bits not zero", EXPFILL }},
2810
14
        { &ei_wisun_nrie_reserved_bits_not_zero, { "wisun.nrie.reserved.invalid", PI_MALFORMED, PI_ERROR,
2811
14
                "Reserved bits not zero", EXPFILL }},
2812
14
        { &ei_wisun_jmie_metric_unsupported, { "wisun.jmie.metric.unsupported", PI_PROTOCOL, PI_WARN,
2813
14
                "Unsupported Metric ID", EXPFILL }},
2814
14
    };
2815
2816
14
    expert_module_t* expert_wisun;
2817
2818
14
    proto_wisun = proto_register_protocol("Wi-SUN Field Area Network", "Wi-SUN", "wisun");
2819
14
    proto_wisun_sec = proto_register_protocol("Wi-SUN FAN Security Extension", "Wi-SUN WM-SEC", "wisun.sec");
2820
14
    proto_wisun_eapol_relay = proto_register_protocol("Wi-SUN FAN EAPOL Relay", "Wi-SUN EAPOL Relay", "wisun.eapol_relay");
2821
14
    proto_wisun_netricity_sc = proto_register_protocol("Wi-SUN Netricity Segment", "Wi-SUN Netricity Segment", "wisun.netricity.sc");
2822
2823
14
    proto_register_field_array(proto_wisun, hf, array_length(hf));
2824
14
    proto_register_subtree_array(ett, array_length(ett));
2825
2826
14
    expert_wisun = expert_register_protocol(proto_wisun);
2827
14
    expert_register_field_array(expert_wisun, ei, array_length(ei));
2828
2829
14
    register_dissector("wisun.sec", dissect_wisun_sec, proto_wisun_sec);
2830
2831
14
    edfe_byaddr = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_int64_hash, g_int64_equal);
2832
2833
14
    wisun_eapol_relay_handle = register_dissector("wisun.eapol_relay", dissect_wisun_eapol_relay, proto_wisun_eapol_relay);
2834
2835
14
    register_dissector("wisun.netricity.sc", dissect_wisun_netricity_sc, proto_wisun_netricity_sc);
2836
14
    reassembly_table_register(&netricity_reassembly_table, &addresses_reassembly_table_functions);
2837
2838
14
    vhie_dissector_table = register_dissector_table("wisun.vhie.vid", "Wi-SUN Vendor Header IEs",
2839
14
                                                    proto_wisun, FT_UINT16, BASE_DEC);
2840
14
    vpie_dissector_table = register_dissector_table("wisun.vpie.vid", "Wi-SUN Vendor Payload IEs",
2841
14
                                                    proto_wisun, FT_UINT16, BASE_DEC);
2842
14
}
2843
2844
void proto_reg_handoff_wisun(void)
2845
14
{
2846
14
    dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_WISUN, create_dissector_handle(dissect_wisun_hie, proto_wisun));
2847
14
    dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_WISUN, create_dissector_handle(dissect_wisun_pie, proto_wisun));
2848
14
    dissector_add_uint(IEEE802154_CMD_VENDOR_DTABLE, OUI_WISUN, create_dissector_handle(dissect_wisun_cmd, proto_wisun));
2849
2850
14
    oid_add_from_string("id-kp-wisun-fan-device", "1.3.6.1.4.1.45605.1");
2851
2852
    // For EAPOL relay
2853
14
    dissector_add_uint("udp.port", WISUN_EAPOL_RELAY_UDP_PORT, wisun_eapol_relay_handle);
2854
14
    eapol_handle = find_dissector("eapol");
2855
2856
    // For Netricity reassembly
2857
14
    ieee802154_nofcs_handle = find_dissector("wpan_nofcs");
2858
2859
14
    proto_ieee802154 = proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN);
2860
14
}
2861
2862
/*
2863
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2864
 *
2865
 * Local variables:
2866
 * c-basic-offset: 4
2867
 * tab-width: 8
2868
 * indent-tabs-mode: nil
2869
 * End:
2870
 *
2871
 * vi: set shiftwidth=4 tabstop=8 expandtab:
2872
 * :indentSize=4:tabSize=8:noTabs=true:
2873
 */