uat: add a reset callback.
[metze/wireshark/wip.git] / epan / dissectors / packet-ieee802154.c
1 /* packet-ieee802154.c
2  *
3  * Auxiliary Security Header support and
4  * option to force TI CC24xx FCS format
5  * By Jean-Francois Wauthy <jfw@info.fundp.ac.be>
6  * Copyright 2009 The University of Namur, Belgium
7  *
8  * IEEE 802.15.4 Dissectors for Wireshark
9  * By Owen Kirby <osk@exegin.com>
10  * Copyright 2007 Exegin Technologies Limited
11  *
12  * Wireshark - Network traffic analyzer
13  * By Gerald Combs <gerald@wireshark.org>
14  * Copyright 1998 Gerald Combs
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29  *------------------------------------------------------------
30  *
31  *  In IEEE 802.15.4 packets, all fields are little endian. And
32  *  Each byte is transmitted least significant bit first (reflected
33  *  bit ordering).
34  *------------------------------------------------------------
35  *
36  *  IEEE 802.15.4 Packets have the following format:
37  *  |  FCF  |Seq No|  Addressing |         Data          |  FCS  |
38  *  |2 bytes|1 byte|0 to 20 bytes|Length-(Overhead) bytes|2 Bytes|
39  *------------------------------------------------------------
40  *
41  *  CRC16 is calculated using the x^16 + x^12 + x^5 + 1 polynomial
42  *  as specified by ITU-T, and is calculated over the IEEE 802.15.4
43  *  packet (excluding the FCS) as transmitted over the air. Note,
44  *  that because the least significan bits are transmitted first, this
45  *  will require reversing the bit-order in each byte. Also, unlike
46  *  most CRC algorithms, IEEE 802.15.4 uses an initial and final value
47  *  of 0x0000, instead of 0xffff (which is used by the CCITT).
48  *------------------------------------------------------------
49  *
50  *  This dissector supports both link-layer IEEE 802.15.4 captures
51  *  and IEEE 802.15.4 packets encapsulated within other layers.
52  *  Additionally, support has been provided for various formats
53  *  of the frame check sequence:
54  *      - IEEE 802.15.4 compliant FCS.
55  *      - ChipCon/Texas Instruments CC24xx style FCS.
56  *------------------------------------------------------------
57  */
58
59 /*  Include files */
60 #include "config.h"
61
62
63 #include <epan/packet.h>
64 #include <epan/decode_as.h>
65 #include <epan/exceptions.h>
66 #include <epan/crc16-tvb.h>
67 #include <epan/expert.h>
68 #include <epan/addr_resolv.h>
69 #include <epan/address_types.h>
70 #include <epan/prefs.h>
71 #include <epan/uat.h>
72 #include <epan/strutil.h>
73 #include <epan/to_str.h>
74 #include <epan/show_exception.h>
75 #include <epan/proto_data.h>
76
77 #include <wsutil/pint.h>
78
79 /* Use libgcrypt for cipher libraries. */
80 #include <wsutil/wsgcrypt.h>
81
82 #include "packet-ieee802154.h"
83 #include "packet-sll.h"
84
85 void proto_register_ieee802154(void);
86 void proto_reg_handoff_ieee802154(void);
87
88 /* Dissection Options for dissect_ieee802154_common */
89 #define DISSECT_IEEE802154_OPTION_CC24xx    0x00000001  /* FCS field contains a TI CC24xx style FCS. */
90 #define DISSECT_IEEE802154_OPTION_LINUX     0x00000002  /* Addressing fields are padded DLT_IEEE802_15_4_LINUX, not implemented. */
91 #define DISSECT_IEEE802154_OPTION_ZBOSS     0x00000004  /* ZBOSS traffic dump */
92
93 /* ethertype for 802.15.4 tag - encapsulating an Ethernet packet */
94 static unsigned int ieee802154_ethertype = 0x809A;
95
96 /* boolean value set if the FCS field is using the TI CC24xx format */
97 static gboolean ieee802154_cc24xx = FALSE;
98
99 /* boolean value set if the FCS must be ok before payload is dissected */
100 static gboolean ieee802154_fcs_ok = TRUE;
101
102 /* User string with the decryption key. */
103 static const gchar *ieee802154_key_str = NULL;
104 static gboolean     ieee802154_key_valid;
105 static guint8       ieee802154_key[IEEE802154_CIPHER_SIZE];
106 static const char  *ieee802154_user    = "User";
107
108 /*
109  * Address Hash Tables
110  *
111  */
112 static ieee802154_map_tab_t ieee802154_map = { NULL, NULL };
113
114 /*
115  * Static Address Mapping UAT
116  *
117  */
118 /* UAT entry structure. */
119 typedef struct {
120     guchar *eui64;
121     guint   eui64_len;
122     guint   addr16;
123     guint   pan;
124 } static_addr_t;
125
126 /* UAT variables */
127 static uat_t         *static_addr_uat  = NULL;
128 static static_addr_t *static_addrs     = NULL;
129 static guint          num_static_addrs = 0;
130
131 /* Sanity-checks a UAT record. */
132 static gboolean
133 addr_uat_update_cb(void *r, char **err)
134 {
135     static_addr_t *map = (static_addr_t *)r;
136     /* Ensure a valid short address */
137     if (map->addr16 >= IEEE802154_NO_ADDR16) {
138         *err = g_strdup("Invalid short address");
139         return FALSE;
140     }
141     /* Ensure a valid PAN identifier. */
142     if (map->pan >= IEEE802154_BCAST_PAN) {
143         *err = g_strdup("Invalid PAN identifier");
144         return FALSE;
145     }
146     /* Ensure a valid EUI-64 length */
147     if (map->eui64_len != sizeof(guint64)) {
148         *err = g_strdup("Invalid EUI-64 length");
149         return FALSE;
150     }
151     return TRUE;
152 } /* ieee802154_addr_uat_update_cb */
153
154 /* Field callbacks. */
155 UAT_HEX_CB_DEF(addr_uat, addr16, static_addr_t)
156 UAT_HEX_CB_DEF(addr_uat, pan, static_addr_t)
157 UAT_BUFFER_CB_DEF(addr_uat, eui64, static_addr_t, eui64, eui64_len)
158
159 /*-------------------------------------
160  * Dissector Function Prototypes
161  *-------------------------------------
162  */
163
164 /* Dissection Routines. */
165 static int dissect_ieee802154_nonask_phy   (tvbuff_t *, packet_info *, proto_tree *, void *);
166 static int dissect_ieee802154              (tvbuff_t *, packet_info *, proto_tree *, void *);
167 static int dissect_ieee802154_nofcs        (tvbuff_t *, packet_info *, proto_tree *, void *);
168 static int dissect_ieee802154_cc24xx       (tvbuff_t *, packet_info *, proto_tree *, void *);
169 static tvbuff_t *dissect_zboss_specific    (tvbuff_t *, packet_info *, proto_tree *);
170 /*static void dissect_ieee802154_linux        (tvbuff_t *, packet_info *, proto_tree *);  TODO: Implement Me. */
171 static void dissect_ieee802154_common       (tvbuff_t *, packet_info *, proto_tree *, guint);
172
173 /* Information Elements */
174 static void dissect_ieee802154_header_ie       (tvbuff_t *, packet_info *, proto_tree *, guint *, ieee802154_packet *);
175 static int  dissect_ieee802154_payload_mlme_sub_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset);
176 static int  dissect_ieee802154_payload_ie      (tvbuff_t *, packet_info *, proto_tree *, int offset);
177 static int  dissect_ieee802154_vendor_ie (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset, gint pie_length);
178 static void dissect_802154_h_ie_time_correction (tvbuff_t *, proto_tree *, guint *);
179 static void dissect_802154_p_ie_sh_mlme_tsch_sync (tvbuff_t *, proto_tree *, guint, guint *);
180 static void dissect_802154_p_ie_sh_mlme_tsch_slotframe_link (tvbuff_t *, proto_tree *, guint16, guint *);
181 static void dissect_802154_p_ie_lg_mlme_channel_hopping(tvbuff_t *, proto_tree *, guint16, guint *);
182 static int  dissect_ieee802154_6top      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *p_inf_elem_tree, guint offset, gint pie_length);
183 /* Sub-dissector helpers. */
184 static void dissect_ieee802154_fcf             (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *, guint *);
185 static void dissect_ieee802154_command         (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
186 static void dissect_ieee802154_assoc_req       (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
187 static void dissect_ieee802154_assoc_rsp       (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
188 static void dissect_ieee802154_disassoc        (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
189 static void dissect_ieee802154_realign         (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
190 static void dissect_ieee802154_gtsreq          (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
191
192 /* Decryption helpers. */
193 typedef enum {
194     DECRYPT_PACKET_SUCCEEDED,
195     DECRYPT_NOT_ENCRYPTED,
196     DECRYPT_VERSION_UNSUPPORTED,
197     DECRYPT_PACKET_TOO_SMALL,
198     DECRYPT_PACKET_NO_EXT_SRC_ADDR,
199     DECRYPT_PACKET_NO_KEY,
200     DECRYPT_PACKET_DECRYPT_FAILED,
201     DECRYPT_PACKET_MIC_CHECK_FAILED
202 } ws_decrypt_status;
203
204 static tvbuff_t *dissect_ieee802154_decrypt(tvbuff_t *, guint, packet_info *, ieee802154_packet *,
205         ws_decrypt_status *);
206 static void ccm_init_block          (gchar *, gboolean, gint, guint64, ieee802154_packet *, gint);
207 static gboolean ccm_ctr_encrypt     (const gchar *, const gchar *, gchar *, gchar *, gint);
208 static gboolean ccm_cbc_mac         (const gchar *, const gchar *, const gchar *, gint, const gchar *, gint, gchar *);
209
210 /*  Initialize Protocol and Registered fields */
211 static int proto_ieee802154_nonask_phy = -1;
212 static int hf_ieee802154_nonask_phy_preamble = -1;
213 static int hf_ieee802154_nonask_phy_sfd = -1;
214 static int hf_ieee802154_nonask_phy_length = -1;
215 static int hf_ieee802154_nonask_phr = -1;
216
217 static int proto_ieee802154 = -1;
218 static int hf_ieee802154_frame_length = -1;
219 static int hf_ieee802154_fcf = -1;
220 static int hf_ieee802154_frame_type = -1;
221 static int hf_ieee802154_security = -1;
222 static int hf_ieee802154_pending = -1;
223 static int hf_ieee802154_ack_request = -1;
224 static int hf_ieee802154_pan_id_compression = -1;
225 static int hf_ieee802154_seqno_suppression = -1;
226 static int hf_ieee802154_ie_present = -1;
227 static int hf_ieee802154_src_addr_mode = -1;
228 static int hf_ieee802154_version = -1;
229 static int hf_ieee802154_dst_addr_mode = -1;
230 static int hf_ieee802154_header_ie = -1;
231 static int hf_ieee802154_header_ie_type = -1;
232 static int hf_ieee802154_header_ie_id = -1;
233 static int hf_ieee802154_header_ie_length = -1;
234 static int hf_ieee802154_header_ie_data = -1;
235 static int hf_ieee802154_h_ie_time_correction1 = -1;
236 static int hf_ieee802154_h_ie_time_correction2 = -1;
237 static int hf_ieee802154_h_ie_time_correction3 = -1;
238 static int hf_ieee802154_h_ie_time_correction4 = -1;
239 static int hf_ieee802154_payload_ie = -1;
240 static int hf_ieee802154_payload_ie_type = -1;
241 static int hf_ieee802154_payload_ie_id = -1;
242 static int hf_ieee802154_payload_ie_length = -1;
243 static int hf_ieee802154_payload_ie_data = -1;
244 static int hf_ieee802154_payload_ie_vendor_oui = -1;
245 static int hf_ieee802154_mlme_ie_data = -1;
246 static int hf_ieee802154_psie_short = -1;
247 static int hf_ieee802154_psie_type_short = -1;
248 static int hf_ieee802154_psie_id_short = -1;
249 static int hf_ieee802154_psie_length_short = -1;
250 static int hf_ieee802154_psie_long = -1;
251 static int hf_ieee802154_psie_type_long = -1;
252 static int hf_ieee802154_psie_id_long = -1;
253 static int hf_ieee802154_psie_length_long = -1;
254 static int hf_ieee802154_p_ie_mlme_sh_tsch_asn = -1;
255 static int hf_ieee802154_p_ie_mlme_sh_tsch_join_p = -1;
256 static int hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_nb_slotf = -1;
257 static int hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_slotf_handle= -1;
258 static int hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_slotf_size = -1;
259 static int hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_nb_links = -1;
260 static int hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_timeslot = -1;
261 static int hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_channel_offset = -1;
262 static int hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_options = -1;
263 static int hf_ieee802154_p_ie_mlme_lg_hopping_sequence_id = -1;
264 static int hf_ieee802154_psie_eb_filter = -1;
265 static int hf_ieee802154_psie_eb_filter_pjoin = -1;
266 static int hf_ieee802154_psie_eb_filter_lqi = -1;
267 static int hf_ieee802154_psie_eb_filter_lqi_min = -1;
268 static int hf_ieee802154_psie_eb_filter_percent = -1;
269 static int hf_ieee802154_psie_eb_filter_percent_prob = -1;
270 static int hf_ieee802154_psie_eb_filter_attr_id = -1;
271 static int hf_ieee802154_psie_eb_filter_attr_id_bitmap = -1;
272 static int hf_ieee802154_p_ie_ietf_sub_id = -1;
273 static int hf_ieee802154_p_ie_6top_version = -1;
274 static int hf_ieee802154_p_ie_6top_type = -1;
275 static int hf_ieee802154_p_ie_6top_flags_reserved = -1;
276 static int hf_ieee802154_p_ie_6top_code = -1;
277 static int hf_ieee802154_p_ie_6top_sfid = -1;
278 static int hf_ieee802154_p_ie_6top_seqnum = -1;
279 static int hf_ieee802154_p_ie_6top_gab = -1;
280 static int hf_ieee802154_p_ie_6top_gba = -1;
281 static int hf_ieee802154_p_ie_6top_metadata = -1;
282 static int hf_ieee802154_p_ie_6top_cell_options = -1;
283 static int hf_ieee802154_p_ie_6top_cell_option_tx = -1;
284 static int hf_ieee802154_p_ie_6top_cell_option_rx = -1;
285 static int hf_ieee802154_p_ie_6top_cell_option_shared = -1;
286 static int hf_ieee802154_p_ie_6top_cell_option_reserved = -1;
287 static int hf_ieee802154_p_ie_6top_num_cells = -1;
288 static int hf_ieee802154_p_ie_6top_reserved = -1;
289 static int hf_ieee802154_p_ie_6top_offset = -1;
290 static int hf_ieee802154_p_ie_6top_max_num_cells = -1;
291 static int hf_ieee802154_p_ie_6top_slot_offset = -1;
292 static int hf_ieee802154_p_ie_6top_channel_offset = -1;
293
294 static int proto_zboss = -1;
295 static int zboss_direction = -1;
296 static int zboss_channel = -1;
297 static int zboss_trace_number = -1;
298
299 static int hf_ieee802154_seqno = -1;
300 static int hf_ieee802154_dst_panID = -1;
301 static int hf_ieee802154_dst16 = -1;
302 static int hf_ieee802154_dst64 = -1;
303 static int hf_ieee802154_src_panID = -1;
304 static int hf_ieee802154_src16 = -1;
305 static int hf_ieee802154_src64 = -1;
306 static int hf_ieee802154_src64_origin = -1;
307 static int hf_ieee802154_fcs = -1;
308 static int hf_ieee802154_rssi = -1;
309 static int hf_ieee802154_fcs_ok = -1;
310 static int hf_ieee802154_correlation = -1;
311
312 /*  Registered fields for Command Packets */
313 static int hf_ieee802154_cmd_id = -1;
314 static int hf_ieee802154_cinfo_alt_coord = -1;
315 static int hf_ieee802154_cinfo_device_type = -1;
316 static int hf_ieee802154_cinfo_power_src = -1;
317 static int hf_ieee802154_cinfo_idle_rx = -1;
318 static int hf_ieee802154_cinfo_sec_capable = -1;
319 static int hf_ieee802154_cinfo_alloc_addr = -1;
320 static int hf_ieee802154_assoc_addr = -1;
321 static int hf_ieee802154_assoc_status = -1;
322 static int hf_ieee802154_disassoc_reason = -1;
323 static int hf_ieee802154_realign_pan = -1;
324 static int hf_ieee802154_realign_caddr = -1;
325 static int hf_ieee802154_realign_channel = -1;
326 static int hf_ieee802154_realign_addr = -1;
327 static int hf_ieee802154_realign_channel_page = -1;
328 static int hf_ieee802154_gtsreq_len = -1;
329 static int hf_ieee802154_gtsreq_dir = -1;
330 static int hf_ieee802154_gtsreq_type = -1;
331
332 /*  Registered fields for Beacon Packets */
333 static int hf_ieee802154_beacon_order = -1;
334 static int hf_ieee802154_superframe_order = -1;
335 static int hf_ieee802154_cap = -1;
336 static int hf_ieee802154_superframe_battery_ext = -1;
337 static int hf_ieee802154_superframe_coord = -1;
338 static int hf_ieee802154_assoc_permit = -1;
339 static int hf_ieee802154_gts_count = -1;
340 static int hf_ieee802154_gts_permit = -1;
341 static int hf_ieee802154_gts_direction = -1;
342 static int hf_ieee802154_gts_address = -1;
343 static int hf_ieee802154_pending16 = -1;
344 static int hf_ieee802154_pending64 = -1;
345
346 /*  Registered fields for Auxiliary Security Header */
347 static int hf_ieee802154_security_control_field = -1;
348 static int hf_ieee802154_security_level = -1;
349 static int hf_ieee802154_key_id_mode = -1;
350 static int hf_ieee802154_aux_sec_reserved = -1;
351 static int hf_ieee802154_aux_sec_frame_counter = -1;
352 static int hf_ieee802154_aux_sec_key_source = -1;
353 static int hf_ieee802154_aux_sec_key_index = -1;
354
355 /* 802.15.4-2003 security */
356 static int hf_ieee802154_sec_frame_counter = -1;
357 static int hf_ieee802154_sec_key_sequence_counter = -1;
358
359 /*  Initialize Subtree Pointers */
360 static gint ett_ieee802154_nonask_phy = -1;
361 static gint ett_ieee802154_nonask_phy_phr = -1;
362 static gint ett_ieee802154 = -1;
363 static gint ett_ieee802154_fcf = -1;
364 static gint ett_ieee802154_auxiliary_security = -1;
365 static gint ett_ieee802154_aux_sec_control = -1;
366 static gint ett_ieee802154_aux_sec_key_id = -1;
367 static gint ett_ieee802154_fcs = -1;
368 static gint ett_ieee802154_cmd = -1;
369 static gint ett_ieee802154_superframe = -1;
370 static gint ett_ieee802154_gts = -1;
371 static gint ett_ieee802154_gts_direction = -1;
372 static gint ett_ieee802154_gts_descriptors = -1;
373 static gint ett_ieee802154_pendaddr = -1;
374 static gint ett_ieee802154_header = -1;
375 static gint ett_ieee802154_header_ie = -1;
376 static gint ett_ieee802154_h_ie_payload = -1;
377 static gint ett_ieee802154_payload = -1;
378 static gint ett_ieee802154_payload_ie = -1;
379 static gint ett_ieee802154_mlme_payload = -1;
380 static gint ett_ieee802154_mlme_payload_data = -1;
381 static gint ett_ieee802154_psie_short = -1;
382 static gint ett_ieee802154_psie_short_bitmap= -1;
383 static gint ett_ieee802154_psie_long = -1;
384 static gint ett_ieee802154_psie_long_bitmap = -1;
385 static gint ett_ieee802154_psie_enh_beacon_flt = -1;
386 static gint ett_ieee802154_psie_enh_beacon_flt_bitmap = -1;
387 static gint ett_ieee802154_psie_slotframe_link_slotframes = -1;
388 static gint ett_ieee802154_zigbee = -1;
389 static gint ett_ieee802154_zboss = -1;
390 static gint ett_ieee802154_p_ie_6top = -1;
391 static gint ett_ieee802154_p_ie_6top_version_type = -1;
392 static gint ett_ieee802154_p_ie_6top_seqnum_gab_gba = -1;
393 static gint ett_ieee802154_p_ie_6top_cell_options = -1;
394 static gint ett_ieee802154_p_ie_6top_cell_list = -1;
395 static gint ett_ieee802154_p_ie_6top_cell = -1;
396
397 static expert_field ei_ieee802154_invalid_addressing = EI_INIT;
398 /* static expert_field ei_ieee802154_invalid_panid_compression = EI_INIT; */
399 static expert_field ei_ieee802154_invalid_panid_compression2 = EI_INIT;
400 static expert_field ei_ieee802154_fcs = EI_INIT;
401 static expert_field ei_ieee802154_decrypt_error = EI_INIT;
402 static expert_field ei_ieee802154_dst = EI_INIT;
403 static expert_field ei_ieee802154_src = EI_INIT;
404 static expert_field ei_ieee802154_frame_ver = EI_INIT;
405 /* static expert_field ei_ieee802154_frame_type = EI_INIT; */
406 static expert_field ei_ieee802154_seqno_suppression = EI_INIT;
407 static expert_field ei_ieee802154_p_ie_6top_type = EI_INIT;
408 static expert_field ei_ieee802154_p_ie_6top_code = EI_INIT;
409
410 static int ieee802_15_4_short_address_type = -1;
411 /*
412  * Dissector handles
413  *  - beacon dissection is always heuristic.
414  *  - the PANID table is for stateful dissectors only (ie: Decode-As)
415  *  - otherwise, data dissectors fall back to the heuristic dissectors.
416  */
417 static dissector_table_t        panid_dissector_table;
418 static heur_dissector_list_t    ieee802154_beacon_subdissector_list;
419 static heur_dissector_list_t    ieee802154_heur_subdissector_list;
420
421 static dissector_handle_t  zigbee_beacon_handle;
422 static dissector_handle_t  zigbee_ie_handle;
423 static dissector_handle_t  zigbee_nwk_handle;
424 static dissector_handle_t  ieee802154_handle;
425 static dissector_handle_t  ieee802154_nonask_phy_handle;
426 static dissector_handle_t  ieee802154_nofcs_handle;
427
428 /* Versions */
429 static const value_string ieee802154_frame_versions[] = {
430     { IEEE802154_VERSION_2003,     "IEEE Std 802.15.4-2003" },
431     { IEEE802154_VERSION_2006,     "IEEE Std 802.15.4-2006" },
432     { IEEE802154_VERSION_2015,     "IEEE Std 802.15.4-2015" },
433     { IEEE802154_VERSION_RESERVED, "Reserved" },
434     { 0, NULL }
435 };
436
437 /* Name Strings */
438 static const value_string ieee802154_frame_types[] = {
439     { IEEE802154_FCF_BEACON,       "Beacon" },
440     { IEEE802154_FCF_DATA,         "Data" },
441     { IEEE802154_FCF_ACK,          "Ack" },
442     { IEEE802154_FCF_CMD,          "Command" },
443     { IEEE802154_FCF_RESERVED,     "Reserved" },
444     { IEEE802154_FCF_MULTIPURPOSE, "Multipurpose" },
445     { IEEE802154_FCF_FRAGMENT,     "Fragment or Frak" },
446     { IEEE802154_FCF_EXTENDED,     "Extended" },
447     { 0, NULL }
448 };
449
450 static const value_string ieee802154_addr_modes[] = {
451     { IEEE802154_FCF_ADDR_NONE,     "None" },
452     { IEEE802154_FCF_ADDR_RESERVED, "Reserved" },
453     { IEEE802154_FCF_ADDR_SHORT,    "Short/16-bit" },
454     { IEEE802154_FCF_ADDR_EXT,      "Long/64-bit" },
455     { 0, NULL }
456 };
457
458 static const value_string ieee802154_cmd_names[] = {
459     { IEEE802154_CMD_ASSOC_REQ,                 "Association Request" },
460     { IEEE802154_CMD_ASSOC_RSP,                 "Association Response" },
461     { IEEE802154_CMD_DISASSOC_NOTIFY,           "Disassociation Notification" },
462     { IEEE802154_CMD_DATA_RQ,                   "Data Request" },
463     { IEEE802154_CMD_PANID_CONFLICT,            "PAN ID Conflict" },
464     { IEEE802154_CMD_ORPHAN_NOTIFY,             "Orphan Notification" },
465     { IEEE802154_CMD_BEACON_REQ,                "Beacon Request" },
466     { IEEE802154_CMD_COORD_REALIGN,             "Coordinator Realignment" },
467     { IEEE802154_CMD_GTS_REQ,                   "GTS Request" },
468     { IEEE802154_CMD_TRLE_MGMT_REQ,             "TRLE Management Request"},
469     { IEEE802154_CMD_TRLE_MGMT_RSP,             "TRLE Management Response"},
470     { IEEE802154_CMD_DSME_ASSOC_REQ,            "DSME Association Request"},
471     { IEEE802154_CMD_DSME_ASSOC_RSP,            "DSME Association Response"},
472     { IEEE802154_CMD_DSME_GTS_REQ,              "DSME GTS Request"},
473     { IEEE802154_CMD_DSME_GTS_RSP,              "DSME GTS Response"},
474     { IEEE802154_CMD_DSME_GTS_NOTIFY,           "DSME GTS Notify"},
475     { IEEE802154_CMD_DSME_INFO_REQ,             "DSME Information Request"},
476     { IEEE802154_CMD_DSME_INFO_RSP,             "DSME Information Response"},
477     { IEEE802154_CMD_DSME_BEACON_ALLOC_NOTIFY,  "DSME Beacon Allocation Notification"},
478     { IEEE802154_CMD_DSME_BEACON_COLL_NOTIFY,   "DSME Beacon Collision Notification"},
479     { IEEE802154_CMD_DSME_LINK_REPORT,          "DSME Link Report"},
480     { IEEE802154_CMD_RIT_DATA_REQ,              "RIT Data Request"},
481     { IEEE802154_CMD_DBS_REQ,                   "DBS Request"},
482     { IEEE802154_CMD_DBS_RSP,                   "DBS Response"},
483     { 0, NULL }
484 };
485
486 static const value_string ieee802154_sec_level_names[] = {
487     { SECURITY_LEVEL_NONE,        "No Security" },
488     { SECURITY_LEVEL_MIC_32,      "32-bit Message Integrity Code" },
489     { SECURITY_LEVEL_MIC_64,      "64-bit Message Integrity Code" },
490     { SECURITY_LEVEL_MIC_128,     "128-bit Message Integrity Code" },
491     { SECURITY_LEVEL_ENC,         "Encryption" },
492     { SECURITY_LEVEL_ENC_MIC_32,  "Encryption with 32-bit Message Integrity Code" },
493     { SECURITY_LEVEL_ENC_MIC_64,  "Encryption with 64-bit Message Integrity Code" },
494     { SECURITY_LEVEL_ENC_MIC_128, "Encryption with 128-bit Message Integrity Code" },
495     { 0, NULL }
496 };
497
498 static const value_string ieee802154_key_id_mode_names[] = {
499     { KEY_ID_MODE_IMPLICIT,       "Implicit Key" },
500     { KEY_ID_MODE_KEY_INDEX,      "Indexed Key using the Default Key Source" },
501     { KEY_ID_MODE_KEY_EXPLICIT_4, "Explicit Key with 4-octet Key Source" },
502     { KEY_ID_MODE_KEY_EXPLICIT_8, "Explicit Key with 8-octet Key Source" },
503     { 0, NULL }
504 };
505
506 static const true_false_string ieee802154_gts_direction_tfs = {
507     "Receive Only",
508     "Transmit Only"
509 };
510
511 /* The 802.15.4-2003 security suites for the security preferences (only AES-CCM suites are supported). */
512 /* NOTE: The equivalent 2006 security level identifier enumerations are used to simplify 2003 & 2006 integration! */
513 static const enum_val_t ieee802154_2003_sec_suite_enums[] = {
514     { "AES-CCM-128", "AES-128 Encryption, 128-bit Integrity Protection", SECURITY_LEVEL_ENC_MIC_128 },
515     { "AES-CCM-64",  "AES-128 Encryption, 64-bit Integrity Protection",  SECURITY_LEVEL_ENC_MIC_64 },
516     { "AES-CCM-32",  "AES-128 Encryption, 32-bit Integrity Protection",  SECURITY_LEVEL_ENC_MIC_32 },
517     { NULL, NULL, 0 }
518 };
519
520 static const value_string ieee802154_ie_types[] = {
521     { 0, "Header" },
522     { 1, "Payload" },
523     { 0, NULL }
524 };
525
526 static const value_string ieee802154_psie_types[] = {
527     { 0,    "Short" },
528     { 1,    "Long" },
529     { 0, NULL }
530 };
531
532 static const value_string ieee802154_header_ie_names[] = {
533     { IEEE802154_HEADER_VENDOR_SPECIFIC,   "Vendor Specific IE" },
534     { IEEE802154_HEADER_IE_CSL,            "CSL IE" },
535     { IEEE802154_HEADER_IE_RIT,            "RIT IE" },
536     { IEEE802154_HEADER_IE_DSME_PAN,       "DSME PAN descriptor IE" },
537     { IEEE802154_HEADER_IE_RENDEZVOUS,     "Rendezvous Time IE" },
538     { IEEE802154_HEADER_IE_TIME_CORR,      "Time Correction IE" },
539     { IEEE802154_HEADER_IE_EXT_DSME_PAN,   "Extended DSME PAN descriptor IE" },
540     { IEEE802154_HEADER_IE_FSCD,           "Fragment Sequence Context Description (FSCD) IE" },
541     { IEEE802154_HEADER_IE_SMPL_SUPER_FRM, "Simplified Superframe Specification IE" },
542     { IEEE802154_HEADER_IE_SMPL_GTS,       "Simplified GTS Specification IE" },
543     { IEEE802154_HEADER_IE_LECIM,          "LECIM Capabilities IE" },
544     { IEEE802154_HEADER_IE_TRLE,           "TRLE Descriptor" },
545     { IEEE802154_HEADER_IE_RCC_CAP,        "RCC Capabilities IE" },
546     { IEEE802154_HEADER_IE_RCCN,           "RCCN Descriptor IE" },
547     { IEEE802154_HEADER_IE_GLOBAL_TIME,    "Global Time IE" },
548     { IEEE802154_HEADER_IE_DA_IE,          "DA IE" },
549     { IEEE802154_HEADER_IE_EID_TERM1,      "Header Termination 1" },
550     { IEEE802154_HEADER_IE_EID_TERM2,      "Header Termination 2" },
551     { 0, NULL }
552 };
553
554 static const value_string ieee802154_payload_ie_names[] = {
555     { IEEE802154_PAYLOAD_IE_ESDU,                     "ESDU IE" },
556     { IEEE802154_PAYLOAD_IE_MLME,                     "MLME IE" },
557     { IEEE802154_PAYLOAD_IE_VENDOR,                   "Vendor Specific IE" },
558     { IEEE802154_PAYLOAD_IE_IETF,                     "IETF IE" },
559     { IEEE802154_PAYLOAD_IE_GID_TERM,                 "Payload Termination IE" },
560     { 0, NULL }
561 };
562
563 static const value_string ieee802154_vendor_oui_names[] = {
564     { IEEE802154_VENDOR_OUI_ZIGBEE,                   "ZigBee" },
565     { 0, NULL }
566 };
567
568 static const value_string ieee802154_psie_names[] = {
569     { IEEE802154_MLME_SUBIE_CHANNEL_HOPPING,          "Channel Hopping IE" },
570     { IEEE802154_MLME_SUBIE_TSCH_SYNCH,               "TSCH Synchronization IE" },
571     { IEEE802154_MLME_SUBIE_TSCH_SLOTFR_LINK,         "TSCH Slotframe and Link IE" },
572     { IEEE802154_MLME_SUBIE_TSCH_TIMESLOT,            "TSCH Timeslot IE" },
573     { IEEE802154_MLME_SUBIE_HOPPING_TIMING,           "Hopping Timing IE" },
574     { IEEE802154_MLME_SUBIE_ENHANCED_BEACON_FILTER,   "Enhanced Beacon Filter IE" },
575     { IEEE802154_MLME_SUBIE_MAC_METRICS,              "MAC Metrics IE" },
576     { IEEE802154_MLME_SUBIE_ALL_MAC_METRICS,          "All MAC Metrics IE" },
577     { IEEE802154_MLME_SUBIE_COEXISTENCE_SPEC,         "Coexistence Specification IE" },
578     { IEEE802154_MLME_SUBIE_SUN_DEVICE_CAPABILITIES,  "SUN Device Capabilities IE" },
579     { IEEE802154_MLME_SUBIE_SUN_FSK_GEN_PHY,          "SUN FSK Generic PHY IE" },
580     { IEEE802154_MLME_SUBIE_MODE_SWITCH_PARAMETER,    "Mode Switch Parameter IE" },
581     { IEEE802154_MLME_SUBIE_PHY_PARAMETER_CHANGE,     "PHY Parameter Change IE" },
582     { IEEE802154_MLME_SUBIE_O_QPSK_PHY_MODE,          "O-QPSY PHY Mode IE" },
583     { IEEE802154_MLME_SUBIE_PCA_ALLOCATION,           "PCA Allocation IE" },
584     { IEEE802154_MLME_SUBIE_DSSS_OPER_MODE,           "LECIM DSSS Operating Mode IE"},
585     { IEEE802154_MLME_SUBIE_FSK_OPER_MODE,            "LECIM FSK Operating Mode IE" },
586     { IEEE802154_MLME_SUBIE_TVWS_PHY_OPE_MODE,        "TVWS PHY Operating Mode Description IE" },
587     { IEEE802154_MLME_SUBIE_TVWS_DEVICE_CAPAB,        "TVWS Device Capabilities IE" },
588     { IEEE802154_MLME_SUBIE_TVWS_DEVICE_CATEG,        "TVWS Device Category IE" },
589     { IEEE802154_MLME_SUBIE_TVWS_DEVICE_IDENTIF,      "TVWS Device Identification IE" },
590     { IEEE802154_MLME_SUBIE_TVWS_DEVICE_LOCATION,     "TVWS Device Location IE" },
591     { IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_QUERY,      "TVWS Channel Information Query IE" },
592     { IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_SOURCE,     "TVWS Channel Information Source IE" },
593     { IEEE802154_MLME_SUBIE_CTM,                      "CTM IE" },
594     { IEEE802154_MLME_SUBIE_TIMESTAMP,                "Timestamp IE" },
595     { IEEE802154_MLME_SUBIE_TIMESTAMP_DIFF,           "Timestamp Difference IE"},
596     { IEEE802154_MLME_SUBIE_TMCP_SPECIFICATION,       "TMCTP Specification IE" },
597     { IEEE802154_MLME_SUBIE_RCC_PHY_OPER_MODE,        "RCC PHY Operating Mode IE" },
598     { IEEE802154_IETF_SUBIE_6TOP,                     "6top IE" },
599     { 0, NULL }
600 };
601
602 static const value_string zboss_direction_names[] = {
603     { 0, "IN" },
604     { 1, "OUT" },
605     { 0, NULL }
606 };
607
608 static const value_string ietf_6top_types[] = {
609     { IETF_6TOP_TYPE_REQUEST, "Request" },
610     { IETF_6TOP_TYPE_RESPONSE, "Response" },
611     { IETF_6TOP_TYPE_CONFIRMATION, "Confirmation" },
612     { 0, NULL }
613 };
614
615 static const value_string ietf_6top_command_identifiers[] = {
616     { IETF_6TOP_CMD_ADD, "Add" },
617     { IETF_6TOP_CMD_DELETE, "Delete" },
618     { IETF_6TOP_CMD_STATUS, "Status" },
619     { IETF_6TOP_CMD_LIST, "List" },
620     { IETF_6TOP_CMD_CLEAR, "Clear" },
621     { 0, NULL }
622 };
623
624 static const value_string ietf_6top_return_codes[] = {
625     { IETF_6TOP_RC_SUCCESS, "SUCCESS" },
626     { IETF_6TOP_RC_ERR_VER, "ERR_VER" },
627     { IETF_6TOP_RC_ERR_SFID, "ERR_SFID" },
628     { IETF_6TOP_RC_ERR_GEN, "ERR_GEN" },
629     { IETF_6TOP_RC_ERR_BUSY, "ERR_BUSY" },
630     { IETF_6TOP_RC_ERR_NORES, "ERR_NORES" },
631     { IETF_6TOP_RC_ERR_RESET, "ERR_RESET" },
632     { IETF_6TOP_RC_ERR, "ERR" },
633     { 0, NULL }
634 };
635
636 static const value_string ietf_6top_generation_numbers[] = {
637     { 0, "clean" },
638     { 1, "counter" },
639     { 2, "counter" },
640     { 3, "reserved" },
641     { 0, NULL}
642 };
643
644 static const value_string ietf_6top_cell_options[] = {
645     { 0, "ALL" },
646     { 1, "TX" },
647     { 2, "RX" },
648     { 3, "TX|RX" },
649     { 4, "SHARED" },
650     { 5, "TX|SHARED" },
651     { 6, "RX|SHARED" },
652     { 7, "TX|RX|SHARED" },
653     { 0, NULL}
654 };
655
656 /* Preferences for 2003 security */
657 static gint ieee802154_sec_suite = SECURITY_LEVEL_ENC_MIC_64;
658 static gboolean ieee802154_extend_auth = TRUE;
659
660 /* Macro to check addressing, and throw a warning flag if incorrect. */
661 #define IEEE802154_CMD_ADDR_CHECK(_pinfo_, _item_, _cmdid_, _x_)     \
662    if (!(_x_))                                                       \
663      expert_add_info_format(_pinfo_, _item_, &ei_ieee802154_invalid_addressing, \
664                             "Invalid Addressing for %s",             \
665                             val_to_str_const(_cmdid_, ieee802154_cmd_names, "Unknown Command"))
666
667 /* CRC definitions. IEEE 802.15.4 CRCs vary from CCITT by using an initial value of
668  * 0x0000, and no XOR out. IEEE802154_CRC_XOR is defined as 0xFFFF in order to un-XOR
669  * the output from the CCITT CRC routines in Wireshark.
670  */
671 #define IEEE802154_CRC_SEED     0x0000
672 #define IEEE802154_CRC_XOROUT   0xFFFF
673 #define ieee802154_crc_tvb(tvb, offset)   (crc16_ccitt_tvb_seed(tvb, offset, IEEE802154_CRC_SEED) ^ IEEE802154_CRC_XOROUT)
674
675
676 static int ieee802_15_4_short_address_to_str(const address* addr, gchar *buf, int buf_len)
677 {
678     guint16 ieee_802_15_4_short_addr = pletoh16(addr->data);
679
680     if (ieee_802_15_4_short_addr == 0xffff)
681     {
682         g_strlcpy(buf, "Broadcast", buf_len);
683         return 10;
684     }
685
686     *buf++ = '0';
687     *buf++ = 'x';
688     buf = word_to_hex(buf, ieee_802_15_4_short_addr);
689     *buf = '\0'; /* NULL terminate */
690
691     return 7;
692 }
693
694 static int ieee802_15_4_short_address_str_len(const address* addr _U_)
695 {
696     return 11;
697 }
698
699 static int ieee802_15_4_short_address_len(void)
700 {
701     return 2;
702 }
703
704 /**
705  * Dissector helper, parses and displays the frame control field.
706  *
707  *@param tvb pointer to buffer containing raw packet.
708  *@param pinfo pointer to packet information fields
709  *@param tree pointer to data tree wireshark uses to display packet.
710  *@param packet IEEE 802.15.4 packet information.
711  *@param offset offset into the tvb to find the FCF.
712  *
713 */
714 static void
715 dissect_ieee802154_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet, guint *offset)
716 {
717     guint16     fcf;
718     static const int * fields[] = {
719         &hf_ieee802154_frame_type,
720         &hf_ieee802154_security,
721         &hf_ieee802154_pending,
722         &hf_ieee802154_ack_request,
723         &hf_ieee802154_pan_id_compression,
724         &hf_ieee802154_seqno_suppression,
725         &hf_ieee802154_ie_present,
726         &hf_ieee802154_dst_addr_mode,
727         &hf_ieee802154_version,
728         &hf_ieee802154_src_addr_mode,
729         NULL
730     };
731
732     /* Get the FCF field. */
733     fcf = tvb_get_letohs(tvb, *offset);
734
735      /* Parse FCF Flags. */
736     packet->frame_type          = (fcf & IEEE802154_FCF_TYPE_MASK);
737     packet->security_enable     = (fcf & IEEE802154_FCF_SEC_EN) >> 3;
738     packet->frame_pending       = (fcf & IEEE802154_FCF_FRAME_PND) >> 4;
739     packet->ack_request         = (fcf & IEEE802154_FCF_ACK_REQ) >> 5;
740     packet->pan_id_compression  = (fcf & IEEE802154_FCF_PAN_ID_COMPRESSION) >> 6;
741     /* bit 7 reserved */
742     packet->seqno_suppression   = (fcf & IEEE802154_FCF_SEQNO_SUPPRESSION) >> 8;
743     packet->ie_present          = (fcf & IEEE802154_FCF_IE_PRESENT) >> 9;
744     packet->dst_addr_mode       = (fcf & IEEE802154_FCF_DADDR_MASK) >> 10;
745     packet->version             = (fcf & IEEE802154_FCF_VERSION) >> 12;
746     packet->src_addr_mode       = (fcf & IEEE802154_FCF_SADDR_MASK) >> 14;
747
748     if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_BEACON)) {
749         proto_item_append_text(tree, " Enhanced Beacon");
750         col_set_str(pinfo->cinfo, COL_INFO, "Enhanced Beacon");
751     }
752     else {
753         proto_item_append_text(tree, " %s", val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved"));
754         col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved"));
755     }
756
757     proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf,
758                            ett_ieee802154_fcf, fields, ENC_LITTLE_ENDIAN);
759
760     *offset += 2;
761 } /* dissect_ieee802154_fcf */
762
763 /*
764  *Dissector for IEEE 802.15.4 non-ASK PHY packet with an FCS containing a 16-bit CRC value.
765  *
766  *@param tvb pointer to buffer containing raw packet.
767  *@param pinfo pointer to packet information fields
768  *@param tree pointer to data tree wireshark uses to display packet.
769 */
770 static int
771 dissect_ieee802154_nonask_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
772 {
773     proto_tree *ieee802154_tree = NULL;
774     proto_item *proto_root      = NULL;
775
776     guint       offset          = 0;
777     guint8      phr;
778     tvbuff_t*   mac;
779
780     /* Create the protocol tree. */
781     if (tree) {
782         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");
783         ieee802154_tree = proto_item_add_subtree(proto_root, ett_ieee802154_nonask_phy);
784     }
785
786     /* Add the protocol name. */
787     col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4 non-ASK PHY");
788     /* Add the packet length. */
789     col_add_fstr(pinfo->cinfo, COL_PACKET_LENGTH, "%i", tvb_captured_length(tvb));
790
791     phr=tvb_get_guint8(tvb,offset+4+1);
792
793     if(tree) {
794         guint loffset=offset;
795         static const int * phr_fields[] = {
796                     &hf_ieee802154_nonask_phy_length,
797                     NULL
798                 };
799
800         proto_tree_add_item(ieee802154_tree, hf_ieee802154_nonask_phy_preamble, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
801         loffset+=4;
802         proto_tree_add_item(ieee802154_tree, hf_ieee802154_nonask_phy_sfd, tvb, loffset, 1, ENC_LITTLE_ENDIAN);
803         loffset+=1;
804
805         proto_tree_add_bitmask(ieee802154_tree, tvb, loffset, hf_ieee802154_nonask_phr, ett_ieee802154_nonask_phy_phr,
806             phr_fields, ENC_NA);
807     }
808
809     offset+=4+2*1;
810     mac=tvb_new_subset_length_caplen(tvb,offset,-1, phr & IEEE802154_PHY_LENGTH_MASK);
811
812     /* Call the common dissector. */
813     dissect_ieee802154(mac, pinfo, ieee802154_tree, NULL);
814     return tvb_captured_length(tvb);
815 } /* dissect_ieee802154_nonask_phy */
816
817 /**
818  *Dissector for IEEE 802.15.4 packet with an FCS containing a 16-bit CRC value.
819  *
820  *@param tvb pointer to buffer containing raw packet.
821  *@param pinfo pointer to packet information fields.
822  *@param tree pointer to data tree wireshark uses to display packet.
823 */
824 static int
825 dissect_ieee802154(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
826 {
827     tvbuff_t *new_tvb = dissect_zboss_specific(tvb, pinfo, tree);
828     guint options = 0;
829
830     if (ieee802154_cc24xx)
831     {
832       options = DISSECT_IEEE802154_OPTION_CC24xx;
833     }
834     if (new_tvb != tvb)
835     {
836       /* ZBOSS traffic dump: always TI FCS, always ZigBee */
837       options = (DISSECT_IEEE802154_OPTION_CC24xx | DISSECT_IEEE802154_OPTION_ZBOSS);
838     }
839     /* Call the common dissector. */
840     dissect_ieee802154_common(new_tvb, pinfo, tree, options);
841     return tvb_captured_length(tvb);
842 } /* dissect_ieee802154 */
843
844 /**
845  * Dissector for IEEE 802.15.4 packet with no FCS present.
846  *
847  *@param tvb pointer to buffer containing raw packet.
848  *@param pinfo pointer to packet information fields
849  *@param tree pointer to data tree wireshark uses to display packet.
850  *@return captured length.
851 */
852 static int
853 dissect_ieee802154_nofcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_)
854 {
855     tvbuff_t    *new_tvb;
856     /* If there is no FCS present in the reported packet, then the length of
857      * the true IEEE 802.15.4 packet is actually 2 bytes longer. Re-create
858      * the buffer with an extended reported length so that the packet will
859      * be handled as though the FCS were truncated.
860      *
861      * Note, we can't just call tvb_set_reported_length(), because it includes
862      * checks to ensure that the new reported length is not longer than the old
863      * reported length (why?), and will throw an exception.
864      */
865     new_tvb = tvb_new_subset_length_caplen(tvb, 0, -1, tvb_reported_length(tvb)+IEEE802154_FCS_LEN);
866     /* Call the common dissector. */
867     dissect_ieee802154_common(new_tvb, pinfo, tree, 0);
868     return tvb_captured_length(tvb);
869 } /* dissect_ieee802154_nofcs */
870
871 /**
872  * Dissector for IEEE 802.15.4 packet dump produced by ZBOSS
873  *
874  *@param tvb pointer to buffer containing raw packet.
875  *@param pinfo pointer to packet information fields
876  *@param tree pointer to data tree wireshark uses to display packet.
877  *@return new tvb subset if this is really ZBOSS dump, else oririnal tvb.
878 */
879 static tvbuff_t *
880 dissect_zboss_specific(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
881 {
882     if (tvb_captured_length(tvb) > 5)
883     {
884         guint off = 0;
885         if (tvb_get_guint8(tvb, off++) == 'Z'
886             && tvb_get_guint8(tvb, off++) == 'B'
887             && tvb_get_guint8(tvb, off++) == 'O'
888             && tvb_get_guint8(tvb, off++) == 'S'
889             && tvb_get_guint8(tvb, off++) == 'S')
890         {
891             proto_tree *zboss_tree = NULL;
892             proto_item *proto_root = NULL;
893
894             /* Create the protocol tree. */
895             if (tree) {
896                 proto_root = proto_tree_add_protocol_format(tree, proto_zboss, tvb, 0, tvb_captured_length(tvb), "ZBOSS dump");
897                 zboss_tree = proto_item_add_subtree(proto_root, ett_ieee802154_zboss);
898             }
899
900             proto_tree_add_item(zboss_tree, zboss_direction, tvb, off, 1, ENC_NA);
901             proto_item_append_text(proto_root, ", %s", tvb_get_guint8(tvb, off) ? "OUT" : "IN");
902             off++;
903             proto_tree_add_item(zboss_tree, zboss_channel, tvb, off, 1, ENC_NA);
904             proto_item_append_text(proto_root, ", channel %u", tvb_get_guint8(tvb, off));
905             off++;
906             proto_tree_add_item(zboss_tree, zboss_trace_number, tvb, off, 4, ENC_LITTLE_ENDIAN);
907             off += 4;
908
909             return tvb_new_subset_length_caplen(tvb, off, tvb_captured_length(tvb) - off, tvb_captured_length(tvb) - off);
910         }
911     }
912     return tvb;
913 } /* dissect_zboss_heur */
914
915 /**
916  *Dissector for IEEE 802.15.4 packet with a ChipCon/Texas
917  *Instruments compatible FCS. This is typically called by
918  *layers encapsulating an IEEE 802.15.4 packet.
919  *
920  *@param tvb pointer to buffer containing raw packet.
921  *@param pinfo pointer to packet information fields
922  *@param tree pointer to data tree wireshark uses to display packet.
923 */
924 static int
925 dissect_ieee802154_cc24xx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_)
926 {
927     /* Call the common dissector. */
928     dissect_ieee802154_common(tvb, pinfo, tree, DISSECT_IEEE802154_OPTION_CC24xx);
929     return tvb_captured_length(tvb);
930 } /* dissect_ieee802154_cc24xx */
931
932 /**
933  *IEEE 802.15.4 packet dissection routine for Wireshark.
934  *
935  *This function extracts all the information first before displaying.
936  *If payload exists, that portion will be passed into another dissector
937  *for further processing.
938  *
939  *This is called after the individual dissect_ieee802154* functions
940  *have been called to determine what sort of FCS is present.
941  *The dissect_ieee802154* functions will set the parameters
942  *in the ieee802154_packet structure, and pass it to this one
943  *through the data parameter.
944  *
945  *@param tvb pointer to buffer containing raw packet.
946  *@param pinfo pointer to packet information fields
947  *@param tree pointer to data tree wireshark uses to display packet.
948  *@param options bitwise or of dissector options (see DISSECT_IEEE802154_OPTION_xxx).
949 */
950 static void
951 dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint options)
952 {
953     tvbuff_t                *volatile payload_tvb;
954     proto_tree              *volatile ieee802154_tree = NULL;
955     proto_item              *volatile proto_root = NULL;
956     proto_item              *hidden_item;
957     proto_item              *ti;
958     guint                   offset = 0;
959     volatile gboolean       fcs_ok = TRUE;
960     const char              *saved_proto;
961     ws_decrypt_status       status;
962     gboolean                dstPanPresent = FALSE;
963     gboolean                srcPanPresent = FALSE;
964
965     ieee802154_packet      *packet = wmem_new0(wmem_packet_scope(), ieee802154_packet);
966     ieee802154_short_addr   addr16;
967     ieee802154_hints_t     *ieee_hints;
968
969     heur_dtbl_entry_t      *hdtbl_entry;
970
971     packet->short_table = ieee802154_map.short_table;
972
973     /* Allocate frame data with hints for upper layers */
974     if(!pinfo->fd->flags.visited){
975         ieee_hints = wmem_new0(wmem_file_scope(), ieee802154_hints_t);
976         p_add_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0, ieee_hints);
977     } else {
978         ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0);
979     }
980
981     /* Create the protocol tree. */
982     if (tree) {
983         proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154, tvb, 0, tvb_captured_length(tvb), "IEEE 802.15.4");
984         ieee802154_tree = proto_item_add_subtree(proto_root, ett_ieee802154);
985     }
986     /* Add the protocol name. */
987     col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4");
988     /* Add the packet length. */
989     col_add_fstr(pinfo->cinfo, COL_PACKET_LENGTH, "%i", tvb_captured_length(tvb));
990
991     /* Add the packet length to the filter field */
992     hidden_item = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_frame_length, NULL, 0, 0, tvb_reported_length(tvb));
993     PROTO_ITEM_SET_HIDDEN(hidden_item);
994
995     /* Frame Control Field */
996     dissect_ieee802154_fcf(tvb, pinfo, ieee802154_tree, packet, &offset);
997
998     /* Sequence Number */
999     if (packet->seqno_suppression) {
1000         if (packet->version != IEEE802154_VERSION_2015) {
1001             expert_add_info(pinfo, proto_root, &ei_ieee802154_seqno_suppression);
1002         }
1003     } else { /* IEEE 802.15.4 Sequence Number Suppression */
1004     packet->seqno = tvb_get_guint8(tvb, offset);
1005     if (tree) {
1006         proto_tree_add_uint(ieee802154_tree, hf_ieee802154_seqno, tvb, offset, 1, packet->seqno);
1007         /* For Ack packets display this in the root. */
1008         if (packet->frame_type == IEEE802154_FCF_ACK) {
1009             proto_item_append_text(proto_root, ", Sequence Number: %u", packet->seqno);
1010         }
1011     }
1012     offset += 1;
1013     }
1014
1015     /*
1016      * ADDRESSING FIELDS
1017      */
1018     /* Clear out the addressing strings. */
1019     clear_address(&pinfo->net_dst);
1020     clear_address(&pinfo->dl_dst);
1021     clear_address(&pinfo->dst);
1022     clear_address(&pinfo->net_src);
1023     clear_address(&pinfo->dl_src);
1024     clear_address(&pinfo->src);
1025
1026     if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_RESERVED) {
1027         /* Invalid Destination Address Mode. Abort Dissection. */
1028         expert_add_info(pinfo, proto_root, &ei_ieee802154_dst);
1029         return;
1030     }
1031
1032     if (packet->src_addr_mode == IEEE802154_FCF_ADDR_RESERVED) {
1033         /* Invalid Source Address Mode. Abort Dissection. */
1034         expert_add_info(pinfo, proto_root, &ei_ieee802154_src);
1035         return;
1036     }
1037
1038     if (packet->version == IEEE802154_VERSION_RESERVED) {
1039         /* Unknown Frame Version. Abort Dissection. */
1040         expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver);
1041         return;
1042     }
1043     else if ((packet->version == IEEE802154_VERSION_2003) ||  /* For Frame Version 0b00 and */
1044              (packet->version == IEEE802154_VERSION_2006))  { /* 0b01 effect defined in section 7.2.1.5 */
1045
1046         if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* if both destination and source */
1047             (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) { /* addressing information is present */
1048             if (packet->pan_id_compression == 1) { /* PAN IDs are identical */
1049                 dstPanPresent = TRUE;
1050                 srcPanPresent = FALSE; /* source PAN ID is omitted */
1051             }
1052             else { /* PAN IDs are different, both shall be included in the frame */
1053                 dstPanPresent = TRUE;
1054                 srcPanPresent = TRUE;
1055             }
1056         }
1057         else {
1058             if (packet->pan_id_compression == 1) { /* all remaining cases pan_id_compression must be zero */
1059                 expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_addressing);
1060                 return;
1061             }
1062             else {
1063                 /* only either the destination or the source addressing information is present */
1064                 if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) &&        /*   Present   */
1065                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) {        /* Not Present */
1066                     dstPanPresent = TRUE;
1067                     srcPanPresent = FALSE;
1068                 }
1069                 else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&   /* Not Present */
1070                          (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) {   /*   Present   */
1071                     dstPanPresent = FALSE;
1072                     srcPanPresent = TRUE;
1073                 }
1074                 else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&   /* Not Present */
1075                          (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) {   /* Not Present */
1076                     dstPanPresent = FALSE;
1077                     srcPanPresent = FALSE;
1078                 }
1079                 else {
1080                     expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_addressing);
1081                     return;
1082                 }
1083             }
1084         }
1085     }
1086     else if (packet->version == IEEE802154_VERSION_2015) {
1087         /* for Frame Version 0b10 PAN Id Compression only applies to these frame types */
1088         if ((packet->frame_type == IEEE802154_FCF_BEACON) ||
1089             (packet->frame_type == IEEE802154_FCF_DATA)   ||
1090             (packet->frame_type == IEEE802154_FCF_ACK)    ||
1091             (packet->frame_type == IEEE802154_FCF_CMD)       ) {
1092
1093             /* Implements Table 7-6 of IEEE 802.15.4-2015
1094              *
1095              *      Destination Address  Source Address  Destination PAN ID  Source PAN ID   PAN ID Compression
1096              *-------------------------------------------------------------------------------------------------
1097              *  1.  Not Present          Not Present     Not Present         Not Present     0
1098              *  2.  Not Present          Not Present     Present             Not Present     1
1099              *  3.  Present              Not Present     Present             Not Present     0
1100              *  4.  Present              Not Present     Not Present         Not Present     1
1101              *
1102              *  5.  Not Present          Present         Not Present         Present         0
1103              *  6.  Not Present          Present         Not Present         Not Present     1
1104              *
1105              *  7.  Extended             Extended        Present             Not Present     0
1106              *  8.  Extended             Extended        Not Present         Not Present     1
1107              *
1108              *  9.  Short                Short           Present             Present         0
1109              * 10.  Short                Extended        Present             Present         0
1110              * 11.  Extended             Short           Present             Present         0
1111              *
1112              * 12.  Short                Extended        Present             Not Present     1
1113              * 13.  Extended             Short           Present             Not Present     1
1114              * 14.  Short                Short           Present             Not Present     1
1115              */
1116
1117             /* Row 1 */
1118             if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&      /* Not Present */
1119                 (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) &&      /* Not Present */
1120                 (packet->pan_id_compression == 0)) {
1121                         dstPanPresent = FALSE;
1122                         srcPanPresent = FALSE;
1123             }
1124             /* Row 2 */
1125             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
1126                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
1127                      (packet->pan_id_compression == 1)) {
1128                         dstPanPresent = TRUE;
1129                         srcPanPresent = FALSE;
1130             }
1131             /* Row 3 */
1132             else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
1133                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
1134                      (packet->pan_id_compression == 0)) {
1135                         dstPanPresent = TRUE;
1136                         srcPanPresent = FALSE;
1137             }
1138             /* Row 4 */
1139             else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
1140                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
1141                      (packet->pan_id_compression == 1)) {
1142                         dstPanPresent = FALSE;
1143                         srcPanPresent = FALSE;
1144             }
1145             /* Row 5 */
1146             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
1147                      (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
1148                      (packet->pan_id_compression == 0)) {
1149                         dstPanPresent = FALSE;
1150                         srcPanPresent = TRUE;
1151             }
1152             /* Row 6 */
1153             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
1154                      (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /*  Present    */
1155                      (packet->pan_id_compression == 1)) {
1156                         dstPanPresent = FALSE;
1157                         srcPanPresent = FALSE;
1158             }
1159             /* Row 7 */
1160             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
1161                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
1162                      (packet->pan_id_compression == 0)) {
1163                         dstPanPresent = TRUE;
1164                         srcPanPresent = FALSE;
1165             }
1166             /* Row 8 */
1167             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
1168                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /*  Extended    */
1169                      (packet->pan_id_compression == 1)) {
1170                         dstPanPresent = FALSE;
1171                         srcPanPresent = FALSE;
1172             }
1173             /* Row 9 */
1174             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /*  Short     */
1175                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /*  Short     */
1176                      (packet->pan_id_compression == 0)) {
1177                         dstPanPresent = TRUE;
1178                         srcPanPresent = TRUE;
1179             }
1180             /* Row 10 */
1181             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /*  Short    */
1182                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&   /*  Extended */
1183                      (packet->pan_id_compression == 0)) {
1184                         dstPanPresent = TRUE;
1185                         srcPanPresent = TRUE;
1186             }
1187             /* Row 11 */
1188             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)   &&   /*  Extended */
1189                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
1190                      (packet->pan_id_compression == 0)) {
1191                         dstPanPresent = TRUE;
1192                         srcPanPresent = TRUE;
1193             }
1194             /* Row 12 */
1195             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
1196                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT)   &&   /*  Extended */
1197                      (packet->pan_id_compression == 1)) {
1198                         dstPanPresent = TRUE;
1199                         srcPanPresent = FALSE;
1200             }
1201             /* Row 13 */
1202             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)   &&   /*  Extended */
1203                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
1204                      (packet->pan_id_compression == 1)) {
1205                         dstPanPresent = TRUE;
1206                         srcPanPresent = FALSE;
1207             }
1208             /* Row 14 */
1209             else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
1210                      (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&   /*  Short    */
1211                      (packet->pan_id_compression == 1)) {
1212                         dstPanPresent = TRUE;
1213                         srcPanPresent = FALSE;
1214             }
1215             else {
1216                 expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_panid_compression2);
1217                 return;
1218             }
1219         }
1220         else { /* Frame Type is neither Beacon, Data, Ack, nor Command: PAN ID Compression is not used */
1221             dstPanPresent = FALSE; /* no PAN ID will */
1222             srcPanPresent = FALSE; /* be present     */
1223         }
1224     }
1225     else {
1226         /* Unknown Frame Version. Abort Dissection. */
1227         expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver);
1228         return;
1229     }
1230
1231     /*
1232      * Addressing Fields
1233      */
1234
1235     /* Destination PAN Id */
1236     if (dstPanPresent) {
1237         packet->dst_pan = tvb_get_letohs(tvb, offset);
1238         if (ieee802154_tree) {
1239             proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_panID, tvb, offset, 2, packet->dst_pan);
1240         }
1241         offset += 2;
1242     }
1243
1244     /* Destination Address  */
1245     if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
1246         gchar* dst_addr;
1247
1248         /* Get the address. */
1249         packet->dst16 = tvb_get_letohs(tvb, offset);
1250
1251         /* Provide address hints to higher layers that need it. */
1252         if (ieee_hints) {
1253             ieee_hints->dst16 = packet->dst16;
1254         }
1255
1256         set_address_tvb(&pinfo->dl_dst, ieee802_15_4_short_address_type, 2, tvb, offset);
1257         copy_address_shallow(&pinfo->dst, &pinfo->dl_dst);
1258         dst_addr = address_to_str(wmem_packet_scope(), &pinfo->dst);
1259
1260         proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst16, tvb, offset, 2, packet->dst16);
1261         proto_item_append_text(proto_root, ", Dst: %s", dst_addr);
1262
1263         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_addr);
1264         offset += 2;
1265     }
1266     else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1267         guint64 *p_addr = (guint64 *)wmem_new(pinfo->pool, guint64);
1268
1269         /* Get the address */
1270         packet->dst64 = tvb_get_letoh64(tvb, offset);
1271
1272         /* Copy and convert the address to network byte order. */
1273         *p_addr = pntoh64(&(packet->dst64));
1274
1275         /* Display the destination address. */
1276         /* XXX - OUI resolution doesn't happen when displaying resolved
1277          * EUI64 addresses; that should probably be fixed in
1278          * epan/addr_resolv.c.
1279          */
1280         set_address(&pinfo->dl_dst, AT_EUI64, 8, p_addr);
1281         copy_address_shallow(&pinfo->dst, &pinfo->dl_dst);
1282         if (tree) {
1283             proto_tree_add_item(ieee802154_tree, hf_ieee802154_dst64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1284             proto_item_append_text(proto_root, ", Dst: %s", eui64_to_display(wmem_packet_scope(), packet->dst64));
1285         }
1286         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", eui64_to_display(wmem_packet_scope(), packet->dst64));
1287         offset += 8;
1288     }
1289
1290     /* Source PAN Id */
1291     if (srcPanPresent) {
1292         packet->src_pan = tvb_get_letohs(tvb, offset);
1293         proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src_panID, tvb, offset, 2, packet->src_pan);
1294         offset += 2;
1295     }
1296     else {
1297         if (dstPanPresent) {
1298             packet->src_pan = packet->dst_pan;
1299         }
1300         else {
1301             packet->src_pan = IEEE802154_BCAST_PAN;
1302         }
1303     }
1304     if (ieee_hints) {
1305         ieee_hints->src_pan = packet->src_pan;
1306     }
1307
1308     /* Source Address */
1309     if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
1310         gchar* src_addr;
1311
1312         /* Get the address. */
1313         packet->src16 = tvb_get_letohs(tvb, offset);
1314
1315         if (!pinfo->fd->flags.visited) {
1316             /* If we know our extended source address from previous packets,
1317                 * provide a pointer to it in a hint for upper layers */
1318             addr16.addr = packet->src16;
1319             addr16.pan = packet->src_pan;
1320
1321             if (ieee_hints) {
1322                 ieee_hints->src16 = packet->src16;
1323                 ieee_hints->map_rec = (ieee802154_map_rec *)
1324                     g_hash_table_lookup(ieee802154_map.short_table, &addr16);
1325             }
1326         }
1327
1328         set_address_tvb(&pinfo->dl_src, ieee802_15_4_short_address_type, 2, tvb, offset);
1329         copy_address_shallow(&pinfo->src, &pinfo->dl_src);
1330         src_addr = address_to_str(wmem_packet_scope(), &pinfo->src);
1331
1332         /* Add the addressing info to the tree. */
1333         if (tree) {
1334             proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src16, tvb, offset, 2, packet->src16);
1335             proto_item_append_text(proto_root, ", Src: %s", src_addr);
1336
1337             if (ieee_hints && ieee_hints->map_rec) {
1338                 /* Display inferred source address info */
1339                 ti = proto_tree_add_eui64(ieee802154_tree, hf_ieee802154_src64, tvb, offset, 0,
1340                         ieee_hints->map_rec->addr64);
1341                 PROTO_ITEM_SET_GENERATED(ti);
1342
1343                 if ( ieee_hints->map_rec->start_fnum ) {
1344                     ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src64_origin, tvb, 0, 0,
1345                         ieee_hints->map_rec->start_fnum);
1346                 }
1347                 else {
1348                     ti = proto_tree_add_uint_format_value(ieee802154_tree, hf_ieee802154_src64_origin, tvb, 0, 0,
1349                         ieee_hints->map_rec->start_fnum, "Pre-configured");
1350                 }
1351                 PROTO_ITEM_SET_GENERATED(ti);
1352             }
1353         }
1354
1355         col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", src_addr);
1356
1357         offset += 2;
1358     }
1359     else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
1360         guint64 *p_addr = (guint64 *)wmem_new(pinfo->pool, guint64);
1361
1362         /* Get the address. */
1363         packet->src64 = tvb_get_letoh64(tvb, offset);
1364
1365         /* Copy and convert the address to network byte order. */
1366         *p_addr = pntoh64(&(packet->src64));
1367
1368         /* Display the source address. */
1369         /* XXX - OUI resolution doesn't happen when displaying resolved
1370          * EUI64 addresses; that should probably be fixed in
1371          * epan/addr_resolv.c.
1372          */
1373         set_address(&pinfo->dl_src, AT_EUI64, 8, p_addr);
1374         copy_address_shallow(&pinfo->src, &pinfo->dl_src);
1375         if (tree) {
1376             proto_tree_add_item(ieee802154_tree, hf_ieee802154_src64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1377             proto_item_append_text(proto_root, ", Src: %s", eui64_to_display(wmem_packet_scope(), packet->src64));
1378         }
1379
1380         col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", eui64_to_display(wmem_packet_scope(), packet->src64));
1381         offset += 8;
1382     }
1383
1384
1385     /* Check, but don't display the FCS yet, otherwise the payload dissection
1386      * may be out of place in the tree. But we want to know if the FCS is OK in
1387      * case the CRC is bad (don't want to continue dissection to the NWK layer).
1388      */
1389     if (tvb_bytes_exist(tvb, tvb_reported_length(tvb)-IEEE802154_FCS_LEN, IEEE802154_FCS_LEN)) {
1390         /* The FCS is in the last two bytes of the packet. */
1391         guint16     fcs = tvb_get_letohs(tvb, tvb_reported_length(tvb)-IEEE802154_FCS_LEN);
1392         /* Check if we are expecting a CC2420-style FCS*/
1393         if (options & DISSECT_IEEE802154_OPTION_CC24xx) {
1394             fcs_ok = (fcs & IEEE802154_CC24xx_CRC_OK);
1395         }
1396         else {
1397             guint16 fcs_calc = ieee802154_crc_tvb(tvb, tvb_reported_length(tvb)-IEEE802154_FCS_LEN);
1398             fcs_ok = (fcs == fcs_calc);
1399         }
1400     }
1401
1402     /* Existance of the Auxiliary Security Header is controlled by the Security Enabled Field */
1403     if (packet->security_enable) {
1404       proto_tree *header_tree, *field_tree;
1405       guint8                    security_control;
1406       guint                     aux_length = 5; /* Minimum length of the auxiliary header. */
1407       static const int * security_fields[] = {
1408                     &hf_ieee802154_security_level,
1409                     &hf_ieee802154_key_id_mode,
1410                     &hf_ieee802154_aux_sec_reserved,
1411                     NULL
1412                 };
1413
1414       /* Parse the security control field. */
1415       security_control = tvb_get_guint8(tvb, offset);
1416       packet->security_level = (ieee802154_security_level)(security_control & IEEE802154_AUX_SEC_LEVEL_MASK);
1417       packet->key_id_mode = (ieee802154_key_id_mode)((security_control & IEEE802154_AUX_KEY_ID_MODE_MASK) >> IEEE802154_AUX_KEY_ID_MODE_SHIFT);
1418
1419       /* Compute the length of the auxiliary header and create a subtree.  */
1420       if (packet->key_id_mode != KEY_ID_MODE_IMPLICIT) aux_length++;
1421       if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_4) aux_length += 4;
1422       if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_8) aux_length += 8;
1423       header_tree = proto_tree_add_subtree(ieee802154_tree, tvb, offset, aux_length,
1424                     ett_ieee802154_auxiliary_security, NULL, "Auxiliary Security Header");
1425
1426       /* Security Control Field */
1427       proto_tree_add_bitmask(header_tree, tvb, offset, hf_ieee802154_security_control_field, ett_ieee802154_aux_sec_control, security_fields, ENC_NA);
1428       offset++;
1429
1430       /* Frame Counter Field */
1431       packet->frame_counter = tvb_get_letohl (tvb, offset);
1432       proto_tree_add_uint(header_tree, hf_ieee802154_aux_sec_frame_counter, tvb, offset,4, packet->frame_counter);
1433       offset +=4;
1434
1435       /* Key identifier field(s). */
1436       if (packet->key_id_mode != KEY_ID_MODE_IMPLICIT) {
1437         /* Create a subtree. */
1438         field_tree = proto_tree_add_subtree(header_tree, tvb, offset, 1,
1439                     ett_ieee802154_aux_sec_key_id, &ti, "Key Identifier Field"); /* Will fix length later. */
1440         /* Add key source, if it exists. */
1441         if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_4) {
1442           packet->key_source.addr32 = tvb_get_ntohl(tvb, offset);
1443           proto_tree_add_uint64(field_tree, hf_ieee802154_aux_sec_key_source, tvb, offset, 4, packet->key_source.addr32);
1444           proto_item_set_len(ti, 1 + 4);
1445           offset += (int)sizeof (guint32);
1446         }
1447         if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_8) {
1448           packet->key_source.addr64 = tvb_get_ntoh64(tvb, offset);
1449           proto_tree_add_uint64(field_tree, hf_ieee802154_aux_sec_key_source, tvb, offset, 8, packet->key_source.addr64);
1450           proto_item_set_len(ti, 1 + 8);
1451           offset += 8;
1452         }
1453         /* Add key identifier. */
1454         packet->key_index = tvb_get_guint8(tvb, offset);
1455         proto_tree_add_uint(field_tree, hf_ieee802154_aux_sec_key_index, tvb, offset,1, packet->key_index);
1456         offset++;
1457       }
1458     }
1459
1460     /*
1461      * NONPAYLOAD FIELDS
1462      *
1463      */
1464     /* All of the beacon fields, except the beacon payload are considered nonpayload. */
1465     if ((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006)) {
1466         if (packet->frame_type == IEEE802154_FCF_BEACON) { /* Regular Beacon. Some are not present in frame version (Enhanced) Beacons */
1467             dissect_ieee802154_superframe(tvb, pinfo, ieee802154_tree, &offset); /* superframe spec */
1468             dissect_ieee802154_gtsinfo(tvb, pinfo, ieee802154_tree, &offset);    /* GTS information fields */
1469             dissect_ieee802154_pendaddr(tvb, pinfo, ieee802154_tree, &offset);   /* Pending address list */
1470         }
1471
1472         if (packet->frame_type == IEEE802154_FCF_CMD) {
1473             /**
1474              *  In IEEE802.15.4-2003 and 2006 the command identifier is considered to be part of the header
1475              * and is thus not encrypted. For IEEE802.15.4-2012e and later the command id is considered to be
1476              * part of the payload, is encrypted, and follows the payload IEs. Thus we only parse the command id
1477              * here for 2006 and earlier frames. */
1478             packet->command_id = tvb_get_guint8(tvb, offset);
1479             if (tree) {
1480                 proto_tree_add_uint(ieee802154_tree, hf_ieee802154_cmd_id, tvb, offset, 1, packet->command_id);
1481             }
1482             offset++;
1483
1484             /* Display the command identifier in the info column. */
1485             col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
1486         }
1487     }
1488     else {
1489         if (packet->ie_present) {
1490                 dissect_ieee802154_header_ie(tvb, pinfo, ieee802154_tree, &offset, packet);
1491         }
1492     }
1493
1494     /* IEEE 802.15.4-2003 may have security information pre-pended to payload */
1495     if (packet->security_enable && (packet->version == IEEE802154_VERSION_2003)) {
1496         /* Store security suite preference in the 2006 security level identifier to simplify 2003 integration! */
1497         packet->security_level = (ieee802154_security_level)ieee802154_sec_suite;
1498
1499         /* Frame Counter and Key Sequence Counter prepended to the payload of an encrypted frame */
1500         if (IEEE802154_IS_ENCRYPTED(packet->security_level)) {
1501             packet->frame_counter = tvb_get_letohl (tvb, offset);
1502             proto_tree_add_uint(ieee802154_tree, hf_ieee802154_sec_frame_counter, tvb, offset, (int)sizeof(guint32), packet->frame_counter);
1503             offset += (int)sizeof(guint32);
1504
1505             packet->key_sequence_counter = tvb_get_guint8 (tvb, offset);
1506             proto_tree_add_uint(ieee802154_tree, hf_ieee802154_sec_key_sequence_counter, tvb, offset, (int)sizeof(guint8), packet->key_sequence_counter);
1507             offset += (int)sizeof(guint8);
1508         }
1509     }
1510
1511     /* Encrypted Payload. */
1512     if (packet->security_enable) {
1513         payload_tvb = dissect_ieee802154_decrypt(tvb, offset, pinfo, packet, &status);
1514
1515         /* Get the unencrypted data if decryption failed.  */
1516         if (!payload_tvb) {
1517             /* Deal with possible truncation and the FCS field at the end. */
1518             gint            reported_len = tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN;
1519             gint            captured_len = tvb_captured_length(tvb)-offset;
1520             if (reported_len < captured_len) captured_len = reported_len;
1521             payload_tvb = tvb_new_subset_length_caplen(tvb, offset, captured_len, reported_len);
1522         }
1523
1524         /* Display the reason for failure, and abort if the error was fatal. */
1525         switch (status) {
1526         case DECRYPT_PACKET_SUCCEEDED:
1527         case DECRYPT_NOT_ENCRYPTED:
1528             /* No problem. */
1529             break;
1530
1531         case DECRYPT_VERSION_UNSUPPORTED:
1532             /* We don't support decryption with that version of the protocol */
1533             expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "We don't support decryption with protocol version %u", packet->version);
1534             call_data_dissector(payload_tvb, pinfo, tree);
1535             goto dissect_ieee802154_fcs;
1536
1537         case DECRYPT_PACKET_TOO_SMALL:
1538             expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Packet was too small to include the CRC and MIC");
1539             call_data_dissector(payload_tvb, pinfo, tree);
1540             goto dissect_ieee802154_fcs;
1541
1542         case DECRYPT_PACKET_NO_EXT_SRC_ADDR:
1543             expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "No extended source address - can't decrypt");
1544             call_data_dissector(payload_tvb, pinfo, tree);
1545             goto dissect_ieee802154_fcs;
1546
1547         case DECRYPT_PACKET_NO_KEY:
1548             expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "No encryption key set - can't decrypt");
1549             call_data_dissector(payload_tvb, pinfo, tree);
1550             goto dissect_ieee802154_fcs;
1551
1552         case DECRYPT_PACKET_DECRYPT_FAILED:
1553             expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Decrypt failed");
1554             call_data_dissector(payload_tvb, pinfo, tree);
1555             goto dissect_ieee802154_fcs;
1556
1557         case DECRYPT_PACKET_MIC_CHECK_FAILED:
1558             expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "MIC check failed");
1559             /*
1560              * Abort only if the payload was encrypted, in which case we
1561              * probably didn't decrypt the packet right (eg: wrong key).
1562              */
1563             if (IEEE802154_IS_ENCRYPTED(packet->security_level)) {
1564                 call_data_dissector(payload_tvb, pinfo, tree);
1565                 goto dissect_ieee802154_fcs;
1566             }
1567             break;
1568         }
1569     }
1570     /* Plaintext Payload. */
1571     else {
1572         /* Deal with possible truncation and the FCS field at the end. */
1573         gint            reported_len = tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN;
1574         gint            captured_len = tvb_captured_length(tvb)-offset;
1575         if (reported_len < captured_len) captured_len = reported_len;
1576         payload_tvb = tvb_new_subset_length_caplen(tvb, offset, captured_len, reported_len);
1577     }
1578
1579     /* presense of Payload IEs is defined by the termination of the Header IEs */
1580     offset = 0;
1581     if (packet->payload_ie_present) {
1582         offset += dissect_ieee802154_payload_ie(payload_tvb, pinfo, ieee802154_tree, offset);
1583     }
1584
1585     if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_CMD)) {
1586         /* In 802.15.4e and later the Command Id follows the Payload IEs. */
1587         packet->command_id = tvb_get_guint8(payload_tvb, offset);
1588         if (tree) {
1589             proto_tree_add_uint(ieee802154_tree, hf_ieee802154_cmd_id, payload_tvb, offset, 1, packet->command_id);
1590         }
1591         offset++;
1592
1593         /* Display the command identifier in the info column. */
1594         if ((packet->version == IEEE802154_VERSION_2015) && (packet->command_id == IEEE802154_CMD_BEACON_REQ)) {
1595             col_set_str(pinfo->cinfo, COL_INFO, "Enhanced Beacon Request");
1596         }
1597         else {
1598             col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
1599         }
1600     }
1601
1602     if (offset > 0) {
1603       payload_tvb = tvb_new_subset_remaining(payload_tvb, offset);
1604       offset = 0;
1605     }
1606
1607     /* If it is ok to dissect bad FCS, FCS might be absent, so still dissect
1608      * commands like Association request. */
1609     if ((!ieee802154_fcs_ok
1610          /* If either ZBOSS traffic dump or TI CC2{45}xx, FCS must be present. */
1611          && !(options & (DISSECT_IEEE802154_OPTION_ZBOSS | DISSECT_IEEE802154_OPTION_CC24xx)))
1612         || tvb_captured_length(payload_tvb) > 0) {
1613         /*
1614          * Wrap the sub-dissection in a try/catch block in case the payload is
1615          * broken. First we store the current protocol so we can fix it if an
1616          * exception is thrown by the subdissectors.
1617          */
1618         saved_proto = pinfo->current_proto;
1619         /* Try to dissect the payload. */
1620         TRY {
1621             switch (packet->frame_type) {
1622             case IEEE802154_FCF_BEACON:
1623                 if (!dissector_try_heuristic(ieee802154_beacon_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) {
1624                     /* Could not subdissect, call the data dissector instead. */
1625                     call_data_dissector(payload_tvb, pinfo, tree);
1626                 }
1627                 break;
1628
1629             case IEEE802154_FCF_CMD:
1630                 dissect_ieee802154_command(payload_tvb, pinfo, ieee802154_tree, packet);
1631                 break;
1632
1633             case IEEE802154_FCF_DATA:
1634                 /* Sanity-check. */
1635                 if ((!fcs_ok && ieee802154_fcs_ok) || !tvb_reported_length(payload_tvb)) {
1636                     call_data_dissector(payload_tvb, pinfo, tree);
1637                     break;
1638                 }
1639                 if (options & DISSECT_IEEE802154_OPTION_ZBOSS) {
1640                     call_dissector_with_data(zigbee_nwk_handle, payload_tvb, pinfo, tree, packet);
1641                     break;
1642                 }
1643                 /* Try the PANID dissector table for stateful dissection. */
1644                 if (dissector_try_uint_new(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, TRUE, packet)) {
1645                     break;
1646                 }
1647                 /* Try again with the destination PANID (if different) */
1648                 if (((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) ||
1649                      (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) &&
1650                         (packet->dst_pan != packet->src_pan) &&
1651                         dissector_try_uint_new(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, TRUE, packet)) {
1652                     break;
1653                 }
1654                 /* Try heuristic dissection. */
1655                 if (dissector_try_heuristic(ieee802154_heur_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) break;
1656                 /* Fall-through to dump undissectable payloads. */
1657             default:
1658                 /* Could not subdissect, call the data dissector instead. */
1659                 call_data_dissector(payload_tvb, pinfo, tree);
1660             } /* switch */
1661         }
1662         CATCH_ALL {
1663             /*
1664              * Someone encountered an error while dissecting the payload. But
1665              * we haven't yet finished processing all of our layer. Catch and
1666              * display the exception, then fall-through to finish displaying
1667              * the FCS (which we display last so the frame is ordered correctly
1668              * in the tree).
1669              */
1670             show_exception(payload_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
1671             pinfo->current_proto = saved_proto;
1672         }
1673         ENDTRY;
1674     }
1675     /*
1676      * Frame Check Sequence (FCS)
1677      *
1678      */
1679 dissect_ieee802154_fcs:
1680     /* The FCS should be the last bytes of the reported packet. */
1681     offset = tvb_reported_length(tvb)-IEEE802154_FCS_LEN;
1682     /* Dissect the FCS only if it exists (captures which don't or can't get the
1683      * FCS will simply truncate the packet to omit it, but should still set the
1684      * reported length to cover the original packet length), so if the snapshot
1685      * is too short for an FCS don't make a fuss.
1686      */
1687     if (tvb_bytes_exist(tvb, offset, IEEE802154_FCS_LEN) && (tree)) {
1688         proto_tree  *field_tree;
1689         guint16     fcs = tvb_get_letohs(tvb, offset);
1690
1691         /* Display the FCS depending on expected FCS format */
1692         if ((options & DISSECT_IEEE802154_OPTION_CC24xx)) {
1693             /* Create a subtree for the FCS. */
1694             field_tree = proto_tree_add_subtree_format(ieee802154_tree, tvb, offset, 2, ett_ieee802154_fcs, NULL,
1695                         "Frame Check Sequence (TI CC24xx format): FCS %s", (fcs_ok) ? "OK" : "Bad");
1696             /* Display FCS contents.  */
1697             proto_tree_add_int(field_tree, hf_ieee802154_rssi, tvb, offset++, 1, (gint8) (fcs & IEEE802154_CC24xx_RSSI));
1698             proto_tree_add_boolean(field_tree, hf_ieee802154_fcs_ok, tvb, offset, 1, (gboolean) (fcs & IEEE802154_CC24xx_CRC_OK));
1699             proto_tree_add_uint(field_tree, hf_ieee802154_correlation, tvb, offset, 1, (guint8) ((fcs & IEEE802154_CC24xx_CORRELATION) >> 8));
1700         }
1701         else {
1702             ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_fcs, tvb, offset, 2, fcs);
1703             if (fcs_ok) {
1704                 proto_item_append_text(ti, " (Correct)");
1705             }
1706             else {
1707                 proto_item_append_text(ti, " (Incorrect, expected FCS=0x%04x", ieee802154_crc_tvb(tvb, offset));
1708             }
1709             /* To Help with filtering, add the fcs_ok field to the tree.  */
1710             ti = proto_tree_add_boolean(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, offset, 2, fcs_ok);
1711             PROTO_ITEM_SET_HIDDEN(ti);
1712         }
1713     }
1714     else if (tree) {
1715         /* Even if the FCS isn't present, add the fcs_ok field to the tree to
1716          * help with filter. Be sure not to make it visible though.
1717          */
1718         ti = proto_tree_add_boolean_format_value(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, offset, 2, fcs_ok, "Unknown");
1719         PROTO_ITEM_SET_HIDDEN(ti);
1720     }
1721
1722     /* If the CRC is invalid, make a note of it in the info column. */
1723     if (!fcs_ok) {
1724         col_append_str(pinfo->cinfo, COL_INFO, ", Bad FCS");
1725         if (tree) proto_item_append_text(proto_root, ", Bad FCS");
1726
1727         /* Flag packet as having a bad crc. */
1728         expert_add_info(pinfo, proto_root, &ei_ieee802154_fcs);
1729     }
1730 } /* dissect_ieee802154_common */
1731
1732 /**
1733  *Subdissector command for the Header Information Element TSCH Time Correction
1734  *
1735  *@param tvb pointer to buffer containing raw packet.
1736  *@param h_inf_elem_tree pointer to data tree wireshark uses to display packet.
1737  *@param offset offset into the tvbuff to begin dissection.
1738  */
1739 static void
1740 dissect_802154_h_ie_time_correction(tvbuff_t *tvb, proto_tree *h_inf_elem_tree, guint *offset){
1741
1742     guint16     time_correction;
1743     proto_tree  *h_inf_elem_tree_payload = NULL;
1744
1745     time_correction = tvb_get_letohs(tvb, *offset);
1746
1747     h_inf_elem_tree_payload = proto_tree_add_subtree_format(h_inf_elem_tree, tvb, *offset, 2, ett_ieee802154_h_ie_payload, NULL,
1748                 "Data: Time Correction IE, Content(0x%04x)", time_correction);
1749
1750     if(time_correction <= 0x07ff) {
1751         proto_tree_add_item(h_inf_elem_tree_payload, hf_ieee802154_h_ie_time_correction1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1752     }
1753     else if ((time_correction >= 0x0800) && (time_correction <= 0x0fff)){
1754         proto_tree_add_item(h_inf_elem_tree_payload, hf_ieee802154_h_ie_time_correction2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1755     }
1756     else if ((time_correction >= 0x8000) && (time_correction <= 0x87ff)){
1757         proto_tree_add_item(h_inf_elem_tree_payload, hf_ieee802154_h_ie_time_correction3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1758     }
1759     else if ((time_correction >= 0x8800) && (time_correction <= 0x8fff )){
1760         proto_tree_add_item(h_inf_elem_tree_payload, hf_ieee802154_h_ie_time_correction4, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1761     }
1762     *offset += 2;
1763 } /* dissect_802154_h_ie_time_correction */
1764
1765 /**
1766  *Subdissector command for the Payload Information Element MLME TSCH Channel Hopping
1767  *
1768  *@param tvb pointer to buffer containing raw packet.
1769  *@param p_inf_elem_tree_mlme pointer to data tree wireshark uses to display packet.
1770  *@param psie_remaining size of the Information Element.
1771  *@param offset offset into the tvbuff to begin dissection.
1772  */
1773 static void
1774 dissect_802154_p_ie_lg_mlme_channel_hopping(tvbuff_t *tvb, proto_tree *p_inf_elem_tree_mlme, guint16 psie_remaining, guint *offset){
1775     proto_tree *p_inf_elem_tree_mlme_payload = NULL;
1776     guint8     hopping_sequence_id;
1777
1778     hopping_sequence_id = tvb_get_guint8(tvb, *offset);
1779
1780     p_inf_elem_tree_mlme_payload = proto_tree_add_subtree_format(p_inf_elem_tree_mlme, tvb, *offset, 1, ett_ieee802154_mlme_payload, NULL,
1781                 "Data: Channel Hopping IE (0x%0d)", hopping_sequence_id);
1782
1783     proto_tree_add_uint(p_inf_elem_tree_mlme_payload, hf_ieee802154_p_ie_mlme_lg_hopping_sequence_id, tvb, (*offset), psie_remaining, hopping_sequence_id);
1784
1785     if (psie_remaining > 1){
1786         proto_tree_add_item(p_inf_elem_tree_mlme_payload, hf_ieee802154_mlme_ie_data, tvb, *offset, psie_remaining, ENC_NA);
1787     }
1788     *offset += psie_remaining;
1789 } /* dissect_802154_p_ie_lg_mlme_channel_hopping */
1790
1791 /**
1792  *Subdissector command for the Payload Information Element MLME TSCH Synchronization
1793  *
1794  *@param tvb pointer to buffer containing raw packet.
1795  *@param p_inf_elem_tree_mlme pointer to data tree wireshark uses to display packet.
1796  *@param psie_remaining size of the Information Element.
1797  *@param offset offset into the tvbuff to begin dissection.
1798  */
1799 static void
1800 dissect_802154_p_ie_sh_mlme_tsch_sync(tvbuff_t *tvb, proto_tree *p_inf_elem_tree_mlme, guint psie_remaining, guint *offset){
1801     proto_tree *p_inf_elem_tree_mlme_payload = NULL;
1802
1803     p_inf_elem_tree_mlme_payload = proto_tree_add_subtree_format(p_inf_elem_tree_mlme, tvb, *offset, psie_remaining, ett_ieee802154_mlme_payload, NULL,
1804                 "Data: TSCH Synchronization IE");
1805
1806     proto_tree_add_item(p_inf_elem_tree_mlme_payload, hf_ieee802154_p_ie_mlme_sh_tsch_asn, tvb, (*offset), 5, ENC_LITTLE_ENDIAN);
1807     proto_tree_add_item(p_inf_elem_tree_mlme_payload, hf_ieee802154_p_ie_mlme_sh_tsch_join_p, tvb, (*offset) + 5, 1, ENC_LITTLE_ENDIAN);
1808     *offset += 6;
1809 }/* dissect_802154_p_ie_sh_mlme_tsch_sync*/
1810
1811 /**
1812  *Subdissector command for the Payload Information Element MLME TSCH Slotframe and Link
1813  *
1814  *@param tvb pointer to buffer containing raw packet.
1815  *@param p_inf_elem_tree_mlme pointer to data tree wireshark uses to display packet.
1816  *@param psie_remaining size of the Information Element.
1817  *@param offset offset into the tvbuff to begin dissection.
1818  */
1819 static void
1820 dissect_802154_p_ie_sh_mlme_tsch_slotframe_link(tvbuff_t *tvb, proto_tree *p_inf_elem_tree_mlme, guint16 psie_remaining, guint *offset){
1821     guint8      nb_slotframes;
1822     guint8      nb_slotframes_aux;
1823     guint8      nb_links;
1824     guint8      nb_links_aux;
1825     proto_tree *p_inf_elem_tree_mlme_payload = NULL;
1826     proto_tree *p_inf_elem_tree_mlme_payload_data = NULL;
1827     proto_tree *p_inf_elem_tree_psie_slotframe_link_slotframes = NULL;
1828     guint8      slotframe_index;
1829     nb_slotframes       = tvb_get_guint8(tvb, *offset);
1830     nb_slotframes_aux   = nb_slotframes;
1831
1832     p_inf_elem_tree_mlme_payload = proto_tree_add_subtree_format(p_inf_elem_tree_mlme, tvb, *offset, psie_remaining, ett_ieee802154_mlme_payload, NULL,
1833                                                                  "Data: Slotframe and Link IE");
1834     proto_tree_add_item(p_inf_elem_tree_mlme_payload, hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_nb_slotf, tvb, (*offset), 1, ENC_LITTLE_ENDIAN);
1835     *offset += 1;
1836
1837     slotframe_index = 1;
1838     while ( nb_slotframes_aux > 0 ){
1839         nb_links            = tvb_get_guint8(tvb, *offset+3);
1840         nb_links_aux        = nb_links;
1841
1842         p_inf_elem_tree_psie_slotframe_link_slotframes =
1843           proto_tree_add_subtree_format(p_inf_elem_tree_mlme_payload,
1844                                         tvb, *offset, 4 + 5 * nb_links_aux,
1845                                         ett_ieee802154_psie_slotframe_link_slotframes,
1846                                         NULL, "Slotframes [%u]", slotframe_index);
1847         slotframe_index += 1;
1848
1849         proto_tree_add_item(p_inf_elem_tree_psie_slotframe_link_slotframes, hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_slotf_handle, tvb, (*offset), 1, ENC_LITTLE_ENDIAN);
1850         proto_tree_add_item(p_inf_elem_tree_psie_slotframe_link_slotframes, hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_slotf_size, tvb, (*offset) + 1, 2, ENC_LITTLE_ENDIAN);
1851         proto_tree_add_item(p_inf_elem_tree_psie_slotframe_link_slotframes, hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_nb_links, tvb, (*offset) + 3, 1, ENC_LITTLE_ENDIAN);
1852
1853         nb_slotframes_aux -= 1;
1854         *offset += 4;
1855         while (nb_links_aux > 0) {
1856
1857             p_inf_elem_tree_mlme_payload_data = proto_tree_add_subtree_format(p_inf_elem_tree_psie_slotframe_link_slotframes, tvb, *offset, 5, ett_ieee802154_mlme_payload_data, NULL,
1858                     "Data: Link Information");
1859             proto_tree_add_item(p_inf_elem_tree_mlme_payload_data, hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_timeslot, tvb, (*offset), 2, ENC_LITTLE_ENDIAN);
1860             proto_tree_add_item(p_inf_elem_tree_mlme_payload_data, hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_channel_offset, tvb, (*offset) + 2, 2, ENC_LITTLE_ENDIAN);
1861             proto_tree_add_item(p_inf_elem_tree_mlme_payload_data, hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_options, tvb, (*offset) + 4, 1, ENC_LITTLE_ENDIAN);
1862             nb_links_aux -= 1;
1863             *offset += 5;
1864         }
1865     }
1866 }/* dissect_802154_p_ie_sh_mlme_tsch_slotframe_link */
1867
1868 /**
1869  *Subdissector command for the 6TOP Protocol contained within the Payload Information Elements.
1870  *
1871  *@param tvb pointer to buffer containing raw packet.
1872  *@param pinfo pointer to packet information fields.
1873  *@param p_inf_elem_tree pointer to data tree wireshark uses to display packet.
1874  *@param offset offset into the tvbuff to begin dissection.
1875  *@param pie_length size of the 6TOP message
1876  */
1877 static int
1878 dissect_ieee802154_6top(tvbuff_t *tvb, packet_info *pinfo, proto_tree *p_inf_elem_tree, guint offset, gint pie_length)
1879 {
1880     const guint8 supported_6p_version = 1;
1881
1882     guint8     subie;
1883     guint8     version;
1884     guint8     type;
1885     guint8     code;
1886     guint8     seqnum;
1887     guint8     gab;
1888     guint8     gba;
1889     int        orig_offset = offset;
1890     gboolean   have_cell_list = FALSE;
1891     int        i;
1892     proto_tree *sixtop_tree = NULL;
1893     proto_tree *version_type_tree = NULL;
1894     proto_tree *seqnum_gab_gba_tree = NULL;
1895     proto_tree *cell_list_tree = NULL;
1896     proto_tree *cell_tree = NULL;
1897     proto_item *type_item = NULL;
1898     proto_item *code_item = NULL;
1899     const gchar *code_str = NULL;
1900     static const int * cell_options[] = {
1901         &hf_ieee802154_p_ie_6top_cell_option_tx,
1902         &hf_ieee802154_p_ie_6top_cell_option_rx,
1903         &hf_ieee802154_p_ie_6top_cell_option_shared,
1904         &hf_ieee802154_p_ie_6top_cell_option_reserved,
1905         NULL
1906     };
1907
1908     if (pie_length < 5) {
1909         return pie_length;
1910     }
1911
1912     subie = tvb_get_guint8(tvb, offset);
1913     version =  tvb_get_guint8(tvb, offset + 1) & IETF_6TOP_VERSION;
1914
1915     if (subie != IEEE802154_IETF_SUBIE_6TOP || version != supported_6p_version) {
1916         return pie_length;
1917     }
1918
1919     type = (tvb_get_guint8(tvb, offset + 1) & IETF_6TOP_TYPE) >> 4;
1920     code = tvb_get_guint8(tvb, offset + 2);
1921     seqnum = tvb_get_guint8(tvb, offset + 4) & IETF_6TOP_SEQNUM;
1922     gab = (tvb_get_guint8(tvb, offset + 4) & IETF_6TOP_GAB) >> 4;
1923     gba = (tvb_get_guint8(tvb, offset + 4) & IETF_6TOP_GBA) >> 6;
1924
1925     proto_tree_add_item(p_inf_elem_tree, hf_ieee802154_p_ie_ietf_sub_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1926
1927     sixtop_tree = proto_tree_add_subtree_format(p_inf_elem_tree, tvb, offset, pie_length, ett_ieee802154_p_ie_6top, NULL, "6top IE Content");
1928     version_type_tree = proto_tree_add_subtree_format(sixtop_tree, tvb, offset + 1, 1, ett_ieee802154_p_ie_6top_version_type, NULL,
1929                                                       "Version: %u, Type: %s", version, val_to_str_const(type, ietf_6top_types,"Unknown"));
1930     proto_tree_add_item(version_type_tree, hf_ieee802154_p_ie_6top_version, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
1931     type_item = proto_tree_add_item(version_type_tree, hf_ieee802154_p_ie_6top_type, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
1932     proto_tree_add_item(version_type_tree, hf_ieee802154_p_ie_6top_flags_reserved, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
1933     code_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_code, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
1934     proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_sfid, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
1935     seqnum_gab_gba_tree = proto_tree_add_subtree_format(sixtop_tree, tvb, offset + 4, 1, ett_ieee802154_p_ie_6top_seqnum_gab_gba, NULL,
1936                                                         "Seqnum: %u, GAB: %u, GBA: %u", seqnum, gab, gba);
1937     proto_tree_add_item(seqnum_gab_gba_tree, hf_ieee802154_p_ie_6top_seqnum, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
1938     proto_tree_add_item(seqnum_gab_gba_tree, hf_ieee802154_p_ie_6top_gab, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
1939     proto_tree_add_item(seqnum_gab_gba_tree, hf_ieee802154_p_ie_6top_gba, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
1940
1941     col_set_str(pinfo->cinfo, COL_PROTOCOL, "6top");
1942     if (type == IETF_6TOP_TYPE_REQUEST) {
1943       code_str = val_to_str_const(code, ietf_6top_command_identifiers,"Unknown");
1944       col_add_fstr(pinfo->cinfo, COL_INFO, "6P %s Request", code_str);
1945     } else {
1946       code_str = val_to_str_const(code, ietf_6top_return_codes,"Unknown");
1947       col_add_fstr(pinfo->cinfo, COL_INFO, "6P %s (%s)",
1948                    val_to_str_const(type, ietf_6top_types,"Unknown"), code_str);
1949     }
1950     proto_item_append_text(code_item, " (%s)", code_str);
1951
1952     offset += 5;
1953     pie_length -= 5;
1954
1955     if (type == IETF_6TOP_TYPE_REQUEST) {
1956         switch(code) {
1957         case IETF_6TOP_CMD_ADD:
1958         case IETF_6TOP_CMD_DELETE:
1959             if (pie_length < 4) {
1960                 break;
1961             }
1962             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1963             proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_p_ie_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN);
1964             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_num_cells, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
1965             pie_length -= 4;
1966             offset += 4;
1967             if (pie_length > 0 && (pie_length % 4) == 0) {
1968                 have_cell_list = TRUE;
1969             }
1970             break;
1971         case IETF_6TOP_CMD_STATUS:
1972             if (pie_length < 3) {
1973                 break;
1974             }
1975             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1976             proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_p_ie_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN);
1977             pie_length -= 3;
1978             offset += 3;
1979             break;
1980         case IETF_6TOP_CMD_LIST:
1981             if (pie_length != 8) {
1982                 break;
1983             }
1984             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1985             proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_p_ie_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN);
1986             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_reserved, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
1987             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_offset, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1988             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_max_num_cells, tvb, offset + 6, 2, ENC_LITTLE_ENDIAN);
1989             pie_length -= 8;
1990             offset += 8;
1991             break;
1992         case IETF_6TOP_CMD_CLEAR:
1993             if (pie_length < 2) {
1994                 break;
1995             }
1996             proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1997             pie_length -= 2;
1998             offset += 2;
1999             break;
2000         default:
2001             /* unsupported command */
2002             expert_add_info(pinfo, code_item, &ei_ieee802154_p_ie_6top_code);
2003             break;
2004         }
2005     } else if (type == IETF_6TOP_TYPE_RESPONSE || type == IETF_6TOP_TYPE_CONFIRMATION) {
2006         switch(code) {
2007         case IETF_6TOP_RC_SUCCESS:
2008             if (pie_length > 0) {
2009                 if (pie_length == 1) {
2010                     proto_tree_add_item(sixtop_tree, hf_ieee802154_p_ie_6top_num_cells, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2011                     pie_length -= 1;
2012                     offset += 1;
2013                 } else if ((pie_length % 4) == 0) {
2014                     have_cell_list = TRUE;
2015                 }
2016             }
2017             break;
2018         case IETF_6TOP_RC_ERR_VER:
2019         case IETF_6TOP_RC_ERR_SFID:
2020         case IETF_6TOP_RC_ERR_GEN:
2021         case IETF_6TOP_RC_ERR_BUSY:
2022         case IETF_6TOP_RC_ERR_NORES:
2023         case IETF_6TOP_RC_ERR_RESET:
2024         case IETF_6TOP_RC_ERR:
2025             /* They have no other field */
2026             break;
2027         default:
2028             /* unsupported return code */
2029             expert_add_info(pinfo, code_item, &ei_ieee802154_p_ie_6top_code);
2030             break;
2031         }
2032     } else {
2033         /* unsupported type */
2034         expert_add_info(pinfo, type_item, &ei_ieee802154_p_ie_6top_type);
2035     }
2036
2037     if (have_cell_list) {
2038         cell_list_tree = proto_tree_add_subtree_format(sixtop_tree, tvb, offset, pie_length, ett_ieee802154_p_ie_6top_cell_list, NULL,
2039                                                        "Cell List");
2040         for (i = 0; pie_length > 0; pie_length -= 4, offset += 4, i++){
2041             cell_tree = proto_tree_add_subtree_format(cell_list_tree, tvb, offset, 4, ett_ieee802154_p_ie_6top_cell, NULL,
2042                                                       "Cell [%u]", i);
2043             proto_tree_add_item(cell_tree, hf_ieee802154_p_ie_6top_slot_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2044             proto_tree_add_item(cell_tree, hf_ieee802154_p_ie_6top_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
2045         }
2046     }
2047
2048     return offset - orig_offset;
2049 } /* dissect_ieee802154_6top */
2050
2051 /**
2052  *Subdissector command for the Superframe specification sub-field within the beacon frame.
2053  *
2054  *@param tvb pointer to buffer containing raw packet.
2055  *@param pinfo pointer to packet information fields (unused).
2056  *@param tree pointer to command subtree.
2057  *@param offset offset into the tvbuff to begin dissection.
2058 */
2059 void
2060 dissect_ieee802154_superframe(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
2061 {
2062     static const int * superframe[] = {
2063         &hf_ieee802154_beacon_order,
2064         &hf_ieee802154_superframe_order,
2065         &hf_ieee802154_cap,
2066         &hf_ieee802154_superframe_battery_ext,
2067         &hf_ieee802154_superframe_coord,
2068         &hf_ieee802154_assoc_permit,
2069         NULL
2070     };
2071
2072     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);
2073     (*offset) += 2;
2074 } /* dissect_ieee802154_superframe */
2075
2076 /**
2077  *Subdissector command for the GTS information fields within the beacon frame.
2078  *
2079  *@param tvb            - pointer to buffer containing raw packet.
2080  *@param pinfo          - pointer to packet information fields (unused).
2081  *@param tree           - pointer to command subtree.
2082  *@param offset         - offset into the tvbuff to begin dissection.
2083 */
2084 void
2085 dissect_ieee802154_gtsinfo(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
2086 {
2087     proto_tree *field_tree = NULL;
2088     proto_tree *subtree    = NULL;
2089     proto_item *ti;
2090     guint8      gts_spec;
2091     guint8      gts_count;
2092
2093     /*  Get and display the GTS specification field */
2094     gts_spec = tvb_get_guint8(tvb, *offset);
2095     gts_count = gts_spec & IEEE802154_GTS_COUNT_MASK;
2096     if (tree) {
2097         /*  Add Subtree for GTS information. */
2098         if (gts_count) {
2099             field_tree = proto_tree_add_subtree(tree, tvb, *offset, 2 + (gts_count * 3), ett_ieee802154_gts, NULL, "GTS");
2100         }
2101         else {
2102             field_tree = proto_tree_add_subtree(tree, tvb, *offset, 1, ett_ieee802154_gts, NULL, "GTS");
2103         }
2104
2105         proto_tree_add_uint(field_tree, hf_ieee802154_gts_count, tvb, *offset, 1, gts_count);
2106         proto_tree_add_boolean(field_tree, hf_ieee802154_gts_permit, tvb, *offset, 1, gts_spec & IEEE802154_GTS_PERMIT_MASK);
2107     }
2108     (*offset) += 1;
2109
2110     /* If the GTS descriptor count is nonzero, then the GTS directions mask and descriptor list are present. */
2111     if (gts_count) {
2112         guint8  gts_directions = tvb_get_guint8(tvb, *offset);
2113         guint   gts_rx = 0;
2114         int     i;
2115
2116         /* Display the directions mask. */
2117         if (tree) {
2118             proto_tree  *dir_tree;
2119
2120             /* Create a subtree. */
2121             dir_tree = proto_tree_add_subtree(field_tree, tvb, *offset, 1, ett_ieee802154_gts_direction, &ti, "GTS Directions");
2122
2123             /* Add the directions to the subtree. */
2124             for (i=0; i<gts_count; i++) {
2125                 gboolean    dir = gts_directions & IEEE802154_GTS_DIRECTION_SLOT(i);
2126                 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");
2127                 if (dir) gts_rx++;
2128             } /* for */
2129             proto_item_append_text(ti, ": %i Receive & %i Transmit", gts_rx, gts_count - gts_rx);
2130         }
2131         (*offset) += 1;
2132
2133         /* Create a subtree for the GTS descriptors. */
2134         subtree = proto_tree_add_subtree(field_tree, tvb, *offset, gts_count * 3, ett_ieee802154_gts_descriptors, NULL, "GTS Descriptors");
2135
2136         /* Get and display the GTS descriptors. */
2137         for (i=0; i<gts_count; i++) {
2138             guint16 gts_addr        = tvb_get_letohs(tvb, (*offset));
2139             guint8  gts_slot        = tvb_get_guint8(tvb, (*offset)+2);
2140             guint8  gts_length      = (gts_slot & IEEE802154_GTS_LENGTH_MASK) >> IEEE802154_GTS_LENGTH_SHIFT;
2141
2142             gts_slot = (gts_slot & IEEE802154_GTS_SLOT_MASK);
2143
2144             if (tree) {
2145                 /* Add address, slot, and time length fields. */
2146                 ti = proto_tree_add_uint(subtree, hf_ieee802154_gts_address, tvb, (*offset), 3, gts_addr);
2147                 proto_item_append_text(ti, ", Slot: %i", gts_slot);
2148                 proto_item_append_text(ti, ", Length: %i", gts_length);
2149             }
2150             (*offset) += 3;
2151         } /* for */
2152     }
2153 } /* dissect_ieee802154_gtsinfo */
2154
2155 /**
2156  *Subdissector command for the pending address list fields within the beacon frame.
2157  *
2158  *@param tvb pointer to buffer containing raw packet.
2159  *@param pinfo pointer to packet information fields (unused).
2160  *@param tree pointer to command subtree.
2161  *@offset offset into the tvbuff to begin dissection.
2162 */
2163 void
2164 dissect_ieee802154_pendaddr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
2165 {
2166     proto_tree *subtree;
2167     guint8      pend_spec;
2168     guint8      pend_num16;
2169     guint8      pend_num64;
2170     int         i;
2171
2172     /*  Get the Pending Addresses specification fields */
2173     pend_spec = tvb_get_guint8(tvb, *offset);
2174     pend_num16 = pend_spec & IEEE802154_PENDADDR_SHORT_MASK;
2175     pend_num64 = (pend_spec & IEEE802154_PENDADDR_LONG_MASK) >> IEEE802154_PENDADDR_LONG_SHIFT;
2176
2177     /*  Add Subtree for the addresses */
2178     subtree = proto_tree_add_subtree_format(tree, tvb, *offset, 1 + 2*pend_num16 + 8*pend_num64,
2179                         ett_ieee802154_pendaddr, NULL, "Pending Addresses: %i Short and %i Long", pend_num16, pend_num64);
2180     (*offset) += 1;
2181
2182     for (i=0; i<pend_num16; i++) {
2183         guint16 addr = tvb_get_letohs(tvb, *offset);
2184         proto_tree_add_uint(subtree, hf_ieee802154_pending16, tvb, *offset, 2, addr);
2185         (*offset) += 2;
2186     } /* for */
2187     for (i=0; i<pend_num64; i++) {
2188         proto_tree_add_item(subtree, hf_ieee802154_pending64, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
2189         (*offset) += 8;
2190     } /* for */
2191 } /* dissect_ieee802154_pendaddr */
2192
2193 /**
2194  *Subdissector for Header IEs (Information Elements)
2195  *Since the header is never encrypted and the payload may be encrypted,
2196  *we dissect header and payload IEs separately.
2197  *The termination of the Header IE tells us whether there are any
2198  *payload IEs to follow, so it is always set by the termination.
2199  *
2200  *@param tvb pointer to buffer containing raw packet.
2201  *@param pinfo pointer to packet information fields (unused).
2202  *@param tree pointer to command subtree.
2203  *@param offset offset into the tvbuff to begin dissection.
2204  *@param packet IEEE 802.15.4 packet information.
2205 */
2206 static void
2207 dissect_ieee802154_header_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset, ieee802154_packet *packet)
2208 {
2209     proto_tree *subtree;
2210     guint16     header_ie;
2211     guint16     id;
2212     guint16     length;
2213     GByteArray *gba = g_byte_array_new();
2214
2215     static const int * fields[] = {
2216         &hf_ieee802154_header_ie_type,
2217         &hf_ieee802154_header_ie_id,
2218         &hf_ieee802154_header_ie_length,
2219         NULL
2220     };
2221
2222     do {
2223         header_ie =  tvb_get_letohs(tvb, *offset);
2224         id        = (header_ie & IEEE802154_HEADER_IE_ID_MASK) >> 7;
2225         length    =  header_ie & IEEE802154_HEADER_IE_LENGTH_MASK;
2226
2227         /* Create a subtree for this command frame. */
2228         subtree = proto_tree_add_subtree(tree, tvb, *offset, 2+length, ett_ieee802154_header, NULL, "Header IE");
2229         proto_item_append_text(subtree, ", Element ID: %s, Length: %d", val_to_str_const(id, ieee802154_header_ie_names, "Unknown IE"), length);
2230
2231         proto_tree_add_bitmask(subtree, tvb, *offset, hf_ieee802154_header_ie,
2232                                ett_ieee802154_header_ie, fields, ENC_LITTLE_ENDIAN);
2233
2234         *offset += 2;
2235
2236         /* until the Header IEs are finalized, just use the data dissector */
2237         if (length > 0) {
2238             switch(id){
2239                 case IEEE802154_HEADER_IE_TIME_CORR:
2240                     dissect_802154_h_ie_time_correction(tvb, subtree, offset);
2241                     break;
2242                 case IEEE802154_HEADER_VENDOR_SPECIFIC:
2243                 case IEEE802154_HEADER_IE_CSL:
2244                 case IEEE802154_HEADER_IE_RIT:
2245                 case IEEE802154_HEADER_IE_DSME_PAN:
2246                 case IEEE802154_HEADER_IE_RENDEZVOUS:
2247                 case IEEE802154_HEADER_IE_EXT_DSME_PAN:
2248                 case IEEE802154_HEADER_IE_FSCD:
2249                 case IEEE802154_HEADER_IE_SMPL_SUPER_FRM:
2250                 case IEEE802154_HEADER_IE_SMPL_GTS:
2251                 case IEEE802154_HEADER_IE_LECIM:
2252                 case IEEE802154_HEADER_IE_TRLE:
2253                 case IEEE802154_HEADER_IE_RCC_CAP:
2254                 case IEEE802154_HEADER_IE_RCCN:
2255                 case IEEE802154_HEADER_IE_GLOBAL_TIME:
2256                 case IEEE802154_HEADER_IE_DA_IE:
2257                 default:
2258                     proto_tree_add_bytes_item(subtree, hf_ieee802154_header_ie_data, tvb, *offset, length, ENC_NA, gba, NULL, NULL);
2259                     *offset += length;
2260                     break;
2261             }
2262         }
2263     } while ((tvb_reported_length_remaining(tvb, *offset) - IEEE802154_FCS_LEN > 1) &&
2264              (id != IEEE802154_HEADER_IE_EID_TERM1) &&
2265              (id != IEEE802154_HEADER_IE_EID_TERM2));
2266
2267     /* Presense of Payload IEs is determined by how the Header IEs are terminated */
2268     if (id == IEEE802154_HEADER_IE_EID_TERM1) {
2269         packet->payload_ie_present = TRUE;
2270     }
2271     else {
2272         packet->payload_ie_present = FALSE;
2273     }
2274
2275 } /* dissect_ieee802154_header_ie */
2276
2277 /**
2278  *Subdissector command for MLME Payload Sub IEs (Information Elements)
2279  *
2280  *@param tvb pointer to buffer containing raw packet.
2281  *@param pinfo pointer to packet information fields (unused).
2282  *@param tree pointer to command subtree.
2283  *@param offset offset into the tvbuff to begin dissection.
2284 */
2285 static int
2286 dissect_ieee802154_payload_mlme_sub_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
2287 {
2288
2289     proto_tree *subtree;
2290     guint16     psie_ie;
2291     guint16     psie_id;
2292     guint       psie_remaining = 0;
2293     int         orig_offset = offset;
2294
2295     static const int * fields_short[] = {
2296         &hf_ieee802154_psie_type_short,
2297         &hf_ieee802154_psie_id_short,
2298         &hf_ieee802154_psie_length_short,
2299         NULL
2300     };
2301
2302     static const int * fields_long[] = {
2303         &hf_ieee802154_psie_type_long,
2304         &hf_ieee802154_psie_id_long,
2305         &hf_ieee802154_psie_length_long,
2306         NULL
2307     };
2308
2309
2310     static const int * fields_eb_filter[] = {
2311         &hf_ieee802154_psie_eb_filter_pjoin,
2312         &hf_ieee802154_psie_eb_filter_lqi,
2313         &hf_ieee802154_psie_eb_filter_percent,
2314         &hf_ieee802154_psie_eb_filter_attr_id,
2315         /* reserved 5-7 */
2316         NULL
2317     };
2318
2319     psie_ie    =  tvb_get_letohs(tvb, offset);
2320     if (psie_ie & IEEE802154_PSIE_TYPE_MASK) { /* long format */
2321         psie_id        = (psie_ie & IEEE802154_PSIE_ID_MASK_LONG) >> 11;
2322         psie_remaining =  psie_ie & IEEE802154_PSIE_LENGTH_MASK_LONG;
2323         subtree = proto_tree_add_subtree(tree, tvb, offset, 2+psie_remaining, ett_ieee802154_psie_long, NULL, "Nested Sub IE (long)");
2324         proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_psie_long,
2325                                ett_ieee802154_psie_long_bitmap, fields_long, ENC_LITTLE_ENDIAN);
2326     }
2327     else { /* short format */
2328         psie_id        = (psie_ie & IEEE802154_PSIE_ID_MASK_SHORT) >> 8;
2329         psie_remaining =  psie_ie & IEEE802154_PSIE_LENGTH_MASK_SHORT;
2330         subtree = proto_tree_add_subtree(tree, tvb, offset, 2+psie_remaining, ett_ieee802154_psie_short, NULL, "Nested Sub IE (short)");
2331         proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_psie_short,
2332                                ett_ieee802154_psie_short_bitmap, fields_short, ENC_LITTLE_ENDIAN);
2333     }
2334     proto_item_append_text(subtree, ", Sub IE: %s, Length: %d", val_to_str_const(psie_id, ieee802154_psie_names, "Unknown IE"), psie_remaining);
2335     offset += 2;
2336
2337     switch (psie_id) {
2338         case IEEE802154_MLME_SUBIE_ENHANCED_BEACON_FILTER:
2339             {
2340                 guint8  filter;
2341                 guint8  attr_len;
2342                 guint32 attr_bitmap = 0;
2343
2344                 filter = tvb_get_guint8(tvb, offset);
2345                 proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_psie_eb_filter,
2346                                        ett_ieee802154_psie_enh_beacon_flt_bitmap, fields_eb_filter,
2347                                        ENC_NA);
2348                 offset += 1;
2349
2350                 if (filter & IEEE802154_MLME_PSIE_EB_FLT_LQI) {
2351                     proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_lqi_min, tvb, offset, 1, ENC_NA);
2352                     offset += 1;
2353                 }
2354
2355                 if (filter & IEEE802154_MLME_PSIE_EB_FLT_PERCENT) {
2356                     proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_percent_prob, tvb, offset, 1, ENC_NA);
2357                     offset += 1;
2358                 }
2359
2360                 attr_len = (filter & IEEE802154_MLME_PSIE_EB_FLT_ATTR_LEN) >> 3;
2361                 if (attr_len) {
2362                     switch(attr_len) {
2363                         case 1:
2364                             attr_bitmap = (guint32)tvb_get_guint8(tvb, offset);
2365                             break;
2366                         case 2:
2367                             attr_bitmap = (guint32)tvb_get_ntohs(tvb, offset);
2368                             break;
2369                         case 3:
2370                             attr_bitmap = tvb_get_ntoh24(tvb, offset);
2371                             break;
2372                         /* default: not reached, attr len is only 2 bits: 0x18 */
2373                     }
2374
2375                     /* just display in hex until we know how to decode */
2376                     proto_tree_add_uint(subtree, hf_ieee802154_psie_eb_filter_attr_id_bitmap, tvb, offset,
2377                                          attr_len, attr_bitmap);
2378                     offset += attr_len;
2379                 }
2380             }
2381             break;
2382
2383         case IEEE802154_MLME_SUBIE_TSCH_SYNCH:
2384                 dissect_802154_p_ie_sh_mlme_tsch_sync(tvb, subtree, psie_remaining, &offset);
2385                 break;
2386         case IEEE802154_MLME_SUBIE_TSCH_SLOTFR_LINK:
2387                 dissect_802154_p_ie_sh_mlme_tsch_slotframe_link(tvb, subtree, psie_remaining, &offset);
2388                 break;
2389         case IEEE802154_MLME_SUBIE_TSCH_TIMESLOT:
2390                 if (psie_remaining) {
2391                 proto_tree_add_item(subtree, hf_ieee802154_mlme_ie_data, tvb, offset, psie_remaining, ENC_NA);
2392                 offset += psie_remaining;
2393                 }
2394                 break;
2395         case IEEE802154_MLME_SUBIE_CHANNEL_HOPPING:
2396                 dissect_802154_p_ie_lg_mlme_channel_hopping(tvb, subtree, psie_remaining, &offset);
2397                 break;
2398         case IEEE802154_MLME_SUBIE_HOPPING_TIMING:
2399         case IEEE802154_MLME_SUBIE_MAC_METRICS:
2400         case IEEE802154_MLME_SUBIE_ALL_MAC_METRICS:
2401         case IEEE802154_MLME_SUBIE_COEXISTENCE_SPEC:
2402         case IEEE802154_MLME_SUBIE_SUN_DEVICE_CAPABILITIES:
2403         case IEEE802154_MLME_SUBIE_SUN_FSK_GEN_PHY:
2404         case IEEE802154_MLME_SUBIE_MODE_SWITCH_PARAMETER:
2405         case IEEE802154_MLME_SUBIE_PHY_PARAMETER_CHANGE:
2406         case IEEE802154_MLME_SUBIE_O_QPSK_PHY_MODE:
2407         case IEEE802154_MLME_SUBIE_PCA_ALLOCATION:
2408         case IEEE802154_MLME_SUBIE_DSSS_OPER_MODE:
2409         case IEEE802154_MLME_SUBIE_FSK_OPER_MODE:
2410         case IEEE802154_MLME_SUBIE_TVWS_PHY_OPE_MODE:
2411         case IEEE802154_MLME_SUBIE_TVWS_DEVICE_CAPAB:
2412         case IEEE802154_MLME_SUBIE_TVWS_DEVICE_CATEG:
2413         case IEEE802154_MLME_SUBIE_TVWS_DEVICE_IDENTIF:
2414         case IEEE802154_MLME_SUBIE_TVWS_DEVICE_LOCATION:
2415         case IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_QUERY:
2416         case IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_SOURCE:
2417         case IEEE802154_MLME_SUBIE_CTM:
2418         case IEEE802154_MLME_SUBIE_TIMESTAMP:
2419         case IEEE802154_MLME_SUBIE_TIMESTAMP_DIFF:
2420         case IEEE802154_MLME_SUBIE_TMCP_SPECIFICATION:
2421         case IEEE802154_MLME_SUBIE_RCC_PHY_OPER_MODE:
2422         default:
2423             /* display bytes */
2424             if (psie_remaining) {
2425                 proto_tree_add_item(subtree, hf_ieee802154_mlme_ie_data, tvb, offset, psie_remaining, ENC_NA);
2426                 offset += psie_remaining;
2427             }
2428             break;
2429     }
2430
2431     return (offset - orig_offset);
2432 }
2433
2434 /**
2435  *Subdissector command for Vendor Specific IEs (Information Elements)
2436  *
2437  *@param tvb pointer to buffer containing the Vendor Specific IE
2438  *@param pinfo pointer to packet information fields (unused).
2439  *@param tree pointer to command subtree.
2440  *@param offset offset into the tvbuff to begin dissection.
2441  *@param pie_length the length of the Vendor Payload IE
2442 */
2443 static int
2444 dissect_ieee802154_vendor_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint pie_length)
2445 {
2446     tvbuff_t  *next_tvb;
2447     guint32    vendor_oui;
2448
2449     vendor_oui = tvb_get_letoh24(tvb, offset);
2450     proto_item_append_text(tree, ", Vendor OUI: %06X (%s)", vendor_oui,
2451             val_to_str_const(vendor_oui, ieee802154_vendor_oui_names, "unknown"));
2452     proto_tree_add_uint_format_value(tree, hf_ieee802154_payload_ie_vendor_oui, tvb, offset, 3,
2453             vendor_oui, "%06X (%s)", vendor_oui, val_to_str_const(vendor_oui, ieee802154_vendor_oui_names, "unknown"));
2454     offset += 3; /* adjust for vendor OUI */
2455     pie_length -= 3;
2456     next_tvb = tvb_new_subset_length(tvb, offset, pie_length);
2457
2458     switch (vendor_oui) {
2459         case IEEE802154_VENDOR_OUI_ZIGBEE:
2460             call_dissector_with_data(zigbee_ie_handle, next_tvb, pinfo, tree, &pie_length);
2461             break;
2462
2463         default:
2464             call_data_dissector(next_tvb, pinfo, tree);
2465             break;
2466     }
2467
2468     return pie_length + 3;
2469 }
2470
2471 /**
2472  *Subdissector command for Payload IEs (Information Elements)
2473  *
2474  *@param tvb pointer to buffer containing raw packet.
2475  *@param pinfo pointer to packet information fields (unused).
2476  *@param tree pointer to command subtree.
2477  *@param offset offset into the tvbuff to begin dissection.
2478 */
2479 static int
2480 dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
2481 {
2482     proto_tree *subtree;
2483     guint16     payload_ie;
2484     guint16     pie_id;
2485     int         pie_length;
2486     int         orig_offset;
2487
2488     static const int * fields[] = {
2489         &hf_ieee802154_payload_ie_type,
2490         &hf_ieee802154_payload_ie_id,
2491         &hf_ieee802154_payload_ie_length,
2492         NULL
2493     };
2494
2495     orig_offset = offset;
2496     do {
2497         payload_ie    =  tvb_get_letohs(tvb, offset);
2498         pie_id        = (payload_ie & IEEE802154_PAYLOAD_IE_ID_MASK) >> 11;
2499         pie_length    =  payload_ie & IEEE802154_PAYLOAD_IE_LENGTH_MASK;
2500
2501         /* Create a subtree for this command frame. */
2502         subtree = proto_tree_add_subtree(tree, tvb, offset, pie_length + 2, ett_ieee802154_payload, NULL, "Payload IE");
2503         proto_item_append_text(subtree, ", %s, Length: %d", val_to_str_const(pie_id, ieee802154_payload_ie_names, "Unknown IE"), pie_length);
2504         proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_payload_ie,
2505                                ett_ieee802154_payload_ie, fields, ENC_LITTLE_ENDIAN);
2506         offset += 2;
2507
2508         switch (pie_id) {
2509             case IEEE802154_PAYLOAD_IE_MLME:
2510                 while (offset < (orig_offset + pie_length)) {
2511                     offset += dissect_ieee802154_payload_mlme_sub_ie(tvb, pinfo, subtree, offset);
2512                 }
2513                 break;
2514
2515             case IEEE802154_PAYLOAD_IE_VENDOR:
2516                 offset += dissect_ieee802154_vendor_ie(tvb, pinfo, subtree, offset, pie_length);
2517                 break;
2518
2519             case IEEE802154_PAYLOAD_IE_IETF:
2520                 offset += dissect_ieee802154_6top(tvb, pinfo, subtree, offset, pie_length);
2521                 break;
2522
2523             default: /* just use the data dissector */
2524                 if (pie_length > 0) {
2525                     proto_tree_add_item(subtree, hf_ieee802154_payload_ie_data, tvb, offset, pie_length, ENC_NA);
2526                     offset += pie_length;
2527                 }
2528         }
2529     } while ((tvb_reported_length_remaining(tvb, offset) - IEEE802154_FCS_LEN > 1) && (pie_id != IEEE802154_PAYLOAD_IE_GID_TERM));
2530
2531     return (offset - orig_offset);
2532 }
2533
2534 static const true_false_string tfs_cinfo_device_type = { "FFD", "RFD" };
2535 static const true_false_string tfs_cinfo_power_src = { "AC/Mains Power", "Battery" };
2536
2537 /**
2538  *Command subdissector routine for the Association request command.
2539  *
2540  *@param tvb pointer to buffer containing raw packet.
2541  *@param pinfo pointer to packet information fields.
2542  *@param tree pointer to protocol tree.
2543  *@param packet IEEE 802.15.4 packet information.
2544 */
2545
2546 static void
2547 dissect_ieee802154_assoc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
2548 {
2549     guint8 cap;
2550     proto_tree *subtree;
2551     static const int * capability[] = {
2552         &hf_ieee802154_cinfo_alt_coord,
2553         &hf_ieee802154_cinfo_device_type,
2554         &hf_ieee802154_cinfo_power_src,
2555         &hf_ieee802154_cinfo_idle_rx,
2556         &hf_ieee802154_cinfo_sec_capable,
2557         &hf_ieee802154_cinfo_alloc_addr,
2558         NULL
2559     };
2560
2561     cap = tvb_get_guint8(tvb, 0);
2562     col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", (cap & IEEE802154_CMD_CINFO_DEVICE_TYPE) ? tfs_cinfo_device_type.true_string : tfs_cinfo_device_type.false_string);
2563
2564     /* Create a subtree for this command frame. */
2565     subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL,
2566                     val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
2567
2568     /* Get and display capability info. */
2569     proto_tree_add_bitmask_list(subtree, tvb, 0, 1, capability, ENC_NA);
2570
2571     /* Call the data dissector for any leftover bytes. */
2572     if (tvb_reported_length(tvb) > 1) {
2573         call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree);
2574     }
2575 } /* dissect_ieee802154_assoc_req */
2576
2577 /**
2578  *Command subdissector routine for the Association response command.
2579  *
2580  *@param tvb pointer to buffer containing raw packet.
2581  *@param pinfo pointer to packet information fields.
2582  *@param tree pointer to protocol tree.
2583  *@param packet IEEE 802.15.4 packet information.
2584 */
2585 static void
2586 dissect_ieee802154_assoc_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
2587 {
2588     proto_tree *subtree;
2589     proto_item *ti;
2590     guint16     short_addr;
2591     guint8      status;
2592     guint       offset  = 0;
2593
2594     /* Create a subtree for this command frame. */
2595     subtree = proto_tree_add_subtree(tree, tvb, offset, 3, ett_ieee802154_cmd, NULL,
2596                     val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
2597
2598     /* Get and display the short address. */
2599     short_addr = tvb_get_letohs(tvb, offset);
2600     proto_tree_add_uint(subtree, hf_ieee802154_assoc_addr, tvb, offset, 2, short_addr);
2601     offset += 2;
2602
2603     /* Get and display the status. */
2604     status = tvb_get_guint8(tvb, offset);
2605     if (tree) {
2606         ti = proto_tree_add_uint(subtree, hf_ieee802154_assoc_status, tvb, offset, 1, status);
2607         if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) proto_item_append_text(ti, " (Association Successful)");
2608         else if (status == IEEE802154_CMD_ASRSP_PAN_FULL) proto_item_append_text(ti, " (PAN Full)");
2609         else if (status == IEEE802154_CMD_ASRSP_PAN_DENIED) proto_item_append_text(ti, " (Association Denied)");
2610         else proto_item_append_text(ti, " (Reserved)");
2611     }
2612     offset += 1;
2613
2614     /* Update the info column. */
2615     if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) {
2616         /* Association was successful. */
2617         if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) {
2618             col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", packet->dst_pan);
2619         }
2620         if (short_addr != IEEE802154_NO_ADDR16) {
2621             col_append_fstr(pinfo->cinfo, COL_INFO, " Addr: 0x%04x", short_addr);
2622         }
2623     }
2624     else {
2625         /* Association was unsuccessful. */
2626         col_append_str(pinfo->cinfo, COL_INFO, ", Unsuccessful");
2627     }
2628
2629     /* Update the address table. */
2630     if ((status == IEEE802154_CMD_ASRSP_AS_SUCCESS) && (short_addr != IEEE802154_NO_ADDR16)) {
2631         ieee802154_addr_update(&ieee802154_map, short_addr, packet->dst_pan, packet->dst64,
2632                 pinfo->current_proto, pinfo->num);
2633     }
2634
2635     /* Call the data dissector for any leftover bytes. */
2636     if (tvb_captured_length(tvb) > offset) {
2637         call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
2638     }
2639 } /* dissect_ieee802154_assoc_rsp */
2640
2641 /**
2642  * Command subdissector routine for the Disassociate command.
2643  *
2644  *@param tvb pointer to buffer containing raw packet.
2645  *@param pinfo pointer to packet information fields.
2646  *@param tree pointer to protocol tree.
2647  *@param packet IEEE 802.15.4 packet information.
2648 */
2649 static void
2650 dissect_ieee802154_disassoc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
2651 {
2652     proto_tree *subtree;
2653     proto_item *ti;
2654     guint8      reason;
2655
2656     /* Create a subtree for this command frame. */
2657     subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL,
2658                     val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
2659
2660     /* Get and display the disassociation reason. */
2661     reason = tvb_get_guint8(tvb, 0);
2662     if (tree) {
2663         ti = proto_tree_add_uint(subtree, hf_ieee802154_disassoc_reason, tvb, 0, 1, reason);
2664         switch(reason) {
2665             case 0x01:
2666                 proto_item_append_text(ti, " (Coordinator requests device to leave)");
2667                 break;
2668
2669             case 0x02:
2670                 proto_item_append_text(ti, " (Device wishes to leave)");
2671                 break;
2672
2673             default:
2674                 proto_item_append_text(ti, " (Reserved)");
2675                 break;
2676         } /* switch */
2677     }
2678
2679     if (!pinfo->fd->flags.visited) {
2680         /* Update the address tables */
2681         if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT ) {
2682             ieee802154_long_addr_invalidate(packet->dst64, pinfo->num);
2683         } else if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT ) {
2684             ieee802154_short_addr_invalidate(packet->dst16, packet->dst_pan, pinfo->num);
2685         }
2686     }
2687
2688     /* Call the data dissector for any leftover bytes. */
2689     if (tvb_captured_length(tvb) > 1) {
2690         call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree);
2691     }
2692 } /* dissect_ieee802154_disassoc */
2693
2694 /**
2695  * Command subdissector routine for the Coordinator Realignment command.
2696  *
2697  *@param tvb pointer to buffer containing raw packet.
2698  *@param pinfo pointer to packet information fields.
2699  *@param tree pointer to protocol tree.
2700  *@param packet IEEE 802.15.4 packet information.
2701 */
2702 static void
2703 dissect_ieee802154_realign(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
2704 {
2705     proto_tree *subtree;
2706     proto_item *subitem;
2707     guint16     pan_id;
2708     guint16     coord_addr;
2709     guint8      channel;
2710     guint16     short_addr;
2711     guint       offset  = 0;
2712
2713     /* Create a subtree for this command frame. */
2714     subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_ieee802154_cmd, &subitem,
2715                 val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
2716
2717     /* Get and display the command PAN ID. */
2718     pan_id = tvb_get_letohs(tvb, offset);
2719     proto_tree_add_uint(subtree, hf_ieee802154_realign_pan, tvb, offset, 2, pan_id);
2720     col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", pan_id);
2721     offset += 2;
2722
2723     /* Get and display the coordinator address. */
2724     coord_addr = tvb_get_letohs(tvb, offset);
2725     proto_tree_add_uint(subtree, hf_ieee802154_realign_caddr, tvb, offset, 2, coord_addr);
2726     col_append_fstr(pinfo->cinfo, COL_INFO, ", Coordinator: 0x%04x", coord_addr);
2727     offset += 2;
2728
2729     /* Get and display the channel. */
2730     channel = tvb_get_guint8(tvb, offset);
2731     proto_tree_add_uint(subtree, hf_ieee802154_realign_channel, tvb, offset, 1, channel);
2732     col_append_fstr(pinfo->cinfo, COL_INFO, ", Channel: %u", channel);
2733     offset += 1;
2734
2735     /* Get and display the short address. */
2736     short_addr = tvb_get_letohs(tvb, offset);
2737     if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_addr, tvb, offset, 2, short_addr);
2738     if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)
2739         && (short_addr != IEEE802154_NO_ADDR16)) {
2740         col_append_fstr(pinfo->cinfo, COL_INFO, ", Addr: 0x%04x", short_addr);
2741     }
2742     offset += 2;
2743     /* Update the address table. */
2744     if ((short_addr != IEEE802154_NO_ADDR16) && (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) {
2745         ieee802154_addr_update(&ieee802154_map, short_addr, packet->dst_pan, packet->dst64,
2746                 pinfo->current_proto, pinfo->num);
2747     }
2748
2749     /* Get and display the channel page, if it exists. Added in IEEE802.15.4-2006 */
2750     if (tvb_bytes_exist(tvb, offset, 1)) {
2751         guint8  channel_page = tvb_get_guint8(tvb, offset);
2752         if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_channel_page, tvb, offset, 1, channel_page);
2753         offset += 1;
2754     }
2755
2756     /* Fix the length of the command subtree. */
2757     if (tree) {
2758         proto_item_set_len(subitem, offset);
2759     }
2760
2761     /* Call the data dissector for any leftover bytes. */
2762     if (tvb_captured_length(tvb) > offset) {
2763         call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
2764     }
2765 } /* dissect_ieee802154_realign */
2766
2767 static const true_false_string tfs_gtsreq_dir = { "Receive", "Transmit" };
2768 static const true_false_string tfs_gtsreq_type= { "Allocate GTS", "Deallocate GTS" };
2769
2770 /**
2771  *Command subdissector routine for the GTS request command.
2772  *
2773  *Assumes that COL_INFO will be set to the command name,
2774  *command name will already be appended to the command subtree
2775  *and protocol root. In addition, assumes that the command ID
2776  *has already been parsed.
2777  *
2778  *@param tvb pointer to buffer containing raw packet.
2779  *@param pinfo pointer to packet information fields (unused).
2780  *@param tree pointer to protocol tree.
2781  *@param packet IEEE 802.15.4 packet information (unused).
2782 */
2783
2784 static void
2785 dissect_ieee802154_gtsreq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
2786 {
2787     proto_tree *subtree;
2788     static const int * characteristics[] = {
2789         &hf_ieee802154_gtsreq_len,
2790         &hf_ieee802154_gtsreq_dir,
2791         &hf_ieee802154_gtsreq_type,
2792         NULL
2793     };
2794
2795     /* Create a subtree for this command frame. */
2796     subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL,
2797                 val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
2798
2799     proto_tree_add_bitmask_list(subtree, tvb, 0, 1, characteristics, ENC_NA);
2800
2801     /* Call the data dissector for any leftover bytes. */
2802     if (tvb_reported_length(tvb) > 1) {
2803         call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree);
2804     }
2805 } /* dissect_ieee802154_gtsreq */
2806
2807 /**
2808  * Subdissector routine all commands.
2809  *
2810  *@param tvb pointer to buffer containing raw packet.
2811  *@param pinfo pointer to packet information fields (unused).
2812  *@param tree pointer to protocol tree.
2813  *@param packet IEEE 802.15.4 packet information (unused).
2814 */
2815 static void
2816 dissect_ieee802154_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
2817 {
2818     switch (packet->command_id) {
2819     case IEEE802154_CMD_ASSOC_REQ:
2820         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2821             (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
2822             (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE));
2823         dissect_ieee802154_assoc_req(tvb, pinfo, tree, packet);
2824         break;
2825
2826     case IEEE802154_CMD_ASSOC_RSP:
2827         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2828             (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
2829             (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
2830         dissect_ieee802154_assoc_rsp(tvb, pinfo, tree, packet);
2831         break;
2832
2833       case IEEE802154_CMD_DISASSOC_NOTIFY:
2834         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2835             (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
2836             (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
2837         dissect_ieee802154_disassoc(tvb, pinfo, tree, packet);
2838         return;
2839
2840       case IEEE802154_CMD_DATA_RQ:
2841         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE);
2842         /* No payload expected. */
2843         break;
2844
2845       case IEEE802154_CMD_PANID_CONFLICT:
2846         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2847             (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
2848             (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
2849         /* No payload expected. */
2850         break;
2851
2852       case IEEE802154_CMD_ORPHAN_NOTIFY:
2853         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2854             (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
2855             (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
2856             (packet->dst16 == IEEE802154_BCAST_ADDR) &&
2857             (packet->src_pan == IEEE802154_BCAST_PAN) &&
2858             (packet->dst_pan == IEEE802154_BCAST_PAN));
2859         /* No payload expected. */
2860         break;
2861
2862       case IEEE802154_CMD_BEACON_REQ:
2863             if ((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006)) {
2864                 IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2865                         (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
2866                         (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) &&
2867                         (packet->dst16 == IEEE802154_BCAST_ADDR) &&
2868                         (packet->dst_pan == IEEE802154_BCAST_PAN));
2869             }
2870         /* No payload expected. */
2871         break;
2872
2873       case IEEE802154_CMD_COORD_REALIGN:
2874         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2875             (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
2876             (packet->dst_pan == IEEE802154_BCAST_PAN) &&
2877             (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE));
2878         if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
2879             /* If directed to a 16-bit address, check that it is being broadcast. */
2880             IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, packet->dst16 == IEEE802154_BCAST_ADDR);
2881         }
2882         dissect_ieee802154_realign(tvb, pinfo, tree, packet);
2883         return;
2884
2885       case IEEE802154_CMD_GTS_REQ:
2886         /* Check that the addressing is correct for this command type. */
2887         IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
2888             (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
2889             (packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&
2890             (packet->src16 != IEEE802154_BCAST_ADDR) &&
2891             (packet->src16 != IEEE802154_NO_ADDR16));
2892         dissect_ieee802154_gtsreq(tvb, pinfo, tree, packet);
2893         return;
2894
2895       case IEEE802154_CMD_TRLE_MGMT_REQ:
2896       case IEEE802154_CMD_TRLE_MGMT_RSP:
2897       case IEEE802154_CMD_DSME_ASSOC_REQ:
2898       case IEEE802154_CMD_DSME_ASSOC_RSP:
2899       case IEEE802154_CMD_DSME_GTS_REQ:
2900       case IEEE802154_CMD_DSME_GTS_RSP:
2901       case IEEE802154_CMD_DSME_GTS_NOTIFY:
2902       case IEEE802154_CMD_DSME_INFO_REQ:
2903       case IEEE802154_CMD_DSME_INFO_RSP:
2904       case IEEE802154_CMD_DSME_BEACON_ALLOC_NOTIFY:
2905       case IEEE802154_CMD_DSME_BEACON_COLL_NOTIFY:
2906       case IEEE802154_CMD_DSME_LINK_REPORT:
2907       case IEEE802154_CMD_RIT_DATA_REQ:
2908       case IEEE802154_CMD_DBS_REQ:
2909       case IEEE802154_CMD_DBS_RSP:
2910             /* TODO add support for these commands, for now
2911              * if anything remains other than the FCS, dump it */
2912             if (tvb_captured_length_remaining(tvb, 0) > 2) {
2913                 call_data_dissector(tvb, pinfo, tree);
2914             }
2915           return;
2916
2917     } /* switch */
2918 } /* dissect_ieee802154_command */
2919
2920 /**
2921  *IEEE 802.15.4 decryption algorithm. Tries to find the
2922  *appropriate key from the information in the IEEE 802.15.4
2923  *packet structure and dissector config.
2924  *
2925  *This function implements the security proceedures for the
2926  *2006 version of the spec only. IEEE 802.15.4-2003 is
2927  *unsupported.
2928  *@param tvb IEEE 802.15.4 packet.
2929  *@param pinfo Packet info structure.
2930  *@param offset Offset where the ciphertext 'c' starts.
2931  *@param packet IEEE 802.15.4 packet information.
2932  *@param status status of decryption returned through here on failure.
2933  *@return decrypted payload.
2934 */
2935 static tvbuff_t *
2936 dissect_ieee802154_decrypt(tvbuff_t *tvb, guint offset, packet_info *pinfo, ieee802154_packet *packet, ws_decrypt_status *status)
2937 {
2938     tvbuff_t           *ptext_tvb;
2939     gboolean            have_mic = FALSE;
2940     guint64             srcAddr;
2941     unsigned char       key[16];
2942     unsigned char       tmp[16];
2943     unsigned char       rx_mic[16];
2944     guint               M;
2945     gint                captured_len;
2946     gint                reported_len;
2947     ieee802154_hints_t *ieee_hints;
2948
2949     /*
2950      * Check the version; we only support IEEE 802.15.4-2003 and IEEE 802.15.4-2006.
2951      * We must do this first, as, if this isn't IEEE 802.15.4-2003 or IEEE 802.15.4-2006,
2952      * we don't have the Auxiliary Security Header, and haven't
2953      * filled in the information for it, and none of the stuff
2954      * we do afterwards, which uses that information, is doable.
2955      */
2956     if ((packet->version != IEEE802154_VERSION_2006) && (packet->version != IEEE802154_VERSION_2003)) {
2957         *status = DECRYPT_VERSION_UNSUPPORTED;
2958         return NULL;
2959     }
2960
2961     ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0);
2962
2963     /* Get the captured and on-the-wire length of the payload. */
2964     M = IEEE802154_MIC_LENGTH(packet->security_level);
2965     reported_len = tvb_reported_length_remaining(tvb, offset) - IEEE802154_FCS_LEN - M;
2966     if (reported_len < 0) {
2967         *status = DECRYPT_PACKET_TOO_SMALL;
2968         return NULL;
2969     }
2970     /* Check of the payload is truncated.  */
2971     if (tvb_bytes_exist(tvb, offset, reported_len)) {
2972         captured_len = reported_len;
2973     }
2974     else {
2975         captured_len = tvb_captured_length_remaining(tvb, offset);
2976     }
2977
2978     /* Check if the MIC is present in the captured data. */
2979     have_mic = tvb_bytes_exist(tvb, offset + reported_len, M);
2980     if (have_mic) {
2981         tvb_memcpy(tvb, rx_mic, offset + reported_len, M);
2982     }
2983
2984     /*
2985      * Key Lookup - Need to find the appropriate key.
2986      *
2987      */
2988     /*
2989      * Oh God! The specification is so bad. This is the worst
2990      * case of design-by-committee I've ever seen in my life.
2991      * The IEEE has created an unintelligible mess in order
2992      * to decipher which key is used for which message.
2993      *
2994      * Let's hope it's simpler to implement for dissecting only.
2995      *
2996      * Also need to find the extended address of the sender.
2997      */
2998     if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
2999         /* The source EUI-64 is included in the headers. */
3000         srcAddr = packet->src64;
3001     }
3002     else if (ieee_hints && ieee_hints->map_rec && ieee_hints->map_rec->addr64) {
3003         /* Use the hint */
3004         srcAddr = ieee_hints->map_rec->addr64;
3005     }
3006     else {
3007         /* Lookup failed.  */
3008         *status = DECRYPT_PACKET_NO_EXT_SRC_ADDR;
3009         return NULL;
3010     }
3011
3012     /* Lookup the key. */
3013     /*
3014      * TODO: What this dissector really needs is a UAT to store multiple keys
3015      * and a variety of key configuration data. However, a single shared key
3016      * should be sufficient to get packet encryption off to a start.
3017      */
3018     if (!ieee802154_key_valid) {
3019         *status = DECRYPT_PACKET_NO_KEY;
3020         return NULL;
3021     }
3022     memcpy(key, ieee802154_key, IEEE802154_CIPHER_SIZE);
3023
3024     /*
3025      * CCM* - CTR mode payload encryption
3026      *
3027      */
3028     /* Create the CCM* initial block for decryption (Adata=0, M=0, counter=0). */
3029     ccm_init_block(tmp, FALSE, 0, srcAddr, packet, 0);
3030
3031     /* Decrypt the ciphertext, and place the plaintext in a new tvb. */
3032     if (IEEE802154_IS_ENCRYPTED(packet->security_level) && captured_len) {
3033         guint8 *text;
3034         /*
3035          * Make a copy of the ciphertext in heap memory.
3036          *
3037          * We will decrypt the message in-place and then use the buffer as the
3038          * real data for the new tvb.
3039          */
3040         text = (guint8 *)tvb_memdup(pinfo->pool, tvb, offset, captured_len);
3041
3042         /* Perform CTR-mode transformation. */
3043         if (!ccm_ctr_encrypt(key, tmp, rx_mic, text, captured_len)) {
3044             g_free(text);
3045             *status = DECRYPT_PACKET_DECRYPT_FAILED;
3046             return NULL;
3047         }
3048
3049         /* Create a tvbuff for the plaintext. */
3050         ptext_tvb = tvb_new_child_real_data(tvb, text, captured_len, reported_len);
3051         add_new_data_source(pinfo, ptext_tvb, "Decrypted IEEE 802.15.4 payload");
3052         *status = DECRYPT_PACKET_SUCCEEDED;
3053     }
3054     /* There is no ciphertext. Wrap the plaintext in a new tvb. */
3055     else {
3056         /* Decrypt the MIC (if present). */
3057         if ((have_mic) && (!ccm_ctr_encrypt(key, tmp, rx_mic, NULL, 0))) {
3058             *status = DECRYPT_PACKET_DECRYPT_FAILED;
3059             return NULL;
3060         }
3061
3062         /* Create a tvbuff for the plaintext. This might result in a zero-length tvbuff. */
3063         ptext_tvb = tvb_new_subset_length_caplen(tvb, offset, captured_len, reported_len);
3064         *status = DECRYPT_PACKET_SUCCEEDED;
3065     }
3066
3067     /*
3068      * CCM* - CBC-mode message authentication
3069      *
3070      */
3071     /* We can only verify the message if the MIC wasn't truncated. */
3072     if (have_mic) {
3073         unsigned char           dec_mic[16];
3074         guint                   l_m = captured_len;
3075         guint                   l_a = offset;
3076
3077         /* Adjust the lengths of the plaintext and additional data if unencrypted. */
3078         if (!IEEE802154_IS_ENCRYPTED(packet->security_level)) {
3079             l_a += l_m;
3080             l_m = 0;
3081         }
3082         else if ((packet->version == IEEE802154_VERSION_2003) && !ieee802154_extend_auth)
3083             l_a -= 5;   /* Exclude Frame Counter (4 bytes) and Key Sequence Counter (1 byte) from authentication data */
3084
3085
3086         /* Create the CCM* initial block for authentication (Adata!=0, M!=0, counter=l(m)). */
3087         ccm_init_block(tmp, TRUE, M, srcAddr, packet, l_m);
3088
3089         /* Compute CBC-MAC authentication tag. */
3090         /*
3091          * And yes, despite the warning in tvbuff.h, I think tvb_get_ptr is the
3092          * right function here since either A) the payload wasn't encrypted, in
3093          * which case l_m is zero, or B) the payload was encrypted, and the tvb
3094          * already points to contiguous memory, since we just allocated it in
3095          * decryption phase.
3096          */
3097         if (!ccm_cbc_mac(key, tmp, (const gchar *)tvb_memdup(wmem_packet_scope(), tvb, 0, l_a), l_a, tvb_get_ptr(ptext_tvb, 0, l_m), l_m, dec_mic)) {
3098             *status = DECRYPT_PACKET_MIC_CHECK_FAILED;
3099         }
3100         /* Compare the received MIC with the one we generated. */
3101         else if (memcmp(rx_mic, dec_mic, M) != 0) {
3102             *status = DECRYPT_PACKET_MIC_CHECK_FAILED;
3103         }
3104     }
3105
3106     /* Done! */
3107     return ptext_tvb;
3108 } /* dissect_ieee802154_decrypt */
3109
3110 /**
3111  *Creates the CCM* initial block value for IEEE 802.15.4.
3112  *
3113  *@param block Output pointer for the initial block.
3114  *@param adata TRUE if additional auth data is present
3115  *@param M CCM* parameter M.
3116  *@param addr Source extended address.
3117  *@param packet IEEE 802.15.4 packet information.
3118  *@param ctr_val Value in the last L bytes of the block.
3119 */
3120 static void
3121 ccm_init_block(gchar *block, gboolean adata, gint M, guint64 addr, ieee802154_packet *packet, gint ctr_val)
3122 {
3123     gint                i = 0;
3124
3125     /* Flags: Reserved(0) || Adata || (M-2)/2 || (L-1) */
3126     block[i] = (0x2 - 1); /* (L-1) */
3127     if (M > 0) block[i] |= (((M-2)/2) << 3); /* (M-2)/2 */
3128     if (adata) block[i] |= (1 << 6); /* Adata */
3129     i++;
3130     /* 2003 CCM Nonce:  Source Address || Frame Counter || Key Sequence Counter */
3131     /* 2006 CCM* Nonce: Source Address || Frame Counter || Security Level */
3132     block[i++] = (guint8)((addr >> 56) & 0xff);
3133     block[i++] = (guint8)((addr >> 48) & 0xff);
3134     block[i++] = (guint8)((addr >> 40) & 0xff);
3135     block[i++] = (guint8)((addr >> 32) & 0xff);
3136     block[i++] = (guint8)((addr >> 24) & 0xff);
3137     block[i++] = (guint8)((addr >> 16) & 0xff);
3138     block[i++] = (guint8)((addr >> 8) & 0xff);
3139     block[i++] = (guint8)((addr >> 0) & 0xff);
3140     block[i++] = (guint8)((packet->frame_counter >> 24) & 0xff);
3141     block[i++] = (guint8)((packet->frame_counter >> 16) & 0xff);
3142     block[i++] = (guint8)((packet->frame_counter >> 8) & 0xff);
3143     block[i++] = (guint8)((packet->frame_counter >> 0) & 0xff);
3144     if (packet->version == IEEE802154_VERSION_2003)
3145         block[i++] = packet->key_sequence_counter;
3146     else
3147         block[i++] = packet->security_level;
3148     /* Plaintext length. */
3149     block[i++] = (guint8)((ctr_val >> 8) & 0xff);
3150     block[i] = (guint8)((ctr_val >> 0) & 0xff);
3151 } /* ccm_init_block */
3152
3153 /*
3154  * Perform an in-place CTR-mode encryption/decryption.
3155  *
3156  *@param key Encryption Key.
3157  *@param iv Counter initial value.
3158  *@param mic MIC to encrypt/decrypt.
3159  *@param data Buffer to encrypt/decrypt.
3160  *@param length Length of the buffer.
3161  *@return TRUE on SUCCESS, FALSE on error.
3162 */
3163 #ifdef HAVE_LIBGCRYPT
3164 static gboolean
3165 ccm_ctr_encrypt(const gchar *key, const gchar *iv, gchar *mic, gchar *data, gint length)
3166 {
3167     gcry_cipher_hd_t    cipher_hd;
3168
3169     /* Open the cipher. */
3170     if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0)) {
3171         return FALSE;
3172     }
3173
3174     /* Set the key and initial value. */
3175     if (gcry_cipher_setkey(cipher_hd, key, 16)) {
3176         gcry_cipher_close(cipher_hd);
3177         return FALSE;
3178     }
3179     if (gcry_cipher_setctr(cipher_hd, iv, 16)) {
3180         gcry_cipher_close(cipher_hd);
3181         return FALSE;
3182     }
3183
3184     /* Decrypt the MIC. */
3185     if (gcry_cipher_encrypt(cipher_hd, mic, 16, NULL, 0)) {
3186         gcry_cipher_close(cipher_hd);
3187         return FALSE;
3188     }
3189     /* Decrypt the payload. */
3190     if (gcry_cipher_encrypt(cipher_hd, data, length, NULL, 0)) {
3191         gcry_cipher_close(cipher_hd);
3192         return FALSE;
3193     }
3194
3195     /* Done with the cipher. */
3196     gcry_cipher_close(cipher_hd);
3197     return TRUE;
3198 } /* ccm_ctr_encrypt */
3199 #else
3200 static gboolean
3201 ccm_ctr_encrypt(const gchar *key _U_, const gchar *iv _U_, gchar *mic _U_, gchar *data _U_, gint length _U_)
3202 {
3203     return FALSE;
3204 }
3205 #endif /* HAVE_LIBGCRYPT */
3206
3207 /**
3208  *Generate a CBC-MAC of the decrypted payload and additional authentication headers.
3209  *@param key Encryption Key.
3210  *@param iv Counter initial value.
3211  *@param a Additional auth headers.
3212  *@param a_len Length of the additional headers.
3213  *@param m Plaintext message.
3214  *@param m_len Length of plaintext message.
3215  *@param mic Output for CBC-MAC.
3216  *@return  TRUE on SUCCESS, FALSE on error.
3217 */
3218 #ifdef HAVE_LIBGCRYPT
3219 static gboolean
3220 ccm_cbc_mac(const gchar *key, const gchar *iv, const gchar *a, gint a_len, const gchar *m, gint m_len, gchar *mic)
3221 {
3222     gcry_cipher_hd_t cipher_hd;
3223     guint            i = 0;
3224     unsigned char    block[16];
3225
3226     /* Open the cipher. */
3227     if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC)) return FALSE;
3228
3229     /* Set the key. */
3230     if (gcry_cipher_setkey(cipher_hd, key, 16)) {
3231         gcry_cipher_close(cipher_hd);
3232         return FALSE;
3233     }
3234
3235     /* Process the initial value. */
3236     if (gcry_cipher_encrypt(cipher_hd, mic, 16, iv, 16)) {
3237         gcry_cipher_close(cipher_hd);
3238         return FALSE;
3239     }
3240
3241     /* Encode L(a) */
3242     i = 0;
3243
3244 /* XXX: GINT_MAX is not defined so #if ... will always be false */
3245 #if (GINT_MAX >= (1LL << 32))
3246     if (a_len >= (1LL << 32)) {
3247         block[i++] = 0xff;
3248         block[i++] = 0xff;
3249         block[i++] = (a_len >> 56) & 0xff;
3250         block[i++] = (a_len >> 48) & 0xff;
3251         block[i++] = (a_len >> 40) & 0xff;
3252         block[i++] = (a_len >> 32) & 0xff;
3253         block[i++] = (a_len >> 24) & 0xff;
3254         block[i++] = (a_len >> 16) & 0xff;
3255         block[i++] = (a_len >> 8) & 0xff;
3256         block[i++] = (a_len >> 0) & 0xff;
3257     }
3258     else
3259 #endif
3260     if (a_len >= ((1 << 16) - (1 << 8))) {
3261         block[i++] = 0xff;
3262         block[i++] = 0xfe;
3263         block[i++] = (a_len >> 24) & 0xff;
3264         block[i++] = (a_len >> 16) & 0xff;
3265         block[i++] = (a_len >> 8) & 0xff;
3266         block[i++] = (a_len >> 0) & 0xff;
3267     }
3268     else {
3269         block[i++] = (a_len >> 8) & 0xff;
3270         block[i++] = (a_len >> 0) & 0xff;
3271     }
3272     /* Append a to get the first block of input (pad if we encounter the end of a). */
3273     while ((i < sizeof(block)) && (a_len-- > 0)) block[i++] = *a++;
3274     while (i < sizeof(block)) block[i++] = 0;
3275
3276     /* Process the first block of AuthData. */
3277     if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, 16)) {
3278         gcry_cipher_close(cipher_hd);
3279         return FALSE;
3280     }
3281
3282     /* Transform and process the remainder of a. */
3283     while (a_len > 0) {
3284         /* Copy and pad. */
3285         if ((guint)a_len >= sizeof(block)) memcpy(block, a, sizeof(block));
3286         else {memcpy(block, a, a_len); memset(block+a_len, 0, sizeof(block)-a_len);}
3287         /* Adjust pointers. */
3288         a += sizeof(block);
3289         a_len -= (int)sizeof(block);
3290         /* Execute the CBC-MAC algorithm. */
3291         if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, sizeof(block))) {
3292             gcry_cipher_close(cipher_hd);
3293             return FALSE;
3294         }
3295     } /* while */
3296
3297     /* Process the message, m. */
3298     while (m_len > 0) {
3299         /* Copy and pad. */
3300         if ((guint)m_len >= sizeof(block)) memcpy(block, m, sizeof(block));
3301         else {memcpy(block, m, m_len); memset(block+m_len, 0, sizeof(block)-m_len);}
3302         /* Adjust pointers. */
3303         m += sizeof(block);
3304         m_len -= (int)sizeof(block);
3305         /* Execute the CBC-MAC algorithm. */
3306         if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, sizeof(block))) {
3307             gcry_cipher_close(cipher_hd);
3308             return FALSE;
3309         }
3310     }
3311
3312     /* Done with the cipher. */
3313     gcry_cipher_close(cipher_hd);
3314     return TRUE;
3315 } /* ccm_cbc_mac */
3316 #else
3317 static gboolean
3318 ccm_cbc_mac(const gchar *key _U_, const gchar *iv _U_,
3319         const gchar *a _U_, gint a_len _U_, const gchar *m _U_, gint m_len _U_, gchar *mic _U_)
3320 {
3321     return FALSE;
3322 }
3323 #endif /* HAVE_LIBGCRYPT */
3324
3325 /* Key hash function. */
3326 guint ieee802154_short_addr_hash(gconstpointer key)
3327 {
3328     return (((const ieee802154_short_addr *)key)->addr) | (((const ieee802154_short_addr *)key)->pan << 16);
3329 }
3330
3331 /* Key equal function. */
3332 gboolean ieee802154_short_addr_equal(gconstpointer a, gconstpointer b)
3333 {
3334     return (((const ieee802154_short_addr *)a)->pan == ((const ieee802154_short_addr *)b)->pan) &&
3335            (((const ieee802154_short_addr *)a)->addr == ((const ieee802154_short_addr *)b)->addr);
3336 }
3337
3338 /* Key hash function. */
3339 guint ieee802154_long_addr_hash(gconstpointer key)
3340 {
3341     return (guint)(((const ieee802154_long_addr *)key)->addr) & 0xFFFFFFFF;
3342 }
3343
3344 /* Key equal function. */
3345 gboolean ieee802154_long_addr_equal(gconstpointer a, gconstpointer b)
3346 {
3347     return (((const ieee802154_long_addr *)a)->addr == ((const ieee802154_long_addr *)b)->addr);
3348 }
3349
3350 /**
3351  *Creates a record that maps the given short address and pan to a long (extended) address.
3352  *@param short_addr 16-bit short address
3353  *@param pan 16-bit PAN id
3354  *@param long_addr 64-bit long (extended) address
3355  *@param proto pointer to name of current protocol
3356  *@param fnum Frame number this mapping became valid
3357  *@return TRUE Record was updated, FALSE Couldn't find it
3358 */
3359 ieee802154_map_rec *ieee802154_addr_update(ieee802154_map_tab_t *au_ieee802154_map,
3360         guint16 short_addr, guint16 pan, guint64 long_addr, const char *proto, guint fnum)
3361 {
3362     ieee802154_short_addr  addr16;
3363     ieee802154_map_rec    *p_map_rec;
3364     gpointer               old_key;
3365
3366     /* Look up short address hash */
3367     addr16.pan = pan;
3368     addr16.addr = short_addr;
3369     p_map_rec = (ieee802154_map_rec *)g_hash_table_lookup(au_ieee802154_map->short_table, &addr16);
3370
3371     /* Update mapping record */
3372     if (p_map_rec) {
3373         /* record already exists */
3374         if ( p_map_rec->addr64 == long_addr ) {
3375             /* no change */
3376             return p_map_rec;
3377         }
3378         else {
3379             /* mark current mapping record invalid */
3380             p_map_rec->end_fnum = fnum;
3381         }
3382     }
3383
3384     /* create a new mapping record */
3385     p_map_rec = wmem_new(wmem_file_scope(), ieee802154_map_rec);
3386     p_map_rec->proto = proto;
3387     p_map_rec->start_fnum = fnum;
3388     p_map_rec->end_fnum = 0;
3389     p_map_rec->addr64 = long_addr;
3390
3391     /* link new mapping record to addr hash tables */
3392     if ( g_hash_table_lookup_extended(au_ieee802154_map->short_table, &addr16, &old_key, NULL) ) {
3393         /* update short addr hash table, reusing pointer to old key */
3394         g_hash_table_insert(au_ieee802154_map->short_table, old_key, p_map_rec);
3395     } else {
3396         /* create new hash entry */
3397         g_hash_table_insert(au_ieee802154_map->short_table, wmem_memdup(wmem_file_scope(), &addr16, sizeof(addr16)), p_map_rec);
3398     }
3399
3400     if ( g_hash_table_lookup_extended(au_ieee802154_map->long_table, &long_addr, &old_key, NULL) ) {
3401         /* update long addr hash table, reusing pointer to old key */
3402         g_hash_table_insert(au_ieee802154_map->long_table, old_key, p_map_rec);
3403     } else {
3404         /* create new hash entry */
3405         g_hash_table_insert(au_ieee802154_map->long_table, wmem_memdup(wmem_file_scope(), &long_addr, sizeof(long_addr)), p_map_rec);
3406     }
3407
3408     return p_map_rec;
3409 } /* ieee802154_addr_update */
3410
3411 /**
3412  *Marks a mapping record associated with device with short_addr
3413  *as invalid at a certain frame number, typically when a
3414  *disassociation occurs.
3415  *
3416  *@param short_addr 16-bit short address
3417  *@param pan 16-bit PAN id
3418  *@param fnum Frame number when mapping became invalid
3419  *@return TRUE Record was updated, FALSE Couldn't find it
3420 */
3421 gboolean ieee802154_short_addr_invalidate(guint16 short_addr, guint16 pan, guint fnum)
3422 {
3423     ieee802154_short_addr  addr16;
3424     ieee802154_map_rec    *map_rec;
3425
3426     addr16.pan = pan;
3427     addr16.addr = short_addr;
3428
3429     map_rec = (ieee802154_map_rec *)g_hash_table_lookup(ieee802154_map.short_table, &addr16);
3430     if ( map_rec ) {
3431         /* indicates this mapping is invalid at frame fnum */
3432         map_rec->end_fnum = fnum;
3433         return TRUE;
3434     }
3435
3436     return FALSE;
3437 } /* ieee802154_short_addr_invalidate */
3438
3439 /**
3440  * Mark a mapping record associated with device with long_addr
3441  * as invalid at a certain frame number, typically when a
3442  * disassociation occurs.
3443  *
3444  *@param long_addr 16-bit short address
3445  *@param fnum Frame number when mapping became invalid
3446  *@return TRUE If record was updated, FALSE otherwise
3447 */
3448 gboolean ieee802154_long_addr_invalidate(guint64 long_addr, guint fnum)
3449 {
3450     ieee802154_map_rec   *map_rec;
3451
3452     map_rec = (ieee802154_map_rec *)g_hash_table_lookup(ieee802154_map.long_table, &long_addr);
3453     if ( map_rec ) {
3454         /* indicates this mapping is invalid at frame fnum */
3455         map_rec->end_fnum = fnum;
3456         return TRUE;
3457     }
3458
3459     return FALSE;
3460 } /* ieee802154_long_addr_invalidate */
3461
3462 /**
3463  * Init routine for the IEEE 802.15.4 dissector. Creates hash
3464  * tables for mapping between 16-bit to 64-bit addresses and
3465  * populates them with static address pairs from a UAT
3466  * preference table.
3467 */
3468 static void
3469 proto_init_ieee802154(void)
3470 {
3471     guint       i;
3472
3473     ieee802154_map.short_table = g_hash_table_new(ieee802154_short_addr_hash, ieee802154_short_addr_equal);
3474     ieee802154_map.long_table = g_hash_table_new(ieee802154_long_addr_hash, ieee802154_long_addr_equal);
3475     /* Reload the hash table from the static address UAT. */
3476     for (i=0; (i<num_static_addrs) && (static_addrs); i++) {
3477         ieee802154_addr_update(&ieee802154_map,(guint16)static_addrs[i].addr16, (guint16)static_addrs[i].pan,
3478                pntoh64(static_addrs[i].eui64), ieee802154_user, IEEE802154_USER_MAPPING);
3479     } /* for */
3480 } /* proto_init_ieee802154 */
3481
3482 /**
3483  * Cleanup for the IEEE 802.15.4 dissector.
3484 */
3485 static void
3486 proto_cleanup_ieee802154(void)
3487 {
3488     g_hash_table_destroy(ieee802154_map.short_table);
3489     g_hash_table_destroy(ieee802154_map.long_table);
3490 }
3491
3492 /* Returns the prompt string for the Decode-As dialog. */
3493 static void ieee802154_da_prompt(packet_info *pinfo _U_, gchar* result)
3494 {
3495     ieee802154_hints_t *hints;
3496     hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
3497                 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
3498     if (hints)
3499         g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IEEE 802.15.4 PAN 0x%04x as", hints->src_pan);
3500     else
3501         g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IEEE 802.15.4 PAN Unknown");
3502 } /* iee802154_da_prompt */
3503
3504 /* Returns the value to index the panid decode table with (source PAN)*/
3505 static gpointer ieee802154_da_value(packet_info *pinfo _U_)
3506 {
3507     ieee802154_hints_t *hints;
3508     hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
3509                 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
3510     if (hints)
3511         return GUINT_TO_POINTER((guint)(hints->src_pan));
3512     else
3513         return NULL;
3514 } /* iee802154_da_value */
3515
3516 /**
3517  * IEEE 802.15.4 protocol registration routine.
3518 */
3519 void proto_register_ieee802154(void)
3520 {
3521     /* Protocol fields  */
3522     static hf_register_info hf_phy[] = {
3523         /* PHY level */
3524
3525         { &hf_ieee802154_nonask_phy_preamble,
3526         { "Preamble",                       "wpan-nonask-phy.preamble", FT_UINT32, BASE_HEX, NULL, 0x0,
3527             NULL, HFILL }},
3528
3529         { &hf_ieee802154_nonask_phy_sfd,
3530         { "Start of Frame Delimiter",       "wpan-nonask-phy.sfd", FT_UINT8, BASE_HEX, NULL, 0x0,
3531             NULL, HFILL }},
3532
3533         { &hf_ieee802154_nonask_phy_length,
3534         { "Frame Length",                   "wpan-nonask-phy.frame_length", FT_UINT8, BASE_HEX, NULL,
3535             IEEE802154_PHY_LENGTH_MASK, NULL, HFILL }},
3536
3537         { &hf_ieee802154_nonask_phr,
3538         { "PHR",                   "wpan-nonask-phy.phr", FT_UINT8, BASE_HEX, NULL,
3539             0x0, NULL, HFILL }},
3540     };
3541
3542     static hf_register_info hf[] = {
3543
3544         { &hf_ieee802154_frame_length,
3545         { "Frame Length",                   "wpan.frame_length", FT_UINT8, BASE_DEC, NULL, 0x0,
3546             "Frame Length as reported from lower layer", HFILL }},
3547
3548         { &hf_ieee802154_fcf,
3549         { "Frame Control Field",            "wpan.fcf", FT_UINT16, BASE_HEX, NULL,
3550             0x0, NULL, HFILL }},
3551
3552         { &hf_ieee802154_frame_type,
3553         { "Frame Type",                     "wpan.frame_type", FT_UINT16, BASE_HEX, VALS(ieee802154_frame_types),
3554             IEEE802154_FCF_TYPE_MASK, NULL, HFILL }},
3555
3556         { &hf_ieee802154_security,
3557         { "Security Enabled",               "wpan.security", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_SEC_EN,
3558             "Whether security operations are performed at the MAC layer or not.", HFILL }},
3559
3560         { &hf_ieee802154_pending,
3561         { "Frame Pending",                  "wpan.pending", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_FRAME_PND,
3562             "Indication of additional packets waiting to be transferred from the source device.", HFILL }},
3563
3564         { &hf_ieee802154_ack_request,
3565         { "Acknowledge Request",            "wpan.ack_request", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_ACK_REQ,
3566             "Whether the sender of this packet requests acknowledgment or not.", HFILL }},
3567
3568         { &hf_ieee802154_pan_id_compression,
3569         { "PAN ID Compression",             "wpan.pan_id_compression", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_PAN_ID_COMPRESSION,
3570             "Whether this packet contains the PAN ID or not.", HFILL }},
3571
3572         { &hf_ieee802154_seqno_suppression,
3573         { "Sequence Number Suppression",    "wpan.seqno_suppression", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_SEQNO_SUPPRESSION,
3574             "Whether this packet contains the Sequence Number or not.", HFILL }},
3575
3576         { &hf_ieee802154_ie_present,
3577         { "Information Elements Present",   "wpan.ie_present", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_IE_PRESENT,
3578             "Whether this packet contains the Information Elements or not.", HFILL }},
3579
3580         { &hf_ieee802154_seqno,
3581         { "Sequence Number",                "wpan.seq_no", FT_UINT8, BASE_DEC, NULL, 0x0,
3582             NULL, HFILL }},
3583
3584         { &hf_ieee802154_dst_addr_mode,
3585         { "Destination Addressing Mode",    "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
3586             IEEE802154_FCF_DADDR_MASK, NULL, HFILL }},
3587
3588         { &hf_ieee802154_src_addr_mode,
3589         { "Source Addressing Mode",         "wpan.src_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
3590             IEEE802154_FCF_SADDR_MASK, NULL, HFILL }},
3591
3592         { &hf_ieee802154_version,
3593         { "Frame Version",                  "wpan.version", FT_UINT16, BASE_DEC, VALS(ieee802154_frame_versions),
3594             IEEE802154_FCF_VERSION, NULL, HFILL }},
3595
3596         { &hf_ieee802154_dst_panID,
3597         { "Destination PAN",                "wpan.dst_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
3598             NULL, HFILL }},
3599
3600         { &hf_ieee802154_dst16,
3601         { "Destination",                    "wpan.dst16", FT_UINT16, BASE_HEX, NULL, 0x0,
3602             NULL, HFILL }},
3603
3604         { &hf_ieee802154_dst64,
3605         { "Destination",                    "wpan.dst64", FT_EUI64, BASE_NONE, NULL, 0x0,
3606             NULL, HFILL }},
3607
3608         { &hf_ieee802154_src_panID,
3609         { "Source PAN",                     "wpan.src_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
3610             NULL, HFILL }},
3611
3612         { &hf_ieee802154_src16,
3613         { "Source",                         "wpan.src16", FT_UINT16, BASE_HEX, NULL, 0x0,
3614             NULL, HFILL }},
3615
3616         { &hf_ieee802154_src64,
3617         { "Extended Source",                "wpan.src64", FT_EUI64, BASE_NONE, NULL, 0x0,
3618             NULL, HFILL }},
3619
3620         { &hf_ieee802154_src64_origin,
3621         { "Origin",                           "wpan.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3622             NULL, HFILL }},
3623
3624         { &hf_ieee802154_fcs,
3625         { "FCS",                            "wpan.fcs", FT_UINT16, BASE_HEX, NULL, 0x0,
3626             NULL, HFILL }},
3627
3628         { &hf_ieee802154_rssi,
3629         { "RSSI",                           "wpan.rssi", FT_INT8, BASE_DEC|BASE_UNIT_STRING, &units_decibels, 0x0,
3630             "Received Signal Strength", HFILL }},
3631
3632         { &hf_ieee802154_fcs_ok,
3633         { "FCS Valid",                      "wpan.fcs_ok", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3634             NULL, HFILL }},
3635
3636         { &hf_ieee802154_correlation,
3637         { "LQI Correlation Value",          "wpan.correlation", FT_UINT8, BASE_DEC, NULL, 0x0,
3638             NULL, HFILL }},
3639
3640         /* Header IE */
3641         { &hf_ieee802154_header_ie,
3642         { "Header IE",                      "wpan.header_ie", FT_UINT16, BASE_HEX, NULL,
3643             0x0, NULL, HFILL }},
3644
3645         { &hf_ieee802154_header_ie_type,
3646         { "Type",                           "wpan.header_ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_ie_types),
3647                 IEEE802154_HEADER_IE_TYPE_MASK, NULL, HFILL }},
3648
3649         { &hf_ieee802154_header_ie_id,
3650         { "Id",                             "wpan.header_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_header_ie_names),
3651                 IEEE802154_HEADER_IE_ID_MASK, NULL, HFILL }},
3652
3653         { &hf_ieee802154_header_ie_length,
3654         { "Length",                         "wpan.header_ie.length", FT_UINT16, BASE_DEC, NULL,
3655                 IEEE802154_HEADER_IE_LENGTH_MASK, NULL, HFILL }},
3656
3657         { &hf_ieee802154_header_ie_data,
3658         { "Data",                           "wpan.header_ie.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3659
3660         { &hf_ieee802154_h_ie_time_correction1,
3661         { "Ack - positive time correction",                       "wpan.h_ie_time_correction", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
3662             NULL, HFILL }},
3663
3664         { &hf_ieee802154_h_ie_time_correction2,
3665         { "Ack - negative time correction",                       "wpan.h_ie_time_correction", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
3666             NULL, HFILL }},
3667
3668         { &hf_ieee802154_h_ie_time_correction3,
3669         { "Non Ack - positive time correction",                       "wpan.h_ie_time_correction", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
3670             NULL, HFILL }},
3671
3672         { &hf_ieee802154_h_ie_time_correction4,
3673         { "Non Ack - negative time correction",                       "wpan.h_ie_time_correction", FT_UINT16, BASE_DEC, NULL, 0x0FFF,
3674             NULL, HFILL }},
3675
3676         /* Payload IEs */
3677         { &hf_ieee802154_payload_ie,
3678         { "Header",                         "wpan.payload_ie", FT_UINT16, BASE_HEX, NULL,
3679             0x0, NULL, HFILL }},
3680
3681         { &hf_ieee802154_payload_ie_type,
3682         { "Type",                           "wpan.payload_ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_ie_types),
3683                 IEEE802154_PAYLOAD_IE_TYPE_MASK, NULL, HFILL }},
3684
3685         { &hf_ieee802154_payload_ie_id,
3686         { "Id",                             "wpan.payload_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_payload_ie_names),
3687                 IEEE802154_PAYLOAD_IE_ID_MASK, NULL, HFILL }},
3688
3689         { &hf_ieee802154_payload_ie_length,
3690         { "Length",                         "wpan.payload_ie.length", FT_UINT16, BASE_DEC, NULL,
3691                 IEEE802154_PAYLOAD_IE_LENGTH_MASK, NULL, HFILL }},
3692
3693         { &hf_ieee802154_psie_short,
3694         { "Payload Sub IE (short)",         "wpan.payload_sub_ie.short", FT_UINT16, BASE_HEX, NULL,
3695             0x0, NULL, HFILL }},
3696
3697         { &hf_ieee802154_psie_type_short,
3698         { "Type",                           "wpan.payload_sub_ie.type_short", FT_UINT16, BASE_DEC, VALS(ieee802154_psie_types),
3699                 IEEE802154_PSIE_TYPE_MASK, NULL, HFILL }},
3700
3701         { &hf_ieee802154_psie_id_short,
3702         { "Sub Id (Short)",                 "wpan.payload_sub_ie.id_short", FT_UINT16, BASE_HEX, VALS(ieee802154_psie_names),
3703                 IEEE802154_PSIE_ID_MASK_SHORT, NULL, HFILL }},
3704
3705         { &hf_ieee802154_psie_length_short,
3706         { "Length",                         "wpan.payload_sub_ie.length_short", FT_UINT16, BASE_DEC, NULL,
3707                 IEEE802154_PSIE_LENGTH_MASK_SHORT, NULL, HFILL }},
3708
3709         { &hf_ieee802154_psie_long,
3710         { "Payload Sub IE (long)",         "wpan.payload_sub_ie.long", FT_UINT16, BASE_HEX, NULL,
3711             0x0, NULL, HFILL }},
3712
3713         { &hf_ieee802154_psie_type_long,
3714         { "Type",                           "wpan.payload_sub_ie.type_long", FT_UINT16, BASE_DEC, VALS(ieee802154_psie_types),
3715                 IEEE802154_PSIE_TYPE_MASK, NULL, HFILL }},
3716
3717         { &hf_ieee802154_psie_id_long,
3718         { "Sub Id (Long)",                  "wpan.payload_sub_ie.id_long", FT_UINT16, BASE_HEX, VALS(ieee802154_psie_names),
3719                 IEEE802154_PSIE_ID_MASK_LONG, NULL, HFILL }},
3720
3721         { &hf_ieee802154_psie_length_long,
3722         { "Length",                         "wpan.payload_sub_ie.length_long", FT_UINT16, BASE_DEC, NULL,
3723                 IEEE802154_PSIE_LENGTH_MASK_LONG, NULL, HFILL }},
3724
3725         { &hf_ieee802154_psie_eb_filter,
3726         { "Enhanced Beacon Filter",         "wpan.payload_sub_ie.eb_filter", FT_UINT8, BASE_HEX, NULL,
3727               0, NULL, HFILL }},
3728
3729         { &hf_ieee802154_p_ie_mlme_sh_tsch_asn,
3730         { "Absolute Slot Number",                   "wpan.p_ie_mlme_sh_asn", FT_UINT64, BASE_DEC, NULL, 0x0,
3731             NULL, HFILL }},
3732
3733         { &hf_ieee802154_p_ie_mlme_sh_tsch_join_p,
3734         { "Join Priority",                   "wpan.p_ie_mlme_sh_joinp", FT_UINT8, BASE_DEC, NULL, 0x0,
3735             NULL, HFILL }},
3736
3737         { &hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_nb_slotf,
3738         { "Number of Slotframes",                   "wpan.p_ie_mlme_sh_slotf_link_nb_slotf", FT_UINT8, BASE_DEC, NULL, 0x0,
3739             NULL, HFILL }},
3740
3741         { &hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_slotf_handle,
3742         { "Slotframe handle",                       "wpan.p_ie_mlme_sh_slotf_link_slotf_handle", FT_UINT8, BASE_DEC, NULL, 0x0,
3743             NULL, HFILL }},
3744
3745         { &hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_slotf_size,
3746         { "Slotframe size",                       "wpan.p_ie_mlme_sh_slotf_link_slotf_size", FT_UINT16, BASE_DEC, NULL, 0x0,
3747             NULL, HFILL }},
3748
3749         { &hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_nb_links,
3750         { "Number of Links",                       "wpan.p_ie_mlme_sh_slotf_link_nb_links", FT_UINT8, BASE_DEC, NULL, 0x0,
3751             NULL, HFILL }},
3752
3753         { &hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_timeslot,
3754         { "Timeslot",                       "wpan.p_ie_mlme_sh_slotf_link_timeslot", FT_UINT16, BASE_DEC, NULL, 0x0,
3755             NULL, HFILL }},
3756
3757         { &hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_channel_offset,
3758         { "Channel Offset",                       "wpan.p_ie_mlme_sh_slotf_link_channel_offset", FT_UINT16, BASE_DEC, NULL, 0x0,
3759             NULL, HFILL }},
3760
3761         { &hf_ieee802154_p_ie_mlme_sh_tsch_slotf_link_options,
3762         { "Link Options",                       "wpan.p_ie_mlme_sh_slotf_link_options", FT_UINT8, BASE_DEC, NULL, 0x0,
3763             NULL, HFILL }},
3764
3765         { &hf_ieee802154_p_ie_mlme_lg_hopping_sequence_id,
3766         { "Hopping Sequence ID",                   "wpan.p_ie_mlme_lg_hopping_sequence_id", FT_UINT8, BASE_HEX, NULL, 0x0,
3767             NULL, HFILL }},
3768 /* ------------------------------------------------------------------------------------------------------------------------------------- */
3769
3770         { &hf_ieee802154_psie_eb_filter_pjoin,
3771         { "Permit Join Filter",             "wpan.payload_sub_ie.eb_filter.pjoin", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled),
3772               IEEE802154_MLME_PSIE_EB_FLT_PJOIN, NULL, HFILL }},
3773
3774         { &hf_ieee802154_psie_eb_filter_lqi,
3775         { "LQI Filter",                     "wpan.payload_sub_ie.eb_filter.lqi", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled),
3776             IEEE802154_MLME_PSIE_EB_FLT_LQI, NULL, HFILL }},
3777
3778         { &hf_ieee802154_psie_eb_filter_lqi_min,
3779         { "Minimum LQI",                    "wpan.payload_sub_ie.eb_filter.lqi_minimum", FT_UINT8, BASE_DEC, NULL,
3780              0x0, NULL, HFILL }},
3781
3782         { &hf_ieee802154_psie_eb_filter_percent,
3783         { "Probability to Respond",         "wpan.payload_sub_ie.eb_filter.contains_prob", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled),
3784             IEEE802154_MLME_PSIE_EB_FLT_PERCENT, NULL, HFILL }},
3785
3786         { &hf_ieee802154_psie_eb_filter_percent_prob,
3787         { "Response Probability Percentage", "wpan.payload_sub_ie.eb_filter.prob", FT_UINT8, BASE_DEC, NULL,
3788                  0x0, NULL, HFILL }},
3789
3790         { &hf_ieee802154_psie_eb_filter_attr_id,
3791         { "Requested Attribute Length",      "wpan.payload_sub_ie.eb_filter.attr_id", FT_UINT8, BASE_DEC, NULL,
3792             IEEE802154_MLME_PSIE_EB_FLT_ATTR_LEN, NULL, HFILL }},
3793
3794         { &hf_ieee802154_psie_eb_filter_attr_id_bitmap,
3795         { "Attribute ID Bitmap",             "wpan.payload_sub_ie.eb_filter.attr_id_bits", FT_UINT24, BASE_HEX, NULL,
3796                 0x0, NULL, HFILL }},
3797
3798         { &hf_ieee802154_payload_ie_data,
3799         { "Data",                            "wpan.payload_ie.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3800
3801         { &hf_ieee802154_payload_ie_vendor_oui,
3802         { "Vendor OUI",                      "wpan.payload_ie.vendor_oui", FT_UINT24, BASE_HEX, NULL,
3803             0x0, NULL, HFILL }},
3804
3805         { &hf_ieee802154_mlme_ie_data,
3806         { "Data",                            "wpan.mlme_sub_ie.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3807
3808         /* IETF IE */
3809         { &hf_ieee802154_p_ie_ietf_sub_id,
3810         { "Sub-ID", "wpan.ietf_ie.sub_id", FT_UINT8, BASE_DEC, NULL, 0,
3811           NULL, HFILL }},
3812
3813         /* IETF IE - 6top IE */
3814         { &hf_ieee802154_p_ie_6top_version,
3815         { "6P Version", "wpan.ietf_ie.6top.version", FT_UINT8, BASE_DEC, NULL, IETF_6TOP_VERSION,
3816           NULL, HFILL }},
3817
3818         { &hf_ieee802154_p_ie_6top_type,
3819           { "Type", "wpan.ietf_ie.6top.type", FT_UINT8, BASE_HEX, VALS(ietf_6top_types), IETF_6TOP_TYPE,
3820           NULL, HFILL }},
3821
3822         { &hf_ieee802154_p_ie_6top_flags_reserved,
3823         { "Reserved", "wpan.ietf_ie.6top.flags.reserved", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_FLAGS_RESERVED,
3824           NULL, HFILL }},
3825
3826         { &hf_ieee802154_p_ie_6top_code,
3827         { "Code",  "wpan.ietf_ie.6top.code", FT_UINT8, BASE_HEX, NULL, 0x0,
3828           NULL, HFILL }},
3829
3830         { &hf_ieee802154_p_ie_6top_sfid,
3831         { "SFID (6top Scheduling Fnction ID)", "wpan.ietf_ie.6top.sfid", FT_UINT8, BASE_HEX, NULL, 0x0,
3832           NULL, HFILL }},
3833
3834         { &hf_ieee802154_p_ie_6top_seqnum,
3835         { "SeqNum", "wpan.ietf_ie.6top.seqnum", FT_UINT8, BASE_DEC, NULL, IETF_6TOP_SEQNUM,
3836           NULL, HFILL }},
3837
3838         { &hf_ieee802154_p_ie_6top_gab,
3839         { "GAB", "wpan.ietf_ie.6top.gab", FT_UINT8, BASE_DEC, VALS(ietf_6top_generation_numbers), IETF_6TOP_GAB,
3840           NULL, HFILL }},
3841
3842         { &hf_ieee802154_p_ie_6top_gba,
3843         { "GBA", "wpan.ietf_ie.6top.gba", FT_UINT8, BASE_DEC, VALS(ietf_6top_generation_numbers), IETF_6TOP_GBA,
3844           NULL, HFILL }},
3845
3846         { &hf_ieee802154_p_ie_6top_metadata,
3847         { "Metadata", "wpan.ietf_ie.6top.metadata", FT_UINT16, BASE_HEX, NULL, 0x0,
3848           NULL, HFILL }},
3849
3850         { &hf_ieee802154_p_ie_6top_cell_options,
3851           { "Cell Options", "wpan.ietf_ie.6top.cell_options", FT_UINT8, BASE_HEX, VALS(ietf_6top_cell_options), 0x0,
3852           NULL, HFILL }},
3853
3854         { &hf_ieee802154_p_ie_6top_cell_option_tx,
3855         { "Transmit (TX) Cell", "wpan.ietf_ie.6top.cell_option_tx", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_TX,
3856           NULL, HFILL }},
3857
3858         { &hf_ieee802154_p_ie_6top_cell_option_rx,
3859         { "Receive (RX) Cell", "wpan.ietf_ie.6top.cell_option_rx", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_RX,
3860           NULL, HFILL }},
3861
3862         { &hf_ieee802154_p_ie_6top_cell_option_shared,
3863         { "SHARED Cell", "wpan.ietf_ie.6top.cell_option_shared", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_SHARED,
3864           NULL, HFILL }},
3865
3866         { &hf_ieee802154_p_ie_6top_cell_option_reserved,
3867         { "Reserved", "wpan.ietf_ie.6top.cell_option_reserved", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_RESERVED,
3868           NULL, HFILL }},
3869
3870         { &hf_ieee802154_p_ie_6top_num_cells,
3871         { "Number of Cells", "wpan.ietf_ie.6top.num_cells", FT_UINT16, BASE_DEC, NULL, 0x0,
3872           NULL, HFILL }},
3873
3874         { &hf_ieee802154_p_ie_6top_reserved,
3875         { "Reserved", "wpan.ietf_ie.6top.reserved", FT_UINT8, BASE_HEX, NULL, 0x0,
3876           NULL, HFILL }},
3877
3878         { &hf_ieee802154_p_ie_6top_offset,
3879         { "Offset", "wpan.ietf_ie.6top.offset", FT_UINT16, BASE_DEC, NULL, 0x0,
3880           NULL, HFILL }},
3881
3882         { &hf_ieee802154_p_ie_6top_max_num_cells,
3883         { "Maximum Number of Requested Cells", "wpan.ietf_ie.6top.max_num_cells", FT_UINT16, BASE_DEC, NULL, 0x0,
3884           NULL, HFILL }},
3885
3886         { &hf_ieee802154_p_ie_6top_slot_offset,
3887         { "Slot Offset", "wpan.ietf_ie.6top.cell.slot_offset", FT_UINT16, BASE_HEX, NULL, 0x0,
3888           NULL, HFILL }},
3889
3890         { &hf_ieee802154_p_ie_6top_channel_offset,
3891         { "Channel Offset", "wpan.ietf_ie.6top.cell.channel_offset", FT_UINT16, BASE_HEX, NULL, 0x0,
3892           NULL, HFILL }},
3893
3894         /*
3895          * Command Frame Specific Fields
3896          */
3897
3898         { &hf_ieee802154_cmd_id,
3899         { "Command Identifier",         "wpan.cmd", FT_UINT8, BASE_HEX, VALS(ieee802154_cmd_names), 0x0,
3900             NULL, HFILL }},
3901
3902         /*  Capability Information Fields */
3903         { &hf_ieee802154_cinfo_alt_coord,
3904         { "Alternate PAN Coordinator",  "wpan.cinfo.alt_coord", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALT_PAN_COORD,
3905             "Whether this device can act as a PAN coordinator or not.", HFILL }},
3906
3907         { &hf_ieee802154_cinfo_device_type,
3908         { "Device Type",                "wpan.cinfo.device_type", FT_BOOLEAN, 8, TFS(&tfs_cinfo_device_type), IEEE802154_CMD_CINFO_DEVICE_TYPE,
3909             "Whether this device is RFD (reduced-function device) or FFD (full-function device).", HFILL }},
3910
3911         { &hf_ieee802154_cinfo_power_src,
3912         { "Power Source",               "wpan.cinfo.power_src", FT_BOOLEAN, 8, TFS(&tfs_cinfo_power_src), IEEE802154_CMD_CINFO_POWER_SRC,
3913             "Whether this device is operating on AC/mains or battery power.", HFILL }},
3914
3915         { &hf_ieee802154_cinfo_idle_rx,
3916         { "Receive On When Idle",       "wpan.cinfo.idle_rx", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_IDLE_RX,
3917             "Whether this device can receive packets while idle or not.", HFILL }},
3918
3919         { &hf_ieee802154_cinfo_sec_capable,
3920         { "Security Capability",        "wpan.cinfo.sec_capable", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_SEC_CAPABLE,
3921             "Whether this device is capable of receiving encrypted packets.", HFILL }},
3922
3923         { &hf_ieee802154_cinfo_alloc_addr,
3924         { "Allocate Address",           "wpan.cinfo.alloc_addr", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALLOC_ADDR,
3925             "Whether this device wishes to use a 16-bit short address instead of its IEEE 802.15.4 64-bit long address.", HFILL }},
3926
3927             /*  Association response fields */
3928         { &hf_ieee802154_assoc_addr,
3929         { "Short Address",              "wpan.asoc.addr", FT_UINT16, BASE_HEX, NULL, 0x0,
3930             "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 }},
3931
3932         { &hf_ieee802154_assoc_status,
3933         { "Association Status",         "wpan.assoc.status", FT_UINT8, BASE_HEX, NULL, 0x0,
3934             NULL, HFILL }},
3935
3936         { &hf_ieee802154_disassoc_reason,
3937         { "Disassociation Reason",      "wpan.disassoc.reason", FT_UINT8, BASE_HEX, NULL, 0x0,
3938             NULL, HFILL }},
3939
3940             /*  Coordinator Realignment fields */
3941         { &hf_ieee802154_realign_pan,
3942         { "PAN ID",                     "wpan.realign.pan", FT_UINT16, BASE_HEX, NULL, 0x0,
3943             "The PAN identifier the coordinator wishes to use for future communication.", HFILL }},
3944
3945         { &hf_ieee802154_realign_caddr,
3946         { "Coordinator Short Address",  "wpan.realign.addr", FT_UINT16, BASE_HEX, NULL, 0x0,
3947             "The 16-bit address the coordinator wishes to use for future communication.", HFILL }},
3948
3949         { &hf_ieee802154_realign_channel,
3950         { "Logical Channel",            "wpan.realign.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
3951             "The logical channel the coordinator wishes to use for future communication.", HFILL }},
3952
3953         { &hf_ieee802154_realign_addr,
3954         { "Short Address",              "wpan.realign.addr", FT_UINT16, BASE_HEX, NULL, 0x0,
3955             "A short-address that the orphaned device shall assume if applicable.", HFILL }},
3956
3957         { &hf_ieee802154_realign_channel_page,
3958         { "Channel Page",               "wpan.realign.channel_page", FT_UINT8, BASE_DEC, NULL, 0x0,
3959             "The logical channel page the coordinator wishes to use for future communication.", HFILL }},
3960
3961         { &hf_ieee802154_gtsreq_len,
3962         { "GTS Length",                 "wpan.gtsreq.length", FT_UINT8, BASE_DEC, NULL, IEEE802154_CMD_GTS_REQ_LEN,
3963             "Number of superframe slots the device is requesting.", HFILL }},
3964
3965         { &hf_ieee802154_gtsreq_dir,
3966         { "GTS Direction",              "wpan.gtsreq.direction", FT_BOOLEAN, 8, TFS(&tfs_gtsreq_dir), IEEE802154_CMD_GTS_REQ_DIR,
3967             "The direction of traffic in the guaranteed timeslot.", HFILL }},
3968
3969         { &hf_ieee802154_gtsreq_type,
3970         { "Characteristic Type",        "wpan.gtsreq.type", FT_BOOLEAN, 8, TFS(&tfs_gtsreq_type), IEEE802154_CMD_GTS_REQ_TYPE,
3971             "Whether this request is to allocate or deallocate a timeslot.", HFILL }},
3972
3973         /*
3974          * Beacon Frame Specific Fields
3975          */
3976         { &hf_ieee802154_beacon_order,
3977         { "Beacon Interval",            "wpan.beacon_order", FT_UINT16, BASE_DEC, NULL, IEEE802154_BEACON_ORDER_MASK,
3978             "Specifies the transmission interval of the beacons.", HFILL }},
3979
3980         { &hf_ieee802154_superframe_order,
3981         { "Superframe Interval",        "wpan.superframe_order", FT_UINT16, BASE_DEC, NULL,
3982             IEEE802154_SUPERFRAME_ORDER_MASK,
3983             "Specifies the length of time the coordinator will interact with the PAN.", HFILL }},
3984
3985         { &hf_ieee802154_cap,
3986         { "Final CAP Slot",             "wpan.cap", FT_UINT16, BASE_DEC, NULL, IEEE802154_SUPERFRAME_CAP_MASK,
3987             "Specifies the final superframe slot used by the CAP.", HFILL }},
3988
3989         { &hf_ieee802154_superframe_battery_ext,
3990         { "Battery Extension",          "wpan.battery_ext", FT_BOOLEAN, 16, NULL, IEEE802154_BATT_EXTENSION_MASK,
3991             "Whether transmissions may not extend past the length of the beacon frame.", HFILL }},
3992
3993         { &hf_ieee802154_superframe_coord,
3994         { "PAN Coordinator",            "wpan.bcn_coord", FT_BOOLEAN, 16, NULL, IEEE802154_SUPERFRAME_COORD_MASK,
3995             "Whether this beacon frame is being transmitted by the PAN coordinator or not.", HFILL }},
3996
3997         { &hf_ieee802154_assoc_permit,
3998         { "Association Permit",         "wpan.assoc_permit", FT_BOOLEAN, 16, NULL, IEEE802154_ASSOC_PERMIT_MASK,
3999             "Whether this PAN is accepting association requests or not.", HFILL }},
4000
4001         { &hf_ieee802154_gts_count,
4002         { "GTS Descriptor Count",       "wpan.gts.count", FT_UINT8, BASE_DEC, NULL, 0x0,
4003             "The number of GTS descriptors present in this beacon frame.", HFILL }},
4004
4005         { &hf_ieee802154_gts_permit,
4006         { "GTS Permit",                 "wpan.gts.permit", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4007             "Whether the PAN coordinator is accepting GTS requests or not.", HFILL }},
4008
4009         { &hf_ieee802154_gts_direction,
4010         { "Direction",                  "wpan.gts.direction", FT_BOOLEAN, BASE_NONE, TFS(&ieee802154_gts_direction_tfs), 0x0,
4011             "A flag defining the direction of the GTS Slot.", HFILL }},
4012
4013         { &hf_ieee802154_gts_address,
4014         { "Address",                  "wpan.gts.address", FT_UINT16, BASE_HEX, NULL, 0x0,
4015             NULL, HFILL }},
4016
4017         { &hf_ieee802154_pending16,
4018         { "Address",                    "wpan.pending16", FT_UINT16, BASE_HEX, NULL, 0x0,
4019             "Device with pending data to receive.", HFILL }},
4020
4021         { &hf_ieee802154_pending64,
4022         { "Address",                    "wpan.pending64", FT_EUI64, BASE_NONE, NULL, 0x0,
4023             "Device with pending data to receive.", HFILL }},
4024
4025         /*
4026          * Auxiliary Security Header Fields
4027          */
4028
4029         { &hf_ieee802154_security_level,
4030         { "Security Level", "wpan.aux_sec.sec_level", FT_UINT8, BASE_HEX, VALS(ieee802154_sec_level_names),
4031             IEEE802154_AUX_SEC_LEVEL_MASK, "The Security Level of the frame", HFILL }},
4032
4033         { &hf_ieee802154_security_control_field,
4034         { "Security Control Field", "wpan.aux_sec.security_control_field", FT_UINT8, BASE_HEX, NULL,
4035             0x0, NULL, HFILL }},
4036
4037         { &hf_ieee802154_key_id_mode,
4038         { "Key Identifier Mode", "wpan.aux_sec.key_id_mode", FT_UINT8, BASE_HEX, VALS(ieee802154_key_id_mode_names),
4039             IEEE802154_AUX_KEY_ID_MODE_MASK,
4040             "The scheme to use by the recipient to lookup the key in its key table", HFILL }},
4041
4042         { &hf_ieee802154_aux_sec_reserved,
4043         { "Reserved", "wpan.aux_sec.reserved", FT_UINT8, BASE_HEX, NULL, IEEE802154_AUX_KEY_RESERVED_MASK,
4044             NULL, HFILL }},
4045
4046         { &hf_ieee802154_aux_sec_frame_counter,
4047         { "Frame Counter", "wpan.aux_sec.frame_counter", FT_UINT32, BASE_DEC, NULL, 0x0,
4048             "Frame counter of the originator of the protected frame", HFILL }},
4049
4050         { &hf_ieee802154_aux_sec_key_source,
4051         { "Key Source", "wpan.aux_sec.key_source", FT_UINT64, BASE_HEX, NULL, 0x0,
4052             "Key Source for processing of the protected frame", HFILL }},
4053
4054         { &hf_ieee802154_aux_sec_key_index,
4055         { "Key Index", "wpan.aux_sec.key_index", FT_UINT8, BASE_HEX, NULL, 0x0,
4056             "Key Index for processing of the protected frame", HFILL }},
4057
4058             /* IEEE 802.15.4-2003 Security Header Fields */
4059         { &hf_ieee802154_sec_frame_counter,
4060         { "Frame Counter", "wpan.sec_frame_counter", FT_UINT32, BASE_HEX, NULL, 0x0,
4061             "Frame counter of the originator of the protected frame (802.15.4-2003)", HFILL }},
4062
4063         { &hf_ieee802154_sec_key_sequence_counter,
4064         { "Key Sequence Counter", "wpan.sec_key_sequence_counter", FT_UINT8, BASE_HEX, NULL, 0x0,
4065             "Key Sequence counter of the originator of the protected frame (802.15.4-2003)", HFILL }},
4066
4067         /* ZBOSS dump */
4068         { &zboss_channel,
4069         { "Channel", "wpan.zboss.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
4070             "Channel number", HFILL }},
4071
4072         { &zboss_direction,
4073         { "ZBOSS Direction", "wpan.zboss.direction", FT_UINT8, BASE_HEX, VALS(zboss_direction_names), 0x0,
4074             "ZBOSS Packet Direction", HFILL }},
4075
4076         { &zboss_trace_number,
4077         { "Trace number", "wpan.zboss.trace", FT_UINT32, BASE_DEC, NULL, 0x0,
4078             "Trace item number", HFILL }},
4079     };
4080
4081     /* Subtrees */
4082     static gint *ett[] = {
4083         &ett_ieee802154_nonask_phy,
4084         &ett_ieee802154_nonask_phy_phr,
4085         &ett_ieee802154,
4086         &ett_ieee802154_fcf,
4087         &ett_ieee802154_auxiliary_security,
4088         &ett_ieee802154_aux_sec_control,
4089         &ett_ieee802154_aux_sec_key_id,
4090         &ett_ieee802154_fcs,
4091         &ett_ieee802154_cmd,
4092         &ett_ieee802154_superframe,
4093         &ett_ieee802154_gts,
4094         &ett_ieee802154_gts_direction,
4095         &ett_ieee802154_gts_descriptors,
4096         &ett_ieee802154_pendaddr,
4097         &ett_ieee802154_header,
4098         &ett_ieee802154_header_ie,
4099         &ett_ieee802154_h_ie_payload,
4100         &ett_ieee802154_payload,
4101         &ett_ieee802154_payload_ie,
4102         &ett_ieee802154_mlme_payload,
4103         &ett_ieee802154_mlme_payload_data,
4104         &ett_ieee802154_psie_short,
4105         &ett_ieee802154_psie_short_bitmap,
4106         &ett_ieee802154_psie_long,
4107         &ett_ieee802154_psie_long_bitmap,
4108         &ett_ieee802154_psie_enh_beacon_flt,
4109         &ett_ieee802154_psie_enh_beacon_flt_bitmap,
4110         &ett_ieee802154_psie_slotframe_link_slotframes,
4111         &ett_ieee802154_zigbee,
4112         &ett_ieee802154_zboss,
4113         &ett_ieee802154_p_ie_6top,
4114         &ett_ieee802154_p_ie_6top_version_type,
4115         &ett_ieee802154_p_ie_6top_seqnum_gab_gba,
4116         &ett_ieee802154_p_ie_6top_cell_options,
4117         &ett_ieee802154_p_ie_6top_cell_list,
4118         &ett_ieee802154_p_ie_6top_cell
4119     };
4120
4121     static ei_register_info ei[] = {
4122         { &ei_ieee802154_invalid_addressing, { "wpan.invalid_addressing", PI_MALFORMED, PI_WARN,
4123                 "Invalid Addressing", EXPFILL }},
4124 #if 0
4125         { &ei_ieee802154_invalid_panid_compression, { "wpan.invalid_panid_compression", PI_MALFORMED, PI_ERROR,
4126                 "Invalid Setting for PAN ID Compression", EXPFILL }},
4127 #endif
4128         { &ei_ieee802154_invalid_panid_compression2, { "wpan.seqno_supression_fv2_invalid",  PI_MALFORMED, PI_WARN,
4129                 "Invalid Pan ID Compression and addressing combination for Frame Version 2", EXPFILL }},
4130         { &ei_ieee802154_dst, { "wpan.dst_invalid", PI_MALFORMED, PI_ERROR,
4131                 "Invalid Destination Address Mode", EXPFILL }},
4132         { &ei_ieee802154_src, { "wpan.src_invalid", PI_MALFORMED, PI_ERROR,
4133                 "Invalid Source Address Mode", EXPFILL }},
4134         { &ei_ieee802154_frame_ver,  { "wpan.frame_version_unknown", PI_MALFORMED, PI_ERROR,
4135                 "Frame Version Unknown Cannot Dissect", EXPFILL }},
4136 #if 0
4137         { &ei_ieee802154_frame_type, { "wpan.frame_type_unknown", PI_MALFORMED, PI_ERROR,
4138                 "Frame Type Unknown Cannot Dissect", EXPFILL }},
4139 #endif
4140         { &ei_ieee802154_decrypt_error, { "wpan.decrypt_error", PI_UNDECODED, PI_WARN,
4141                 "Decryption error", EXPFILL }},
4142         { &ei_ieee802154_fcs, { "wpan.fcs.bad", PI_CHECKSUM, PI_WARN,
4143                 "Bad FCS", EXPFILL }},
4144         { &ei_ieee802154_seqno_suppression, { "wpan.seqno_supression_invalid",  PI_MALFORMED, PI_WARN,
4145                 "Sequence Number Suppression invalid for 802.15.4-2003 and 2006", EXPFILL }},
4146         { &ei_ieee802154_p_ie_6top_type, { "wpan.ietf_ie.6top.type.unsupported", PI_PROTOCOL, PI_WARN,
4147                 "Unsupported Type of Message", EXPFILL }},
4148         { &ei_ieee802154_p_ie_6top_code, { "wpan.ietf_ie.6top.code.unsupported", PI_PROTOCOL, PI_WARN,
4149                 "Unsupported Request Command or Return Code", EXPFILL }},
4150
4151     };
4152
4153     /* Preferences. */
4154     module_t *ieee802154_module;
4155     expert_module_t* expert_ieee802154;
4156
4157     static uat_field_t addr_uat_flds[] = {
4158         UAT_FLD_HEX(addr_uat,addr16,"Short Address",
4159                 "16-bit short address in hexadecimal."),
4160         UAT_FLD_HEX(addr_uat,pan,"PAN Identifier",
4161                 "16-bit PAN identifier in hexadecimal."),
4162         UAT_FLD_BUFFER(addr_uat,eui64,"EUI-64",
4163                 "64-bit extended unique identifier."),
4164         UAT_END_FIELDS
4165     };
4166
4167     static build_valid_func     ieee802154_da_build_value[1] = {ieee802154_da_value};
4168     static decode_as_value_t    ieee802154_da_values = {ieee802154_da_prompt, 1, ieee802154_da_build_value};
4169     static decode_as_t          ieee802154_da = {
4170         IEEE802154_PROTOABBREV_WPAN, "PAN", IEEE802154_PROTOABBREV_WPAN_PANID,
4171         1, 0, &ieee802154_da_values, NULL, NULL,
4172         decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL
4173     };
4174
4175     /* Register the init routine. */
4176     register_init_routine(proto_init_ieee802154);
4177     register_cleanup_routine(proto_cleanup_ieee802154);
4178
4179     /*  Register Protocol name and description. */
4180     proto_ieee802154 = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN", "IEEE 802.15.4",
4181            IEEE802154_PROTOABBREV_WPAN);
4182     proto_ieee802154_nonask_phy = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN non-ASK PHY",
4183             "IEEE 802.15.4 non-ASK PHY", "wpan-nonask-phy");
4184     proto_zboss = proto_register_protocol("ZBOSS IEEE 802.15.4 dump",
4185                                           "ZBOSS dump", "wpan-zboss");
4186
4187     /*  Register header fields and subtrees. */
4188     proto_register_field_array(proto_ieee802154, hf, array_length(hf));
4189     proto_register_field_array(proto_ieee802154, hf_phy, array_length(hf_phy));
4190
4191     proto_register_subtree_array(ett, array_length(ett));
4192
4193     expert_ieee802154 = expert_register_protocol(proto_ieee802154);
4194     expert_register_field_array(expert_ieee802154, ei, array_length(ei));
4195
4196     ieee802_15_4_short_address_type = address_type_dissector_register("AT_IEEE_802_15_4_SHORT", "IEEE 802.15.4 16-bit short address",
4197                                         ieee802_15_4_short_address_to_str, ieee802_15_4_short_address_str_len, NULL, NULL, ieee802_15_4_short_address_len, NULL, NULL);
4198
4199     /* add a user preference to set the 802.15.4 ethertype */
4200     ieee802154_module = prefs_register_protocol(proto_ieee802154,
4201                                    proto_reg_handoff_ieee802154);
4202     prefs_register_uint_preference(ieee802154_module, "802154_ethertype",
4203                                    "802.15.4 Ethertype (in hex)",
4204                                    "(Hexadecimal) Ethertype used to indicate IEEE 802.15.4 frame.",
4205                                    16, &ieee802154_ethertype);
4206     prefs_register_bool_preference(ieee802154_module, "802154_cc24xx",
4207                                    "TI CC24xx FCS format",
4208                                    "Set if the FCS field is in TI CC24xx format.",
4209                                    &ieee802154_cc24xx);
4210     prefs_register_bool_preference(ieee802154_module, "802154_fcs_ok",
4211                                    "Dissect only good FCS",
4212                                    "Dissect payload only if FCS is valid.",
4213                                    &ieee802154_fcs_ok);
4214
4215     /* Create a UAT for static address mappings. */
4216     static_addr_uat = uat_new("Static Addresses",
4217             sizeof(static_addr_t),      /* record size */
4218             "802154_addresses",         /* filename */
4219             TRUE,                       /* from_profile */
4220             &static_addrs,              /* data_ptr */
4221             &num_static_addrs,          /* numitems_ptr */
4222             UAT_AFFECTS_DISSECTION,     /* affects dissection of packets, but not set of named fields */
4223             NULL,                       /* help */
4224             NULL,                       /* copy callback */
4225             addr_uat_update_cb,         /* update callback */
4226             NULL,                       /* free callback */
4227             NULL,                       /* post update callback */
4228             NULL,                       /* reset callback */
4229             addr_uat_flds);             /* UAT field definitions */
4230     prefs_register_uat_preference(ieee802154_module, "static_addr",
4231                 "Static Addresses",
4232                 "A table of static address mappings between 16-bit short addressing and EUI-64 addresses",
4233                 static_addr_uat);
4234
4235     /* Register preferences for a decryption key */
4236     /* TODO: Implement a UAT for multiple keys, and with more advanced key management. */
4237     prefs_register_string_preference(ieee802154_module, "802154_key", "Decryption key",
4238             "128-bit decryption key in hexadecimal format", (const char **)&ieee802154_key_str);
4239
4240     prefs_register_enum_preference(ieee802154_module, "802154_sec_suite",
4241                                    "Security Suite (802.15.4-2003)",
4242                                    "Specifies the security suite to use for 802.15.4-2003 secured frames"
4243                                    " (only supported suites are listed). Option ignored for 802.15.4-2006"
4244                                    " and unsecured frames.",
4245                                    &ieee802154_sec_suite, ieee802154_2003_sec_suite_enums, FALSE);
4246
4247     prefs_register_bool_preference(ieee802154_module, "802154_extend_auth",
4248                                    "Extend authentication data (802.15.4-2003)",
4249                                    "Set if the manufacturer extends the authentication data with the"
4250                                    " security header. Option ignored for 802.15.4-2006 and unsecured frames.",
4251                                    &ieee802154_extend_auth);
4252
4253     /* Register the subdissector list */
4254     panid_dissector_table = register_dissector_table(IEEE802154_PROTOABBREV_WPAN_PANID, "IEEE 802.15.4 PANID", proto_ieee802154, FT_UINT16, BASE_HEX);
4255     ieee802154_heur_subdissector_list = register_heur_dissector_list(IEEE802154_PROTOABBREV_WPAN, proto_ieee802154);
4256     ieee802154_beacon_subdissector_list = register_heur_dissector_list(IEEE802154_PROTOABBREV_WPAN_BEACON, proto_ieee802154);
4257
4258     /*  Register dissectors with Wireshark. */
4259     ieee802154_handle = register_dissector(IEEE802154_PROTOABBREV_WPAN, dissect_ieee802154, proto_ieee802154);
4260     ieee802154_nofcs_handle = register_dissector("wpan_nofcs", dissect_ieee802154_nofcs, proto_ieee802154);
4261     register_dissector("wpan_cc24xx", dissect_ieee802154_cc24xx, proto_ieee802154);
4262     ieee802154_nonask_phy_handle = register_dissector("wpan-nonask-phy", dissect_ieee802154_nonask_phy, proto_ieee802154_nonask_phy);
4263
4264     /* Register a Decode-As handler. */
4265     register_decode_as(&ieee802154_da);
4266 } /* proto_register_ieee802154 */
4267
4268
4269 /**
4270  * Registers the IEEE 802.15.4 dissector with Wireshark.
4271  * Will be called every time 'apply' is pressed in the preferences menu.
4272  * as well as during Wireshark initialization
4273  */
4274 void proto_reg_handoff_ieee802154(void)
4275 {
4276     static gboolean            prefs_initialized = FALSE;
4277     static unsigned int        old_ieee802154_ethertype;
4278     GByteArray                *bytes;
4279     gboolean                   res;
4280
4281     if (!prefs_initialized){
4282         /* Get the dissector handles. */
4283         zigbee_beacon_handle = find_dissector_add_dependency("zbee_beacon", proto_ieee802154);
4284         zigbee_ie_handle = find_dissector_add_dependency("zbee_ie", proto_ieee802154);
4285         zigbee_nwk_handle = find_dissector("zbee_nwk");
4286
4287         dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4, ieee802154_handle);
4288         dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_NONASK_PHY, ieee802154_nonask_phy_handle);
4289         dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_NOFCS, ieee802154_nofcs_handle);
4290         dissector_add_uint("sll.ltype", LINUX_SLL_P_IEEE802154, ieee802154_handle);
4291
4292         prefs_initialized = TRUE;
4293     } else {
4294         dissector_delete_uint("ethertype", old_ieee802154_ethertype, ieee802154_handle);
4295     }
4296
4297     old_ieee802154_ethertype = ieee802154_ethertype;
4298
4299     /* Get the IEEE 802.15.4 decryption key. */
4300     bytes = g_byte_array_new();
4301     res = hex_str_to_bytes(ieee802154_key_str, bytes, FALSE);
4302     ieee802154_key_valid =  (res && bytes->len >= IEEE802154_CIPHER_SIZE);
4303     if (ieee802154_key_valid) {
4304         memcpy(ieee802154_key, bytes->data, IEEE802154_CIPHER_SIZE);
4305     }
4306     g_byte_array_free(bytes, TRUE);
4307
4308     /* Register dissector handles. */
4309     dissector_add_uint("ethertype", ieee802154_ethertype, ieee802154_handle);
4310 } /* proto_reg_handoff_ieee802154 */