aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ieee802154.c
diff options
context:
space:
mode:
authorDevan Lai <devanl@davisinstruments.com>2019-09-18 18:25:54 -0700
committerAnders Broman <a.broman58@gmail.com>2019-10-03 07:52:32 +0000
commit6a7d3150ee737e1860eaca0c507fde7279db16a0 (patch)
tree0057e19a8ce2d7d33bcabe49b65ceee1d8dc215e /epan/dissectors/packet-ieee802154.c
parentb5091d8cd800c6ab35c0af4f5f4e056d138eb0bf (diff)
ieee802154: support multipurpose frames
Add support for IEEE802.15.4-2015 multipurpose frames, which are similar to data frames with the following exceptions: - The Frame Control Field can be either 1 or 2 octets, with different bit offsets for all fields except for Frame Type. - The Frame Version field, when present, must always be set to 00. - The source PAN ID is always absent - Instead of a PAN ID Compression field, there is a PAN ID Present field for the destination PAN ID only. See Section 7.3.5 of IEEE802.15.4-2015 (esp Figure 7-19) for details. Bug: 16101 Change-Id: I1e64d90694b567573ca10395b823adb9015f8917 Reviewed-on: https://code.wireshark.org/review/34682 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Jaap Keuter <jaap.keuter@xs4all.nl> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-ieee802154.c')
-rw-r--r--epan/dissectors/packet-ieee802154.c196
1 files changed, 171 insertions, 25 deletions
diff --git a/epan/dissectors/packet-ieee802154.c b/epan/dissectors/packet-ieee802154.c
index d2bf64030e..4337670bfb 100644
--- a/epan/dissectors/packet-ieee802154.c
+++ b/epan/dissectors/packet-ieee802154.c
@@ -1,5 +1,9 @@
/* packet-ieee802154.c
*
+ * Multipurpose frame support
+ * By Devan Lai <devanl@davisinstruments.com>
+ * Copyright 2019 Davis Instruments
+ *
* IEEE 802.15.4-2015 CCM* nonce for TSCH mode
* By Maxime Brunelle <Maxime.Brunelle@trilliant.com>
* Copyright 2019 Trilliant Inc.
@@ -36,11 +40,16 @@
* bit ordering).
*------------------------------------------------------------
*
- * IEEE 802.15.4 Packets have the following format:
+ * Most IEEE 802.15.4 Packets have the following format:
* | FCF |Seq No| Addressing | Data | FCS |
* |2 bytes|1 byte|0 to 20 bytes|Length-(Overhead) bytes|2/4 Bytes|
*------------------------------------------------------------
*
+ * Multipurpose frame packets have the following format:
+ * | FCF | Seq No | Addressing | Data | FCS |
+ * |1/2 bytes|0/1 bytes|0 to 20 bytes|Length-(Overhead) bytes|2 bytes|
+ *------------------------------------------------------------
+ *
* CRC16 is calculated using the x^16 + x^12 + x^5 + 1 polynomial
* as specified by ITU-T, and is calculated over the IEEE 802.15.4
* packet (excluding the FCS) as transmitted over the air. Note,
@@ -412,6 +421,18 @@ static int hf_ieee802154_ie_present = -1;
static int hf_ieee802154_src_addr_mode = -1;
static int hf_ieee802154_version = -1;
static int hf_ieee802154_dst_addr_mode = -1;
+
+static int hf_ieee802154_mpf_long_frame_control = -1;
+static int hf_ieee802154_mpf_dst_addr_mode = -1;
+static int hf_ieee802154_mpf_src_addr_mode = -1;
+static int hf_ieee802154_mpf_pan_id_present = -1;
+static int hf_ieee802154_mpf_security = -1;
+static int hf_ieee802154_mpf_seqno_suppression = -1;
+static int hf_ieee802154_mpf_pending = -1;
+static int hf_ieee802154_mpf_version = -1;
+static int hf_ieee802154_mpf_ack_request = -1;
+static int hf_ieee802154_mpf_ie_present = -1;
+
static int hf_ieee802154_header_ies = -1;
static int hf_ieee802154_header_ie_tlv = -1;
static int hf_ieee802154_header_ie_type = -1;
@@ -725,6 +746,7 @@ static gint ett_ieee802154_p_ie_6top_cell = -1;
static gint ett_ieee802159_mpx = -1;
static gint ett_ieee802159_mpx_transaction_control = -1;
+static expert_field ei_ieee802154_fcs_bitmask_len = EI_INIT;
static expert_field ei_ieee802154_invalid_addressing = EI_INIT;
static expert_field ei_ieee802154_invalid_panid_compression = EI_INIT;
static expert_field ei_ieee802154_invalid_panid_compression2 = EI_INIT;
@@ -1452,7 +1474,7 @@ static void
dissect_ieee802154_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet, guint *offset)
{
guint16 fcf;
- static const int * fields[] = {
+ static const int * ieee802154_fields[] = {
&hf_ieee802154_frame_type,
&hf_ieee802154_security,
&hf_ieee802154_pending,
@@ -1467,21 +1489,72 @@ dissect_ieee802154_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee
NULL
};
+ static const int* ieee802154_mpf_short_fields[] = {
+ &hf_ieee802154_frame_type,
+ &hf_ieee802154_mpf_long_frame_control,
+ &hf_ieee802154_mpf_dst_addr_mode,
+ &hf_ieee802154_mpf_src_addr_mode,
+ NULL
+ };
+
+ static const int* ieee802154_mpf_long_fields[] = {
+ &hf_ieee802154_frame_type,
+ &hf_ieee802154_mpf_long_frame_control,
+ &hf_ieee802154_mpf_dst_addr_mode,
+ &hf_ieee802154_mpf_src_addr_mode,
+ &hf_ieee802154_mpf_pan_id_present,
+ &hf_ieee802154_mpf_security,
+ &hf_ieee802154_mpf_seqno_suppression,
+ &hf_ieee802154_mpf_pending,
+ &hf_ieee802154_mpf_version,
+ &hf_ieee802154_mpf_ack_request,
+ &hf_ieee802154_mpf_ie_present,
+ NULL
+ };
+
/* Get the FCF field. */
fcf = tvb_get_letohs(tvb, *offset);
/* Parse FCF Flags. */
packet->frame_type = (fcf & IEEE802154_FCF_TYPE_MASK);
- packet->security_enable = (fcf & IEEE802154_FCF_SEC_EN) >> 3;
- packet->frame_pending = (fcf & IEEE802154_FCF_FRAME_PND) >> 4;
- packet->ack_request = (fcf & IEEE802154_FCF_ACK_REQ) >> 5;
- packet->pan_id_compression = (fcf & IEEE802154_FCF_PAN_ID_COMPRESSION) >> 6;
- /* bit 7 reserved */
- packet->seqno_suppression = (fcf & IEEE802154_FCF_SEQNO_SUPPRESSION) >> 8;
- packet->ie_present = (fcf & IEEE802154_FCF_IE_PRESENT) >> 9;
- packet->dst_addr_mode = (fcf & IEEE802154_FCF_DADDR_MASK) >> 10;
- packet->version = (fcf & IEEE802154_FCF_VERSION) >> 12;
- packet->src_addr_mode = (fcf & IEEE802154_FCF_SADDR_MASK) >> 14;
+
+ if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) {
+ /* Multipurpose frames use a different 1 or 2 byte FCF */
+ packet->long_frame_control = (fcf & IEEE802154_MPF_FCF_LONG_FC) >> 3;
+ packet->dst_addr_mode = (fcf & IEEE802154_MPF_FCF_DADDR_MASK) >> 4;
+ packet->src_addr_mode = (fcf & IEEE802154_MPF_FCF_SADDR_MASK) >> 6;
+
+ /* The second octet of the FCF is only present if the long frame control bit is set */
+ if (packet->long_frame_control) {
+ packet->security_enable = (fcf & IEEE802154_MPF_FCF_SEC_EN) >> 9;
+ packet->seqno_suppression = (fcf & IEEE802154_MPF_FCF_SEQNO_SUPPRESSION) >> 10;
+ packet->frame_pending = (fcf & IEEE802154_MPF_FCF_FRAME_PND) >> 11;
+ packet->version = (fcf & IEEE802154_MPF_FCF_VERSION) >> 12;
+ packet->ack_request = (fcf & IEEE802154_MPF_FCF_ACK_REQ) >> 14;
+ packet->ie_present = (fcf & IEEE802154_MPF_FCF_IE_PRESENT) >> 15;
+ }
+ else {
+ packet->security_enable = FALSE;
+ packet->seqno_suppression = FALSE;
+ packet->frame_pending = FALSE;
+ packet->version = 0;
+ packet->ack_request = FALSE;
+ packet->ie_present = FALSE;
+ }
+ }
+ else {
+ /* Standard 802.15.4 FCF */
+ packet->security_enable = (fcf & IEEE802154_FCF_SEC_EN) >> 3;
+ packet->frame_pending = (fcf & IEEE802154_FCF_FRAME_PND) >> 4;
+ packet->ack_request = (fcf & IEEE802154_FCF_ACK_REQ) >> 5;
+ packet->pan_id_compression = (fcf & IEEE802154_FCF_PAN_ID_COMPRESSION) >> 6;
+ /* bit 7 reserved */
+ packet->seqno_suppression = (fcf & IEEE802154_FCF_SEQNO_SUPPRESSION) >> 8;
+ packet->ie_present = (fcf & IEEE802154_FCF_IE_PRESENT) >> 9;
+ packet->dst_addr_mode = (fcf & IEEE802154_FCF_DADDR_MASK) >> 10;
+ packet->version = (fcf & IEEE802154_FCF_VERSION) >> 12;
+ packet->src_addr_mode = (fcf & IEEE802154_FCF_SADDR_MASK) >> 14;
+ }
if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_BEACON)) {
proto_item_append_text(tree, " Enhanced Beacon");
@@ -1492,10 +1565,25 @@ dissect_ieee802154_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee
col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved"));
}
- proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf,
- ett_ieee802154_fcf, fields, ENC_LITTLE_ENDIAN);
+ if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) {
+ if (packet->long_frame_control) {
+ proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf,
+ ett_ieee802154_fcf, ieee802154_mpf_long_fields, ENC_LITTLE_ENDIAN);
+ *offset += 2;
+ }
+ else {
+ proto_tree_add_bitmask_len(tree, tvb, *offset, 1, hf_ieee802154_fcf,
+ ett_ieee802154_fcf, ieee802154_mpf_short_fields,
+ &ei_ieee802154_fcs_bitmask_len, ENC_LITTLE_ENDIAN);
+ *offset += 1;
+ }
+ }
+ else {
+ proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf,
+ ett_ieee802154_fcf, ieee802154_fields, ENC_LITTLE_ENDIAN);
+ *offset += 2;
+ }
- *offset += 2;
} /* dissect_ieee802154_fcf */
void register_ieee802154_mac_key_hash_handler(guint hash_identifier, ieee802154_set_key_func key_func)
@@ -2153,7 +2241,7 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
/* Sequence Number */
if (packet->seqno_suppression) {
- if (packet->version != IEEE802154_VERSION_2015) {
+ if (packet->version != IEEE802154_VERSION_2015 && packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) {
expert_add_info(pinfo, proto_root, &ei_ieee802154_seqno_suppression);
}
} else { /* IEEE 802.15.4 Sequence Number Suppression */
@@ -2191,7 +2279,22 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
return 0;
}
- if (packet->version == IEEE802154_VERSION_RESERVED) {
+ if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) {
+ /* Multipurpose frames have a different set of frame versions, with 0 as the only valid version */
+ if (packet->version != 0) {
+ /* Unknown Frame Version for Multipurpose frames. Abort Dissection */
+ expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver);
+ return 0;
+ }
+
+ /* The source PAN ID is always omitted in multipurpose frames */
+ srcPanPresent = FALSE;
+
+ if (packet->pan_id_present) {
+ dstPanPresent = TRUE;
+ }
+ }
+ else if (packet->version == IEEE802154_VERSION_RESERVED) {
/* Unknown Frame Version. Abort Dissection. */
expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver);
return 0;
@@ -2562,7 +2665,7 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
*
*/
/* All of the beacon fields, except the beacon payload are considered nonpayload. */
- if ((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006)) {
+ if (((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006)) && (packet->frame_type != IEEE802154_FCF_MULTIPURPOSE)) {
if (packet->frame_type == IEEE802154_FCF_BEACON) { /* Regular Beacon. Some are not present in frame version (Enhanced) Beacons */
dissect_ieee802154_superframe(tvb, pinfo, ieee802154_tree, &offset); /* superframe spec */
dissect_ieee802154_gtsinfo(tvb, pinfo, ieee802154_tree, &offset); /* GTS information fields */
@@ -5437,21 +5540,62 @@ void proto_register_ieee802154(void)
{ "Information Elements Present", "wpan.ie_present", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_IE_PRESENT,
"Whether this packet contains the Information Elements or not.", HFILL }},
- { &hf_ieee802154_seqno,
- { "Sequence Number", "wpan.seq_no", FT_UINT8, BASE_DEC, NULL, 0x0,
- NULL, HFILL }},
-
{ &hf_ieee802154_dst_addr_mode,
{ "Destination Addressing Mode", "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
IEEE802154_FCF_DADDR_MASK, NULL, HFILL }},
+ { &hf_ieee802154_version,
+ { "Frame Version", "wpan.version", FT_UINT16, BASE_DEC, VALS(ieee802154_frame_versions),
+ IEEE802154_FCF_VERSION, NULL, HFILL }},
+
{ &hf_ieee802154_src_addr_mode,
{ "Source Addressing Mode", "wpan.src_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
IEEE802154_FCF_SADDR_MASK, NULL, HFILL }},
- { &hf_ieee802154_version,
- { "Frame Version", "wpan.version", FT_UINT16, BASE_DEC, VALS(ieee802154_frame_versions),
- IEEE802154_FCF_VERSION, NULL, HFILL }},
+ /* 802.15.4-2015 Multipurpose frame control fields */
+ { &hf_ieee802154_mpf_long_frame_control,
+ { "Long Frame Control", "wpan.long_frame_control", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_LONG_FC,
+ "Whether this frame control field uses one or two octets.", HFILL }},
+
+ { &hf_ieee802154_mpf_dst_addr_mode,
+ { "Destination Addressing Mode", "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
+ IEEE802154_MPF_FCF_DADDR_MASK, NULL, HFILL }},
+
+ { &hf_ieee802154_mpf_src_addr_mode,
+ { "Source Addressing Mode", "wpan.src_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes),
+ IEEE802154_MPF_FCF_SADDR_MASK, NULL, HFILL }},
+
+ { &hf_ieee802154_mpf_pan_id_present,
+ { "PAN ID Present", "wpan.pan_id_present", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_PAN_ID_PRESENT,
+ "Whether this packet contains the destination PAN ID or not", HFILL }},
+
+ { &hf_ieee802154_mpf_security,
+ { "Security Enabled", "wpan.security", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_SEC_EN,
+ "Whether security operations are performed at the MAC layer or not.", HFILL }},
+
+ { &hf_ieee802154_mpf_seqno_suppression,
+ { "Sequence Number Suppression", "wpan.seqno_suppression", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_SEQNO_SUPPRESSION,
+ "Whether this packet contains the Sequence Number or not.", HFILL }},
+
+ { &hf_ieee802154_mpf_pending,
+ { "Frame Pending", "wpan.pending", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_FRAME_PND,
+ "Indication of additional packets waiting to be transferred from the source device.", HFILL }},
+
+ { &hf_ieee802154_mpf_version,
+ { "Multipurpose Frame Version", "wpan.mpf_version", FT_UINT16, BASE_DEC, NULL,
+ IEEE802154_MPF_FCF_VERSION, NULL, HFILL }},
+
+ { &hf_ieee802154_mpf_ack_request,
+ { "Acknowledge Request", "wpan.ack_request", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_ACK_REQ,
+ "Whether the sender of this packet requests acknowledgment or not.", HFILL }},
+
+ { &hf_ieee802154_mpf_ie_present,
+ { "Information Elements Present", "wpan.ie_present", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_IE_PRESENT,
+ "Whether this packet contains the Information Elements or not.", HFILL }},
+
+ { &hf_ieee802154_seqno,
+ { "Sequence Number", "wpan.seq_no", FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
{ &hf_ieee802154_dst_panID,
{ "Destination PAN", "wpan.dst_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
@@ -6436,6 +6580,8 @@ void proto_register_ieee802154(void)
};
static ei_register_info ei[] = {
+ { &ei_ieee802154_fcs_bitmask_len, { "wpan.bitmask_len_error", PI_UNDECODED, PI_WARN,
+ "Only least-significant bytes decoded", EXPFILL }},
{ &ei_ieee802154_invalid_addressing, { "wpan.invalid_addressing", PI_MALFORMED, PI_WARN,
"Invalid Addressing", EXPFILL }},
{ &ei_ieee802154_invalid_panid_compression, { "wpan.invalid_panid_compression", PI_MALFORMED, PI_ERROR,