aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-zbee-aps.c
diff options
context:
space:
mode:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>2010-10-26 05:42:24 +0000
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>2010-10-26 05:42:24 +0000
commit683fee3d17a891f2b42f1529c1e9890afb054db0 (patch)
treecf0b7371cfeaf8b1326cd86baf39beba169b5efa /epan/dissectors/packet-zbee-aps.c
parent54bf60fadc63e8d6b7b176617ab54e66acc89ad7 (diff)
From Fred Fierling:
Multi-key Support and Extended Address Mapping for ZigBee Dissectors https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5331 git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@34647 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-zbee-aps.c')
-rw-r--r--epan/dissectors/packet-zbee-aps.c140
1 files changed, 89 insertions, 51 deletions
diff --git a/epan/dissectors/packet-zbee-aps.c b/epan/dissectors/packet-zbee-aps.c
index e56dc2f94f..48771a7030 100644
--- a/epan/dissectors/packet-zbee-aps.c
+++ b/epan/dissectors/packet-zbee-aps.c
@@ -39,9 +39,9 @@
#include <epan/reassemble.h>
#include "packet-zbee.h"
+#include "packet-zbee-nwk.h"
#include "packet-zbee-security.h"
#include "packet-zbee-aps.h"
-#include "packet-zbee-nwk.h"
/*************************
* Function Declarations *
@@ -67,6 +67,10 @@ static guint dissect_zbee_aps_tunnel (tvbuff_t *tvb, packet_info *pinf
/* Helper routine. */
static guint zbee_apf_transaction_len (tvbuff_t *tvb, guint offset, guint8 type);
+static void proto_init_zbee_aps(void);
+void proto_reg_handoff_zbee_aps(void);
+void proto_register_zbee_aps(void);
+
/********************
* Global Variables *
********************
@@ -76,7 +80,7 @@ static int proto_zbee_aps = -1;
static int hf_zbee_aps_fcf_frame_type = -1;
static int hf_zbee_aps_fcf_delivery = -1;
static int hf_zbee_aps_fcf_indirect_mode = -1; /* ZigBee 2004 and earlier. */
-static int hf_zbee_aps_fcf_ack_mode = -1; /* ZigBee 2007 and later. */
+static int hf_zbee_aps_fcf_ack_format = -1; /* ZigBee 2007 and later. */
static int hf_zbee_aps_fcf_security = -1;
static int hf_zbee_aps_fcf_ack_req = -1;
static int hf_zbee_aps_fcf_ext_header = -1;
@@ -165,6 +169,7 @@ static const fragment_items zbee_aps_frag_items = {
/* Tag */
"APS Message fragments"
};
+
/********************/
/* Field Names */
/********************/
@@ -538,7 +543,7 @@ const value_string zbee_aps_cid_names[] = {
* ZigBee Application Support Sublayer dissector for wireshark.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
- * packet_into *pinfo - pointer to packet information fields
+ * packet_info *pinfo - pointer to packet information fields
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* RETURNS
* void
@@ -556,7 +561,7 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_item *ti;
zbee_aps_packet packet;
- zbee_nwk_packet *nwk = pinfo->private_data;
+ zbee_nwk_packet *nwk = (zbee_nwk_packet *)pinfo->private_data;
guint8 fcf;
guint8 offset = 0;
@@ -577,7 +582,7 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
packet.type = zbee_get_bit_field(fcf, ZBEE_APS_FCF_FRAME_TYPE);
packet.delivery = zbee_get_bit_field(fcf, ZBEE_APS_FCF_DELIVERY_MODE);
packet.indirect_mode = zbee_get_bit_field(fcf, ZBEE_APS_FCF_INDIRECT_MODE);
- packet.ack_mode = zbee_get_bit_field(fcf, ZBEE_APS_FCF_ACK_MODE);
+ packet.ack_format = zbee_get_bit_field(fcf, ZBEE_APS_FCF_ACK_FORMAT);
packet.security = zbee_get_bit_field(fcf, ZBEE_APS_FCF_SECURITY);
packet.ack_req = zbee_get_bit_field(fcf, ZBEE_APS_FCF_ACK_REQ);
packet.ext_header = zbee_get_bit_field(fcf, ZBEE_APS_FCF_EXT_HEADER);
@@ -603,13 +608,15 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
/* ZigBee 2007 and later uses an ack mode flag. */
if (packet.type == ZBEE_APS_FCF_ACK) {
- proto_tree_add_boolean(field_tree, hf_zbee_aps_fcf_ack_mode, tvb, offset, 1, fcf & ZBEE_APS_FCF_ACK_MODE);
+ proto_tree_add_boolean(field_tree, hf_zbee_aps_fcf_ack_format, tvb, offset, 1,
+ fcf & ZBEE_APS_FCF_ACK_FORMAT);
}
}
else {
/* ZigBee 2004, uses indirect mode. */
if (packet.delivery == ZBEE_APS_FCF_INDIRECT) {
- proto_tree_add_boolean(field_tree, hf_zbee_aps_fcf_indirect_mode, tvb, offset, 1, fcf & ZBEE_APS_FCF_INDIRECT_MODE);
+ proto_tree_add_boolean(field_tree, hf_zbee_aps_fcf_indirect_mode, tvb, offset, 1,
+ fcf & ZBEE_APS_FCF_INDIRECT_MODE);
}
}
@@ -627,7 +634,7 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
case ZBEE_APS_FCF_ACK:
- if ((pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) && (packet.ack_mode)) {
+ if ((pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) && (packet.ack_format)) {
/* Command Ack: endpoint addressing does not exist. */
goto dissect_zbee_aps_no_endpt;
}
@@ -719,7 +726,7 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += 1;
}
- /* Get and display the profile ID if it exists. */
+ /* Get and display the profile ID. */
packet.profile = tvb_get_letohs(tvb, offset);
profile_handle = dissector_get_port_handle(zbee_aps_dissector_table, packet.profile);
if (tree) {
@@ -729,7 +736,8 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Update the protocol root and info column later, after the source endpoint
* so that the source and destination will be back-to-back in the text.
*/
- }
+ }
+ offset += sizeof(guint16);
/* The source endpoint is present for all cases except indirect /w indirect_mode == FALSE */
if ((packet.delivery != ZBEE_APS_FCF_INDIRECT) || (!packet.indirect_mode)) {
@@ -762,7 +770,6 @@ dissect_zbee_aps_no_endpt:
offset += 1;
}
-
/* Get and display the extended header, if present. */
if (packet.ext_header) {
fcf = tvb_get_guint8(tvb, offset);
@@ -813,7 +820,7 @@ dissect_zbee_aps_no_endpt:
/* If a payload is present, and security is enabled, decrypt the payload. */
if ((offset < tvb_length(tvb)) && packet.security) {
- payload_tvb = dissect_zbee_secure(tvb, pinfo, aps_tree, offset, 0);
+ payload_tvb = dissect_zbee_secure(tvb, pinfo, aps_tree, offset);
if (payload_tvb == NULL) {
/* If Payload_tvb is NULL, then the security dissector cleaned up. */
return;
@@ -1142,9 +1149,12 @@ dissect_zbee_aps_skke_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
static guint
dissect_zbee_aps_transport_key(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
{
- guint8 key_type;
- gchar *key = ep_alloc(ZBEE_APS_CMD_KEY_LENGTH);
- guint i;
+ guint8 key_type;
+ guint8 key[ZBEE_APS_CMD_KEY_LENGTH];
+ GSList **nwk_keyring;
+ key_record_t key_record;
+ zbee_nwk_hints_t *nwk_hints;
+ guint i;
/* Get and display the key type. */
key_type = tvb_get_guint8(tvb, offset);
@@ -1156,21 +1166,47 @@ dissect_zbee_aps_transport_key(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
/* Coincidentally, all the key descriptors start with the key. So
* get and display it.
*/
- for (i=0;i<ZBEE_APS_CMD_KEY_LENGTH; i++) {
- /* Copy the key in while swapping because the key is transmitted in little-endian
- * order, but we want to display it in big-endian.
- */
- key[(ZBEE_APS_CMD_KEY_LENGTH-1)-i] = tvb_get_guint8(tvb, offset+i);
+ for (i=0; i<ZBEE_APS_CMD_KEY_LENGTH ; i++) {
+ key[i] = tvb_get_guint8(tvb, offset+i);
} /* for */
if (tree) {
proto_tree_add_item(tree, hf_zbee_aps_cmd_key, tvb, offset, ZBEE_APS_CMD_KEY_LENGTH, ENC_BIG_ENDIAN);
}
offset += ZBEE_APS_CMD_KEY_LENGTH;
+
+ /* Update the key ring for this pan */
+ if ( !pinfo->fd->flags.visited &&
+ (nwk_hints = (zbee_nwk_hints_t *)p_get_proto_data(pinfo->fd,
+ proto_get_id_by_filter_name(ZBEE_PROTOABBREV_NWK)))) {
+
+ nwk_keyring = (GSList **)g_hash_table_lookup(zbee_table_nwk_keyring, &nwk_hints->src_pan);
+ if ( !nwk_keyring ) {
+ /* Create an empty key ring for this pan. Use g_alloc() because we must free
+ * GSLists after a capture is closed and wireshark freed seasonal memory
+ * with se_free_all()
+ */
+ nwk_keyring = (GSList **)g_malloc0(sizeof(GSList**));
+ g_hash_table_insert(zbee_table_nwk_keyring,
+ g_memdup(&nwk_hints->src_pan, sizeof(nwk_hints->src_pan)), nwk_keyring);
+ }
+
+ if ( nwk_keyring ) {
+ if ( !*nwk_keyring ||
+ memcmp( ((key_record_t *)((GSList *)(*nwk_keyring))->data)->key, &key,
+ ZBEE_APS_CMD_KEY_LENGTH) ) {
+ /* Store a new or different key in the key ring */
+ key_record.frame_num = pinfo->fd->num;
+ key_record.label = NULL;
+ memcpy(&key_record.key, &key, ZBEE_APS_CMD_KEY_LENGTH);
+ *nwk_keyring = g_slist_prepend(*nwk_keyring, se_memdup(&key_record, sizeof(key_record_t)));
+ }
+ }
+ }
/* Parse the rest of the key descriptor. */
switch (key_type) {
case ZBEE_APS_CMD_KEY_STANDARD_NWK:
- case ZBEE_APS_CMD_KEY_HIGH_SEC_NWK:{
+ case ZBEE_APS_CMD_KEY_HIGH_SEC_NWK: {
/* Network Key */
guint8 seqno;
guint64 src;
@@ -1227,7 +1263,7 @@ dissect_zbee_aps_transport_key(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
guint64 partner;
guint8 initiator;
- /* get and display the parter address. */
+ /* get and display the partner address. */
partner = tvb_get_letoh64(tvb, offset);
if (tree) {
proto_tree_add_eui64(tree, hf_zbee_aps_cmd_partner, tvb, offset, sizeof(guint64), partner);
@@ -1540,7 +1576,8 @@ dissect_zbee_aps_tunnel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gui
offset += sizeof(guint64);
/* The remainder is a tunneled APS frame. */
- tunnel_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_reported_length_remaining(tvb, offset));
+ tunnel_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset),
+ tvb_reported_length_remaining(tvb, offset));
if (tree) root = proto_tree_get_root(tree);
call_dissector(zbee_aps_handle, tunnel_tvb, pinfo, root);
offset = tvb_length(tvb);
@@ -1576,11 +1613,12 @@ static void dissect_zbee_apf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
tvbuff_t *app_tvb;
- dissector_handle_t app_dissector = (pinfo->private_data);
+ dissector_handle_t app_dissector = (dissector_handle_t)(pinfo->private_data);
/* Create the tree for the application framework. */
if (tree) {
- proto_root = proto_tree_add_protocol_format(tree, proto_zbee_apf, tvb, 0, tvb_length(tvb), "ZigBee Application Framework");
+ proto_root = proto_tree_add_protocol_format(tree, proto_zbee_apf, tvb, 0,
+ tvb_length(tvb), "ZigBee Application Framework");
apf_tree = proto_item_add_subtree(proto_root, ett_zbee_apf);
}
@@ -1714,24 +1752,6 @@ zbee_apf_transaction_len(tvbuff_t *tvb, guint offset, guint8 type)
/*FUNCTION:------------------------------------------------------
* NAME
- * proto_init_zbee_aps
- * DESCRIPTION
- * Initializes the APS dissectors prior to beginning protocol
- * dissection.
- * PARAMETERS
- * none
- * RETURNS
- * void
- *---------------------------------------------------------------
- */
-static void proto_init_zbee_aps(void)
-{
- fragment_table_init(&zbee_aps_fragment_table);
- reassembled_table_init(&zbee_aps_reassembled_table);
-} /* proto_init_zbee_aps */
-
-/*FUNCTION:------------------------------------------------------
- * NAME
* proto_register_zbee_aps
* DESCRIPTION
* ZigBee APS protocol registration routine.
@@ -1756,8 +1776,8 @@ void proto_register_zbee_aps(void)
{ "Indirect Address Mode", "zbee.aps.indirect_mode", FT_BOOLEAN, 8, NULL, ZBEE_APS_FCF_INDIRECT_MODE,
NULL, HFILL }},
- { &hf_zbee_aps_fcf_ack_mode,
- { "Acknowledgement Mode", "zbee.aps.ack_mode", FT_BOOLEAN, 8, NULL, ZBEE_APS_FCF_ACK_MODE,
+ { &hf_zbee_aps_fcf_ack_format,
+ { "Acknowledgement Format", "zbee.aps.ack_format", FT_BOOLEAN, 8, NULL, ZBEE_APS_FCF_ACK_FORMAT,
NULL, HFILL }},
{ &hf_zbee_aps_fcf_security,
@@ -1936,24 +1956,24 @@ void proto_register_zbee_aps(void)
};
/* Register ZigBee APS protocol with Wireshark. */
- proto_zbee_aps = proto_register_protocol("ZigBee Application Support Layer", "ZigBee APS", "zbee.aps");
+ proto_zbee_aps = proto_register_protocol("ZigBee Application Support Layer", "ZigBee APS", ZBEE_PROTOABBREV_APS);
proto_register_field_array(proto_zbee_aps, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/* Register the APS dissector and subdissector list. */
zbee_aps_dissector_table = register_dissector_table("zbee.profile", "ZigBee Profile ID", FT_UINT16, BASE_HEX);
- register_dissector("zbee.aps", dissect_zbee_aps, proto_zbee_aps);
+ register_dissector(ZBEE_PROTOABBREV_APS, dissect_zbee_aps, proto_zbee_aps);
/* Register the init routine. */
register_init_routine(proto_init_zbee_aps);
/* Register the ZigBee Application Framework protocol with Wireshark. */
- proto_zbee_apf = proto_register_protocol("ZigBee Application Framework", "ZigBee APF", "zbee.apf");
+ proto_zbee_apf = proto_register_protocol("ZigBee Application Framework", "ZigBee APF", ZBEE_PROTOABBREV_APF);
proto_register_field_array(proto_zbee_apf, hf_apf, array_length(hf_apf));
proto_register_subtree_array(ett_apf, array_length(ett_apf));
/* Register the App dissector. */
- register_dissector("zbee.apf", dissect_zbee_apf, proto_zbee_apf);
+ register_dissector(ZBEE_PROTOABBREV_APF, dissect_zbee_apf, proto_zbee_apf);
} /* proto_register_zbee_aps */
/*FUNCTION:------------------------------------------------------
@@ -1971,7 +1991,25 @@ void proto_reg_handoff_zbee_aps(void)
{
/* Find the other dissectors we need. */
data_handle = find_dissector("data");
- zbee_aps_handle = find_dissector("zbee.aps");
- zbee_apf_handle = find_dissector("zbee.apf");
+ zbee_aps_handle = find_dissector(ZBEE_PROTOABBREV_APS);
+ zbee_apf_handle = find_dissector(ZBEE_PROTOABBREV_APF);
} /* proto_reg_handoff_zbee_aps */
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_init_zbee_aps
+ * DESCRIPTION
+ * Initializes the APS dissectors prior to beginning protocol
+ * dissection.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+static void proto_init_zbee_aps(void)
+{
+ fragment_table_init(&zbee_aps_fragment_table);
+ reassembled_table_init(&zbee_aps_reassembled_table);
+} /* proto_init_zbee_aps */
+