summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-ieee802154.c204
-rw-r--r--epan/dissectors/packet-ieee802154.h21
2 files changed, 213 insertions, 12 deletions
diff --git a/epan/dissectors/packet-ieee802154.c b/epan/dissectors/packet-ieee802154.c
index c14181f6e7..e7026ac5f0 100644
--- a/epan/dissectors/packet-ieee802154.c
+++ b/epan/dissectors/packet-ieee802154.c
@@ -173,6 +173,9 @@ static void dissect_ieee802154_common (tvbuff_t *, packet_info *, proto_tr
static void dissect_ieee802154_header_ie (tvbuff_t *, packet_info *, proto_tree *, guint *, ieee802154_packet *);
static void dissect_ieee802154_payload_mlme_sub_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset);
static void dissect_ieee802154_payload_ie (tvbuff_t *, packet_info *, proto_tree *, guint *);
+static void dissect_ieee802154_vendor_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset, guint pie_remaining, guint32 vendor_oui);
+static void dissect_ieee802154_zigbee_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset, guint pie_remaining);
+static void dissect_ieee802154_zigbee_rejoin(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset);
/* Sub-dissector helpers. */
static void dissect_ieee802154_fcf (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *, guint *);
@@ -237,6 +240,15 @@ static int hf_ieee802154_payload_ie_length = -1;
static int hf_ieee802154_payload_ie_data = -1;
static int hf_ieee802154_payload_ie_vendor_oui = -1;
static int hf_ieee802154_mlme_ie_data = -1;
+static int hf_ieee802154_vendor_ie_data = -1;
+static int hf_ieee802154_zigbee_ie = -1;
+static int hf_ieee802154_zigbee_ie_id = -1;
+static int hf_ieee802154_zigbee_ie_length = -1;
+static int hf_ieee802154_zigbee_ie_data = -1;
+static int hf_ieee802154_zigbee_ie_tx_power = -1;
+static int hf_ieee802154_zigbee_ie_source_addr = -1;
+static int hf_ieee802154_zigbee_rejoin_epid = -1;
+static int hf_ieee802154_zigbee_rejoin_source_addr = -1;
static int hf_ieee802154_psie_short = -1;
static int hf_ieee802154_psie_type_short = -1;
static int hf_ieee802154_psie_id_short = -1;
@@ -344,6 +356,9 @@ static gint ett_ieee802154_psie_long = -1;
static gint ett_ieee802154_psie_long_bitmap = -1;
static gint ett_ieee802154_psie_enh_beacon_flt = -1;
static gint ett_ieee802154_psie_enh_beacon_flt_bitmap = -1;
+static gint ett_ieee802154_zigbee = -1;
+static gint ett_ieee802154_zigbee_ie = -1;
+static gint ett_ieee802154_zigbee_beacon = -1;
static gint ett_ieee802154_zboss = -1;
static expert_field ei_ieee802154_invalid_addressing = EI_INIT;
@@ -369,6 +384,9 @@ static dissector_table_t panid_dissector_table;
static heur_dissector_list_t ieee802154_beacon_subdissector_list;
static heur_dissector_list_t ieee802154_heur_subdissector_list;
+static dissector_handle_t zigbee_beacon_handle;
+
+
/* Versions */
static const value_string ieee802154_frame_versions[] = {
{ IEEE802154_VERSION_2003, "IEEE Std 802.15.4-2003" },
@@ -508,6 +526,13 @@ static const value_string ieee802154_vendor_oui_names[] = {
{ 0, NULL }
};
+static const value_string ieee802154_zigbee_ie_names[] = {
+ { IEEE802154_ZIGBEE_IE_REJOIN, "ReJoin" },
+ { IEEE802154_ZIGBEE_IE_TX_POWER, "Tx Power" },
+ { IEEE802154_ZIGBEE_IE_BEACON_PAYLOAD, "Extended Beacon Payload" },
+ { 0, NULL }
+};
+
static const value_string ieee802154_psie_names[] = {
{ IEEE802154_MLME_SUBIE_TSCH_SYNCH, "TSCH Synchronization IE" },
{ IEEE802154_MLME_SUBIE_TSCH_SLOTFR_LINK, "TSCH Slotframe and Link IE" },
@@ -942,8 +967,8 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
/* only either the destination or the source addressing information is present */
if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) { /* Not Present */
- dstPanPresent = TRUE;
- srcPanPresent = FALSE;
+ dstPanPresent = TRUE;
+ srcPanPresent = FALSE;
}
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) { /* Present */
@@ -1114,7 +1139,9 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
/* Destination PAN Id */
if (dstPanPresent) {
packet->dst_pan = tvb_get_letohs(tvb, offset);
- proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_panID, tvb, offset, 2, packet->dst_pan);
+ if (ieee802154_tree) {
+ proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_panID, tvb, offset, 2, packet->dst_pan);
+ }
offset += 2;
}
@@ -1940,6 +1967,135 @@ dissect_ieee802154_payload_mlme_sub_ie(tvbuff_t *tvb, packet_info *pinfo _U_, pr
}
/**
+ *Subdissector for the ZigBee specific rejoin information
+ *
+ *@param tvb pointer to buffer containing raw packet.
+ *@param pinfo pointer to packet information fields (unused).
+ *@param tree pointer to command subtree.
+ *@param offset offset into the tvbuff to begin dissection.
+*/
+static void
+dissect_ieee802154_zigbee_rejoin(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
+{
+ proto_tree *subtree;
+
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1, ett_ieee802154_zigbee_beacon, NULL, "ZigBee Rejoin");
+
+ proto_tree_add_item(subtree, hf_ieee802154_zigbee_rejoin_epid, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
+ *offset += 8;
+
+ proto_tree_add_item(subtree, hf_ieee802154_zigbee_rejoin_source_addr, tvb, *offset, 2, ENC_NA);
+ *offset += 2;
+
+} /* dissect_ieee802154_zigbee_rejoin */
+
+/**
+ *Subdissector command for ZigBee Specific IEs (Information Elements)
+ *
+ *@param tvb pointer to buffer containing raw packet.
+ *@param pinfo pointer to packet information fields (unused).
+ *@param tree pointer to command subtree.
+ *@param offset offset into the tvbuff to begin dissection.
+ *@param pie_remaining remaining payload IE bytes
+*/
+static void
+dissect_ieee802154_zigbee_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset, guint pie_remaining)
+{
+ proto_tree *subtree;
+ guint16 zigbee_ie;
+ guint16 id;
+ guint16 length;
+ guint remaining;
+
+ static const int * fields[] = {
+ &hf_ieee802154_zigbee_ie_id,
+ &hf_ieee802154_zigbee_ie_length,
+ NULL
+ };
+
+ for (remaining = pie_remaining; remaining > 0; ) {
+ zigbee_ie = tvb_get_letohs(tvb, *offset);
+ id = (zigbee_ie & IEEE802154_ZIGBEE_IE_ID_MASK) >> 6;
+ length = zigbee_ie & IEEE802154_ZIGBEE_IE_LENGTH_MASK;
+
+ /* Create a subtree for this command frame. */
+ subtree = proto_tree_add_subtree(tree, tvb, *offset, 1, ett_ieee802154_header, NULL, "ZigBee IE");
+ proto_item_append_text(subtree, ", %s, Length: %d", val_to_str_const(id, ieee802154_zigbee_ie_names, "Unknown IE"), length);
+
+ proto_tree_add_bitmask(subtree, tvb, *offset, hf_ieee802154_zigbee_ie,
+ ett_ieee802154_zigbee_ie, fields, ENC_LITTLE_ENDIAN);
+
+ *offset += 2;
+ remaining -= 2;
+
+ switch (id) {
+ case IEEE802154_ZIGBEE_IE_REJOIN:
+ dissect_ieee802154_zigbee_rejoin(tvb, pinfo, subtree, offset);
+ remaining -= 10;
+ break;
+
+ case IEEE802154_ZIGBEE_IE_TX_POWER:
+ proto_tree_add_item(subtree, hf_ieee802154_zigbee_ie_tx_power, tvb, *offset, 1, ENC_NA);
+ *offset += 1;
+ remaining -= 1;
+ break;
+
+ case IEEE802154_ZIGBEE_IE_BEACON_PAYLOAD:
+ /* should start with a Legacy ZigBee Beacon */
+ *offset += call_dissector(zigbee_beacon_handle, tvb_new_subset_remaining(tvb, *offset), pinfo, subtree);
+ remaining -= 15;
+
+ /* followed by a Superframe Specification */
+ dissect_ieee802154_superframe(tvb, pinfo, subtree, offset);
+ remaining -= 2;
+
+ /* finally the Short Address of the sending device */
+ proto_tree_add_item(subtree, hf_ieee802154_zigbee_ie_source_addr, tvb, *offset, 2, ENC_NA);
+ *offset += 2;
+ remaining -= 2;
+ break;
+
+ default:
+ if (length > 0) { /* just use the data dissector */
+ proto_tree_add_item(tree, hf_ieee802154_zigbee_ie_data, tvb, *offset, length, ENC_NA);
+ *offset += length;
+ remaining -= length;
+ }
+ break;
+ }
+ }
+}
+
+/**
+ *Subdissector command for Vendor Specific IEs (Information Elements)
+ *
+ *@param tvb pointer to buffer containing raw packet.
+ *@param pinfo pointer to packet information fields (unused).
+ *@param tree pointer to command subtree.
+ *@param offset offset into the tvbuff to begin dissection.
+ *@param pie_remaining remaining payload IE bytes
+ *@param vendor_oui the vendor OUI
+*/
+static void
+dissect_ieee802154_vendor_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset, guint pie_remaining, guint32 vendor_oui)
+{
+
+ switch (vendor_oui) {
+
+ case IEEE802154_VENDOR_OUI_ZIGBEE:
+ dissect_ieee802154_zigbee_ie(tvb, pinfo, tree, offset, pie_remaining);
+ break;
+
+ default:
+ if (pie_remaining > 0) { /* just use the data dissector */
+ proto_tree_add_item(tree, hf_ieee802154_vendor_ie_data, tvb, *offset, pie_remaining, ENC_NA);
+ *offset += pie_remaining;
+ }
+ break;
+ }
+}
+
+/**
*Subdissector command for Payload IEs (Information Elements)
*
*@param tvb pointer to buffer containing raw packet.
@@ -1956,7 +2112,6 @@ dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
guint pie_remaining;
guint pie_offset_end;
guint32 vendor_oui;
- GByteArray *gba = g_byte_array_new();
static const int * fields[] = {
&hf_ieee802154_payload_ie_type,
@@ -1994,15 +2149,12 @@ dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
proto_tree_add_uint(subtree, hf_ieee802154_payload_ie_vendor_oui, tvb, *offset, 3, vendor_oui);
*offset += 3;
pie_remaining -= 3;
- if (pie_remaining > 0) { /* just use the data dissector */
- proto_tree_add_bytes_item(subtree, hf_ieee802154_payload_ie_data, tvb, *offset, pie_remaining, ENC_NA, gba, NULL, NULL);
- *offset += pie_remaining;
- }
+ dissect_ieee802154_vendor_ie(tvb, pinfo, subtree, offset, pie_remaining, vendor_oui);
break;
default: /* just use the data dissector */
if (pie_remaining > 0) {
- proto_tree_add_bytes_item(subtree, hf_ieee802154_payload_ie_data, tvb, *offset, pie_remaining, ENC_NA, gba, NULL, NULL);
+ proto_tree_add_item(subtree, hf_ieee802154_payload_ie_data, tvb, *offset, pie_remaining, ENC_NA);
*offset += pie_remaining;
}
}
@@ -3223,6 +3375,36 @@ void proto_register_ieee802154(void)
{ &hf_ieee802154_mlme_ie_data,
{ "Data", "wpan.mlme_sub_ie.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_ieee802154_vendor_ie_data,
+ { "Data", "wpan.vendor_ie.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_ieee802154_zigbee_ie,
+ { "ZigBee IE", "wpan.zigbee_ie", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_ieee802154_zigbee_ie_id,
+ { "Id", "wpan.zigbee_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_zigbee_ie_names),
+ IEEE802154_ZIGBEE_IE_ID_MASK, NULL, HFILL }},
+
+ { &hf_ieee802154_zigbee_ie_length,
+ { "Length", "wpan.zigbee_ie.length", FT_UINT16, BASE_DEC, NULL,
+ IEEE802154_ZIGBEE_IE_LENGTH_MASK, NULL, HFILL }},
+
+ { &hf_ieee802154_zigbee_ie_data,
+ { "Data", "wpan.zigbee_ie.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_ieee802154_zigbee_ie_tx_power,
+ { "Tx Power (dBm)", "wpan.zigbee_ie.tx_power", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_ieee802154_zigbee_ie_source_addr,
+ { "Source Address", "wpan.zigbee_ie.source_address", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_ieee802154_zigbee_rejoin_epid,
+ { "Extended PAN ID", "wpan.zigbee_rejoin.ext_panid", FT_EUI64, BASE_NONE, NULL, 0x0,
+ "Extended PAN identifier", HFILL }},
+
+ { &hf_ieee802154_zigbee_rejoin_source_addr,
+ { "Source Address", "wpan.zigbee_rejoin.source_address", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
/*
* Command Frame Specific Fields
*/
@@ -3436,6 +3618,9 @@ void proto_register_ieee802154(void)
&ett_ieee802154_psie_long_bitmap,
&ett_ieee802154_psie_enh_beacon_flt,
&ett_ieee802154_psie_enh_beacon_flt_bitmap,
+ &ett_ieee802154_zigbee,
+ &ett_ieee802154_zigbee_ie,
+ &ett_ieee802154_zigbee_beacon,
&ett_ieee802154_zboss,
};
@@ -3599,6 +3784,7 @@ void proto_reg_handoff_ieee802154(void)
ieee802154_handle = find_dissector(IEEE802154_PROTOABBREV_WPAN);
ieee802154_nonask_phy_handle = find_dissector("wpan-nonask-phy");
ieee802154_nofcs_handle = find_dissector("wpan_nofcs");
+ zigbee_beacon_handle = find_dissector_add_dependency("zbee_beacon", proto_ieee802154);
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4, ieee802154_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_NONASK_PHY, ieee802154_nonask_phy_handle);
diff --git a/epan/dissectors/packet-ieee802154.h b/epan/dissectors/packet-ieee802154.h
index 5ab2334b15..1f2a1e9ad2 100644
--- a/epan/dissectors/packet-ieee802154.h
+++ b/epan/dissectors/packet-ieee802154.h
@@ -172,6 +172,24 @@
#define IEEE802154_MLME_PSIE_EB_FLT_PERCENT 0x04
#define IEEE802154_MLME_PSIE_EB_FLT_ATTR_LEN 0x18
+/* Vendor OUIs */
+#define IEEE802154_VENDOR_OUI_ZIGBEE 0x4A191B
+
+/* ZigBee Vendor Sub IE Fields */
+#define IEEE802154_ZIGBEE_IE_ID_MASK 0xFFC0
+#define IEEE802154_ZIGBEE_IE_LENGTH_MASK 0x003F
+#define IEEE802154_ZIGBEE_IE_REJOIN 0x00
+#define IEEE802154_ZIGBEE_IE_TX_POWER 0x01
+#define IEEE802154_ZIGBEE_IE_BEACON_PAYLOAD 0x02
+
+/* ZigBee PRO beacons */
+#define IEEE802154_ZIGBEE_BEACON_PROTOCOL_ID 0x00
+#define IEEE802154_ZIGBEE_BEACON_STACK_PROFILE 0x0f
+#define IEEE802154_ZIGBEE_BEACON_PROTOCOL_VERSION 0xf0
+#define IEEE802154_ZIGBEE_BEACON_ROUTER_CAPACITY 0x04
+#define IEEE802154_ZIGBEE_BEACON_NETWORK_DEPTH 0x78
+#define IEEE802154_ZIGBEE_BEACON_END_DEVICE_CAPACITY 0x80
+
/* Bit-masks for CC24xx style FCS */
#define IEEE802154_CC24xx_CORRELATION 0x7F00
#define IEEE802154_CC24xx_CRC_OK 0x8000
@@ -241,9 +259,6 @@ typedef enum {
/* Reserved 0x3-0xe */
#define IEEE802154_PAYLOAD_IE_GID_TERM 0xf
-/* Vendor OUIs */
-#define IEEE802154_VENDOR_OUI_ZIGBEE 0xacde48
-
/* Payload IE (Nested) Sub ID */
/* 0x00 - 0x0f Reserved for Long Format */
/* 0x10 - 0x19 Short Format Reserved */