Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-ieee802154.c
Line
Count
Source
1
/* packet-ieee802154.c
2
 *
3
 * Multipurpose frame support
4
 * By Devan Lai <devanl@davisinstruments.com>
5
 * Copyright 2019 Davis Instruments
6
 *
7
 * IEEE 802.15.4-2015 CCM* nonce for TSCH mode
8
 * By Maxime Brunelle <Maxime.Brunelle@trilliant.com>
9
 * Copyright 2019 Trilliant Inc.
10
 *
11
 * IEEE802154 TAP link type
12
 * By James Ko <jck@exegin.com>
13
 * Copyright 2019 Exegin Technologies Limited
14
 *
15
 * 4-byte FCS support and ACK tracking
16
 * By Carl Levesque Imbeault <carl.levesque@trilliant.com>
17
 * Copyright 2018 Trilliant Inc.
18
 * Integrated and added FCS type enum
19
 * by James Ko <jck@exegin.com>
20
 * Copyright 2019 Exegin Technologies Limited
21
 *
22
 * Auxiliary Security Header support and
23
 * option to force TI CC24xx FCS format
24
 * By Jean-Francois Wauthy <jfw@info.fundp.ac.be>
25
 * Copyright 2009 The University of Namur, Belgium
26
 *
27
 * IEEE 802.15.4 Dissectors for Wireshark
28
 * By Owen Kirby <osk@exegin.com>
29
 * Copyright 2007 Exegin Technologies Limited
30
 *
31
 * Wireshark - Network traffic analyzer
32
 * By Gerald Combs <gerald@wireshark.org>
33
 * Copyright 1998 Gerald Combs
34
 *
35
 * SPDX-License-Identifier: GPL-2.0-or-later
36
 *------------------------------------------------------------
37
 *
38
 *  In IEEE 802.15.4 packets, all fields are little endian. And
39
 *  Each byte is transmitted least significant bit first (reflected
40
 *  bit ordering).
41
 *------------------------------------------------------------
42
 *
43
 *  Most IEEE 802.15.4 Packets have the following format:
44
 *  |  FCF  |Seq No|  Addressing |         Data          |   FCS   |
45
 *  |2 bytes|1 byte|0 to 20 bytes|Length-(Overhead) bytes|2/4 Bytes|
46
 *------------------------------------------------------------
47
 *
48
 *  Multipurpose frame packets have the following format:
49
 *  |   FCF   | Seq No  |  Addressing |         Data          |  FCS  |
50
 *  |1/2 bytes|0/1 bytes|0 to 20 bytes|Length-(Overhead) bytes|2 bytes|
51
 *------------------------------------------------------------
52
 *
53
 *  CRC16 is calculated using the x^16 + x^12 + x^5 + 1 polynomial
54
 *  as specified by ITU-T, and is calculated over the IEEE 802.15.4
55
 *  packet (excluding the FCS) as transmitted over the air. Note,
56
 *  that because the least significant bits are transmitted first, this
57
 *  will require reversing the bit-order in each byte. Also, unlike
58
 *  most CRC algorithms, IEEE 802.15.4 uses an initial and final value
59
 *  of 0x0000, instead of 0xffff (which is used by the ITU-T).
60
 *
61
 *  For a 4-byte FCS, CRC32 is calculated using the ITU-T CRC32.
62
 *
63
 *  (Fun fact: the reference to "a 32-bit CRC equivalent to ANSI X3.66-1979"
64
 *  in IEEE Std 802.15.4-2015 nonwithstanding, ANSI X3.66-1979 does not
65
 *  describe any 32-bit CRC, only a 16-bit CRC from ITU-T V.41.  ITU-T
66
 *  V.42 describes both a 16-bit and 32-bit CRC; all the 16-bit CRCs
67
 *  floating around seem to use the same generator polynomial,
68
 *  x^16 + x^12 + x^5 + 1, but have different initial conditions and
69
 *  no-error final remainder; the 32-bit CRC from V.42 and the one
70
 *  described in IEEE Std 802.15.4-2015 also use the same generator
71
 *  polynomial.)
72
 *------------------------------------------------------------
73
 *
74
 *  This dissector supports both link-layer IEEE 802.15.4 captures
75
 *  and IEEE 802.15.4 packets encapsulated within other layers.
76
 *  Additionally, support has been provided for 16-bit and 32-bit
77
 *  FCS, as well as for frames with no FCS but with a 16-bit
78
 *  ChipCon/Texas Instruments CC24xx-style metadata field.
79
 *------------------------------------------------------------
80
 */
81
82
/*  Include files */
83
#include "config.h"
84
#include <epan/packet.h>
85
#include <epan/decode_as.h>
86
#include <epan/exceptions.h>
87
#include <epan/crc16-tvb.h>
88
#include <epan/crc32-tvb.h>
89
#include <epan/expert.h>
90
#include <epan/addr_resolv.h>
91
#include <epan/address_types.h>
92
#include <epan/conversation.h>
93
#include <epan/conversation_table.h>
94
#include <epan/conversation_filter.h>
95
#include <epan/prefs.h>
96
#include <epan/uat.h>
97
#include <epan/strutil.h>
98
#include <epan/to_str.h>
99
#include <epan/show_exception.h>
100
#include <epan/proto_data.h>
101
#include <epan/etypes.h>
102
#include <epan/oui.h>
103
#include <epan/tap.h>
104
#include <epan/tfs.h>
105
#include <epan/unit_strings.h>
106
#include <wsutil/pint.h>
107
108
/* Use libgcrypt for cipher libraries. */
109
#include <wsutil/wsgcrypt.h>
110
111
#include <wsutil/ws_padding_to.h>
112
113
#include "packet-ieee802154.h"
114
#include "packet-sll.h"
115
#include "packet-zbee-tlv.h"
116
117
void proto_register_ieee802154(void);
118
void proto_reg_handoff_ieee802154(void);
119
120
/* Dissection Options for dissect_ieee802154_common */
121
539
#define DISSECT_IEEE802154_OPTION_CC24xx    0x00000001 /* Frame has TI CC24xx metadata, not an FCS, at the end */
122
14.6k
#define DISSECT_IEEE802154_OPTION_ZBOSS     0x00000002 /* ZBOSS traffic dump */
123
124
/* ethertype for 802.15.4 tag - encapsulating an Ethernet packet */
125
static unsigned int ieee802154_ethertype = 0x809A;
126
127
static int ieee802154_fcs_type = IEEE802154_FCS_16_BIT;
128
129
/* 802.15.4 TAP Fields */
130
typedef enum {
131
    IEEE802154_TAP_FCS_TYPE             = 0x0000,
132
    IEEE802154_TAP_RSS                  = 0x0001,
133
    IEEE802154_TAP_BIT_RATE             = 0x0002,
134
    IEEE802154_TAP_CHANNEL_ASSIGNMENT   = 0x0003,
135
    IEEE802154_TAP_SUN_PHY_INFO         = 0x0004,
136
    IEEE802154_TAP_START_OF_FRAME_TS    = 0x0005,
137
    IEEE802154_TAP_END_OF_FRAME_TS      = 0x0006,
138
    IEEE802154_TAP_ASN                  = 0x0007,
139
    IEEE802154_TAP_SLOT_START_TS        = 0x0008,
140
    IEEE802154_TAP_TIMESLOT_LENGTH      = 0x0009,
141
    IEEE802154_TAP_LQI                  = 0x000A,
142
    IEEE802154_TAP_CHANNEL_FREQUENCY    = 0x000B,
143
    IEEE802154_TAP_CHANNEL_PLAN         = 0x000C,
144
    IEEE802154_TAP_PHY_HEADER           = 0x000D,
145
} ieee802154_info_type_t;
146
147
typedef enum {
148
    PHR_RAW             = 0,
149
    PHR_O_QPSK          = 1,
150
    PHR_CSS             = 2,
151
    PHR_HRP_UWB         = 3,
152
    PHR_MSK             = 4,
153
    PHR_LRP_UWB         = 5,
154
    PHR_SUN_FSK         = 6,
155
    PHR_SUN_OFDM        = 7,
156
    PHR_SUN_O_QPSK      = 8,
157
    PHR_LECIM_FSK       = 9,
158
    PHR_TVWS_FSK        = 10,
159
    PHR_TVWS_OFDM       = 11,
160
    PHR_TVWS_NB_OFDM    = 12,
161
    PHR_RCC_LMR         = 13,
162
    PHR_CMB_O_QPSK      = 14,
163
    PHR_CMB_GFSK        = 15,
164
    PHR_TASK            = 16,
165
    PHR_RS_GFSK         = 17,
166
    PHR_WISUN_FSK_MS    = 18,
167
} ieee802154_tap_phr_type_t;
168
169
typedef enum {
170
    IEEE802154_FCS_TYPE_NONE        = 0,
171
    IEEE802154_FCS_TYPE_16_BIT      = 1, /* ITU-T CRC16 */
172
    IEEE802154_FCS_TYPE_32_BIT      = 2, /* ITU-T CRC32 */
173
} ieee802154_fcs_type_t;
174
175
typedef enum {
176
    IEEE802154_SUN_TYPE_FSK_A       = 0x00,
177
    IEEE802154_SUN_TYPE_FSK_B       = 0x01,
178
    IEEE802154_SUN_TYPE_OQPSK_A     = 0x02,
179
    IEEE802154_SUN_TYPE_OQPSK_B     = 0x03,
180
    IEEE802154_SUN_TYPE_OQPSK_C     = 0x04,
181
    IEEE802154_SUN_TYPE_OFDM_OPT1   = 0x05,
182
    IEEE802154_SUN_TYPE_OFDM_OPT2   = 0x06,
183
    IEEE802154_SUN_TYPE_OFDM_OPT3   = 0x07,
184
    IEEE802154_SUN_TYPE_OFDM_OPT4   = 0x08,
185
} ieee802154_sun_type_t;
186
187
/* boolean value set if the FCS must be ok before payload is dissected */
188
static bool ieee802154_fcs_ok = true;
189
190
/* boolean value set to enable ack tracking */
191
static bool ieee802154_ack_tracking;
192
193
/* boolean value set to enable 802.15.4e dissection compatibility */
194
static bool ieee802154e_compatibility;
195
196
/* TSCH ASN for nonce in decryption */
197
static uint64_t ieee802154_tsch_asn;
198
199
static const char  *ieee802154_user    = "User";
200
201
static wmem_tree_t* mac_key_hash_handlers;
202
203
/*
204
 * Address Hash Tables
205
 *
206
 */
207
ieee802154_map_tab_t ieee802154_map = { NULL, NULL };
208
209
/*
210
 * Static Address Mapping UAT
211
 *
212
 */
213
/* UAT entry structure. */
214
typedef struct {
215
    unsigned char *eui64;
216
    unsigned   eui64_len;
217
    unsigned   addr16;
218
    unsigned   pan;
219
} static_addr_t;
220
221
/* UAT variables */
222
static uat_t         *static_addr_uat;
223
static static_addr_t *static_addrs;
224
static unsigned       num_static_addrs;
225
226
static void*
227
addr_uat_copy_cb(void *dest, const void *source, size_t len _U_)
228
0
{
229
0
    const static_addr_t* o = (const static_addr_t*)source;
230
0
    static_addr_t* d = (static_addr_t*)dest;
231
232
0
    d->eui64 = (unsigned char *)g_memdup2(o->eui64, o->eui64_len);
233
0
    d->eui64_len = o->eui64_len;
234
0
    d->addr16 = o->addr16;
235
0
    d->pan = o->pan;
236
237
0
    return dest;
238
0
}
239
240
/* Sanity-checks a UAT record. */
241
static bool
242
addr_uat_update_cb(void *r, char **err)
243
0
{
244
0
    static_addr_t *map = (static_addr_t *)r;
245
    /* Ensure a valid short address */
246
0
    if (map->addr16 >= IEEE802154_NO_ADDR16) {
247
0
        *err = g_strdup("Invalid short address");
248
0
        return false;
249
0
    }
250
    /* Ensure a valid PAN identifier. */
251
0
    if (map->pan >= IEEE802154_BCAST_PAN) {
252
0
        *err = g_strdup("Invalid PAN identifier");
253
0
        return false;
254
0
    }
255
    /* Ensure a valid EUI-64 length */
256
0
    if (map->eui64_len != sizeof(uint64_t)) {
257
0
        *err = g_strdup("Invalid EUI-64 length");
258
0
        return false;
259
0
    }
260
0
    return true;
261
0
} /* ieee802154_addr_uat_update_cb */
262
263
static void
264
addr_uat_free_cb(void *r)
265
0
{
266
0
    static_addr_t *rec = (static_addr_t *)r;
267
0
    g_free(rec->eui64);
268
0
}
269
270
/* Field callbacks. */
271
0
UAT_HEX_CB_DEF(addr_uat, addr16, static_addr_t)
Unexecuted instantiation: packet-ieee802154.c:addr_uat_addr16_set_cb
Unexecuted instantiation: packet-ieee802154.c:addr_uat_addr16_tostr_cb
272
0
UAT_HEX_CB_DEF(addr_uat, pan, static_addr_t)
Unexecuted instantiation: packet-ieee802154.c:addr_uat_pan_set_cb
Unexecuted instantiation: packet-ieee802154.c:addr_uat_pan_tostr_cb
273
0
UAT_BUFFER_CB_DEF(addr_uat, eui64, static_addr_t, eui64, eui64_len)
Unexecuted instantiation: packet-ieee802154.c:addr_uat_eui64_set_cb
Unexecuted instantiation: packet-ieee802154.c:addr_uat_eui64_tostr_cb
274
275
/*
276
 * Decryption Keys UAT
277
 */
278
279
/* UAT variables */
280
static uat_t            *ieee802154_key_uat;
281
static ieee802154_key_t *ieee802154_keys;
282
static unsigned          num_ieee802154_keys;
283
284
static void ieee802154_key_post_update_cb(void)
285
16
{
286
16
    unsigned i;
287
16
    GByteArray *bytes;
288
289
16
    for (i = 0; i < num_ieee802154_keys; i++)
290
0
    {
291
0
        switch (ieee802154_keys[i].hash_type) {
292
0
        case KEY_HASH_NONE:
293
0
        case KEY_HASH_ZIP:
294
            /* Get the IEEE 802.15.4 decryption key. */
295
0
            bytes = g_byte_array_new();
296
0
            if (hex_str_to_bytes(ieee802154_keys[i].pref_key, bytes, false))
297
0
            {
298
0
                if (ieee802154_keys[i].hash_type == KEY_HASH_ZIP) {
299
0
                    char digest[32];
300
301
0
                    if (!ws_hmac_buffer(GCRY_MD_SHA256, digest, "ZigBeeIP", 8, bytes->data, IEEE802154_CIPHER_SIZE)) {
302
                        /* Copy upper hashed bytes to the key */
303
0
                        memcpy(ieee802154_keys[i].key, &digest[IEEE802154_CIPHER_SIZE], IEEE802154_CIPHER_SIZE);
304
                        /* Copy lower hashed bytes to the MLE key */
305
0
                        memcpy(ieee802154_keys[i].mle_key, digest, IEEE802154_CIPHER_SIZE);
306
0
                    } else {
307
                        /* Just copy the keys verbatim */
308
0
                        memcpy(ieee802154_keys[i].key, bytes->data, IEEE802154_CIPHER_SIZE);
309
0
                        memcpy(ieee802154_keys[i].mle_key, bytes->data, IEEE802154_CIPHER_SIZE);
310
0
                    }
311
0
                } else {
312
                    /* Just copy the keys verbatim */
313
0
                    memcpy(ieee802154_keys[i].key, bytes->data, IEEE802154_CIPHER_SIZE);
314
0
                    memcpy(ieee802154_keys[i].mle_key, bytes->data, IEEE802154_CIPHER_SIZE);
315
0
                }
316
0
            }
317
0
            g_byte_array_free(bytes, true);
318
0
            break;
319
0
        case KEY_HASH_THREAD:
320
            /* XXX - TODO? */
321
0
            break;
322
0
        }
323
0
    }
324
16
}
325
326
static bool ieee802154_key_update_cb(void *r, char **err)
327
0
{
328
0
    ieee802154_key_t* rec = (ieee802154_key_t*)r;
329
0
    GByteArray *bytes;
330
331
0
    switch (rec->hash_type) {
332
0
    case KEY_HASH_NONE:
333
0
    case KEY_HASH_ZIP:
334
0
        bytes = g_byte_array_new();
335
0
        if (hex_str_to_bytes(rec->pref_key, bytes, false) == false)
336
0
        {
337
0
            *err = g_strdup("Invalid key");
338
0
            g_byte_array_free(bytes, true);
339
0
            return false;
340
0
        }
341
342
0
        if (bytes->len < IEEE802154_CIPHER_SIZE)
343
0
        {
344
0
            *err = ws_strdup_printf("Key must be at least %d bytes", IEEE802154_CIPHER_SIZE);
345
0
            g_byte_array_free(bytes, true);
346
0
            return false;
347
0
        }
348
0
        g_byte_array_free(bytes, true);
349
0
        break;
350
0
    case KEY_HASH_THREAD:
351
        /* XXX - TODO? */
352
0
        break;
353
0
    }
354
355
0
    return true;
356
0
}
357
358
0
static void* ieee802154_key_copy_cb(void* n, const void* o, size_t siz _U_) {
359
0
    ieee802154_key_t* new_record = (ieee802154_key_t*)n;
360
0
    const ieee802154_key_t* old_record = (const ieee802154_key_t*)o;
361
362
0
    new_record->pref_key = g_strdup(old_record->pref_key);
363
0
    new_record->key_index = old_record->key_index;
364
0
    new_record->hash_type = old_record->hash_type;
365
366
0
    return new_record;
367
0
}
368
369
0
static void ieee802154_key_free_cb(void*r) {
370
0
    ieee802154_key_t* rec = (ieee802154_key_t *)r;
371
372
0
    g_free(rec->pref_key);
373
0
}
374
375
/* Field callbacks. */
376
0
UAT_CSTRING_CB_DEF(key_uat, pref_key, ieee802154_key_t)
377
0
UAT_DEC_CB_DEF(key_uat, key_index, ieee802154_key_t)
Unexecuted instantiation: packet-ieee802154.c:key_uat_key_index_set_cb
Unexecuted instantiation: packet-ieee802154.c:key_uat_key_index_tostr_cb
378
0
UAT_VS_DEF(key_uat, hash_type, ieee802154_key_t, ieee802154_key_hash, KEY_HASH_NONE, "No hash")
Unexecuted instantiation: packet-ieee802154.c:key_uat_hash_type_set_cb
Unexecuted instantiation: packet-ieee802154.c:key_uat_hash_type_tostr_cb
379
380
381
/*-------------------------------------
382
 * Dissector Function Prototypes
383
 *-------------------------------------
384
 */
385
386
/* Dissection Routines. */
387
static int dissect_ieee802154_nonask_phy   (tvbuff_t *, packet_info *, proto_tree *, void *);
388
static int dissect_ieee802154              (tvbuff_t *, packet_info *, proto_tree *, void *);
389
static int dissect_ieee802154_nofcs        (tvbuff_t *, packet_info *, proto_tree *, void *);
390
static int dissect_ieee802154_cc24xx       (tvbuff_t *, packet_info *, proto_tree *, void *);
391
static int dissect_ieee802154_tap          (tvbuff_t *, packet_info *, proto_tree *, void *);
392
static tvbuff_t *dissect_zboss_specific    (tvbuff_t *, packet_info *, proto_tree *);
393
static void dissect_ieee802154_common      (tvbuff_t *, packet_info *, proto_tree *, unsigned, unsigned);
394
static void ieee802154_dissect_fcs(tvbuff_t *tvb, proto_tree *ieee802154_tree, unsigned fcs_len, bool fcs_ok);
395
static void ieee802154_dissect_cc24xx_metadata(tvbuff_t *tvb, proto_tree *ieee802154_tree, bool fcs_ok);
396
static ieee802154_fcs_type_t dissect_ieee802154_tap_tlvs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
397
398
/* Information Elements */
399
static int dissect_ieee802154_header_ie        (tvbuff_t *, packet_info *, proto_tree *, unsigned, ieee802154_packet *);
400
static int dissect_ieee802154_payload_ie       (tvbuff_t *, packet_info *, proto_tree *, unsigned, ieee802154_packet *);
401
static int dissect_802154_eb_filter            (tvbuff_t *, packet_info *, proto_tree *, void *);
402
static int dissect_802154_tsch_time_sync       (tvbuff_t *, packet_info *, proto_tree *, void *);
403
static int dissect_802154_tsch_timeslot        (tvbuff_t *, packet_info *, proto_tree *, void *);
404
static int dissect_802154_tsch_slotframe_link  (tvbuff_t *, packet_info *, proto_tree *, void *);
405
static int dissect_802154_channel_hopping      (tvbuff_t *, packet_info *, proto_tree *, void *);
406
/* Sub-dissector helpers. */
407
static void dissect_ieee802154_fcf             (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *, unsigned *);
408
static void dissect_ieee802154_command         (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
409
static void dissect_ieee802154_assoc_req       (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
410
static void dissect_ieee802154_assoc_rsp       (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
411
static void dissect_ieee802154_disassoc        (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
412
static void dissect_ieee802154_realign         (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
413
static void dissect_ieee802154_gtsreq          (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
414
415
/* Decryption helpers. */
416
static tvbuff_t *dissect_ieee802154_decrypt(tvbuff_t *, unsigned, packet_info *, ieee802154_packet *, ieee802154_decrypt_info_t*, unsigned char *);
417
418
static unsigned ieee802154_set_mac_key(ieee802154_packet *packet, unsigned char *key, unsigned char *alt_key, ieee802154_key_t *uat_key);
419
static unsigned ieee802154_set_trel_key(ieee802154_packet* packet, unsigned char* key, unsigned char* alt_key, ieee802154_key_t* uat_key);
420
static void tsch_ccm_init_nonce(uint64_t addr, uint64_t asn, uint8_t* generic_nonce);
421
422
/* Initialize Protocol and Registered fields */
423
static int proto_ieee802154_nonask_phy;
424
static int hf_ieee802154_nonask_phy_preamble;
425
static int hf_ieee802154_nonask_phy_sfd;
426
static int hf_ieee802154_nonask_phy_length;
427
static int hf_ieee802154_nonask_phr;
428
429
static int proto_ieee802154;
430
static int proto_ieee802154_tap;
431
static int hf_ieee802154_frame_length;
432
static int hf_ieee802154_fcf;
433
static int hf_ieee802154_frame_type;
434
static int hf_ieee802154_security;
435
static int hf_ieee802154_pending;
436
static int hf_ieee802154_ack_request;
437
static int hf_ieee802154_pan_id_compression;
438
static int hf_ieee802154_fcf_reserved;
439
static int hf_ieee802154_seqno_suppression;
440
static int hf_ieee802154_ie_present;
441
static int hf_ieee802154_src_addr_mode;
442
static int hf_ieee802154_version;
443
static int hf_ieee802154_dst_addr_mode;
444
445
static int hf_ieee802154_mpf_long_frame_control;
446
static int hf_ieee802154_mpf_dst_addr_mode;
447
static int hf_ieee802154_mpf_src_addr_mode;
448
static int hf_ieee802154_mpf_pan_id_present;
449
static int hf_ieee802154_mpf_security;
450
static int hf_ieee802154_mpf_seqno_suppression;
451
static int hf_ieee802154_mpf_pending;
452
static int hf_ieee802154_mpf_version;
453
static int hf_ieee802154_mpf_ack_request;
454
static int hf_ieee802154_mpf_ie_present;
455
456
static int hf_ieee802154_header_ies;
457
static int hf_ieee802154_header_ie_tlv;
458
static int hf_ieee802154_header_ie_type;
459
static int hf_ieee802154_header_ie_id;
460
static int hf_ieee802154_header_ie_length;
461
static int hf_ieee802154_ie_unknown_content;
462
static int hf_ieee802154_ie_unknown_content_payload;
463
static int hf_ieee802154_hie_unsupported;
464
static int hf_ieee802154_hie_time_correction;
465
static int hf_ieee802154_hie_ht1;
466
static int hf_ieee802154_hie_ht2;
467
static int hf_ieee802154_hie_thread;
468
static int hf_ieee802154_nack;
469
static int hf_ieee802154_hie_time_correction_time_sync_info;
470
static int hf_ieee802154_hie_time_correction_value;
471
static int hf_ieee802154_hie_csl;
472
static int hf_ieee802154_hie_csl_phase;
473
static int hf_ieee802154_hie_csl_period;
474
static int hf_ieee802154_hie_csl_rendezvous_time;
475
static int hf_ieee802154_hie_rdv;
476
static int hf_ieee802154_hie_rdv_wakeup_interval;
477
static int hf_ieee802154_hie_global_time;
478
static int hf_ieee802154_hie_global_time_value;
479
static int hf_ieee802154_hie_vendor_specific;
480
static int hf_ieee802154_hie_vendor_specific_vendor_oui;
481
static int hf_ieee802154_hie_vendor_specific_content;
482
static int hf_ieee802154_payload_ies;
483
static int hf_ieee802154_payload_ie_tlv;
484
static int hf_ieee802154_payload_ie_type;
485
static int hf_ieee802154_payload_ie_id;
486
static int hf_ieee802154_payload_ie_length;
487
static int hf_ieee802154_pie_unsupported;
488
static int hf_ieee802154_pie_termination;
489
static int hf_ieee802154_pie_vendor;
490
static int hf_ieee802154_pie_vendor_oui;
491
static int hf_ieee802154_pie_vendor_variable;
492
static int hf_ieee802154_pie_ietf;
493
static int hf_ieee802154_mlme;
494
static int hf_ieee802154_mlme_ie_data;
495
static int hf_ieee802154_mlme_ie_unsupported;
496
static int hf_ieee802154_psie;
497
static int hf_ieee802154_psie_type;
498
static int hf_ieee802154_psie_id_short;
499
static int hf_ieee802154_psie_length_short;
500
static int hf_ieee802154_psie_id_long;
501
static int hf_ieee802154_psie_length_long;
502
503
static int hf_ieee802154_tsch_sync;
504
static int hf_ieee802154_tsch_asn;
505
static int hf_ieee802154_tsch_join_metric;
506
static int hf_ieee802154_tsch_slotframe;
507
static int hf_ieee802154_tsch_link_info;
508
static int hf_ieee802154_tsch_slotf_link_nb_slotf;
509
static int hf_ieee802154_tsch_slotf_link_slotf_handle;
510
static int hf_ieee802154_tsch_slotf_size;
511
static int hf_ieee802154_tsch_slotf_link_nb_links;
512
static int hf_ieee802154_tsch_slotf_link_timeslot;
513
static int hf_ieee802154_tsch_slotf_link_channel_offset;
514
static int hf_ieee802154_tsch_slotf_link_options;
515
static int hf_ieee802154_tsch_slotf_link_options_tx;
516
static int hf_ieee802154_tsch_slotf_link_options_rx;
517
static int hf_ieee802154_tsch_slotf_link_options_shared;
518
static int hf_ieee802154_tsch_slotf_link_options_timkeeping;
519
static int hf_ieee802154_tsch_slotf_link_options_priority;
520
static int hf_ieee802154_tsch_channel_hopping;
521
static int hf_ieee802154_tsch_hopping_sequence_id;
522
static int hf_ieee802154_tsch_timeslot;
523
static int hf_ieee802154_tsch_timeslot_id;
524
static int hf_ieee802154_tsch_timeslot_cca_offset;
525
static int hf_ieee802154_tsch_timeslot_cca;
526
static int hf_ieee802154_tsch_timeslot_tx_offset;
527
static int hf_ieee802154_tsch_timeslot_rx_offset;
528
static int hf_ieee802154_tsch_timeslot_rx_ack_delay;
529
static int hf_ieee802154_tsch_timeslot_tx_ack_delay;
530
static int hf_ieee802154_tsch_timeslot_rx_wait;
531
static int hf_ieee802154_tsch_timeslot_ack_wait;
532
static int hf_ieee802154_tsch_timeslot_turnaround;
533
static int hf_ieee802154_tsch_timeslot_max_ack;
534
static int hf_ieee802154_tsch_timeslot_max_tx;
535
static int hf_ieee802154_tsch_timeslot_length;
536
537
static int hf_ieee802154_psie_eb_filter;
538
static int hf_ieee802154_psie_eb_filter_pjoin;
539
static int hf_ieee802154_psie_eb_filter_lqi;
540
static int hf_ieee802154_psie_eb_filter_lqi_min;
541
static int hf_ieee802154_psie_eb_filter_percent;
542
static int hf_ieee802154_psie_eb_filter_percent_prob;
543
static int hf_ieee802154_psie_eb_filter_attr_id;
544
static int hf_ieee802154_psie_eb_filter_attr_id_bitmap;
545
static int hf_ieee802154_p_ie_ietf_sub_id;
546
547
static int hf_ieee802154_6top;
548
static int hf_ieee802154_6top_version;
549
static int hf_ieee802154_6top_type;
550
static int hf_ieee802154_6top_flags_reserved;
551
static int hf_ieee802154_6top_code;
552
static int hf_ieee802154_6top_sfid;
553
static int hf_ieee802154_6top_seqnum;
554
static int hf_ieee802154_6top_metadata;
555
static int hf_ieee802154_6top_cell_options;
556
static int hf_ieee802154_6top_cell_option_tx;
557
static int hf_ieee802154_6top_cell_option_rx;
558
static int hf_ieee802154_6top_cell_option_shared;
559
static int hf_ieee802154_6top_cell_option_reserved;
560
static int hf_ieee802154_6top_num_cells;
561
static int hf_ieee802154_6top_cell_list;
562
static int hf_ieee802154_6top_rel_cell_list;
563
static int hf_ieee802154_6top_cand_cell_list;
564
static int hf_ieee802154_6top_cell;
565
static int hf_ieee802154_6top_reserved;
566
static int hf_ieee802154_6top_offset;
567
static int hf_ieee802154_6top_max_num_cells;
568
static int hf_ieee802154_6top_slot_offset;
569
static int hf_ieee802154_6top_channel_offset;
570
static int hf_ieee802154_6top_total_num_cells;
571
static int hf_ieee802154_6top_payload;
572
573
static int hf_ieee802159_mpx;
574
static int hf_ieee802159_mpx_transaction_control;
575
static int hf_ieee802159_mpx_transfer_type;
576
static int hf_ieee802159_mpx_transaction_id;
577
static int hf_ieee802159_mpx_transaction_id_as_multiplex_id;
578
static int hf_ieee802159_mpx_fragment_number;
579
static int hf_ieee802159_mpx_total_frame_size;
580
static int hf_ieee802159_mpx_multiplex_id;
581
static int hf_ieee802159_mpx_kmp_id;
582
static int hf_ieee802159_mpx_kmp_vendor_oui;
583
static int hf_ieee802159_mpx_fragment;
584
static int hf_ieee802159_mpx_wisun_subid;
585
586
static int proto_zboss;
587
static int hf_zboss_direction;
588
static int hf_zboss_page;
589
static int hf_zboss_channel;
590
static int hf_zboss_trace_number;
591
592
static int hf_ieee802154_seqno;
593
static int hf_ieee802154_dst_panID;
594
static int hf_ieee802154_dst16;
595
static int hf_ieee802154_dst64;
596
static int hf_ieee802154_src_panID;
597
static int hf_ieee802154_src16;
598
static int hf_ieee802154_src64;
599
static int hf_ieee802154_src64_origin;
600
static int hf_ieee802154_addr16;
601
static int hf_ieee802154_addr64;
602
static int hf_ieee802154_fcs;
603
static int hf_ieee802154_fcs32;
604
static int hf_ieee802154_rssi;
605
static int hf_ieee802154_fcs_ok;
606
static int hf_ieee802154_correlation;
607
608
/* Registered fields for Command Packets */
609
static int hf_ieee802154_cmd_id;
610
static int hf_ieee802154_cinfo_alt_coord;
611
static int hf_ieee802154_cinfo_device_type;
612
static int hf_ieee802154_cinfo_power_src;
613
static int hf_ieee802154_cinfo_idle_rx;
614
static int hf_ieee802154_cinfo_sec_capable;
615
static int hf_ieee802154_cinfo_alloc_addr;
616
static int hf_ieee802154_assoc_addr;
617
static int hf_ieee802154_assoc_status;
618
static int hf_ieee802154_disassoc_reason;
619
static int hf_ieee802154_realign_pan;
620
static int hf_ieee802154_realign_caddr;
621
static int hf_ieee802154_realign_channel;
622
static int hf_ieee802154_realign_addr;
623
static int hf_ieee802154_realign_channel_page;
624
static int hf_ieee802154_gtsreq_len;
625
static int hf_ieee802154_gtsreq_dir;
626
static int hf_ieee802154_gtsreq_type;
627
static int hf_ieee802154_cmd_vendor_oui;
628
629
/* Registered fields for Beacon Packets */
630
static int hf_ieee802154_beacon_order;
631
static int hf_ieee802154_superframe_order;
632
static int hf_ieee802154_cap;
633
static int hf_ieee802154_superframe_battery_ext;
634
static int hf_ieee802154_superframe_coord;
635
static int hf_ieee802154_assoc_permit;
636
static int hf_ieee802154_gts_count;
637
static int hf_ieee802154_gts_permit;
638
static int hf_ieee802154_gts_direction;
639
static int hf_ieee802154_gts_address;
640
static int hf_ieee802154_pending16;
641
static int hf_ieee802154_pending64;
642
643
/* Registered fields for Auxiliary Security Header */
644
static int hf_ieee802154_aux_security_header;
645
static int hf_ieee802154_aux_sec_security_control;
646
static int hf_ieee802154_aux_sec_security_level;
647
static int hf_ieee802154_aux_sec_key_id_mode;
648
static int hf_ieee802154_aux_sec_frame_counter_suppression;
649
static int hf_ieee802154_aux_sec_asn_in_nonce;
650
static int hf_ieee802154_aux_sec_reserved;
651
static int hf_ieee802154_aux_sec_frame_counter;
652
static int hf_ieee802154_aux_sec_key_source;
653
static int hf_ieee802154_aux_sec_key_source_bytes;
654
static int hf_ieee802154_aux_sec_key_index;
655
static int hf_ieee802154_mic;
656
static int hf_ieee802154_key_number;
657
658
/* 802.15.4-2003 security */
659
static int hf_ieee802154_sec_frame_counter;
660
static int hf_ieee802154_sec_key_sequence_counter;
661
662
/* 802.15.4 ack */
663
static int hf_ieee802154_no_ack;
664
static int hf_ieee802154_no_ack_request;
665
static int hf_ieee802154_ack_in;
666
static int hf_ieee802154_ack_to;
667
static int hf_ieee802154_ack_time;
668
669
/* 802.15.4 TAP */
670
static int hf_ieee802154_tap_version;
671
static int hf_ieee802154_tap_reserved;
672
static int hf_ieee802154_tap_length;
673
static int hf_ieee802154_tap_data_length;
674
static int hf_ieee802154_tap_tlv_type;
675
static int hf_ieee802154_tap_tlv_length;
676
static int hf_ieee802154_tap_tlv_unknown;
677
static int hf_ieee802154_tap_tlv_padding;
678
static int hf_ieee802154_tap_fcs_type;
679
static int hf_ieee802154_tap_rss;
680
static int hf_ieee802154_ch_page;
681
static int hf_ieee802154_ch_num;
682
static int hf_ieee802154_bit_rate;
683
static int hf_ieee802154_sun_band;
684
static int hf_ieee802154_sun_type;
685
static int hf_ieee802154_sun_mode;
686
static int hf_ieee802154_mode_fsk_a;
687
static int hf_ieee802154_mode_fsk_b;
688
static int hf_ieee802154_mode_oqpsk_a;
689
static int hf_ieee802154_mode_oqpsk_b;
690
static int hf_ieee802154_mode_oqpsk_c;
691
static int hf_ieee802154_mode_ofdm;
692
static int hf_ieee802154_sof_ts;
693
static int hf_ieee802154_eof_ts;
694
static int hf_ieee802154_slot_start_ts;
695
static int hf_ieee802154_tap_timeslot_length;
696
static int hf_ieee802154_tap_lqi;
697
static int hf_ieee802154_chplan_start;
698
static int hf_ieee802154_chplan_spacing;
699
static int hf_ieee802154_chplan_channels;
700
static int hf_ieee802154_ch_freq;
701
static int hf_ieee802154_frame_start_offset;
702
static int hf_ieee802154_frame_duration;
703
static int hf_ieee802154_frame_end_offset;
704
static int hf_ieee802154_asn;
705
706
static int hf_ieee802154_tap_phr_type;
707
static int hf_ieee802154_tap_phr_bits;
708
static int hf_ieee802154_tap_phr_data;
709
710
static int hf_ieee802154_tap_phr_fsk;
711
static int hf_ieee802154_tap_fsk_ms_phr;
712
static int hf_ieee802154_tap_wisun_ms_phr;
713
714
static int hf_ieee802154_tap_phr_fsk_ms;
715
static int hf_ieee802154_tap_phr_fsk_fcs;
716
static int hf_ieee802154_tap_phr_fsk_dw;
717
static int hf_ieee802154_tap_phr_fsk_length;
718
719
static int hf_ieee802154_tap_phr_fsk_ms_param;
720
static int hf_ieee802154_tap_phr_fsk_ms_fec;
721
static int hf_ieee802154_tap_phr_fsk_ms_checksum;
722
static int hf_ieee802154_tap_phr_fsk_ms_parity;
723
724
static int hf_ieee802154_tap_phr_fsk_ms_mode_page;
725
static int hf_ieee802154_tap_phr_fsk_ms_mode_scheme;
726
static int hf_ieee802154_tap_phr_fsk_ms_mode_mode;
727
static int hf_ieee802154_tap_phr_fsk_ms_mode_addl_mode;
728
static int hf_ieee802154_tap_phr_wisun_fsk_ms_reserved;
729
static int hf_ieee802154_tap_phr_wisun_fsk_ms_phymodeid;
730
731
/* Bit-masks for SUN FSK PHR per IEEE 802.15.4-2020 19.2.4 */
732
16
#define IEEE802154_TAP_PHR_FSK_MS               0x8000
733
16
#define IEEE802154_TAP_PHR_FSK_FCS              0x0100
734
16
#define IEEE802154_TAP_PHR_FSK_DW               0x0080
735
16
#define IEEE802154_TAP_PHR_FSK_LENGTH           0x07ff
736
737
/* Bit-masks for SUN FSK Mode Switch PHR per IEEE 802.15.4-2020 19.2.5 */
738
16
#define IEEE802154_TAP_PHR_FSK_MS_PARAM         0x6000
739
16
#define IEEE802154_TAP_PHR_FSK_MS_FEC           0x1000
740
#define IEEE802154_TAP_PHR_FSK_MS_MODE          0x0FE0
741
16
#define IEEE802154_TAP_PHR_FSK_MS_MODE_PAGE     0x0800
742
16
#define IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME   0x0600
743
32
#define IEEE802154_TAP_PHR_FSK_MS_MODE_MODE     0x01E0
744
16
#define IEEE802154_TAP_PHR_FSK_MS_CHECKSUM      0x001E
745
16
#define IEEE802154_TAP_PHR_FSK_MS_PARITY        0x0001
746
747
0
#define IEEE802154_TAP_PHR_FSK_MS_SCHEME_FSK    0x0000
748
0
#define IEEE802154_TAP_PHR_FSK_MS_SCHEME_OFDM   0x0200
749
0
#define IEEE802154_TAP_PHR_FSK_MS_SCHEME_OQPSK  0x0400
750
#define IEEE802154_TAP_PHR_FSK_MS_SCHEME_ADDL   0x0600
751
752
/* Bit-masks for Wi-SUN FSK Mode Switch PHR */
753
16
#define IEEE802154_TAP_PHR_WISUN_FSK_MS_RESERVED  0x6000
754
16
#define IEEE802154_TAP_PHR_WISUN_FSK_MS_PHYMODEID 0x1FE0
755
756
typedef struct _ieee802154_transaction_t {
757
    uint64_t dst64;
758
    uint64_t src64;
759
    int32_t dst_addr_mode;
760
    int32_t src_addr_mode;
761
    uint16_t dst16;
762
    uint16_t src16;
763
    uint32_t rqst_frame;
764
    uint32_t ack_frame;
765
    nstime_t rqst_time;
766
    nstime_t ack_time;
767
    bool dst_pan_present;
768
    bool src_pan_present;
769
    uint16_t dst_pan;
770
    uint16_t src_pan;
771
} ieee802154_transaction_t;
772
773
static const nstime_t ieee802154_transaction_timeout = NSTIME_INIT_SECS_MSECS(1, 0); // ACKs usually arrive within milliseconds
774
775
static wmem_tree_t *transaction_unmatched_pdus;
776
static wmem_tree_t *transaction_matched_pdus;
777
778
static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key);
779
static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key);
780
781
/* Initialize Subtree Pointers */
782
static int ett_ieee802154_nonask_phy;
783
static int ett_ieee802154_nonask_phy_phr;
784
static int ett_ieee802154_tap;
785
static int ett_ieee802154_tap_header;
786
static int ett_ieee802154_tap_tlv;
787
static int ett_ieee802154;
788
static int ett_ieee802154_fcf;
789
static int ett_ieee802154_auxiliary_security;
790
static int ett_ieee802154_aux_sec_control;
791
static int ett_ieee802154_aux_sec_key_id;
792
static int ett_ieee802154_fcs;
793
static int ett_ieee802154_cmd;
794
static int ett_ieee802154_superframe;
795
static int ett_ieee802154_gts;
796
static int ett_ieee802154_gts_direction;
797
static int ett_ieee802154_gts_descriptors;
798
static int ett_ieee802154_pendaddr;
799
static int ett_ieee802154_header_ies;
800
static int ett_ieee802154_header_ie;
801
static int ett_ieee802154_header_ie_tlv;
802
static int ett_ieee802154_hie_unsupported;
803
static int ett_ieee802154_hie_time_correction;
804
static int ett_ieee802154_hie_ht;
805
static int ett_ieee802154_hie_thread;
806
static int ett_ieee802154_hie_csl;
807
static int ett_ieee802154_hie_rdv;
808
static int ett_ieee802154_hie_global_time;
809
static int ett_ieee802154_hie_vendor_specific;
810
static int ett_ieee802154_payload_ie;
811
static int ett_ieee802154_payload_ie_tlv;
812
static int ett_ieee802154_pie_termination;
813
static int ett_ieee802154_pie_vendor;
814
static int ett_ieee802154_pie_ietf;
815
static int ett_ieee802154_pie_unsupported;
816
static int ett_ieee802154_mlme;
817
static int ett_ieee802154_mlme_payload;
818
static int ett_ieee802154_mlme_payload_data;
819
static int ett_ieee802154_mlme_unsupported;
820
static int ett_ieee802154_tsch_slotframe;
821
static int ett_ieee802154_tsch_slotframe_list;
822
static int ett_ieee802154_tsch_slotframe_link;
823
static int ett_ieee802154_tsch_slotframe_link_options;
824
static int ett_ieee802154_tsch_timeslot;
825
static int ett_ieee802154_tsch_synch;
826
static int ett_ieee802154_channel_hopping;
827
static int ett_ieee802154_psie;
828
static int ett_ieee802154_eb_filter;
829
static int ett_ieee802154_eb_filter_bitmap;
830
static int ett_ieee802154_zigbee;
831
static int ett_ieee802154_zboss;
832
static int ett_ieee802154_p_ie_6top;
833
static int ett_ieee802154_p_ie_6top_cell_options;
834
static int ett_ieee802154_p_ie_6top_cell_list;
835
static int ett_ieee802154_p_ie_6top_cand_cell_list;
836
static int ett_ieee802154_p_ie_6top_rel_cell_list;
837
static int ett_ieee802154_p_ie_6top_cell;
838
static int ett_ieee802159_mpx;
839
static int ett_ieee802159_mpx_transaction_control;
840
static int ett_ieee802154_tap_phr;
841
842
static expert_field ei_ieee802154_fcs_bitmask_len;
843
static expert_field ei_ieee802154_invalid_addressing;
844
static expert_field ei_ieee802154_invalid_panid_compression;
845
static expert_field ei_ieee802154_invalid_panid_compression2;
846
static expert_field ei_ieee802154_fcs;
847
static expert_field ei_ieee802154_decrypt_error;
848
static expert_field ei_ieee802154_dst;
849
static expert_field ei_ieee802154_src;
850
static expert_field ei_ieee802154_frame_ver;
851
/* static expert_field ei_ieee802154_frame_type; */
852
static expert_field ei_ieee802154_seqno_suppression;
853
static expert_field ei_ieee802154_ack_not_found;
854
static expert_field ei_ieee802154_ack_request_not_found;
855
static expert_field ei_ieee802154_time_correction_error;
856
static expert_field ei_ieee802154_6top_unsupported_type;
857
static expert_field ei_ieee802154_6top_unsupported_return_code;
858
static expert_field ei_ieee802154_6top_unsupported_command;
859
static expert_field ei_ieee802154_ie_unsupported_id;
860
static expert_field ei_ieee802154_ie_unknown_extra_content;
861
static expert_field ei_ieee802154_ie_unknown_extra_content_payload;
862
static expert_field ei_ieee802159_mpx_invalid_transfer_type;
863
static expert_field ei_ieee802159_mpx_unsupported_kmp;
864
static expert_field ei_ieee802159_mpx_unknown_kmp;
865
static expert_field ei_ieee802154_missing_payload_ie;
866
static expert_field ei_ieee802154_payload_ie_in_header;
867
static expert_field ei_ieee802154_unsupported_cmd;
868
static expert_field ei_ieee802154_unknown_cmd;
869
static expert_field ei_ieee802154_tap_tlv_invalid_type;
870
static expert_field ei_ieee802154_tap_tlv_invalid_length;
871
static expert_field ei_ieee802154_tap_tlv_padding_not_zeros;
872
static expert_field ei_ieee802154_tap_tlv_invalid_fcs_type;
873
static expert_field ei_ieee802154_tap_tlv_reserved_not_zero;
874
static expert_field ei_ieee802154_tap_no_payload;
875
876
static int ieee802_15_4_short_address_type = -1;
877
/*
878
 * Dissector handles
879
 *  - beacon dissection is always heuristic.
880
 *  - the PANID table is for stateful dissectors only (ie: Decode-As)
881
 *  - otherwise, data dissectors fall back to the heuristic dissectors.
882
 */
883
static dissector_table_t        panid_dissector_table;
884
static heur_dissector_list_t    ieee802154_beacon_subdissector_list;
885
static heur_dissector_list_t    ieee802154_heur_subdissector_list;
886
887
/* For the IEs and the vendor specific command */
888
static dissector_table_t header_ie_dissector_table;
889
static dissector_table_t payload_ie_dissector_table;
890
static dissector_table_t mlme_ie_dissector_table;
891
static dissector_table_t cmd_vendor_dissector_table;
892
893
static dissector_handle_t  zigbee_ie_handle;
894
static dissector_handle_t  zigbee_nwk_handle;
895
static dissector_handle_t  ieee802154_handle;
896
static dissector_handle_t  ieee802154_nonask_phy_handle;
897
static dissector_handle_t  ieee802154_fcs_handle;
898
static dissector_handle_t  ieee802154_nofcs_handle;
899
static dissector_handle_t  ieee802154_tap_handle;
900
901
/* Thread 802.15.4 - 2015 */
902
static dissector_handle_t thread_ie_handle;
903
904
static int ieee802154_tap;
905
906
/* Handles for MPX-IE the Multiplex ID */
907
static dissector_table_t ethertype_table;
908
static dissector_handle_t eapol_handle;
909
static dissector_handle_t lowpan_handle;
910
static dissector_handle_t wisun_sec_handle;
911
912
/* Versions */
913
static const value_string ieee802154_frame_versions[] = {
914
    { IEEE802154_VERSION_2003,     "IEEE Std 802.15.4-2003" },
915
    { IEEE802154_VERSION_2006,     "IEEE Std 802.15.4-2006" },
916
    { IEEE802154_VERSION_2015,     "IEEE Std 802.15.4-2015" },
917
    { IEEE802154_VERSION_RESERVED, "Reserved" },
918
    { 0, NULL }
919
};
920
921
/* Name Strings */
922
static const value_string ieee802154_frame_types[] = {
923
    { IEEE802154_FCF_BEACON,       "Beacon" },
924
    { IEEE802154_FCF_DATA,         "Data" },
925
    { IEEE802154_FCF_ACK,          "Ack" },
926
    { IEEE802154_FCF_CMD,          "Command" },
927
    { IEEE802154_FCF_RESERVED,     "Reserved" },
928
    { IEEE802154_FCF_MULTIPURPOSE, "Multipurpose" },
929
    { IEEE802154_FCF_FRAGMENT,     "Fragment or Frak" },
930
    { IEEE802154_FCF_EXTENDED,     "Extended" },
931
    { 0, NULL }
932
};
933
934
static const value_string ieee802154_addr_modes[] = {
935
    { IEEE802154_FCF_ADDR_NONE,     "None" },
936
    { IEEE802154_FCF_ADDR_RESERVED, "Reserved" },
937
    { IEEE802154_FCF_ADDR_SHORT,    "Short/16-bit" },
938
    { IEEE802154_FCF_ADDR_EXT,      "Long/64-bit" },
939
    { 0, NULL }
940
};
941
942
static const value_string ieee802154_cmd_names[] = {
943
    { IEEE802154_CMD_ASSOC_REQ,                 "Association Request" },
944
    { IEEE802154_CMD_ASSOC_RSP,                 "Association Response" },
945
    { IEEE802154_CMD_DISASSOC_NOTIFY,           "Disassociation Notification" },
946
    { IEEE802154_CMD_DATA_RQ,                   "Data Request" },
947
    { IEEE802154_CMD_PANID_CONFLICT,            "PAN ID Conflict" },
948
    { IEEE802154_CMD_ORPHAN_NOTIFY,             "Orphan Notification" },
949
    { IEEE802154_CMD_BEACON_REQ,                "Beacon Request" },
950
    { IEEE802154_CMD_COORD_REALIGN,             "Coordinator Realignment" },
951
    { IEEE802154_CMD_GTS_REQ,                   "GTS Request" },
952
    { IEEE802154_CMD_TRLE_MGMT_REQ,             "TRLE Management Request"},
953
    { IEEE802154_CMD_TRLE_MGMT_RSP,             "TRLE Management Response"},
954
    { IEEE802154_CMD_DSME_ASSOC_REQ,            "DSME Association Request"},
955
    { IEEE802154_CMD_DSME_ASSOC_RSP,            "DSME Association Response"},
956
    { IEEE802154_CMD_DSME_GTS_REQ,              "DSME GTS Request"},
957
    { IEEE802154_CMD_DSME_GTS_RSP,              "DSME GTS Response"},
958
    { IEEE802154_CMD_DSME_GTS_NOTIFY,           "DSME GTS Notify"},
959
    { IEEE802154_CMD_DSME_INFO_REQ,             "DSME Information Request"},
960
    { IEEE802154_CMD_DSME_INFO_RSP,             "DSME Information Response"},
961
    { IEEE802154_CMD_DSME_BEACON_ALLOC_NOTIFY,  "DSME Beacon Allocation Notification"},
962
    { IEEE802154_CMD_DSME_BEACON_COLL_NOTIFY,   "DSME Beacon Collision Notification"},
963
    { IEEE802154_CMD_DSME_LINK_REPORT,          "DSME Link Report"},
964
    { IEEE802154_CMD_RIT_DATA_REQ,              "RIT Data Request"},
965
    { IEEE802154_CMD_DBS_REQ,                   "DBS Request"},
966
    { IEEE802154_CMD_DBS_RSP,                   "DBS Response"},
967
    { IEEE802154_CMD_RIT_DATA_RSP,              "RIT Data Response"},
968
    { IEEE802154_CMD_VENDOR_SPECIFIC,           "Vendor Specific"},
969
    { 0, NULL }
970
};
971
972
const value_string ieee802154_sec_level_names[] = {
973
    { SECURITY_LEVEL_NONE,        "No Security" },
974
    { SECURITY_LEVEL_MIC_32,      "32-bit Message Integrity Code" },
975
    { SECURITY_LEVEL_MIC_64,      "64-bit Message Integrity Code" },
976
    { SECURITY_LEVEL_MIC_128,     "128-bit Message Integrity Code" },
977
    { SECURITY_LEVEL_ENC,         "Encryption" },
978
    { SECURITY_LEVEL_ENC_MIC_32,  "Encryption with 32-bit Message Integrity Code" },
979
    { SECURITY_LEVEL_ENC_MIC_64,  "Encryption with 64-bit Message Integrity Code" },
980
    { SECURITY_LEVEL_ENC_MIC_128, "Encryption with 128-bit Message Integrity Code" },
981
    { 0, NULL }
982
};
983
984
const value_string ieee802154_key_id_mode_names[] = {
985
    { KEY_ID_MODE_IMPLICIT,       "Implicit Key" },
986
    { KEY_ID_MODE_KEY_INDEX,      "Indexed Key using the Default Key Source" },
987
    { KEY_ID_MODE_KEY_EXPLICIT_4, "Explicit Key with 4-octet Key Source" },
988
    { KEY_ID_MODE_KEY_EXPLICIT_8, "Explicit Key with 8-octet Key Source" },
989
    { 0, NULL }
990
};
991
992
static const true_false_string ieee802154_gts_direction_tfs = {
993
    "Receive Only",
994
    "Transmit Only"
995
};
996
997
/* The 802.15.4-2003 security suites for the security preferences (only AES-CCM suites are supported). */
998
/* NOTE: The equivalent 2006 security level identifier enumerations are used to simplify 2003 & 2006 integration! */
999
static const enum_val_t ieee802154_2003_sec_suite_enums[] = {
1000
    { "AES-CCM-128", "AES-128 Encryption, 128-bit Integrity Protection", SECURITY_LEVEL_ENC_MIC_128 },
1001
    { "AES-CCM-64",  "AES-128 Encryption, 64-bit Integrity Protection",  SECURITY_LEVEL_ENC_MIC_64 },
1002
    { "AES-CCM-32",  "AES-128 Encryption, 32-bit Integrity Protection",  SECURITY_LEVEL_ENC_MIC_32 },
1003
    { NULL, NULL, 0 }
1004
};
1005
1006
/* Enumeration for key generation */
1007
static const value_string ieee802154_key_hash_vals[] = {
1008
    { KEY_HASH_NONE, "No hash"},
1009
    { KEY_HASH_ZIP, "ZigBee IP hash" },
1010
    { KEY_HASH_THREAD, "Thread hash" },
1011
    { 0, NULL }
1012
};
1013
1014
static const value_string ieee802154_ie_types[] = {
1015
    { 0, "Header" },
1016
    { 1, "Payload" },
1017
    { 0, NULL }
1018
};
1019
1020
static const value_string ieee802154_psie_types[] = {
1021
    { 0, "Short" },
1022
    { 1, "Long" },
1023
    { 0, NULL }
1024
};
1025
1026
static const value_string ieee802154_header_ie_names[] = {
1027
    { IEEE802154_HEADER_IE_VENDOR_SPECIFIC, "Vendor Specific IE" },
1028
    { IEEE802154_HEADER_IE_CSL,             "CSL IE" },
1029
    { IEEE802154_HEADER_IE_RIT,             "RIT IE" },
1030
    { IEEE802154_HEADER_IE_DSME_PAN,        "DSME PAN descriptor IE" },
1031
    { IEEE802154_HEADER_IE_RENDEZVOUS,      "Rendezvous Time IE" },
1032
    { IEEE802154_HEADER_IE_TIME_CORR,       "Time Correction IE" },
1033
    { IEEE802154_HEADER_IE_EXT_DSME_PAN,    "Extended DSME PAN descriptor IE" },
1034
    { IEEE802154_HEADER_IE_FSCD,            "Fragment Sequence Context Description (FSCD) IE" },
1035
    { IEEE802154_HEADER_IE_SMPL_SUPER_FRM,  "Simplified Superframe Specification IE" },
1036
    { IEEE802154_HEADER_IE_SMPL_GTS,        "Simplified GTS Specification IE" },
1037
    { IEEE802154_HEADER_IE_LECIM,           "LECIM Capabilities IE" },
1038
    { IEEE802154_HEADER_IE_TRLE,            "TRLE Descriptor" },
1039
    { IEEE802154_HEADER_IE_RCC_CAP,         "RCC Capabilities IE" },
1040
    { IEEE802154_HEADER_IE_RCCN,            "RCCN Descriptor IE" },
1041
    { IEEE802154_HEADER_IE_GLOBAL_TIME,     "Global Time IE" },
1042
    { IEEE802154_HEADER_IE_WISUN,           "Wi-SUN IE" },
1043
    { IEEE802154_HEADER_IE_DA_IE,           "DA IE" },
1044
    { IEEE802154_HEADER_IE_HT1,             "Header Termination 1 IE" },
1045
    { IEEE802154_HEADER_IE_HT2,             "Header Termination 2 IE" },
1046
    { 0, NULL }
1047
};
1048
1049
static const true_false_string hf_ieee802154_nack_tfs = {
1050
    "Negative Acknowledgement",
1051
    "Acknowledgement"
1052
};
1053
1054
static const value_string ieee802154_payload_ie_names[] = {
1055
    { IEEE802154_PAYLOAD_IE_ESDU,                     "ESDU IE" },
1056
    { IEEE802154_PAYLOAD_IE_MLME,                     "MLME IE" },
1057
    { IEEE802154_PAYLOAD_IE_VENDOR,                   "Vendor Specific IE" },
1058
    { IEEE802154_PAYLOAD_IE_MPX,                      "MPX IE" },
1059
    { IEEE802154_PAYLOAD_IE_WISUN,                    "Wi-SUN IE" },
1060
    { IEEE802154_PAYLOAD_IE_IETF,                     "IETF IE" },
1061
    { IEEE802154_PAYLOAD_IE_TERMINATION,              "Payload Termination IE" },
1062
    { 0, NULL }
1063
};
1064
1065
static const value_string ieee802154_psie_names[] = {
1066
    { IEEE802154_MLME_SUBIE_CHANNEL_HOPPING,          "Channel Hopping IE" },
1067
    { IEEE802154_MLME_SUBIE_TSCH_SYNCH,               "TSCH Synchronization IE" },
1068
    { IEEE802154_MLME_SUBIE_TSCH_SLOTFR_LINK,         "TSCH Slotframe and Link IE" },
1069
    { IEEE802154_MLME_SUBIE_TSCH_TIMESLOT,            "TSCH Timeslot IE" },
1070
    { IEEE802154_MLME_SUBIE_HOPPING_TIMING,           "Hopping Timing IE" },
1071
    { IEEE802154_MLME_SUBIE_ENHANCED_BEACON_FILTER,   "Enhanced Beacon Filter IE" },
1072
    { IEEE802154_MLME_SUBIE_MAC_METRICS,              "MAC Metrics IE" },
1073
    { IEEE802154_MLME_SUBIE_ALL_MAC_METRICS,          "All MAC Metrics IE" },
1074
    { IEEE802154_MLME_SUBIE_COEXISTENCE_SPEC,         "Coexistence Specification IE" },
1075
    { IEEE802154_MLME_SUBIE_SUN_DEVICE_CAPABILITIES,  "SUN Device Capabilities IE" },
1076
    { IEEE802154_MLME_SUBIE_SUN_FSK_GEN_PHY,          "SUN FSK Generic PHY IE" },
1077
    { IEEE802154_MLME_SUBIE_MODE_SWITCH_PARAMETER,    "Mode Switch Parameter IE" },
1078
    { IEEE802154_MLME_SUBIE_PHY_PARAMETER_CHANGE,     "PHY Parameter Change IE" },
1079
    { IEEE802154_MLME_SUBIE_O_QPSK_PHY_MODE,          "O-QPSY PHY Mode IE" },
1080
    { IEEE802154_MLME_SUBIE_PCA_ALLOCATION,           "PCA Allocation IE" },
1081
    { IEEE802154_MLME_SUBIE_DSSS_OPER_MODE,           "LECIM DSSS Operating Mode IE"},
1082
    { IEEE802154_MLME_SUBIE_FSK_OPER_MODE,            "LECIM FSK Operating Mode IE" },
1083
    { IEEE802154_MLME_SUBIE_TVWS_PHY_OPE_MODE,        "TVWS PHY Operating Mode Description IE" },
1084
    { IEEE802154_MLME_SUBIE_TVWS_DEVICE_CAPAB,        "TVWS Device Capabilities IE" },
1085
    { IEEE802154_MLME_SUBIE_TVWS_DEVICE_CATEG,        "TVWS Device Category IE" },
1086
    { IEEE802154_MLME_SUBIE_TVWS_DEVICE_IDENTIF,      "TVWS Device Identification IE" },
1087
    { IEEE802154_MLME_SUBIE_TVWS_DEVICE_LOCATION,     "TVWS Device Location IE" },
1088
    { IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_QUERY,      "TVWS Channel Information Query IE" },
1089
    { IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_SOURCE,     "TVWS Channel Information Source IE" },
1090
    { IEEE802154_MLME_SUBIE_CTM,                      "CTM IE" },
1091
    { IEEE802154_MLME_SUBIE_TIMESTAMP,                "Timestamp IE" },
1092
    { IEEE802154_MLME_SUBIE_TIMESTAMP_DIFF,           "Timestamp Difference IE"},
1093
    { IEEE802154_MLME_SUBIE_TMCP_SPECIFICATION,       "TMCTP Specification IE" },
1094
    { IEEE802154_MLME_SUBIE_RCC_PHY_OPER_MODE,        "RCC PHY Operating Mode IE" },
1095
    { IEEE802154_IETF_SUBIE_6TOP,                     "6top IE" },
1096
    { IEEE802154_IETF_SUBIE_6TOP_DRAFT,               "6top IE (draft)" },
1097
    { 0, NULL }
1098
};
1099
1100
const value_string zboss_page_names[] = {
1101
    { 0, "2.4 GHz" },
1102
    { 28, "863-868 MHz band"},
1103
    { 29, "868-870, 870-876 MHz band" },
1104
    { 30, "870-876 MHz band" },
1105
    { 31, "915-921 MHz band" },
1106
    { 0, NULL }
1107
};
1108
1109
static const value_string zboss_direction_names[] = {
1110
    { 0, "IN" },
1111
    { 1, "OUT" },
1112
    { 0, NULL }
1113
};
1114
1115
static const value_string tap_tlv_types[] = {
1116
    { IEEE802154_TAP_FCS_TYPE,  "FCS type"},
1117
    { IEEE802154_TAP_RSS, "RSS"},
1118
    { IEEE802154_TAP_BIT_RATE, "Bit rate"},
1119
    { IEEE802154_TAP_CHANNEL_ASSIGNMENT, "Channel assignment"},
1120
    { IEEE802154_TAP_SUN_PHY_INFO, "SUN PHY Information"},
1121
    { IEEE802154_TAP_START_OF_FRAME_TS, "Start of frame timestamp"},
1122
    { IEEE802154_TAP_END_OF_FRAME_TS, "End of frame timestamp"},
1123
    { IEEE802154_TAP_ASN, "Absolute Slot Number (ASN)"},
1124
    { IEEE802154_TAP_SLOT_START_TS, "Start of slot timestamp"},
1125
    { IEEE802154_TAP_TIMESLOT_LENGTH, "Slot length"},
1126
    { IEEE802154_TAP_LQI, "Link Quality Indicator"},
1127
    { IEEE802154_TAP_CHANNEL_FREQUENCY, "Channel center frequency"},
1128
    { IEEE802154_TAP_CHANNEL_PLAN, "Channel plan"},
1129
    { IEEE802154_TAP_PHY_HEADER, "PHY Header"},
1130
    { 0, NULL }
1131
};
1132
1133
static const value_string tap_fcs_type_names[] = {
1134
    { IEEE802154_FCS_TYPE_NONE, "None" },
1135
    { IEEE802154_FCS_TYPE_16_BIT, "ITU-T CRC16" },
1136
    { IEEE802154_FCS_TYPE_32_BIT, "ITU-T CRC32" },
1137
    { 0, NULL }
1138
};
1139
1140
/* IEEE 802.15.4 Table 7-19 */
1141
static const value_string sun_bands[] = {
1142
    { 0, "169 MHz [169.400-169.475]" },
1143
    { 1, "450 MHz [450-470]" },
1144
    { 2, "470 MHz [470-510]" },
1145
    { 3, "780 MHz [779-787]" },
1146
    { 4, "863 MHz [863-870]" },
1147
    { 5, "896 MHz [896-901]" },
1148
    { 6, "901 MHz [901-902]" },
1149
    { 7, "915 MHz [902-928]" },
1150
    { 8, "917 MHz [917-923.5]" },
1151
    { 9, "920 MHz [920-928]" },
1152
    { 10, "928 MHz [928-960]" },
1153
    { 11, "920 MHz [920-960]" },
1154
    { 12, "1427 MHz [1427-1518]" },
1155
    { 13, "2450 MHz [2400-2483.5]" },
1156
    { 14, "866 MHz [865-867]" },
1157
    { 15, "870 MHz [870-876]" },
1158
    { 16, "915 MHz-a [902-928 alternate]" },
1159
    { 17, "915 MHz-b [902-907.5 & 915-928]" },
1160
    { 18, "915 MHz-c [915-928]" },
1161
    { 19, "915 MHz-d [915-921]" },
1162
    { 20, "915 MHz-e [915-918]" },
1163
    { 21, "919 MHz [919-923]" },
1164
    { 22, "920 MHz-a [920.5-924.5]" },
1165
    { 23, "920 MHz-b [920-925]" },
1166
    { 24, "867 MHz [866-869]" },
1167
    /* Exegin defined numbers for bands in Table 10-1 but not in Table 7-19 */
1168
    { 32, "433 MHz [433.05-434.79]" },
1169
    { 33, "868 MHz [868-868.6]" },
1170
    { 34, "2380 MHz [2360-2400]" },
1171
    { 0, NULL }
1172
};
1173
1174
/* IEEE 802.15.4 Table 7-20 */
1175
static const value_string sun_types[] = {
1176
    { IEEE802154_SUN_TYPE_FSK_A, "FSK-A" },
1177
    { IEEE802154_SUN_TYPE_FSK_B, "FSK-B" },
1178
    { IEEE802154_SUN_TYPE_OQPSK_A, "O-QPSK-A" },
1179
    { IEEE802154_SUN_TYPE_OQPSK_B, "O-QPSK-B" },
1180
    { IEEE802154_SUN_TYPE_OQPSK_C, "O-QPSK-C" },
1181
    { IEEE802154_SUN_TYPE_OFDM_OPT1, "OFDM Option 1" },
1182
    { IEEE802154_SUN_TYPE_OFDM_OPT2, "OFDM Option 2" },
1183
    { IEEE802154_SUN_TYPE_OFDM_OPT3, "OFDM Option 3" },
1184
    { IEEE802154_SUN_TYPE_OFDM_OPT4, "OFDM Option 4" },
1185
    { 0, NULL }
1186
};
1187
1188
static const value_string fsk_a_modes[] = {
1189
    { 0, "4.8 kb/s; 2-FSK; mod index = 1.0; channel spacing = 12.5 kHz" },
1190
    { 1, "9.6 kb/s; 4-FSK; mod index = 0.33; channel spacing = 12.5 kHz" },
1191
    { 2, "10 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" },
1192
    { 3, "20 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" },
1193
    { 4, "40 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" },
1194
    { 5, "4.8 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" },
1195
    { 6, "2.4 kb/s; 2-FSK; mod index = 2.0; channel spacing = 12.5 kHz" },
1196
    { 7, "9.6 kb/s; 4-FSK; mod index = 0.33; channel spacing = 12.5 kHz" },
1197
    { 0, NULL }
1198
};
1199
1200
static const value_string fsk_b_modes[] = {
1201
    { 0, "50 kb/s; 2-FSK; mod index = 1.0; channel spacing = 200 kHz" },
1202
    { 1, "100 kb/s; 2-FSK; mod index = 1.0; channel spacing = 400 kHz" },
1203
    { 2, "150 kb/s; 2-FSK; mod index = 0.5; channel spacing = 400 kHz" },
1204
    { 3, "200 kb/s; 2-FSK; mod index = 0.5; channel spacing = 400 kHz" },
1205
    { 4, "200 kb/s; 4-FSK; mod index = 0.33; channel spacing = 400 kHz" },
1206
    { 5, "200 kb/s; 2-FSK; mod index = 1.0; channel spacing = 600 kHz" },
1207
    { 6, "400 kb/s; 4-FSK; mod index = 0.33; channel spacing = 600 kHz" },
1208
    { 7, "100 kb/s; 2-FSK; mod index = 0.5; channel spacing = 200 kHz"},
1209
    { 8, "50 kb/s; 2-FSK; mod index = 0.5; channel spacing = 100 kHz"},
1210
    { 9, "150 kb/s; 2-FSK; mod index = 0.5; channel spacing = 200 kHz"},
1211
    { 10, "300 kb/s; 2-FSK; mod index = 0.5; channel spacing = 400 kHz" },
1212
    { 0, NULL }
1213
};
1214
1215
static const value_string oqpsk_a_modes[] = {
1216
    { 0, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 0; data rate = 6.25 kb/s"},
1217
    { 1, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 1; data rate = 12.5 kb/s"},
1218
    { 2, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 2; data rate = 25 kb/s"},
1219
    { 3, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 3; data rate = 50 kb/s"},
1220
    { 0, NULL }
1221
};
1222
1223
static const value_string oqpsk_b_modes[] = {
1224
    { 0, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 0; data rate = 31.25 kb/s"},
1225
    { 1, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 1; data rate = 125 kb/s"},
1226
    { 2, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 2; data rate = 250 kb/s"},
1227
    { 3, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 3; data rate = 500 kb/s"},
1228
    { 4, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 0; data rate = 62.5 kb/s"},
1229
    { 5, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 1; data rate = 125 kb/s"},
1230
    { 6, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 2; data rate = 250 kb/s"},
1231
    { 7, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 3; data rate = 500 kb/s"},
1232
    { 0, NULL }
1233
};
1234
1235
static const value_string oqpsk_c_modes[] = {
1236
    { 0, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 0; data rate = 31.25 kb/s"},
1237
    { 1, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 1; data rate = 125 kb/s"},
1238
    { 2, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 2; data rate = 250 kb/s"},
1239
    { 3, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 3; data rate = 500 kb/s"},
1240
    { 4, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 0; data rate = 62.5 kb/s"},
1241
    { 5, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 1; data rate = 125 kb/s"},
1242
    { 6, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 2; data rate = 250 kb/s"},
1243
    { 7, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 3; data rate = 500 kb/s"},
1244
    { 0, NULL }
1245
};
1246
1247
static const value_string ofdm_modes[] = {
1248
    { 0, "MCS0" },
1249
    { 1, "MCS1" },
1250
    { 2, "MCS2" },
1251
    { 3, "MCS3" },
1252
    { 4, "MCS4" },
1253
    { 5, "MCS5" },
1254
    { 6, "MCS6" },
1255
    { 0, NULL },
1256
};
1257
1258
static const value_string channel_page_names[] = {
1259
    { 0, "Default" },
1260
    { 1, "ASK" },
1261
    { 2, "O-QPSK" },
1262
    { 3, "CSS" },
1263
    { 4, "HRP UWB" },
1264
    { 5, "780 MHz" },
1265
    { 6, "GFSK" },
1266
    { 7, "MSK" },
1267
    { 8, "LRP_UWB" },
1268
    { 9, "SUN" },
1269
    { 10, "SUN FSK" },
1270
    { 11, "2380 MHz" },
1271
    { 12, "LECIM" },
1272
    { 13, "RCC" },
1273
    { 0, NULL }
1274
};
1275
1276
static const value_string ietf_6top_types[] = {
1277
    { IETF_6TOP_TYPE_REQUEST, "Request" },
1278
    { IETF_6TOP_TYPE_RESPONSE, "Response" },
1279
    { IETF_6TOP_TYPE_CONFIRMATION, "Confirmation" },
1280
    { 0, NULL }
1281
};
1282
1283
static const value_string ietf_6top_command_identifiers[] = {
1284
    { IETF_6TOP_CMD_ADD, "ADD" },
1285
    { IETF_6TOP_CMD_DELETE, "DELETE" },
1286
    { IETF_6TOP_CMD_RELOCATE, "RELOCATE" },
1287
    { IETF_6TOP_CMD_COUNT, "COUNT" },
1288
    { IETF_6TOP_CMD_LIST, "LIST" },
1289
    { IETF_6TOP_CMD_SIGNAL, "SIGNAL" },
1290
    { IETF_6TOP_CMD_CLEAR, "CLEAR" },
1291
    { 0, NULL }
1292
};
1293
1294
static const value_string ietf_6top_return_codes[] = {
1295
    { IETF_6TOP_RC_SUCCESS, "SUCCESS" },
1296
    { IETF_6TOP_RC_EOL, "RC_EOL" },
1297
    { IETF_6TOP_RC_ERR, "RC_ERR" },
1298
    { IETF_6TOP_RC_RESET, "RC_RESET" },
1299
    { IETF_6TOP_RC_ERR_VERSION, "RC_ERR_VERSION" },
1300
    { IETF_6TOP_RC_ERR_SFID, "RC_ERR_SFID" },
1301
    { IETF_6TOP_RC_ERR_SEQNUM, "RC_ERR_SEQNUM" },
1302
    { IETF_6TOP_RC_ERR_CELLLIST, "RC_ERR_CELLLIST" },
1303
    { IETF_6TOP_RC_ERR_BUSY, "RC_ERR_BUSY" },
1304
    { IETF_6TOP_RC_ERR_LOCKED, "RC_ERR_LOCKED" },
1305
    { 0, NULL }
1306
};
1307
1308
static const value_string ietf_6top_cell_options[] = {
1309
    { 0, "ALL" },
1310
    { 1, "TX" },
1311
    { 2, "RX" },
1312
    { 3, "TX|RX" },
1313
    { 4, "SHARED" },
1314
    { 5, "TX|SHARED" },
1315
    { 6, "RX|SHARED" },
1316
    { 7, "TX|RX|SHARED" },
1317
    { 0, NULL}
1318
};
1319
1320
static const value_string mpx_transfer_type_vals[] = {
1321
    { IEEE802159_MPX_FULL_FRAME, "Full Frame" },
1322
    { IEEE802159_MPX_FULL_FRAME_NO_MUXID, "Full frame with compressed Multiplex ID" },
1323
    { IEEE802159_MPX_NON_LAST_FRAGMENT, "Non-last Fragment" },
1324
    { IEEE802159_MPX_LAST_FRAGMENT, "Last Fragment" },
1325
    { IEEE802159_MPX_ABORT, "Abort" },
1326
    { 0, NULL }
1327
};
1328
1329
static const value_string mpx_multiplex_id_vals[] = {
1330
    { IEEE802159_MPX_MULTIPLEX_ID_KMP, "KMP" },
1331
    { IEEE802159_MPX_MULTIPLEX_ID_WISUN, "Wi-SUN" },
1332
    { 0, NULL }
1333
};
1334
1335
// used by the Wi-SUN dissector
1336
const value_string ieee802154_mpx_kmp_id_vals[] = {
1337
    { IEEE802159_MPX_KMP_ID_IEEE8021X, "IEEE 802.1X/MKA" },
1338
    { IEEE802159_MPX_KMP_ID_HIP, "HIP" },
1339
    { IEEE802159_MPX_KMP_ID_IKEV2, "IKEv2" },
1340
    { IEEE802159_MPX_KMP_ID_PANA, "PANA" },
1341
    { IEEE802159_MPX_KMP_ID_DRAGONFLY, "Dragonfly" },
1342
    { IEEE802159_MPX_KMP_ID_IEEE80211_4WH, "IEEE 802.11/4WH" },
1343
    { IEEE802159_MPX_KMP_ID_IEEE80211_GKH, "IEEE 802.11/GKH" },
1344
    { IEEE802159_MPX_KMP_ID_ETSI_TS_102_887_2, "ETSI TS 102 887-2" },
1345
    { IEEE802159_MPX_KMP_ID_VENDOR_SPECIFIC, "Vendor-specific" },
1346
    { 0, NULL }
1347
};
1348
1349
static const value_string mpx_wisun_subid_vals[] = {
1350
    { IEEE802159_MPX_WISUN_SUBID_MHDS, "WM-MHDS" },
1351
    { IEEE802159_MPX_WISUN_SUBID_6LOWPAN, "WM-6LO" },
1352
    { IEEE802159_MPX_WISUN_SUBID_SECURITY, "WM-SEC" },
1353
    { 0, NULL }
1354
};
1355
1356
static const value_string ieee802154_phr_type_vals[] = {
1357
    { PHR_RAW             , "RAW" },
1358
    { PHR_O_QPSK          , "O-QPSK" },
1359
    { PHR_CSS             , "CSS" },
1360
    { PHR_HRP_UWB         , "HRP UWB" },
1361
    { PHR_MSK             , "MSK" },
1362
    { PHR_LRP_UWB         , "LRP UWB" },
1363
    { PHR_SUN_FSK         , "SUN FSK" },
1364
    { PHR_SUN_OFDM        , "SUN OFDM" },
1365
    { PHR_SUN_O_QPSK      , "SUN O-QPSK" },
1366
    { PHR_LECIM_FSK       , "LECIM FSK" },
1367
    { PHR_TVWS_FSK        , "TVWS FSK" },
1368
    { PHR_TVWS_OFDM       , "TVWS OFDM" },
1369
    { PHR_TVWS_NB_OFDM    , "TVWS-NB OFDM" },
1370
    { PHR_RCC_LMR         , "RCC LMR" },
1371
    { PHR_CMB_O_QPSK      , "CMB O-QPSK" },
1372
    { PHR_CMB_GFSK        , "CMB GFSK" },
1373
    { PHR_TASK            , "TASK" },
1374
    { PHR_RS_GFSK         , "RS GFSK" },
1375
    { PHR_WISUN_FSK_MS    , "Wi-SUN FSK MS" },
1376
    { 0, NULL }
1377
};
1378
1379
/* SUN FSK PHR fields - IEEE 802.15.4-2020 19.2.4 */
1380
static const true_false_string tfs_fcs_type = { "2-octet FCS", "4-octet FCS" };
1381
static const value_string vals_fsk_ms_page[] = {
1382
    {0, "9"},
1383
    {1, "10"},
1384
    {0, NULL}
1385
};
1386
1387
static const value_string ieee802154_phr_fsk_ms_scheme[] = {
1388
    { 0, "SUN FSK" },
1389
    { 1, "SUN OFDM" },
1390
    { 2, "SUN O-QPSK" },
1391
    { 3, "Additional" },
1392
    { 0, NULL }
1393
};
1394
1395
static const value_string ieee802154_phr_fsk_ms_mode[] = {
1396
    { 1, "SUN FSK operating mode #1" },
1397
    { 2, "SUN FSK operating mode #2" },
1398
    { 4, "SUN FSK operating mode #3" },
1399
    { 8, "SUN FSK operating mode #4" },
1400
    { 0, NULL }
1401
};
1402
1403
static const value_string ieee802154_phr_fsk_ms_additional_modes[] = {
1404
    { 0, "SUN FSK operating mode #5" },
1405
    { 1, "SUN FSK operating mode #1a" },
1406
    { 2, "SUN FSK operating mode #1b" },
1407
    { 0, NULL }
1408
};
1409
1410
/* Wi-SUN phyModeID - Wi-SUN PHY Specification Revision 1v09 Annex F PHY Operating Mode */
1411
static const value_string ieee802154_phr_wisun_phymodeid[] = {
1412
    { 1, "FSK #1a 50ksym/s mod-index 0.5" },
1413
    { 2, "FSK #1b 50ksym/s mod-index 1.0" },
1414
    { 3, "FSK #2a 100ksym/s mod-index 0.5" },
1415
    { 4, "FSK #2b 100ksym/s mod-index 1.0" },
1416
    { 5, "FSK #3 150ksym/s mod-index 0.5" },
1417
    { 6, "FSK #4a 200ksym/s mod-index 0.5" },
1418
    { 7, "FSK #4b 200ksym/s mod-index 1.0" },
1419
    { 8, "FSK #5 300ksym/s mod-index 0.5" },
1420
    { 17, "FSK with FEC #1a 50ksym/s mod-index 0.5" },
1421
    { 18, "FSK with FEC #1b 50ksym/s mod-index 1.0" },
1422
    { 19, "FSK with FEC #2a 100ksym/s mod-index 0.5" },
1423
    { 20, "FSK with FEC #2b 100ksym/s mod-index 1.0" },
1424
    { 21, "FSK with FEC #3 150ksym/s mod-index 0.5" },
1425
    { 22, "FSK with FEC #4a 200ksym/s mod-index 0.5" },
1426
    { 23, "FSK with FEC #4b 200ksym/s mod-index 1.0" },
1427
    { 24, "FSK with FEC #5 300ksym/s mod-index 0.5" },
1428
    { 34, "OFDM Option 1 MCS 2 400kbps" },
1429
    { 35, "OFDM Option 1 MCS 3 800kbps" },
1430
    { 36, "OFDM Option 1 MCS 4 1200kbps" },
1431
    { 37, "OFDM Option 1 MCS 5 1600kbps" },
1432
    { 38, "OFDM Option 1 MCS 6 2400kbps" },
1433
    { 51, "OFDM Option 2 MCS 3 400kbps" },
1434
    { 52, "OFDM Option 2 MCS 4 600kbps" },
1435
    { 53, "OFDM Option 2 MCS 5 800kbps" },
1436
    { 54, "OFDM Option 2 MCS 6 1200kbps" },
1437
    { 68, "OFDM Option 3 MCS 4 300kbps" },
1438
    { 69, "OFDM Option 3 MCS 5 400kbps" },
1439
    { 70, "OFDM Option 3 MCS 6 600kbps" },
1440
    { 84, "OFDM Option 4 MCS 4 150kbps" },
1441
    { 85, "OFDM Option 4 MCS 5 200kbps" },
1442
    { 86, "OFDM Option 4 MCS 6 300kbps" },
1443
    { 0, NULL }
1444
};
1445
1446
/* Preferences for 2003 security */
1447
static int ieee802154_sec_suite = SECURITY_LEVEL_ENC_MIC_64;
1448
static bool ieee802154_extend_auth = true;
1449
1450
/* Macro to check addressing, and throw a warning flag if incorrect. */
1451
#define IEEE802154_CMD_ADDR_CHECK(_pinfo_, _item_, _cmdid_, _x_)     \
1452
44
   if (!(_x_))                                                       \
1453
25
     expert_add_info_format(_pinfo_, _item_, &ei_ieee802154_invalid_addressing, \
1454
24
                            "Invalid Addressing for %s",             \
1455
24
                            val_to_str_const(_cmdid_, ieee802154_cmd_names, "Unknown Command"))
1456
1457
/* CRC definitions. IEEE 802.15.4 CRCs vary from ITU-T by using an initial value of
1458
 * 0x0000, and no XOR out. IEEE802154_CRC_XOR is defined as 0xFFFF in order to un-XOR
1459
 * the output from the ITU-T (CCITT) CRC routines in Wireshark.
1460
 */
1461
537
#define IEEE802154_CRC_SEED     0x0000
1462
537
#define IEEE802154_CRC_XOROUT   0xFFFF
1463
537
#define ieee802154_crc_tvb(tvb, offset)   (crc16_ccitt_tvb_seed(tvb, offset, IEEE802154_CRC_SEED) ^ IEEE802154_CRC_XOROUT)
1464
1465
/* For the 32-bit CRC, IEEE 802.15.4 uses ITU-T (CCITT) CRC-32. */
1466
0
#define ieee802154_crc32_tvb(tvb, offset) (crc32_ccitt_tvb(tvb, offset))
1467
1468
static int ieee802_15_4_short_address_to_str(const address* addr, char *buf, int buf_len)
1469
20.1k
{
1470
20.1k
    uint16_t ieee_802_15_4_short_addr = pletohu16(addr->data);
1471
1472
20.1k
    if (ieee_802_15_4_short_addr == 0xffff)
1473
58
    {
1474
58
        (void) g_strlcpy(buf, "Broadcast", buf_len);
1475
58
        return 10;
1476
58
    }
1477
1478
20.0k
    *buf++ = '0';
1479
20.0k
    *buf++ = 'x';
1480
20.0k
    buf = word_to_hex(buf, ieee_802_15_4_short_addr);
1481
20.0k
    *buf = '\0'; /* NULL terminate */
1482
1483
20.0k
    return 7;
1484
20.1k
}
1485
1486
static int ieee802_15_4_short_address_str_len(const address* addr _U_)
1487
20.1k
{
1488
20.1k
    return 11;
1489
20.1k
}
1490
1491
static int ieee802_15_4_short_address_len(void)
1492
0
{
1493
0
    return 2;
1494
0
}
1495
1496
/* ======================================================================= */
1497
static conversation_t *_find_or_create_conversation(packet_info *pinfo, const address *src_addr, const address *dst_addr)
1498
4.53k
{
1499
4.53k
    conversation_t *conv = NULL;
1500
1501
    /* Have we seen this conversation before? */
1502
4.53k
    conv = find_conversation(pinfo->num, src_addr, dst_addr, CONVERSATION_NONE, 0, 0, 0);
1503
4.53k
    if (conv == NULL) {
1504
        /* No, this is a new conversation. */
1505
798
        conv = conversation_new(pinfo->num, src_addr, dst_addr, CONVERSATION_NONE, 0, 0, 0);
1506
798
    }
1507
4.53k
    return conv;
1508
4.53k
}
1509
1510
/* ======================================================================= */
1511
static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key)
1512
0
{
1513
0
    ieee802154_transaction_t    *ieee802154_trans;
1514
0
    wmem_tree_key_t             ieee802154_key[3];
1515
0
    proto_item                  *it;
1516
1517
0
    if (!PINFO_FD_VISITED(pinfo)) {
1518
        /*
1519
         * This is a new request, create a new transaction structure and map it
1520
         * to the unmatched table.
1521
         */
1522
0
        ieee802154_key[0].length = 2;
1523
0
        ieee802154_key[0].key = key;
1524
0
        ieee802154_key[1].length = 0;
1525
0
        ieee802154_key[1].key = NULL;
1526
1527
0
        ieee802154_trans = wmem_new0(wmem_file_scope(), ieee802154_transaction_t);
1528
1529
0
        if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT)
1530
0
            ieee802154_trans->dst16 = packet->dst16;
1531
0
        else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)
1532
0
            ieee802154_trans->dst64 = packet->dst64;
1533
0
        ieee802154_trans->dst_addr_mode = packet->dst_addr_mode;
1534
1535
0
        if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT)
1536
0
            ieee802154_trans->src16 = packet->src16;
1537
0
        else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT)
1538
0
            ieee802154_trans->src64 = packet->src64;
1539
0
        ieee802154_trans->src_addr_mode = packet->src_addr_mode;
1540
1541
0
        if (packet->dst_pan_present) {
1542
0
            ieee802154_trans->dst_pan_present = true;
1543
0
            ieee802154_trans->dst_pan = packet->dst_pan;
1544
0
        }
1545
0
        if (packet->src_pan_present) {
1546
0
            ieee802154_trans->src_pan_present = true;
1547
0
            ieee802154_trans->src_pan = packet->src_pan;
1548
0
        }
1549
0
        ieee802154_trans->rqst_frame = pinfo->num;
1550
0
        ieee802154_trans->ack_frame = 0;
1551
0
        ieee802154_trans->rqst_time = pinfo->abs_ts;
1552
0
        nstime_set_unset(&ieee802154_trans->ack_time);
1553
0
        wmem_tree_insert32_array(transaction_unmatched_pdus, ieee802154_key, (void *)ieee802154_trans);
1554
0
    } else {
1555
        /* Already visited this frame */
1556
0
        uint32_t frame_num = pinfo->num;
1557
1558
0
        ieee802154_key[0].length = 2;
1559
0
        ieee802154_key[0].key = key;
1560
0
        ieee802154_key[1].length = 1;
1561
0
        ieee802154_key[1].key = &frame_num;
1562
0
        ieee802154_key[2].length = 0;
1563
0
        ieee802154_key[2].key = NULL;
1564
1565
0
        ieee802154_trans = (ieee802154_transaction_t *)wmem_tree_lookup32_array(transaction_matched_pdus, ieee802154_key);
1566
1567
0
        if (!ieee802154_trans) {
1568
            /* No ACK found - add field and expert info */
1569
0
            it = proto_tree_add_item(tree, hf_ieee802154_no_ack, NULL, 0, 0, ENC_NA);
1570
0
            proto_item_set_generated(it);
1571
1572
0
            expert_add_info_format(pinfo, it, &ei_ieee802154_ack_not_found, "No ack found to request in frame %u", pinfo->num);
1573
1574
0
            return NULL;
1575
0
        }
1576
0
    }
1577
1578
    /* Print state tracking in the tree */
1579
0
    if (ieee802154_trans->ack_frame) {
1580
0
        it = proto_tree_add_uint(tree, hf_ieee802154_ack_in, NULL, 0, 0, ieee802154_trans->ack_frame);
1581
0
        proto_item_set_generated(it);
1582
0
    }
1583
1584
0
    return ieee802154_trans;
1585
0
} /* transaction_start() */
1586
1587
static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key)
1588
0
{
1589
0
    ieee802154_transaction_t    *ieee802154_trans = NULL;
1590
0
    wmem_tree_key_t             ieee802154_key[3];
1591
0
    proto_item                  *it;
1592
1593
0
    if (!PINFO_FD_VISITED(pinfo)) {
1594
0
        uint32_t frame_num;
1595
0
        nstime_t ns;
1596
1597
0
        ieee802154_key[0].length = 2;
1598
0
        ieee802154_key[0].key = key;
1599
0
        ieee802154_key[1].length = 0;
1600
0
        ieee802154_key[1].key = NULL;
1601
1602
0
        ieee802154_trans = (ieee802154_transaction_t *)wmem_tree_lookup32_array(transaction_unmatched_pdus, ieee802154_key);
1603
0
        if (ieee802154_trans == NULL)
1604
0
            return NULL;
1605
1606
        /* we have already seen this response, or an identical one */
1607
0
        if (ieee802154_trans->ack_frame != 0)
1608
0
            return NULL;
1609
1610
        /* If addresses are present they must match */
1611
0
        if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
1612
0
            if (packet->src16 != ieee802154_trans->dst16)
1613
0
                return NULL;
1614
0
        }
1615
0
        else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1616
0
            if (packet->src64 != ieee802154_trans->dst64)
1617
0
                return NULL;
1618
0
        }
1619
0
        if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
1620
0
            if (packet->dst16 != ieee802154_trans->src16)
1621
0
                return NULL;
1622
0
        }
1623
0
        else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1624
0
            if (packet->dst64 != ieee802154_trans->src64)
1625
0
                return NULL;
1626
0
        }
1627
1628
0
        nstime_delta(&ns, &pinfo->abs_ts, &ieee802154_trans->rqst_time);
1629
0
        if (nstime_cmp(&ns, &ieee802154_transaction_timeout) > 0)
1630
0
            return NULL;
1631
1632
0
        ieee802154_trans->ack_time = ns;
1633
0
        ieee802154_trans->ack_frame = pinfo->num;
1634
1635
        /*
1636
         * We found a match.  Add entries to the matched table for both
1637
         * request and ack frames
1638
         */
1639
0
        ieee802154_key[0].length = 2;
1640
0
        ieee802154_key[0].key = key;
1641
0
        ieee802154_key[1].length = 1;
1642
0
        ieee802154_key[1].key = &frame_num;
1643
0
        ieee802154_key[2].length = 0;
1644
0
        ieee802154_key[2].key = NULL;
1645
1646
0
        frame_num = ieee802154_trans->rqst_frame;
1647
0
        wmem_tree_insert32_array(transaction_matched_pdus, ieee802154_key, (void *)ieee802154_trans);
1648
1649
0
        frame_num = ieee802154_trans->ack_frame;
1650
0
        wmem_tree_insert32_array(transaction_matched_pdus, ieee802154_key, (void *)ieee802154_trans);
1651
0
    } else {
1652
        /* Already visited this frame */
1653
0
        uint32_t frame_num = pinfo->num;
1654
1655
0
        ieee802154_key[0].length = 2;
1656
0
        ieee802154_key[0].key = key;
1657
0
        ieee802154_key[1].length = 1;
1658
0
        ieee802154_key[1].key = &frame_num;
1659
0
        ieee802154_key[2].length = 0;
1660
0
        ieee802154_key[2].key = NULL;
1661
1662
0
        ieee802154_trans = (ieee802154_transaction_t *)wmem_tree_lookup32_array(transaction_matched_pdus, ieee802154_key);
1663
1664
0
        if (!ieee802154_trans) {
1665
            /* No ack request found - add field and expert info */
1666
0
            it = proto_tree_add_item(tree, hf_ieee802154_no_ack_request, NULL, 0, 0, ENC_NA);
1667
0
            proto_item_set_generated(it);
1668
1669
0
            expert_add_info_format(pinfo, it, &ei_ieee802154_ack_request_not_found, "No request found to ack in frame %u", pinfo->num);
1670
0
            return NULL;
1671
0
        }
1672
0
    }
1673
1674
0
    if (packet->dst_pan_present == false) {
1675
0
        if (ieee802154_trans->src_pan_present) {
1676
0
            it = proto_tree_add_uint(tree, hf_ieee802154_dst_panID, NULL, 0, 0, ieee802154_trans->src_pan);
1677
0
            proto_item_set_generated(it);
1678
0
        }
1679
0
        else if (ieee802154_trans->dst_pan_present) {
1680
0
            it = proto_tree_add_uint(tree, hf_ieee802154_dst_panID, NULL, 0, 0, ieee802154_trans->dst_pan);
1681
0
            proto_item_set_generated(it);
1682
0
        }
1683
0
    }
1684
0
    if ((packet->src_pan_present == false) && (ieee802154_trans->src_pan_present) && (ieee802154_trans->dst_pan_present)) {
1685
0
        it = proto_tree_add_uint(tree, hf_ieee802154_src_panID, NULL, 0, 0, ieee802154_trans->dst_pan);
1686
0
        proto_item_set_generated(it);
1687
0
    }
1688
1689
0
    if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) {
1690
0
        if (ieee802154_trans->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
1691
0
            it = proto_tree_add_uint(tree, hf_ieee802154_dst16, NULL, 0, 0, ieee802154_trans->src16);
1692
0
            proto_item_set_generated(it);
1693
1694
0
            it = proto_tree_add_uint(tree, hf_ieee802154_addr16, NULL, 0, 0, ieee802154_trans->src16);
1695
0
            proto_item_set_hidden(it);
1696
0
            proto_item_set_generated(it);
1697
0
        }
1698
0
        else if (ieee802154_trans->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1699
0
            it = proto_tree_add_eui64(tree, hf_ieee802154_dst64, NULL, 0, 0, ieee802154_trans->src64);
1700
0
            proto_item_set_generated(it);
1701
1702
0
            it = proto_tree_add_eui64(tree, hf_ieee802154_addr64, NULL, 0, 0, ieee802154_trans->src64);
1703
0
            proto_item_set_hidden(it);
1704
0
            proto_item_set_generated(it);
1705
0
        }
1706
0
    }
1707
1708
0
    if (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) {
1709
0
        if (ieee802154_trans->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
1710
0
            it = proto_tree_add_uint(tree, hf_ieee802154_src16, NULL, 0, 0, ieee802154_trans->dst16);
1711
0
            proto_item_set_generated(it);
1712
1713
0
            it = proto_tree_add_uint(tree, hf_ieee802154_addr16, NULL, 0, 0, ieee802154_trans->dst16);
1714
0
            proto_item_set_hidden(it);
1715
0
            proto_item_set_generated(it);
1716
0
        }
1717
0
        else if (ieee802154_trans->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1718
0
            it = proto_tree_add_eui64(tree, hf_ieee802154_src64, NULL, 0, 0, ieee802154_trans->dst64);
1719
0
            proto_item_set_generated(it);
1720
1721
0
            it = proto_tree_add_eui64(tree, hf_ieee802154_addr64, NULL, 0, 0, ieee802154_trans->dst64);
1722
0
            proto_item_set_hidden(it);
1723
0
            proto_item_set_generated(it);
1724
0
        }
1725
0
    }
1726
1727
    /* Print state tracking in the tree */
1728
0
    it = proto_tree_add_uint(tree, hf_ieee802154_ack_to, NULL, 0, 0, ieee802154_trans->rqst_frame);
1729
0
    proto_item_set_generated(it);
1730
1731
0
    it = proto_tree_add_time(tree, hf_ieee802154_ack_time, NULL, 0, 0, &ieee802154_trans->ack_time);
1732
0
    proto_item_set_generated(it);
1733
1734
0
    return ieee802154_trans;
1735
1736
0
} /* transaction_end() */
1737
1738
/**
1739
 * Dissector helper, parses and displays the frame control field.
1740
 *
1741
 * @param tvb pointer to buffer containing raw packet.
1742
 * @param pinfo pointer to packet information fields
1743
 * @param tree pointer to data tree wireshark uses to display packet.
1744
 * @param packet IEEE 802.15.4 packet information.
1745
 * @param offset offset into the tvb to find the FCF.
1746
 *
1747
 */
1748
static void
1749
dissect_ieee802154_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet, unsigned *offset)
1750
7.62k
{
1751
7.62k
    uint16_t    fcf;
1752
7.62k
    static int * const ieee802154_fields[] = {
1753
7.62k
        &hf_ieee802154_frame_type,
1754
7.62k
        &hf_ieee802154_security,
1755
7.62k
        &hf_ieee802154_pending,
1756
7.62k
        &hf_ieee802154_ack_request,
1757
7.62k
        &hf_ieee802154_pan_id_compression,
1758
7.62k
        &hf_ieee802154_fcf_reserved,
1759
7.62k
        &hf_ieee802154_seqno_suppression,
1760
7.62k
        &hf_ieee802154_ie_present,
1761
7.62k
        &hf_ieee802154_dst_addr_mode,
1762
7.62k
        &hf_ieee802154_version,
1763
7.62k
        &hf_ieee802154_src_addr_mode,
1764
7.62k
        NULL
1765
7.62k
    };
1766
1767
7.62k
    static int* const ieee802154_mpf_short_fields[] = {
1768
7.62k
        &hf_ieee802154_frame_type,
1769
7.62k
        &hf_ieee802154_mpf_long_frame_control,
1770
7.62k
        &hf_ieee802154_mpf_dst_addr_mode,
1771
7.62k
        &hf_ieee802154_mpf_src_addr_mode,
1772
7.62k
        NULL
1773
7.62k
    };
1774
1775
7.62k
    static int* const ieee802154_mpf_long_fields[] = {
1776
7.62k
        &hf_ieee802154_frame_type,
1777
7.62k
        &hf_ieee802154_mpf_long_frame_control,
1778
7.62k
        &hf_ieee802154_mpf_dst_addr_mode,
1779
7.62k
        &hf_ieee802154_mpf_src_addr_mode,
1780
7.62k
        &hf_ieee802154_mpf_pan_id_present,
1781
7.62k
        &hf_ieee802154_mpf_security,
1782
7.62k
        &hf_ieee802154_mpf_seqno_suppression,
1783
7.62k
        &hf_ieee802154_mpf_pending,
1784
7.62k
        &hf_ieee802154_mpf_version,
1785
7.62k
        &hf_ieee802154_mpf_ack_request,
1786
7.62k
        &hf_ieee802154_mpf_ie_present,
1787
7.62k
        NULL
1788
7.62k
    };
1789
1790
    /* Get the FCF field. */
1791
7.62k
    fcf = tvb_get_letohs(tvb, *offset);
1792
1793
     /* Parse FCF Flags. */
1794
7.62k
    packet->frame_type          = (fcf & IEEE802154_FCF_TYPE_MASK);
1795
1796
7.62k
    if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) {
1797
        /* Multipurpose frames use a different 1 or 2 byte FCF */
1798
40
        packet->long_frame_control  = (fcf & IEEE802154_MPF_FCF_LONG_FC) >> 3;
1799
40
        packet->dst_addr_mode       = (fcf & IEEE802154_MPF_FCF_DADDR_MASK) >> 4;
1800
40
        packet->src_addr_mode       = (fcf & IEEE802154_MPF_FCF_SADDR_MASK) >> 6;
1801
1802
        /* The second octet of the FCF is only present if the long frame control bit is set */
1803
40
        if (packet->long_frame_control) {
1804
37
            packet->pan_id_present = (fcf & IEEE802154_MPF_FCF_PAN_ID_PRESENT) >> 8;
1805
37
            packet->security_enable = (fcf & IEEE802154_MPF_FCF_SEC_EN) >> 9;
1806
37
            packet->seqno_suppression = (fcf & IEEE802154_MPF_FCF_SEQNO_SUPPRESSION) >> 10;
1807
37
            packet->frame_pending   = (fcf & IEEE802154_MPF_FCF_FRAME_PND) >> 11;
1808
37
            packet->version         = (fcf & IEEE802154_MPF_FCF_VERSION) >> 12;
1809
37
            packet->ack_request     = (fcf & IEEE802154_MPF_FCF_ACK_REQ) >> 14;
1810
37
            packet->ie_present      = (fcf & IEEE802154_MPF_FCF_IE_PRESENT) >> 15;
1811
37
        }
1812
3
        else {
1813
3
            packet->security_enable = false;
1814
3
            packet->seqno_suppression = false;
1815
3
            packet->frame_pending   = false;
1816
3
            packet->version         = 0;
1817
3
            packet->ack_request     = false;
1818
3
            packet->ie_present      = false;
1819
3
        }
1820
1821
40
        if (ieee802154e_compatibility) {
1822
0
            if (((tvb_reported_length(tvb) == IEEE802154E_LE_WUF_LEN)) && !packet->long_frame_control) {
1823
                /* Check if this is an IEEE 802.15.4e LE-multipurpose Wake-up Frame, which has a single-octet FCF
1824
                 * and a static layout that cannot be inferred from the FCF alone. */
1825
0
                uint16_t ie_header = tvb_get_letohs(tvb, (*offset) + 6);
1826
0
                uint16_t id = (uint16_t)((ie_header & IEEE802154_HEADER_IE_ID_MASK) >> 7);
1827
0
                uint16_t length = (uint16_t)(ie_header & IEEE802154_HEADER_IE_LENGTH_MASK);
1828
0
                if ((id == IEEE802154_HEADER_IE_RENDEZVOUS) && (length == 2)) {
1829
                    /* This appears to be a WUF, as identified by containing a single
1830
                     * Rendezvous Time Header IE with only a rendezvous time. */
1831
0
                    packet->ie_present = true;
1832
0
                    packet->pan_id_present = true;
1833
0
                }
1834
0
            }
1835
0
        }
1836
40
    }
1837
7.58k
    else {
1838
        /* Standard 802.15.4 FCF */
1839
7.58k
        packet->security_enable     = (fcf & IEEE802154_FCF_SEC_EN) >> 3;
1840
7.58k
        packet->frame_pending       = (fcf & IEEE802154_FCF_FRAME_PND) >> 4;
1841
7.58k
        packet->ack_request         = (fcf & IEEE802154_FCF_ACK_REQ) >> 5;
1842
7.58k
        packet->pan_id_compression  = (fcf & IEEE802154_FCF_PAN_ID_COMPRESSION) >> 6;
1843
        /* bit 7 reserved */
1844
7.58k
        packet->seqno_suppression   = (fcf & IEEE802154_FCF_SEQNO_SUPPRESSION) >> 8;
1845
7.58k
        packet->ie_present          = (fcf & IEEE802154_FCF_IE_PRESENT) >> 9;
1846
7.58k
        packet->dst_addr_mode       = (fcf & IEEE802154_FCF_DADDR_MASK) >> 10;
1847
7.58k
        packet->version             = (fcf & IEEE802154_FCF_VERSION) >> 12;
1848
7.58k
        packet->src_addr_mode       = (fcf & IEEE802154_FCF_SADDR_MASK) >> 14;
1849
7.58k
    }
1850
1851
7.62k
    if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_BEACON)) {
1852
201
        proto_item_append_text(tree, " Enhanced Beacon");
1853
201
        col_set_str(pinfo->cinfo, COL_INFO, "Enhanced Beacon");
1854
201
    }
1855
7.42k
    else {
1856
7.42k
        proto_item_append_text(tree, " %s", val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved"));
1857
7.42k
        col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved"));
1858
7.42k
    }
1859
1860
7.62k
    if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) {
1861
40
        if (packet->long_frame_control) {
1862
37
            proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf,
1863
37
                                   ett_ieee802154_fcf, ieee802154_mpf_long_fields, ENC_LITTLE_ENDIAN);
1864
37
            *offset += 2;
1865
37
        }
1866
3
        else {
1867
3
            proto_tree_add_bitmask_len(tree, tvb, *offset, 1, hf_ieee802154_fcf,
1868
3
                                       ett_ieee802154_fcf, ieee802154_mpf_short_fields,
1869
3
                                       &ei_ieee802154_fcs_bitmask_len, ENC_LITTLE_ENDIAN);
1870
3
            *offset += 1;
1871
3
        }
1872
40
    }
1873
7.58k
    else {
1874
7.58k
        proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf,
1875
7.58k
                               ett_ieee802154_fcf, ieee802154_fields, ENC_LITTLE_ENDIAN);
1876
7.58k
        *offset += 2;
1877
7.58k
    }
1878
1879
7.62k
} /* dissect_ieee802154_fcf */
1880
1881
void register_ieee802154_mac_key_hash_handler(unsigned hash_identifier, ieee802154_set_key_func key_func)
1882
16
{
1883
    /* Ensure no duplication */
1884
16
    DISSECTOR_ASSERT(wmem_tree_lookup32(mac_key_hash_handlers, hash_identifier) == NULL);
1885
1886
16
    wmem_tree_insert32(mac_key_hash_handlers, hash_identifier, (void*)key_func);
1887
16
}
1888
1889
void dissect_ieee802154_aux_sec_header_and_key_with_hf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, ieee802154_packet *packet, unsigned *offset, const ieee802154_aux_sec_hf_t *aux_sec_hf)
1890
118
{
1891
118
    proto_tree *field_tree, *header_tree;
1892
118
    proto_item *ti, *hidden_item;
1893
118
    uint8_t    security_control;
1894
118
    unsigned   aux_length = 1; /* Minimum length of the auxiliary header. */
1895
118
    int hf_hdr = aux_sec_hf ? aux_sec_hf->hf_aux_security_header : hf_ieee802154_aux_security_header;
1896
118
    int hf_sec_ctrl = aux_sec_hf ? aux_sec_hf->hf_aux_sec_security_control : hf_ieee802154_aux_sec_security_control;
1897
118
    int hf_sec_level = aux_sec_hf ? aux_sec_hf->hf_aux_sec_security_level : hf_ieee802154_aux_sec_security_level;
1898
118
    int hf_key_id_mode = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_id_mode : hf_ieee802154_aux_sec_key_id_mode;
1899
118
    int hf_fc_suppress = aux_sec_hf ? aux_sec_hf->hf_aux_sec_frame_counter_suppression : hf_ieee802154_aux_sec_frame_counter_suppression;
1900
118
    int hf_asn = aux_sec_hf ? aux_sec_hf->hf_aux_sec_asn_in_nonce : hf_ieee802154_aux_sec_asn_in_nonce;
1901
118
    int hf_res = aux_sec_hf ? aux_sec_hf->hf_aux_sec_reserved : hf_ieee802154_aux_sec_reserved;
1902
118
    int hf_fc = aux_sec_hf ? aux_sec_hf->hf_aux_sec_frame_counter : hf_ieee802154_aux_sec_frame_counter;
1903
118
    int hf_ks = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_source : hf_ieee802154_aux_sec_key_source;
1904
118
    int hf_ks_bytes = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_source_bytes : hf_ieee802154_aux_sec_key_source_bytes;
1905
118
    int hf_ki = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_index : hf_ieee802154_aux_sec_key_index;
1906
118
    int ett_aux = aux_sec_hf ? aux_sec_hf->ett_auxiliary_security : ett_ieee802154_auxiliary_security;
1907
118
    int ett_ctrl = aux_sec_hf ? aux_sec_hf->ett_aux_sec_control : ett_ieee802154_aux_sec_control;
1908
118
    int ett_kid = aux_sec_hf ? aux_sec_hf->ett_aux_sec_key_id : ett_ieee802154_aux_sec_key_id;
1909
1910
118
    int * const security_fields[] = {
1911
118
            &hf_sec_level,
1912
118
            &hf_key_id_mode,
1913
118
            &hf_fc_suppress,
1914
118
            &hf_asn,
1915
118
            &hf_res,
1916
118
            NULL
1917
118
    };
1918
1919
    /* Parse the security control field. */
1920
118
    security_control = tvb_get_uint8(tvb, *offset);
1921
118
    packet->security_level = (ieee802154_security_level)(security_control & IEEE802154_AUX_SEC_LEVEL_MASK);
1922
118
    packet->key_id_mode = (ieee802154_key_id_mode)((security_control & IEEE802154_AUX_KEY_ID_MODE_MASK) >> IEEE802154_AUX_KEY_ID_MODE_SHIFT);
1923
118
    if (packet->version == IEEE802154_VERSION_2015) {
1924
25
        packet->frame_counter_suppression = security_control & IEEE802154_AUX_FRAME_COUNTER_SUPPRESSION_MASK ? true : false;
1925
25
    }
1926
1927
    /* Compute the length of the auxiliary header and create a subtree.  */
1928
118
    if (!packet->frame_counter_suppression) aux_length += 4;
1929
118
    if (packet->key_id_mode != KEY_ID_MODE_IMPLICIT) aux_length++;
1930
118
    if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_4) aux_length += 4;
1931
118
    if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_8) aux_length += 8;
1932
1933
118
    ti = proto_tree_add_item(tree, hf_hdr, tvb, *offset, aux_length, ENC_NA);
1934
118
    header_tree = proto_item_add_subtree(ti, ett_aux);
1935
1936
    /* Security Control Field */
1937
118
    proto_tree_add_bitmask(header_tree, tvb, *offset, hf_sec_ctrl, ett_ctrl, security_fields, ENC_NA);
1938
118
    (*offset)++;
1939
1940
    /* Frame Counter Field */
1941
118
    if (!packet->frame_counter_suppression) {
1942
101
        proto_tree_add_item_ret_uint(header_tree, hf_fc, tvb, *offset, 4, ENC_LITTLE_ENDIAN, &packet->frame_counter);
1943
101
        (*offset) += 4;
1944
101
    }
1945
17
    else {
1946
17
        packet->asn = ieee802154_tsch_asn;
1947
17
    }
1948
1949
    /* Key identifier field(s). */
1950
118
    if (packet->key_id_mode != KEY_ID_MODE_IMPLICIT) {
1951
        /* Create a subtree. */
1952
30
        field_tree = proto_tree_add_subtree(header_tree, tvb, *offset, 1,
1953
30
                ett_kid, &ti, "Key Identifier Field"); /* Will fix length later. */
1954
        /* Add key source, if it exists. */
1955
30
        if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_4) {
1956
10
            packet->key_source.addr32 = tvb_get_ntohl(tvb, *offset);
1957
10
            proto_tree_add_uint64(field_tree, hf_ks, tvb, *offset, 4, packet->key_source.addr32);
1958
10
            hidden_item = proto_tree_add_item(field_tree, hf_ks_bytes, tvb, *offset, 4, ENC_NA);
1959
10
            proto_item_set_hidden(hidden_item);
1960
10
            proto_item_set_len(ti, 1 + 4);
1961
10
            (*offset) += 4;
1962
10
        }
1963
30
        if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_8) {
1964
8
            packet->key_source.addr64 = tvb_get_ntoh64(tvb, *offset);
1965
8
            proto_tree_add_uint64(field_tree, hf_ks, tvb, *offset, 8, packet->key_source.addr64);
1966
8
            hidden_item = proto_tree_add_item(field_tree, hf_ks_bytes, tvb, *offset, 8, ENC_NA);
1967
8
            proto_item_set_hidden(hidden_item);
1968
8
            proto_item_set_len(ti, 1 + 8);
1969
8
            (*offset) += 8;
1970
8
        }
1971
        /* Add key identifier. */
1972
30
        packet->key_index = tvb_get_uint8(tvb, *offset);
1973
30
        proto_tree_add_uint(field_tree, hf_ki, tvb, *offset, 1, packet->key_index);
1974
30
        (*offset)++;
1975
30
    }
1976
118
}
1977
1978
void dissect_ieee802154_aux_sec_header_and_key(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, ieee802154_packet *packet, unsigned *offset)
1979
47
{
1980
47
    dissect_ieee802154_aux_sec_header_and_key_with_hf(tvb, pinfo, tree, packet, offset, NULL);
1981
47
}
1982
1983
tvbuff_t *decrypt_ieee802154_payload(tvbuff_t * tvb, unsigned offset, packet_info * pinfo, proto_tree* key_tree,
1984
                                     ieee802154_packet * packet, ieee802154_decrypt_info_t* decrypt_info,
1985
                                     ieee802154_set_key_func set_key_func, ieee802154_decrypt_func decrypt_func)
1986
36
{
1987
36
    proto_item* ti;
1988
36
    unsigned char key[IEEE802154_CIPHER_SIZE];
1989
36
    unsigned char alt_key[IEEE802154_CIPHER_SIZE];
1990
36
    tvbuff_t * payload_tvb = NULL;
1991
1992
    /* Lookup the key. */
1993
36
    for (decrypt_info->key_number = 0; decrypt_info->key_number < num_ieee802154_keys; decrypt_info->key_number++) {
1994
0
        unsigned nkeys = set_key_func(packet, key, alt_key, &ieee802154_keys[decrypt_info->key_number]);
1995
0
        if (nkeys >= 1) {
1996
            /* Try with the initial key */
1997
0
            payload_tvb = decrypt_func(tvb, offset, pinfo, packet, decrypt_info, key);
1998
0
            if (!((*decrypt_info->status == DECRYPT_PACKET_MIC_CHECK_FAILED) || (*decrypt_info->status == DECRYPT_PACKET_DECRYPT_FAILED))) {
1999
0
                break;
2000
0
            }
2001
0
        }
2002
0
        if (nkeys >= 2) {
2003
            /* Try also with the alternate key */
2004
0
            payload_tvb = decrypt_func(tvb, offset, pinfo, packet, decrypt_info, alt_key);
2005
0
            if (!((*decrypt_info->status == DECRYPT_PACKET_MIC_CHECK_FAILED) || (*decrypt_info->status == DECRYPT_PACKET_DECRYPT_FAILED))) {
2006
0
                break;
2007
0
            }
2008
0
        }
2009
0
    }
2010
36
    if (decrypt_info->key_number == num_ieee802154_keys) {
2011
        /* None of the stored keys seemed to work */
2012
36
        *decrypt_info->status = DECRYPT_PACKET_NO_KEY;
2013
36
    }
2014
2015
    /* Store the key number used for retrieval */
2016
36
    ti = proto_tree_add_uint(key_tree, hf_ieee802154_key_number, tvb, 0, 0, decrypt_info->key_number);
2017
36
    proto_item_set_hidden(ti);
2018
36
    return payload_tvb;
2019
36
}
2020
2021
2022
/**
2023
 * Check if the CRC-OK flag in the CC24xx metadata trailer is true
2024
 * @param tvb the IEEE 802.15.4 frame
2025
 * @return if the flag is true
2026
 */
2027
static bool
2028
is_cc24xx_crc_ok(tvbuff_t *tvb)
2029
0
{
2030
0
    return tvb_get_letohs(tvb, tvb_reported_length(tvb)-2) & IEEE802154_CC24xx_CRC_OK ? true : false;
2031
0
}
2032
2033
/**
2034
 * Verify the 16/32 bit IEEE 802.15.4 FCS
2035
 * @param tvb the IEEE 802.15.4 frame from the FCF up to and including the FCS
2036
 * @return if the computed FCS matches the transmitted FCS
2037
 */
2038
static bool
2039
is_fcs_ok(tvbuff_t *tvb, unsigned fcs_len)
2040
396
{
2041
396
    if (fcs_len == 2) {
2042
        /* The FCS is in the last two bytes of the packet. */
2043
396
        uint16_t fcs = tvb_get_letohs(tvb, tvb_reported_length(tvb)-2);
2044
396
        uint16_t fcs_calc = (uint16_t) ieee802154_crc_tvb(tvb, tvb_reported_length(tvb)-2);
2045
396
        return fcs == fcs_calc;
2046
396
    }
2047
0
    else {
2048
        /* The FCS is in the last four bytes of the packet. */
2049
0
        uint32_t fcs = tvb_get_letohl(tvb, tvb_reported_length(tvb)-4);
2050
0
        uint32_t fcs_calc = ieee802154_crc32_tvb(tvb, tvb_reported_length(tvb)-4);
2051
0
        return fcs == fcs_calc;
2052
0
    }
2053
396
}
2054
2055
/**
2056
 * Dissector for IEEE 802.15.4 packets with a PHY for which there's a
2057
 * 4-octet preamble, a 1-octet SFD, and a 1-octet PHY header
2058
 * with the uppermost bit reserved and the remaining 7 bits being
2059
 * the frame length, and a 16-bit CRC value at the end.
2060
 *
2061
 * Currently, those are the following PHYs:
2062
 *
2063
 *    O-QPSK
2064
 *    Binary phase-shift keying (BPSK)
2065
 *    GFSK
2066
 *    MSK
2067
 *    RCC DSSS BPSK
2068
 *
2069
 * @param tvb pointer to buffer containing raw packet.
2070
 * @param pinfo pointer to packet information fields
2071
 * @param tree pointer to data tree wireshark uses to display packet.
2072
 */
2073
static int
2074
dissect_ieee802154_nonask_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2075
0
{
2076
0
    proto_tree *ieee802154_tree = NULL;
2077
0
    proto_item *proto_root      = NULL;
2078
2079
0
    unsigned    offset          = 0;
2080
0
    uint8_t     phr;
2081
0
    tvbuff_t*   mac;
2082
2083
    /* Create the protocol tree. */
2084
0
    if (tree) {
2085
0
        proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154_nonask_phy, tvb, 0, tvb_captured_length(tvb), "IEEE 802.15.4 non-ASK PHY");
2086
0
        ieee802154_tree = proto_item_add_subtree(proto_root, ett_ieee802154_nonask_phy);
2087
0
    }
2088
2089
    /* Add the protocol name. */
2090
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4 non-ASK PHY");
2091
2092
0
    phr = tvb_get_uint8(tvb,offset+4+1);
2093
2094
0
    if (tree) {
2095
0
        unsigned loffset = offset;
2096
0
        static int * const phr_fields[] = {
2097
0
                    &hf_ieee802154_nonask_phy_length,
2098
0
                    NULL
2099
0
                };
2100
2101
0
        proto_tree_add_item(ieee802154_tree, hf_ieee802154_nonask_phy_preamble, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
2102
0
        loffset +=4 ;
2103
0
        proto_tree_add_item(ieee802154_tree, hf_ieee802154_nonask_phy_sfd, tvb, loffset, 1, ENC_LITTLE_ENDIAN);
2104
0
        loffset +=1 ;
2105
2106
0
        proto_tree_add_bitmask(ieee802154_tree, tvb, loffset, hf_ieee802154_nonask_phr, ett_ieee802154_nonask_phy_phr,
2107
0
            phr_fields, ENC_NA);
2108
0
    }
2109
2110
0
    offset += 4+2*1;
2111
0
    mac = tvb_new_subset_length(tvb,offset, phr & IEEE802154_PHY_LENGTH_MASK);
2112
2113
    /* These always have the FCS at the end. */
2114
2115
    /*
2116
     * Call the common dissector; FCS length is 2, and no flags.
2117
     */
2118
0
    dissect_ieee802154_common(mac, pinfo, ieee802154_tree, 2, 0);
2119
0
    return tvb_captured_length(tvb);
2120
0
} /* dissect_ieee802154_nonask_phy */
2121
2122
/* Return the length in octets for the user configured
2123
 * FCS/metadata following the PHY Payload */
2124
static unsigned
2125
ieee802154_fcs_type_len(unsigned i)
2126
402
{
2127
402
    unsigned fcs_type_lengths[] = { 2, 2, 4 };
2128
402
    if (i < array_length(fcs_type_lengths)) {
2129
402
        return fcs_type_lengths[i];
2130
402
    }
2131
0
    return 0;
2132
402
}
2133
2134
/**
2135
 * Dissector for IEEE 802.15.4 packet with an FCS containing a 16/32-bit
2136
 * CRC value, or TI CC24xx metadata, at the end, as specified by the
2137
 * user preference.
2138
 *
2139
 * @param tvb pointer to buffer containing raw packet.
2140
 * @param pinfo pointer to packet information fields.
2141
 * @param tree pointer to data tree wireshark uses to display packet.
2142
 * @param data unused
2143
 */
2144
static int
2145
dissect_ieee802154(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2146
402
{
2147
402
    tvbuff_t *new_tvb = dissect_zboss_specific(tvb, pinfo, tree);
2148
402
    unsigned options = 0;
2149
402
    unsigned fcs_len;
2150
402
    int fcs_type;
2151
2152
402
    fcs_type = ieee802154_fcs_type;
2153
2154
    /* Set the default FCS length based on the FCS type in the configuration */
2155
402
    fcs_len = ieee802154_fcs_type_len(fcs_type);
2156
2157
402
    if (fcs_type == IEEE802154_CC24XX_METADATA) {
2158
0
        options = DISSECT_IEEE802154_OPTION_CC24xx;
2159
0
    }
2160
2161
402
    if (new_tvb != tvb) {
2162
        /* ZBOSS traffic dump: always TI metadata trailer, always ZigBee */
2163
0
        options = DISSECT_IEEE802154_OPTION_CC24xx|DISSECT_IEEE802154_OPTION_ZBOSS;
2164
0
        fcs_len = 2;
2165
0
    }
2166
2167
    /* Call the common dissector. */
2168
402
    dissect_ieee802154_common(new_tvb, pinfo, tree, fcs_len, options);
2169
402
    return tvb_captured_length(tvb);
2170
402
} /* dissect_ieee802154 */
2171
2172
/**
2173
 * Dissector for IEEE 802.15.4 packet with an FCS containing a 16/32-bit
2174
 * CRC value, or TI CC24xx metadata, at the end, as specified by the
2175
 * data parameter.
2176
 *
2177
 * @param tvb pointer to buffer containing raw packet.
2178
 * @param pinfo pointer to packet information fields.
2179
 * @param tree pointer to data tree wireshark uses to display packet.
2180
 * @param data int pointer to fcs type to override user config.
2181
 */
2182
static int
2183
dissect_ieee802154_fcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2184
0
{
2185
0
    tvbuff_t *new_tvb = dissect_zboss_specific(tvb, pinfo, tree);
2186
0
    unsigned options = 0;
2187
0
    unsigned fcs_len;
2188
0
    int fcs_type;
2189
2190
0
    DISSECTOR_ASSERT(data != NULL);
2191
0
    fcs_type = *(int *)data;
2192
2193
    /* Set the default FCS length based on the FCS type in the configuration */
2194
0
    fcs_len = ieee802154_fcs_type_len(fcs_type);
2195
2196
0
    if (fcs_type == IEEE802154_CC24XX_METADATA) {
2197
0
        options = DISSECT_IEEE802154_OPTION_CC24xx;
2198
0
    }
2199
2200
0
    if (new_tvb != tvb) {
2201
        /* ZBOSS traffic dump: always TI metadata trailer, always ZigBee */
2202
0
        options = DISSECT_IEEE802154_OPTION_CC24xx|DISSECT_IEEE802154_OPTION_ZBOSS;
2203
0
        fcs_len = 2;
2204
0
    }
2205
2206
    /* Call the common dissector. */
2207
0
    dissect_ieee802154_common(new_tvb, pinfo, tree, fcs_len, options);
2208
0
    return tvb_captured_length(tvb);
2209
0
} /* dissect_ieee802154_fcs */
2210
2211
/**
2212
 * Dissector for IEEE 802.15.4 packet with no FCS present.
2213
 *
2214
 * @param tvb pointer to buffer containing raw packet.
2215
 * @param pinfo pointer to packet information fields
2216
 * @param tree pointer to data tree wireshark uses to display packet.
2217
 * @return captured length.
2218
 */
2219
static int
2220
dissect_ieee802154_nofcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_)
2221
7.22k
{
2222
    /*
2223
     * Call the common dissector; FCS length is 0, and no flags.
2224
     */
2225
7.22k
    dissect_ieee802154_common(tvb, pinfo, tree, 0, 0);
2226
7.22k
    return tvb_captured_length(tvb);
2227
7.22k
} /* dissect_ieee802154_nofcs */
2228
2229
/**
2230
 * Dissector for IEEE 802.15.4 packet dump produced by ZBOSS
2231
 *
2232
 * @param tvb pointer to buffer containing raw packet.
2233
 * @param pinfo pointer to packet information fields
2234
 * @param tree pointer to data tree wireshark uses to display packet.
2235
 * @return new tvb subset if this is really ZBOSS dump, else original tvb.
2236
 */
2237
static tvbuff_t *
2238
dissect_zboss_specific(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
2239
402
{
2240
402
    proto_tree *zboss_tree;
2241
402
    proto_item *proto_root;
2242
402
    unsigned off = 0;
2243
402
    uint32_t direction_byte, page_byte, channel;
2244
2245
402
    if (tvb_captured_length(tvb) > 5)
2246
364
    {
2247
364
        if (tvb_get_uint8(tvb, off++) == 'Z'
2248
0
            && tvb_get_uint8(tvb, off++) == 'B'
2249
0
            && tvb_get_uint8(tvb, off++) == 'O'
2250
0
            && tvb_get_uint8(tvb, off++) == 'S'
2251
0
            && tvb_get_uint8(tvb, off++) == 'S')
2252
0
        {
2253
            /* Create the protocol tree. */
2254
0
            proto_root = proto_tree_add_protocol_format(tree, proto_zboss, tvb, 0, tvb_captured_length(tvb), "ZBOSS dump");
2255
0
            zboss_tree = proto_item_add_subtree(proto_root, ett_ieee802154_zboss);
2256
2257
0
            proto_tree_add_item_ret_uint(zboss_tree, hf_zboss_direction, tvb, off, 1, ENC_NA, &direction_byte);
2258
0
            proto_item_append_text(proto_root, ", %s", direction_byte ? "OUT" : "IN");
2259
2260
0
            proto_tree_add_item_ret_uint(zboss_tree, hf_zboss_page, tvb, off, 1, ENC_NA, &page_byte);
2261
0
            proto_item_append_text(proto_root, ", page %u", page_byte);
2262
0
            off++;
2263
2264
0
            proto_tree_add_item_ret_uint(zboss_tree, hf_zboss_channel, tvb, off, 1, ENC_NA, &channel);
2265
0
            proto_item_append_text(proto_root, ", channel %u", channel);
2266
0
            off++;
2267
2268
0
            proto_tree_add_item(zboss_tree, hf_zboss_trace_number, tvb, off, 4, ENC_LITTLE_ENDIAN);
2269
0
            off += 4;
2270
2271
0
            return tvb_new_subset_remaining(tvb, off);
2272
0
        }
2273
364
    }
2274
402
    return tvb;
2275
402
} /* dissect_zboss_specific */
2276
2277
/**
2278
 * Dissector for IEEE 802.15.4 packet with 2 bytes of ChipCon/Texas
2279
 * Instruments compatible metadata at the end of the frame, and no FCS.
2280
 * This is typically called by layers encapsulating an IEEE 802.15.4 packet.
2281
 *
2282
 * @param tvb pointer to buffer containing raw packet.
2283
 * @param pinfo pointer to packet information fields
2284
 * @param tree pointer to data tree wireshark uses to display packet.
2285
 */
2286
static int
2287
dissect_ieee802154_cc24xx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_)
2288
0
{
2289
    /*
2290
     * Call the common dissector.
2291
     * 2 bytes of metadata at the end of the packet data.
2292
     */
2293
0
    dissect_ieee802154_common(tvb, pinfo, tree, 2, DISSECT_IEEE802154_OPTION_CC24xx);
2294
0
    return tvb_captured_length(tvb);
2295
0
} /* dissect_ieee802154_cc24xx */
2296
2297
/**
2298
 * Dissector for IEEE 802.15.4 TAP packet
2299
 *
2300
 * Contains optional TLVs and encapsulates an IEEE 802.15.4 packet.
2301
 *
2302
 * @param tvb pointer to buffer containing raw packet.
2303
 * @param pinfo pointer to packet information fields
2304
 * @param tree pointer to data tree wireshark uses to display packet.
2305
 */
2306
static int
2307
dissect_ieee802154_tap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_)
2308
1
{
2309
1
    proto_tree *info_tree = NULL;
2310
1
    proto_tree *header_tree = NULL;
2311
1
    proto_item *proto_root = NULL;
2312
1
    proto_item *ti = NULL;
2313
1
    uint32_t    version = 0;
2314
1
    uint32_t    length = 0;
2315
1
    uint32_t    data_length = 0;
2316
1
    tvbuff_t*   tlv_tvb;
2317
1
    tvbuff_t*   payload_tvb;
2318
1
    ieee802154_fcs_type_t tap_fcs_type;
2319
1
    unsigned    fcs_len;
2320
2321
    /* Check the version in the TAP header */
2322
1
    version = tvb_get_uint8(tvb, 0);
2323
1
    if (version != 0) {
2324
        /* Malformed packet. We do not understand any other version at this time */
2325
1
        return 0;
2326
1
    }
2327
2328
    /* Get the total length of the header and TLVs */
2329
0
    length = tvb_get_letohs(tvb, 2);
2330
2331
0
    if (length > tvb_captured_length(tvb)) {
2332
        /* Malformed packet. The TLVs exceeds our captured packet. */
2333
0
        return 0;
2334
0
    }
2335
2336
    /* Create the protocol tree */
2337
0
    proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154_tap, tvb, 0, length, "IEEE 802.15.4 TAP");
2338
0
    info_tree = proto_item_add_subtree(proto_root, ett_ieee802154_tap);
2339
2340
0
    header_tree = proto_tree_add_subtree(info_tree, tvb, 0, 4, ett_ieee802154_tap_header, &proto_root, "Header");
2341
0
    proto_tree_add_item(header_tree, hf_ieee802154_tap_version, tvb, 0, 1, ENC_LITTLE_ENDIAN);
2342
0
    proto_tree_add_item(header_tree, hf_ieee802154_tap_reserved, tvb, 1, 1, ENC_LITTLE_ENDIAN);
2343
0
    proto_tree_add_item(header_tree, hf_ieee802154_tap_length, tvb, 2, 2, ENC_LITTLE_ENDIAN);
2344
2345
    /* Add the protocol name. */
2346
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4 TAP");
2347
2348
    /* Create a new tvb subset with only the TLVs to dissect */
2349
0
    tlv_tvb = tvb_new_subset_length(tvb, 4, length - 4);
2350
0
    tap_fcs_type = dissect_ieee802154_tap_tlvs(tlv_tvb, pinfo, info_tree);
2351
2352
    /* Set the FCS length based on the FCS type */
2353
0
    switch (tap_fcs_type) {
2354
2355
0
    case IEEE802154_FCS_TYPE_NONE:
2356
0
        fcs_len = 0;
2357
0
        break;
2358
2359
0
    case IEEE802154_FCS_TYPE_16_BIT:
2360
0
        fcs_len = 2;
2361
0
        break;
2362
2363
0
    case IEEE802154_FCS_TYPE_32_BIT:
2364
0
        fcs_len = 4;
2365
0
        break;
2366
2367
0
    default:
2368
        /* Not valid */
2369
0
        return tvb_captured_length(tvb);
2370
0
    }
2371
2372
    /* Report the remaining bytes as the IEEE 802.15.4 Data Length */
2373
0
    data_length = tvb_reported_length_remaining(tvb, length);
2374
0
    ti = proto_tree_add_uint(info_tree, hf_ieee802154_tap_data_length, NULL, 0, 0, data_length);
2375
0
    proto_item_set_generated(ti);
2376
2377
0
    if (data_length > 0) {
2378
        /*
2379
         * Call the common dissector with the real 802.15.4 data which follows the TLV header.
2380
         * Create a separate packet bytes pane for the real data.
2381
         * Specified FCS length, no flags.
2382
         */
2383
0
        payload_tvb = tvb_new_child_real_data(tvb, tvb_get_ptr(tvb, length, data_length), data_length, data_length);
2384
0
        add_new_data_source(pinfo, payload_tvb, "IEEE 802.15.4 Data");
2385
0
        dissect_ieee802154_common(payload_tvb, pinfo, tree, fcs_len, 0);
2386
0
    }
2387
0
    else {
2388
0
        expert_add_info(pinfo, ti, &ei_ieee802154_tap_no_payload);
2389
0
    }
2390
2391
0
    return tvb_captured_length(tvb);
2392
0
} /* dissect_ieee802154_tap */
2393
2394
/**
2395
 * IEEE 802.15.4 packet dissection routine for Wireshark.
2396
 *
2397
 * This function extracts all the information first before displaying.
2398
 * If payload exists, that portion will be passed into another dissector
2399
 * for further processing.
2400
 *
2401
 * This is called after the individual dissect_ieee802154* functions
2402
 * have been called to determine what sort of FCS is present, if any.
2403
 *
2404
 * @param tvb pointer to buffer containing raw packet.
2405
 * @param pinfo pointer to packet information fields
2406
 * @param tree pointer to data tree Wireshark uses to display packet.
2407
 * @param options bitwise or of dissector options (see DISSECT_IEEE802154_OPTION_xxx).
2408
 */
2409
static void
2410
dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned fcs_len, unsigned options)
2411
7.62k
{
2412
7.62k
    proto_tree *ieee802154_tree;
2413
7.62k
    ieee802154_packet *packet;
2414
7.62k
    bool fcs_present;
2415
7.62k
    bool fcs_ok;
2416
7.62k
    tvbuff_t* no_fcs_tvb;
2417
2418
7.62k
    if (fcs_len != 0) {
2419
        /*
2420
         * Well, this packet should, in theory, have an FCS or CC24xx
2421
         * metadata.
2422
         * Do we have the entire packet, and does it have enough data for
2423
         * the FCS/metadata?
2424
         */
2425
402
        unsigned reported_len = tvb_reported_length(tvb);
2426
2427
402
        if (reported_len < fcs_len) {
2428
            /*
2429
             * The packet is claimed not to even have enough data
2430
             * for the FCS/metadata.  Pretend it doesn't have one.
2431
             */
2432
6
            no_fcs_tvb = tvb;
2433
6
            fcs_present = false;
2434
6
            fcs_ok = true;  // assume OK if not present
2435
396
        } else {
2436
            /*
2437
             * The packet is claimed to have enough data for the
2438
             * FCS/metadata.
2439
             * Slice it off from the reported length.
2440
             */
2441
396
            reported_len -= fcs_len;
2442
396
            no_fcs_tvb = tvb_new_subset_length(tvb, 0, reported_len);
2443
2444
            /*
2445
             * Is the FCS/metadata present in the captured data?
2446
             * reported_len is now the length of the packet without the
2447
             * FCS/metadata, so the FCS/metadata begins at an offset of
2448
             * reported_len.
2449
             */
2450
396
            if (tvb_bytes_exist(tvb, reported_len, fcs_len)) {
2451
                /*
2452
                 * Yes.  Check whether the FCS was OK.
2453
                 *
2454
                 * If we have an FCS, check it.
2455
                 * If we have metadata, check its "FCS OK" flag.
2456
                 */
2457
396
                fcs_present = true;
2458
396
                fcs_ok = options & DISSECT_IEEE802154_OPTION_CC24xx ? is_cc24xx_crc_ok(tvb) : is_fcs_ok(tvb, fcs_len);
2459
396
            } else {
2460
                /*
2461
                 * No.
2462
                 *
2463
                 * Either 1) this means that there was a snapshot length
2464
                 * in effect when the capture was done, and that sliced
2465
                 * some or all of the FCS/metadata off or 2) this is a
2466
                 * capture with no FCS/metadata, using the same link-layer
2467
                 * header type value as captures with the FCS/metadata,
2468
                 * and indicating the lack of the FCS/metadata by having
2469
                 * the captured length be the length of the packet minus
2470
                 * the length of the FCS/metadata and the actual length
2471
                 * being the length of the packet including the FCS/metadata,
2472
                 * rather than by using the "no FCS" link-layer header type.
2473
                 *
2474
                 * We could try to distinguish between them by checking
2475
                 * for a captured length that's exactly fcs_len bytes
2476
                 * less than the actual length.  That would allow us to
2477
                 * report packets that are cut short just before, or in
2478
                 * the middle of, the FCS as having been cut short by the
2479
                 * snapshot length.
2480
                 *
2481
                 * However, we can't distinguish between a packet that
2482
                 * happened to be cut fcs_len bytes short due to a
2483
                 * snapshot length being in effect when the capture was
2484
                 * done and a packet that *wasn't* cut short by a snapshot
2485
                 * length but that doesn't include the FCS/metadata.
2486
                 * Let's hope that rarely happens.
2487
                 */
2488
0
                fcs_present = false;
2489
0
                fcs_ok = true;  // assume OK if not present
2490
0
            }
2491
396
        }
2492
7.22k
    } else {
2493
7.22k
        no_fcs_tvb = tvb;
2494
7.22k
        fcs_present = false;
2495
7.22k
        fcs_ok = true;  // assume OK if not present
2496
7.22k
    }
2497
2498
7.62k
    unsigned mhr_len = ieee802154_dissect_header(no_fcs_tvb, pinfo, tree, 0, &ieee802154_tree, &packet);
2499
7.62k
    if (!mhr_len) {
2500
25
        return;
2501
25
    }
2502
2503
7.60k
    if ((packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE)) {
2504
4.53k
        _find_or_create_conversation(pinfo, &pinfo->dl_src, &pinfo->dl_dst);
2505
4.53k
    }
2506
2507
7.60k
    if (ieee802154_ack_tracking && (packet->ack_request || packet->frame_type == IEEE802154_FCF_ACK)) {
2508
0
        uint32_t key[2] = {0};
2509
2510
0
        key[0] = packet->seqno;
2511
0
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
2512
0
            key[1] = pinfo->rec->rec_header.packet_header.interface_id;
2513
0
        }
2514
2515
0
        if (packet->ack_request) {
2516
0
            transaction_start(pinfo, ieee802154_tree, packet, key);
2517
0
        }
2518
0
        else {
2519
0
            transaction_end(pinfo, ieee802154_tree, packet, key);
2520
0
        }
2521
0
    }
2522
2523
7.60k
    tvbuff_t* payload = ieee802154_decrypt_payload(no_fcs_tvb, mhr_len, pinfo, ieee802154_tree, packet);
2524
7.60k
    if (payload) {
2525
7.31k
        unsigned pie_size = ieee802154_dissect_payload_ies(payload, pinfo, ieee802154_tree, packet);
2526
7.31k
        payload = tvb_new_subset_remaining(payload, pie_size);
2527
7.31k
        if (options & DISSECT_IEEE802154_OPTION_ZBOSS && packet->frame_type == IEEE802154_FCF_DATA) {
2528
0
            if ((!fcs_ok && ieee802154_fcs_ok) || !tvb_reported_length(payload)) {
2529
0
                call_data_dissector(payload, pinfo, tree);
2530
0
            } else {
2531
0
                call_dissector_with_data(zigbee_nwk_handle, payload, pinfo, tree, packet);
2532
0
            }
2533
7.31k
        } else {
2534
7.31k
            ieee802154_dissect_frame_payload(payload, pinfo, ieee802154_tree, packet, fcs_ok);
2535
7.31k
        }
2536
7.31k
    }
2537
2538
7.60k
    if (fcs_present) {
2539
143
        if (options & DISSECT_IEEE802154_OPTION_CC24xx)
2540
0
            ieee802154_dissect_cc24xx_metadata(tvb, ieee802154_tree, fcs_ok);
2541
143
        else
2542
143
            ieee802154_dissect_fcs(tvb, ieee802154_tree, fcs_len, fcs_ok);
2543
2544
        /* If the CRC is invalid, make a note of it in the info column. */
2545
143
        if (!fcs_ok) {
2546
141
            col_append_str(pinfo->cinfo, COL_INFO, ", Bad FCS");
2547
141
            proto_item_append_text(proto_tree_get_parent(ieee802154_tree), ", Bad FCS");
2548
2549
            /* Flag packet as having a bad crc. */
2550
141
            expert_add_info(pinfo, proto_tree_get_parent(ieee802154_tree), &ei_ieee802154_fcs);
2551
141
        }
2552
7.45k
    } else {
2553
7.45k
        if (ieee802154_tree) {
2554
            /* Even if the FCS isn't present, add the fcs_ok field to the tree to
2555
             * help with filter. Be sure not to make it visible though.
2556
             */
2557
6.92k
            proto_item *ti = proto_tree_add_boolean_format_value(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, 0, 0, fcs_ok, "Unknown");
2558
6.92k
            proto_item_set_hidden(ti);
2559
6.92k
        }
2560
7.45k
    }
2561
2562
7.60k
    tap_queue_packet(ieee802154_tap, pinfo, NULL);
2563
7.60k
}
2564
2565
unsigned
2566
ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned options, proto_tree **created_header_tree, ieee802154_packet **parsed_info)
2567
7.62k
{
2568
7.62k
    proto_tree              *ieee802154_tree = NULL;
2569
7.62k
    proto_item              *proto_root = NULL;
2570
7.62k
    proto_item              *hidden_item;
2571
7.62k
    proto_item              *ti;
2572
7.62k
    unsigned                offset = 0;
2573
7.62k
    ieee802154_packet      *packet = wmem_new0(pinfo->pool, ieee802154_packet);
2574
7.62k
    ieee802154_short_addr   addr16;
2575
7.62k
    ieee802154_hints_t     *ieee_hints;
2576
2577
7.62k
    packet->short_table = ieee802154_map.short_table;
2578
2579
    /* Allocate frame data with hints for upper layers */
2580
7.62k
    if (!PINFO_FD_VISITED(pinfo) ||
2581
7.62k
        (ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0)) == NULL) {
2582
7.62k
        ieee_hints = wmem_new0(wmem_file_scope(), ieee802154_hints_t);
2583
7.62k
        p_add_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0, ieee_hints);
2584
7.62k
    }
2585
2586
    /* Save a pointer to the whole packet */
2587
7.62k
    ieee_hints->packet = packet;
2588
2589
    /* Create the protocol tree. */
2590
7.62k
    proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154, tvb, 0, tvb_captured_length(tvb), "IEEE 802.15.4");
2591
7.62k
    ieee802154_tree = proto_item_add_subtree(proto_root, ett_ieee802154);
2592
    /* Add the protocol name. */
2593
7.62k
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4");
2594
2595
    /* Set out parameters */
2596
7.62k
    *created_header_tree = ieee802154_tree;
2597
7.62k
    *parsed_info = packet;
2598
2599
    /* Add the packet length to the filter field */
2600
7.62k
    hidden_item = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_frame_length, NULL, 0, 0, tvb_reported_length(tvb));
2601
7.62k
    proto_item_set_hidden(hidden_item);
2602
2603
    /* Frame Control Field */
2604
7.62k
    dissect_ieee802154_fcf(tvb, pinfo, ieee802154_tree, packet, &offset);
2605
2606
    /* Sequence Number */
2607
7.62k
    if (packet->seqno_suppression) {
2608
6.11k
        if (packet->version != IEEE802154_VERSION_2015 && packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) {
2609
5.38k
            expert_add_info(pinfo, proto_root, &ei_ieee802154_seqno_suppression);
2610
5.38k
        }
2611
6.11k
    } else { /* IEEE 802.15.4 Sequence Number Suppression */
2612
1.51k
        packet->seqno = tvb_get_uint8(tvb, offset);
2613
1.51k
        proto_tree_add_uint(ieee802154_tree, hf_ieee802154_seqno, tvb, offset, 1, packet->seqno);
2614
        /* For Ack packets display this in the root. */
2615
1.51k
        if (packet->frame_type == IEEE802154_FCF_ACK) {
2616
9
            proto_item_append_text(proto_root, ", Sequence Number: %u", packet->seqno);
2617
9
        }
2618
1.51k
        offset += 1;
2619
1.51k
    }
2620
2621
    /*
2622
     * ADDRESSING FIELDS
2623
     */
2624
    /* Clear out the addressing strings. */
2625
7.62k
    clear_address(&pinfo->net_dst);
2626
7.62k
    clear_address(&pinfo->dl_dst);
2627
7.62k
    clear_address(&pinfo->dst);
2628
7.62k
    clear_address(&pinfo->net_src);
2629
7.62k
    clear_address(&pinfo->dl_src);
2630
7.62k
    clear_address(&pinfo->src);
2631
2632
7.62k
    if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_RESERVED) {
2633
        /* Invalid Destination Address Mode. Abort Dissection. */
2634
4
        expert_add_info(pinfo, proto_root, &ei_ieee802154_dst);
2635
4
        return 0;
2636
4
    }
2637
2638
7.62k
    if (packet->src_addr_mode == IEEE802154_FCF_ADDR_RESERVED) {
2639
        /* Invalid Source Address Mode. Abort Dissection. */
2640
6
        expert_add_info(pinfo, proto_root, &ei_ieee802154_src);
2641
6
        return 0;
2642
6
    }
2643
2644
7.61k
    if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) {
2645
        /* Multipurpose frames have a different set of frame versions, with 0 as the only valid version */
2646
39
        if (packet->version != 0) {
2647
            /* Unknown Frame Version for Multipurpose frames. Abort Dissection */
2648
2
            expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver);
2649
2
            return 0;
2650
2
        }
2651
2652
        /* The source PAN ID is always omitted in multipurpose frames */
2653
37
        packet->src_pan_present = false;
2654
2655
37
        if (packet->pan_id_present) {
2656
31
            packet->dst_pan_present = true;
2657
31
        }
2658
37
    }
2659
7.57k
    else if (packet->version == IEEE802154_VERSION_RESERVED) {
2660
        /* Unknown Frame Version. Abort Dissection. */
2661
4
        expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver);
2662
4
        return 0;
2663
4
    }
2664
7.57k
    else if ((packet->version == IEEE802154_VERSION_2003) ||  /* For Frame Version 0b00 and */
2665
6.68k
             (packet->version == IEEE802154_VERSION_2006))  { /* 0b01 effect defined in section 7.2.1.5 */
2666
2667
6.68k
        if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* if both destination and source */
2668
4.83k
            (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) { /* addressing information is present */
2669
4.33k
            if (packet->pan_id_compression == 1) { /* PAN IDs are identical */
2670
9
                packet->dst_pan_present = true;
2671
9
                packet->src_pan_present = false; /* source PAN ID is omitted */
2672
9
            }
2673
4.32k
            else { /* PAN IDs are different, both shall be included in the frame */
2674
4.32k
                packet->dst_pan_present = true;
2675
4.32k
                packet->src_pan_present = true;
2676
4.32k
            }
2677
4.33k
        }
2678
2.35k
        else {
2679
2.35k
            if (packet->pan_id_compression == 1) { /* all remaining cases pan_id_compression must be zero */
2680
9
                expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_panid_compression);
2681
9
                return 0;
2682
9
            }
2683
2.34k
            else {
2684
                /* only either the destination or the source addressing information is present */
2685
2.34k
                if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) &&        /*   Present   */
2686
496
                    (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) {        /* Not Present */
2687
496
                    packet->dst_pan_present = true;
2688
496
                    packet->src_pan_present = false;
2689
496
                }
2690
1.84k
                else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&   /* Not Present */
2691
1.84k
                         (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) {   /*   Present   */
2692
1.60k
                    packet->dst_pan_present = false;
2693
1.60k
                    packet->src_pan_present = true;
2694
1.60k
                }
2695
247
                else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&   /* Not Present */
2696
247
                         (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) {   /* Not Present */
2697
247
                    packet->dst_pan_present = false;
2698
247
                    packet->src_pan_present = false;
2699
247
                }
2700
0
                else {
2701
0
                    expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_addressing);
2702
0
                    return 0;
2703
0
                }
2704
2.34k
            }
2705
2.35k
        }
2706
6.68k
    }
2707
885
    else if (packet->version == IEEE802154_VERSION_2015) {
2708
        /* for Frame Version 0b10 PAN Id Compression only applies to these frame types */
2709
873
        if ((packet->frame_type == IEEE802154_FCF_BEACON) ||
2710
672
            (packet->frame_type == IEEE802154_FCF_DATA)   ||
2711
78
            (packet->frame_type == IEEE802154_FCF_ACK)    ||
2712
830
            (packet->frame_type == IEEE802154_FCF_CMD)       ) {
2713
2714
            /* Implements Table 7-6 of IEEE 802.15.4-2015
2715
             *
2716
             *      Destination Address  Source Address  Destination PAN ID  Source PAN ID   PAN ID Compression
2717
             *-------------------------------------------------------------------------------------------------
2718
             *  1.  Not Present          Not Present     Not Present         Not Present     0
2719
             *  2.  Not Present          Not Present     Present             Not Present     1
2720
             *  3.  Present              Not Present     Present             Not Present     0
2721
             *  4.  Present              Not Present     Not Present         Not Present     1
2722
             *
2723
             *  5.  Not Present          Present         Not Present         Present         0
2724
             *  6.  Not Present          Present         Not Present         Not Present     1
2725
             *
2726
             *  7.  Extended             Extended        Present             Not Present     0
2727
             *  8.  Extended             Extended        Not Present         Not Present     1
2728
             *
2729
             *  9.  Short                Short           Present             Present         0
2730
             * 10.  Short                Extended        Present             Present         0
2731
             * 11.  Extended             Short           Present             Present         0
2732
             *
2733
             * 12.  Short                Extended        Present             Not Present     1
2734
             * 13.  Extended             Short           Present             Not Present     1
2735
             * 14.  Short                Short           Present             Not Present     1
2736
             */
2737
2738
            /* Row 1 */
2739
830
            if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&      /* Not Present */
2740
117
                (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) &&      /* Not Present */
2741
90
                (packet->pan_id_compression == 0)) {
2742
84
                        packet->dst_pan_present = false;
2743
84
                        packet->src_pan_present = false;
2744
84
            }
2745
            /* Row 2 */
2746
746
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
2747
33
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
2748
6
                     (packet->pan_id_compression == 1)) {
2749
6
                        packet->dst_pan_present = true;
2750
6
                        packet->src_pan_present = false;
2751
6
            }
2752
            /* Row 3 */
2753
740
            else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
2754
713
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
2755
460
                     (packet->pan_id_compression == 0)) {
2756
453
                        packet->dst_pan_present = true;
2757
453
                        packet->src_pan_present = false;
2758
453
            }
2759
            /* Row 4 */
2760
287
            else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
2761
260
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
2762
7
                     (packet->pan_id_compression == 1)) {
2763
7
                        packet->dst_pan_present = false;
2764
7
                        packet->src_pan_present = false;
2765
7
            }
2766
            /* Row 5 */
2767
280
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
2768
27
                     (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
2769
27
                     (packet->pan_id_compression == 0)) {
2770
24
                        packet->dst_pan_present = false;
2771
24
                        packet->src_pan_present = true;
2772
24
            }
2773
            /* Row 6 */
2774
256
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
2775
3
                     (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
2776
3
                     (packet->pan_id_compression == 1)) {
2777
3
                        packet->dst_pan_present = false;
2778
3
                        packet->src_pan_present = false;
2779
3
            }
2780
            /* Row 7 */
2781
253
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
2782
181
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
2783
22
                     (packet->pan_id_compression == 0)) {
2784
17
                        packet->dst_pan_present = true;
2785
17
                        packet->src_pan_present = false;
2786
17
            }
2787
            /* Row 8 */
2788
236
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
2789
164
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
2790
5
                     (packet->pan_id_compression == 1)) {
2791
5
                        packet->dst_pan_present = false;
2792
5
                        packet->src_pan_present = false;
2793
5
            }
2794
            /* Row 9 */
2795
231
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /*  Short     */
2796
72
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /*  Short     */
2797
60
                     (packet->pan_id_compression == 0)) {
2798
58
                        packet->dst_pan_present = true;
2799
58
                        packet->src_pan_present = (ieee802154e_compatibility ? false : true);
2800
58
            }
2801
            /* Row 10 */
2802
173
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /*  Short    */
2803
14
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&   /*  Extended */
2804
12
                     (packet->pan_id_compression == 0)) {
2805
9
                        packet->dst_pan_present = true;
2806
9
                        packet->src_pan_present = (ieee802154e_compatibility ? false : true);
2807
9
            }
2808
            /* Row 11 */
2809
164
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)   &&   /*  Extended */
2810
159
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
2811
159
                     (packet->pan_id_compression == 0)) {
2812
157
                        packet->dst_pan_present = true;
2813
157
                        packet->src_pan_present = (ieee802154e_compatibility ? false : true);
2814
157
            }
2815
            /* Row 12 */
2816
7
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
2817
5
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT)   &&   /*  Extended */
2818
3
                     (packet->pan_id_compression == 1)) {
2819
3
                        packet->dst_pan_present = true;
2820
3
                        packet->src_pan_present = false;
2821
3
            }
2822
            /* Row 13 */
2823
4
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)   &&   /*  Extended */
2824
2
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
2825
2
                     (packet->pan_id_compression == 1)) {
2826
2
                        packet->dst_pan_present = true;
2827
2
                        packet->src_pan_present = false;
2828
2
            }
2829
            /* Row 14 */
2830
2
            else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
2831
2
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
2832
2
                     (packet->pan_id_compression == 1)) {
2833
2
                        packet->dst_pan_present = true;
2834
2
                        packet->src_pan_present = false;
2835
2
            }
2836
0
            else {
2837
0
                expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_panid_compression2);
2838
0
                return 0;
2839
0
            }
2840
830
        }
2841
43
        else { /* Frame Type is neither Beacon, Data, Ack, nor Command: PAN ID Compression is not used */
2842
43
            packet->dst_pan_present = false; /* no PAN ID will */
2843
43
            packet->src_pan_present = false; /* be present     */
2844
43
        }
2845
873
    }
2846
12
    else {
2847
        /* Unknown Frame Version. Abort Dissection. */
2848
12
        expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver);
2849
12
        return 0;
2850
12
    }
2851
2852
    /*
2853
     * Addressing Fields
2854
     */
2855
2856
    /* Destination PAN Id */
2857
7.58k
    if (packet->dst_pan_present) {
2858
5.56k
        packet->dst_pan = tvb_get_letohs(tvb, offset);
2859
5.56k
        proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_panID, tvb, offset, 2, packet->dst_pan);
2860
5.56k
        offset += 2;
2861
5.56k
    }
2862
2863
    /* Destination Address  */
2864
7.58k
    if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
2865
        /* Get the address. */
2866
4.43k
        packet->dst16 = tvb_get_letohs(tvb, offset);
2867
2868
        /* Provide address hints to higher layers that need it. */
2869
4.43k
        ieee_hints->dst16 = packet->dst16;
2870
2871
4.43k
        set_address_tvb(&pinfo->dl_dst, ieee802_15_4_short_address_type, 2, tvb, offset);
2872
4.43k
        copy_address_shallow(&pinfo->dst, &pinfo->dl_dst);
2873
2874
4.43k
        proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst16, tvb, offset, 2, packet->dst16);
2875
4.43k
        ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_addr16, tvb, offset, 2, packet->dst16);
2876
4.43k
        proto_item_set_generated(ti);
2877
4.43k
        proto_item_set_hidden(ti);
2878
2879
4.43k
        offset += 2;
2880
4.43k
    }
2881
3.15k
    else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
2882
1.14k
        uint64_t *p_addr = (uint64_t *)wmem_new(pinfo->pool, uint64_t);
2883
2884
        /* Get the address */
2885
1.14k
        packet->dst64 = tvb_get_letoh64(tvb, offset);
2886
2887
        /* Copy and convert the address to network byte order. */
2888
1.14k
        *p_addr = pntohu64(&(packet->dst64));
2889
2890
        /* Display the destination address. */
2891
        /* XXX - OUI resolution doesn't happen when displaying resolved
2892
         * EUI64 addresses; that should probably be fixed in
2893
         * epan/addr_resolv.c.
2894
         */
2895
1.14k
        set_address(&pinfo->dl_dst, AT_EUI64, 8, p_addr);
2896
1.14k
        copy_address_shallow(&pinfo->dst, &pinfo->dl_dst);
2897
1.14k
        proto_tree_add_item(ieee802154_tree, hf_ieee802154_dst64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2898
1.14k
        ti = proto_tree_add_item(ieee802154_tree, hf_ieee802154_addr64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2899
1.14k
        proto_item_set_generated(ti);
2900
1.14k
        proto_item_set_hidden(ti);
2901
2902
1.14k
        offset += 8;
2903
1.14k
    }
2904
2905
    /* Source PAN Id */
2906
7.58k
    if (packet->src_pan_present) {
2907
6.16k
        packet->src_pan = tvb_get_letohs(tvb, offset);
2908
6.16k
        proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src_panID, tvb, offset, 2, packet->src_pan);
2909
6.16k
        offset += 2;
2910
6.16k
    }
2911
1.42k
    else {
2912
1.42k
        if (packet->dst_pan_present) {
2913
986
            packet->src_pan = packet->dst_pan;
2914
986
        }
2915
438
        else {
2916
438
            packet->src_pan = IEEE802154_BCAST_PAN;
2917
438
        }
2918
1.42k
    }
2919
7.58k
    ieee_hints->src_pan = packet->src_pan;
2920
2921
    /* Source Address */
2922
7.58k
    if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
2923
        /* Get the address. */
2924
5.63k
        packet->src16 = tvb_get_letohs(tvb, offset);
2925
2926
5.63k
        if (!PINFO_FD_VISITED(pinfo)) {
2927
            /* If we know our extended source address from previous packets,
2928
                * provide a pointer to it in a hint for upper layers */
2929
5.63k
            addr16.addr = packet->src16;
2930
5.63k
            addr16.pan = packet->src_pan;
2931
2932
5.63k
            ieee_hints->src16 = packet->src16;
2933
5.63k
            ieee_hints->map_rec = (ieee802154_map_rec *)
2934
5.63k
                g_hash_table_lookup(ieee802154_map.short_table, &addr16);
2935
5.63k
        }
2936
2937
5.63k
        set_address_tvb(&pinfo->dl_src, ieee802_15_4_short_address_type, 2, tvb, offset);
2938
5.63k
        copy_address_shallow(&pinfo->src, &pinfo->dl_src);
2939
2940
        /* Add the addressing info to the tree. */
2941
5.63k
        proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src16, tvb, offset, 2, packet->src16);
2942
5.63k
        ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_addr16, tvb, offset, 2, packet->src16);
2943
5.63k
        proto_item_set_generated(ti);
2944
5.63k
        proto_item_set_hidden(ti);
2945
2946
5.63k
        if (ieee_hints->map_rec) {
2947
            /* Display inferred source address info */
2948
0
            ti = proto_tree_add_eui64(ieee802154_tree, hf_ieee802154_src64, tvb, offset, 0,
2949
0
                    ieee_hints->map_rec->addr64);
2950
0
            proto_item_set_generated(ti);
2951
0
            ti = proto_tree_add_eui64(ieee802154_tree, hf_ieee802154_addr64, tvb, offset, 0, ieee_hints->map_rec->addr64);
2952
0
            proto_item_set_generated(ti);
2953
0
            proto_item_set_hidden(ti);
2954
2955
0
            if ( ieee_hints->map_rec->start_fnum ) {
2956
0
                ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src64_origin, tvb, 0, 0,
2957
0
                    ieee_hints->map_rec->start_fnum);
2958
0
            }
2959
0
            else {
2960
0
                ti = proto_tree_add_uint_format_value(ieee802154_tree, hf_ieee802154_src64_origin, tvb, 0, 0,
2961
0
                    ieee_hints->map_rec->start_fnum, "Pre-configured");
2962
0
            }
2963
0
            proto_item_set_generated(ti);
2964
0
        }
2965
2966
5.63k
        offset += 2;
2967
5.63k
    }
2968
1.94k
    else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
2969
574
        uint64_t *p_addr = (uint64_t *)wmem_new(pinfo->pool, uint64_t);
2970
2971
        /* Get the address. */
2972
574
        packet->src64 = tvb_get_letoh64(tvb, offset);
2973
2974
        /* Copy and convert the address to network byte order. */
2975
574
        *p_addr = pntohu64(&(packet->src64));
2976
2977
        /* Display the source address. */
2978
        /* XXX - OUI resolution doesn't happen when displaying resolved
2979
         * EUI64 addresses; that should probably be fixed in
2980
         * epan/addr_resolv.c.
2981
         */
2982
574
        set_address(&pinfo->dl_src, AT_EUI64, 8, p_addr);
2983
574
        copy_address_shallow(&pinfo->src, &pinfo->dl_src);
2984
574
        proto_tree_add_item(ieee802154_tree, hf_ieee802154_src64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2985
574
        ti = proto_tree_add_item(ieee802154_tree, hf_ieee802154_addr64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2986
574
        proto_item_set_generated(ti);
2987
574
        proto_item_set_hidden(ti);
2988
2989
574
        offset += 8;
2990
574
    }
2991
2992
    /* Add the addressing info to the root of the tree. */
2993
7.58k
    if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
2994
5.63k
        proto_item_append_text(proto_root, ", Src: %s", address_to_str(pinfo->pool, &pinfo->src));
2995
5.63k
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", address_to_str(pinfo->pool, &pinfo->src));
2996
5.63k
    }
2997
1.95k
    else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
2998
573
        proto_item_append_text(proto_root, ", Src: %s", eui64_to_display(pinfo->pool, packet->src64));
2999
573
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", eui64_to_display(pinfo->pool, packet->src64));
3000
573
    }
3001
3002
7.58k
    if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
3003
4.43k
        proto_item_append_text(proto_root, ", Dst: %s", address_to_str(pinfo->pool, &pinfo->dst));
3004
4.43k
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", address_to_str(pinfo->pool, &pinfo->dst));
3005
4.43k
    }
3006
3.15k
    else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
3007
1.13k
        proto_item_append_text(proto_root, ", Dst: %s", eui64_to_display(pinfo->pool, packet->dst64));
3008
1.13k
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", eui64_to_display(pinfo->pool, packet->dst64));
3009
1.13k
    }
3010
3011
    /* Existence of the Auxiliary Security Header is controlled by the Security Enabled Field */
3012
7.58k
    if (packet->security_enable &&
3013
55
        ((packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) || (packet->version != IEEE802154_VERSION_2003)) &&
3014
47
        !(options & IEEE802154_DISSECT_HEADER_OPTION_NO_AUX_SEC_HDR))
3015
47
    {
3016
47
        dissect_ieee802154_aux_sec_header_and_key(tvb, pinfo, ieee802154_tree, packet, &offset);
3017
47
    }
3018
3019
    /*
3020
     * NONPAYLOAD FIELDS
3021
     *
3022
     */
3023
    /* All of the beacon fields, except the beacon payload are considered nonpayload. */
3024
7.58k
    if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && ((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006))) {
3025
6.63k
        if (tvb_reported_length(tvb) > offset) {
3026
6.62k
            if (packet->frame_type == IEEE802154_FCF_BEACON) { /* Regular Beacon. Some are not present in frame version (Enhanced) Beacons */
3027
226
                dissect_ieee802154_superframe(tvb, pinfo, ieee802154_tree, &offset); /* superframe spec */
3028
226
                dissect_ieee802154_gtsinfo(tvb, pinfo, ieee802154_tree, &offset);    /* GTS information fields */
3029
226
                dissect_ieee802154_pendaddr(tvb, pinfo, ieee802154_tree, &offset);   /* Pending address list */
3030
226
            }
3031
6.62k
        }
3032
3033
6.63k
        if (packet->frame_type == IEEE802154_FCF_CMD) {
3034
            /**
3035
             * In IEEE802.15.4-2003 and 2006 the command identifier is considered to be part of the header
3036
             * and is thus not encrypted. For IEEE802.15.4-2012e and later the command id is considered to be
3037
             * part of the payload, is encrypted, and follows the payload IEs. Thus we only parse the command id
3038
             * here for 2006 and earlier frames. */
3039
34
            packet->command_id = tvb_get_uint8(tvb, offset);
3040
34
            proto_tree_add_uint(ieee802154_tree, hf_ieee802154_cmd_id, tvb, offset, 1, packet->command_id);
3041
34
            offset++;
3042
3043
            /* Display the command identifier in the info column. */
3044
34
            col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
3045
34
        }
3046
6.63k
    }
3047
950
    else {
3048
950
        if (packet->ie_present) {
3049
415
            offset += dissect_ieee802154_header_ie(tvb, pinfo, ieee802154_tree, offset, packet);
3050
415
        }
3051
950
    }
3052
3053
    /* IEEE 802.15.4-2003 may have security information pre-pended to payload */
3054
7.58k
    if (packet->security_enable && (packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003))
3055
8
    {
3056
        /* Store security suite preference in the 2006 security level identifier to simplify 2003 integration! */
3057
8
        packet->security_level = (ieee802154_security_level)ieee802154_sec_suite;
3058
3059
        /* Frame Counter and Key Sequence Counter prepended to the payload of an encrypted frame */
3060
8
        if (IEEE802154_IS_ENCRYPTED(packet->security_level)) {
3061
8
            packet->frame_counter = tvb_get_letohl (tvb, offset);
3062
8
            proto_tree_add_uint(ieee802154_tree, hf_ieee802154_sec_frame_counter, tvb, offset, (int)sizeof(uint32_t), packet->frame_counter);
3063
8
            offset += (int)sizeof(uint32_t);
3064
3065
8
            packet->key_sequence_counter = tvb_get_uint8 (tvb, offset);
3066
8
            proto_tree_add_uint(ieee802154_tree, hf_ieee802154_sec_key_sequence_counter, tvb, offset, (int)sizeof(uint8_t), packet->key_sequence_counter);
3067
8
            offset += (int)sizeof(uint8_t);
3068
8
        }
3069
8
    }
3070
3071
7.58k
    return offset;
3072
7.61k
}
3073
3074
/*
3075
 * XXX - "mhr_len" is really a general offset; this is used elsewhere.
3076
 */
3077
tvbuff_t*
3078
ieee802154_decrypt_payload(tvbuff_t *tvb, unsigned mhr_len, packet_info *pinfo, proto_tree *ieee802154_tree, ieee802154_packet *packet)
3079
7.40k
{
3080
7.40k
    proto_item *proto_root = proto_tree_get_parent(ieee802154_tree);
3081
7.40k
    proto_tree *tree = proto_tree_get_parent_tree(ieee802154_tree);
3082
7.40k
    unsigned char rx_mic[IEEE802154_CIPHER_SIZE];
3083
7.40k
    unsigned rx_mic_len = IEEE802154_MIC_LENGTH(packet->security_level);
3084
7.40k
    ieee802154_decrypt_status status = DECRYPT_NOT_ENCRYPTED;
3085
7.40k
    tvbuff_t *payload_tvb;
3086
3087
7.40k
    unsigned id2 = proto_get_id_by_short_name("TREL");
3088
7.40k
    wmem_list_frame_t* ptr2 = wmem_list_find(pinfo->layers, GUINT_TO_POINTER(id2));
3089
3090
    /* Encrypted Payload. */
3091
7.40k
    if (packet->security_enable || ptr2) {
3092
35
        ieee802154_decrypt_info_t decrypt_info;
3093
3094
35
        decrypt_info.rx_mic = rx_mic;
3095
35
        decrypt_info.rx_mic_length = &rx_mic_len;
3096
35
        decrypt_info.status = &status;
3097
3098
35
        if (ptr2)  // if this pointer is not null that mean we found trel
3099
0
            payload_tvb = decrypt_ieee802154_payload(tvb, mhr_len, pinfo, NULL, packet, &decrypt_info,
3100
0
                ieee802154_set_trel_key, dissect_ieee802154_decrypt);
3101
35
        else
3102
            // call with NULL tree since we add the key_number below without hiding it
3103
35
            payload_tvb = decrypt_ieee802154_payload(tvb, mhr_len, pinfo, NULL, packet, &decrypt_info,
3104
35
                ieee802154_set_mac_key, dissect_ieee802154_decrypt);
3105
3106
        /* Get the unencrypted data if decryption failed.  */
3107
35
        if (!payload_tvb) {
3108
            /* Deal with possible truncation and the MIC field at the end. */
3109
35
            int reported_len = tvb_reported_length(tvb)-mhr_len-rx_mic_len;
3110
35
            payload_tvb = tvb_new_subset_length(tvb, mhr_len, reported_len);
3111
35
        }
3112
3113
        /* Display the MIC. */
3114
35
        if (rx_mic_len) {
3115
12
            if (tvb_bytes_exist(tvb, tvb_reported_length(tvb) - rx_mic_len, rx_mic_len)) {
3116
9
                proto_tree_add_item(ieee802154_tree, hf_ieee802154_mic, tvb, tvb_reported_length(tvb)-rx_mic_len, rx_mic_len, ENC_NA);
3117
9
            }
3118
12
        }
3119
3120
        /* Display the reason for failure, and abort if the error was fatal. */
3121
35
        switch (status) {
3122
0
        case DECRYPT_PACKET_SUCCEEDED:
3123
0
        {
3124
0
            proto_item *pi = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_key_number, tvb, 0, 0, decrypt_info.key_number);
3125
0
            proto_item_set_generated(pi);
3126
0
            break;
3127
0
        }
3128
0
        case DECRYPT_NOT_ENCRYPTED:
3129
0
            break;  // nothing to do
3130
3131
0
        case DECRYPT_FRAME_COUNTER_SUPPRESSION_UNSUPPORTED:
3132
0
            expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Decryption of 802.15.4-2015 with frame counter suppression is not supported");
3133
0
            call_data_dissector(payload_tvb, pinfo, tree);
3134
0
            return NULL;
3135
3136
0
        case DECRYPT_PACKET_TOO_SMALL:
3137
0
            expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Packet was too small to include the CRC and MIC");
3138
0
            call_data_dissector(payload_tvb, pinfo, tree);
3139
0
            return NULL;
3140
3141
0
        case DECRYPT_PACKET_NO_EXT_SRC_ADDR:
3142
0
            expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "No extended source address - can't decrypt");
3143
0
            call_data_dissector(payload_tvb, pinfo, tree);
3144
0
            return NULL;
3145
3146
26
        case DECRYPT_PACKET_NO_KEY:
3147
26
            expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "No encryption key set - can't decrypt");
3148
26
            call_data_dissector(payload_tvb, pinfo, tree);
3149
26
            return NULL;
3150
3151
0
        case DECRYPT_PACKET_DECRYPT_FAILED:
3152
0
            expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Decrypt failed");
3153
0
            call_data_dissector(payload_tvb, pinfo, tree);
3154
0
            return NULL;
3155
3156
0
        case DECRYPT_PACKET_MIC_CHECK_FAILED:
3157
0
            expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "MIC check failed");
3158
            /*
3159
             * Abort only if the payload was encrypted, in which case we
3160
             * probably didn't decrypt the packet right (eg: wrong key).
3161
             */
3162
0
            if (IEEE802154_IS_ENCRYPTED(packet->security_level)) {
3163
0
                call_data_dissector(payload_tvb, pinfo, tree);
3164
0
                return NULL;
3165
0
            }
3166
0
            break;
3167
35
        }
3168
35
    }
3169
    /* Plaintext Payload. */
3170
7.36k
    else {
3171
        /* Deal with possible truncation. */
3172
7.36k
        int reported_len = tvb_reported_length(tvb)-mhr_len;
3173
7.36k
        payload_tvb = tvb_new_subset_length(tvb, mhr_len, reported_len);
3174
7.36k
    }
3175
3176
7.36k
    return payload_tvb;
3177
7.40k
}
3178
3179
3180
unsigned ieee802154_dissect_payload_ies(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ieee802154_tree, ieee802154_packet *packet)
3181
7.31k
{
3182
    /* Presence of Payload IEs is defined by the termination of the Header IEs */
3183
7.31k
    if (packet->payload_ie_present) {
3184
277
        if (tvb_reported_length(tvb) > 2) {
3185
275
            return (unsigned) dissect_ieee802154_payload_ie(tvb, pinfo, ieee802154_tree, 0, packet);
3186
275
        } else {
3187
2
            expert_add_info(pinfo, proto_tree_get_parent(ieee802154_tree), &ei_ieee802154_missing_payload_ie);
3188
2
        }
3189
277
    }
3190
7.03k
    return 0;
3191
7.31k
}
3192
3193
3194
unsigned ieee802154_dissect_frame_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ieee802154_tree, ieee802154_packet *packet, bool fcs_ok)
3195
7.04k
{
3196
7.04k
    tvbuff_t *payload_tvb = tvb;
3197
7.04k
    proto_tree *tree = proto_tree_get_parent_tree(ieee802154_tree);
3198
7.04k
    heur_dtbl_entry_t *hdtbl_entry;
3199
3200
    /* There are commands without payload */
3201
7.04k
    if (tvb_captured_length(payload_tvb) > 0 || packet->frame_type == IEEE802154_FCF_CMD) {
3202
        /*
3203
         * Wrap the sub-dissection in a try/catch block in case the payload is
3204
         * broken. First we store the current protocol so we can fix it if an
3205
         * exception is thrown by the subdissectors.
3206
         */
3207
7.02k
        const char* saved_proto = pinfo->current_proto;
3208
        /* Try to dissect the payload. */
3209
7.02k
        TRY {
3210
7.02k
            switch (packet->frame_type) {
3211
170
            case IEEE802154_FCF_BEACON:
3212
170
                if (!dissector_try_heuristic(ieee802154_beacon_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) {
3213
153
                    unsigned offset;
3214
153
                    offset = dissect_zbee_tlvs(payload_tvb, pinfo, tree, 0, NULL, ZBEE_TLV_SRC_TYPE_DEFAULT, 0);
3215
153
                    if (tvb_captured_length_remaining(payload_tvb, offset) > 0)
3216
30
                    {
3217
30
                      tvbuff_t *payload_tvb_remaining;
3218
30
                      payload_tvb_remaining = tvb_new_subset_remaining(payload_tvb, offset);
3219
                      /* Could not subdissect, call the data dissector instead. */
3220
30
                      call_data_dissector(payload_tvb_remaining, pinfo, tree);
3221
30
                    }
3222
153
                }
3223
170
                break;
3224
3225
43
            case IEEE802154_FCF_CMD:
3226
43
                dissect_ieee802154_command(payload_tvb, pinfo, ieee802154_tree, packet);
3227
43
                break;
3228
3229
6.80k
            case IEEE802154_FCF_DATA:
3230
                /* Sanity-check. */
3231
6.80k
                if ((!fcs_ok && ieee802154_fcs_ok) || !tvb_reported_length(payload_tvb)) {
3232
16
                    call_data_dissector(payload_tvb, pinfo, tree);
3233
16
                    break;
3234
16
                }
3235
                /* Try the PANID dissector table for stateful dissection. */
3236
6.78k
                if (dissector_try_uint_with_data(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, true, packet)) {
3237
0
                    break;
3238
0
                }
3239
                /* Try again with the destination PANID (if different) */
3240
6.78k
                if (((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) ||
3241
2.51k
                     (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) &&
3242
5.08k
                        (packet->dst_pan != packet->src_pan) &&
3243
4.21k
                        dissector_try_uint_with_data(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, true, packet)) {
3244
0
                    break;
3245
0
                }
3246
                /* Try heuristic dissection. */
3247
6.78k
                if (dissector_try_heuristic(ieee802154_heur_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) break;
3248
                /* Fall-through to dump undissectable payloads. */
3249
                /* FALL THROUGH */
3250
3.38k
            default:
3251
                /* Could not subdissect, call the data dissector instead. */
3252
3.38k
                call_data_dissector(payload_tvb, pinfo, tree);
3253
7.02k
            } /* switch */
3254
7.02k
        }
3255
3.59k
        CATCH_ALL {
3256
            /*
3257
             * Someone encountered an error while dissecting the payload. But
3258
             * we haven't yet finished processing all of our layer. Catch and
3259
             * display the exception, then fall-through to finish displaying
3260
             * the FCS (which we display last so the frame is ordered correctly
3261
             * in the tree).
3262
             */
3263
3.42k
            show_exception(payload_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
3264
3.42k
            pinfo->current_proto = saved_proto;
3265
3.42k
        }
3266
3.59k
        ENDTRY;
3267
3.59k
    }
3268
3.61k
    return tvb_captured_length(tvb);
3269
7.04k
}
3270
3271
/**
3272
 * Dissect the FCS at the end of the frame.
3273
 * That is only displayed if the included length of the tvb encompasses it.
3274
 *
3275
 * @param tvb the 802.15.4 frame tvb
3276
 * @param ieee802154_tree the 802.15.4 protocol tree
3277
 * @param fcs_len length of the FCS field
3278
 * @param fcs_ok set to false to indicate FCS verification failed
3279
 */
3280
static void
3281
ieee802154_dissect_fcs(tvbuff_t *tvb, proto_tree *ieee802154_tree, unsigned fcs_len, bool fcs_ok)
3282
143
{
3283
143
    proto_item *ti;
3284
    /* The FCS should be the last bytes of the reported packet. */
3285
143
    unsigned offset = tvb_reported_length(tvb)-fcs_len;
3286
    /* Dissect the FCS only if it exists (captures which don't or can't get the
3287
     * FCS will simply truncate the packet to omit it, but should still set the
3288
     * reported length to cover the original packet length), so if the snapshot
3289
     * is too short for an FCS don't make a fuss.
3290
     */
3291
143
    if (ieee802154_tree) {
3292
143
        if (fcs_len == 2) {
3293
143
            uint16_t    fcs = tvb_get_letohs(tvb, offset);
3294
3295
143
            ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_fcs, tvb, offset, 2, fcs);
3296
143
            if (fcs_ok) {
3297
2
                proto_item_append_text(ti, " (Correct)");
3298
2
            }
3299
141
            else {
3300
141
                proto_item_append_text(ti, " (Incorrect, expected FCS=0x%04x)", ieee802154_crc_tvb(tvb, offset));
3301
141
            }
3302
            /* To Help with filtering, add the fcs_ok field to the tree.  */
3303
143
            ti = proto_tree_add_boolean(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, offset, 2, (uint64_t) fcs_ok);
3304
143
            proto_item_set_hidden(ti);
3305
143
        }
3306
0
        else {
3307
0
            uint32_t fcs = tvb_get_letohl(tvb, offset);
3308
3309
0
            ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_fcs32, tvb, offset, 4, fcs);
3310
0
            if (fcs_ok) {
3311
0
                proto_item_append_text(ti, " (Correct)");
3312
0
            }
3313
0
            else {
3314
0
                proto_item_append_text(ti, " (Incorrect, expected FCS=0x%08x)", ieee802154_crc32_tvb(tvb, offset));
3315
0
            }
3316
            /* To Help with filtering, add the fcs_ok field to the tree.  */
3317
0
            ti = proto_tree_add_boolean(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, offset, 2, (uint64_t) fcs_ok);
3318
0
            proto_item_set_hidden(ti);
3319
0
        }
3320
143
    }
3321
143
} /* ieee802154_dissect_fcs */
3322
3323
/**
3324
 * Dissect the TI CC24xx metadata at the end of the frame.
3325
 * That is only displayed if the included length of the tvb encompasses it.
3326
 *
3327
 * @param tvb the 802.15.4 frame tvb
3328
 * @param ieee802154_tree the 802.15.4 protocol tree
3329
 * @param fcs_ok set to false to indicate FCS verification failed
3330
 */
3331
static void
3332
ieee802154_dissect_cc24xx_metadata(tvbuff_t *tvb, proto_tree *ieee802154_tree, bool fcs_ok)
3333
0
{
3334
    /* The metadata should be the last 2 bytes of the reported packet. */
3335
0
    unsigned offset = tvb_reported_length(tvb)-2;
3336
    /* Dissect the metadata only if it exists (captures which don't or can't get the
3337
     * metadata will simply truncate the packet to omit it, but should still set the
3338
     * reported length to cover the original packet length), so if the snapshot
3339
     * is too short for the metadata don't make a fuss.
3340
     */
3341
0
    if (ieee802154_tree) {
3342
0
        proto_tree  *field_tree;
3343
0
        uint16_t    metadata = tvb_get_letohs(tvb, offset);
3344
3345
        /* Create a subtree for the metadata. */
3346
0
        field_tree = proto_tree_add_subtree_format(ieee802154_tree, tvb, offset, 2, ett_ieee802154_fcs, NULL,
3347
0
                     "TI CC24xx-format metadata: FCS %s", (fcs_ok) ? "OK" : "Bad");
3348
        /* Display metadata contents.  */
3349
0
        proto_tree_add_boolean(field_tree, hf_ieee802154_fcs_ok, tvb, offset, 1, (uint64_t) (metadata & IEEE802154_CC24xx_CRC_OK));
3350
0
        proto_tree_add_int(field_tree, hf_ieee802154_rssi, tvb, offset++, 1, (int8_t) (metadata & IEEE802154_CC24xx_RSSI));
3351
0
        proto_tree_add_uint(field_tree, hf_ieee802154_correlation, tvb, offset, 1, (uint8_t) ((metadata & IEEE802154_CC24xx_CORRELATION) >> 8));
3352
0
    }
3353
0
} /* ieee802154_dissect_cc24xx_metadata */
3354
3355
static void
3356
dissect_ieee802154_tap_sun_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, unsigned length)
3357
0
{
3358
0
    (void) pinfo;
3359
0
    if (length == 3) {
3360
0
        uint32_t band;
3361
0
        uint32_t sun_type;
3362
0
        uint32_t mode;
3363
0
        proto_tree_add_item_ret_uint(tree, hf_ieee802154_sun_band, tvb, offset, 1, ENC_LITTLE_ENDIAN, &band);
3364
0
        proto_item_append_text(proto_tree_get_parent(tree), ": Band: %s (%u)", val_to_str_const(band, sun_bands, "Unknown"), band);
3365
0
        proto_tree_add_item_ret_uint(tree, hf_ieee802154_sun_type, tvb, offset+1, 1, ENC_LITTLE_ENDIAN, &sun_type);
3366
0
        if (sun_type < array_length(sun_types)) {
3367
0
            proto_item_append_text(proto_tree_get_parent(tree), ", Type: %s (%u)", val_to_str_const(sun_type, sun_types, "Unknown"), sun_type);
3368
0
        }
3369
3370
0
        switch (sun_type) {
3371
0
            case IEEE802154_SUN_TYPE_FSK_A:
3372
0
                proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_fsk_a, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode);
3373
0
                proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode);
3374
0
                break;
3375
0
            case IEEE802154_SUN_TYPE_FSK_B:
3376
0
                proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_fsk_b, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode);
3377
0
                proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode);
3378
0
                break;
3379
0
            case IEEE802154_SUN_TYPE_OQPSK_A:
3380
0
                proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_oqpsk_a, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode);
3381
0
                proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode);
3382
0
                break;
3383
0
            case IEEE802154_SUN_TYPE_OQPSK_B:
3384
0
                proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_oqpsk_b, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode);
3385
0
                proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode);
3386
0
                break;
3387
0
            case IEEE802154_SUN_TYPE_OQPSK_C:
3388
0
                proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_oqpsk_c, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode);
3389
0
                proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode);
3390
0
                break;
3391
0
            case IEEE802154_SUN_TYPE_OFDM_OPT1:
3392
0
            case IEEE802154_SUN_TYPE_OFDM_OPT2:
3393
0
            case IEEE802154_SUN_TYPE_OFDM_OPT3:
3394
0
            case IEEE802154_SUN_TYPE_OFDM_OPT4:
3395
0
                proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_ofdm, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode);
3396
0
                proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode);
3397
0
                break;
3398
0
            default:
3399
0
                proto_tree_add_item(tree, hf_ieee802154_sun_mode, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
3400
0
                break;
3401
0
        } /* switch (sun_type) */
3402
0
    }
3403
0
} /* dissect_ieee802154_tap_sun_phy */
3404
3405
static void
3406
dissect_ieee802154_tap_phy_header(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset, unsigned length)
3407
0
{
3408
0
    uint32_t phr_type;
3409
0
    uint32_t phr_bits;
3410
3411
0
    proto_tree_add_item_ret_uint(tree, hf_ieee802154_tap_phr_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, &phr_type);
3412
0
    proto_tree_add_item_ret_uint(tree, hf_ieee802154_tap_phr_bits, tvb, offset+2, 2, ENC_LITTLE_ENDIAN, &phr_bits);
3413
3414
0
    switch (phr_type) {
3415
0
        case PHR_WISUN_FSK_MS: {
3416
0
            uint32_t phr_data = tvb_get_letohs(tvb, offset+4);
3417
0
            if (phr_data & IEEE802154_TAP_PHR_FSK_MS) {
3418
0
                static int* const ieee802154_tap_phr_fsk_wisun_ms_fields[] = {
3419
0
                    &hf_ieee802154_tap_phr_fsk_ms,
3420
0
                    &hf_ieee802154_tap_phr_wisun_fsk_ms_reserved,
3421
0
                    &hf_ieee802154_tap_phr_wisun_fsk_ms_phymodeid,
3422
0
                    &hf_ieee802154_tap_phr_fsk_ms_checksum,
3423
0
                    &hf_ieee802154_tap_phr_fsk_ms_parity,
3424
0
                    NULL
3425
0
                };
3426
0
                proto_item *pi = proto_tree_add_bitmask_with_flags(tree, tvb, offset+4, hf_ieee802154_tap_wisun_ms_phr,
3427
0
                        ett_ieee802154_tap_phr, ieee802154_tap_phr_fsk_wisun_ms_fields, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
3428
0
                if (phr_data & IEEE802154_TAP_PHR_WISUN_FSK_MS_RESERVED) {
3429
0
                    expert_add_info(NULL, pi, &ei_ieee802154_tap_tlv_reserved_not_zero);
3430
0
                }
3431
                /* TODO: expert info BCH(15,11) checksum check */
3432
                /* TODO: expert info parity check */
3433
0
            }
3434
0
            break;
3435
0
        }
3436
0
        case PHR_SUN_FSK: {
3437
0
            uint32_t phr_data = tvb_get_letohs(tvb, offset+4);
3438
0
            if (phr_data & IEEE802154_TAP_PHR_FSK_MS) {
3439
0
                int *const *fields;
3440
0
                if ((phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_FSK) {
3441
                    /* SUN FSK */
3442
0
                    static int* const ieee802154_tap_phr_fsk_ms_fields[] = {
3443
0
                        &hf_ieee802154_tap_phr_fsk_ms,
3444
0
                        &hf_ieee802154_tap_phr_fsk_ms_param,
3445
0
                        &hf_ieee802154_tap_phr_fsk_ms_fec,
3446
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_page,
3447
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_scheme,
3448
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_mode,
3449
0
                        &hf_ieee802154_tap_phr_fsk_ms_checksum,
3450
0
                        &hf_ieee802154_tap_phr_fsk_ms_parity,
3451
0
                        NULL
3452
0
                    };
3453
0
                    fields = ieee802154_tap_phr_fsk_ms_fields;
3454
0
                }
3455
0
                else if ((phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_OFDM ||
3456
0
                    (phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_OQPSK) {
3457
                    /* SUN OFDM or SUN O-QPSK */
3458
0
                    static int* const ieee802154_tap_phr_fsk_ms_ofdm_fields[] = {
3459
0
                        &hf_ieee802154_tap_phr_fsk_ms,
3460
0
                        &hf_ieee802154_tap_phr_fsk_ms_param,
3461
0
                        &hf_ieee802154_tap_phr_fsk_ms_fec,
3462
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_page,
3463
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_scheme,
3464
0
                        &hf_ieee802154_tap_phr_fsk_ms_checksum,
3465
0
                        &hf_ieee802154_tap_phr_fsk_ms_parity,
3466
0
                        NULL
3467
0
                    };
3468
0
                    fields = ieee802154_tap_phr_fsk_ms_ofdm_fields;
3469
0
                }
3470
0
                else /* if ((phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_ADDL) */ {
3471
                    /* Additional Modes */
3472
0
                    static int* const ieee802154_tap_phr_fsk_ms_addl_fields[] = {
3473
0
                        &hf_ieee802154_tap_phr_fsk_ms,
3474
0
                        &hf_ieee802154_tap_phr_fsk_ms_param,
3475
0
                        &hf_ieee802154_tap_phr_fsk_ms_fec,
3476
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_page,
3477
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_scheme,
3478
0
                        &hf_ieee802154_tap_phr_fsk_ms_mode_addl_mode,
3479
0
                        &hf_ieee802154_tap_phr_fsk_ms_checksum,
3480
0
                        &hf_ieee802154_tap_phr_fsk_ms_parity,
3481
0
                        NULL
3482
0
                    };
3483
0
                    fields = ieee802154_tap_phr_fsk_ms_addl_fields;
3484
0
                }
3485
0
                proto_tree_add_bitmask_with_flags(tree, tvb, offset+4, hf_ieee802154_tap_fsk_ms_phr,
3486
0
                        ett_ieee802154_tap_phr, fields, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
3487
                /* TODO: expert info BCH(15,11) checksum check */
3488
                /* TODO: expert info parity check */
3489
0
            }
3490
0
            else {
3491
0
                static int* const ieee802154_tap_phr_fsk_fields[] = {
3492
0
                    &hf_ieee802154_tap_phr_fsk_ms,
3493
0
                    &hf_ieee802154_tap_phr_fsk_fcs,
3494
0
                    &hf_ieee802154_tap_phr_fsk_dw,
3495
0
                    &hf_ieee802154_tap_phr_fsk_length,
3496
0
                    NULL
3497
0
                };
3498
0
                proto_tree_add_bitmask_with_flags(tree, tvb, offset+4, hf_ieee802154_tap_phr_fsk,
3499
0
                    ett_ieee802154_tap_phr, ieee802154_tap_phr_fsk_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
3500
0
            }
3501
0
            break;
3502
0
        }
3503
3504
0
        case PHR_O_QPSK:
3505
0
        case PHR_CSS:
3506
0
        case PHR_HRP_UWB:
3507
0
        case PHR_MSK:
3508
0
        case PHR_LRP_UWB:
3509
0
        case PHR_SUN_OFDM:
3510
0
        case PHR_SUN_O_QPSK:
3511
0
        case PHR_LECIM_FSK:
3512
0
        case PHR_TVWS_FSK:
3513
0
        case PHR_TVWS_OFDM:
3514
0
        case PHR_TVWS_NB_OFDM:
3515
0
        case PHR_RCC_LMR:
3516
0
        case PHR_CMB_O_QPSK:
3517
0
        case PHR_CMB_GFSK:
3518
0
        case PHR_TASK:
3519
0
        case PHR_RS_GFSK:
3520
            /* TODO: write specific dissectors for these PHR types */
3521
            /* fall-through with RAW dissection */
3522
0
        case PHR_RAW:
3523
0
        default: {
3524
0
            proto_tree_add_item(tree, hf_ieee802154_tap_phr_data, tvb, offset+4, length-4, ENC_NA);
3525
0
            break;
3526
0
        }
3527
0
    }
3528
0
}
3529
3530
/**
3531
 * Create a tree for a TAP TLV
3532
 *
3533
 * @param tree the tree to append this item to
3534
 * @param tvb the tv buffer
3535
 * @param offset offset into the tvbuff to begin dissection
3536
 * @param type TLV type
3537
 * @param length TLV length
3538
 * @returns the tree created for the Payload IE
3539
 */
3540
static proto_tree*
3541
ieee802154_create_tap_tlv_tree(proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t *type, uint32_t *length)
3542
0
{
3543
0
    proto_tree *subtree = NULL;
3544
0
    proto_item *ti = NULL;
3545
0
    uint32_t subtree_length;
3546
3547
0
    *length = tvb_get_letohs(tvb, offset+2);
3548
3549
0
    subtree_length = 4 + *length;
3550
0
    subtree_length += WS_PADDING_TO_4(*length);
3551
3552
0
    subtree = proto_tree_add_subtree(tree, tvb, offset, subtree_length, ett_ieee802154_tap_tlv, &ti, "");
3553
3554
    /* Check if we have a valid TLV */
3555
0
    proto_tree_add_item_ret_uint(subtree, hf_ieee802154_tap_tlv_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, type);
3556
0
    if (*type < array_length(tap_tlv_types)) {
3557
0
        proto_item_append_text(ti, "%s", val_to_str_const(*type, tap_tlv_types, "Unknown"));
3558
0
    }
3559
0
    else {
3560
0
        expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_invalid_type);
3561
0
    }
3562
3563
0
    proto_tree_add_item(subtree, hf_ieee802154_tap_tlv_length, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
3564
0
    if (!tvb_bytes_exist(tvb, offset+4, *length)) {
3565
0
        expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_invalid_length);
3566
0
    }
3567
0
    return subtree;
3568
0
} /* ieee802154_create_tap_tlv_tree */
3569
3570
static ieee802154_fcs_type_t
3571
dissect_ieee802154_tap_tlvs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3572
0
{
3573
0
    uint32_t type;
3574
0
    uint32_t length;
3575
0
    unsigned offset = 0;
3576
0
    proto_item *ti;
3577
0
    proto_tree *tlvtree;
3578
0
    uint32_t tap_fcs_type;
3579
0
    const char *type_str;
3580
0
    nstime_t nstime;
3581
0
    uint64_t frame_start_ts = 0;
3582
0
    uint64_t frame_end_ts = 0;
3583
0
    uint64_t slot_start_ts = 0;
3584
0
    double delta_us = 0;
3585
0
    uint32_t timeslot_length = 0;
3586
3587
    /* Default the FCS type to NONE when parsing TAP packets */
3588
0
    tap_fcs_type = IEEE802154_FCS_TYPE_NONE;
3589
3590
0
    while (tvb_bytes_exist(tvb, offset, 4)) {
3591
0
        tlvtree = ieee802154_create_tap_tlv_tree(tree, tvb, offset, &type, &length);
3592
0
        offset += 4;
3593
3594
0
        switch (type) {
3595
0
            case IEEE802154_TAP_FCS_TYPE:
3596
0
                ti = proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_tap_fcs_type, tvb, offset, 1,
3597
0
                                                  ENC_LITTLE_ENDIAN, &tap_fcs_type);
3598
0
                type_str = try_val_to_str(tap_fcs_type, tap_fcs_type_names);
3599
0
                if (type_str == NULL) {
3600
                    /* Invalid - flag it as such */
3601
0
                    expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_invalid_fcs_type);
3602
3603
                    /* Use "Unknown" for the parent */
3604
0
                    type_str = "Unknown";
3605
0
                }
3606
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s (%u)",
3607
0
                                       type_str, tap_fcs_type);
3608
0
                break;
3609
0
            case IEEE802154_TAP_RSS: {
3610
0
                float rss = tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN);
3611
0
                proto_tree_add_float_format_value(tlvtree, hf_ieee802154_tap_rss, tvb, offset, 4, rss, "%.2f dBm", rss);
3612
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %.2f dBm", rss);
3613
0
                break;
3614
0
            }
3615
0
            case IEEE802154_TAP_BIT_RATE: {
3616
0
                uint32_t bitrate;
3617
0
                proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_bit_rate, tvb, offset, 4, ENC_LITTLE_ENDIAN, &bitrate);
3618
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %.3f kbps", bitrate/1000.0);
3619
0
                break;
3620
0
            }
3621
0
            case IEEE802154_TAP_CHANNEL_ASSIGNMENT: {
3622
0
                uint32_t channel;
3623
0
                uint32_t page;
3624
0
                proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_ch_num, tvb, offset, 2, ENC_LITTLE_ENDIAN, &channel);
3625
0
                proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_ch_page, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &page);
3626
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": Page: %s (%u), Number: %u", val_to_str_const(page, channel_page_names, "Unknown"), page, channel);
3627
0
                break;
3628
0
            }
3629
0
            case IEEE802154_TAP_SUN_PHY_INFO:
3630
0
                dissect_ieee802154_tap_sun_phy(tvb, pinfo, tlvtree, offset, length);
3631
0
                break;
3632
0
            case IEEE802154_TAP_START_OF_FRAME_TS:
3633
0
                proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_sof_ts, tvb, offset, 8,
3634
0
                                               ENC_LITTLE_ENDIAN, &frame_start_ts);
3635
0
                nstime.secs = (time_t)frame_start_ts / 1000000000L;
3636
0
                nstime.nsecs = frame_start_ts % 1000000000UL;
3637
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s s", rel_time_to_secs_str(pinfo->pool, &nstime));
3638
0
                break;
3639
0
            case IEEE802154_TAP_END_OF_FRAME_TS:
3640
0
                proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_eof_ts, tvb, offset, 8,
3641
0
                                    ENC_LITTLE_ENDIAN, &frame_end_ts);
3642
0
                nstime.secs = (time_t)frame_end_ts / 1000000000L;
3643
0
                nstime.nsecs = frame_end_ts % 1000000000UL;
3644
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s s", rel_time_to_secs_str(pinfo->pool, &nstime));
3645
0
                break;
3646
0
            case IEEE802154_TAP_ASN:
3647
0
                proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_asn, tvb, offset, 8, ENC_LITTLE_ENDIAN, &ieee802154_tsch_asn);
3648
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %"PRIu64, ieee802154_tsch_asn);
3649
0
                break;
3650
0
            case IEEE802154_TAP_SLOT_START_TS:
3651
0
                proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_slot_start_ts, tvb, offset, 8,
3652
0
                                    ENC_LITTLE_ENDIAN, &slot_start_ts);
3653
0
                nstime.secs = (time_t)slot_start_ts / 1000000000L;
3654
0
                nstime.nsecs = slot_start_ts % 1000000000UL;
3655
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s s", rel_time_to_secs_str(pinfo->pool, &nstime));
3656
0
                break;
3657
0
            case IEEE802154_TAP_TIMESLOT_LENGTH:
3658
0
                proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_tap_timeslot_length, tvb, offset, 4,
3659
0
                                             ENC_LITTLE_ENDIAN, &timeslot_length);
3660
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %"PRIu32" %s", timeslot_length, units_microseconds.singular);
3661
0
                break;
3662
0
            case IEEE802154_TAP_LQI: {
3663
0
                uint32_t lqi;
3664
0
                proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_tap_lqi, tvb, offset, 1, ENC_LITTLE_ENDIAN, &lqi);
3665
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %u", lqi);
3666
0
                break;
3667
0
            }
3668
0
            case IEEE802154_TAP_CHANNEL_FREQUENCY: {
3669
0
                float freq = tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN);
3670
0
                proto_tree_add_float_format_value(tlvtree, hf_ieee802154_ch_freq, tvb, offset, 4, freq, "%.3f kHz", freq);
3671
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": %.3f kHz", freq);
3672
0
                break;
3673
0
            }
3674
0
            case IEEE802154_TAP_CHANNEL_PLAN: {
3675
0
                uint32_t count;
3676
0
                float ch0_freq = tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN);
3677
0
                float spacing = tvb_get_ieee_float(tvb, offset+4, ENC_LITTLE_ENDIAN);
3678
0
                proto_tree_add_float_format_value(tlvtree, hf_ieee802154_chplan_start, tvb, offset, 4, ch0_freq, "%.3f kHz", ch0_freq);
3679
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ": Start %.3f kHz", ch0_freq);
3680
0
                proto_tree_add_float_format_value(tlvtree, hf_ieee802154_chplan_spacing, tvb, offset+4, 4, spacing, "%.3f kHz", spacing);
3681
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ", Spacing %.3f kHz", spacing);
3682
0
                proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_chplan_channels, tvb, offset+8, 2, ENC_LITTLE_ENDIAN, &count);
3683
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), ", Channels %u", count);
3684
0
                break;
3685
0
            }
3686
0
            case IEEE802154_TAP_PHY_HEADER:
3687
0
                dissect_ieee802154_tap_phy_header(tvb, pinfo, tlvtree, offset, length);
3688
0
                break;
3689
0
            default:
3690
0
                proto_tree_add_item(tlvtree, hf_ieee802154_tap_tlv_unknown, tvb, offset, length, ENC_NA);
3691
0
                proto_item_append_text(proto_tree_get_parent(tlvtree), "Unknown TLV");
3692
0
                break;
3693
0
        } /* switch (tlv_type) */
3694
0
        offset += length;
3695
3696
0
        unsigned padding_len = WS_PADDING_TO_4(length);
3697
0
        if (padding_len != 0) {
3698
0
            uint32_t zero = 0;
3699
0
            GByteArray *padding = g_byte_array_sized_new(4);
3700
0
            ti = proto_tree_add_bytes_item(tlvtree, hf_ieee802154_tap_tlv_padding, tvb, offset, padding_len, ENC_NA, padding, NULL, NULL);
3701
0
            if (memcmp(&zero, padding->data, padding_len)) {
3702
0
                expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_padding_not_zeros);
3703
0
            }
3704
0
            g_byte_array_free(padding, true);
3705
0
            offset += padding_len;
3706
0
        }
3707
0
    } /* while */
3708
3709
    /* if we have both slot start and frame start timestamp, show frame start offset */
3710
0
    if (slot_start_ts && frame_start_ts) {
3711
0
        delta_us = (double)(frame_start_ts - slot_start_ts) / 1000;
3712
0
        ti = proto_tree_add_double_format_value(tree, hf_ieee802154_frame_start_offset, NULL, 0, 0, delta_us, "%.3f %s", delta_us, units_microseconds.singular);
3713
0
        proto_item_set_generated(ti);
3714
0
    }
3715
3716
    /* if we have both start and end frame timestamp, show frame duration */
3717
0
    if (frame_start_ts && frame_end_ts) {
3718
0
        delta_us = (double)(frame_end_ts - frame_start_ts) / 1000;
3719
0
        ti = proto_tree_add_double_format_value(tree, hf_ieee802154_frame_duration, NULL, 0, 0, delta_us, "%.3f %s", delta_us, units_microseconds.singular);
3720
0
        proto_item_set_generated(ti);
3721
0
    }
3722
3723
    /* if we have start of slot, timeslot length, and end of frame timestamp, show frame overflow (+ve) or underflow (-ve) */
3724
0
    if (timeslot_length && frame_end_ts && slot_start_ts) {
3725
        /* overflow = frame_end_ts - slot_start_ts - timeslot_length */
3726
0
        delta_us = (double)(frame_end_ts - slot_start_ts) / 1000;
3727
0
        delta_us -= timeslot_length;
3728
0
        ti = proto_tree_add_double_format_value(tree, hf_ieee802154_frame_end_offset, NULL, 0, 0, delta_us, "%.3f %s", delta_us, units_microseconds.singular);
3729
0
        proto_item_set_generated(ti);
3730
0
    }
3731
3732
0
    return (ieee802154_fcs_type_t)tap_fcs_type;
3733
0
} /* dissect_ieee802154_tap_tlvs */
3734
3735
/*
3736
 * Information Elements Processing (IEs)
3737
 */
3738
3739
/**
3740
 * Create a tree for a Payload IE incl. the TLV header and append the IE name to the parent item
3741
 *
3742
 * @param tvb the tv buffer
3743
 * @param tree the tree to append this item to
3744
 * @param hf field index
3745
 * @param ett tree index
3746
 * @returns the tree created for the Payload IE
3747
 */
3748
proto_tree*
3749
ieee802154_create_pie_tree(tvbuff_t *tvb, proto_tree *tree, int hf, int ett)
3750
1.41k
{
3751
1.41k
    proto_item *subitem;
3752
1.41k
    proto_tree *subtree;
3753
1.41k
    header_field_info *hfinfo;
3754
1.41k
    static int * const tlv_fields[] = {
3755
1.41k
            &hf_ieee802154_payload_ie_type,
3756
1.41k
            &hf_ieee802154_payload_ie_id,
3757
1.41k
            &hf_ieee802154_payload_ie_length,
3758
1.41k
            NULL
3759
1.41k
    };
3760
3761
1.41k
    subitem = proto_tree_add_item(tree, hf, tvb, 0, tvb_reported_length(tvb), ENC_NA);
3762
1.41k
    subtree = proto_item_add_subtree(subitem, ett);
3763
1.41k
    proto_tree_add_bitmask_with_flags(subtree, tvb, 0, hf_ieee802154_payload_ie_tlv, ett_ieee802154_payload_ie_tlv,
3764
1.41k
                                      tlv_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
3765
3766
1.41k
    hfinfo = proto_registrar_get_nth(hf);
3767
1.41k
    if (hfinfo && hfinfo->name) {
3768
1.41k
        proto_item_append_text(proto_tree_get_parent(tree), ", %s", hfinfo->name);
3769
1.41k
    }
3770
1.41k
    return subtree;
3771
1.41k
}
3772
3773
/**
3774
 * Create a tree for a Payload Sub-IE incl. the TLV header and append the IE name to the parent item
3775
 *
3776
 * @param tvb the tv buffer
3777
 * @param tree the tree to append this item to
3778
 * @param hf field index
3779
 * @param ett tree index
3780
 * @returns the tree created for the Payload IE
3781
 */
3782
static proto_tree*
3783
ieee802154_create_psie_tree(tvbuff_t *tvb, proto_tree *tree, int hf, int ett)
3784
1.27k
{
3785
1.27k
    proto_item *subitem;
3786
1.27k
    proto_tree *subtree;
3787
1.27k
    header_field_info *hfinfo;
3788
3789
1.27k
    subitem  = proto_tree_add_item(tree, hf, tvb, 0, tvb_reported_length(tvb), ENC_NA);
3790
1.27k
    subtree = proto_item_add_subtree(subitem, ett);
3791
1.27k
    if (tvb_get_letohs(tvb, 0) & IEEE802154_PSIE_TYPE_MASK) {
3792
58
        static int * const fields_long[] = {
3793
58
            &hf_ieee802154_psie_type,
3794
58
            &hf_ieee802154_psie_id_long,
3795
58
            &hf_ieee802154_psie_length_long,
3796
58
            NULL
3797
58
        };
3798
58
        proto_tree_add_bitmask(subtree, tvb, 0, hf_ieee802154_psie, ett_ieee802154_psie, fields_long, ENC_LITTLE_ENDIAN);
3799
58
    }
3800
1.22k
    else {
3801
1.22k
        static int * const fields_short[] = {
3802
1.22k
            &hf_ieee802154_psie_type,
3803
1.22k
            &hf_ieee802154_psie_id_short,
3804
1.22k
            &hf_ieee802154_psie_length_short,
3805
1.22k
            NULL
3806
1.22k
        };
3807
1.22k
        proto_tree_add_bitmask(subtree, tvb, 0, hf_ieee802154_psie, ett_ieee802154_psie, fields_short, ENC_LITTLE_ENDIAN);
3808
1.22k
    }
3809
3810
1.27k
    hfinfo = proto_registrar_get_nth(hf);
3811
1.27k
    if (hfinfo && hfinfo->name) {
3812
1.27k
        proto_item_append_text(proto_tree_get_parent(tree), ", %s", hfinfo->name);
3813
1.27k
    }
3814
1.27k
    return subtree;
3815
1.27k
}
3816
3817
/**
3818
 * Subdissector for the MLME Channel Hopping Payload IE
3819
 */
3820
static int
3821
dissect_802154_channel_hopping(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3822
123
{
3823
123
    proto_tree *subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_channel_hopping, ett_ieee802154_mlme_payload);
3824
3825
123
    proto_tree_add_item(subtree, hf_ieee802154_tsch_hopping_sequence_id, tvb, 2, 1, ENC_LITTLE_ENDIAN);
3826
3827
123
    if (tvb_reported_length_remaining(tvb, 3) > 1) {
3828
        /* TODO: There's still a huge amount of optional stuff that could follow */
3829
116
        proto_tree_add_item(subtree, hf_ieee802154_mlme_ie_data, tvb, 3, tvb_reported_length_remaining(tvb, 3), ENC_NA);
3830
116
    }
3831
123
    return tvb_reported_length(tvb);
3832
123
} /* dissect_802154_channel_hopping */
3833
3834
/**
3835
 * Subdissector for the Nested MLME IE for TSCH Synchronization
3836
 */
3837
static int
3838
dissect_802154_tsch_time_sync(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3839
9
{
3840
9
    proto_tree *subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_sync, ett_ieee802154_tsch_synch);
3841
3842
9
    proto_tree_add_item(subtree, hf_ieee802154_tsch_asn, tvb, 2, 5, ENC_LITTLE_ENDIAN);
3843
9
    proto_tree_add_item(subtree, hf_ieee802154_tsch_join_metric, tvb, 7, 1, ENC_LITTLE_ENDIAN);
3844
9
    return 8;
3845
9
}/* dissect_802154_tsch_time_sync*/
3846
3847
/**
3848
 * Subdissector for the Nested MLME IE for TSCH Slotframe and Link
3849
 */
3850
static int
3851
dissect_802154_tsch_slotframe_link(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3852
54
{
3853
54
    uint8_t nb_slotframes;
3854
54
    uint8_t slotframe_index;
3855
54
    proto_tree *subtree;
3856
54
    unsigned offset = 0;
3857
3858
54
    subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_slotframe, ett_ieee802154_tsch_slotframe);
3859
54
    offset += 2;
3860
3861
54
    nb_slotframes = tvb_get_uint8(tvb, offset);
3862
54
    proto_tree_add_item(subtree, hf_ieee802154_tsch_slotf_link_nb_slotf, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3863
54
    offset += 1;
3864
3865
155
    for (slotframe_index = 1; slotframe_index <= nb_slotframes; slotframe_index++) {
3866
        /* Create a tree for the slotframe. */
3867
101
        uint8_t nb_links = tvb_get_uint8(tvb, offset + 3);
3868
101
        proto_item *sf_item = proto_tree_add_subtree_format(subtree, tvb, offset, 4 + (5 * nb_links),
3869
101
                                                            ett_ieee802154_tsch_slotframe, NULL,
3870
101
                                                            "Slotframes [%u]", slotframe_index);
3871
101
        proto_tree *sf_tree = proto_item_add_subtree(sf_item, ett_ieee802154_tsch_slotframe_list);
3872
101
        proto_tree_add_item(sf_tree, hf_ieee802154_tsch_slotf_link_slotf_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3873
101
        proto_tree_add_item(sf_tree, hf_ieee802154_tsch_slotf_size, tvb, offset + 1, 2, ENC_LITTLE_ENDIAN);
3874
101
        proto_tree_add_item(sf_tree, hf_ieee802154_tsch_slotf_link_nb_links, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
3875
3876
        /* Create a tree for each link in the slotframe. */
3877
101
        offset += 4;
3878
295
        while (nb_links > 0) {
3879
194
            static int * const fields_options[] = {
3880
194
                &hf_ieee802154_tsch_slotf_link_options_tx,
3881
194
                &hf_ieee802154_tsch_slotf_link_options_rx,
3882
194
                &hf_ieee802154_tsch_slotf_link_options_shared,
3883
194
                &hf_ieee802154_tsch_slotf_link_options_timkeeping,
3884
194
                &hf_ieee802154_tsch_slotf_link_options_priority,
3885
194
                NULL
3886
194
            };
3887
3888
194
            proto_item  *link_item = proto_tree_add_item(sf_tree, hf_ieee802154_tsch_link_info, tvb, offset, 5, ENC_NA);
3889
194
            proto_tree  *link_tree = proto_item_add_subtree(link_item, ett_ieee802154_tsch_slotframe_link);
3890
194
            proto_tree_add_item(link_tree, hf_ieee802154_tsch_slotf_link_timeslot, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3891
194
            proto_tree_add_item(link_tree, hf_ieee802154_tsch_slotf_link_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
3892
194
            proto_tree_add_bitmask(link_tree, tvb, offset + 4, hf_ieee802154_tsch_slotf_link_options, ett_ieee802154_tsch_slotframe_link_options, fields_options, ENC_LITTLE_ENDIAN);
3893
194
            nb_links -= 1;
3894
194
            offset += 5;
3895
194
        }
3896
101
    }
3897
3898
54
    return offset;
3899
54
}/* dissect_802154_tsch_slotframe_link */
3900
3901
/**
3902
 * Subdissector for the Nested MLME IE for TSCH Timeslot Description
3903
 */
3904
static int
3905
dissect_802154_tsch_timeslot(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3906
37
{
3907
37
    proto_tree *subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_timeslot, ett_ieee802154_tsch_timeslot);
3908
37
    unsigned offset = 2;
3909
3910
37
    proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_id, tvb, 2, 1, ENC_LITTLE_ENDIAN);
3911
37
    offset++;
3912
3913
37
    if (tvb_reported_length(tvb) > offset) {
3914
34
        const int timeslot_fields[] = {
3915
34
            hf_ieee802154_tsch_timeslot_cca_offset,
3916
34
            hf_ieee802154_tsch_timeslot_cca,
3917
34
            hf_ieee802154_tsch_timeslot_tx_offset,
3918
34
            hf_ieee802154_tsch_timeslot_rx_offset,
3919
34
            hf_ieee802154_tsch_timeslot_rx_ack_delay,
3920
34
            hf_ieee802154_tsch_timeslot_tx_ack_delay,
3921
34
            hf_ieee802154_tsch_timeslot_rx_wait,
3922
34
            hf_ieee802154_tsch_timeslot_ack_wait,
3923
34
            hf_ieee802154_tsch_timeslot_turnaround,
3924
34
            hf_ieee802154_tsch_timeslot_max_ack,
3925
34
        };
3926
34
        unsigned int i;
3927
369
        for (i = 0; i < array_length(timeslot_fields); i++) {
3928
335
            proto_tree_add_item(subtree, timeslot_fields[i], tvb, offset, 2, ENC_LITTLE_ENDIAN);
3929
335
            offset += 2;
3930
335
        }
3931
3932
        /* The last two fields are may have different encodings depending on the length of the IE. */
3933
34
        if (tvb_reported_length_remaining(tvb, offset) > 4) {
3934
33
            proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_max_tx, tvb, offset, 3, ENC_LITTLE_ENDIAN);
3935
33
            offset += 3;
3936
33
            proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_length, tvb, offset, 3, ENC_LITTLE_ENDIAN);
3937
33
            offset += 3;
3938
33
        }
3939
1
        else {
3940
1
            proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_max_tx, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3941
1
            offset += 2;
3942
1
            proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3943
1
            offset += 2;
3944
1
        }
3945
34
    }
3946
37
    return offset;
3947
37
} /* dissect_802154_tsch_timeslot */
3948
3949
/**
3950
 * Subdissector for the 6TOP Protocol contained within the Payload Information Elements.
3951
 */
3952
static int
3953
dissect_ietf_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_)
3954
36
{
3955
36
    const uint8_t supported_6p_version = 0x00;
3956
3957
36
    proto_tree *p_inf_elem_tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_pie_ietf, ett_ieee802154_pie_ietf);
3958
36
    unsigned   offset = 2;
3959
36
    unsigned   pie_length = tvb_reported_length(tvb) - 2;
3960
36
    uint8_t    version;
3961
36
    uint8_t    type;
3962
36
    uint8_t    code;
3963
36
    uint8_t    num_cells = 0;
3964
36
    bool       have_cell_list = false;
3965
36
    int        i;
3966
36
    proto_item *sixtop_item = NULL;
3967
36
    proto_tree *sixtop_tree = NULL;
3968
36
    proto_item *cell_list_item = NULL;
3969
36
    proto_tree *cell_list_tree = NULL;
3970
36
    proto_item *cell_item = NULL;
3971
36
    proto_tree *cell_tree = NULL;
3972
36
    proto_item *type_item = NULL;
3973
36
    proto_item *code_item = NULL;
3974
36
    const char *code_str = NULL;
3975
36
    static int * const cell_options[] = {
3976
36
        &hf_ieee802154_6top_cell_option_tx,
3977
36
        &hf_ieee802154_6top_cell_option_rx,
3978
36
        &hf_ieee802154_6top_cell_option_shared,
3979
36
        &hf_ieee802154_6top_cell_option_reserved,
3980
36
        NULL
3981
36
    };
3982
3983
36
    if (pie_length < 5) {
3984
7
        return pie_length + 2;
3985
7
    }
3986
3987
29
    version =  tvb_get_uint8(tvb, offset + 1) & IETF_6TOP_VERSION;
3988
3989
29
    if (version != supported_6p_version) {
3990
10
        return pie_length + 2;
3991
10
    }
3992
3993
19
    type = (tvb_get_uint8(tvb, offset + 1) & IETF_6TOP_TYPE) >> 4;
3994
19
    code = tvb_get_uint8(tvb, offset + 2);
3995
3996
19
    proto_tree_add_item(p_inf_elem_tree, hf_ieee802154_p_ie_ietf_sub_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3997
3998
19
    sixtop_item = proto_tree_add_item(p_inf_elem_tree, hf_ieee802154_6top, tvb, offset, pie_length, ENC_NA);
3999
19
    sixtop_tree = proto_item_add_subtree(sixtop_item, ett_ieee802154_p_ie_6top);
4000
4001
19
    proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_version, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
4002
19
    type_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_type, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
4003
19
    proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_flags_reserved, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
4004
19
    code_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_code, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
4005
19
    proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_sfid, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
4006
19
    proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_seqnum, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
4007
4008
19
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "6top");
4009
19
    if (type == IETF_6TOP_TYPE_REQUEST) {
4010
12
      code_str = val_to_str_const(code, ietf_6top_command_identifiers,"Unknown");
4011
12
      col_add_fstr(pinfo->cinfo, COL_INFO, "6P %s Request", code_str);
4012
12
    } else {
4013
7
      code_str = val_to_str_const(code, ietf_6top_return_codes,"Unknown");
4014
7
      col_add_fstr(pinfo->cinfo, COL_INFO, "6P %s (%s)",
4015
7
                   val_to_str_const(type, ietf_6top_types,"Unknown"), code_str);
4016
7
    }
4017
19
    proto_item_append_text(code_item, " (%s)", code_str);
4018
4019
19
    offset += 5;
4020
19
    pie_length -= 5;
4021
4022
19
    if (type == IETF_6TOP_TYPE_REQUEST) {
4023
12
        switch (code) {
4024
3
        case IETF_6TOP_CMD_ADD:
4025
3
        case IETF_6TOP_CMD_DELETE:
4026
4
        case IETF_6TOP_CMD_RELOCATE:
4027
4
            if (pie_length < 4) {
4028
0
                break;
4029
0
            }
4030
4
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4031
4
            proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN);
4032
4
            proto_tree_add_item_ret_uint8(sixtop_tree, hf_ieee802154_6top_num_cells, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN, &num_cells);
4033
4
            pie_length -= 4;
4034
4
            offset += 4;
4035
4
            if (pie_length > 0 && (pie_length % 4) == 0) {
4036
3
                have_cell_list = true;
4037
3
            }
4038
4
            break;
4039
0
        case IETF_6TOP_CMD_COUNT:
4040
0
            if (pie_length < 3) {
4041
0
                break;
4042
0
            }
4043
0
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4044
0
            proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN);
4045
0
            pie_length -= 3;
4046
0
            offset += 3;
4047
0
            break;
4048
0
        case IETF_6TOP_CMD_LIST:
4049
0
            if (pie_length != 8) {
4050
0
                break;
4051
0
            }
4052
0
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4053
0
            proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN);
4054
0
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_reserved, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
4055
0
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_offset, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
4056
0
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_max_num_cells, tvb, offset + 6, 2, ENC_LITTLE_ENDIAN);
4057
0
            pie_length -= 8;
4058
0
            offset += 8;
4059
0
            break;
4060
1
        case IETF_6TOP_CMD_SIGNAL:
4061
1
            if (pie_length < 2) {
4062
0
                break;
4063
0
            }
4064
1
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4065
1
            if (pie_length > 2) {
4066
1
                proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_payload, tvb, offset + 2, pie_length - 2, ENC_NA);
4067
1
            }
4068
1
            offset += pie_length;
4069
1
            pie_length = 0;
4070
1
            break;
4071
0
        case IETF_6TOP_CMD_CLEAR:
4072
0
            if (pie_length < 2) {
4073
0
                break;
4074
0
            }
4075
0
            proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4076
0
            pie_length -= 2;
4077
0
            offset += 2;
4078
0
            break;
4079
7
        default:
4080
            /* unsupported command */
4081
7
            expert_add_info(pinfo, code_item, &ei_ieee802154_6top_unsupported_command);
4082
7
            break;
4083
12
        }
4084
12
    } else if (type == IETF_6TOP_TYPE_RESPONSE || type == IETF_6TOP_TYPE_CONFIRMATION) {
4085
5
        switch(code) {
4086
2
        case IETF_6TOP_RC_SUCCESS:
4087
2
            if (pie_length > 0) {
4088
2
                if (pie_length == 2) {
4089
0
                    proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_total_num_cells, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4090
0
                    pie_length -= 2;
4091
0
                    offset += 2;
4092
2
                } else if ((pie_length % 4) == 0) {
4093
0
                    have_cell_list = true;
4094
2
                } else {
4095
2
                    proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_payload, tvb, offset, pie_length, ENC_NA);
4096
2
                    offset += pie_length;
4097
2
                    pie_length = 0;
4098
2
                }
4099
2
            }
4100
2
            break;
4101
0
        case IETF_6TOP_RC_EOL:
4102
0
            if(pie_length > 0 && (pie_length % 4) == 0) {
4103
0
                have_cell_list = true;
4104
0
            }
4105
0
            break;
4106
0
        case IETF_6TOP_RC_ERR:
4107
0
        case IETF_6TOP_RC_RESET:
4108
0
        case IETF_6TOP_RC_ERR_VERSION:
4109
0
        case IETF_6TOP_RC_ERR_SFID:
4110
0
        case IETF_6TOP_RC_ERR_SEQNUM:
4111
0
        case IETF_6TOP_RC_ERR_CELLLIST:
4112
0
        case IETF_6TOP_RC_ERR_BUSY:
4113
0
        case IETF_6TOP_RC_ERR_LOCKED:
4114
            /* They have no other field */
4115
0
            break;
4116
3
        default:
4117
            /* unsupported return code */
4118
3
            expert_add_info(pinfo, code_item, &ei_ieee802154_6top_unsupported_return_code);
4119
3
            break;
4120
5
        }
4121
5
    } else {
4122
        /* unsupported type */
4123
2
        expert_add_info(pinfo, type_item, &ei_ieee802154_6top_unsupported_type);
4124
2
    }
4125
4126
16
    if (have_cell_list) {
4127
3
        if (type == IETF_6TOP_TYPE_REQUEST && code == IETF_6TOP_CMD_RELOCATE) {
4128
1
            cell_list_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_rel_cell_list, tvb, offset, pie_length, ENC_NA);
4129
1
            cell_list_tree = proto_item_add_subtree(cell_list_item, ett_ieee802154_p_ie_6top_rel_cell_list);
4130
            /* num_cells is expected to be set properly */
4131
70
            for (i = 0; i < num_cells; offset += 4, i++) {
4132
69
                cell_item = proto_tree_add_item(cell_list_tree, hf_ieee802154_6top_cell, tvb, offset, 4, ENC_NA);
4133
69
                cell_tree = proto_item_add_subtree(cell_item, ett_ieee802154_p_ie_6top_cell);
4134
69
                proto_tree_add_item(cell_tree, hf_ieee802154_6top_slot_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4135
69
                proto_tree_add_item(cell_tree, hf_ieee802154_6top_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
4136
69
            }
4137
1
            pie_length -= num_cells * 4;
4138
1
            cell_list_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_cand_cell_list, tvb, offset, pie_length, ENC_NA);
4139
1
            cell_list_tree = proto_item_add_subtree(cell_list_item, ett_ieee802154_p_ie_6top_cand_cell_list);
4140
35
            for (i = 0; pie_length > 0; pie_length -= 4, offset += 4, i++) {
4141
34
                cell_item = proto_tree_add_item(cell_list_tree, hf_ieee802154_6top_cell, tvb, offset, 4, ENC_NA);
4142
34
                cell_tree = proto_item_add_subtree(cell_item, ett_ieee802154_p_ie_6top_cell);
4143
34
                proto_tree_add_item(cell_tree, hf_ieee802154_6top_slot_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4144
34
                proto_tree_add_item(cell_tree, hf_ieee802154_6top_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
4145
34
            }
4146
2
        } else {
4147
2
            cell_list_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_cell_list, tvb, offset, pie_length, ENC_NA);
4148
2
            cell_list_tree = proto_item_add_subtree(cell_list_item, ett_ieee802154_p_ie_6top_cell_list);
4149
98
            for (i = 0; pie_length > 0; pie_length -= 4, offset += 4, i++) {
4150
96
                cell_item = proto_tree_add_item(cell_list_tree, hf_ieee802154_6top_cell, tvb, offset, 4, ENC_NA);
4151
96
                cell_tree = proto_item_add_subtree(cell_item, ett_ieee802154_p_ie_6top_cell);
4152
96
                proto_tree_add_item(cell_tree, hf_ieee802154_6top_slot_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4153
96
                proto_tree_add_item(cell_tree, hf_ieee802154_6top_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
4154
96
            }
4155
2
        }
4156
3
    }
4157
4158
16
    return offset;
4159
19
} /* dissect_ieee802154_6top */
4160
4161
/**
4162
 * Subdissector for the Superframe specification sub-field within the beacon frame.
4163
 *
4164
 * @param tvb pointer to buffer containing raw packet.
4165
 * @param pinfo pointer to packet information fields (unused).
4166
 * @param tree pointer to command subtree.
4167
 * @param offset offset into the tvbuff to begin dissection.
4168
 */
4169
void
4170
dissect_ieee802154_superframe(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset)
4171
226
{
4172
226
    static int * const superframe[] = {
4173
226
        &hf_ieee802154_beacon_order,
4174
226
        &hf_ieee802154_superframe_order,
4175
226
        &hf_ieee802154_cap,
4176
226
        &hf_ieee802154_superframe_battery_ext,
4177
226
        &hf_ieee802154_superframe_coord,
4178
226
        &hf_ieee802154_assoc_permit,
4179
226
        NULL
4180
226
    };
4181
4182
226
    proto_tree_add_bitmask_text(tree, tvb, *offset, 2, "Superframe Specification: ", NULL , ett_ieee802154_superframe, superframe, ENC_LITTLE_ENDIAN, BMT_NO_INT|BMT_NO_TFS);
4183
226
    (*offset) += 2;
4184
226
} /* dissect_ieee802154_superframe */
4185
4186
/**
4187
 * Subdissector for the GTS information fields within the beacon frame.
4188
 *
4189
 * @param tvb pointer to buffer containing raw packet.
4190
 * @param pinfo pointer to packet information fields (unused).
4191
 * @param tree pointer to command subtree.
4192
 * @param offset offset into the tvbuff to begin dissection.
4193
 */
4194
void
4195
dissect_ieee802154_gtsinfo(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset)
4196
223
{
4197
223
    proto_tree *field_tree = NULL;
4198
223
    proto_tree *subtree    = NULL;
4199
223
    proto_item *ti;
4200
223
    uint8_t     gts_spec;
4201
223
    uint8_t     gts_count;
4202
4203
    /*  Get and display the GTS specification field */
4204
223
    gts_spec = tvb_get_uint8(tvb, *offset);
4205
223
    gts_count = gts_spec & IEEE802154_GTS_COUNT_MASK;
4206
223
    if (tree) {
4207
        /*  Add Subtree for GTS information. */
4208
223
        if (gts_count) {
4209
136
            field_tree = proto_tree_add_subtree(tree, tvb, *offset, 2 + (gts_count * 3), ett_ieee802154_gts, NULL, "GTS");
4210
136
        }
4211
87
        else {
4212
87
            field_tree = proto_tree_add_subtree(tree, tvb, *offset, 1, ett_ieee802154_gts, NULL, "GTS");
4213
87
        }
4214
4215
223
        proto_tree_add_uint(field_tree, hf_ieee802154_gts_count, tvb, *offset, 1, gts_count);
4216
223
        proto_tree_add_boolean(field_tree, hf_ieee802154_gts_permit, tvb, *offset, 1, gts_spec & IEEE802154_GTS_PERMIT_MASK);
4217
223
    }
4218
223
    (*offset) += 1;
4219
4220
    /* If the GTS descriptor count is nonzero, then the GTS directions mask and descriptor list are present. */
4221
223
    if (gts_count) {
4222
136
        uint8_t gts_directions = tvb_get_uint8(tvb, *offset);
4223
136
        unsigned   gts_rx = 0;
4224
136
        int     i;
4225
4226
        /* Display the directions mask. */
4227
136
        if (tree) {
4228
135
            proto_tree  *dir_tree;
4229
4230
            /* Create a subtree. */
4231
135
            dir_tree = proto_tree_add_subtree(field_tree, tvb, *offset, 1, ett_ieee802154_gts_direction, &ti, "GTS Directions");
4232
4233
            /* Add the directions to the subtree. */
4234
685
            for (i=0; i<gts_count; i++) {
4235
550
                bool        dir = gts_directions & IEEE802154_GTS_DIRECTION_SLOT(i);
4236
550
                proto_tree_add_boolean_format(dir_tree, hf_ieee802154_gts_direction, tvb, *offset, 1, dir, "GTS Slot %i: %s", i+1, dir?"Receive Only":"Transmit Only");
4237
550
                if (dir) gts_rx++;
4238
550
            } /* for */
4239
135
            proto_item_append_text(ti, ": %i Receive & %i Transmit", gts_rx, gts_count - gts_rx);
4240
135
        }
4241
136
        (*offset) += 1;
4242
4243
        /* Create a subtree for the GTS descriptors. */
4244
136
        subtree = proto_tree_add_subtree(field_tree, tvb, *offset, gts_count * 3, ett_ieee802154_gts_descriptors, NULL, "GTS Descriptors");
4245
4246
        /* Get and display the GTS descriptors. */
4247
597
        for (i=0; i<gts_count; i++) {
4248
461
            uint16_t gts_addr        = tvb_get_letohs(tvb, (*offset));
4249
461
            uint8_t gts_slot        = tvb_get_uint8(tvb, (*offset)+2);
4250
461
            uint8_t gts_length      = (gts_slot & IEEE802154_GTS_LENGTH_MASK) >> IEEE802154_GTS_LENGTH_SHIFT;
4251
4252
461
            gts_slot = (gts_slot & IEEE802154_GTS_SLOT_MASK);
4253
4254
461
            if (tree) {
4255
                /* Add address, slot, and time length fields. */
4256
438
                ti = proto_tree_add_uint(subtree, hf_ieee802154_gts_address, tvb, (*offset), 3, gts_addr);
4257
438
                proto_item_append_text(ti, ", Slot: %i", gts_slot);
4258
438
                proto_item_append_text(ti, ", Length: %i", gts_length);
4259
438
            }
4260
461
            (*offset) += 3;
4261
461
        } /* for */
4262
136
    }
4263
223
} /* dissect_ieee802154_gtsinfo */
4264
4265
/**
4266
 * Subdissector for the pending address list fields within the beacon frame.
4267
 *
4268
 * @param tvb pointer to buffer containing raw packet.
4269
 * @param pinfo pointer to packet information fields (unused).
4270
 * @param tree pointer to command subtree.
4271
 * @param offset into the tvbuff to begin dissection.
4272
 */
4273
void
4274
dissect_ieee802154_pendaddr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset)
4275
189
{
4276
189
    proto_tree *subtree;
4277
189
    uint8_t     pend_spec;
4278
189
    uint8_t     pend_num16;
4279
189
    uint8_t     pend_num64;
4280
189
    int         i;
4281
4282
    /*  Get the Pending Addresses specification fields */
4283
189
    pend_spec = tvb_get_uint8(tvb, *offset);
4284
189
    pend_num16 = pend_spec & IEEE802154_PENDADDR_SHORT_MASK;
4285
189
    pend_num64 = (pend_spec & IEEE802154_PENDADDR_LONG_MASK) >> IEEE802154_PENDADDR_LONG_SHIFT;
4286
4287
    /*  Add Subtree for the addresses */
4288
189
    subtree = proto_tree_add_subtree_format(tree, tvb, *offset, 1 + 2*pend_num16 + 8*pend_num64,
4289
189
                        ett_ieee802154_pendaddr, NULL, "Pending Addresses: %i Short and %i Long", pend_num16, pend_num64);
4290
189
    (*offset) += 1;
4291
4292
466
    for (i=0; i<pend_num16; i++) {
4293
277
        uint16_t addr = tvb_get_letohs(tvb, *offset);
4294
277
        proto_tree_add_uint(subtree, hf_ieee802154_pending16, tvb, *offset, 2, addr);
4295
277
        (*offset) += 2;
4296
277
    } /* for */
4297
458
    for (i=0; i<pend_num64; i++) {
4298
269
        proto_tree_add_item(subtree, hf_ieee802154_pending64, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
4299
269
        (*offset) += 8;
4300
269
    } /* for */
4301
189
} /* dissect_ieee802154_pendaddr */
4302
4303
/*
4304
 * Header IEs
4305
 */
4306
4307
/**
4308
 * Create a tree for a Header IE incl. the TLV header and append the IE name to the parent item
4309
 *
4310
 * @param tvb the tv buffer
4311
 * @param tree the tree to append this item to
4312
 * @param hf field index
4313
 * @param ett tree index
4314
 * @returns the tree created for the Header IE
4315
 */
4316
proto_tree*
4317
ieee802154_create_hie_tree(tvbuff_t *tvb, proto_tree *tree, int hf, int ett)
4318
1.79k
{
4319
1.79k
    proto_item *subitem;
4320
1.79k
    proto_tree *subtree;
4321
1.79k
    header_field_info *hfinfo;
4322
1.79k
    static int * const tlv_fields[] = {
4323
1.79k
            &hf_ieee802154_header_ie_type,
4324
1.79k
            &hf_ieee802154_header_ie_id,
4325
1.79k
            &hf_ieee802154_header_ie_length,
4326
1.79k
            NULL
4327
1.79k
    };
4328
4329
1.79k
    subitem = proto_tree_add_item(tree, hf, tvb, 0, tvb_reported_length(tvb), ENC_NA);
4330
1.79k
    subtree = proto_item_add_subtree(subitem, ett);
4331
1.79k
    proto_tree_add_bitmask_with_flags(subtree, tvb, 0, hf_ieee802154_header_ie_tlv, ett_ieee802154_header_ie_tlv,
4332
1.79k
                                      tlv_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
4333
4334
1.79k
    hfinfo = proto_registrar_get_nth(hf);
4335
1.79k
    if (hfinfo && hfinfo->name) {
4336
1.79k
        proto_item_append_text(proto_tree_get_parent(tree), ", %s", hfinfo->name);
4337
1.79k
    }
4338
1.79k
    return subtree;
4339
1.79k
}
4340
4341
/*
4342
 * The dissectors for the individual Header IEs
4343
 * They are called via call_dissector with the tvb including the IE header and data as ieee802154_packet
4344
 */
4345
4346
/**
4347
 * Dissect the CSL IE (7.4.2.3)
4348
 */
4349
static int
4350
dissect_hie_csl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4351
76
{
4352
76
    proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_csl, ett_ieee802154_hie_csl);
4353
76
    proto_tree_add_item(subtree, hf_ieee802154_hie_csl_phase, tvb, 2, 2, ENC_LITTLE_ENDIAN);
4354
76
    proto_tree_add_item(subtree, hf_ieee802154_hie_csl_period, tvb, 4, 2, ENC_LITTLE_ENDIAN);
4355
76
    if (tvb_reported_length(tvb) >= 8) {
4356
59
        proto_tree_add_item(subtree, hf_ieee802154_hie_csl_rendezvous_time, tvb, 6, 2, ENC_LITTLE_ENDIAN);
4357
59
        return 2 + 6;
4358
59
    }
4359
17
    return 2 + 4;
4360
76
}
4361
4362
/**
4363
 * Dissect the Rendez-Vous Time IE (7.4.2.6)
4364
 * The IE is made of 2 fields:
4365
 *  - RendezVous Time: in 802.15.4-2015, this is exactly the same field as in the CSL IE
4366
 *  - Wake-Up Interval: the spec text is unclear about the field being optional or not. This dissector assumes it is
4367
 */
4368
static int
4369
dissect_hie_rendezvous_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4370
73
{
4371
73
    proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_rdv, ett_ieee802154_hie_rdv);
4372
4373
    // reuse field from CSL IE
4374
73
    proto_tree_add_item(subtree, hf_ieee802154_hie_csl_rendezvous_time, tvb, 2, 2, ENC_LITTLE_ENDIAN);
4375
4376
    // In 802.15.4-2015, Rendez-Vous Time IE is only present in CSL Wake-Up Frames
4377
    // Update the packet information
4378
73
    col_set_str(pinfo->cinfo, COL_INFO, "CSL Wake-up Frame");
4379
73
    col_append_fstr(pinfo->cinfo, COL_INFO, ", Rendez-Vous Time: %d", tvb_get_uint16(tvb, 2, ENC_LITTLE_ENDIAN));
4380
4381
    // Assume Wake-Up Interval is optional. Spec says "only present [...] when macCslInterval is nonzero"
4382
73
    if (tvb_reported_length(tvb) >= 6) {
4383
72
        proto_tree_add_item(subtree, hf_ieee802154_hie_rdv_wakeup_interval, tvb, 4, 2, ENC_LITTLE_ENDIAN);
4384
72
        return 2 + 4;
4385
72
    }
4386
4387
1
    return 2 + 2;
4388
73
}
4389
4390
/**
4391
 * Dissect the Time Correction Header IE (7.4.2.7)
4392
 *
4393
 * This field is constructed by taking a signed 16-bit 2's complement time
4394
 * correction in the range of -2048 us to 2047 us, AND'ing it with 0xfff, and
4395
 * OR'ing again with 0x8000 to indicate a negative acknowledgment.
4396
 */
4397
static int
4398
dissect_hie_time_correction(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_)
4399
74
{
4400
74
    static int * const fields[] = {
4401
74
            &hf_ieee802154_hie_time_correction_value,
4402
74
            &hf_ieee802154_nack,
4403
74
            NULL
4404
74
    };
4405
74
    proto_tree *tree = ieee802154_create_hie_tree(tvb, ies_tree, hf_ieee802154_hie_time_correction, ett_ieee802154_hie_time_correction);
4406
74
    uint16_t time_sync_value = tvb_get_letohs(tvb, 2);
4407
74
    proto_tree_add_bitmask_with_flags(tree, tvb, 2, hf_ieee802154_hie_time_correction_time_sync_info, ett_ieee802154_header_ie,
4408
74
                                      fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
4409
4410
74
    if (time_sync_value & ~(0x8fff)) {
4411
23
        expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802154_time_correction_error);
4412
23
    }
4413
74
    if (time_sync_value & 0x8000) {
4414
14
        proto_item_append_text(proto_tree_get_parent(ies_tree), ": NACK");
4415
14
    }
4416
74
    return 2 + 2;
4417
74
}
4418
4419
static int
4420
dissect_hie_global_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4421
21
{
4422
21
    proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_global_time, ett_ieee802154_hie_global_time);
4423
21
    proto_tree_add_item(subtree, hf_ieee802154_hie_global_time_value, tvb, 2, 4, ENC_TIME_SECS|ENC_LITTLE_ENDIAN);
4424
21
    return 2 + 4;
4425
21
}
4426
4427
/**
4428
 * Dissect the Vendor Specific IE (7.4.2.2)
4429
 */
4430
static int
4431
dissect_hie_vendor_specific(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4432
0
{
4433
0
    proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_vendor_specific,
4434
0
                                                                ett_ieee802154_hie_vendor_specific);
4435
4436
0
    unsigned hie_length = tvb_reported_length(tvb) - 2;
4437
0
    unsigned   offset = 2;
4438
4439
0
    tvb_get_letoh24(tvb, offset);
4440
0
    proto_tree_add_item(subtree, hf_ieee802154_hie_vendor_specific_vendor_oui, tvb, offset, 3, ENC_LITTLE_ENDIAN);
4441
0
    offset += 3; /* adjust for vendor OUI */
4442
0
    hie_length -= 3;
4443
4444
0
    proto_tree_add_item(subtree, hf_ieee802154_hie_vendor_specific_content, tvb, offset, hie_length, ENC_NA);
4445
4446
0
    return tvb_reported_length(tvb);
4447
0
}
4448
4449
/**
4450
 Subdissector for Vendor Specific Header IEs (Information Elements)
4451
 */
4452
static int
4453
dissect_ie_vendor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_)
4454
107
{
4455
107
    proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_pie_vendor, ett_ieee802154_pie_vendor);
4456
4457
107
    unsigned   offset = 2;
4458
107
    unsigned   pie_length = tvb_reported_length(tvb) - 2;
4459
107
    tvbuff_t  *next_tvb;
4460
107
    uint32_t   vendor_oui;
4461
4462
107
    vendor_oui = tvb_get_letoh24(tvb, offset);
4463
107
    proto_tree_add_item(tree, hf_ieee802154_pie_vendor_oui, tvb, offset, 3, ENC_LITTLE_ENDIAN);
4464
107
    offset += 3; /* adjust for vendor OUI */
4465
107
    pie_length -= 3;
4466
107
    next_tvb = tvb_new_subset_length(tvb, offset, pie_length);
4467
4468
107
    switch (vendor_oui) {
4469
0
        case OUI_THREAD:
4470
            /*Decoding vendor variable data */
4471
0
            proto_tree_add_item(tree, hf_ieee802154_pie_vendor_variable, tvb, offset, pie_length, ENC_NA);
4472
0
            break;
4473
4474
78
        default:
4475
78
            call_data_dissector(next_tvb, pinfo, tree);
4476
78
            break;
4477
107
    }
4478
4479
78
    return tvb_reported_length(tvb);
4480
107
}
4481
4482
/**
4483
 * Subdissector for Header IEs (Information Elements)
4484
 *
4485
 * Since the header is never encrypted and the payload may be encrypted,
4486
 * we dissect header and payload IEs separately.
4487
 * The termination of the Header IE tells us whether there are any
4488
 * payload IEs to follow.
4489
 *
4490
 * @param tvb the tv buffer
4491
 * @param pinfo pointer to packet information fields.
4492
 * @param tree the tree to append this item to
4493
 * @param orig_offset offset into the tvbuff to begin dissection.
4494
 * @param packet IEEE 802.15.4 packet information.
4495
 */
4496
static int
4497
dissect_ieee802154_header_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned orig_offset, ieee802154_packet *packet)
4498
415
{
4499
    // GCC emits a spurious -Wclobbered if offset is used as function parameter (even with volatile)
4500
415
    volatile unsigned offset = orig_offset;
4501
415
    proto_item *ies_item = proto_tree_add_item(tree, hf_ieee802154_header_ies, tvb, offset, -1, ENC_NA);
4502
415
    proto_tree *ies_tree = proto_item_add_subtree(ies_item, ett_ieee802154_header_ie);
4503
415
    volatile int remaining = tvb_reported_length_remaining(tvb, offset) - IEEE802154_MIC_LENGTH(packet->security_level);
4504
4505
    // Loop as long as we don't:
4506
    //
4507
    // 1) run out of data;
4508
    // 2) get a header termination IE.
4509
    //
4510
    // See Table 9-6 "Termination IE inclusion rules" of IEEE Std 802.15.4-2015;
4511
    // unless we have no payload IEs and no payload data, we *have* to have
4512
    // a header termination IE to end the list of header IEs, so the "run out
4513
    // of data" check needs only to check whether there's any data
4514
    // left in the tvbuff (which has already had the FCS removed from
4515
    // it), other than a MIC if present - if we have no payload IEs or
4516
    // payload data, there might still be a MIC to Check the Message
4517
    // Integrity.
4518
    //
4519
    // XXX - we should make sure we have enough data left for an IE header,
4520
    // and report a malformed frame if not, and if we do have enough data,
4521
    // make sure we have enough data for the full IE, and report a malformed
4522
    // frame if not.
4523
1.81k
    do {
4524
1.81k
        volatile int consumed = 0;
4525
1.81k
        uint16_t ie_header = tvb_get_letohs(tvb, offset);
4526
1.81k
        uint16_t id = (uint16_t) ((ie_header & IEEE802154_HEADER_IE_ID_MASK) >> 7);
4527
1.81k
        uint16_t length = (uint16_t) (ie_header & IEEE802154_HEADER_IE_LENGTH_MASK);
4528
1.81k
        tvbuff_t * volatile ie_tvb = tvb_new_subset_length(tvb, offset, 2 + length);
4529
4530
1.81k
        if (id == IEEE802154_HEADER_IE_HT1 || id == IEEE802154_HEADER_IE_HT2) {
4531
283
            int hf_term_ie = (id == IEEE802154_HEADER_IE_HT1) ? hf_ieee802154_hie_ht1 : hf_ieee802154_hie_ht2;
4532
283
            ieee802154_create_hie_tree(ie_tvb, ies_tree, hf_term_ie, ett_ieee802154_hie_ht);
4533
283
            consumed = 2;
4534
1.52k
        } else if (id == IEEE802154_HEADER_IE_VENDOR_SPECIFIC) {
4535
107
            ieee802154_create_hie_tree(ie_tvb, ies_tree, hf_ieee802154_hie_thread, ett_ieee802154_hie_thread);
4536
107
            dissect_ie_vendor(ie_tvb, pinfo, ies_tree, packet);
4537
107
            consumed = 2 + length;
4538
1.42k
        } else {
4539
1.42k
            TRY {
4540
1.40k
                consumed = dissector_try_uint_with_data(header_ie_dissector_table, id, ie_tvb, pinfo, ies_tree, false, packet);
4541
1.40k
                if (consumed == 0) {
4542
1.08k
                    proto_tree *subtree = ieee802154_create_hie_tree(ie_tvb, ies_tree, hf_ieee802154_hie_unsupported,
4543
1.08k
                                                                ett_ieee802154_hie_unsupported);
4544
1.08k
                    proto_tree_add_item(subtree, hf_ieee802154_ie_unknown_content, ie_tvb, 2, length, ENC_NA);
4545
1.08k
                    consumed = 2 + length;
4546
1.08k
                    if (ie_header & IEEE802154_PAYLOAD_IE_TYPE_MASK) {
4547
438
                        expert_add_info(pinfo, ies_tree, &ei_ieee802154_payload_ie_in_header);
4548
651
                    } else {
4549
651
                        expert_add_info(pinfo, ies_tree, &ei_ieee802154_ie_unsupported_id);
4550
651
                    }
4551
1.08k
                }
4552
1.40k
            }
4553
1.42k
            CATCH_ALL {
4554
99
                show_exception(tvb, pinfo, ies_tree, EXCEPT_CODE, GET_MESSAGE);
4555
99
                consumed = 2 + length;
4556
99
            }
4557
1.42k
            ENDTRY;
4558
1.42k
        }
4559
4560
1.81k
        if (consumed < 2 + length) {
4561
465
            proto_tree_add_item(ies_tree, hf_ieee802154_ie_unknown_content, ie_tvb, consumed, 2 + length - consumed, ENC_NA);
4562
465
            expert_add_info(pinfo, ies_item, &ei_ieee802154_ie_unknown_extra_content);
4563
465
        }
4564
4565
1.81k
        offset += 2 + length;
4566
1.81k
        remaining -= 2 + length;
4567
4568
1.81k
        if (id == IEEE802154_HEADER_IE_HT1 || id == IEEE802154_HEADER_IE_HT2) {
4569
281
            packet->payload_ie_present = (id == IEEE802154_HEADER_IE_HT1);
4570
281
            break;
4571
281
        }
4572
1.81k
    } while (remaining > 0);
4573
4574
415
    proto_item_set_len(ies_item, offset - orig_offset);
4575
415
    return offset - orig_offset;
4576
415
}
4577
4578
static int
4579
dissect_802154_eb_filter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4580
17
{
4581
17
    uint8_t filter;
4582
17
    uint8_t attr_len;
4583
17
    proto_tree *subtree;
4584
17
    unsigned offset = 0;
4585
4586
17
    static int * const fields_eb_filter[] = {
4587
17
        &hf_ieee802154_psie_eb_filter_pjoin,
4588
17
        &hf_ieee802154_psie_eb_filter_lqi,
4589
17
        &hf_ieee802154_psie_eb_filter_percent,
4590
17
        &hf_ieee802154_psie_eb_filter_attr_id,
4591
        /* reserved 5-7 */
4592
17
        NULL
4593
17
    };
4594
4595
17
    subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_psie_eb_filter, ett_ieee802154_eb_filter);
4596
17
    offset += 2;
4597
4598
17
    filter = tvb_get_uint8(tvb, offset);
4599
17
    proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_psie_eb_filter,
4600
17
                           ett_ieee802154_eb_filter_bitmap, fields_eb_filter, ENC_NA);
4601
17
    offset++;
4602
4603
17
    if (filter & IEEE802154_MLME_PSIE_EB_FLT_LQI) {
4604
12
        proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_lqi_min, tvb, offset, 1, ENC_NA);
4605
12
        offset++;
4606
12
    }
4607
4608
17
    if (filter & IEEE802154_MLME_PSIE_EB_FLT_PERCENT) {
4609
12
        proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_percent_prob, tvb, offset, 1, ENC_NA);
4610
12
        offset++;
4611
12
    }
4612
4613
17
    attr_len = (uint8_t) ((filter & IEEE802154_MLME_PSIE_EB_FLT_ATTR_LEN) >> 3);
4614
17
    if (attr_len) {
4615
        /* just display in hex until we know how to decode */
4616
12
        proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_attr_id_bitmap, tvb, offset, attr_len, ENC_LITTLE_ENDIAN);
4617
12
        offset += attr_len;
4618
12
    }
4619
4620
17
    return offset;
4621
17
}
4622
4623
/**
4624
 * Subdissector for MLME IEs
4625
 */
4626
static int
4627
dissect_pie_mlme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ies_tree, void *data)
4628
127
{
4629
127
    proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_mlme, ett_ieee802154_mlme);
4630
127
    volatile unsigned offset = 2;
4631
4632
1.40k
    while (tvb_reported_length_remaining(tvb, offset) > 1) {
4633
1.28k
        uint16_t            psie_ie = tvb_get_letohs(tvb, offset);
4634
1.28k
        volatile uint16_t   psie_id;
4635
1.28k
        tvbuff_t *volatile  psie_tvb;
4636
4637
1.28k
        if (psie_ie & IEEE802154_PSIE_TYPE_MASK) {
4638
            /* long format: Table 7-17-Sub-ID allocation for long format */
4639
58
            psie_id  = (uint16_t) ((psie_ie & IEEE802154_PSIE_ID_MASK_LONG) >> 11);
4640
58
            psie_tvb = tvb_new_subset_length(tvb, offset, (psie_ie & IEEE802154_PSIE_LENGTH_MASK_LONG) + 2);
4641
58
        }
4642
1.22k
        else {
4643
            /* short format: Table 7-16-Sub-ID allocation for short format */
4644
1.22k
            psie_id  = (uint16_t) ((psie_ie & IEEE802154_PSIE_ID_MASK_SHORT) >> 8);
4645
1.22k
            psie_tvb = tvb_new_subset_length(tvb, offset, (psie_ie & IEEE802154_PSIE_LENGTH_MASK_SHORT) + 2);
4646
1.22k
        }
4647
1.28k
        offset += tvb_reported_length(psie_tvb);
4648
4649
        /* Pass the tvb off to a subdissector. */
4650
1.28k
        TRY {
4651
1.27k
            unsigned consumed = dissector_try_uint_with_data(mlme_ie_dissector_table, psie_id, psie_tvb, pinfo, tree, false, data);
4652
1.27k
            if (consumed == 0) {
4653
1.03k
                proto_tree *subtree = ieee802154_create_psie_tree(psie_tvb, tree, hf_ieee802154_mlme_ie_unsupported, ett_ieee802154_mlme_unsupported);
4654
1.03k
                if (tvb_reported_length(psie_tvb) > 2) {
4655
352
                    proto_tree_add_item(subtree, hf_ieee802154_mlme_ie_data, psie_tvb, 2, -1, ENC_NA);
4656
352
                }
4657
1.03k
                expert_add_info(pinfo, subtree, &ei_ieee802154_ie_unsupported_id);
4658
1.03k
            }
4659
1.27k
        }
4660
1.28k
        CATCH_ALL {
4661
73
            show_exception(tvb, pinfo, ies_tree, EXCEPT_CODE, GET_MESSAGE);
4662
73
        }
4663
1.28k
        ENDTRY;
4664
1.28k
    }
4665
127
    return offset;
4666
127
}
4667
4668
/**
4669
 * Subdissector for MPX IEs (IEEE 802.15.9)
4670
 */
4671
static int
4672
dissect_mpx_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_)
4673
149
{
4674
149
    static int * const fields[] = {
4675
149
            &hf_ieee802159_mpx_transaction_id,
4676
149
            &hf_ieee802159_mpx_transfer_type,
4677
149
            NULL
4678
149
    };
4679
149
    static int * const fields_compressed_multiplex_id[] = {
4680
149
            &hf_ieee802159_mpx_transaction_id_as_multiplex_id,
4681
149
            &hf_ieee802159_mpx_transfer_type,
4682
149
            NULL
4683
149
    };
4684
4685
149
    proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802159_mpx, ett_ieee802159_mpx);
4686
149
    unsigned offset = 2;
4687
149
    uint8_t transaction_control = tvb_get_uint8(tvb, offset);
4688
149
    uint8_t transfer_type = (uint8_t) (transaction_control & IEEE802159_MPX_TRANSFER_TYPE_MASK);
4689
149
    uint8_t transaction_id = (uint8_t) ((transaction_control & IEEE802159_MPX_TRANSACTION_ID_MASK) >> IEEE802159_MPX_TRANSACTION_ID_SHIFT);
4690
149
    int32_t multiplex_id = -1;
4691
149
    uint8_t fragment_number;
4692
4693
149
    if (transfer_type == IEEE802159_MPX_FULL_FRAME_NO_MUXID) {
4694
7
        proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee802159_mpx_transaction_control, ett_ieee802159_mpx_transaction_control,
4695
7
                               fields_compressed_multiplex_id, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
4696
7
        multiplex_id = transaction_id;
4697
142
    } else {
4698
142
        proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee802159_mpx_transaction_control, ett_ieee802159_mpx_transaction_control,
4699
142
                               fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
4700
142
    }
4701
149
    offset += 1;
4702
4703
149
    switch (transfer_type) {  // cf. IEEE 802.15.9 Table 18 - Summary of different MPX IE formats
4704
103
        case IEEE802159_MPX_FULL_FRAME:
4705
103
            multiplex_id = tvb_get_letohs(tvb, offset);
4706
103
            proto_tree_add_uint_format_value(tree, hf_ieee802159_mpx_multiplex_id, tvb, offset, 2, multiplex_id, "%s (0x%04x)",
4707
103
                val_to_str_const(multiplex_id, (multiplex_id > 1500) ? etype_vals : mpx_multiplex_id_vals, "Unknown"), multiplex_id);
4708
103
            offset += 2;
4709
103
            break;
4710
7
        case IEEE802159_MPX_FULL_FRAME_NO_MUXID:
4711
7
            break;  // nothing to do
4712
5
        case IEEE802159_MPX_NON_LAST_FRAGMENT:
4713
5
            proto_tree_add_item_ret_uint8(tree, hf_ieee802159_mpx_fragment_number, tvb, offset, 1, ENC_LITTLE_ENDIAN, &fragment_number);
4714
5
            offset += 1;
4715
5
            if (fragment_number == 0) {
4716
3
                proto_tree_add_item(tree, hf_ieee802159_mpx_total_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4717
3
                offset += 2;
4718
3
                multiplex_id = tvb_get_letohs(tvb, offset);
4719
3
                proto_tree_add_item(tree, hf_ieee802159_mpx_multiplex_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4720
3
                offset += 2;
4721
3
            }
4722
5
            break;
4723
1
        case IEEE802159_MPX_LAST_FRAGMENT:
4724
1
            proto_tree_add_item(tree, hf_ieee802159_mpx_fragment_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4725
1
            offset += 1;
4726
1
            break;
4727
3
        case IEEE802159_MPX_ABORT:
4728
3
            if (tvb_reported_length_remaining(tvb, offset) == 2) {
4729
0
                proto_tree_add_item(tree, hf_ieee802159_mpx_total_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4730
0
                offset += 2;
4731
0
            }
4732
3
            return offset;
4733
3
        default:  // reserved values -> warning and return
4734
3
            expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_invalid_transfer_type);
4735
3
            return offset;
4736
149
    }
4737
4738
    // TODO: reassembly
4739
4740
115
    dissector_handle_t dissector = NULL;
4741
4742
115
    if (multiplex_id == IEEE802159_MPX_MULTIPLEX_ID_KMP) {
4743
2
        uint8_t kmp_id = tvb_get_uint8(tvb, offset);
4744
2
        proto_tree_add_item(tree, hf_ieee802159_mpx_kmp_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4745
2
        offset += 1;
4746
2
        switch (kmp_id) {
4747
1
            case IEEE802159_MPX_KMP_ID_IEEE8021X:
4748
1
            case IEEE802159_MPX_KMP_ID_IEEE80211_4WH:
4749
1
            case IEEE802159_MPX_KMP_ID_IEEE80211_GKH:
4750
1
                dissector = eapol_handle;
4751
1
                break;
4752
4753
            // TODO
4754
0
            case IEEE802159_MPX_KMP_ID_HIP:
4755
0
            case IEEE802159_MPX_KMP_ID_IKEV2:
4756
0
            case IEEE802159_MPX_KMP_ID_PANA:
4757
0
            case IEEE802159_MPX_KMP_ID_DRAGONFLY:
4758
0
            case IEEE802159_MPX_KMP_ID_ETSI_TS_102_887_2:
4759
0
                expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unsupported_kmp);
4760
0
                break;
4761
4762
0
            case IEEE802159_MPX_KMP_ID_VENDOR_SPECIFIC:
4763
0
                proto_tree_add_item(tree, hf_ieee802159_mpx_kmp_vendor_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
4764
0
                offset += 3;
4765
0
                break;
4766
4767
            // Unknown
4768
1
            default:
4769
1
                expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unknown_kmp);
4770
2
        }
4771
2
    }
4772
113
    else if (multiplex_id == IEEE802159_MPX_MULTIPLEX_ID_WISUN) {
4773
1
        uint8_t subid = tvb_get_uint8(tvb, offset);
4774
1
        proto_tree_add_item(tree, hf_ieee802159_mpx_wisun_subid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4775
1
        offset += 1;
4776
1
        switch (subid) {
4777
0
            case IEEE802159_MPX_WISUN_SUBID_6LOWPAN:
4778
0
                dissector = lowpan_handle;
4779
0
                break;
4780
4781
0
            case IEEE802159_MPX_WISUN_SUBID_SECURITY:
4782
0
                dissector = wisun_sec_handle;
4783
0
                break;
4784
4785
0
            case IEEE802159_MPX_WISUN_SUBID_MHDS:
4786
0
                expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unsupported_kmp);
4787
0
                break;
4788
4789
1
            default:
4790
1
                expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unknown_kmp);
4791
1
                break;
4792
1
        }
4793
1
    }
4794
112
    else if (multiplex_id > 1500) {
4795
94
        dissector = dissector_get_uint_handle(ethertype_table, (unsigned)multiplex_id);
4796
94
    }
4797
4798
115
    if (transfer_type == IEEE802159_MPX_FULL_FRAME || transfer_type == IEEE802159_MPX_FULL_FRAME_NO_MUXID) {
4799
110
        tvbuff_t * payload = tvb_new_subset_remaining(tvb, offset);
4800
110
        if (dissector) {
4801
1
            call_dissector(dissector, payload, pinfo, proto_tree_get_root(tree));  // exceptions are caught in our caller
4802
109
        } else {
4803
109
            call_data_dissector(payload, pinfo, proto_tree_get_root(tree));
4804
109
        }
4805
110
    } else {
4806
5
        proto_tree_add_item(tree, hf_ieee802159_mpx_fragment, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA);
4807
5
    }
4808
115
    offset = tvb_reported_length(tvb);
4809
4810
115
    return offset;
4811
115
}
4812
4813
/**
4814
 * Subdissector for Vendor Specific Payload IEs (Information Elements)
4815
 */
4816
static int
4817
dissect_pie_vendor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_)
4818
16
{
4819
16
    proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_pie_vendor, ett_ieee802154_pie_vendor);
4820
4821
16
    unsigned   offset = 2;
4822
16
    unsigned   pie_length = tvb_reported_length(tvb) - 2;
4823
16
    tvbuff_t  *next_tvb;
4824
16
    uint32_t   vendor_oui;
4825
4826
16
    vendor_oui = tvb_get_letoh24(tvb, offset);
4827
16
    proto_tree_add_item(tree, hf_ieee802154_pie_vendor_oui, tvb, offset, 3, ENC_LITTLE_ENDIAN);
4828
16
    offset += 3; /* adjust for vendor OUI */
4829
16
    pie_length -= 3;
4830
16
    next_tvb = tvb_new_subset_length(tvb, offset, pie_length);
4831
4832
16
    switch (vendor_oui) {
4833
0
        case OUI_ZIGBEE:
4834
0
            call_dissector_with_data(zigbee_ie_handle, next_tvb, pinfo, tree, &pie_length);
4835
0
            break;
4836
4837
14
        default:
4838
14
            call_data_dissector(next_tvb, pinfo, tree);
4839
14
            break;
4840
16
    }
4841
4842
14
    return tvb_reported_length(tvb);
4843
16
}
4844
4845
/**
4846
 * Subdissector for Payload IEs (Information Elements)
4847
 *
4848
 * @param tvb the tv buffer
4849
 * @param pinfo pointer to packet information fields.
4850
 * @param tree the tree to append this item to
4851
 * @param orig_offset offset into the tvbuff to begin dissection.
4852
 * @param packet IEEE 802.15.4 packet information.
4853
*/
4854
static int
4855
dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned orig_offset, ieee802154_packet *packet)
4856
275
{
4857
    // GCC emits a spurious -Wclobbered if offset is used as function parameter (even with volatile)
4858
275
    volatile unsigned offset = orig_offset;
4859
275
    proto_item *ies_item = proto_tree_add_item(tree, hf_ieee802154_payload_ies, tvb, offset, -1, ENC_NA);
4860
275
    proto_tree *ies_tree = proto_item_add_subtree(ies_item, ett_ieee802154_payload_ie);
4861
4862
1.30k
    do {
4863
1.30k
        volatile int consumed = 0;
4864
1.30k
        uint16_t ie_header = tvb_get_letohs(tvb, offset);
4865
1.30k
        uint16_t id = (uint16_t) ((ie_header & IEEE802154_PAYLOAD_IE_ID_MASK) >> 11);
4866
1.30k
        volatile uint16_t length = (uint16_t) (ie_header & IEEE802154_PAYLOAD_IE_LENGTH_MASK);
4867
1.30k
        tvbuff_t * volatile ie_tvb = tvb_new_subset_length(tvb, offset, 2 + length);
4868
4869
1.30k
        if (id == IEEE802154_PAYLOAD_IE_TERMINATION) {
4870
8
            ieee802154_create_pie_tree(ie_tvb, ies_tree, hf_ieee802154_pie_termination, ett_ieee802154_pie_termination);
4871
8
            consumed = 2;
4872
1.29k
        } else {
4873
1.29k
            TRY {
4874
1.29k
                consumed = dissector_try_uint_with_data(payload_ie_dissector_table, id, ie_tvb, pinfo, ies_tree, false, packet);
4875
1.29k
                if (consumed == 0) {
4876
807
                    proto_tree *subtree = ieee802154_create_pie_tree(ie_tvb, ies_tree, hf_ieee802154_pie_unsupported, ett_ieee802154_pie_unsupported);
4877
807
                    proto_tree_add_item(subtree, hf_ieee802154_ie_unknown_content_payload, ie_tvb, 2, length, ENC_NA);
4878
807
                    consumed = 2 + length;
4879
807
                    expert_add_info(pinfo, proto_tree_get_parent(subtree), &ei_ieee802154_ie_unsupported_id);
4880
807
                }
4881
1.29k
            }
4882
1.29k
            CATCH_ALL {
4883
127
                show_exception(tvb, pinfo, ies_tree, EXCEPT_CODE, GET_MESSAGE);
4884
127
                consumed = 2 + length;
4885
127
            }
4886
1.29k
            ENDTRY;
4887
1.29k
        }
4888
4889
1.30k
        if (consumed < 2 + length) {
4890
122
            proto_tree_add_item(ies_tree, hf_ieee802154_ie_unknown_content_payload, ie_tvb, consumed, 2 + length - consumed, ENC_NA);
4891
122
            expert_add_info(pinfo, ies_item, &ei_ieee802154_ie_unknown_extra_content_payload);
4892
122
        }
4893
4894
1.30k
        offset += 2 + length;
4895
4896
1.30k
        if (id == IEEE802154_PAYLOAD_IE_TERMINATION) {
4897
3
            break;
4898
3
        }
4899
1.30k
    } while (tvb_reported_length_remaining(tvb, offset) > 1);
4900
4901
275
    proto_item_set_len(ies_item, offset - orig_offset);
4902
275
    return offset - orig_offset;
4903
275
}
4904
4905
static const true_false_string tfs_cinfo_device_type = { "FFD", "RFD" };
4906
static const true_false_string tfs_cinfo_power_src = { "AC/Mains Power", "Battery" };
4907
4908
/**
4909
 * Command subdissector routine for the Association request command.
4910
 *
4911
 * @param tvb pointer to buffer containing raw packet.
4912
 * @param pinfo pointer to packet information fields.
4913
 * @param tree pointer to protocol tree.
4914
 * @param packet IEEE 802.15.4 packet information.
4915
 */
4916
4917
static void
4918
dissect_ieee802154_assoc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
4919
5
{
4920
5
    uint8_t cap;
4921
5
    proto_tree *subtree;
4922
5
    static int * const capability[] = {
4923
5
        &hf_ieee802154_cinfo_alt_coord,
4924
5
        &hf_ieee802154_cinfo_device_type,
4925
5
        &hf_ieee802154_cinfo_power_src,
4926
5
        &hf_ieee802154_cinfo_idle_rx,
4927
5
        &hf_ieee802154_cinfo_sec_capable,
4928
5
        &hf_ieee802154_cinfo_alloc_addr,
4929
5
        NULL
4930
5
    };
4931
4932
5
    cap = tvb_get_uint8(tvb, 0);
4933
5
    col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", tfs_get_string(cap & IEEE802154_CMD_CINFO_DEVICE_TYPE, &tfs_cinfo_device_type));
4934
4935
    /* Create a subtree for this command frame. */
4936
5
    subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL,
4937
5
                    val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
4938
4939
    /* Get and display capability info. */
4940
5
    proto_tree_add_bitmask_list(subtree, tvb, 0, 1, capability, ENC_NA);
4941
4942
    /* Call the data dissector for any leftover bytes. */
4943
5
    if (tvb_reported_length(tvb) > 1) {
4944
4
        call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree);
4945
4
    }
4946
5
} /* dissect_ieee802154_assoc_req */
4947
4948
/**
4949
 * Command subdissector routine for the Association response command.
4950
 *
4951
 * @param tvb pointer to buffer containing raw packet.
4952
 * @param pinfo pointer to packet information fields.
4953
 * @param tree pointer to protocol tree.
4954
 * @param packet IEEE 802.15.4 packet information.
4955
 */
4956
static void
4957
dissect_ieee802154_assoc_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
4958
7
{
4959
7
    proto_tree *subtree;
4960
7
    proto_item *ti;
4961
7
    uint16_t    short_addr;
4962
7
    uint8_t     status;
4963
7
    unsigned    offset  = 0;
4964
4965
    /* Create a subtree for this command frame. */
4966
7
    subtree = proto_tree_add_subtree(tree, tvb, offset, 3, ett_ieee802154_cmd, NULL,
4967
7
                    val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
4968
4969
    /* Get and display the short address. */
4970
7
    short_addr = tvb_get_letohs(tvb, offset);
4971
7
    proto_tree_add_uint(subtree, hf_ieee802154_assoc_addr, tvb, offset, 2, short_addr);
4972
7
    offset += 2;
4973
4974
    /* Get and display the status. */
4975
7
    status = tvb_get_uint8(tvb, offset);
4976
7
    if (tree) {
4977
6
        ti = proto_tree_add_uint(subtree, hf_ieee802154_assoc_status, tvb, offset, 1, status);
4978
6
        if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) proto_item_append_text(ti, " (Association Successful)");
4979
3
        else if (status == IEEE802154_CMD_ASRSP_PAN_FULL) proto_item_append_text(ti, " (PAN Full)");
4980
2
        else if (status == IEEE802154_CMD_ASRSP_PAN_DENIED) proto_item_append_text(ti, " (Association Denied)");
4981
1
        else proto_item_append_text(ti, " (Reserved)");
4982
6
    }
4983
7
    offset += 1;
4984
4985
    /* Update the info column. */
4986
7
    if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) {
4987
        /* Association was successful. */
4988
3
        if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) {
4989
2
            col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", packet->dst_pan);
4990
2
        }
4991
3
        if (short_addr != IEEE802154_NO_ADDR16) {
4992
3
            col_append_fstr(pinfo->cinfo, COL_INFO, " Addr: 0x%04x", short_addr);
4993
3
        }
4994
3
    }
4995
4
    else {
4996
        /* Association was unsuccessful. */
4997
4
        col_append_str(pinfo->cinfo, COL_INFO, ", Unsuccessful");
4998
4
    }
4999
5000
    /* Update the address table. */
5001
7
    if ((status == IEEE802154_CMD_ASRSP_AS_SUCCESS) && (short_addr != IEEE802154_NO_ADDR16)) {
5002
3
        ieee802154_addr_update(&ieee802154_map, short_addr, packet->dst_pan, packet->dst64,
5003
3
                pinfo->current_proto, pinfo->num);
5004
3
    }
5005
5006
    /* Call the data dissector for any leftover bytes. */
5007
7
    if (tvb_captured_length(tvb) > offset) {
5008
6
        call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
5009
6
    }
5010
7
} /* dissect_ieee802154_assoc_rsp */
5011
5012
/**
5013
 * Command subdissector routine for the Disassociate command.
5014
 *
5015
 * @param tvb pointer to buffer containing raw packet.
5016
 * @param pinfo pointer to packet information fields.
5017
 * @param tree pointer to protocol tree.
5018
 * @param packet IEEE 802.15.4 packet information.
5019
 */
5020
static void
5021
dissect_ieee802154_disassoc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
5022
3
{
5023
3
    proto_tree *subtree;
5024
3
    proto_item *ti;
5025
3
    uint8_t     reason;
5026
5027
    /* Create a subtree for this command frame. */
5028
3
    subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL,
5029
3
                    val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
5030
5031
    /* Get and display the disassociation reason. */
5032
3
    reason = tvb_get_uint8(tvb, 0);
5033
3
    if (tree) {
5034
3
        ti = proto_tree_add_uint(subtree, hf_ieee802154_disassoc_reason, tvb, 0, 1, reason);
5035
3
        switch (reason) {
5036
0
            case 0x01:
5037
0
                proto_item_append_text(ti, " (Coordinator requests device to leave)");
5038
0
                break;
5039
5040
0
            case 0x02:
5041
0
                proto_item_append_text(ti, " (Device wishes to leave)");
5042
0
                break;
5043
5044
3
            default:
5045
3
                proto_item_append_text(ti, " (Reserved)");
5046
3
                break;
5047
3
        } /* switch */
5048
3
    }
5049
5050
3
    if (!PINFO_FD_VISITED(pinfo)) {
5051
        /* Update the address tables */
5052
3
        if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT ) {
5053
0
            ieee802154_long_addr_invalidate(packet->dst64, pinfo->num);
5054
3
        } else if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT ) {
5055
2
            ieee802154_short_addr_invalidate(packet->dst16, packet->dst_pan, pinfo->num);
5056
2
        }
5057
3
    }
5058
5059
    /* Call the data dissector for any leftover bytes. */
5060
3
    if (tvb_captured_length(tvb) > 1) {
5061
3
        call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree);
5062
3
    }
5063
3
} /* dissect_ieee802154_disassoc */
5064
5065
/**
5066
 * Command subdissector routine for the Coordinator Realignment command.
5067
 *
5068
 * @param tvb pointer to buffer containing raw packet.
5069
 * @param pinfo pointer to packet information fields.
5070
 * @param tree pointer to protocol tree.
5071
 * @param packet IEEE 802.15.4 packet information.
5072
 */
5073
static void
5074
dissect_ieee802154_realign(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
5075
2
{
5076
2
    proto_tree *subtree;
5077
2
    proto_item *subitem;
5078
2
    uint16_t    pan_id;
5079
2
    uint16_t    coord_addr;
5080
2
    uint8_t     channel;
5081
2
    uint16_t    short_addr;
5082
2
    unsigned    offset  = 0;
5083
5084
    /* Create a subtree for this command frame. */
5085
2
    subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_ieee802154_cmd, &subitem,
5086
2
                val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
5087
5088
    /* Get and display the command PAN ID. */
5089
2
    pan_id = tvb_get_letohs(tvb, offset);
5090
2
    proto_tree_add_uint(subtree, hf_ieee802154_realign_pan, tvb, offset, 2, pan_id);
5091
2
    col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", pan_id);
5092
2
    offset += 2;
5093
5094
    /* Get and display the coordinator address. */
5095
2
    coord_addr = tvb_get_letohs(tvb, offset);
5096
2
    proto_tree_add_uint(subtree, hf_ieee802154_realign_caddr, tvb, offset, 2, coord_addr);
5097
2
    col_append_fstr(pinfo->cinfo, COL_INFO, ", Coordinator: 0x%04x", coord_addr);
5098
2
    offset += 2;
5099
5100
    /* Get and display the channel. */
5101
2
    channel = tvb_get_uint8(tvb, offset);
5102
2
    proto_tree_add_uint(subtree, hf_ieee802154_realign_channel, tvb, offset, 1, channel);
5103
2
    col_append_fstr(pinfo->cinfo, COL_INFO, ", Channel: %u", channel);
5104
2
    offset += 1;
5105
5106
    /* Get and display the short address. */
5107
2
    short_addr = tvb_get_letohs(tvb, offset);
5108
2
    if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_addr, tvb, offset, 2, short_addr);
5109
2
    if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)
5110
1
        && (short_addr != IEEE802154_NO_ADDR16)) {
5111
1
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Addr: 0x%04x", short_addr);
5112
1
    }
5113
2
    offset += 2;
5114
    /* Update the address table. */
5115
2
    if ((short_addr != IEEE802154_NO_ADDR16) && (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) {
5116
1
        ieee802154_addr_update(&ieee802154_map, short_addr, packet->dst_pan, packet->dst64,
5117
1
                pinfo->current_proto, pinfo->num);
5118
1
    }
5119
5120
    /* Get and display the channel page, if it exists. Added in IEEE802.15.4-2006 */
5121
2
    if (tvb_bytes_exist(tvb, offset, 1)) {
5122
2
        uint8_t channel_page = tvb_get_uint8(tvb, offset);
5123
2
        if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_channel_page, tvb, offset, 1, channel_page);
5124
2
        offset += 1;
5125
2
    }
5126
5127
    /* Fix the length of the command subtree. */
5128
2
    if (tree) {
5129
2
        proto_item_set_len(subitem, offset);
5130
2
    }
5131
5132
    /* Call the data dissector for any leftover bytes. */
5133
2
    if (tvb_captured_length(tvb) > offset) {
5134
2
        call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
5135
2
    }
5136
2
} /* dissect_ieee802154_realign */
5137
5138
static const true_false_string tfs_gtsreq_dir = { "Receive", "Transmit" };
5139
static const true_false_string tfs_gtsreq_type= { "Allocate GTS", "Deallocate GTS" };
5140
5141
/**
5142
 * Command subdissector routine for the GTS request command.
5143
 *
5144
 * Assumes that COL_INFO will be set to the command name,
5145
 * command name will already be appended to the command subtree
5146
 * and protocol root. In addition, assumes that the command ID
5147
 * has already been parsed.
5148
 *
5149
 * @param tvb pointer to buffer containing raw packet.
5150
 * @param pinfo pointer to packet information fields (unused).
5151
 * @param tree pointer to protocol tree.
5152
 * @param packet IEEE 802.15.4 packet information (unused).
5153
 */
5154
5155
static void
5156
dissect_ieee802154_gtsreq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
5157
2
{
5158
2
    proto_tree *subtree;
5159
2
    static int * const characteristics[] = {
5160
2
        &hf_ieee802154_gtsreq_len,
5161
2
        &hf_ieee802154_gtsreq_dir,
5162
2
        &hf_ieee802154_gtsreq_type,
5163
2
        NULL
5164
2
    };
5165
5166
    /* Create a subtree for this command frame. */
5167
2
    subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL,
5168
2
                val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
5169
5170
2
    proto_tree_add_bitmask_list(subtree, tvb, 0, 1, characteristics, ENC_NA);
5171
5172
    /* Call the data dissector for any leftover bytes. */
5173
2
    if (tvb_reported_length(tvb) > 1) {
5174
2
        call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree);
5175
2
    }
5176
2
} /* dissect_ieee802154_gtsreq */
5177
5178
/**
5179
 * Subdissector routine for IEEE 802.15.4 commands
5180
 *
5181
 * @param tvb pointer to buffer containing the command payload
5182
 * @param pinfo pointer to packet information fields
5183
 * @param tree pointer to the protocol tree
5184
 * @param packet IEEE 802.15.4 packet information
5185
 */
5186
static void
5187
dissect_ieee802154_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
5188
43
{
5189
43
    if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_CMD)) {
5190
        /* In 802.15.4e and later the Command Id follows the Payload IEs. */
5191
12
        packet->command_id = tvb_get_uint8(tvb, 0);
5192
12
        proto_tree_add_uint(tree, hf_ieee802154_cmd_id, tvb, 0, 1, packet->command_id);
5193
12
        tvb = tvb_new_subset_remaining(tvb, 1);
5194
5195
        /* Display the command identifier in the info column. */
5196
12
        if ((packet->version == IEEE802154_VERSION_2015) && (packet->command_id == IEEE802154_CMD_BEACON_REQ)) {
5197
1
            col_set_str(pinfo->cinfo, COL_INFO, "Enhanced Beacon Request");
5198
1
        }
5199
11
        else {
5200
11
            col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
5201
11
        }
5202
12
    }
5203
5204
43
    switch (packet->command_id) {
5205
5
    case IEEE802154_CMD_ASSOC_REQ:
5206
5
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5207
5
            (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
5208
5
            (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE));
5209
5
        dissect_ieee802154_assoc_req(tvb, pinfo, tree, packet);
5210
5
        break;
5211
5212
7
    case IEEE802154_CMD_ASSOC_RSP:
5213
7
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5214
7
            (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
5215
7
            (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
5216
7
        dissect_ieee802154_assoc_rsp(tvb, pinfo, tree, packet);
5217
7
        break;
5218
5219
3
    case IEEE802154_CMD_DISASSOC_NOTIFY:
5220
3
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5221
3
            (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
5222
3
            (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
5223
3
        dissect_ieee802154_disassoc(tvb, pinfo, tree, packet);
5224
3
        break;
5225
5226
2
    case IEEE802154_CMD_DATA_RQ:
5227
2
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE);
5228
        /* No payload expected. */
5229
2
        break;
5230
5231
0
    case IEEE802154_CMD_PANID_CONFLICT:
5232
0
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5233
0
            (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
5234
0
            (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
5235
        /* No payload expected. */
5236
0
        break;
5237
5238
2
    case IEEE802154_CMD_ORPHAN_NOTIFY:
5239
2
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5240
2
            (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
5241
2
            (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
5242
2
            (packet->dst16 == IEEE802154_BCAST_ADDR) &&
5243
2
            (packet->src_pan == IEEE802154_BCAST_PAN) &&
5244
2
            (packet->dst_pan == IEEE802154_BCAST_PAN));
5245
        /* No payload expected. */
5246
2
        break;
5247
5248
2
    case IEEE802154_CMD_BEACON_REQ:
5249
2
        if ((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006)) {
5250
1
            IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5251
1
                    (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
5252
1
                    (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) &&
5253
1
                    (packet->dst16 == IEEE802154_BCAST_ADDR) &&
5254
1
                    (packet->dst_pan == IEEE802154_BCAST_PAN));
5255
1
        }
5256
        /* No payload expected. */
5257
2
        break;
5258
5259
2
    case IEEE802154_CMD_COORD_REALIGN:
5260
2
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5261
2
            (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
5262
2
            (packet->dst_pan == IEEE802154_BCAST_PAN) &&
5263
2
            (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE));
5264
2
        if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
5265
            /* If directed to a 16-bit address, check that it is being broadcast. */
5266
1
            IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, packet->dst16 == IEEE802154_BCAST_ADDR);
5267
1
        }
5268
2
        dissect_ieee802154_realign(tvb, pinfo, tree, packet);
5269
2
        break;
5270
5271
2
    case IEEE802154_CMD_GTS_REQ:
5272
        /* Check that the addressing is correct for this command type. */
5273
2
        IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
5274
2
            (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
5275
2
            (packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&
5276
2
            (packet->src16 != IEEE802154_BCAST_ADDR) &&
5277
2
            (packet->src16 != IEEE802154_NO_ADDR16));
5278
2
        dissect_ieee802154_gtsreq(tvb, pinfo, tree, packet);
5279
2
        break;
5280
5281
2
    case IEEE802154_CMD_VENDOR_SPECIFIC:
5282
2
    {
5283
2
        uint32_t oui = tvb_get_letoh24(tvb, 0);
5284
2
        proto_tree_add_item(tree, hf_ieee802154_cmd_vendor_oui, tvb, 0, 3, ENC_LITTLE_ENDIAN);
5285
2
        if (!dissector_try_uint_with_data(cmd_vendor_dissector_table, oui, tvb_new_subset_remaining(tvb, 3), pinfo, tree, false, packet)) {
5286
2
            call_data_dissector(tvb_new_subset_remaining(tvb, 3), pinfo, tree);
5287
2
        }
5288
2
        break;
5289
0
    }
5290
5291
2
    case IEEE802154_CMD_TRLE_MGMT_REQ:
5292
3
    case IEEE802154_CMD_TRLE_MGMT_RSP:
5293
4
    case IEEE802154_CMD_DSME_ASSOC_REQ:
5294
5
    case IEEE802154_CMD_DSME_ASSOC_RSP:
5295
6
    case IEEE802154_CMD_DSME_GTS_REQ:
5296
6
    case IEEE802154_CMD_DSME_GTS_RSP:
5297
6
    case IEEE802154_CMD_DSME_GTS_NOTIFY:
5298
6
    case IEEE802154_CMD_DSME_INFO_REQ:
5299
7
    case IEEE802154_CMD_DSME_INFO_RSP:
5300
7
    case IEEE802154_CMD_DSME_BEACON_ALLOC_NOTIFY:
5301
7
    case IEEE802154_CMD_DSME_BEACON_COLL_NOTIFY:
5302
7
    case IEEE802154_CMD_DSME_LINK_REPORT:
5303
7
    case IEEE802154_CMD_RIT_DATA_REQ:
5304
9
    case IEEE802154_CMD_DBS_REQ:
5305
9
    case IEEE802154_CMD_DBS_RSP:
5306
9
    case IEEE802154_CMD_RIT_DATA_RSP:
5307
        /* TODO add support for these commands, for now if anything remains, dump it */
5308
9
        expert_add_info(pinfo, tree, &ei_ieee802154_unsupported_cmd);
5309
9
        if (tvb_captured_length_remaining(tvb, 0) > 0) {
5310
8
            call_data_dissector(tvb, pinfo, tree);
5311
8
        }
5312
9
        break;
5313
6
    default:
5314
6
        expert_add_info(pinfo, tree, &ei_ieee802154_unknown_cmd);
5315
6
        if (tvb_captured_length_remaining(tvb, 0) > 0) {
5316
4
            call_data_dissector(tvb, pinfo, tree);
5317
4
        }
5318
43
    } /* switch */
5319
43
} /* dissect_ieee802154_command */
5320
5321
/**
5322
 * IEEE 802.15.4 decryption algorithm
5323
 * @param tvb IEEE 802.15.4 packet, not including the FCS or metadata trailer.
5324
 * @param pinfo Packet info structure.
5325
 * @param offset Offset where the ciphertext 'c' starts.
5326
 * @param packet IEEE 802.15.4 packet information.
5327
 * @return decrypted payload.
5328
 */
5329
static tvbuff_t *
5330
dissect_ieee802154_decrypt(tvbuff_t *tvb,
5331
                           unsigned offset,
5332
                           packet_info *pinfo,
5333
                           ieee802154_packet *packet,
5334
                           ieee802154_decrypt_info_t* decrypt_info,
5335
                           unsigned char *key)
5336
0
{
5337
0
    tvbuff_t           *ptext_tvb;
5338
0
    bool                have_mic = false;
5339
0
    uint64_t            srcAddr = 0;
5340
0
    unsigned char       tmp[IEEE802154_CIPHER_SIZE];
5341
0
    unsigned            M;
5342
0
    int                 captured_len;
5343
0
    int                 reported_len;
5344
0
    ieee802154_hints_t *ieee_hints;
5345
0
    uint8_t            *generic_nonce_ptr = NULL;
5346
0
    uint8_t             generic_nonce[13];
5347
5348
0
    ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0);
5349
5350
    /* Get the captured and on-the-air length of the payload. */
5351
0
    M = IEEE802154_MIC_LENGTH(packet->security_level);
5352
0
    *decrypt_info->rx_mic_length = M;
5353
5354
    /* Is the MIC larger than the total amount of data? */
5355
0
    reported_len = tvb_reported_length_remaining(tvb, offset) - M;
5356
0
    if (reported_len < 0) {
5357
        /* Yes.  Give up. */
5358
0
        *decrypt_info->status = DECRYPT_PACKET_TOO_SMALL;
5359
0
        return NULL;
5360
0
    }
5361
    /* Check whether the payload is truncated by a snapshot length. */
5362
0
    if (tvb_bytes_exist(tvb, offset, reported_len)) {
5363
        /* It's not, so we have all of the payload. */
5364
0
        captured_len = reported_len;
5365
0
    }
5366
0
    else {
5367
        /*
5368
         * It is, so we don't have all of the payload - and we don't
5369
         * have the MIC, either, as that comes after the payload.
5370
         * As the MIC isn't part of the captured data - the captured
5371
         * data was cut short before the first byte of the MIC - we
5372
         * don't subtract the length of the MIC from the amount of
5373
         * captured data.
5374
         */
5375
0
        captured_len = tvb_captured_length_remaining(tvb, offset);
5376
0
    }
5377
5378
    /* Check if the MIC is present in the captured data. */
5379
0
    have_mic = tvb_bytes_exist(tvb, offset + reported_len, M);
5380
0
    if (have_mic) {
5381
        /* It is - save a copy of it. */
5382
0
        tvb_memcpy(tvb, decrypt_info->rx_mic, offset + reported_len, M);
5383
0
    }
5384
5385
    /* We need the extended source address. */
5386
0
    if ((packet->key_index == IEEE802154_THR_WELL_KNOWN_KEY_INDEX) &&
5387
0
        (packet->key_source.addr32 == IEEE802154_THR_WELL_KNOWN_KEY_SRC))
5388
0
    {
5389
        /* Use the well-known extended address */
5390
0
        srcAddr = IEEE802154_THR_WELL_KNOWN_EXT_ADDR;
5391
0
    } else {
5392
0
        if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
5393
            /* The source EUI-64 is included in the headers. */
5394
0
            srcAddr = packet->src64;
5395
0
        }
5396
0
        else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT && packet->frame_counter_suppression) {
5397
            /* In TSCH mode, the source address is a combination of 802.15 CID, PAN ID and Short Address */
5398
0
            srcAddr = IEEE80215_CID << 40;
5399
0
            srcAddr |= ((uint64_t)packet->src_pan & 0xffff) << 16;
5400
0
            srcAddr |= packet->src16;
5401
0
        }
5402
0
        else if (ieee_hints && ieee_hints->map_rec && ieee_hints->map_rec->addr64) {
5403
            /* Use the hint */
5404
0
            srcAddr = ieee_hints->map_rec->addr64;
5405
0
        }
5406
0
        else {
5407
            /* Lookup failed.  */
5408
0
            *decrypt_info->status = DECRYPT_PACKET_NO_EXT_SRC_ADDR;
5409
0
            return NULL;
5410
0
        }
5411
0
    }
5412
5413
    /*
5414
     * CCM* - CTR mode payload encryption
5415
     *
5416
     */
5417
    /* 802.15.4-2015 TSCH mode */
5418
0
    if (packet->frame_counter_suppression) {
5419
0
        tsch_ccm_init_nonce(srcAddr, packet->asn, generic_nonce);
5420
0
        generic_nonce_ptr = generic_nonce;
5421
0
    }
5422
5423
    /* Create the CCM* initial block for decryption (Adata=0, M=0, counter=0). */
5424
0
    if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003))
5425
0
        ccm_init_block(tmp, false, 0, srcAddr, packet->frame_counter, packet->key_sequence_counter, 0, NULL);
5426
0
    else
5427
0
        ccm_init_block(tmp, false, 0, srcAddr, packet->frame_counter, packet->security_level, 0, generic_nonce_ptr);
5428
5429
    /*
5430
     * If the payload is encrypted, so that it's the ciphertext, and we
5431
     * have at least one byte of it in the captured data, decrypt the
5432
     * ciphertext, and place the plaintext in a new tvb.
5433
     */
5434
0
    if (IEEE802154_IS_ENCRYPTED(packet->security_level) && captured_len) {
5435
0
        uint8_t *text;
5436
        /*
5437
         * Make a copy of the ciphertext in heap memory.
5438
         *
5439
         * We will decrypt the message in-place and then use the buffer as the
5440
         * real data for the new tvb.
5441
         */
5442
0
        text = (uint8_t *)tvb_memdup(pinfo->pool, tvb, offset, captured_len);
5443
5444
        /* Perform CTR-mode transformation. */
5445
0
        if (!ccm_ctr_encrypt(key, tmp, decrypt_info->rx_mic, text, captured_len)) {
5446
0
            wmem_free(pinfo->pool, text);
5447
0
            *decrypt_info->status = DECRYPT_PACKET_DECRYPT_FAILED;
5448
0
            return NULL;
5449
0
        }
5450
5451
        /* Create a tvbuff for the plaintext. */
5452
0
        ptext_tvb = tvb_new_child_real_data(tvb, text, captured_len, reported_len);
5453
0
        add_new_data_source(pinfo, ptext_tvb, "Decrypted IEEE 802.15.4 payload");
5454
0
        *decrypt_info->status = DECRYPT_PACKET_SUCCEEDED;
5455
0
    }
5456
0
    else {
5457
        /*
5458
         * Either the payload isn't encrypted or we don't have any of it
5459
         * in the captured data.
5460
         */
5461
        /* Decrypt the MIC (if present). */
5462
0
        if ((have_mic) && (!ccm_ctr_encrypt(key, tmp, decrypt_info->rx_mic, NULL, 0))) {
5463
0
            *decrypt_info->status = DECRYPT_PACKET_DECRYPT_FAILED;
5464
0
            return NULL;
5465
0
        }
5466
5467
        /* Create a tvbuff for the plaintext. This might result in a zero-length tvbuff. */
5468
0
        ptext_tvb = tvb_new_subset_length(tvb, offset, reported_len);
5469
0
        *decrypt_info->status = DECRYPT_PACKET_SUCCEEDED;
5470
0
    }
5471
5472
    /*
5473
     * CCM* - CBC-mode message authentication
5474
     *
5475
     */
5476
    /* We can only verify the message if the MIC wasn't truncated. */
5477
0
    if (have_mic) {
5478
0
        unsigned char           dec_mic[16];
5479
0
        unsigned                l_m = captured_len;
5480
0
        unsigned                l_a = offset;
5481
5482
        /* Adjust the lengths of the plaintext and additional data if unencrypted. */
5483
0
        if (!IEEE802154_IS_ENCRYPTED(packet->security_level)) {
5484
0
            l_a += l_m;
5485
0
            l_m = 0;
5486
0
        }
5487
0
        else if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003) && !ieee802154_extend_auth)
5488
0
            l_a -= 5;   /* Exclude Frame Counter (4 bytes) and Key Sequence Counter (1 byte) from authentication data */
5489
5490
5491
        /* Create the CCM* initial block for authentication (Adata!=0, M!=0, counter=l(m)). */
5492
0
        if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003))
5493
0
            ccm_init_block(tmp, true, M, srcAddr, packet->frame_counter, packet->key_sequence_counter, l_m, NULL);
5494
0
        else
5495
0
            ccm_init_block(tmp, true, M, srcAddr, packet->frame_counter, packet->security_level, l_m, generic_nonce_ptr);
5496
5497
        /* Compute CBC-MAC authentication tag. */
5498
        /*
5499
         * And yes, despite the warning in tvbuff.h, I think tvb_get_ptr is the
5500
         * right function here since either A) the payload wasn't encrypted, in
5501
         * which case l_m is zero, or B) the payload was encrypted, and the tvb
5502
         * already points to contiguous memory, since we just allocated it in
5503
         * decryption phase.
5504
         */
5505
0
        memset(dec_mic, 0, sizeof(dec_mic));
5506
0
        if (!ccm_cbc_mac(key, tmp, tvb_memdup(pinfo->pool, tvb, 0, l_a), l_a, tvb_get_ptr(ptext_tvb, 0, l_m), l_m, dec_mic)) {
5507
0
            *decrypt_info->status = DECRYPT_PACKET_MIC_CHECK_FAILED;
5508
0
        }
5509
        /* Compare the received MIC with the one we generated. */
5510
0
        else if (memcmp(decrypt_info->rx_mic, dec_mic, M) != 0) {
5511
0
            *decrypt_info->status = DECRYPT_PACKET_MIC_CHECK_FAILED;
5512
0
        }
5513
0
    }
5514
5515
    /* Done! */
5516
0
    return ptext_tvb;
5517
0
} /* dissect_ieee802154_decrypt */
5518
5519
/**
5520
 * Creates the CCM* initial block value for IEEE 802.15.4.
5521
 *
5522
 * @param block Output pointer for the initial block.
5523
 * @param adata true if additional auth data is present
5524
 * @param M CCM* parameter M.
5525
 * @param addr Source extended address.
5526
 * @param frame_counter Packet frame counter
5527
 * @param level Security level or key_sequence_counter for 802.15.4-2003
5528
 * @param ctr_val Value in the last L bytes of the block.
5529
 * @param generic_nonce 13-byte nonce to be set by non 802.15.4 calls. If set addr, frame_counter and level are ignored.
5530
 */
5531
void
5532
ccm_init_block(uint8_t *block, bool adata, int M, uint64_t addr, uint32_t frame_counter, uint8_t level, int ctr_val, const uint8_t *generic_nonce)
5533
0
{
5534
0
    int                 i = 0;
5535
5536
    /* Flags: Reserved(0) || Adata || (M-2)/2 || (L-1) */
5537
0
    block[i] = (0x2 - 1); /* (L-1) */
5538
0
    if (M > 0) block[i] |= (((M-2)/2) << 3); /* (M-2)/2 */
5539
0
    if (adata) block[i] |= (1 << 6); /* Adata */
5540
0
    i++;
5541
0
    if (generic_nonce == NULL) {
5542
        /* 2003 CCM Nonce:  Source Address || Frame Counter || Key Sequence Counter */
5543
        /* 2006 CCM* Nonce: Source Address || Frame Counter || Security Level */
5544
0
        block[i++] = (uint8_t)((addr >> 56) & 0xff);
5545
0
        block[i++] = (uint8_t)((addr >> 48) & 0xff);
5546
0
        block[i++] = (uint8_t)((addr >> 40) & 0xff);
5547
0
        block[i++] = (uint8_t)((addr >> 32) & 0xff);
5548
0
        block[i++] = (uint8_t)((addr >> 24) & 0xff);
5549
0
        block[i++] = (uint8_t)((addr >> 16) & 0xff);
5550
0
        block[i++] = (uint8_t)((addr >> 8) & 0xff);
5551
0
        block[i++] = (uint8_t)((addr >> 0) & 0xff);
5552
0
        block[i++] = (uint8_t)((frame_counter >> 24) & 0xff);
5553
0
        block[i++] = (uint8_t)((frame_counter >> 16) & 0xff);
5554
0
        block[i++] = (uint8_t)((frame_counter >> 8) & 0xff);
5555
0
        block[i++] = (uint8_t)((frame_counter >> 0) & 0xff);
5556
0
        block[i++] = level;
5557
0
    } else {
5558
0
        memcpy(&block[i], generic_nonce, 13);
5559
0
        i += 13;
5560
0
    }
5561
    /* Plaintext length. */
5562
0
    block[i++] = (uint8_t)((ctr_val >> 8) & 0xff);
5563
0
    block[i] = (uint8_t)((ctr_val >> 0) & 0xff);
5564
0
} /* ccm_init_block */
5565
5566
/**
5567
 * Creates the IEEE 802.15.4 TSCH nonce.
5568
 *
5569
 * @param addr Source extended address.
5570
 * @param asn TSCH Absolute Slot Number
5571
 * @param generic_nonce 13-byte nonce to returned by this function.
5572
 */
5573
static void
5574
tsch_ccm_init_nonce(uint64_t addr, uint64_t asn, uint8_t* generic_nonce)
5575
0
{
5576
0
    int i = 0;
5577
5578
    /* 2015 CCM* Nonce: Source Address || ASN */
5579
0
    generic_nonce[i++] = (uint8_t)((addr >> 56) & 0xff);
5580
0
    generic_nonce[i++] = (uint8_t)((addr >> 48) & 0xff);
5581
0
    generic_nonce[i++] = (uint8_t)((addr >> 40) & 0xff);
5582
0
    generic_nonce[i++] = (uint8_t)((addr >> 32) & 0xff);
5583
0
    generic_nonce[i++] = (uint8_t)((addr >> 24) & 0xff);
5584
0
    generic_nonce[i++] = (uint8_t)((addr >> 16) & 0xff);
5585
0
    generic_nonce[i++] = (uint8_t)((addr >> 8) & 0xff);
5586
0
    generic_nonce[i++] = (uint8_t)((addr >> 0) & 0xff);
5587
0
    generic_nonce[i++] = (uint8_t)((asn >> 32) & 0xff);
5588
0
    generic_nonce[i++] = (uint8_t)((asn >> 24) & 0xff);
5589
0
    generic_nonce[i++] = (uint8_t)((asn >> 16) & 0xff);
5590
0
    generic_nonce[i++] = (uint8_t)((asn >> 8) & 0xff);
5591
0
    generic_nonce[i++] = (uint8_t)((asn >> 0) & 0xff);
5592
0
} /* tsch_ccm_init_nonce */
5593
5594
/**
5595
 * Perform an in-place CTR-mode encryption/decryption.
5596
 *
5597
 * @param key Encryption Key.
5598
 * @param iv Counter initial value.
5599
 * @param mic MIC to encrypt/decrypt.
5600
 * @param data Buffer to encrypt/decrypt.
5601
 * @param length Length of the buffer.
5602
 * @return true on SUCCESS, false on error.
5603
 */
5604
bool
5605
ccm_ctr_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *mic, uint8_t *data, int length)
5606
0
{
5607
0
    gcry_cipher_hd_t    cipher_hd;
5608
5609
    /* Open the cipher. */
5610
0
    if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0)) {
5611
0
        return false;
5612
0
    }
5613
5614
    /* Set the key and initial value. */
5615
0
    if (gcry_cipher_setkey(cipher_hd, key, 16)) {
5616
0
        gcry_cipher_close(cipher_hd);
5617
0
        return false;
5618
0
    }
5619
0
    if (gcry_cipher_setctr(cipher_hd, iv, 16)) {
5620
0
        gcry_cipher_close(cipher_hd);
5621
0
        return false;
5622
0
    }
5623
5624
    /* Decrypt the MIC. */
5625
0
    if (gcry_cipher_encrypt(cipher_hd, mic, 16, NULL, 0)) {
5626
0
        gcry_cipher_close(cipher_hd);
5627
0
        return false;
5628
0
    }
5629
    /* Decrypt the payload. */
5630
0
    if (gcry_cipher_encrypt(cipher_hd, data, length, NULL, 0)) {
5631
0
        gcry_cipher_close(cipher_hd);
5632
0
        return false;
5633
0
    }
5634
5635
    /* Done with the cipher. */
5636
0
    gcry_cipher_close(cipher_hd);
5637
0
    return true;
5638
0
} /* ccm_ctr_encrypt */
5639
5640
/**
5641
 * Generate a CBC-MAC of the decrypted payload and additional authentication headers.
5642
 * @param key Encryption Key.
5643
 * @param iv Counter initial value.
5644
 * @param a Additional auth headers.
5645
 * @param a_len Length of the additional headers.
5646
 * @param m Plaintext message.
5647
 * @param m_len Length of plaintext message.
5648
 * @param mic Output for CBC-MAC.
5649
 * @return  true on SUCCESS, false on error.
5650
 */
5651
bool
5652
ccm_cbc_mac(const uint8_t *key, const uint8_t *iv, const uint8_t *a, int a_len, const uint8_t *m, int m_len, uint8_t *mic)
5653
0
{
5654
0
    gcry_cipher_hd_t cipher_hd;
5655
0
    unsigned         i = 0;
5656
0
    unsigned char    block[IEEE802154_CIPHER_SIZE];
5657
5658
    /* Open the cipher. */
5659
0
    if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC)) return false;
5660
5661
    /* Set the key. */
5662
0
    if (gcry_cipher_setkey(cipher_hd, key, IEEE802154_CIPHER_SIZE)) {
5663
0
        gcry_cipher_close(cipher_hd);
5664
0
        return false;
5665
0
    }
5666
5667
    /* Process the initial value. */
5668
0
    if (gcry_cipher_encrypt(cipher_hd, mic, 16, iv, 16)) {
5669
0
        gcry_cipher_close(cipher_hd);
5670
0
        return false;
5671
0
    }
5672
5673
    /* Encode L(a) */
5674
0
    i = 0;
5675
5676
/* XXX: GINT_MAX is not defined so #if ... will always be false */
5677
#if (GINT_MAX >= (1LL << 32))
5678
    if (a_len >= (1LL << 32)) {
5679
        block[i++] = 0xff;
5680
        block[i++] = 0xff;
5681
        block[i++] = (a_len >> 56) & 0xff;
5682
        block[i++] = (a_len >> 48) & 0xff;
5683
        block[i++] = (a_len >> 40) & 0xff;
5684
        block[i++] = (a_len >> 32) & 0xff;
5685
        block[i++] = (a_len >> 24) & 0xff;
5686
        block[i++] = (a_len >> 16) & 0xff;
5687
        block[i++] = (a_len >> 8) & 0xff;
5688
        block[i++] = (a_len >> 0) & 0xff;
5689
    }
5690
    else
5691
#endif
5692
0
    if (a_len >= ((1 << 16) - (1 << 8))) {
5693
0
        block[i++] = 0xff;
5694
0
        block[i++] = 0xfe;
5695
0
        block[i++] = (a_len >> 24) & 0xff;
5696
0
        block[i++] = (a_len >> 16) & 0xff;
5697
0
        block[i++] = (a_len >> 8) & 0xff;
5698
0
        block[i++] = (a_len >> 0) & 0xff;
5699
0
    }
5700
0
    else {
5701
0
        block[i++] = (a_len >> 8) & 0xff;
5702
0
        block[i++] = (a_len >> 0) & 0xff;
5703
0
    }
5704
    /* Append a to get the first block of input (pad if we encounter the end of a). */
5705
0
    while ((i < sizeof(block)) && (a_len > 0)) {
5706
0
        block[i++] = *a++;
5707
0
        a_len--;
5708
0
    }
5709
0
    while (i < sizeof(block)) {
5710
0
        block[i++] = 0;
5711
0
    }
5712
5713
    /* Process the first block of AuthData. */
5714
0
    if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, 16)) {
5715
0
        gcry_cipher_close(cipher_hd);
5716
0
        return false;
5717
0
    }
5718
5719
    /* Transform and process the remainder of a. */
5720
0
    while (a_len > 0) {
5721
        /* Copy and pad. */
5722
0
        if ((unsigned)a_len >= sizeof(block)) {
5723
0
            memcpy(block, a, sizeof(block));
5724
0
        }
5725
0
        else {
5726
0
            memcpy(block, a, a_len);
5727
0
            memset(&block[a_len], 0, sizeof(block)-a_len);
5728
0
        }
5729
        /* Adjust pointers. */
5730
0
        a += sizeof(block);
5731
0
        a_len -= (int)sizeof(block);
5732
        /* Execute the CBC-MAC algorithm. */
5733
0
        if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, sizeof(block))) {
5734
0
            gcry_cipher_close(cipher_hd);
5735
0
            return false;
5736
0
        }
5737
0
    } /* while */
5738
5739
    /* Process the message, m. */
5740
0
    while (m_len > 0) {
5741
        /* Copy and pad. */
5742
0
        if ((unsigned)m_len >= sizeof(block)) {
5743
0
            memcpy(block, m, sizeof(block));
5744
0
        }
5745
0
        else {
5746
0
            memcpy(block, m, m_len);
5747
0
            memset(&block[m_len], 0, sizeof(block)-m_len);
5748
0
        }
5749
        /* Adjust pointers. */
5750
0
        m += sizeof(block);
5751
0
        m_len -= (int)sizeof(block);
5752
        /* Execute the CBC-MAC algorithm. */
5753
0
        if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, sizeof(block))) {
5754
0
            gcry_cipher_close(cipher_hd);
5755
0
            return false;
5756
0
        }
5757
0
    }
5758
5759
    /* Done with the cipher. */
5760
0
    gcry_cipher_close(cipher_hd);
5761
0
    return true;
5762
0
} /* ccm_cbc_mac */
5763
5764
/* Key hash function. */
5765
unsigned ieee802154_short_addr_hash(const void *key)
5766
16.0k
{
5767
16.0k
    return (((const ieee802154_short_addr *)key)->addr) | (((const ieee802154_short_addr *)key)->pan << 16);
5768
16.0k
}
5769
5770
/* Key equal function. */
5771
gboolean ieee802154_short_addr_equal(const void *a, const void *b)
5772
4.25k
{
5773
4.25k
    return (((const ieee802154_short_addr *)a)->pan == ((const ieee802154_short_addr *)b)->pan) &&
5774
4.25k
           (((const ieee802154_short_addr *)a)->addr == ((const ieee802154_short_addr *)b)->addr);
5775
4.25k
}
5776
5777
/* Key hash function. */
5778
unsigned ieee802154_long_addr_hash(const void *key)
5779
336
{
5780
336
    return (unsigned)(((const ieee802154_long_addr *)key)->addr) & 0xFFFFFFFF;
5781
336
}
5782
5783
/* Key equal function. */
5784
gboolean ieee802154_long_addr_equal(const void *a, const void *b)
5785
328
{
5786
328
    return (((const ieee802154_long_addr *)a)->addr == ((const ieee802154_long_addr *)b)->addr);
5787
328
}
5788
5789
/* Set MAC key function. */
5790
static unsigned ieee802154_set_mac_key(ieee802154_packet *packet, unsigned char *key, unsigned char *alt_key, ieee802154_key_t *uat_key)
5791
0
{
5792
0
    ieee802154_set_key_func func = (ieee802154_set_key_func)wmem_tree_lookup32(mac_key_hash_handlers, uat_key->hash_type);
5793
5794
0
    if (func != NULL)
5795
0
        return func(packet, key, alt_key, uat_key);
5796
5797
    /* Right now, KEY_HASH_NONE and KEY_HASH_ZIP are not registered because they
5798
        work with this "default" behavior */
5799
0
    if (packet->key_index == uat_key->key_index)
5800
0
    {
5801
0
        memcpy(key, uat_key->key, IEEE802154_CIPHER_SIZE);
5802
0
        return 1;
5803
0
    }
5804
5805
0
    return 0;
5806
0
}
5807
5808
static bool trel_key_derivation_func(/*ieee802154_packet* packet*/ unsigned char* key, uint32_t seq, ieee802154_key_t* uat_key)
5809
0
{
5810
0
    uint8_t         prk[32];    /* GCRY_MD_SHA256 hash output. */
5811
0
    gcry_error_t    err;
5812
0
    uint32_t Key_sequence = seq;
5813
0
    unsigned char ikm[16];
5814
0
    GByteArray* bytes;
5815
0
    bytes = g_byte_array_new();
5816
0
    bool res = hex_str_to_bytes(uat_key->pref_key, bytes, false);
5817
0
    if (!res) {
5818
0
        g_byte_array_unref(bytes);
5819
0
        return false;
5820
0
    }
5821
5822
0
    uint8_t saltstring[] = { 'T', 'h', 'r', 'e', 'a', 'd', 'S', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 'M', 'a', 's', 't', 'e', 'r', 'K', 'e', 'y' };
5823
0
    uint8_t info_str[] = { 'T', 'h', 'r', 'e', 'a', 'd', 'O', 'v', 'e','r', 'I', 'n', 'f', 'r', 'a', 'K', 'e', 'y' };
5824
0
    uint8_t salt[sizeof(uint32_t) + sizeof(saltstring)];
5825
5826
0
    salt[0] = (Key_sequence >> 24) & 0xff;
5827
0
    salt[1] = (Key_sequence >> 16) & 0xff;
5828
0
    salt[2] = (Key_sequence >> 8) & 0xff;
5829
0
    salt[3] = (Key_sequence >> 0) & 0xff;
5830
5831
0
    memcpy(ikm, bytes->data, 16);
5832
0
    g_byte_array_unref(bytes);
5833
0
    memcpy(salt + sizeof(uint32_t), saltstring, sizeof(saltstring));
5834
5835
0
    err = hkdf_extract(GCRY_MD_SHA256, salt, sizeof(salt), ikm, sizeof(ikm), prk);
5836
0
    DISSECTOR_ASSERT(err == 0);
5837
0
    err = hkdf_expand(GCRY_MD_SHA256, prk, sizeof(prk), info_str, sizeof(info_str), key, 16);
5838
0
    DISSECTOR_ASSERT(err == 0);
5839
5840
0
    return true;
5841
0
}
5842
static unsigned ieee802154_set_trel_key(ieee802154_packet* packet, unsigned char* key, unsigned char* alt_key, ieee802154_key_t* uat_key)
5843
0
{
5844
0
    if (packet->key_index == uat_key->key_index && alt_key)
5845
0
    {
5846
0
        memcpy(key, uat_key->key, IEEE802154_CIPHER_SIZE);
5847
0
    }
5848
5849
0
    if(trel_key_derivation_func(key, 0, uat_key) == 1)
5850
0
    return 1;
5851
5852
0
    return 0;
5853
0
}
5854
5855
/**
5856
 * Creates a record that maps the given short address and pan to a long (extended) address.
5857
 * @param short_addr 16-bit short address
5858
 * @param pan 16-bit PAN id
5859
 * @param long_addr 64-bit long (extended) address
5860
 * @param proto pointer to name of current protocol
5861
 * @param fnum Frame number this mapping became valid
5862
 * @return true Record was updated, false Couldn't find it
5863
 */
5864
ieee802154_map_rec *ieee802154_addr_update(ieee802154_map_tab_t *au_ieee802154_map,
5865
        uint16_t short_addr, uint16_t pan, uint64_t long_addr, const char *proto, unsigned fnum)
5866
214
{
5867
214
    ieee802154_short_addr  addr16;
5868
214
    ieee802154_map_rec    *p_map_rec;
5869
214
    void *                 old_key;
5870
5871
    /* Look up short address hash */
5872
214
    addr16.pan = pan;
5873
214
    addr16.addr = short_addr;
5874
214
    p_map_rec = (ieee802154_map_rec *)g_hash_table_lookup(au_ieee802154_map->short_table, &addr16);
5875
5876
    /* Update mapping record */
5877
214
    if (p_map_rec) {
5878
        /* record already exists */
5879
109
        if ( p_map_rec->addr64 == long_addr ) {
5880
            /* no change */
5881
46
            return p_map_rec;
5882
46
        }
5883
63
        else {
5884
            /* mark current mapping record invalid */
5885
63
            p_map_rec->end_fnum = fnum;
5886
63
        }
5887
109
    }
5888
5889
    /* create a new mapping record */
5890
168
    p_map_rec = wmem_new(wmem_file_scope(), ieee802154_map_rec);
5891
168
    p_map_rec->proto = proto;
5892
168
    p_map_rec->start_fnum = fnum;
5893
168
    p_map_rec->end_fnum = 0;
5894
168
    p_map_rec->addr64 = long_addr;
5895
5896
    /* link new mapping record to addr hash tables */
5897
168
    if ( g_hash_table_lookup_extended(au_ieee802154_map->short_table, &addr16, &old_key, NULL) ) {
5898
        /* update short addr hash table, reusing pointer to old key */
5899
63
        g_hash_table_insert(au_ieee802154_map->short_table, old_key, p_map_rec);
5900
105
    } else {
5901
        /* create new hash entry */
5902
105
        g_hash_table_insert(au_ieee802154_map->short_table, wmem_memdup(wmem_file_scope(), &addr16, sizeof(addr16)), p_map_rec);
5903
105
    }
5904
5905
168
    if ( g_hash_table_lookup_extended(au_ieee802154_map->long_table, &long_addr, &old_key, NULL) ) {
5906
        /* update long addr hash table, reusing pointer to old key */
5907
35
        g_hash_table_insert(au_ieee802154_map->long_table, old_key, p_map_rec);
5908
133
    } else {
5909
        /* create new hash entry */
5910
133
        g_hash_table_insert(au_ieee802154_map->long_table, wmem_memdup(wmem_file_scope(), &long_addr, sizeof(long_addr)), p_map_rec);
5911
133
    }
5912
5913
168
    return p_map_rec;
5914
214
} /* ieee802154_addr_update */
5915
5916
/**
5917
 * Marks a mapping record associated with device with short_addr
5918
 * as invalid at a certain frame number, typically when a
5919
 * disassociation occurs.
5920
 *
5921
 * @param short_addr 16-bit short address
5922
 * @param pan 16-bit PAN id
5923
 * @param fnum Frame number when mapping became invalid
5924
 * @return true Record was updated, false Couldn't find it
5925
 */
5926
bool ieee802154_short_addr_invalidate(uint16_t short_addr, uint16_t pan, unsigned fnum)
5927
2
{
5928
2
    ieee802154_short_addr  addr16;
5929
2
    ieee802154_map_rec    *map_rec;
5930
5931
2
    addr16.pan = pan;
5932
2
    addr16.addr = short_addr;
5933
5934
2
    map_rec = (ieee802154_map_rec *)g_hash_table_lookup(ieee802154_map.short_table, &addr16);
5935
2
    if ( map_rec ) {
5936
        /* indicates this mapping is invalid at frame fnum */
5937
0
        map_rec->end_fnum = fnum;
5938
0
        return true;
5939
0
    }
5940
5941
2
    return false;
5942
2
} /* ieee802154_short_addr_invalidate */
5943
5944
/**
5945
 * Mark a mapping record associated with device with long_addr
5946
 * as invalid at a certain frame number, typically when a
5947
 * disassociation occurs.
5948
 *
5949
 * @param long_addr 16-bit short address
5950
 * @param fnum Frame number when mapping became invalid
5951
 * @return true If record was updated, false otherwise
5952
 */
5953
bool ieee802154_long_addr_invalidate(uint64_t long_addr, unsigned fnum)
5954
0
{
5955
0
    ieee802154_map_rec   *map_rec;
5956
5957
0
    map_rec = (ieee802154_map_rec *)g_hash_table_lookup(ieee802154_map.long_table, &long_addr);
5958
0
    if ( map_rec ) {
5959
        /* indicates this mapping is invalid at frame fnum */
5960
0
        map_rec->end_fnum = fnum;
5961
0
        return true;
5962
0
    }
5963
5964
0
    return false;
5965
0
} /* ieee802154_long_addr_invalidate */
5966
5967
/**
5968
 * Init routine for the IEEE 802.15.4 dissector. Creates hash
5969
 * tables for mapping between 16-bit to 64-bit addresses and
5970
 * populates them with static address pairs from a UAT
5971
 * preference table.
5972
 */
5973
static void
5974
proto_init_ieee802154(void)
5975
16
{
5976
16
    unsigned    i;
5977
5978
16
    ieee802154_map.short_table = g_hash_table_new(ieee802154_short_addr_hash, ieee802154_short_addr_equal);
5979
16
    ieee802154_map.long_table = g_hash_table_new(ieee802154_long_addr_hash, ieee802154_long_addr_equal);
5980
    /* Reload the hash table from the static address UAT. */
5981
16
    for (i=0; (i<num_static_addrs) && (static_addrs); i++) {
5982
0
        ieee802154_addr_update(&ieee802154_map,(uint16_t)static_addrs[i].addr16, (uint16_t)static_addrs[i].pan,
5983
0
               pntohu64(static_addrs[i].eui64), ieee802154_user, IEEE802154_USER_MAPPING);
5984
0
    } /* for */
5985
16
} /* proto_init_ieee802154 */
5986
5987
/**
5988
 * Cleanup for the IEEE 802.15.4 dissector.
5989
 */
5990
static void
5991
proto_cleanup_ieee802154(void)
5992
0
{
5993
0
    g_hash_table_destroy(ieee802154_map.short_table);
5994
0
    g_hash_table_destroy(ieee802154_map.long_table);
5995
0
}
5996
5997
/* Returns the prompt string for the Decode-As dialog. */
5998
static void ieee802154_da_prompt(packet_info *pinfo _U_, char* result)
5999
0
{
6000
0
    ieee802154_hints_t *hints;
6001
0
    hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0);
6002
0
    if (hints)
6003
0
        snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IEEE 802.15.4 PAN 0x%04x as", hints->src_pan);
6004
0
    else
6005
0
        snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IEEE 802.15.4 PAN Unknown");
6006
0
} /* iee802154_da_prompt */
6007
6008
/* Returns the value to index the panid decode table with (source PAN)*/
6009
static void *ieee802154_da_value(packet_info *pinfo _U_)
6010
0
{
6011
0
    ieee802154_hints_t *hints;
6012
0
    hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0);
6013
0
    if (hints)
6014
0
        return GUINT_TO_POINTER((unsigned)(hints->src_pan));
6015
0
    else
6016
0
        return NULL;
6017
0
} /* iee802154_da_value */
6018
6019
static const char* ieee802154_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
6020
0
{
6021
0
    if (filter == CONV_FT_SRC_ADDRESS) {
6022
0
        if (conv->src_address.type == ieee802_15_4_short_address_type)
6023
0
            return "wpan.src16";
6024
0
        else if (conv->src_address.type == AT_EUI64)
6025
0
            return "wpan.src64";
6026
0
    }
6027
6028
0
    if (filter == CONV_FT_DST_ADDRESS) {
6029
0
        if (conv->dst_address.type == ieee802_15_4_short_address_type)
6030
0
            return "wpan.dst16";
6031
0
        else if (conv->dst_address.type == AT_EUI64)
6032
0
            return "wpan.dst64";
6033
0
    }
6034
6035
0
    if (filter == CONV_FT_ANY_ADDRESS) {
6036
0
        if (conv->src_address.type == ieee802_15_4_short_address_type)
6037
0
            return "wpan.addr16";
6038
0
        else if (conv->src_address.type == AT_EUI64)
6039
0
            return "wpan.addr64";
6040
0
    }
6041
6042
0
    return CONV_FILTER_INVALID;
6043
0
}
6044
6045
static ct_dissector_info_t ieee802154_ct_dissector_info = {&ieee802154_conv_get_filter_type };
6046
6047
static tap_packet_status ieee802154_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags)
6048
0
{
6049
0
    conv_hash_t *hash = (conv_hash_t*)pct;
6050
0
    hash->flags = flags;
6051
6052
0
    add_conversation_table_data(hash, &pinfo->dl_src, &pinfo->dl_dst, 0, 0, 1,
6053
0
            pinfo->fd->pkt_len, &pinfo->rel_ts, &pinfo->abs_ts,
6054
0
            &ieee802154_ct_dissector_info, CONVERSATION_NONE);
6055
6056
0
    return TAP_PACKET_REDRAW;
6057
0
}
6058
6059
static const char* ieee802154_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
6060
0
{
6061
0
    if (filter == CONV_FT_ANY_ADDRESS) {
6062
0
        if (endpoint->myaddress.type == ieee802_15_4_short_address_type)
6063
0
            return "wpan.addr16";
6064
0
        else if (endpoint->myaddress.type == AT_EUI64)
6065
0
            return "wpan.addr64";
6066
0
    }
6067
6068
0
    return CONV_FILTER_INVALID;
6069
0
}
6070
6071
static et_dissector_info_t ieee802154_endpoint_dissector_info = {&ieee802154_endpoint_get_filter_type };
6072
6073
static tap_packet_status ieee802154_endpoint_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags)
6074
0
{
6075
0
    conv_hash_t *hash = (conv_hash_t*)pit;
6076
0
    hash->flags = flags;
6077
6078
    /* Take two "add" passes per packet, adding for each direction, ensures that all
6079
     packets are counted properly (even if address is sending to itself)
6080
     XXX - this could probably be done more efficiently inside endpoint_table */
6081
0
    add_endpoint_table_data(hash, &pinfo->dl_src, 0, true, 1,
6082
0
            pinfo->fd->pkt_len, &ieee802154_endpoint_dissector_info, ENDPOINT_NONE);
6083
0
    add_endpoint_table_data(hash, &pinfo->dl_dst, 0, false, 1,
6084
0
            pinfo->fd->pkt_len, &ieee802154_endpoint_dissector_info, ENDPOINT_NONE);
6085
6086
0
    return TAP_PACKET_REDRAW;
6087
0
}
6088
6089
static bool ieee802154_filter_valid(packet_info *pinfo, void *user_data _U_)
6090
0
{
6091
0
    return proto_is_frame_protocol(pinfo->layers, "wpan")
6092
0
            && ((pinfo->dl_src.type == ieee802_15_4_short_address_type) || (pinfo->dl_src.type == AT_EUI64))
6093
0
            && ((pinfo->dl_dst.type == ieee802_15_4_short_address_type) || (pinfo->dl_dst.type == AT_EUI64));
6094
0
}
6095
6096
static char* ieee802154_build_filter(packet_info *pinfo, void *user_data _U_)
6097
0
{
6098
0
    return ws_strdup_printf("wpan.%s eq %s and wpan.%s eq %s",
6099
0
            (pinfo->dl_src.type == ieee802_15_4_short_address_type) ? "addr16" : "addr64",
6100
0
            address_to_str(pinfo->pool, &pinfo->dl_src),
6101
0
            (pinfo->dl_dst.type == ieee802_15_4_short_address_type) ? "addr16" : "addr64",
6102
0
            address_to_str(pinfo->pool, &pinfo->dl_dst));
6103
0
}
6104
6105
/**
6106
 * IEEE 802.15.4 protocol registration routine.
6107
 */
6108
void proto_register_ieee802154(void)
6109
16
{
6110
    /* Protocol fields  */
6111
16
    static hf_register_info hf_phy[] = {
6112
        /* PHY level */
6113
6114
16
        { &hf_ieee802154_nonask_phy_preamble,
6115
16
        { "Preamble",                       "wpan-nonask-phy.preamble", FT_UINT32, BASE_HEX, NULL, 0x0,
6116
16
            NULL, HFILL }},
6117
6118
16
        { &hf_ieee802154_nonask_phy_sfd,
6119
16
        { "Start of Frame Delimiter",       "wpan-nonask-phy.sfd", FT_UINT8, BASE_HEX, NULL, 0x0,
6120
16
            NULL, HFILL }},
6121
6122
16
        { &hf_ieee802154_nonask_phy_length,
6123
16
        { "Frame Length",                   "wpan-nonask-phy.frame_length", FT_UINT8, BASE_HEX, NULL,
6124
16
            IEEE802154_PHY_LENGTH_MASK, NULL, HFILL }},
6125
6126
16
        { &hf_ieee802154_nonask_phr,
6127
16
        { "PHR",                            "wpan-nonask-phy.phr", FT_UINT8, BASE_HEX, NULL,
6128
16
            0x0, NULL, HFILL }},
6129
16
    };
6130
6131
16
    static hf_register_info hf[] = {
6132
6133
16
        { &hf_ieee802154_frame_length,
6134
16
        { "Frame Length",                   "wpan.frame_length", FT_UINT8, BASE_DEC, NULL, 0x0,
6135
16
            "Frame Length as reported from lower layer", HFILL }},
6136
6137
16
        { &hf_ieee802154_fcf,
6138
16
        { "Frame Control Field",            "wpan.fcf", FT_UINT16, BASE_HEX, NULL,
6139
16
            0x0, NULL, HFILL }},
6140
6141
16
        { &hf_ieee802154_frame_type,
6142
16
        { "Frame Type",                     "wpan.frame_type", FT_UINT16, BASE_HEX, VALS(ieee802154_frame_types),
6143
16
            IEEE802154_FCF_TYPE_MASK, NULL, HFILL }},
6144
6145
16
        { &hf_ieee802154_security,
6146
16
        { "Security Enabled",               "wpan.security", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_SEC_EN,
6147
16
            "Whether security operations are performed at the MAC layer or not.", HFILL }},
6148
6149
16
        { &hf_ieee802154_pending,
6150
16
        { "Frame Pending",                  "wpan.pending", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_FRAME_PND,
6151
16
            "Indication of additional packets waiting to be transferred from the source device.", HFILL }},
6152
6153
16
        { &hf_ieee802154_ack_request,
6154
16
        { "Acknowledge Request",            "wpan.ack_request", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_ACK_REQ,
6155
16
            "Whether the sender of this packet requests acknowledgment or not.", HFILL }},
6156
6157
16
        { &hf_ieee802154_pan_id_compression,
6158
16
        { "PAN ID Compression",             "wpan.pan_id_compression", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_PAN_ID_COMPRESSION,
6159
16
            "Whether this packet contains the PAN ID or not.", HFILL }},
6160
6161
16
        { &hf_ieee802154_fcf_reserved,
6162
16
        { "Reserved",                       "wpan.fcf.reserved", FT_BOOLEAN, 16, NULL, 0x0080,
6163
16
            NULL, HFILL }},
6164
6165
16
        { &hf_ieee802154_seqno_suppression,
6166
16
        { "Sequence Number Suppression",    "wpan.seqno_suppression", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_SEQNO_SUPPRESSION,
6167
16
            "Whether this packet contains the Sequence Number or not.", HFILL }},
6168
6169
16
        { &hf_ieee802154_ie_present,
6170
16
        { "Information Elements Present",   "wpan.ie_present", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_IE_PRESENT,
6171
16
            "Whether this packet contains the Information Elements or not.", HFILL }},
6172
6173
16
        { &hf_ieee802154_dst_addr_mode,
6174
16
        { "Destination Addressing Mode",    "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
6175
16
            IEEE802154_FCF_DADDR_MASK, NULL, HFILL }},
6176
6177
16
        { &hf_ieee802154_version,
6178
16
        { "Frame Version",                  "wpan.version", FT_UINT16, BASE_DEC, VALS(ieee802154_frame_versions),
6179
16
            IEEE802154_FCF_VERSION, NULL, HFILL }},
6180
6181
16
        { &hf_ieee802154_src_addr_mode,
6182
16
        { "Source Addressing Mode",         "wpan.src_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
6183
16
            IEEE802154_FCF_SADDR_MASK, NULL, HFILL }},
6184
6185
        /* 802.15.4-2015 Multipurpose frame control fields */
6186
16
        { &hf_ieee802154_mpf_long_frame_control,
6187
16
        { "Long Frame Control",             "wpan.long_frame_control", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_LONG_FC,
6188
16
            "Whether this frame control field uses one or two octets.", HFILL }},
6189
6190
16
        { &hf_ieee802154_mpf_dst_addr_mode,
6191
16
        { "Destination Addressing Mode",    "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
6192
16
            IEEE802154_MPF_FCF_DADDR_MASK, NULL, HFILL }},
6193
6194
16
        { &hf_ieee802154_mpf_src_addr_mode,
6195
16
        { "Source Addressing Mode",         "wpan.src_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
6196
16
            IEEE802154_MPF_FCF_SADDR_MASK, NULL, HFILL }},
6197
6198
16
        { &hf_ieee802154_mpf_pan_id_present,
6199
16
        { "PAN ID Present",                 "wpan.pan_id_present", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_PAN_ID_PRESENT,
6200
16
            "Whether this packet contains the destination PAN ID or not", HFILL }},
6201
6202
16
        { &hf_ieee802154_mpf_security,
6203
16
        { "Security Enabled",               "wpan.security", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_SEC_EN,
6204
16
            "Whether security operations are performed at the MAC layer or not.", HFILL }},
6205
6206
16
        { &hf_ieee802154_mpf_seqno_suppression,
6207
16
        { "Sequence Number Suppression",    "wpan.seqno_suppression", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_SEQNO_SUPPRESSION,
6208
16
            "Whether this packet contains the Sequence Number or not.", HFILL }},
6209
6210
16
        { &hf_ieee802154_mpf_pending,
6211
16
        { "Frame Pending",                  "wpan.pending", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_FRAME_PND,
6212
16
            "Indication of additional packets waiting to be transferred from the source device.", HFILL }},
6213
6214
16
        { &hf_ieee802154_mpf_version,
6215
16
        { "Multipurpose Frame Version",     "wpan.mpf_version", FT_UINT16, BASE_DEC, NULL,
6216
16
            IEEE802154_MPF_FCF_VERSION, NULL, HFILL }},
6217
6218
16
        { &hf_ieee802154_mpf_ack_request,
6219
16
        { "Acknowledge Request",            "wpan.ack_request", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_ACK_REQ,
6220
16
            "Whether the sender of this packet requests acknowledgment or not.", HFILL }},
6221
6222
16
        { &hf_ieee802154_mpf_ie_present,
6223
16
        { "Information Elements Present",   "wpan.ie_present", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_IE_PRESENT,
6224
16
            "Whether this packet contains the Information Elements or not.", HFILL }},
6225
6226
16
        { &hf_ieee802154_seqno,
6227
16
        { "Sequence Number",                "wpan.seq_no", FT_UINT8, BASE_DEC, NULL, 0x0,
6228
16
            NULL, HFILL }},
6229
6230
16
        { &hf_ieee802154_dst_panID,
6231
16
        { "Destination PAN",                "wpan.dst_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
6232
16
            NULL, HFILL }},
6233
6234
16
        { &hf_ieee802154_dst16,
6235
16
        { "Destination",                    "wpan.dst16", FT_UINT16, BASE_HEX, NULL, 0x0,
6236
16
            NULL, HFILL }},
6237
6238
16
        { &hf_ieee802154_dst64,
6239
16
        { "Destination",                    "wpan.dst64", FT_EUI64, BASE_NONE, NULL, 0x0,
6240
16
            NULL, HFILL }},
6241
6242
16
        { &hf_ieee802154_src_panID,
6243
16
        { "Source PAN",                     "wpan.src_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
6244
16
            NULL, HFILL }},
6245
6246
16
        { &hf_ieee802154_src16,
6247
16
        { "Source",                         "wpan.src16", FT_UINT16, BASE_HEX, NULL, 0x0,
6248
16
            NULL, HFILL }},
6249
6250
16
        { &hf_ieee802154_src64,
6251
16
        { "Extended Source",                "wpan.src64", FT_EUI64, BASE_NONE, NULL, 0x0,
6252
16
            NULL, HFILL }},
6253
6254
16
        { &hf_ieee802154_addr16,
6255
16
        { "Address",                        "wpan.addr16", FT_UINT16, BASE_HEX, NULL, 0x0,
6256
16
            NULL, HFILL }},
6257
6258
16
        { &hf_ieee802154_addr64,
6259
16
        { "Extended Address",               "wpan.addr64", FT_EUI64, BASE_NONE, NULL, 0x0,
6260
16
            NULL, HFILL }},
6261
6262
16
        { &hf_ieee802154_src64_origin,
6263
16
        { "Origin",                         "wpan.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
6264
16
            NULL, HFILL }},
6265
6266
16
        { &hf_ieee802154_fcs,
6267
16
        { "FCS",                            "wpan.fcs", FT_UINT16, BASE_HEX, NULL, 0x0,
6268
16
            NULL, HFILL }},
6269
6270
16
        { &hf_ieee802154_fcs32,
6271
16
        { "FCS",                            "wpan.fcs32", FT_UINT32, BASE_HEX, NULL, 0x0,
6272
16
            NULL, HFILL }},
6273
6274
16
        { &hf_ieee802154_rssi,
6275
16
        { "RSSI",                           "wpan.rssi", FT_INT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_decibels), 0x0,
6276
16
            "Received Signal Strength", HFILL }},
6277
6278
16
        { &hf_ieee802154_fcs_ok,
6279
16
        { "FCS Valid",                      "wpan.fcs_ok", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
6280
16
            NULL, HFILL }},
6281
6282
16
        { &hf_ieee802154_correlation,
6283
16
        { "LQI Correlation Value",          "wpan.correlation", FT_UINT8, BASE_DEC, NULL, 0x0,
6284
16
            NULL, HFILL }},
6285
6286
        /* Information Elements */
6287
6288
16
        { &hf_ieee802154_ie_unknown_content,
6289
16
        { "Unknown Content",                "wpan.ie.unknown_content", FT_BYTES, SEP_SPACE, NULL, 0x0,
6290
16
            NULL, HFILL }},
6291
6292
16
        { &hf_ieee802154_ie_unknown_content_payload,
6293
16
        { "Unknown Content Payload",        "wpan.ie.unknown_content_payload", FT_BYTES, SEP_SPACE, NULL, 0x0,
6294
16
            NULL, HFILL }},
6295
6296
        /* Header IE */
6297
6298
16
        { &hf_ieee802154_header_ies,
6299
16
        { "Header IEs",                     "wpan.header_ie", FT_NONE, BASE_NONE, NULL,
6300
16
            0x0, NULL, HFILL }},
6301
6302
16
        { &hf_ieee802154_header_ie_tlv,
6303
16
          { "IE Header",                    "wpan.header_ie_tlv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
6304
6305
16
        { &hf_ieee802154_header_ie_type,
6306
16
        { "Type",                           "wpan.header_ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_ie_types),
6307
16
                IEEE802154_HEADER_IE_TYPE_MASK, NULL, HFILL }},
6308
6309
16
        { &hf_ieee802154_header_ie_id,
6310
16
        { "Id",                             "wpan.header_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_header_ie_names),
6311
16
                IEEE802154_HEADER_IE_ID_MASK, NULL, HFILL }},
6312
6313
16
        { &hf_ieee802154_header_ie_length,
6314
16
        { "Length",                         "wpan.header_ie.length", FT_UINT16, BASE_DEC, NULL,
6315
16
                IEEE802154_HEADER_IE_LENGTH_MASK, NULL, HFILL }},
6316
6317
6318
        /* Individual Header IEs */
6319
6320
16
        { &hf_ieee802154_hie_unsupported,
6321
16
        { "Unsupported Header IE",          "wpan.header_ie.unsupported", FT_NONE, BASE_NONE, NULL, 0x0,
6322
16
            NULL, HFILL }},
6323
6324
16
        { &hf_ieee802154_hie_ht1,
6325
16
        { "Header Termination 1 IE (Payload IEs follow)", "wpan.header_ie.ht1", FT_NONE, BASE_NONE, NULL, 0x0,
6326
16
            NULL, HFILL }},
6327
6328
16
        { &hf_ieee802154_hie_ht2,
6329
16
        { "Header Termination 2 IE (Payload follows)",    "wpan.header_ie.ht2", FT_NONE, BASE_NONE, NULL, 0x0,
6330
16
            NULL, HFILL }},
6331
6332
16
        { &hf_ieee802154_hie_thread,
6333
16
        { "Thread IE (Payload follows)",    "wpan.header_ie.thread", FT_NONE, BASE_NONE, NULL, 0x0,
6334
16
            NULL, HFILL }},
6335
6336
6337
        /* Time correction IE */
6338
16
        { &hf_ieee802154_hie_time_correction,
6339
16
        { "Time Correction IE",             "wpan.header_ie.time_correction", FT_NONE, BASE_NONE, NULL, 0x0,
6340
16
            NULL, HFILL }},
6341
6342
16
        { &hf_ieee802154_hie_time_correction_time_sync_info,
6343
16
        { "Time Sync Info",                 "wpan.header_ie.time_correction.time_sync_info", FT_UINT16, BASE_HEX, NULL, 0x0,
6344
16
            NULL, HFILL }},
6345
6346
16
        { &hf_ieee802154_nack,
6347
16
        { "Nack",                           "wpan.nack", FT_BOOLEAN, 16, TFS(&hf_ieee802154_nack_tfs), 0x8000,
6348
16
            NULL, HFILL }},
6349
6350
16
        { &hf_ieee802154_hie_time_correction_value,
6351
16
        { "Time Correction",                "wpan.header_ie.time_correction.value", FT_INT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0FFF,
6352
16
            "Time correction in microseconds", HFILL }},
6353
6354
        /* CSL IE */
6355
16
        { &hf_ieee802154_hie_csl,
6356
16
        { "CSL IE", "wpan.header_ie.csl", FT_NONE, BASE_NONE, NULL, 0x0,
6357
16
            NULL, HFILL }},
6358
6359
16
        { &hf_ieee802154_hie_csl_phase,
6360
16
        { "Phase", "wpan.header_ie.csl.phase", FT_INT16, BASE_DEC, NULL, 0x0,
6361
16
            "CSL Phase in units of 10 symbols", HFILL }},
6362
6363
16
        { &hf_ieee802154_hie_csl_period,
6364
16
        { "Period", "wpan.header_ie.csl.period", FT_INT16, BASE_DEC, NULL, 0x0,
6365
16
            "CSL Period in units of 10 symbols", HFILL }},
6366
6367
16
        { &hf_ieee802154_hie_csl_rendezvous_time,
6368
16
        { "Rendezvous Time", "wpan.header_ie.csl.rendezvous_time", FT_INT16, BASE_DEC, NULL, 0x0,
6369
16
            "CSL Rendezvous Time in units of 10 symbols", HFILL }},
6370
6371
        /* RendezVous Time IE */
6372
16
        { &hf_ieee802154_hie_rdv,
6373
16
        { "Rendezvous Time IE", "wpan.header_ie.rdv", FT_NONE, BASE_NONE, NULL, 0x0,
6374
16
            NULL, HFILL }},
6375
6376
16
        { &hf_ieee802154_hie_rdv_wakeup_interval,
6377
16
        { "Wake-up Interval", "wpan.header_ie.csl.wakeup_interval", FT_INT16, BASE_DEC, NULL, 0x0,
6378
16
            "Interval between two successive Wake-Up frames, in units of 10 symbols", HFILL }},
6379
6380
        /* Global Time IE */
6381
16
        { &hf_ieee802154_hie_global_time,
6382
16
        { "Global Time IE",                 "wpan.header_ie.global_time", FT_NONE, BASE_NONE, NULL, 0x0,
6383
16
            NULL, HFILL }},
6384
6385
16
        { &hf_ieee802154_hie_global_time_value,
6386
16
        { "Global Time",                    "wpan.header_ie.global_time.value", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
6387
16
            NULL, HFILL }},
6388
6389
        /* Vendor Specific IE */
6390
16
        { &hf_ieee802154_hie_vendor_specific,
6391
16
        { "Vendor Specific IE",             "wpan.header_ie.vendor_specific", FT_NONE, BASE_NONE, NULL, 0x0,
6392
16
            NULL, HFILL }},
6393
6394
16
        { &hf_ieee802154_hie_vendor_specific_vendor_oui,
6395
16
        { "Vendor OUI",                 "wpan.header_ie.vendor_specific.vendor_oui", FT_UINT24, BASE_OUI, NULL, 0x0,
6396
16
            NULL, HFILL }},
6397
6398
16
        { &hf_ieee802154_hie_vendor_specific_content,
6399
16
        { "Vendor Content",                "wpan.header_ie.vendor_specific.content", FT_BYTES, SEP_SPACE, NULL, 0x0,
6400
16
            NULL, HFILL }},
6401
6402
        /* Payload IEs */
6403
6404
16
        { &hf_ieee802154_payload_ies,
6405
16
        { "Payload IEs",                    "wpan.payload_ie", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6406
6407
16
        { &hf_ieee802154_payload_ie_tlv,
6408
16
        { "IE Header",                      "wpan.payload_ie_tlv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6409
6410
16
        { &hf_ieee802154_payload_ie_type,
6411
16
        { "Type",                           "wpan.payload_ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_ie_types),
6412
16
                IEEE802154_PAYLOAD_IE_TYPE_MASK, NULL, HFILL }},
6413
6414
16
        { &hf_ieee802154_payload_ie_id,
6415
16
        { "Id",                             "wpan.payload_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_payload_ie_names),
6416
16
                IEEE802154_PAYLOAD_IE_ID_MASK, NULL, HFILL }},
6417
6418
16
        { &hf_ieee802154_payload_ie_length,
6419
16
        { "Length",                         "wpan.payload_ie.length", FT_UINT16, BASE_DEC, NULL,
6420
16
                IEEE802154_PAYLOAD_IE_LENGTH_MASK, NULL, HFILL }},
6421
6422
6423
        /* Individual Payload IEs */
6424
6425
16
        { &hf_ieee802154_pie_unsupported,
6426
16
        { "Unknown Payload IE",             "wpan.payload_ie.unknown", FT_NONE, BASE_NONE, NULL, 0x0,
6427
16
            NULL, HFILL }},
6428
6429
16
        { &hf_ieee802154_pie_termination,
6430
16
        { "Payload Termination IE",         "wpan.payload_ie.termination", FT_NONE, BASE_NONE, NULL, 0x0,
6431
16
            NULL, HFILL }},
6432
6433
16
        { &hf_ieee802154_pie_vendor,
6434
16
        { "Vendor Specific IE",             "wpan.payload_ie.vendor", FT_NONE, BASE_NONE, NULL, 0x0,
6435
16
            NULL, HFILL }},
6436
6437
16
        { &hf_ieee802154_pie_vendor_oui,
6438
16
        { "Vendor OUI",                     "wpan.payload_ie.vendor.oui", FT_UINT24, BASE_OUI, NULL, 0x0,
6439
16
            NULL, HFILL }},
6440
6441
16
        { &hf_ieee802154_pie_vendor_variable,
6442
16
        { "Vendor variable",                "wpan.payload_ie.vendor.variable", FT_BYTES, BASE_NONE, NULL, 0x0,
6443
16
            NULL, HFILL }},
6444
6445
16
        { &hf_ieee802154_mlme,
6446
16
        { "MLME IE",                        "wpan.mlme", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6447
6448
16
        { &hf_ieee802154_psie_type,
6449
16
        { "Type",                           "wpan.mlme.ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_psie_types),
6450
16
                IEEE802154_PSIE_TYPE_MASK, NULL, HFILL }},
6451
6452
16
        { &hf_ieee802154_psie,
6453
16
        { "MLME Sub IE",                    "wpan.mlme.ie", FT_UINT16, BASE_HEX, NULL,
6454
16
            0x0, NULL, HFILL }},
6455
6456
16
        { &hf_ieee802154_psie_id_short,
6457
16
        { "Sub ID",                         "wpan.mlme.ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_psie_names),
6458
16
                IEEE802154_PSIE_ID_MASK_SHORT, NULL, HFILL }},
6459
6460
16
        { &hf_ieee802154_psie_length_short,
6461
16
        { "Length",                         "wpan.mlme.ie.length", FT_UINT16, BASE_DEC, NULL,
6462
16
                IEEE802154_PSIE_LENGTH_MASK_SHORT, NULL, HFILL }},
6463
6464
16
        { &hf_ieee802154_psie_id_long,
6465
16
        { "Sub ID",                         "wpan.mlme.ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_psie_names),
6466
16
                IEEE802154_PSIE_ID_MASK_LONG, NULL, HFILL }},
6467
6468
16
        { &hf_ieee802154_psie_length_long,
6469
16
        { "Length",                         "wpan.mlme.ie.length", FT_UINT16, BASE_DEC, NULL,
6470
16
                IEEE802154_PSIE_LENGTH_MASK_LONG, NULL, HFILL }},
6471
6472
16
        { &hf_ieee802154_mlme_ie_unsupported,
6473
16
        { "Unsupported Sub IE",             "wpan.mlme.unsupported", FT_NONE, BASE_NONE, NULL,
6474
16
              0, NULL, HFILL }},
6475
6476
16
        { &hf_ieee802154_mlme_ie_data,
6477
16
        { "Data",                            "wpan.mlme.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6478
6479
16
        { &hf_ieee802154_psie_eb_filter,
6480
16
        { "Enhanced Beacon Filter",         "wpan.eb_filter", FT_UINT8, BASE_HEX, NULL,
6481
16
              0, NULL, HFILL }},
6482
6483
16
        { &hf_ieee802154_psie_eb_filter_pjoin,
6484
16
        { "Permit Join Filter",             "wpan.eb_filter.pjoin", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled),
6485
16
              IEEE802154_MLME_PSIE_EB_FLT_PJOIN, NULL, HFILL }},
6486
6487
16
        { &hf_ieee802154_psie_eb_filter_lqi,
6488
16
        { "LQI Filter",                     "wpan.eb_filter.lqi", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled),
6489
16
            IEEE802154_MLME_PSIE_EB_FLT_LQI, NULL, HFILL }},
6490
6491
16
        { &hf_ieee802154_psie_eb_filter_lqi_min,
6492
16
        { "Minimum LQI",                    "wpan.eb_filter.lqi_minimum", FT_UINT8, BASE_DEC, NULL,
6493
16
             0x0, NULL, HFILL }},
6494
6495
16
        { &hf_ieee802154_psie_eb_filter_percent,
6496
16
        { "Probability to Respond",         "wpan.eb_filter.contains_prob", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled),
6497
16
            IEEE802154_MLME_PSIE_EB_FLT_PERCENT, NULL, HFILL }},
6498
6499
16
        { &hf_ieee802154_psie_eb_filter_percent_prob,
6500
16
        { "Response Probability Percentage", "wpan.eb_filter.prob", FT_UINT8, BASE_DEC, NULL,
6501
16
                 0x0, NULL, HFILL }},
6502
6503
16
        { &hf_ieee802154_psie_eb_filter_attr_id,
6504
16
        { "Requested Attribute Length",      "wpan.eb_filter.attr_id", FT_UINT8, BASE_DEC, NULL,
6505
16
            IEEE802154_MLME_PSIE_EB_FLT_ATTR_LEN, NULL, HFILL }},
6506
6507
16
        { &hf_ieee802154_psie_eb_filter_attr_id_bitmap,
6508
16
        { "Attribute ID Bitmap",             "wpan.eb_filter.attr_id_bits", FT_UINT24, BASE_HEX, NULL,
6509
16
                0x0, NULL, HFILL }},
6510
6511
16
        { &hf_ieee802154_tsch_sync,
6512
16
          { "TSCH Synchronization IE",      "wpan.tsch.time_sync", FT_NONE, BASE_NONE, NULL, 0x0,
6513
16
            NULL, HFILL }},
6514
6515
16
        { &hf_ieee802154_tsch_asn,
6516
16
        { "Absolute Slot Number",           "wpan.tsch.asn", FT_UINT40, BASE_DEC, NULL, 0x0,
6517
16
            NULL, HFILL }},
6518
6519
16
        { &hf_ieee802154_tsch_join_metric,
6520
16
        { "Join Metric",                    "wpan.tsch.join_metric", FT_UINT8, BASE_DEC, NULL, 0x0,
6521
16
            NULL, HFILL }},
6522
6523
16
        { &hf_ieee802154_tsch_timeslot,
6524
16
          { "TSCH Timeslot IE",             "wpan.tsch.timeslot", FT_NONE, BASE_NONE, NULL, 0x0,
6525
16
            NULL, HFILL }},
6526
6527
16
        { &hf_ieee802154_tsch_timeslot_id,
6528
16
          { "Timeslot ID",                  "wpan.tsch.timeslot.id", FT_UINT8, BASE_HEX, NULL, 0x0,
6529
16
            "Identifier of the Timeslot Template", HFILL }},
6530
6531
16
        { &hf_ieee802154_tsch_timeslot_cca_offset,
6532
16
          { "CCA Offset",                   "wpan.tsch.timeslot.cca_offset", FT_UINT16, BASE_DEC, NULL, 0x0,
6533
16
            "Time between the beginning of the timeslot and the start of CCA", HFILL }},
6534
6535
16
        { &hf_ieee802154_tsch_timeslot_cca,
6536
16
          { "CCA",                          "wpan.tsch.timeslot.cca", FT_UINT16, BASE_DEC, NULL, 0x0,
6537
16
            "Duration of CCA", HFILL }},
6538
6539
16
        { &hf_ieee802154_tsch_timeslot_tx_offset,
6540
16
          { "TX Offset",                    "wpan.tsch.timeslot.tx_offset", FT_UINT16, BASE_DEC, NULL, 0x0,
6541
16
            "Time between the beginning of the timeslot and the start of frame transmission", HFILL }},
6542
6543
16
        { &hf_ieee802154_tsch_timeslot_rx_offset,
6544
16
          { "RX Offset",                    "wpan.tsch.timeslot.rx_offset", FT_UINT16, BASE_DEC, NULL, 0x0,
6545
16
            "Time between the beginning of the timeslot to when the receiver shall be listening", HFILL }},
6546
6547
16
        { &hf_ieee802154_tsch_timeslot_rx_ack_delay,
6548
16
          { "RX Ack Delay",                "wpan.tsch.timeslot.rx_ack_delay", FT_UINT16, BASE_DEC, NULL, 0x0,
6549
16
            "Time between the end of frame to when the transmitter shall listen for acknowledgment", HFILL }},
6550
6551
16
        { &hf_ieee802154_tsch_timeslot_tx_ack_delay,
6552
16
          { "TX Ack Delay",                "wpan.tsch.timeslot.tx_ack_delay", FT_UINT16, BASE_DEC, NULL, 0x0,
6553
16
            "Time between the end of frame to start of acknowledgment", HFILL }},
6554
6555
16
        { &hf_ieee802154_tsch_timeslot_rx_wait,
6556
16
          { "RX Wait",                      "wpan.tsch.timeslot.rx_wait", FT_UINT16, BASE_DEC, NULL, 0x0,
6557
16
            "Time to wait for the start of frame", HFILL }},
6558
6559
16
        { &hf_ieee802154_tsch_timeslot_ack_wait,
6560
16
          { "Ack Wait",                     "wpan.tsch.timeslot.ack_wait", FT_UINT16, BASE_DEC, NULL, 0x0,
6561
16
            "Minimum time to wait for the start of an acknowledgment", HFILL }},
6562
6563
16
        { &hf_ieee802154_tsch_timeslot_turnaround,
6564
16
          { "Turn Around",                  "wpan.tsch.timeslot.turnaround", FT_UINT16, BASE_DEC, NULL, 0x0,
6565
16
            "Transmit to receive turnaround time", HFILL }},
6566
6567
16
        { &hf_ieee802154_tsch_timeslot_max_ack,
6568
16
          { "Max Ack",                      "wpan.tsch.timeslot.max_ack", FT_UINT16, BASE_DEC, NULL, 0x0,
6569
16
            "Transmission time to send an acknowledgment", HFILL }},
6570
6571
16
        { &hf_ieee802154_tsch_timeslot_max_tx,
6572
16
          { "Max TX",                      "wpan.tsch.timeslot.max_tx", FT_UINT24, BASE_DEC, NULL, 0x0,
6573
16
            "Transmission time to send the maximum length frame", HFILL }},
6574
6575
16
        { &hf_ieee802154_tsch_timeslot_length,
6576
16
          { "Timeslot Length",              "wpan.tsch.timeslot.length", FT_UINT24, BASE_DEC, NULL, 0x0,
6577
16
            "Total length of the timeslot, including any unused time after frame transmission", HFILL }},
6578
6579
16
        { &hf_ieee802154_tsch_channel_hopping,
6580
16
        { "Channel Hopping IE",             "wpan.channel_hopping", FT_NONE, BASE_NONE, NULL, 0x0,
6581
16
            NULL, HFILL }},
6582
6583
16
        { &hf_ieee802154_tsch_slotframe,
6584
16
        { "Slotframe IE", "wpan.tsch.slotframe", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6585
6586
16
        { &hf_ieee802154_tsch_link_info,
6587
16
        { "Link Information", "wpan.tsch.link_info", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6588
6589
16
        { &hf_ieee802154_tsch_slotf_link_nb_slotf,
6590
16
        { "Number of Slotframes",           "wpan.tsch.slotframe_num", FT_UINT8, BASE_DEC, NULL, 0x0,
6591
16
            NULL, HFILL }},
6592
6593
16
        { &hf_ieee802154_tsch_slotf_link_slotf_handle,
6594
16
        { "Slotframe handle",               "wpan.tsch.slotframe_handle", FT_UINT8, BASE_DEC, NULL, 0x0,
6595
16
            NULL, HFILL }},
6596
6597
16
        { &hf_ieee802154_tsch_slotf_size,
6598
16
        { "Slotframe size",                 "wpan.tsch.slotframe_size", FT_UINT16, BASE_DEC, NULL, 0x0,
6599
16
            NULL, HFILL }},
6600
6601
16
        { &hf_ieee802154_tsch_slotf_link_nb_links,
6602
16
        { "Number of Links",                "wpan.tsch.nb_links", FT_UINT8, BASE_DEC, NULL, 0x0,
6603
16
            NULL, HFILL }},
6604
6605
16
        { &hf_ieee802154_tsch_slotf_link_timeslot,
6606
16
        { "Timeslot",                       "wpan.tsch.link_timeslot", FT_UINT16, BASE_DEC, NULL, 0x0,
6607
16
            NULL, HFILL }},
6608
6609
16
        { &hf_ieee802154_tsch_slotf_link_channel_offset,
6610
16
        { "Channel Offset",                 "wpan.tsch.channel_offset", FT_UINT16, BASE_DEC, NULL, 0x0,
6611
16
            NULL, HFILL }},
6612
6613
16
        { &hf_ieee802154_tsch_slotf_link_options,
6614
16
        { "Link Options",                   "wpan.tsch.link_options", FT_UINT8, BASE_HEX, NULL, 0x0,
6615
16
            NULL, HFILL }},
6616
6617
16
        { &hf_ieee802154_tsch_slotf_link_options_tx,
6618
16
        { "TX Link",                        "wpan.tsch.link_options.tx", FT_BOOLEAN, 8, NULL, (1 << 0),
6619
16
            NULL, HFILL }},
6620
6621
16
        { &hf_ieee802154_tsch_slotf_link_options_rx,
6622
16
        { "RX Link",                        "wpan.tsch.link_options.rx", FT_BOOLEAN, 8, NULL, (1 << 1),
6623
16
            NULL, HFILL }},
6624
6625
16
        { &hf_ieee802154_tsch_slotf_link_options_shared,
6626
16
        { "Shared Link",                    "wpan.tsch.link_options.shared", FT_BOOLEAN, 8, NULL, (1 << 2),
6627
16
            NULL, HFILL }},
6628
6629
16
        { &hf_ieee802154_tsch_slotf_link_options_timkeeping,
6630
16
        { "Timekeeping",                    "wpan.tsch.link_options.timekeeping", FT_BOOLEAN, 8, NULL, (1 << 3),
6631
16
            NULL, HFILL }},
6632
6633
16
        { &hf_ieee802154_tsch_slotf_link_options_priority,
6634
16
        { "Priority",                       "wpan.tsch.link_options.priority", FT_BOOLEAN, 8, NULL, (1 << 4),
6635
16
            NULL, HFILL }},
6636
6637
16
        { &hf_ieee802154_tsch_hopping_sequence_id,
6638
16
        { "Hopping Sequence ID",            "wpan.tsch.hopping_sequence_id", FT_UINT8, BASE_HEX, NULL, 0x0,
6639
16
            NULL, HFILL }},
6640
6641
        /* IETF IE */
6642
16
        { &hf_ieee802154_pie_ietf,
6643
16
        { "IETF Payload IE",                 "wpan.payload_ie.ietf", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6644
6645
16
        { &hf_ieee802154_p_ie_ietf_sub_id,
6646
16
        { "Sub-ID",                          "wpan.ietf_ie.sub_id", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
6647
6648
        /* IETF IE - 6top IE */
6649
16
        { &hf_ieee802154_6top,
6650
16
        { "6top IE", "wpan.6top", FT_NONE, BASE_NONE, NULL, 0x0,
6651
16
          NULL, HFILL }},
6652
6653
16
        { &hf_ieee802154_6top_version,
6654
16
        { "6P Version", "wpan.6top_version", FT_UINT8, BASE_DEC, NULL, IETF_6TOP_VERSION,
6655
16
          NULL, HFILL }},
6656
6657
16
        { &hf_ieee802154_6top_type,
6658
16
          { "Type", "wpan.6top_type", FT_UINT8, BASE_HEX, VALS(ietf_6top_types), IETF_6TOP_TYPE,
6659
16
          NULL, HFILL }},
6660
6661
16
        { &hf_ieee802154_6top_flags_reserved,
6662
16
        { "Reserved", "wpan.6top_flags_reserved", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_FLAGS_RESERVED,
6663
16
          NULL, HFILL }},
6664
6665
16
        { &hf_ieee802154_6top_code,
6666
16
        { "Code",  "wpan.6top_code", FT_UINT8, BASE_HEX, NULL, 0x0,
6667
16
          NULL, HFILL }},
6668
6669
16
        { &hf_ieee802154_6top_sfid,
6670
16
        { "SFID (6top Scheduling Function ID)", "wpan.6top_sfid", FT_UINT8, BASE_HEX, NULL, 0x0,
6671
16
          NULL, HFILL }},
6672
6673
16
        { &hf_ieee802154_6top_seqnum,
6674
16
        { "SeqNum", "wpan.6top_seqnum", FT_UINT8, BASE_DEC, NULL, IETF_6TOP_SEQNUM,
6675
16
          NULL, HFILL }},
6676
6677
16
        { &hf_ieee802154_6top_metadata,
6678
16
        { "Metadata", "wpan.6top_metadata", FT_UINT16, BASE_HEX, NULL, 0x0,
6679
16
          NULL, HFILL }},
6680
6681
16
        { &hf_ieee802154_6top_cell_options,
6682
16
          { "Cell Options", "wpan.6top_cell_options", FT_UINT8, BASE_HEX, VALS(ietf_6top_cell_options), 0x0,
6683
16
          NULL, HFILL }},
6684
6685
16
        { &hf_ieee802154_6top_cell_option_tx,
6686
16
        { "Transmit (TX) Cell", "wpan.6top_cell_option_tx", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_TX,
6687
16
          NULL, HFILL }},
6688
6689
16
        { &hf_ieee802154_6top_cell_option_rx,
6690
16
        { "Receive (RX) Cell", "wpan.6top_cell_option_rx", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_RX,
6691
16
          NULL, HFILL }},
6692
6693
16
        { &hf_ieee802154_6top_cell_option_shared,
6694
16
        { "SHARED Cell", "wpan.6top_cell_option_shared", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_SHARED,
6695
16
          NULL, HFILL }},
6696
6697
16
        { &hf_ieee802154_6top_cell_option_reserved,
6698
16
        { "Reserved", "wpan.6top_cell_option_reserved", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_RESERVED,
6699
16
          NULL, HFILL }},
6700
6701
16
        { &hf_ieee802154_6top_num_cells,
6702
16
        { "Number of Cells", "wpan.6top_num_cells", FT_UINT8, BASE_DEC, NULL, 0x0,
6703
16
          NULL, HFILL }},
6704
6705
16
        { &hf_ieee802154_6top_cell_list,
6706
16
        { "CellList", "wpan.6top_cell_list", FT_NONE, BASE_NONE, NULL, 0x0,
6707
16
          NULL, HFILL }},
6708
6709
16
        { &hf_ieee802154_6top_rel_cell_list,
6710
16
        { "Rel. CellList", "wpan.6top_rel_cell_list", FT_NONE, BASE_NONE, NULL, 0x0,
6711
16
          NULL, HFILL }},
6712
6713
16
        { &hf_ieee802154_6top_cand_cell_list,
6714
16
        { "Cand. CellList", "wpan.6top_cand_cell_list", FT_NONE, BASE_NONE, NULL, 0x0,
6715
16
          NULL, HFILL }},
6716
6717
16
        { &hf_ieee802154_6top_cell,
6718
16
        { "Cell", "wpan.6top_cell", FT_BYTES, BASE_NONE, NULL, 0x0,
6719
16
          NULL, HFILL }},
6720
6721
16
        { &hf_ieee802154_6top_reserved,
6722
16
        { "Reserved", "wpan.6top_reserved", FT_UINT8, BASE_HEX, NULL, 0x0,
6723
16
          NULL, HFILL }},
6724
6725
16
        { &hf_ieee802154_6top_offset,
6726
16
        { "Offset", "wpan.6top_offset", FT_UINT16, BASE_DEC, NULL, 0x0,
6727
16
          NULL, HFILL }},
6728
6729
16
        { &hf_ieee802154_6top_max_num_cells,
6730
16
        { "Maximum Number of Requested Cells", "wpan.6top_max_num_cells", FT_UINT16, BASE_DEC, NULL, 0x0,
6731
16
          NULL, HFILL }},
6732
6733
16
        { &hf_ieee802154_6top_slot_offset,
6734
16
        { "Slot Offset", "wpan.6top_cell_slot_offset", FT_UINT16, BASE_HEX, NULL, 0x0,
6735
16
          NULL, HFILL }},
6736
6737
16
        { &hf_ieee802154_6top_channel_offset,
6738
16
        { "Channel Offset", "wpan.6top_channel_offset", FT_UINT16, BASE_HEX, NULL, 0x0,
6739
16
          NULL, HFILL }},
6740
6741
16
        { &hf_ieee802154_6top_total_num_cells,
6742
16
        { "Total Number of Cells", "wpan.6top_total_num_cells", FT_UINT16, BASE_DEC, NULL, 0x0,
6743
16
          NULL, HFILL }},
6744
6745
16
        { &hf_ieee802154_6top_payload,
6746
16
        { "Payload", "wpan.6top_payload", FT_BYTES, BASE_NONE, NULL, 0x0,
6747
16
          NULL, HFILL }},
6748
6749
        /* MPX IE (IEEE 802.15.9) */
6750
16
        { &hf_ieee802159_mpx,
6751
16
          { "MPX IE", "wpan.mpx", FT_NONE, BASE_NONE, NULL, 0x0,
6752
16
            NULL, HFILL }
6753
16
        },
6754
6755
16
        { &hf_ieee802159_mpx_transaction_control,
6756
16
          { "Transaction Control", "wpan.mpx.transaction_control", FT_UINT8, BASE_HEX, NULL, 0x0,
6757
16
            NULL, HFILL }
6758
16
        },
6759
6760
16
        { &hf_ieee802159_mpx_transfer_type,
6761
16
          { "Transfer Type", "wpan.mpx.transfer_type", FT_UINT8, BASE_HEX, VALS(mpx_transfer_type_vals), IEEE802159_MPX_TRANSFER_TYPE_MASK,
6762
16
            NULL, HFILL }
6763
16
        },
6764
6765
16
        { &hf_ieee802159_mpx_transaction_id,
6766
16
          { "Transaction ID", "wpan.mpx.transaction_id", FT_UINT8, BASE_HEX, NULL, IEEE802159_MPX_TRANSACTION_ID_MASK,
6767
16
            NULL, HFILL }
6768
16
        },
6769
6770
16
        { &hf_ieee802159_mpx_transaction_id_as_multiplex_id,
6771
16
          { "Multiplex ID", "wpan.mpx.multiplex_id", FT_UINT8, BASE_HEX, VALS(mpx_multiplex_id_vals), IEEE802159_MPX_TRANSACTION_ID_MASK,
6772
16
            "Transaction ID used as Multiplex ID", HFILL }
6773
16
        },
6774
6775
16
        { &hf_ieee802159_mpx_fragment_number,
6776
16
          { "Fragment Number", "wpan.mpx.fragment_number", FT_UINT8, BASE_DEC, NULL, 0x0,
6777
16
            NULL, HFILL }
6778
16
        },
6779
6780
16
        { &hf_ieee802159_mpx_total_frame_size,
6781
16
          { "Total Frame Size", "wpan.mpx.total_frame_size", FT_UINT16, BASE_DEC, NULL, 0x0,
6782
16
            "Total Upper-Layer Frame Size", HFILL }
6783
16
        },
6784
6785
16
        { &hf_ieee802159_mpx_multiplex_id,
6786
16
          { "Multiplex ID", "wpan.mpx.multiplex_id", FT_UINT16, BASE_HEX, NULL, 0x0,
6787
16
            NULL, HFILL }
6788
16
        },
6789
6790
16
        { &hf_ieee802159_mpx_kmp_id,
6791
16
          { "KMP ID", "wpan.mpx.kmp.id", FT_UINT8, BASE_DEC, VALS(ieee802154_mpx_kmp_id_vals), 0x0,
6792
16
            NULL, HFILL }
6793
16
        },
6794
6795
16
        { &hf_ieee802159_mpx_kmp_vendor_oui,
6796
16
          { "Vendor OUI", "wpan.mpx.kmp.vendor_oui", FT_UINT24, BASE_OUI, NULL, 0x0,
6797
16
            NULL, HFILL }
6798
16
        },
6799
6800
16
        { &hf_ieee802159_mpx_fragment,
6801
16
          { "Upper-Layer Frame Fragment", "wpan.mpx.fragment", FT_BYTES, SEP_SPACE, NULL, 0x0,
6802
16
            NULL, HFILL }
6803
16
        },
6804
6805
16
        { &hf_ieee802159_mpx_wisun_subid,
6806
16
          { "Wi-SUN Multiplex Sub ID", "wpan.mpx.wisun", FT_UINT8, BASE_HEX, VALS(mpx_wisun_subid_vals), 0x0,
6807
16
            NULL, HFILL }
6808
16
        },
6809
6810
        /* Command Frame Specific Fields */
6811
6812
16
        { &hf_ieee802154_cmd_id,
6813
16
        { "Command Identifier",         "wpan.cmd", FT_UINT8, BASE_HEX, VALS(ieee802154_cmd_names), 0x0,
6814
16
            NULL, HFILL }},
6815
6816
16
        { &hf_ieee802154_cmd_vendor_oui,
6817
16
        { "Vendor OUI",                 "wpan.cmd.vendor_oui", FT_UINT24, BASE_OUI, NULL, 0x0,
6818
16
            NULL, HFILL }},
6819
6820
        /*  Capability Information Fields */
6821
6822
16
        { &hf_ieee802154_cinfo_alt_coord,
6823
16
        { "Alternate PAN Coordinator",  "wpan.cinfo.alt_coord", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALT_PAN_COORD,
6824
16
            "Whether this device can act as a PAN coordinator or not.", HFILL }},
6825
6826
16
        { &hf_ieee802154_cinfo_device_type,
6827
16
        { "Device Type",                "wpan.cinfo.device_type", FT_BOOLEAN, 8, TFS(&tfs_cinfo_device_type), IEEE802154_CMD_CINFO_DEVICE_TYPE,
6828
16
            "Whether this device is RFD (reduced-function device) or FFD (full-function device).", HFILL }},
6829
6830
16
        { &hf_ieee802154_cinfo_power_src,
6831
16
        { "Power Source",               "wpan.cinfo.power_src", FT_BOOLEAN, 8, TFS(&tfs_cinfo_power_src), IEEE802154_CMD_CINFO_POWER_SRC,
6832
16
            "Whether this device is operating on AC/mains or battery power.", HFILL }},
6833
6834
16
        { &hf_ieee802154_cinfo_idle_rx,
6835
16
        { "Receive On When Idle",       "wpan.cinfo.idle_rx", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_IDLE_RX,
6836
16
            "Whether this device can receive packets while idle or not.", HFILL }},
6837
6838
16
        { &hf_ieee802154_cinfo_sec_capable,
6839
16
        { "Security Capability",        "wpan.cinfo.sec_capable", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_SEC_CAPABLE,
6840
16
            "Whether this device is capable of receiving encrypted packets.", HFILL }},
6841
6842
16
        { &hf_ieee802154_cinfo_alloc_addr,
6843
16
        { "Allocate Address",           "wpan.cinfo.alloc_addr", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALLOC_ADDR,
6844
16
            "Whether this device wishes to use a 16-bit short address instead of its IEEE 802.15.4 64-bit long address.", HFILL }},
6845
6846
        /*  Association response fields */
6847
6848
16
        { &hf_ieee802154_assoc_addr,
6849
16
        { "Short Address",              "wpan.asoc.addr", FT_UINT16, BASE_HEX, NULL, 0x0,
6850
16
            "The short address that the device should assume. An address of 0xfffe indicates that the device should use its IEEE 64-bit long address.", HFILL }},
6851
6852
16
        { &hf_ieee802154_assoc_status,
6853
16
        { "Association Status",         "wpan.assoc.status", FT_UINT8, BASE_HEX, NULL, 0x0,
6854
16
            NULL, HFILL }},
6855
6856
16
        { &hf_ieee802154_disassoc_reason,
6857
16
        { "Disassociation Reason",      "wpan.disassoc.reason", FT_UINT8, BASE_HEX, NULL, 0x0,
6858
16
            NULL, HFILL }},
6859
6860
        /*  Coordinator Realignment fields */
6861
6862
16
        { &hf_ieee802154_realign_pan,
6863
16
        { "PAN ID",                     "wpan.realign.pan", FT_UINT16, BASE_HEX, NULL, 0x0,
6864
16
            "The PAN identifier the coordinator wishes to use for future communication.", HFILL }},
6865
6866
16
        { &hf_ieee802154_realign_caddr,
6867
16
        { "Coordinator Short Address",  "wpan.realign.caddr", FT_UINT16, BASE_HEX, NULL, 0x0,
6868
16
            "The 16-bit address the coordinator wishes to use for future communication.", HFILL }},
6869
6870
16
        { &hf_ieee802154_realign_channel,
6871
16
        { "Logical Channel",            "wpan.realign.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
6872
16
            "The logical channel the coordinator wishes to use for future communication.", HFILL }},
6873
6874
16
        { &hf_ieee802154_realign_addr,
6875
16
        { "Short Address",              "wpan.realign.addr", FT_UINT16, BASE_HEX, NULL, 0x0,
6876
16
            "A short-address that the orphaned device shall assume if applicable.", HFILL }},
6877
6878
16
        { &hf_ieee802154_realign_channel_page,
6879
16
        { "Channel Page",               "wpan.realign.channel_page", FT_UINT8, BASE_DEC, NULL, 0x0,
6880
16
            "The logical channel page the coordinator wishes to use for future communication.", HFILL }},
6881
6882
16
        { &hf_ieee802154_gtsreq_len,
6883
16
        { "GTS Length",                 "wpan.gtsreq.length", FT_UINT8, BASE_DEC, NULL, IEEE802154_CMD_GTS_REQ_LEN,
6884
16
            "Number of superframe slots the device is requesting.", HFILL }},
6885
6886
16
        { &hf_ieee802154_gtsreq_dir,
6887
16
        { "GTS Direction",              "wpan.gtsreq.direction", FT_BOOLEAN, 8, TFS(&tfs_gtsreq_dir), IEEE802154_CMD_GTS_REQ_DIR,
6888
16
            "The direction of traffic in the guaranteed timeslot.", HFILL }},
6889
6890
16
        { &hf_ieee802154_gtsreq_type,
6891
16
        { "Characteristic Type",        "wpan.gtsreq.type", FT_BOOLEAN, 8, TFS(&tfs_gtsreq_type), IEEE802154_CMD_GTS_REQ_TYPE,
6892
16
            "Whether this request is to allocate or deallocate a timeslot.", HFILL }},
6893
6894
        /* Beacon Frame Specific Fields */
6895
6896
16
        { &hf_ieee802154_beacon_order,
6897
16
        { "Beacon Interval",            "wpan.beacon_order", FT_UINT16, BASE_DEC, NULL, IEEE802154_BEACON_ORDER_MASK,
6898
16
            "Specifies the transmission interval of the beacons.", HFILL }},
6899
6900
16
        { &hf_ieee802154_superframe_order,
6901
16
        { "Superframe Interval",        "wpan.superframe_order", FT_UINT16, BASE_DEC, NULL,
6902
16
            IEEE802154_SUPERFRAME_ORDER_MASK,
6903
16
            "Specifies the length of time the coordinator will interact with the PAN.", HFILL }},
6904
6905
16
        { &hf_ieee802154_cap,
6906
16
        { "Final CAP Slot",             "wpan.cap", FT_UINT16, BASE_DEC, NULL, IEEE802154_SUPERFRAME_CAP_MASK,
6907
16
            "Specifies the final superframe slot used by the CAP.", HFILL }},
6908
6909
16
        { &hf_ieee802154_superframe_battery_ext,
6910
16
        { "Battery Extension",          "wpan.battery_ext", FT_BOOLEAN, 16, NULL, IEEE802154_BATT_EXTENSION_MASK,
6911
16
            "Whether transmissions may not extend past the length of the beacon frame.", HFILL }},
6912
6913
16
        { &hf_ieee802154_superframe_coord,
6914
16
        { "PAN Coordinator",            "wpan.bcn_coord", FT_BOOLEAN, 16, NULL, IEEE802154_SUPERFRAME_COORD_MASK,
6915
16
            "Whether this beacon frame is being transmitted by the PAN coordinator or not.", HFILL }},
6916
6917
16
        { &hf_ieee802154_assoc_permit,
6918
16
        { "Association Permit",         "wpan.assoc_permit", FT_BOOLEAN, 16, NULL, IEEE802154_ASSOC_PERMIT_MASK,
6919
16
            "Whether this PAN is accepting association requests or not.", HFILL }},
6920
6921
16
        { &hf_ieee802154_gts_count,
6922
16
        { "GTS Descriptor Count",       "wpan.gts.count", FT_UINT8, BASE_DEC, NULL, 0x0,
6923
16
            "The number of GTS descriptors present in this beacon frame.", HFILL }},
6924
6925
16
        { &hf_ieee802154_gts_permit,
6926
16
        { "GTS Permit",                 "wpan.gts.permit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
6927
16
            "Whether the PAN coordinator is accepting GTS requests or not.", HFILL }},
6928
6929
16
        { &hf_ieee802154_gts_direction,
6930
16
        { "Direction",                  "wpan.gts.direction", FT_BOOLEAN, BASE_NONE, TFS(&ieee802154_gts_direction_tfs), 0x0,
6931
16
            "A flag defining the direction of the GTS Slot.", HFILL }},
6932
6933
16
        { &hf_ieee802154_gts_address,
6934
16
        { "Address",                    "wpan.gts.address", FT_UINT16, BASE_HEX, NULL, 0x0,
6935
16
            NULL, HFILL }},
6936
6937
16
        { &hf_ieee802154_pending16,
6938
16
        { "Address",                    "wpan.pending16", FT_UINT16, BASE_HEX, NULL, 0x0,
6939
16
            "Device with pending data to receive.", HFILL }},
6940
6941
16
        { &hf_ieee802154_pending64,
6942
16
        { "Address",                    "wpan.pending64", FT_EUI64, BASE_NONE, NULL, 0x0,
6943
16
            "Device with pending data to receive.", HFILL }},
6944
6945
        /* Auxiliary Security Header Fields */
6946
16
        { &hf_ieee802154_aux_security_header,
6947
16
        { "Auxiliary Security Header", "wpan.aux_sec.hdr", FT_NONE, BASE_NONE, NULL,
6948
16
            0x0, "The Auxiliary Security Header of the frame", HFILL }},
6949
6950
16
        { &hf_ieee802154_aux_sec_security_level,
6951
16
        { "Security Level", "wpan.aux_sec.sec_level", FT_UINT8, BASE_HEX, VALS(ieee802154_sec_level_names),
6952
16
            IEEE802154_AUX_SEC_LEVEL_MASK, "The Security Level of the frame", HFILL }},
6953
6954
16
        { &hf_ieee802154_aux_sec_security_control,
6955
16
        { "Security Control Field", "wpan.aux_sec.security_control_field", FT_UINT8, BASE_HEX, NULL,
6956
16
            0x0, NULL, HFILL }},
6957
6958
16
        { &hf_ieee802154_aux_sec_key_id_mode,
6959
16
        { "Key Identifier Mode", "wpan.aux_sec.key_id_mode", FT_UINT8, BASE_HEX, VALS(ieee802154_key_id_mode_names),
6960
16
            IEEE802154_AUX_KEY_ID_MODE_MASK,
6961
16
            "The scheme to use by the recipient to lookup the key in its key table", HFILL }},
6962
6963
16
        { &hf_ieee802154_aux_sec_frame_counter_suppression,
6964
16
        { "Frame Counter Suppression", "wpan.aux_sec.frame_counter_suppression", FT_BOOLEAN, 8, NULL,
6965
16
            IEEE802154_AUX_FRAME_COUNTER_SUPPRESSION_MASK,
6966
16
            "Whether the frame counter is omitted from the Auxiliary Security Header", HFILL }},
6967
6968
16
        { &hf_ieee802154_aux_sec_asn_in_nonce,
6969
16
        { "ASN in Nonce", "wpan.aux_sec.asn_in_nonce", FT_BOOLEAN, 8, NULL,
6970
16
            IEEE802154_AUX_ASN_IN_NONCE_MASK,
6971
16
            "Whether the ASN is used to generate the nonce instead of the frame counter", HFILL }},
6972
6973
16
        { &hf_ieee802154_aux_sec_reserved,
6974
16
        { "Reserved", "wpan.aux_sec.reserved", FT_UINT8, BASE_HEX, NULL, IEEE802154_AUX_CTRL_RESERVED_MASK,
6975
16
            NULL, HFILL }},
6976
6977
16
        { &hf_ieee802154_aux_sec_frame_counter,
6978
16
        { "Frame Counter", "wpan.aux_sec.frame_counter", FT_UINT32, BASE_DEC, NULL, 0x0,
6979
16
            "Frame counter of the originator of the protected frame", HFILL }},
6980
6981
16
        { &hf_ieee802154_aux_sec_key_source,
6982
16
        { "Key Source", "wpan.aux_sec.key_source", FT_UINT64, BASE_HEX, NULL, 0x0,
6983
16
            "Key Source for processing of the protected frame", HFILL }},
6984
6985
16
        { &hf_ieee802154_aux_sec_key_source_bytes,
6986
16
        { "Key Source", "wpan.aux_sec.key_source.bytes", FT_BYTES, BASE_NONE, NULL, 0x0,
6987
16
            "Key Source for processing of the protected frame", HFILL }},
6988
6989
16
        { &hf_ieee802154_aux_sec_key_index,
6990
16
        { "Key Index", "wpan.aux_sec.key_index", FT_UINT8, BASE_HEX, NULL, 0x0,
6991
16
            "Key Index for processing of the protected frame", HFILL }},
6992
6993
16
        { &hf_ieee802154_mic,
6994
16
        { "MIC", "wpan.mic", FT_BYTES, BASE_NONE, NULL, 0x0,
6995
16
            NULL, HFILL }},
6996
6997
16
        { &hf_ieee802154_key_number,
6998
16
        { "Key Number", "wpan.key_number", FT_UINT8, BASE_DEC, NULL, 0x0,
6999
16
            "Key number used to decode", HFILL }},
7000
7001
        /* IEEE 802.15.4-2003 Security Header Fields */
7002
16
        { &hf_ieee802154_sec_frame_counter,
7003
16
        { "Frame Counter", "wpan.sec_frame_counter", FT_UINT32, BASE_HEX, NULL, 0x0,
7004
16
            "Frame counter of the originator of the protected frame (802.15.4-2003)", HFILL }},
7005
7006
16
        { &hf_ieee802154_sec_key_sequence_counter,
7007
16
        { "Key Sequence Counter", "wpan.sec_key_sequence_counter", FT_UINT8, BASE_HEX, NULL, 0x0,
7008
16
            "Key Sequence counter of the originator of the protected frame (802.15.4-2003)", HFILL }},
7009
7010
16
        { &hf_ieee802154_no_ack,
7011
16
        { "No ack found", "wpan.no_ack", FT_NONE, BASE_NONE, NULL, 0x0,
7012
16
            "No corresponding ack frame was found", HFILL }},
7013
7014
16
        { &hf_ieee802154_no_ack_request,
7015
16
        { "No request found", "wpan.no_ack_request", FT_NONE, BASE_NONE, NULL, 0x0,
7016
16
            "No corresponding request frame was found", HFILL }},
7017
7018
16
        { &hf_ieee802154_ack_in,
7019
16
        { "Ack In", "wpan.ack_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
7020
16
            "The ack to this request is in this frame", HFILL }},
7021
7022
16
        { &hf_ieee802154_ack_to,
7023
16
        { "Ack To", "wpan.ack_to", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_ACK), 0x0,
7024
16
            "This is the ack to the request in this frame", HFILL }},
7025
7026
16
        { &hf_ieee802154_ack_time,
7027
16
        { "Ack Time", "wpan.ack_time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
7028
16
            "The time between the request and the ack", HFILL }},
7029
7030
        /* ZBOSS dump */
7031
7032
16
        { &hf_zboss_page,
7033
16
        { "Page", "wpan-zboss.page", FT_UINT8, BASE_DEC_HEX, VALS(zboss_page_names), 0xFE,
7034
16
            "IEEE802.15.4 page number", HFILL } },
7035
7036
16
        { &hf_zboss_channel,
7037
16
        { "Channel", "wpan-zboss.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
7038
16
            "Channel number", HFILL }},
7039
7040
16
        { &hf_zboss_direction,
7041
16
        { "ZBOSS Direction", "wpan-zboss.direction", FT_UINT8, BASE_HEX, VALS(zboss_direction_names), 0x01,
7042
16
            "ZBOSS Packet Direction", HFILL }},
7043
7044
16
        { &hf_zboss_trace_number,
7045
16
        { "Trace number", "wpan-zboss.trace", FT_UINT32, BASE_DEC, NULL, 0x0,
7046
16
            "Trace item number", HFILL }},
7047
7048
        /* TAP Packet Fields */
7049
16
        { &hf_ieee802154_tap_version,
7050
16
        { "Version",        "wpan-tap.version", FT_UINT8, BASE_DEC, NULL, 0x0,
7051
16
            "TAP Packet Version", HFILL }},
7052
7053
16
        { &hf_ieee802154_tap_reserved,
7054
16
        { "Reserved",        "wpan-tap.reserved", FT_UINT8, BASE_DEC, NULL, 0x0,
7055
16
            "TAP Packet Reserved", HFILL }},
7056
7057
16
        { &hf_ieee802154_tap_length,
7058
16
        { "Length",        "wpan-tap.length", FT_UINT16, BASE_DEC, NULL, 0x0,
7059
16
            "TAP Packet Length", HFILL }},
7060
7061
16
        { &hf_ieee802154_tap_data_length,
7062
16
        { "Data Length",   "wpan-tap.data_length", FT_UINT16, BASE_DEC, NULL, 0x0,
7063
16
            "IEEE 802.15.4 Data Length", HFILL }},
7064
7065
16
        { &hf_ieee802154_tap_tlv_type,
7066
16
        { "TLV Type",       "wpan-tap.tlv.type", FT_UINT16, BASE_DEC, VALS(tap_tlv_types), 0x0,
7067
16
            NULL, HFILL }},
7068
7069
16
        { &hf_ieee802154_tap_tlv_length,
7070
16
        { "TLV Length",       "wpan-tap.tlv.length", FT_UINT16, BASE_DEC, NULL, 0x0,
7071
16
            NULL, HFILL }},
7072
7073
16
        { &hf_ieee802154_tap_tlv_unknown,
7074
16
        { "Unknown",                "wpan-tap.tlv.unknown", FT_BYTES, BASE_NONE, NULL, 0x0,
7075
16
            NULL, HFILL }},
7076
7077
16
        { &hf_ieee802154_tap_tlv_padding,
7078
16
        { "Padding",                "wpan-tap.tlv.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
7079
16
            NULL, HFILL }},
7080
7081
16
        { &hf_ieee802154_tap_fcs_type,
7082
16
        { "FCS Type",       "wpan-tap.fcs_type", FT_UINT8, BASE_DEC, VALS(tap_fcs_type_names), 0x0,
7083
16
            NULL, HFILL }},
7084
7085
16
        { &hf_ieee802154_tap_rss,
7086
16
        { "RSS",           "wpan-tap.rss", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_dbm), 0x0,
7087
16
            NULL, HFILL }},
7088
7089
16
        { &hf_ieee802154_ch_num,
7090
16
        { "Channel",        "wpan-tap.ch_num", FT_UINT16, BASE_DEC, NULL, 0x0,
7091
16
            "Channel number", HFILL }},
7092
7093
16
        { &hf_ieee802154_ch_page,
7094
16
        { "Page",           "wpan-tap.ch_page", FT_UINT8, BASE_DEC, VALS(channel_page_names), 0x0,
7095
16
            "Channel page", HFILL }},
7096
7097
16
        { &hf_ieee802154_bit_rate,
7098
16
        { "Bit Rate",       "wpan-tap.bit_rate", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_sec), 0x0,
7099
16
            NULL, HFILL }},
7100
7101
16
        { &hf_ieee802154_sun_band,
7102
16
        { "Band",           "wpan-tap.sun_band", FT_UINT8, BASE_DEC, VALS(sun_bands), 0x0,
7103
16
            NULL, HFILL }},
7104
7105
16
        { &hf_ieee802154_sun_type,
7106
16
        { "Type",           "wpan-tap.sun_type", FT_UINT8, BASE_DEC, VALS(sun_types), 0x0,
7107
16
            NULL, HFILL }},
7108
7109
16
        { &hf_ieee802154_sun_mode,
7110
16
        { "Mode",           "wpan-tap.sun_mode", FT_UINT8, BASE_DEC, NULL, 0x0,
7111
16
            NULL, HFILL }},
7112
7113
16
        { &hf_ieee802154_mode_fsk_a,
7114
16
        { "FSK-A mode",     "wpan-tap.mode.fsk_a", FT_UINT8, BASE_DEC, VALS(fsk_a_modes), 0x0,
7115
16
            NULL, HFILL }},
7116
7117
16
        { &hf_ieee802154_mode_fsk_b,
7118
16
        { "FSK-B mode",     "wpan-tap.mode.fsk_b", FT_UINT8, BASE_DEC, VALS(fsk_b_modes), 0x0,
7119
16
            NULL, HFILL }},
7120
7121
16
        { &hf_ieee802154_mode_oqpsk_a,
7122
16
        { "O-QPSK-A mode",   "wpan-tap.mode.oqpsk_a", FT_UINT8, BASE_DEC, VALS(oqpsk_a_modes), 0x0,
7123
16
            NULL, HFILL }},
7124
7125
16
        { &hf_ieee802154_mode_oqpsk_b,
7126
16
        { "O-QPSK-B mode",   "wpan-tap.mode.oqpsk_b", FT_UINT8, BASE_DEC, VALS(oqpsk_b_modes), 0x0,
7127
16
            NULL, HFILL }},
7128
7129
16
        { &hf_ieee802154_mode_oqpsk_c,
7130
16
        { "O-QPSK-C mode",   "wpan-tap.mode.oqpsk_c", FT_UINT8, BASE_DEC, VALS(oqpsk_c_modes), 0x0,
7131
16
            NULL, HFILL }},
7132
7133
16
        { &hf_ieee802154_mode_ofdm,
7134
16
        { "OFDM mode",       "wpan-tap.mode.ofdm", FT_UINT8, BASE_DEC, VALS(ofdm_modes), 0x0,
7135
16
            NULL, HFILL }},
7136
7137
16
        { &hf_ieee802154_sof_ts,
7138
16
        { "Start of frame timestamp",   "wpan-tap.sof_ts", FT_UINT64, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0,
7139
16
            NULL, HFILL }},
7140
7141
16
        { &hf_ieee802154_eof_ts,
7142
16
        { "End of frame timestamp",     "wpan-tap.eof_ts", FT_UINT64, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0,
7143
16
            NULL, HFILL }},
7144
7145
16
        { &hf_ieee802154_slot_start_ts,
7146
16
        { "Start of slot timestamp",    "wpan-tap.slot_start_ts", FT_UINT64, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0,
7147
16
            NULL, HFILL }},
7148
7149
16
        { &hf_ieee802154_tap_timeslot_length,
7150
16
        { "Timeslot length",            "wpan-tap.timeslot_length", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0,
7151
16
            NULL, HFILL }},
7152
7153
16
        { &hf_ieee802154_tap_lqi,
7154
16
        { "Link Quality Indicator",     "wpan-tap.lqi", FT_UINT8, BASE_DEC, NULL, 0x0,
7155
16
            NULL, HFILL }},
7156
7157
16
        { &hf_ieee802154_chplan_start,
7158
16
        { "Channel0 freq",              "wpan-tap.chplan.start", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_khz), 0x0,
7159
16
            "Channel 0 center frequency", HFILL }},
7160
7161
16
        { &hf_ieee802154_chplan_spacing,
7162
16
        { "Spacing",                    "wpan-tap.chplan.spacing", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_khz), 0x0,
7163
16
            "Channel spacing", HFILL }},
7164
7165
16
        { &hf_ieee802154_chplan_channels,
7166
16
        { "Channels",                   "wpan-tap.chplan.channels", FT_UINT16, BASE_DEC, NULL, 0x0,
7167
16
            "Number of channels", HFILL }},
7168
7169
16
        { &hf_ieee802154_ch_freq,
7170
16
        { "Frequency",                  "wpan-tap.ch_freq", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_khz), 0x0,
7171
16
            "Channel center frequency", HFILL }},
7172
7173
16
        { &hf_ieee802154_frame_start_offset,
7174
16
        { "Frame start offset",       "wpan.tsch.frame_start_offset", FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0,
7175
16
            "Start of frame timestamp - start of slot timestamp", HFILL }},
7176
7177
16
        { &hf_ieee802154_frame_duration,
7178
16
        { "Frame duration",           "wpan.tsch.frame_duration", FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0,
7179
16
            "End of frame timestamp - start of frame timestamp", HFILL }},
7180
7181
16
        { &hf_ieee802154_frame_end_offset,
7182
16
        { "Frame end offset", "wpan.tsch.frame_end_offset", FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0,
7183
16
            "End of frame timestamp - (start of slot timestamp + timeslot length)", HFILL }},
7184
7185
16
        { &hf_ieee802154_asn,
7186
16
        { "ASN", "wpan-tap.asn", FT_UINT64, BASE_DEC, NULL, 0x0,
7187
16
            "Absolute Slot Number", HFILL }},
7188
7189
16
        { &hf_ieee802154_tap_phr_type,
7190
16
        { "PHR Type",       "wpan-tap.phr.type", FT_UINT16, BASE_DEC, VALS(ieee802154_phr_type_vals), 0x0,
7191
16
            NULL, HFILL }},
7192
7193
16
        { &hf_ieee802154_tap_phr_bits,
7194
16
        { "PHR Bits",       "wpan-tap.phr.bits", FT_UINT16, BASE_DEC, NULL, 0x0,
7195
16
            NULL, HFILL }},
7196
7197
16
        { &hf_ieee802154_tap_phr_data,
7198
16
        { "PHR Data",       "wpan-tap.phr.data", FT_BYTES, BASE_NONE, NULL, 0x0,
7199
16
            NULL, HFILL }},
7200
7201
16
        { &hf_ieee802154_tap_phr_fsk,
7202
16
        { "FSK PHR",        "wpan-tap.phr.fsk", FT_UINT16, BASE_HEX, NULL, 0x0,
7203
16
            NULL, HFILL }},
7204
7205
16
        { &hf_ieee802154_tap_fsk_ms_phr,
7206
16
        { "FSK Mode Switch PHR", "wpan-tap.phr.fsk_ms", FT_UINT16, BASE_HEX, NULL, 0x0,
7207
16
            NULL, HFILL }},
7208
7209
16
        { &hf_ieee802154_tap_wisun_ms_phr,
7210
16
        { "Wi-SUN Mode Switch PHR", "wpan-tap.phr.wisun_ms", FT_UINT16, BASE_HEX, NULL, 0x0,
7211
16
            NULL, HFILL }},
7212
7213
16
        { &hf_ieee802154_tap_phr_fsk_ms,
7214
16
        { "MS",             "wpan-tap.phr.fsk.ms", FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), IEEE802154_TAP_PHR_FSK_MS,
7215
16
            "Mode Switch", HFILL }},
7216
7217
16
        { &hf_ieee802154_tap_phr_fsk_fcs,
7218
16
        { "FCS Type",    "wpan-tap.phr.fsk.fcs", FT_BOOLEAN, 16, TFS(&tfs_fcs_type), IEEE802154_TAP_PHR_FSK_FCS,
7219
16
            NULL, HFILL }},
7220
7221
16
        { &hf_ieee802154_tap_phr_fsk_dw,
7222
16
        { "DW",             "wpan-tap.phr.fsk.dw", FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), IEEE802154_TAP_PHR_FSK_DW,
7223
16
            "Data Whitening", HFILL }},
7224
7225
16
        { &hf_ieee802154_tap_phr_fsk_length,
7226
16
        { "Frame Length",   "wpan-tap.phr.fsk.length", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_LENGTH,
7227
16
            NULL, HFILL }},
7228
7229
16
        { &hf_ieee802154_tap_phr_fsk_ms_param,
7230
16
        { "Parameter",      "wpan-tap.phr.fsk_ms.length", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_MS_PARAM,
7231
16
            "Mode Switch Parameter", HFILL }},
7232
7233
16
        { &hf_ieee802154_tap_phr_fsk_ms_fec,
7234
16
        { "FEC",            "wpan-tap.phr.fsk_ms.fec", FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), IEEE802154_TAP_PHR_FSK_MS_FEC,
7235
16
            "New Mode FEC", HFILL }},
7236
7237
16
        { &hf_ieee802154_tap_phr_fsk_ms_checksum,
7238
16
        { "Checksum",       "wpan-tap.phr.fsk_ms.checksum", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_MS_CHECKSUM,
7239
16
            "BCH(15,11) checksum", HFILL }},
7240
7241
16
        { &hf_ieee802154_tap_phr_fsk_ms_parity,
7242
16
        { "Parity",         "wpan-tap.phr.fsk_ms.parity", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_MS_PARITY,
7243
16
            "Parity Check bit", HFILL }},
7244
7245
16
        { &hf_ieee802154_tap_phr_fsk_ms_mode_page,
7246
16
        { "Page",        "wpan-tap.phr.fsk_ms.page", FT_UINT16, BASE_HEX, VALS(vals_fsk_ms_page), IEEE802154_TAP_PHR_FSK_MS_MODE_PAGE,
7247
16
            "New Mode Page", HFILL }},
7248
7249
16
        { &hf_ieee802154_tap_phr_fsk_ms_mode_scheme,
7250
16
        { "Scheme",        "wpan-tap.phr.fsk_ms.scheme", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_fsk_ms_scheme), IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME,
7251
16
            "New Mode Modulation Scheme", HFILL }},
7252
7253
16
        { &hf_ieee802154_tap_phr_fsk_ms_mode_mode,
7254
16
        { "Mode",  "wpan-tap.phr.fsk_ms.mode", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_fsk_ms_mode), IEEE802154_TAP_PHR_FSK_MS_MODE_MODE,
7255
16
            "New Mode Mode", HFILL }},
7256
7257
16
        { &hf_ieee802154_tap_phr_fsk_ms_mode_addl_mode,
7258
16
        { "Additional Mode",  "wpan-tap.phr.fsk_ms.mode", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_fsk_ms_additional_modes), IEEE802154_TAP_PHR_FSK_MS_MODE_MODE,
7259
16
            "New Mode Additional Mode", HFILL }},
7260
7261
16
        { &hf_ieee802154_tap_phr_wisun_fsk_ms_reserved,
7262
16
        { "Reserved",       "wpan-tap.phr.wisun_ms.reserved", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_WISUN_FSK_MS_RESERVED,
7263
16
            NULL, HFILL }},
7264
7265
16
        { &hf_ieee802154_tap_phr_wisun_fsk_ms_phymodeid,
7266
16
        { "PhyModeId",  "wpan-tap.phr.wisun_ms.phymodeid", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_wisun_phymodeid), IEEE802154_TAP_PHR_WISUN_FSK_MS_PHYMODEID,
7267
16
            "New Wi-SUN PhyModeId", HFILL }},
7268
16
    };
7269
7270
    /* Subtrees */
7271
16
    static int *ett[] = {
7272
16
        &ett_ieee802154_nonask_phy,
7273
16
        &ett_ieee802154_nonask_phy_phr,
7274
16
        &ett_ieee802154_tap,
7275
16
        &ett_ieee802154_tap_header,
7276
16
        &ett_ieee802154_tap_tlv,
7277
16
        &ett_ieee802154,
7278
16
        &ett_ieee802154_fcf,
7279
16
        &ett_ieee802154_auxiliary_security,
7280
16
        &ett_ieee802154_aux_sec_control,
7281
16
        &ett_ieee802154_aux_sec_key_id,
7282
16
        &ett_ieee802154_fcs,
7283
16
        &ett_ieee802154_cmd,
7284
16
        &ett_ieee802154_superframe,
7285
16
        &ett_ieee802154_gts,
7286
16
        &ett_ieee802154_gts_direction,
7287
16
        &ett_ieee802154_gts_descriptors,
7288
16
        &ett_ieee802154_pendaddr,
7289
16
        &ett_ieee802154_header_ies,
7290
16
        &ett_ieee802154_header_ie,
7291
16
        &ett_ieee802154_header_ie_tlv,
7292
16
        &ett_ieee802154_hie_unsupported,
7293
16
        &ett_ieee802154_hie_time_correction,
7294
16
        &ett_ieee802154_hie_ht,
7295
16
        &ett_ieee802154_hie_thread,
7296
16
        &ett_ieee802154_hie_csl,
7297
16
        &ett_ieee802154_hie_rdv,
7298
16
        &ett_ieee802154_hie_global_time,
7299
16
        &ett_ieee802154_hie_vendor_specific,
7300
16
        &ett_ieee802154_payload_ie,
7301
16
        &ett_ieee802154_payload_ie_tlv,
7302
16
        &ett_ieee802154_pie_termination,
7303
16
        &ett_ieee802154_pie_vendor,
7304
16
        &ett_ieee802159_mpx,
7305
16
        &ett_ieee802159_mpx_transaction_control,
7306
16
        &ett_ieee802154_pie_ietf,
7307
16
        &ett_ieee802154_pie_unsupported,
7308
16
        &ett_ieee802154_tsch_slotframe,
7309
16
        &ett_ieee802154_tsch_slotframe_list,
7310
16
        &ett_ieee802154_tsch_slotframe_link,
7311
16
        &ett_ieee802154_tsch_slotframe_link_options,
7312
16
        &ett_ieee802154_tsch_timeslot,
7313
16
        &ett_ieee802154_tsch_synch,
7314
16
        &ett_ieee802154_channel_hopping,
7315
16
        &ett_ieee802154_mlme,
7316
16
        &ett_ieee802154_mlme_payload,
7317
16
        &ett_ieee802154_mlme_payload_data,
7318
16
        &ett_ieee802154_mlme_unsupported,
7319
16
        &ett_ieee802154_psie,
7320
16
        &ett_ieee802154_eb_filter,
7321
16
        &ett_ieee802154_eb_filter_bitmap,
7322
16
        &ett_ieee802154_zigbee,
7323
16
        &ett_ieee802154_zboss,
7324
16
        &ett_ieee802154_p_ie_6top,
7325
16
        &ett_ieee802154_p_ie_6top_cell_options,
7326
16
        &ett_ieee802154_p_ie_6top_cell_list,
7327
16
        &ett_ieee802154_p_ie_6top_rel_cell_list,
7328
16
        &ett_ieee802154_p_ie_6top_cand_cell_list,
7329
16
        &ett_ieee802154_p_ie_6top_cell,
7330
16
        &ett_ieee802154_tap_phr,
7331
16
    };
7332
7333
16
    static ei_register_info ei[] = {
7334
16
        { &ei_ieee802154_fcs_bitmask_len, { "wpan.bitmask_len_error", PI_UNDECODED, PI_WARN,
7335
16
                "Only least-significant bytes decoded", EXPFILL }},
7336
16
        { &ei_ieee802154_invalid_addressing, { "wpan.invalid_addressing", PI_MALFORMED, PI_WARN,
7337
16
                "Invalid Addressing", EXPFILL }},
7338
16
        { &ei_ieee802154_invalid_panid_compression, { "wpan.invalid_panid_compression", PI_MALFORMED, PI_ERROR,
7339
16
                "Invalid Setting for PAN ID Compression", EXPFILL }},
7340
16
        { &ei_ieee802154_invalid_panid_compression2, { "wpan.invalid_panid_compression2", PI_MALFORMED, PI_ERROR,
7341
16
                "Invalid Pan ID Compression and addressing combination for Frame Version 2", EXPFILL }},
7342
16
        { &ei_ieee802154_dst, { "wpan.dst_invalid", PI_MALFORMED, PI_ERROR,
7343
16
                "Invalid Destination Address Mode", EXPFILL }},
7344
16
        { &ei_ieee802154_src, { "wpan.src_invalid", PI_MALFORMED, PI_ERROR,
7345
16
                "Invalid Source Address Mode", EXPFILL }},
7346
16
        { &ei_ieee802154_frame_ver,  { "wpan.frame_version_unknown", PI_MALFORMED, PI_ERROR,
7347
16
                "Frame Version Unknown Cannot Dissect", EXPFILL }},
7348
#if 0
7349
        { &ei_ieee802154_frame_type, { "wpan.frame_type_unknown", PI_MALFORMED, PI_ERROR,
7350
                "Frame Type Unknown Cannot Dissect", EXPFILL }},
7351
#endif
7352
16
        { &ei_ieee802154_decrypt_error, { "wpan.decrypt_error", PI_UNDECODED, PI_WARN,
7353
16
                "Decryption error", EXPFILL }},
7354
16
        { &ei_ieee802154_fcs, { "wpan.fcs.bad", PI_CHECKSUM, PI_WARN,
7355
16
                "Bad FCS", EXPFILL }},
7356
16
        { &ei_ieee802154_ack_not_found, { "wpan.ack_not_found",  PI_SEQUENCE, PI_NOTE,
7357
16
                "Ack not found", EXPFILL }},
7358
16
        { &ei_ieee802154_ack_request_not_found, { "wpan.ack_request_not_found",  PI_SEQUENCE, PI_NOTE,
7359
16
                "Request not found", EXPFILL }},
7360
16
        { &ei_ieee802154_seqno_suppression, { "wpan.seqno_suppression_invalid",  PI_MALFORMED, PI_WARN,
7361
16
                "Sequence Number Suppression invalid for 802.15.4-2003 and 2006", EXPFILL }},
7362
16
        { &ei_ieee802154_6top_unsupported_type, { "wpan.6top_unsupported_type", PI_PROTOCOL, PI_WARN,
7363
16
                "Unsupported Type of Message", EXPFILL }},
7364
16
        { &ei_ieee802154_6top_unsupported_command, { "wpan.6top_unsupported_command", PI_PROTOCOL, PI_WARN,
7365
16
                "Unsupported 6top command", EXPFILL }},
7366
16
        { &ei_ieee802154_time_correction_error, { "wpan.time_correction.error", PI_PROTOCOL, PI_WARN,
7367
16
                "Incorrect value. Reference: IEEE-802.15.4-2015. Table 7-8: Values of the Time Sync Info field for ACK with timing information", EXPFILL}},
7368
16
        { &ei_ieee802154_6top_unsupported_return_code, { "wpan.6top_unsupported_code", PI_PROTOCOL, PI_WARN,
7369
16
                "Unsupported 6top return code", EXPFILL }},
7370
16
        { &ei_ieee802154_ie_unsupported_id, { "wpan.ie_unsupported_id", PI_PROTOCOL, PI_WARN,
7371
16
                "Unsupported IE ID", EXPFILL }},
7372
16
        { &ei_ieee802154_ie_unknown_extra_content, { "wpan.ie_unknown_extra_content", PI_PROTOCOL, PI_WARN,
7373
16
                "Unexpected extra content for IE", EXPFILL }},
7374
16
        { &ei_ieee802154_ie_unknown_extra_content_payload, { "wpan.ie_unknown_extra_content_payload", PI_PROTOCOL, PI_WARN,
7375
16
                "Unexpected extra content for IE payload", EXPFILL }},
7376
16
        { &ei_ieee802159_mpx_invalid_transfer_type, { "wpan.payload_ie.mpx.invalid_transfer_type", PI_PROTOCOL, PI_WARN,
7377
16
                "Invalid transfer type (cf. IEEE 802.15.9 Table 19)", EXPFILL }},
7378
16
        { &ei_ieee802159_mpx_unsupported_kmp, { "wpan.mpx.unsupported_kmp", PI_PROTOCOL, PI_WARN,
7379
16
                "Unsupported KMP ID", EXPFILL }},
7380
16
        { &ei_ieee802159_mpx_unknown_kmp, { "wpan.mpx.unknown_kmp", PI_PROTOCOL, PI_WARN,
7381
16
                "Unknown KMP ID (cf. IEEE 802.15.9 Table 21)", EXPFILL }},
7382
16
        { &ei_ieee802154_missing_payload_ie, { "wpan.payload_ie.missing",  PI_MALFORMED, PI_WARN,
7383
16
                "Payload IE indicated by Header Termination, but no Payload IE present", EXPFILL }},
7384
16
        { &ei_ieee802154_payload_ie_in_header, { "wpan.payload_ie.in_header",  PI_MALFORMED, PI_WARN,
7385
16
                "Payload IE in header", EXPFILL }},
7386
16
        { &ei_ieee802154_unsupported_cmd, { "wpan.cmd.unsupported_cmd", PI_PROTOCOL, PI_WARN,
7387
16
                "Unsupported Command ID", EXPFILL }},
7388
16
        { &ei_ieee802154_unknown_cmd, { "wpan.cmd.unknown_cmd", PI_PROTOCOL, PI_WARN,
7389
16
                "Unknown Command Id (cf. IEEE 802.15.4-2015 Table 7-49)", EXPFILL }},
7390
16
        { &ei_ieee802154_tap_tlv_invalid_type, { "wpan-tap.tlv.invalid_type", PI_MALFORMED, PI_WARN,
7391
16
                "Invalid TLV type", EXPFILL }},
7392
16
        { &ei_ieee802154_tap_tlv_invalid_length, { "wpan-tap.tlv.invalid_length", PI_MALFORMED, PI_WARN,
7393
16
                "Invalid TLV length", EXPFILL }},
7394
16
        { &ei_ieee802154_tap_tlv_padding_not_zeros, { "wpan-tap.tlv.padding_not_zeros", PI_MALFORMED, PI_WARN,
7395
16
                "TLV padding not zero", EXPFILL }},
7396
16
        { &ei_ieee802154_tap_tlv_invalid_fcs_type, { "wpan-tap.tlv.invalid_fcs_type", PI_MALFORMED, PI_ERROR,
7397
16
                "Invalid FCS type", EXPFILL }},
7398
16
        { &ei_ieee802154_tap_tlv_reserved_not_zero, { "wpan-tap.tlv.reserved_not_zero", PI_PROTOCOL, PI_WARN,
7399
16
                "Reserved bits not zero", EXPFILL }},
7400
16
        { &ei_ieee802154_tap_no_payload, { "wpan-tap.tlv.no_payload", PI_COMMENTS_GROUP, PI_COMMENT,
7401
16
                "No payload", EXPFILL }},
7402
16
    };
7403
7404
    /* Preferences. */
7405
16
    module_t *ieee802154_module;
7406
16
    expert_module_t* expert_ieee802154;
7407
7408
16
    static uat_field_t addr_uat_flds[] = {
7409
16
        UAT_FLD_HEX(addr_uat,addr16,"Short Address",
7410
16
                "16-bit short address in hexadecimal."),
7411
16
        UAT_FLD_HEX(addr_uat,pan,"PAN Identifier",
7412
16
                "16-bit PAN identifier in hexadecimal."),
7413
16
        UAT_FLD_BUFFER(addr_uat,eui64,"EUI-64",
7414
16
                "64-bit extended unique identifier."),
7415
16
        UAT_END_FIELDS
7416
16
    };
7417
7418
16
    static uat_field_t key_uat_flds[] = {
7419
16
        UAT_FLD_CSTRING(key_uat,pref_key,"Decryption key",
7420
16
                "128-bit decryption key in hexadecimal format"),
7421
16
        UAT_FLD_DEC(key_uat,key_index,"Decryption key index",
7422
16
                "Key index in decimal format"),
7423
16
        UAT_FLD_VS(key_uat, hash_type, "Key hash", ieee802154_key_hash_vals, "Specifies which hash scheme is used to derived the key"),
7424
16
        UAT_END_FIELDS
7425
16
    };
7426
7427
16
    static const enum_val_t fcs_type_vals[] = {
7428
16
        {"cc24xx", "TI CC24xx metadata",    IEEE802154_CC24XX_METADATA},
7429
16
        {"16",     "ITU-T CRC-16",          IEEE802154_FCS_16_BIT},
7430
16
        {"32",     "ITU-T CRC-32",          IEEE802154_FCS_32_BIT},
7431
16
        {NULL, NULL, -1}
7432
16
    };
7433
7434
16
    static build_valid_func     ieee802154_da_build_value[1] = {ieee802154_da_value};
7435
16
    static decode_as_value_t    ieee802154_da_values = {ieee802154_da_prompt, 1, ieee802154_da_build_value};
7436
16
    static decode_as_t          ieee802154_da = {
7437
16
        IEEE802154_PROTOABBREV_WPAN, IEEE802154_PROTOABBREV_WPAN_PANID,
7438
16
        1, 0, &ieee802154_da_values, NULL, NULL,
7439
16
        decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL
7440
16
    };
7441
7442
    /* Register the init routine. */
7443
16
    register_init_routine(proto_init_ieee802154);
7444
16
    register_cleanup_routine(proto_cleanup_ieee802154);
7445
7446
    /*  Register Protocol name and description. */
7447
16
    proto_ieee802154 = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN", "IEEE 802.15.4",
7448
16
           IEEE802154_PROTOABBREV_WPAN);
7449
16
    proto_ieee802154_nonask_phy = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN non-ASK PHY",
7450
16
            "IEEE 802.15.4 non-ASK PHY", "wpan-nonask-phy");
7451
16
    proto_zboss = proto_register_protocol("ZBOSS IEEE 802.15.4 dump",
7452
16
                                          "ZBOSS dump", "wpan-zboss");
7453
16
    proto_ieee802154_tap = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN TAP",
7454
16
                                          "IEEE 802.15.4 TAP", "wpan-tap");
7455
7456
    /*  Register header fields and subtrees. */
7457
16
    proto_register_field_array(proto_ieee802154, hf, array_length(hf));
7458
16
    proto_register_field_array(proto_ieee802154, hf_phy, array_length(hf_phy));
7459
7460
16
    proto_register_subtree_array(ett, array_length(ett));
7461
7462
16
    expert_ieee802154 = expert_register_protocol(proto_ieee802154);
7463
16
    expert_register_field_array(expert_ieee802154, ei, array_length(ei));
7464
7465
16
    ieee802_15_4_short_address_type = address_type_dissector_register("AT_IEEE_802_15_4_SHORT", "IEEE 802.15.4 16-bit short address",
7466
16
                                        ieee802_15_4_short_address_to_str, ieee802_15_4_short_address_str_len, NULL, NULL, ieee802_15_4_short_address_len, NULL, NULL);
7467
7468
    /* add a user preference to set the 802.15.4 ethertype */
7469
16
    ieee802154_module = prefs_register_protocol(proto_ieee802154,
7470
16
                                   proto_reg_handoff_ieee802154);
7471
16
    prefs_register_uint_preference(ieee802154_module, "802154_ethertype",
7472
16
                                   "802.15.4 Ethertype (in hex)",
7473
16
                                   "(Hexadecimal) Ethertype used to indicate IEEE 802.15.4 frame.",
7474
16
                                   16, &ieee802154_ethertype);
7475
16
    prefs_register_obsolete_preference(ieee802154_module, "802154_cc24xx");
7476
16
    prefs_register_enum_preference(ieee802154_module, "fcs_format",
7477
16
                                   "FCS format",
7478
16
                                   "The FCS format in the captured payload",
7479
16
                                   &ieee802154_fcs_type, fcs_type_vals, false);
7480
16
    prefs_register_bool_preference(ieee802154_module, "802154_fcs_ok",
7481
16
                                   "Dissect only good FCS",
7482
16
                                   "Dissect payload only if FCS is valid.",
7483
16
                                   &ieee802154_fcs_ok);
7484
16
    prefs_register_bool_preference(ieee802154_module, "802154_ack_tracking",
7485
16
                                   "Enable ACK tracking",
7486
16
                                   "Match frames with ACK request to ACK packets",
7487
16
                                   &ieee802154_ack_tracking);
7488
16
    prefs_register_bool_preference(ieee802154_module, "802154e_compatibility",
7489
16
                                    "Assume 802.15.4e-2012 for compatibility",
7490
16
                                    "Parse assuming 802.15.4e quirks for compatibility",
7491
16
                                    &ieee802154e_compatibility);
7492
7493
    /* Create a UAT for static address mappings. */
7494
16
    static_addr_uat = uat_new("Static Addresses",
7495
16
            sizeof(static_addr_t),      /* record size */
7496
16
            "802154_addresses",         /* filename */
7497
16
            true,                       /* from_profile */
7498
16
            &static_addrs,              /* data_ptr */
7499
16
            &num_static_addrs,          /* numitems_ptr */
7500
16
            UAT_AFFECTS_DISSECTION,     /* affects dissection of packets, but not set of named fields */
7501
16
            NULL,                       /* help */
7502
16
            addr_uat_copy_cb,           /* copy callback */
7503
16
            addr_uat_update_cb,         /* update callback */
7504
16
            addr_uat_free_cb,           /* free callback */
7505
16
            NULL,                       /* post update callback */
7506
16
            NULL,                       /* reset callback */
7507
16
            addr_uat_flds);             /* UAT field definitions */
7508
16
    prefs_register_uat_preference(ieee802154_module, "static_addr",
7509
16
                "Static Addresses",
7510
16
                "A table of static address mappings between 16-bit short addressing and EUI-64 addresses",
7511
16
                static_addr_uat);
7512
7513
    /* Create a UAT for key management. */
7514
16
    ieee802154_key_uat = uat_new("Keys",
7515
16
            sizeof(ieee802154_key_t),   /* record size */
7516
16
            "ieee802154_keys",          /* filename */
7517
16
            true,                       /* from_profile */
7518
16
            &ieee802154_keys,           /* data_ptr */
7519
16
            &num_ieee802154_keys,       /* numitems_ptr */
7520
16
            UAT_AFFECTS_DISSECTION,     /* affects dissection of packets, but not set of named fields */
7521
16
            NULL,                       /* help */
7522
16
            ieee802154_key_copy_cb,     /* copy callback */
7523
16
            ieee802154_key_update_cb,   /* update callback */
7524
16
            ieee802154_key_free_cb,     /* free callback */
7525
16
            ieee802154_key_post_update_cb, /* post update callback */
7526
16
            NULL,                       /* reset callback */
7527
16
            key_uat_flds);              /* UAT field definitions */
7528
16
    prefs_register_uat_preference(ieee802154_module, "ieee802154_keys",
7529
16
                "Decryption Keys",
7530
16
                "Decryption key configuration data",
7531
16
                ieee802154_key_uat);
7532
7533
    /* Register preferences for a decryption key */
7534
16
    prefs_register_obsolete_preference(ieee802154_module, "802154_key");
7535
7536
16
    prefs_register_enum_preference(ieee802154_module, "802154_sec_suite",
7537
16
                                   "Security Suite (802.15.4-2003)",
7538
16
                                   "Specifies the security suite to use for 802.15.4-2003 secured frames"
7539
16
                                   " (only supported suites are listed). Option ignored for 802.15.4-2006"
7540
16
                                   " and unsecured frames.",
7541
16
                                   &ieee802154_sec_suite, ieee802154_2003_sec_suite_enums, false);
7542
7543
16
    prefs_register_bool_preference(ieee802154_module, "802154_extend_auth",
7544
16
                                   "Extend authentication data (802.15.4-2003)",
7545
16
                                   "Set if the manufacturer extends the authentication data with the"
7546
16
                                   " security header. Option ignored for 802.15.4-2006 and unsecured frames.",
7547
16
                                   &ieee802154_extend_auth);
7548
7549
    /* Register the subdissector list */
7550
16
    panid_dissector_table = register_dissector_table(IEEE802154_PROTOABBREV_WPAN_PANID, "IEEE 802.15.4 PANID", proto_ieee802154, FT_UINT16, BASE_HEX);
7551
16
    ieee802154_heur_subdissector_list = register_heur_dissector_list_with_description(IEEE802154_PROTOABBREV_WPAN, "IEEE 802.15.4 PANID", proto_ieee802154);
7552
16
    ieee802154_beacon_subdissector_list = register_heur_dissector_list_with_description(IEEE802154_PROTOABBREV_WPAN_BEACON, "IEEE 802.15.4 FCF beacon", proto_ieee802154);
7553
7554
    /* Register dissector tables */
7555
16
    header_ie_dissector_table = register_dissector_table(IEEE802154_HEADER_IE_DTABLE, "IEEE 802.15.4 Header IEs", proto_ieee802154, FT_UINT8, BASE_HEX);
7556
16
    payload_ie_dissector_table = register_dissector_table(IEEE802154_PAYLOAD_IE_DTABLE, "IEEE 802.15.4 Payload IEs", proto_ieee802154, FT_UINT8, BASE_HEX);
7557
16
    mlme_ie_dissector_table = register_dissector_table(IEEE802154_MLME_IE_DTABLE, "IEEE 802.15.4 Nested IEs", proto_ieee802154, FT_UINT8, BASE_HEX);
7558
16
    cmd_vendor_dissector_table = register_dissector_table(IEEE802154_CMD_VENDOR_DTABLE, "IEEE 802.15.4 Vendor Specific Commands", proto_ieee802154, FT_UINT24, BASE_HEX );
7559
7560
    /* Register dissectors with Wireshark */
7561
16
    ieee802154_handle = register_dissector("wpan", dissect_ieee802154, proto_ieee802154);
7562
16
    ieee802154_fcs_handle = register_dissector("wpan_fcs", dissect_ieee802154_fcs, proto_ieee802154);
7563
16
    ieee802154_nofcs_handle = register_dissector("wpan_nofcs", dissect_ieee802154_nofcs, proto_ieee802154);
7564
16
    register_dissector("wpan_cc24xx", dissect_ieee802154_cc24xx, proto_ieee802154);
7565
16
    ieee802154_nonask_phy_handle = register_dissector("wpan-nonask-phy", dissect_ieee802154_nonask_phy, proto_ieee802154_nonask_phy);
7566
16
    ieee802154_tap_handle = register_dissector("wpan-tap", dissect_ieee802154_tap, proto_ieee802154_tap);
7567
7568
    /* Setup registration for other dissectors to provide mac key hash algorithms */
7569
16
    mac_key_hash_handlers = wmem_tree_new(wmem_epan_scope());
7570
7571
    /* Register a Decode-As handler */
7572
16
    register_decode_as(&ieee802154_da);
7573
7574
    /* Create trees for transactions */
7575
16
    transaction_unmatched_pdus = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
7576
16
    transaction_matched_pdus = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
7577
7578
16
    ieee802154_tap = register_tap(IEEE802154_PROTOABBREV_WPAN);
7579
7580
16
    register_conversation_table(proto_ieee802154, true, ieee802154_conversation_packet, ieee802154_endpoint_packet);
7581
16
    register_conversation_filter(IEEE802154_PROTOABBREV_WPAN, "IEEE 802.15.4", ieee802154_filter_valid, ieee802154_build_filter, NULL);
7582
16
} /* proto_register_ieee802154 */
7583
7584
7585
/**
7586
 * Registers the IEEE 802.15.4 dissector with Wireshark.
7587
 * Will be called every time 'apply' is pressed in the preferences menu.
7588
 * as well as during Wireshark initialization
7589
 */
7590
void proto_reg_handoff_ieee802154(void)
7591
16
{
7592
16
    static bool                prefs_initialized = false;
7593
16
    static unsigned int        old_ieee802154_ethertype;
7594
7595
16
    if (!prefs_initialized) {
7596
        /* Get the dissector handles. */
7597
16
        zigbee_ie_handle = find_dissector_add_dependency("zbee_ie", proto_ieee802154);
7598
16
        zigbee_nwk_handle = find_dissector("zbee_nwk");
7599
7600
16
        thread_ie_handle = find_dissector_add_dependency("thread_ie",proto_ieee802154);
7601
16
        dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4, ieee802154_handle);
7602
16
        dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_NONASK_PHY, ieee802154_nonask_phy_handle);
7603
16
        dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_NOFCS, ieee802154_nofcs_handle);
7604
16
        dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_TAP, ieee802154_tap_handle);
7605
16
        dissector_add_uint("sll.ltype", LINUX_SLL_P_IEEE802154, ieee802154_handle);
7606
7607
        /* Register internal IE handlers */
7608
16
        dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_TIME_CORR, create_dissector_handle(dissect_hie_time_correction, -1));
7609
16
        dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_CSL, create_dissector_handle(dissect_hie_csl, -1));
7610
16
        dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_RENDEZVOUS, create_dissector_handle(dissect_hie_rendezvous_time, -1));
7611
16
        dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_GLOBAL_TIME, create_dissector_handle(dissect_hie_global_time, -1));
7612
16
        dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_VENDOR_SPECIFIC, create_dissector_handle(dissect_hie_vendor_specific, -1));
7613
7614
16
        dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_MLME, create_dissector_handle(dissect_pie_mlme, -1));
7615
16
        dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_VENDOR, create_dissector_handle(dissect_pie_vendor, -1));
7616
16
        dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_MPX, create_dissector_handle(dissect_mpx_ie, -1));
7617
16
        dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_IETF, create_dissector_handle(dissect_ietf_ie, -1));
7618
7619
16
        dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_CHANNEL_HOPPING, create_dissector_handle(dissect_802154_channel_hopping, -1));
7620
16
        dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_TSCH_SYNCH, create_dissector_handle(dissect_802154_tsch_time_sync, -1));
7621
16
        dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_TSCH_SLOTFR_LINK, create_dissector_handle(dissect_802154_tsch_slotframe_link, -1));
7622
16
        dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_TSCH_TIMESLOT, create_dissector_handle(dissect_802154_tsch_timeslot, -1));
7623
16
        dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_ENHANCED_BEACON_FILTER, create_dissector_handle(dissect_802154_eb_filter, -1));
7624
7625
        /* For the MPX-IE */
7626
16
        ethertype_table = find_dissector_table("ethertype");
7627
16
        eapol_handle = find_dissector("eapol");
7628
16
        lowpan_handle = find_dissector("6lowpan");
7629
16
        wisun_sec_handle = find_dissector("wisun.sec");
7630
16
        prefs_initialized = true;
7631
16
    } else {
7632
0
        dissector_delete_uint("ethertype", old_ieee802154_ethertype, ieee802154_handle);
7633
0
    }
7634
7635
16
    old_ieee802154_ethertype = ieee802154_ethertype;
7636
7637
    /* Register dissector handles. */
7638
16
    dissector_add_uint("ethertype", ieee802154_ethertype, ieee802154_handle);
7639
7640
16
} /* proto_reg_handoff_ieee802154 */
7641
7642
/*
7643
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
7644
 *
7645
 * Local variables:
7646
 * c-basic-offset: 4
7647
 * tab-width: 8
7648
 * indent-tabs-mode: nil
7649
 * End:
7650
 *
7651
 * vi: set shiftwidth=4 tabstop=8 expandtab:
7652
 * :indentSize=4:tabSize=8:noTabs=true:
7653
 */