aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2010-10-24 15:22:44 +0000
committerAnders Broman <anders.broman@ericsson.com>2010-10-24 15:22:44 +0000
commitb1e852cf709bb12a9c9ab7ab644ad44f4ad0d6ef (patch)
tree832c465309fc75ee99488fba577f28b775f18dcb /epan
parent2ccfd848fe511fb8315d6049b9b11cf224cd13d3 (diff)
Back out 34627 and friends again.
svn path=/trunk/; revision=34633
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-6lowpan.c8
-rw-r--r--epan/dissectors/packet-ieee802154.c594
-rw-r--r--epan/dissectors/packet-ieee802154.h61
-rw-r--r--epan/dissectors/packet-zbee-aps.c145
-rw-r--r--epan/dissectors/packet-zbee-aps.h58
-rw-r--r--epan/dissectors/packet-zbee-nwk.c427
-rw-r--r--epan/dissectors/packet-zbee-nwk.h32
-rw-r--r--epan/dissectors/packet-zbee-security.c715
-rw-r--r--epan/dissectors/packet-zbee-security.h12
-rw-r--r--epan/dissectors/packet-zbee.h10
10 files changed, 689 insertions, 1373 deletions
diff --git a/epan/dissectors/packet-6lowpan.c b/epan/dissectors/packet-6lowpan.c
index 7cd4054bdb..f2525b0e3b 100644
--- a/epan/dissectors/packet-6lowpan.c
+++ b/epan/dissectors/packet-6lowpan.c
@@ -516,14 +516,14 @@ lowpan_dlsrc_to_ifcid(packet_info *pinfo, guint8 *ifcid)
/* Derive the IID from the IEEE 802.15.4 packet structure. */
if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
guint64 addr;
- addr = pntoh64(&packet->src64);
+ addr = pntoh64(&packet->src.addr64);
memcpy(ifcid, &addr, LOWPAN_IFC_ID_LEN);
/* RFC2464: Invert the U/L bit when using an EUI64 address. */
ifcid[0] ^= 0x02;
return TRUE;
}
if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
- lowpan_addr16_to_ifcid(packet->src16, ifcid);
+ lowpan_addr16_to_ifcid(packet->src.addr16, ifcid);
return TRUE;
}
@@ -561,14 +561,14 @@ lowpan_dldst_to_ifcid(packet_info *pinfo, guint8 *ifcid)
/* Derive the IID from the IEEE 802.15.4 packet structure. */
if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
guint64 addr;
- addr = pntoh64(&packet->dst64);
+ addr = pntoh64(&packet->dst.addr64);
memcpy(ifcid, &addr, LOWPAN_IFC_ID_LEN);
/* RFC2464: Invert the U/L bit when using an EUI64 address. */
ifcid[0] ^= 0x02;
return TRUE;
}
if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
- lowpan_addr16_to_ifcid(packet->dst16, ifcid);
+ lowpan_addr16_to_ifcid(packet->dst.addr16, ifcid);
return TRUE;
}
diff --git a/epan/dissectors/packet-ieee802154.c b/epan/dissectors/packet-ieee802154.c
index 8a1d4f87e8..9d230807bd 100644
--- a/epan/dissectors/packet-ieee802154.c
+++ b/epan/dissectors/packet-ieee802154.c
@@ -90,11 +90,6 @@
#include "packet-ieee802154.h"
#include "packet-frame.h" /* For Exception Handling */
-
-/* Forward declarations */
-static gboolean ieee802154_short_addr_invalidate(guint16, guint16, guint);
-static gboolean ieee802154_long_addr_invalidate(guint64, guint);
-
/* Dissection Options for dissect_ieee802154_common */
#define DISSECT_IEEE802154_OPTION_CC24xx 0x00000001 /* FCS field contains a TI CC24xx style FCS. */
#define DISSECT_IEEE802154_OPTION_LINUX 0x00000002 /* Addressing fields are padded DLT_IEEE802_15_4_LINUX, not implemented. */
@@ -105,7 +100,7 @@ static unsigned int ieee802154_ethertype = 0x809A;
/* boolean value set if the FCS field is using the TI CC24xx format */
static gboolean ieee802154_cc24xx = FALSE;
-/* boolean value set if the FCS must be ok before payload is dissected */
+/* boolean value set if the FCS must be oke before data is dissected */
static gboolean ieee802154_fcs_ok = TRUE;
/* User string with the decryption key. */
@@ -114,10 +109,56 @@ static gboolean ieee802154_key_valid;
static guint8 ieee802154_key[IEEE802154_CIPHER_SIZE];
/*-------------------------------------
- * Address Hash Tables
+ * Address Hash Table
*-------------------------------------
*/
-static ieee802154_addr_t ieee802154_addr = { 0, NULL, NULL };
+static GHashTable * ieee802154_addr_table = NULL;
+
+/* Value used for the hash table. */
+typedef struct {
+ guint64 addr;
+ /*guint32 frame_counter; TODO for frame counter sequence checks. Any other security state to save across packets? */
+} ieee802154_long_addr;
+
+/* Keys used for the hash table. */
+typedef struct {
+ guint16 addr;
+ guint16 pan;
+} ieee802154_short_addr;
+
+/* Key hash function. */
+static guint
+ieee802154_addr_hash(gconstpointer key)
+{
+ return (((ieee802154_short_addr *)key)->addr) | (((ieee802154_short_addr *)key)->pan << 16);
+}
+
+/* Key equals function. */
+static gboolean
+ieee802154_addr_equals(gconstpointer a, gconstpointer b)
+{
+ return (((ieee802154_short_addr *)a)->addr == ((ieee802154_short_addr *)b)->addr) &&
+ (((ieee802154_short_addr *)a)->pan == ((ieee802154_short_addr *)b)->pan);
+}
+
+/* Function to update the address table. */
+/* TODO: Make this a public function, in case other layers expose short-to-extended address pairs. */
+static void ieee802154_addr_update(guint16 short_addr, guint16 pan, guint64 long_addr)
+{
+ ieee802154_short_addr addr16;
+ ieee802154_long_addr * addr64;
+ addr16.addr = short_addr;
+ addr16.pan = pan;
+ addr64 = g_hash_table_lookup(ieee802154_addr_table, &addr16);
+ if (addr64) {
+ addr64->addr = long_addr;
+ }
+ else {
+ addr64 = se_alloc(sizeof(ieee802154_long_addr));
+ addr64->addr = long_addr;
+ g_hash_table_insert(ieee802154_addr_table, se_memdup(&addr16, sizeof(addr16)), addr64);
+ }
+} /* ieee802154_addr_update */
/*-------------------------------------
* Static Address Mapping UAT
@@ -151,7 +192,7 @@ addr_uat_update_cb(void* r, const char** err)
}
/* Ensure a valid EUI-64 length */
if (map->eui64_len != sizeof(guint64)) {
- *err = "Invalid EUI-64 length";
+ *err = "Invalid EUI-64";
}
} /* ieee802154_addr_uat_update_cb */
@@ -202,11 +243,10 @@ typedef enum {
DECRYPT_PACKET_MIC_CHECK_FAILED,
} ws_decrypt_status;
-static tvbuff_t * dissect_ieee802154_decrypt(tvbuff_t *, guint, packet_info *, ieee802154_packet *,
- ws_decrypt_status *);
-static void ccm_init_block (gchar *, gboolean, gint, guint64, guint32, ieee802154_security_level, gint);
-static gboolean ccm_ctr_encrypt (const gchar *, const gchar *, gchar *, gchar *, gint);
-static gboolean ccm_cbc_mac (const gchar *, const gchar *, const gchar *, gint, const gchar *, gint, gchar *);
+static tvbuff_t * dissect_ieee802154_decrypt(tvbuff_t *, guint, packet_info *, ieee802154_packet *, ws_decrypt_status *);
+static void ccm_init_block (gchar * block, gboolean adata, gint M, guint64 addr, guint32 counter, ieee802154_security_level level, gint ctr_val);
+static gboolean ccm_ctr_encrypt (const gchar *key, const gchar *iv, gchar *mic, gchar *data, gint length);
+static gboolean ccm_cbc_mac (const gchar * key, const gchar *iv, const gchar *a, gint a_len, const gchar *m, gint m_len, gchar *mic);
/* Initialize Protocol and Registered fields */
static int proto_ieee802154_nonask_phy = -1;
@@ -228,9 +268,8 @@ static int hf_ieee802154_dst_pan = -1;
static int hf_ieee802154_dst_addr16 = -1;
static int hf_ieee802154_dst_addr64 = -1;
static int hf_ieee802154_src_panID = -1;
-static int hf_ieee802154_src16 = -1;
-static int hf_ieee802154_src64 = -1;
-static int hf_ieee802154_src64_origin = -1;
+static int hf_ieee802154_src_addr16 = -1;
+static int hf_ieee802154_src_addr64 = -1;
static int hf_ieee802154_fcs = -1;
static int hf_ieee802154_rssi = -1;
static int hf_ieee802154_fcs_ok = -1;
@@ -470,9 +509,8 @@ dissect_ieee802154_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee
packet->src_addr_mode = (fcf & IEEE802154_FCF_SADDR_MASK) >> 14;
/* Display the frame type. */
- if (tree)
- proto_item_append_text(tree, " %s", val_to_str(packet->frame_type, ieee802154_frame_types, "Reserved"));
- col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved"));
+ if (tree) proto_item_append_text(tree, " %s", val_to_str(packet->frame_type, ieee802154_frame_types, "Reserved"));
+ if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved"));
/* Add the FCF to the protocol tree. */
if (tree) {
@@ -530,9 +568,11 @@ dissect_ieee802154_nonask_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
/* Add the protocol name. */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4 non-ASK PHY");
/* Add the packet length. */
- col_clear(pinfo->cinfo, COL_PACKET_LENGTH);
- col_add_fstr(pinfo->cinfo, COL_PACKET_LENGTH, "%i", tvb_length(tvb));
-
+ if(check_col(pinfo->cinfo, COL_PACKET_LENGTH)){
+ col_clear(pinfo->cinfo, COL_PACKET_LENGTH);
+ col_add_fstr(pinfo->cinfo, COL_PACKET_LENGTH, "%i", tvb_length(tvb));
+ }
+
preamble=tvb_get_letohl(tvb,offset);
sfd=tvb_get_guint8(tvb,offset+4);
phr=tvb_get_guint8(tvb,offset+4+1);
@@ -664,36 +704,23 @@ dissect_ieee802154_cc24xx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint options)
{
- tvbuff_t *volatile payload_tvb;
- proto_tree *volatile ieee802154_tree = NULL;
- proto_item *volatile proto_root = NULL;
- proto_item *ti;
- void *pd_save;
-
- guint offset = 0;
- volatile gboolean fcs_ok = TRUE;
- const char *saved_proto;
- ws_decrypt_status status;
-
- ieee802154_packet *packet = ep_alloc(sizeof(ieee802154_packet));
- ieee802154_short_addr addr16;
- ieee802154_hints_t *ieee_hints;
+ tvbuff_t *volatile payload_tvb;
+ proto_tree *volatile ieee802154_tree = NULL;
+ proto_item *volatile proto_root = NULL;
+ proto_item *ti;
+ void *pd_save;
+
+ guint offset = 0;
+ volatile gboolean fcs_ok = TRUE;
+ const char *saved_proto;
+ ieee802154_packet *packet = ep_alloc(sizeof(ieee802154_packet));
+ ws_decrypt_status status;
/* Link our packet info structure into the private data field for the
* Network-Layer heuristic subdissectors. */
pd_save = pinfo->private_data;
pinfo->private_data = packet;
- packet->short_table = ieee802154_addr.short_table;
-
- /* Allocate frame data with hints for upper layers */
- if(!pinfo->fd->flags.visited){
- ieee_hints = se_alloc0(sizeof(ieee802154_hints_t));
- p_add_proto_data(pinfo->fd, proto_ieee802154, ieee_hints);
- } else {
- ieee_hints = p_get_proto_data(pinfo->fd, proto_ieee802154);
- }
-
/* Create the protocol tree. */
if (tree) {
proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154, tvb, 0, tvb_length(tvb), "IEEE 802.15.4");
@@ -702,8 +729,10 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
/* Add the protocol name. */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4");
/* Add the packet length. */
- col_clear(pinfo->cinfo, COL_PACKET_LENGTH);
- col_add_fstr(pinfo->cinfo, COL_PACKET_LENGTH, "%i", tvb_length(tvb));
+ if(check_col(pinfo->cinfo, COL_PACKET_LENGTH)){
+ col_clear(pinfo->cinfo, COL_PACKET_LENGTH);
+ col_add_fstr(pinfo->cinfo, COL_PACKET_LENGTH, "%i", tvb_length(tvb));
+ }
/*=====================================================
* FRAME CONTROL FIELD
@@ -753,25 +782,20 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
gchar *dst_addr = ep_alloc(32);
/* Get the address. */
- packet->dst16 = tvb_get_letohs(tvb, offset);
+ packet->dst.addr16 = tvb_get_letohs(tvb, offset);
/* Display the destination address. */
- if ( packet->dst16 == IEEE802154_BCAST_ADDR ) {
- g_snprintf(dst_addr, 32, "Broadcast");
- }
- else {
- g_snprintf(dst_addr, 32, "0x%04x", packet->dst16);
- }
-
+ if(packet->dst.addr16==IEEE802154_BCAST_ADDR) g_snprintf(dst_addr, 32, "Broadcast");
+ else g_snprintf(dst_addr, 32, "0x%04x", packet->dst.addr16);
SET_ADDRESS(&pinfo->dl_dst, AT_STRINGZ, (int)strlen(dst_addr)+1, dst_addr);
SET_ADDRESS(&pinfo->dst, AT_STRINGZ, (int)strlen(dst_addr)+1, dst_addr);
-
if (tree) {
- proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_addr16, tvb, offset, 2, packet->dst16);
+ proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_addr16, tvb, offset, 2, packet->dst.addr16);
proto_item_append_text(proto_root, ", Dst: %s", dst_addr);
}
-
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_addr);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_addr);
+ }
offset += 2;
}
else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
@@ -780,14 +804,14 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
gchar *dst, *dst_oui;
/* Get the address */
- packet->dst64 = tvb_get_letoh64(tvb, offset);
+ packet->dst.addr64 = tvb_get_letoh64(tvb, offset);
/* print the address strings. */
- dst = print_eui64(packet->dst64);
- dst_oui = print_eui64_oui(packet->dst64);
+ dst = print_eui64(packet->dst.addr64);
+ dst_oui = print_eui64_oui(packet->dst.addr64);
/* Copy and convert the address to network byte order. */
- *(guint64 *)(addr) = pntoh64(&(packet->dst64));
+ *(guint64 *)(addr) = pntoh64(&(packet->dst.addr64));
/* Display the destination address. */
/* NOTE: OUI resolution doesn't happen when displaying EUI64 addresses
@@ -797,12 +821,12 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
SET_ADDRESS(&pinfo->dl_dst, AT_EUI64, 8, addr);
SET_ADDRESS(&pinfo->dst, AT_EUI64, 8, addr);
if (tree) {
- proto_tree_add_uint64_format_value(ieee802154_tree, hf_ieee802154_dst_addr64, tvb, offset,
- 8, packet->dst64, "%s (%s)", dst_oui, dst);
+ proto_tree_add_uint64_format_value(ieee802154_tree, hf_ieee802154_dst_addr64, tvb, offset, 8, packet->dst.addr64, "%s (%s)", dst_oui, dst);
proto_item_append_text(proto_root, ", Dst: %s", dst_oui);
}
-
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_oui);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_oui);
+ }
offset += 8;
}
else if (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) {
@@ -819,8 +843,7 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
if ( ((packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) || (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT)) &&
((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) || (!packet->intra_pan)) ) {
/* Source PAN is present, extract it and add it to the tree. */
- ieee_hints->src_pan = packet->src_pan = tvb_get_letohs(tvb, offset);
-
+ packet->src_pan = tvb_get_letohs(tvb, offset);
if (tree) {
proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src_panID, tvb, offset, 2, packet->src_pan);
}
@@ -828,64 +851,31 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
}
else {
/* Set the panID field in case the intra-pan condition was met. */
- ieee_hints->src_pan = packet->src_pan = packet->dst_pan;
+ packet->src_pan = packet->dst_pan;
}
- /* Get short source address if present. */
+ /* Get source address if present. */
if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
/* Dynamic (not stack) memory required for address column. */
gchar *src_addr = ep_alloc(32);
/* Get the address. */
- packet->src16 = tvb_get_letohs(tvb, offset);
+ packet->src.addr16 = tvb_get_letohs(tvb, offset);
/* Update the Address fields. */
- if (packet->src16==IEEE802154_BCAST_ADDR) {
- g_snprintf(src_addr, 32, "Broadcast");
- }
- else {
- g_snprintf(src_addr, 32, "0x%04x", packet->src16);
-
- if (!pinfo->fd->flags.visited) {
- /* If we know our extended source address from previous packets,
- * provide a pointer to it in a hint for upper layers */
- addr16.addr = packet->src16;
- addr16.pan = packet->src_pan;
-
- if (ieee_hints) {
- ieee_hints->src16 = packet->src16;
- ieee_hints->map_rec = (ieee802154_map_rec *)
- g_hash_table_lookup(ieee802154_addr.short_table, &addr16);
- }
- }
- }
-
+ if(packet->src.addr16==IEEE802154_BCAST_ADDR) g_snprintf(src_addr, 32, "Broadcast");
+ else g_snprintf(src_addr, 32, "0x%04x", packet->src.addr16);
SET_ADDRESS(&pinfo->dl_src, AT_STRINGZ, (int)strlen(src_addr)+1, src_addr);
SET_ADDRESS(&pinfo->src, AT_STRINGZ, (int)strlen(src_addr)+1, src_addr);
/* Add the addressing info to the tree. */
if (tree) {
- proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src16, tvb, offset, 2, packet->src16);
+ proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src_addr16, tvb, offset, 2, packet->src.addr16);
proto_item_append_text(proto_root, ", Src: %s", src_addr);
-
- if (ieee_hints && ieee_hints->map_rec) {
- /* Display inferred source address info */
- ti = proto_tree_add_eui64(ieee802154_tree, hf_ieee802154_src64, tvb, offset, 0,
- ieee_hints->map_rec->addr64);
- PROTO_ITEM_SET_GENERATED(ti);
-
- if ( ieee_hints->map_rec->start_fnum ) {
- ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src64_origin, tvb, 0, 0,
- ieee_hints->map_rec->start_fnum);
- }
- else {
- ti = proto_tree_add_text(ieee802154_tree, tvb, 0, 0, "Origin: Pre-configured");
- }
- PROTO_ITEM_SET_GENERATED(ti);
- }
}
-
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", src_addr);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", src_addr);
+ }
offset += 2;
}
else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
@@ -894,14 +884,14 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
gchar *src, *src_oui;
/* Get the address. */
- packet->src64 = tvb_get_letoh64(tvb, offset);
+ packet->src.addr64 = tvb_get_letoh64(tvb, offset);
/* Print the address strings. */
- src = print_eui64(packet->src64);
- src_oui = print_eui64_oui(packet->src64);
+ src = print_eui64(packet->src.addr64);
+ src_oui = print_eui64_oui(packet->src.addr64);
/* Copy and convert the address to network byte order. */
- *(guint64 *)(addr) = pntoh64(&(packet->src64));
+ *(guint64 *)(addr) = pntoh64(&(packet->src.addr64));
/* Display the source address. */
/* NOTE: OUI resolution doesn't happen when displaying EUI64 addresses
@@ -911,12 +901,12 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
SET_ADDRESS(&pinfo->dl_src, AT_EUI64, 8, addr);
SET_ADDRESS(&pinfo->src, AT_EUI64, 8, addr);
if (tree) {
- proto_tree_add_uint64_format_value(ieee802154_tree, hf_ieee802154_src64, tvb, offset,
- 8, packet->src64, "%s (%s)", src_oui, src);
+ proto_tree_add_uint64_format_value(ieee802154_tree, hf_ieee802154_src_addr64, tvb, offset, 8, packet->src.addr64, "%s (%s)", src_oui, src);
proto_item_append_text(proto_root, ", Src: %s", src_oui);
}
-
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", src_oui);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", src_oui);
+ }
offset += 8;
}
else if (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) {
@@ -955,14 +945,14 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
if (packet->security_enable && (packet->version == 1)) {
proto_tree *header_tree, *field_tree;
guint8 security_control;
- guint aux_length = 5; /* Minimum length of the auxiliary header. */
+ guint aux_length = 5; /* Minimum length of the auxilliary header. */
/* Parse the security control field. */
security_control = tvb_get_guint8(tvb, offset);
packet->security_level = (security_control & IEEE802154_AUX_SEC_LEVEL_MASK);
packet->key_id_mode = (security_control & IEEE802154_AUX_KEY_ID_MODE_MASK) >> IEEE802154_AUX_KEY_ID_MODE_SHIFT;
- /* Compute the length of the auxiliary header and create a subtree. */
+ /* Compute the length of the auxilliar header and create a subtree. */
if (packet->key_id_mode != KEY_ID_MODE_IMPLICIT) aux_length++;
if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_4) aux_length += 4;
if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_8) aux_length += 8;
@@ -1029,7 +1019,9 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
offset++;
/* Display the command identifier in the info column. */
- col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
+ if(check_col(pinfo->cinfo, COL_INFO)) {
+ col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
+ }
}
/* No other frame types have nonpayload fields. */
@@ -1169,7 +1161,7 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
- (packet->dst16 == IEEE802154_BCAST_ADDR) &&
+ (packet->dst.addr16 == IEEE802154_BCAST_ADDR) &&
(packet->src_pan == IEEE802154_BCAST_PAN) &&
(packet->dst_pan == IEEE802154_BCAST_PAN));
/* No payload expected. */
@@ -1179,7 +1171,7 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id,
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) &&
- (packet->dst16 == IEEE802154_BCAST_ADDR) &&
+ (packet->dst.addr16 == IEEE802154_BCAST_ADDR) &&
(packet->dst_pan == IEEE802154_BCAST_PAN));
/* No payload expected. */
break;
@@ -1191,7 +1183,7 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
(packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE));
if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
/* If directed to a 16-bit address, check that it is being broadcast. */
- IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id, packet->dst16 == IEEE802154_BCAST_ADDR);
+ IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id, packet->dst.addr16 == IEEE802154_BCAST_ADDR);
}
dissect_ieee802154_realign(payload_tvb, pinfo, ieee802154_tree, packet);
break;
@@ -1201,8 +1193,8 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) &&
- (packet->src16 != IEEE802154_BCAST_ADDR) &&
- (packet->src16 != IEEE802154_NO_ADDR16));
+ (packet->src.addr16 != IEEE802154_BCAST_ADDR) &&
+ (packet->src.addr16 != IEEE802154_NO_ADDR16));
dissect_ieee802154_gtsreq(payload_tvb, pinfo, ieee802154_tree, packet);
break;
@@ -1545,8 +1537,7 @@ dissect_ieee802154_assoc_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
/* Create a subtree for this command frame. */
if (tree) {
- ti = proto_tree_add_text(tree, tvb, offset, 3, "%s", val_to_str(packet->command_id,
- ieee802154_cmd_names, "Unknown Command"));
+ ti = proto_tree_add_text(tree, tvb, offset, 3, "%s", val_to_str(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
subtree = proto_item_add_subtree(ti, ett_ieee802154_cmd);
}
@@ -1569,24 +1560,25 @@ dissect_ieee802154_assoc_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
offset += 1;
/* Update the info column. */
- if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) {
- /* Association was successful. */
- if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) {
- col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", packet->dst_pan);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) {
+ /* Association was successful. */
+ if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", packet->dst_pan);
+ }
+ if (short_addr != IEEE802154_NO_ADDR16) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Addr: 0x%04x", short_addr);
+ }
}
- if (short_addr != IEEE802154_NO_ADDR16) {
- col_append_fstr(pinfo->cinfo, COL_INFO, " Addr: 0x%04x", short_addr);
+ else {
+ /* Association was unsuccessful. */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Unsuccessful");
}
}
- else {
- /* Association was unsuccessful. */
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Unsuccessful");
- }
/* Update the address table. */
if ((status == IEEE802154_CMD_ASRSP_AS_SUCCESS) && (short_addr != IEEE802154_NO_ADDR16)) {
- ieee802154_addr_update(&ieee802154_addr, short_addr, packet->dst_pan, packet->dst64,
- proto_ieee802154, pinfo->fd->num);
+ ieee802154_addr_update(short_addr, packet->dst_pan, packet->dst.addr64);
}
/* Call the data dissector for any leftover bytes. */
@@ -1622,7 +1614,7 @@ dissect_ieee802154_disassoc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
subtree = proto_item_add_subtree(ti, ett_ieee802154_cmd);
}
- /* Get and display the disassociation reason. */
+ /* Get and display the dissasociation reason. */
reason = tvb_get_guint8(tvb, 0);
if (tree) {
ti = proto_tree_add_uint(subtree, hf_ieee802154_disassoc_reason, tvb, 0, 1, reason);
@@ -1641,15 +1633,6 @@ dissect_ieee802154_disassoc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
} /* switch */
}
- if (!pinfo->fd->flags.visited) {
- /* Update the address tables */
- if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT ) {
- ieee802154_long_addr_invalidate(packet->dst64, pinfo->fd->num);
- } else if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT ) {
- ieee802154_short_addr_invalidate(packet->dst16, packet->dst_pan, pinfo->fd->num);
- }
- }
-
/* Call the data dissector for any leftover bytes. */
if (tvb_length(tvb) > 1) {
call_dissector(data_handle, tvb_new_subset(tvb, 1, -1, -1), pinfo, tree);
@@ -1690,45 +1673,40 @@ dissect_ieee802154_realign(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* Get and display the command PAN ID. */
pan_id = tvb_get_letohs(tvb, offset);
- if (tree)
- proto_tree_add_uint(subtree, hf_ieee802154_realign_pan, tvb, offset, 2, pan_id);
- col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", pan_id);
+ if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_pan, tvb, offset, 2, pan_id);
+ if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", pan_id);
offset += 2;
/* Get and display the coordinator address. */
coord_addr = tvb_get_letohs(tvb, offset);
- if (tree)
- proto_tree_add_uint(subtree, hf_ieee802154_realign_caddr, tvb, offset, 2, coord_addr);
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Coordinator: 0x%04x", coord_addr);
+ if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_caddr, tvb, offset, 2, coord_addr);
+ if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, ", Coordinator: 0x%04x", coord_addr);
offset += 2;
/* Get and display the channel. */
channel = tvb_get_guint8(tvb, offset);
- if (tree)
- proto_tree_add_uint(subtree, hf_ieee802154_realign_channel, tvb, offset, 1, channel);
- col_append_fstr(pinfo->cinfo, COL_INFO, ", Channel: %u", channel);
+ if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_channel, tvb, offset, 1, channel);
+ if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, ", Channel: %u", channel);
offset += 1;
/* Get and display the short address. */
short_addr = tvb_get_letohs(tvb, offset);
- if (tree)
- proto_tree_add_uint(subtree, hf_ieee802154_realign_addr, tvb, offset, 2, short_addr);
- if ( (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)
+ if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_addr, tvb, offset, 2, short_addr);
+ if ( (check_col(pinfo->cinfo, COL_INFO))
+ && (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)
&& (short_addr != IEEE802154_NO_ADDR16)) {
col_append_fstr(pinfo->cinfo, COL_INFO, ", Addr: 0x%04x", short_addr);
}
offset += 2;
/* Update the address table. */
if ((short_addr != IEEE802154_NO_ADDR16) && (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) {
- ieee802154_addr_update(&ieee802154_addr, short_addr, packet->dst_pan, packet->dst64,
- proto_ieee802154, pinfo->fd->num);
+ ieee802154_addr_update(short_addr, packet->dst_pan, packet->dst.addr64);
}
/* Get and display the channel page, if it exists. Added in IEEE802.15.4-2006 */
if (tvb_bytes_exist(tvb, offset, 1)) {
guint8 channel_page = tvb_get_guint8(tvb, offset);
- if (tree)
- proto_tree_add_uint(subtree, hf_ieee802154_realign_channel_page, tvb, offset, 1, channel_page);
+ if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_channel_page, tvb, offset, 1, channel_page);
offset += 1;
}
@@ -1774,8 +1752,7 @@ dissect_ieee802154_gtsreq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
/* Create a subtree for this command frame. */
if (tree) {
- ti = proto_tree_add_text(tree, tvb, 0, 1, "%s", val_to_str(packet->command_id, ieee802154_cmd_names,
- "Unknown Command"));
+ ti = proto_tree_add_text(tree, tvb, 0, 1, "%s", val_to_str(packet->command_id, ieee802154_cmd_names, "Unknown Command"));
subtree = proto_item_add_subtree(ti, ett_ieee802154_cmd);
}
@@ -1835,9 +1812,6 @@ dissect_ieee802154_decrypt(tvbuff_t * tvb, guint offset, packet_info * pinfo, ie
guint M = IEEE802154_MIC_LENGTH(packet->security_level);
gint captured_len;
gint reported_len;
- ieee802154_hints_t *ieee_hints;
-
- ieee_hints = p_get_proto_data(pinfo->fd, proto_ieee802154);
/* Get the captured and on-the-wire length of the payload. */
reported_len = tvb_reported_length_remaining(tvb, offset) - IEEE802154_FCS_LEN - M;
@@ -1881,14 +1855,26 @@ dissect_ieee802154_decrypt(tvbuff_t * tvb, guint offset, packet_info * pinfo, ie
*/
if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
/* The source EUI-64 is included in the headers. */
- srcAddr = packet->src64;
- }
- else if (ieee_hints && ieee_hints->map_rec && ieee_hints->map_rec->addr64) {
- /* Use the hint */
- srcAddr = ieee_hints->map_rec->addr64;
+ srcAddr = packet->src.addr64;
+ }
+ else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) {
+ ieee802154_short_addr addr16;
+ ieee802154_long_addr * addr64;
+
+ /* Try to lookup the EUI-64 from the address table. */
+ addr16.addr = packet->src.addr16;
+ addr16.pan = packet->src_pan;
+ addr64 = (ieee802154_long_addr *)g_hash_table_lookup(ieee802154_addr_table, &addr16);
+ if (!addr64) {
+ /* Lookup failed. */
+ *status = DECRYPT_PACKET_NO_EXT_SRC_ADDR;
+ return NULL;
+ }
+ /* Lookup successful. */
+ srcAddr = addr64->addr;
}
else {
- /* Lookup failed. */
+ /* No addressing is present in the headers. We're screwed. */
*status = DECRYPT_PACKET_NO_EXT_SRC_ADDR;
return NULL;
}
@@ -2208,177 +2194,6 @@ ccm_cbc_mac(const gchar *key _U_, const gchar *iv _U_, const gchar *a _U_, gint
#endif
} /* ccm_cbc_mac */
-/* Key hash function. */
-guint ieee802154_short_addr_hash(gconstpointer key)
-{
- return (((ieee802154_short_addr *)key)->addr) | (((ieee802154_short_addr *)key)->pan << 16);
-}
-
-/* Key equal function. */
-gboolean ieee802154_short_addr_equal(gconstpointer a, gconstpointer b)
-{
- return (((ieee802154_short_addr *)a)->pan == ((ieee802154_short_addr *)b)->pan) &&
- (((ieee802154_short_addr *)a)->addr == ((ieee802154_short_addr *)b)->addr);
-}
-
-/*FUNCTION:------------------------------------------------------
- * NAME
- * ieee802154_addr_update
- * DESCRIPTION
- * Creates a record that maps the given short address and pan
- * to a long (extended) address. Typically called when a
- * successful association reponse is received.
- * PARAMETERS
- * guint16 short_addr - 16-bit short address
- * guint16 pan - 16-bit PAN id
- * guint64 long_addr - 64-bit long (extended) address
- * guint - Frame number this mapping became valid
- * RETURNS
- * TRUE - Record was updated
- * FALSE - Couldn't find it
- *---------------------------------------------------------------
- */
-ieee802154_map_rec *ieee802154_addr_update(ieee802154_addr_t *ieee802154_addr,
- guint16 short_addr, guint16 pan, guint64 long_addr, int proto, guint fnum)
-{
- ieee802154_short_addr addr16;
- ieee802154_map_rec *p_map_rec;
- gpointer old_key;
-
- /* Look up short address hash */
- addr16.pan = pan;
- addr16.addr = short_addr;
- p_map_rec = g_hash_table_lookup(ieee802154_addr->short_table, &addr16);
-
- /* Update mapping record */
- if (p_map_rec) {
- /* record already exists */
- if ( p_map_rec->addr64 == long_addr ) {
- /* no change */
- return p_map_rec;
- }
- else {
- /* mark current mapping record invalid */
- p_map_rec->end_fnum = fnum;
- }
- }
-
- /* create a new mapping record */
- p_map_rec = se_alloc(sizeof(ieee802154_map_rec));
- p_map_rec->proto = proto;
- p_map_rec->start_fnum = fnum;
- p_map_rec->end_fnum = 0;
- p_map_rec->addr64 = long_addr;
-
- /* link new mapping record to addr hash tables */
- if ( g_hash_table_lookup_extended(ieee802154_addr->short_table, &addr16, &old_key, NULL) ) {
- /* update short addr hash table, reusing pointer to old key */
- g_hash_table_insert(ieee802154_addr->short_table, &old_key, p_map_rec);
- } else {
- /* create new hash entry */
- g_hash_table_insert(ieee802154_addr->short_table, se_memdup(&addr16, sizeof(addr16)), p_map_rec);
- }
-
- if ( g_hash_table_lookup_extended(ieee802154_addr->long_table, &long_addr, &old_key, NULL) ) {
- /* update long addr hash table, reusing pointer to old key */
- g_hash_table_insert(ieee802154_addr->long_table, &old_key, p_map_rec);
- } else {
- /* create new hash entry */
- g_hash_table_insert(ieee802154_addr->long_table, se_memdup(&long_addr, sizeof(long_addr)), p_map_rec);
- }
-
- return p_map_rec;
-} /* ieee802154_addr_update */
-
-/*FUNCTION:------------------------------------------------------
- * NAME
- * ieee802154_short_addr_invalidate
- * DESCRIPTION
- * Marks a mapping record associated with device with short_addr
- * as invalid at a certain frame number, typically when a
- * dissassociation occurs.
- * PARAMETERS
- * guint16 short_addr - 16-bit short address
- * guint16 pan - 16-bit PAN id
- * guint - Frame number when mapping became invalid
- * RETURNS
- * TRUE - Record was updated
- * FALSE - Couldn't find it
- *---------------------------------------------------------------
- */
-static gboolean
-ieee802154_short_addr_invalidate(guint16 short_addr, guint16 pan, guint fnum)
-{
- ieee802154_short_addr addr16;
- ieee802154_map_rec *map_rec;
-
- addr16.pan = pan;
- addr16.addr = short_addr;
-
- map_rec = g_hash_table_lookup(ieee802154_addr.short_table, &addr16);
- if ( map_rec ) {
- /* indicates this mapping is invalid at frame fnum */
- map_rec->end_fnum = fnum;
- return TRUE;
- }
-
- return FALSE;
-} /* ieee802154_short_addr_invalidate */
-
-/*FUNCTION:------------------------------------------------------
- * NAME
- * ieee802154_long_addr_invalidate
- * DESCRIPTION
- * Marks a mapping record associated with device with long_addr
- * as invalid at a certain frame number, typically when a
- * dissassociation occurs.
- * PARAMETERS
- * guint64 long_addr - 16-bit short address
- * guint - Frame number when mapping became invalid
- * RETURNS
- * TRUE - If record was updated
- * FALSE - If record wasn't updated
- *---------------------------------------------------------------
- */
-static gboolean
-ieee802154_long_addr_invalidate(guint64 long_addr, guint fnum)
-{
- ieee802154_map_rec *map_rec;
-
- map_rec = g_hash_table_lookup(ieee802154_addr.long_table, &long_addr);
- if ( map_rec ) {
- /* indicates this mapping is invalid at frame fnum */
- map_rec->end_fnum = fnum;
- return TRUE;
- }
-
- return FALSE;
-} /* ieee802154_long_addr_invalidate */
-
-/*FUNCTION:------------------------------------------------------
- * NAME
- * proto_tree_add_eui64
- * DESCRIPTION
- * Helper function to display an EUI-64 address to the tree.
- * PARAMETERS
- * proto_tree *tree
- * int hfindex
- * tvbuff_t *tvb
- * gint start
- * gint length
- * guint64 value;
- * RETURNS
- * proto_item *
- *---------------------------------------------------------------
- */
-proto_item *
-proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length, gint64 value)
-{
- header_field_info *hf = proto_registrar_get_nth(hfindex);
- return proto_tree_add_uint64_format(tree, hfindex, tvb, start, length, value, "%s: %s (%s)",
- hf->name, print_eui64_oui(value), print_eui64(value));
-}
-
/*FUNCTION:------------------------------------------------------
* NAME
* proto_register_ieee802154
@@ -2405,14 +2220,14 @@ void proto_register_ieee802154(void)
NULL, HFILL }},
{ &hf_ieee802154_nonask_phy_length,
- { "Frame Length", "wpan-nonask-phy.frame_length", FT_UINT8, BASE_HEX, NULL,
- IEEE802154_PHY_LENGTH_MASK, NULL, HFILL }},
+ { "Frame Length", "wpan-nonask-phy.frame_length", FT_UINT8, BASE_HEX, NULL, IEEE802154_PHY_LENGTH_MASK,
+ NULL, HFILL }},
};
static hf_register_info hf[] = {
{ &hf_ieee802154_frame_type,
- { "Frame Type", "wpan.frame_type", FT_UINT16, BASE_HEX, VALS(ieee802154_frame_types),
- IEEE802154_FCF_TYPE_MASK, NULL, HFILL }},
+ { "Frame Type", "wpan.frame_type", FT_UINT16, BASE_HEX, VALS(ieee802154_frame_types), IEEE802154_FCF_TYPE_MASK,
+ NULL, HFILL }},
{ &hf_ieee802154_security,
{ "Security Enabled", "wpan.security", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_SEC_EN,
@@ -2435,12 +2250,12 @@ void proto_register_ieee802154(void)
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 }},
+ { "Destination Addressing Mode", "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes), IEEE802154_FCF_DADDR_MASK,
+ 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 }},
+ { "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, NULL, IEEE802154_FCF_VERSION,
@@ -2462,16 +2277,12 @@ void proto_register_ieee802154(void)
{ "Source PAN", "wpan.src_pan", FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }},
- { &hf_ieee802154_src16,
- { "Source", "wpan.src16", FT_UINT16, BASE_HEX, NULL, 0x0,
- NULL, HFILL }},
-
- { &hf_ieee802154_src64,
- { "Extended Source", "wpan.src64", FT_UINT64, BASE_HEX, NULL, 0x0,
+ { &hf_ieee802154_src_addr16,
+ { "Source", "wpan.src_addr16", FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }},
- { &hf_ieee802154_src64_origin,
- { "Origin", "wpan.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ { &hf_ieee802154_src_addr64,
+ { "Source", "wpan.src_addr64", FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL }},
{ &hf_ieee802154_fcs,
@@ -2575,8 +2386,7 @@ void proto_register_ieee802154(void)
"Specifies the transmission interval of the beacons.", HFILL }},
{ &hf_ieee802154_superframe_order,
- { "Superframe Interval", "wpan.superframe_order", FT_UINT16, BASE_DEC, NULL,
- IEEE802154_SUPERFRAME_ORDER_MASK,
+ { "Superframe Interval", "wpan.superframe_order", FT_UINT16, BASE_DEC, NULL, IEEE802154_SUPERFRAME_ORDER_MASK,
"Specifies the length of time the coordinator will interact with the PAN.", HFILL }},
{ &hf_ieee802154_cap,
@@ -2618,12 +2428,11 @@ void proto_register_ieee802154(void)
/* Auxiliary Security Header Fields */
/*----------------------------------*/
{ &hf_ieee802154_security_level,
- { "Security Level", "wpan.aux_sec.sec_level", FT_UINT8, BASE_HEX, VALS(ieee802154_sec_level_names),
- IEEE802154_AUX_SEC_LEVEL_MASK, "The Security Level of the frame", HFILL }},
+ { "Security Level", "wpan.aux_sec.sec_level", FT_UINT8, BASE_HEX, VALS(ieee802154_sec_level_names), IEEE802154_AUX_SEC_LEVEL_MASK,
+ "The Security Level of the frame", HFILL }},
{ &hf_ieee802154_key_id_mode,
- { "Key Identifier Mode", "wpan.aux_sec.key_id_mode", FT_UINT8, BASE_HEX, VALS(ieee802154_key_id_mode_names),
- IEEE802154_AUX_KEY_ID_MODE_MASK,
+ { "Key Identifier Mode", "wpan.aux_sec.key_id_mode", FT_UINT8, BASE_HEX, VALS(ieee802154_key_id_mode_names), IEEE802154_AUX_KEY_ID_MODE_MASK,
"The scheme to use by the recipient to lookup the key in its key table", HFILL }},
{ &hf_ieee802154_aux_sec_reserved,
@@ -2678,10 +2487,8 @@ void proto_register_ieee802154(void)
register_init_routine(proto_init_ieee802154);
/* Register Protocol name and description. */
- proto_ieee802154 = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN", "IEEE 802.15.4",
- IEEE802154_PROTOABBREV_WPAN);
- proto_ieee802154_nonask_phy = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN non-ASK PHY",
- "IEEE 802.15.4 non-ASK PHY", "wpan-nonask-phy");
+ proto_ieee802154 = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN", "IEEE 802.15.4", "wpan");
+ proto_ieee802154_nonask_phy = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN non-ASK PHY", "IEEE 802.15.4 non-ASK PHY", "wpan-nonask-phy");
/* Register header fields and subtrees. */
proto_register_field_array(proto_ieee802154, hf, array_length(hf));
@@ -2691,7 +2498,7 @@ void proto_register_ieee802154(void)
/* add a user preference to set the 802.15.4 ethertype */
ieee802154_module = prefs_register_protocol(proto_ieee802154,
- proto_reg_handoff_ieee802154);
+ proto_reg_handoff_ieee802154);
prefs_register_uint_preference(ieee802154_module, "802154_ethertype",
"802.15.4 Ethertype (in hex)",
"(Hexadecimal) Ethertype used to indicate IEEE 802.15.4 frame.",
@@ -2701,8 +2508,8 @@ void proto_register_ieee802154(void)
"Set if the FCS field is in TI CC24xx format.",
&ieee802154_cc24xx);
prefs_register_bool_preference(ieee802154_module, "802154_fcs_ok",
- "Dissect only good FCS",
- "Dissect payload only if FCS is valid.",
+ "Dissect data only if FCS is ok",
+ "Dissect data only if FCS is ok.",
&ieee802154_fcs_ok);
/* Create a UAT for static address mappings. */
@@ -2730,10 +2537,10 @@ void proto_register_ieee802154(void)
"128-bit decryption key in hexadecimal format", (const char **)&ieee802154_key_str);
/* Register the subdissector list */
- register_heur_dissector_list(IEEE802154_PROTOABBREV_WPAN, &ieee802154_heur_subdissector_list);
+ register_heur_dissector_list("wpan", &ieee802154_heur_subdissector_list);
/* Register dissectors with Wireshark. */
- register_dissector(IEEE802154_PROTOABBREV_WPAN, dissect_ieee802154, proto_ieee802154);
+ register_dissector("wpan", dissect_ieee802154, proto_ieee802154);
register_dissector("wpan_nofcs", dissect_ieee802154_nofcs, proto_ieee802154);
register_dissector("wpan_cc24xx", dissect_ieee802154_cc24xx, proto_ieee802154);
register_dissector("wpan-nonask-phy", dissect_ieee802154_nonask_phy, proto_ieee802154_nonask_phy);
@@ -2764,7 +2571,7 @@ void proto_reg_handoff_ieee802154(void)
if (!prefs_initialized){
/* Get the dissector handles. */
- ieee802154_handle = find_dissector(IEEE802154_PROTOABBREV_WPAN);
+ ieee802154_handle = find_dissector("wpan");
ieee802154_nonask_phy_handle = find_dissector("wpan-nonask-phy");
ieee802154_nofcs_handle = find_dissector("wpan_nofcs");
data_handle = find_dissector("data");
@@ -2797,9 +2604,9 @@ void proto_reg_handoff_ieee802154(void)
* NAME
* proto_init_ieee802154
* DESCRIPTION
- * Init routine for the IEEE 802.15.4 dissector. Creates hash
- * tables for mapping between 16-bit to 64-bit addresses and
- * populates them with static address pairs from a UAT
+ * Init routine for the IEEE 802.15.4 dissector. Creates a
+ * hash table for mapping 16-bit to 64-bit addresses and
+ * populates it with static address pairs from a UAT
* preference table.
* PARAMETERS
* none
@@ -2812,17 +2619,16 @@ proto_init_ieee802154(void)
{
guint i;
- /* Destroy hash tables, if they exist. */
- if (ieee802154_addr.short_table) g_hash_table_destroy(ieee802154_addr.short_table);
- if (ieee802154_addr.long_table) g_hash_table_destroy(ieee802154_addr.long_table);
+ /* Destroy the hash table, if it exists. */
+ if (ieee802154_addr_table)
+ g_hash_table_destroy(ieee802154_addr_table);
- /* Create the hash tables. */
- ieee802154_addr.short_table = g_hash_table_new(ieee802154_short_addr_hash, ieee802154_short_addr_equal);
- ieee802154_addr.long_table = g_hash_table_new(g_int64_hash, g_int64_equal);
+ /* (Re)create the hash table. */
+ ieee802154_addr_table = g_hash_table_new(ieee802154_addr_hash, ieee802154_addr_equals);
/* Re-load the hash table from the static address UAT. */
for (i=0; (i<num_static_addrs) && (static_addrs); i++) {
- ieee802154_addr_update(&ieee802154_addr,(guint16)static_addrs[i].addr16, (guint16)static_addrs[i].pan,
- pntoh64(static_addrs[i].eui64), proto_ieee802154, IEEE802154_USER_MAPPING);
+ ieee802154_addr_update((guint16)static_addrs[i].addr16, (guint16)static_addrs[i].pan, pntoh64(static_addrs[i].eui64));
} /* for */
} /* proto_init_ieee802154 */
+
diff --git a/epan/dissectors/packet-ieee802154.h b/epan/dissectors/packet-ieee802154.h
index c106be5f38..428f573359 100644
--- a/epan/dissectors/packet-ieee802154.h
+++ b/epan/dissectors/packet-ieee802154.h
@@ -27,9 +27,6 @@
#ifndef PACKET_IEEE802154_H
#define PACKET_IEEE802154_H
-/* Protocol Abbreviation */
-#define IEEE802154_PROTOABBREV_WPAN "wpan"
-
/* Packet Overhead from MAC header + footer (excluding addressing) */
#define IEEE802154_MAX_FRAME_LEN 127
#define IEEE802154_FCS_LEN 2
@@ -51,7 +48,7 @@
#define IEEE802154_CMD_ASRSP_PAN_FULL 0x01
#define IEEE802154_CMD_ASRSP_PAN_DENIED 0x02
-/* Bit Masks for Capability Information Field
+/* Bit Masks for Capability Information Feild
Included in Association Req. command */
#define IEEE802154_CMD_CINFO_ALT_PAN_COORD 0x01
#define IEEE802154_CMD_CINFO_DEVICE_TYPE 0x02
@@ -102,7 +99,7 @@
#define IEEE802154_FCF_SEC_EN 0x0008
#define IEEE802154_FCF_FRAME_PND 0x0010
#define IEEE802154_FCF_ACK_REQ 0x0020
-#define IEEE802154_FCF_INTRA_PAN 0x0040 /* known as PAN ID Compression in IEEE 802.15.4-2006 */
+#define IEEE802154_FCF_INTRA_PAN 0x0040
#define IEEE802154_FCF_DADDR_MASK 0x0C00 /* destination addressing mask */
#define IEEE802154_FCF_VERSION 0x3000
#define IEEE802154_FCF_SADDR_MASK 0xC000 /* source addressing mask */
@@ -167,7 +164,7 @@ typedef enum {
/* Macro to check for payload encryption. */
#define IEEE802154_IS_ENCRYPTED(_level_) ((_level_) & 0x4)
-/* Structure containing information regarding all necessary packet fields. */
+/* Structure containing information regarding all necessary packet feilds. */
typedef struct {
/* Frame control field. */
gint32 version;
@@ -183,11 +180,15 @@ typedef struct {
/* Addressing Info. */
guint16 dst_pan;
+ union {
+ guint16 addr16;
+ guint64 addr64;
+ } dst;
guint16 src_pan;
- guint16 dst16;
- guint64 dst64;
- guint16 src16;
- guint64 src64;
+ union {
+ guint16 addr16;
+ guint64 addr64;
+ } src;
/* Security Info. */
ieee802154_security_level security_level;
@@ -201,47 +202,11 @@ typedef struct {
/* Command ID (only if frame_type == 0x3) */
guint8 command_id;
- GHashTable *short_table;
} ieee802154_packet;
-typedef struct {
- guint proto;
- GHashTable *long_table;
- GHashTable *short_table;
-} ieee802154_addr_t;
-
-/* Key used by the short address hash table. */
-typedef struct {
- guint16 pan;
- guint16 addr;
-} ieee802154_short_addr;
-
-/* A mapping record for a frame, pointed to by hash table */
-typedef struct {
- int proto; /* protocol that created this record */
- guint start_fnum;
- guint end_fnum;
- guint64 addr64;
- /*guint32 frame_counter; TODO for frame counter sequence checks. */
-} ieee802154_map_rec;
-
-#define IEEE802154_USER_MAPPING 0
-
-typedef struct {
- guint16 src_pan;
- guint16 src16;
- ieee802154_map_rec *map_rec;
-} ieee802154_hints_t;
/* Some Helper Function Definitions. */
-extern gchar *print_eui64(guint64);
-extern gchar *print_eui64_oui(guint64);
-extern proto_item *proto_tree_add_eui64(proto_tree *, int, tvbuff_t *, gint, gint, gint64);
-
-/* Short to Extended Address Prototypes */
-extern ieee802154_map_rec *ieee802154_addr_update(ieee802154_addr_t *, guint16, guint16, guint64, int, guint);
-extern guint ieee802154_short_addr_hash(gconstpointer);
-extern gboolean ieee802154_short_addr_equal(gconstpointer, gconstpointer);
-
+extern gchar *print_eui64(guint64);
+extern gchar *print_eui64_oui(guint64);
#endif /* PACKET_IEEE802154_H */
diff --git a/epan/dissectors/packet-zbee-aps.c b/epan/dissectors/packet-zbee-aps.c
index 9e468b3c23..48cc7b84e6 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,8 +67,6 @@ 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);
-
/********************
* Global Variables *
********************
@@ -78,7 +76,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_format = -1; /* ZigBee 2007 and later. */
+static int hf_zbee_aps_fcf_ack_mode = -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;
@@ -167,7 +165,6 @@ static const fragment_items zbee_aps_frag_items = {
/* Tag */
"APS Message fragments"
};
-
/********************/
/* Field Names */
/********************/
@@ -541,7 +538,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_info *pinfo - pointer to packet information fields
+ * packet_into *pinfo - pointer to packet information fields
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* RETURNS
* void
@@ -580,7 +577,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_format = zbee_get_bit_field(fcf, ZBEE_APS_FCF_ACK_FORMAT);
+ packet.ack_mode = zbee_get_bit_field(fcf, ZBEE_APS_FCF_ACK_MODE);
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);
@@ -606,7 +603,7 @@ 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_format, tvb, offset, sizeof(guint8), fcf & ZBEE_APS_FCF_ACK_FORMAT);
+ proto_tree_add_boolean(field_tree, hf_zbee_aps_fcf_ack_mode, tvb, offset, sizeof(guint8), fcf & ZBEE_APS_FCF_ACK_MODE);
}
}
else {
@@ -630,7 +627,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_format)) {
+ if ((pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) && (packet.ack_mode)) {
/* Command Ack: endpoint addressing does not exist. */
goto dissect_zbee_aps_no_endpt;
}
@@ -722,17 +719,17 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += sizeof(guint8);
}
- /* Get and display the profile ID. */
+ /* Get and display the profile ID if it exists. */
packet.profile = tvb_get_letohs(tvb, offset);
profile_handle = dissector_get_port_handle(zbee_aps_dissector_table, packet.profile);
if (tree) {
ti = proto_tree_add_uint(aps_tree, hf_zbee_aps_profile, tvb, offset, sizeof(guint16),
packet.profile);
+ offset += sizeof(guint16);
/* 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)) {
@@ -765,6 +762,7 @@ dissect_zbee_aps_no_endpt:
offset += sizeof(guint8);
}
+
/* Get and display the extended header, if present. */
if (packet.ext_header) {
fcf = tvb_get_guint8(tvb, offset);
@@ -1073,8 +1071,9 @@ dissect_zbee_aps_skke_challenge(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
offset += sizeof(guint64);
/* Get and display the SKKE data. */
+ tvb_ensure_bytes_exist(tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH);
if (tree) {
- proto_tree_add_item(tree, hf_zbee_aps_cmd_challenge, tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH, ENC_BIG_ENDIAN);
+ proto_tree_add_bytes(tree, hf_zbee_aps_cmd_challenge, tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH, ep_tvb_memdup(tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH));
}
offset += ZBEE_APS_CMD_SKKE_DATA_LENGTH;
@@ -1118,8 +1117,9 @@ dissect_zbee_aps_skke_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
offset += sizeof(guint64);
/* Get and display the SKKE data. */
+ tvb_ensure_bytes_exist(tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH);
if (tree) {
- proto_tree_add_item(tree, hf_zbee_aps_cmd_mac, tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH, ENC_BIG_ENDIAN);
+ proto_tree_add_bytes(tree, hf_zbee_aps_cmd_mac, tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH, ep_tvb_memdup(tvb, offset, ZBEE_APS_CMD_SKKE_DATA_LENGTH));
}
offset += ZBEE_APS_CMD_SKKE_DATA_LENGTH;
@@ -1144,12 +1144,9 @@ 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;
- guint8 key[ZBEE_APS_CMD_KEY_LENGTH];
- GSList **nwk_keyring;
- key_record_t key_record;
- zbee_nwk_hints_t *nwk_hints;
- guint i;
+ guint8 key_type;
+ gchar *key = ep_alloc(ZBEE_APS_CMD_KEY_LENGTH);
+ guint i;
/* Get and display the key type. */
key_type = tvb_get_guint8(tvb, offset);
@@ -1161,46 +1158,21 @@ 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++) {
- key[i] = tvb_get_guint8(tvb, offset+i);
+ 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 */
if (tree) {
- proto_tree_add_item(tree, hf_zbee_aps_cmd_key, tvb, offset, ZBEE_APS_CMD_KEY_LENGTH, ENC_BIG_ENDIAN);
+ proto_tree_add_bytes(tree, hf_zbee_aps_cmd_key, tvb, offset, ZBEE_APS_CMD_KEY_LENGTH, key);
}
offset += ZBEE_APS_CMD_KEY_LENGTH;
-
- /* Update the key ring for this pan */
- if ( !pinfo->fd->flags.visited &&
- (nwk_hints = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name(ZBEE_PROTOABBREV_NWK)))) {
-
- nwk_keyring = 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 = 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;
@@ -1257,7 +1229,7 @@ dissect_zbee_aps_transport_key(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
guint64 partner;
guint8 initiator;
- /* get and display the partner address. */
+ /* get and display the parter address. */
partner = tvb_get_letoh64(tvb, offset);
if (tree) {
proto_tree_add_eui64(tree, hf_zbee_aps_cmd_partner, tvb, offset, sizeof(guint64), partner);
@@ -1483,8 +1455,9 @@ dissect_zbee_aps_auth_challenge(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
offset += sizeof(guint64);
/* Get and display the challenge. */
+ tvb_ensure_bytes_exist(tvb, offset, ZBEE_APS_CMD_EA_CHALLENGE_LENGTH);
if (tree) {
- proto_tree_add_item(tree, hf_zbee_aps_cmd_challenge, tvb, offset, ZBEE_APS_CMD_EA_CHALLENGE_LENGTH, ENC_BIG_ENDIAN);
+ proto_tree_add_bytes(tree, hf_zbee_aps_cmd_challenge, tvb, offset, ZBEE_APS_CMD_EA_CHALLENGE_LENGTH, ep_tvb_memdup(tvb, offset, ZBEE_APS_CMD_EA_CHALLENGE_LENGTH));
}
offset += ZBEE_APS_CMD_EA_CHALLENGE_LENGTH;
@@ -1513,8 +1486,9 @@ dissect_zbee_aps_auth_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
guint8 data_type;
/* Get and display the MAC. */
+ tvb_ensure_bytes_exist(tvb, offset, ZBEE_APS_CMD_EA_MAC_LENGTH);
if (tree) {
- proto_tree_add_item(tree, hf_zbee_aps_cmd_mac, tvb, offset, ZBEE_APS_CMD_EA_MAC_LENGTH, ENC_BIG_ENDIAN);
+ proto_tree_add_bytes(tree, hf_zbee_aps_cmd_mac, tvb, offset, ZBEE_APS_CMD_EA_MAC_LENGTH, ep_tvb_memdup(tvb, offset, ZBEE_APS_CMD_EA_MAC_LENGTH));
}
offset += ZBEE_APS_CMD_EA_MAC_LENGTH;
@@ -1532,8 +1506,9 @@ dissect_zbee_aps_auth_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
offset += sizeof(guint8);
/* Get and display the data field. */
+ tvb_ensure_bytes_exist(tvb, offset, ZBEE_APS_CMD_EA_DATA_LENGTH);
if (tree) {
- proto_tree_add_item(tree, hf_zbee_aps_cmd_ea_data, tvb, offset, ZBEE_APS_CMD_EA_DATA_LENGTH, ENC_BIG_ENDIAN);
+ proto_tree_add_bytes(tree, hf_zbee_aps_cmd_ea_data, tvb, offset, ZBEE_APS_CMD_EA_DATA_LENGTH, ep_tvb_memdup(tvb, offset, ZBEE_APS_CMD_EA_DATA_LENGTH));
}
offset += ZBEE_APS_CMD_EA_DATA_LENGTH;
@@ -1570,8 +1545,7 @@ 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);
@@ -1611,8 +1585,7 @@ static void dissect_zbee_apf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
/* 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);
}
@@ -1746,6 +1719,24 @@ 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.
@@ -1770,8 +1761,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_format,
- { "Acknowledgement Format", "zbee.aps.ack_format", FT_BOOLEAN, 8, NULL, ZBEE_APS_FCF_ACK_FORMAT,
+ { &hf_zbee_aps_fcf_ack_mode,
+ { "Acknowledgement Mode", "zbee.aps.ack_mode", FT_BOOLEAN, 8, NULL, ZBEE_APS_FCF_ACK_MODE,
NULL, HFILL }},
{ &hf_zbee_aps_fcf_security,
@@ -1950,24 +1941,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_PROTOABBREV_APS);
+ proto_zbee_aps = proto_register_protocol("ZigBee Application Support Layer", "ZigBee APS", "zbee.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_PROTOABBREV_APS, dissect_zbee_aps, proto_zbee_aps);
+ register_dissector("zbee.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_PROTOABBREV_APF);
+ proto_zbee_apf = proto_register_protocol("ZigBee Application Framework", "ZigBee APF", "zbee.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_PROTOABBREV_APF, dissect_zbee_apf, proto_zbee_apf);
+ register_dissector("zbee.apf", dissect_zbee_apf, proto_zbee_apf);
} /* proto_register_zbee_aps */
/*FUNCTION:------------------------------------------------------
@@ -1985,25 +1976,7 @@ void proto_reg_handoff_zbee_aps(void)
{
/* Find the other dissectors we need. */
data_handle = find_dissector("data");
- zbee_aps_handle = find_dissector(ZBEE_PROTOABBREV_APS);
- zbee_apf_handle = find_dissector(ZBEE_PROTOABBREV_APF);
+ zbee_aps_handle = find_dissector("zbee.aps");
+ zbee_apf_handle = find_dissector("zbee.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 */
-
diff --git a/epan/dissectors/packet-zbee-aps.h b/epan/dissectors/packet-zbee-aps.h
index d8aa4b1e20..eb106d81e2 100644
--- a/epan/dissectors/packet-zbee-aps.h
+++ b/epan/dissectors/packet-zbee-aps.h
@@ -27,11 +27,39 @@
#ifndef PACKET_ZBEE_APS_H
#define PACKET_ZBEE_APS_H
+/* Structure to contain the APS frame information */
+typedef struct{
+ gboolean indirect_mode; /* ZigBee 2004 and Earlier */
+ gboolean ack_mode; /* ZigBee 2007 and Later */
+ gboolean security;
+ gboolean ack_req;
+ gboolean ext_header; /* ZigBee 2007 and Later */
+ guint8 type;
+ guint8 delivery;
+
+ guint8 dst;
+ guint16 group; /* ZigBee 2006 and Later */
+ guint16 cluster;
+ guint16 profile;
+ guint8 src;
+ guint8 counter;
+
+ /* Fragmentation Fields. */
+ guint8 fragmentation; /* ZigBee 2007 and Later */
+ guint8 block_number; /* ZigBee 2007 and Later */
+ guint8 ack_bitfield; /* ZigBee 2007 and Later */
+
+ /* Some helpers for the upper layers. */
+ gboolean profile_present;
+ gboolean dst_present;
+ gboolean src_present;
+} zbee_aps_packet;
+
/* ZigBee APS */
#define ZBEE_APS_FCF_FRAME_TYPE 0x03
#define ZBEE_APS_FCF_DELIVERY_MODE 0x0c
#define ZBEE_APS_FCF_INDIRECT_MODE 0x10 /* ZigBee 2004 and earlier. */
-#define ZBEE_APS_FCF_ACK_FORMAT 0x10 /* ZigBee 2007 and later. */
+#define ZBEE_APS_FCF_ACK_MODE 0x10 /* ZigBee 2007 and later. */
#define ZBEE_APS_FCF_SECURITY 0x20
#define ZBEE_APS_FCF_ACK_REQ 0x40
#define ZBEE_APS_FCF_EXT_HEADER 0x80
@@ -206,32 +234,4 @@
#define ZBEE_ZCL_CID_SMART_ENERGY_TUNNELING 0x0704
#define ZBEE_ZCL_CID_PRE_PAYMENT 0x0705
-/* Structure to contain the APS frame information */
-typedef struct{
- gboolean indirect_mode; /* ZigBee 2004 and Earlier */
- guint8 type;
- guint8 delivery;
- gboolean ack_format; /* ZigBee 2007 and Later */
- gboolean security;
- gboolean ack_req;
- gboolean ext_header; /* ZigBee 2007 and Later */
-
- guint8 dst;
- guint16 group; /* ZigBee 2006 and Later */
- guint16 cluster;
- guint16 profile;
- guint8 src;
- guint8 counter;
-
- /* Fragmentation Fields. */
- guint8 fragmentation; /* ZigBee 2007 and Later */
- guint8 block_number; /* ZigBee 2007 and Later */
- guint8 ack_bitfield; /* ZigBee 2007 and Later */
-
- /* Some helpers for the upper layers. */
- gboolean profile_present;
- gboolean dst_present;
- gboolean src_present;
-} zbee_aps_packet;
-
#endif /* PACKET_ZBEE_APS_H*/
diff --git a/epan/dissectors/packet-zbee-nwk.c b/epan/dissectors/packet-zbee-nwk.c
index 341ea94f78..006220a53e 100644
--- a/epan/dissectors/packet-zbee-nwk.c
+++ b/epan/dissectors/packet-zbee-nwk.c
@@ -40,10 +40,9 @@
#include <epan/expert.h>
#include <epan/value_string.h>
-#include "packet-ieee802154.h"
#include "packet-zbee.h"
-#include "packet-zbee-nwk.h"
#include "packet-zbee-security.h"
+#include "packet-zbee-nwk.h"
/*************************/
/* Function Declarations */
@@ -54,21 +53,16 @@ static void dissect_zbee_nwk_cmd (tvbuff_t *tvb, packet_info *pinfo, p
static void dissect_zbee_beacon (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
/* Command Dissector Helpers */
-static guint dissect_zbee_nwk_route_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- zbee_nwk_packet * packet, guint offset);
+static guint dissect_zbee_nwk_route_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, guint offset);
static guint dissect_zbee_nwk_route_rep (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
static guint dissect_zbee_nwk_status (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
static guint dissect_zbee_nwk_leave (tvbuff_t *tvb, proto_tree *tree, guint offset);
-static guint dissect_zbee_nwk_route_rec (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- zbee_nwk_packet * packet, guint offset);
-static guint dissect_zbee_nwk_rejoin_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- zbee_nwk_packet * packet, guint offset);
-static guint dissect_zbee_nwk_rejoin_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- zbee_nwk_packet * packet, guint offset);
+static guint dissect_zbee_nwk_route_rec (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, guint offset);
+static guint dissect_zbee_nwk_rejoin_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, guint offset);
+static guint dissect_zbee_nwk_rejoin_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet * packet, guint offset);
static guint dissect_zbee_nwk_link_status(tvbuff_t *tvb, proto_tree *tree, guint offset);
static guint dissect_zbee_nwk_report (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
static guint dissect_zbee_nwk_update (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
-static void proto_init_zbee_nwk (void);
/********************/
@@ -92,7 +86,6 @@ static int hf_zbee_nwk_mcast_radius = -1;
static int hf_zbee_nwk_mcast_max_radius = -1;
static int hf_zbee_nwk_dst64 = -1;
static int hf_zbee_nwk_src64 = -1;
-static int hf_zbee_nwk_src64_origin = -1;
static int hf_zbee_nwk_relay_count = -1;
static int hf_zbee_nwk_relay_index = -1;
@@ -250,14 +243,28 @@ static const value_string zbee_nwk_stack_profiles[] = {
{ 0, NULL }
};
-/* TODO: much of the following copied from ieee80154 dissector */
-/*-------------------------------------
- * Hash Tables and Lists
- *-------------------------------------
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_tree_add_eui64
+ * DESCRIPTION
+ * Helper function to display an EUI-64 address to the tree.
+ * PARAMETERS
+ * proto_tree *tree
+ * int hfindex
+ * tvbuff_t *tvb
+ * gint start
+ * gint length
+ * guint64 value;
+ * RETURNS
+ * proto_item *
+ *---------------------------------------------------------------
*/
-static ieee802154_addr_t zbee_nwk_addr = { 0, NULL, NULL };
-GHashTable *zbee_table_nwk_keyring = NULL;
-GHashTable *zbee_table_link_keyring = NULL;
+proto_item *
+proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length, gint64 value)
+{
+ header_field_info *hf = proto_registrar_get_nth(hfindex);
+ return proto_tree_add_uint64_format(tree, hfindex, tvb, start, length, value, "%s: %s (%s)", hf->name, print_eui64_oui(value), print_eui64(value));
+}
/*FUNCTION:------------------------------------------------------
* NAME
@@ -351,41 +358,19 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree *field_tree = NULL;
zbee_nwk_packet packet;
- ieee802154_packet *ieee_packet = pinfo->private_data;
guint offset = 0;
gchar *src_addr = ep_alloc(32);
gchar *dst_addr = ep_alloc(32);
guint16 fcf;
-
- ieee802154_short_addr addr16;
- ieee802154_map_rec *map_rec;
- ieee802154_hints_t *ieee_hints;
-
- zbee_nwk_hints_t *nwk_hints;
- gboolean unicast_src;
-
memset(&packet, 0, sizeof(packet));
- /* Set up hint structures */
- if (!pinfo->fd->flags.visited) {
- /* Allocate frame data with hints for upper layers */
- nwk_hints = se_alloc0(sizeof(zbee_nwk_hints_t));
- p_add_proto_data(pinfo->fd, proto_zbee_nwk, nwk_hints);
- } else {
- /* Retrieve existing structure */
- nwk_hints = p_get_proto_data(pinfo->fd, proto_zbee_nwk);
- }
-
- ieee_hints = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN));
-
/* Add ourself to the protocol column, clear the info column, and create the protocol tree. */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee");
col_clear(pinfo->cinfo, COL_INFO);
if (tree) {
- proto_root = proto_tree_add_protocol_format(tree, proto_zbee_nwk, tvb, offset,
- tvb_length(tvb), "ZigBee Network Layer");
+ proto_root = proto_tree_add_protocol_format(tree, proto_zbee_nwk, tvb, offset, tvb_length(tvb), "ZigBee Network Layer");
nwk_tree = proto_item_add_subtree(proto_root, ett_zbee_nwk);
}
@@ -407,27 +392,19 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ti = proto_tree_add_text(nwk_tree, tvb, offset, sizeof(guint16), "Frame Control Field: %s (0x%04x)",
val_to_str(packet.type, zbee_nwk_frame_types, "Unknown"), fcf);
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_fcf);
- proto_tree_add_uint(field_tree, hf_zbee_nwk_frame_type, tvb, offset, sizeof(guint8),
- fcf & ZBEE_NWK_FCF_FRAME_TYPE);
+ proto_tree_add_uint(field_tree, hf_zbee_nwk_frame_type, tvb, offset, sizeof(guint8), fcf & ZBEE_NWK_FCF_FRAME_TYPE);
/* Add the rest of the fcf fields to the subtree */
- proto_tree_add_uint(field_tree, hf_zbee_nwk_proto_version, tvb, offset, sizeof(guint8),
- fcf & ZBEE_NWK_FCF_VERSION);
- proto_tree_add_uint(field_tree, hf_zbee_nwk_discover_route, tvb, offset, sizeof(guint8),
- fcf & ZBEE_NWK_FCF_DISCOVER_ROUTE);
+ proto_tree_add_uint(field_tree, hf_zbee_nwk_proto_version, tvb, offset, sizeof(guint8), fcf & ZBEE_NWK_FCF_VERSION);
+ proto_tree_add_uint(field_tree, hf_zbee_nwk_discover_route, tvb, offset, sizeof(guint8), fcf & ZBEE_NWK_FCF_DISCOVER_ROUTE);
if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_multicast, tvb, offset+sizeof(guint8),
- sizeof(guint8), fcf & ZBEE_NWK_FCF_MULTICAST);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_multicast, tvb, offset+sizeof(guint8), sizeof(guint8), fcf & ZBEE_NWK_FCF_MULTICAST);
}
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_security, tvb, offset+sizeof(guint8),
- sizeof(guint8), fcf & ZBEE_NWK_FCF_SECURITY);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_security, tvb, offset+sizeof(guint8), sizeof(guint8), fcf & ZBEE_NWK_FCF_SECURITY);
if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_source_route, tvb, offset+sizeof(guint8),
- sizeof(guint8), fcf & ZBEE_NWK_FCF_SOURCE_ROUTE);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_ext_dst, tvb, offset+sizeof(guint8),
- sizeof(guint8), fcf & ZBEE_NWK_FCF_EXT_DEST);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_ext_src, tvb, offset+sizeof(guint8),
- sizeof(guint8), fcf & ZBEE_NWK_FCF_EXT_SOURCE);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_source_route, tvb, offset+sizeof(guint8), sizeof(guint8), fcf & ZBEE_NWK_FCF_SOURCE_ROUTE);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_ext_dst, tvb, offset+sizeof(guint8), sizeof(guint8), fcf & ZBEE_NWK_FCF_EXT_DEST);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_ext_src, tvb, offset+sizeof(guint8), sizeof(guint8), fcf & ZBEE_NWK_FCF_EXT_SOURCE);
}
}
offset += sizeof(guint16);
@@ -453,13 +430,9 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|| (packet.dst == ZBEE_BCAST_ROUTERS)){
g_snprintf(dst_addr, 32, "Broadcast");
}
- else {
- g_snprintf(dst_addr, 32, "0x%04x", packet.dst);
- }
-
+ else g_snprintf(dst_addr, 32, "0x%04x", packet.dst);
SET_ADDRESS(&pinfo->dst, AT_STRINGZ, (int)strlen(dst_addr)+1, dst_addr);
SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, (int)strlen(dst_addr)+1, dst_addr);
-
if (tree) {
proto_item_append_text(proto_root, ", Dst: %s", dst_addr);
}
@@ -467,9 +440,9 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", dst_addr);
}
- /* Get the short nwk source address. */
+ /* Get the source address. */
packet.src = tvb_get_letohs(tvb, offset);
- if (tree) {
+ if(tree){
proto_tree_add_uint(nwk_tree, hf_zbee_nwk_src, tvb, offset, sizeof(guint16), packet.src);
}
offset += sizeof(guint16);
@@ -479,17 +452,11 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|| (packet.src == ZBEE_BCAST_ACTIVE)
|| (packet.src == ZBEE_BCAST_ROUTERS)){
/* Source Broadcast doesn't make much sense. */
- g_snprintf(src_addr, 32, "Unexpected Source Broadcast");
- unicast_src = FALSE;
- }
- else {
- g_snprintf(src_addr, 32, "0x%04x", packet.src);
- unicast_src = TRUE;
+ g_snprintf(src_addr, 32, "Broadcast");
}
-
+ else g_snprintf(src_addr, 32, "0x%04x", packet.src);
SET_ADDRESS(&pinfo->src, AT_STRINGZ, (int)strlen(src_addr)+1, src_addr);
SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, (int)strlen(src_addr)+1, src_addr);
-
if (tree) {
proto_item_append_text(proto_root, ", Src: %s", src_addr);
}
@@ -523,12 +490,9 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ti = proto_tree_add_text(nwk_tree, tvb, offset, sizeof(guint8), "Multicast Control Field");
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_mcast);
/* Add the fields. */
- ti = proto_tree_add_uint(field_tree, hf_zbee_nwk_mcast_mode, tvb, offset, sizeof(guint8),
- mcast_control & ZBEE_NWK_MCAST_MODE);
- proto_tree_add_uint(field_tree, hf_zbee_nwk_mcast_radius, tvb, offset, sizeof(guint8),
- mcast_control & ZBEE_NWK_MCAST_RADIUS);
- proto_tree_add_uint(field_tree, hf_zbee_nwk_mcast_max_radius, tvb, offset, sizeof(guint8),
- mcast_control & ZBEE_NWK_MCAST_MAX_RADIUS);
+ ti = proto_tree_add_uint(field_tree, hf_zbee_nwk_mcast_mode, tvb, offset, sizeof(guint8), mcast_control & ZBEE_NWK_MCAST_MODE);
+ proto_tree_add_uint(field_tree, hf_zbee_nwk_mcast_radius, tvb, offset, sizeof(guint8), mcast_control & ZBEE_NWK_MCAST_RADIUS);
+ proto_tree_add_uint(field_tree, hf_zbee_nwk_mcast_max_radius, tvb, offset, sizeof(guint8), mcast_control & ZBEE_NWK_MCAST_MAX_RADIUS);
}
offset += sizeof(guint8);
}
@@ -542,79 +506,14 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += sizeof(guint64);
}
- /* Display the extended source address. (ZigBee 2006 and later). */
- if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
- addr16.pan = ieee_packet->src_pan;
-
- if (packet.ext_src) {
- packet.src64 = tvb_get_letoh64(tvb, offset);
- if (tree) {
- proto_tree_add_eui64(nwk_tree, hf_zbee_nwk_src64, tvb, offset, sizeof(guint64), packet.src64);
- }
- offset += sizeof(guint64);
-
- if (!pinfo->fd->flags.visited) {
- /* Provide hints to upper layers */
- nwk_hints->src_pan = ieee_packet->src_pan;
-
- /* Update nwk extended address hash table */
- if ( unicast_src ) {
- nwk_hints->map_rec = ieee802154_addr_update(&zbee_nwk_addr,
- packet.src, addr16.pan, packet.src64, proto_zbee_nwk, pinfo->fd->num);
- }
- }
- }
- else {
- /* See if extended source info was previously sniffed */
- if (!pinfo->fd->flags.visited) {
- nwk_hints->src_pan = ieee_packet->src_pan;
- addr16.addr = packet.src;
-
- map_rec = (ieee802154_map_rec *) g_hash_table_lookup(zbee_nwk_addr.short_table, &addr16);
- if (map_rec) {
- /* found a nwk mapping record */
- nwk_hints->map_rec = map_rec;
- }
- else {
- /* does ieee layer know? */
- map_rec = (ieee802154_map_rec *) g_hash_table_lookup(ieee_packet->short_table, &addr16);
- if (map_rec) nwk_hints->map_rec = map_rec;
- }
- } /* (!pinfo->fd->flags.visited) */
- else {
- if (tree && nwk_hints && nwk_hints->map_rec ) {
- /* Display inferred source address info */
- ti = proto_tree_add_eui64(nwk_tree, hf_zbee_nwk_src64, tvb, offset, 0,
- nwk_hints->map_rec->addr64);
- PROTO_ITEM_SET_GENERATED(ti);
-
- if ( nwk_hints->map_rec->start_fnum ) {
- ti = proto_tree_add_uint(nwk_tree, hf_zbee_nwk_src64_origin, tvb, 0, 0,
- nwk_hints->map_rec->start_fnum);
- }
- else {
- ti = proto_tree_add_text(nwk_tree, tvb, 0, 0, "Origin: Pre-configured");
- }
- PROTO_ITEM_SET_GENERATED(ti);
- }
- }
+ /* Add the extended source address. (ZigBee 2006 and later). */
+ if ((pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) && packet.ext_src) {
+ packet.src64 = tvb_get_letoh64(tvb, offset);
+ if (tree) {
+ proto_tree_add_eui64(nwk_tree, hf_zbee_nwk_src64, tvb, offset, sizeof(guint64), packet.src64);
}
-
- /* If ieee layer didn't know its extended source address, and nwk layer does, fill it in */
- if (!pinfo->fd->flags.visited) {
- if ( (ieee_packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) &&
- ieee_hints && !ieee_hints->map_rec ) {
- addr16.pan = ieee_packet->src_pan;
- addr16.addr = ieee_packet->src16;
- map_rec = (ieee802154_map_rec *) g_hash_table_lookup(zbee_nwk_addr.short_table, &addr16);
-
- if (map_rec) {
- /* found a ieee mapping record */
- ieee_hints->map_rec = map_rec;
- }
- }
- } /* (!pinfo->fd->flags.visited */
- } /* (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) */
+ offset += sizeof(guint64);
+ }
/* Add the Source Route field. (ZigBee 2006 and later). */
if ((pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) && packet.route) {
@@ -710,7 +609,7 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* dissect_zbee_nwk_cmd
* DESCRIPTION
* ZigBee Network command packet dissection routine for Wireshark.
- * note: this dissector differs from others in that it shouldn't be
+ * note: this dissector differs from others in that is shouldn't be
* passed the main tree pointer, but the nwk tree instead.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
@@ -732,8 +631,7 @@ static void dissect_zbee_nwk_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
/* Create a subtree for this command. */
if (tree) {
- cmd_root = proto_tree_add_text(tree, tvb, offset, tvb_length(tvb), "Command Frame: %s",
- val_to_str(cmd_id, zbee_nwk_cmd_names, "Unknown"));
+ cmd_root = proto_tree_add_text(tree, tvb, offset, tvb_length(tvb), "Command Frame: %s", val_to_str(cmd_id, zbee_nwk_cmd_names, "Unknown"));
cmd_tree = proto_item_add_subtree(cmd_root, ett_zbee_nwk_cmd);
/* Add the command ID. */
@@ -856,16 +754,12 @@ dissect_zbee_nwk_route_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_options);
if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_route_opt_multicast, tvb, offset,
- sizeof(guint8), route_options & ZBEE_NWK_CMD_ROUTE_OPTION_MCAST);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_route_opt_dest_ext, tvb, offset,
- sizeof(guint8), route_options & ZBEE_NWK_CMD_ROUTE_OPTION_DEST_EXT);
- proto_tree_add_uint(field_tree, hf_zbee_nwk_cmd_route_opt_many_to_one, tvb, offset,
- sizeof(guint8), route_options & ZBEE_NWK_CMD_ROUTE_OPTION_MANY_MASK);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_route_opt_multicast, tvb, offset, sizeof(guint8), route_options & ZBEE_NWK_CMD_ROUTE_OPTION_MCAST);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_route_opt_dest_ext, tvb, offset, sizeof(guint8), route_options & ZBEE_NWK_CMD_ROUTE_OPTION_DEST_EXT);
+ proto_tree_add_uint(field_tree, hf_zbee_nwk_cmd_route_opt_many_to_one, tvb, offset, sizeof(guint8), route_options & ZBEE_NWK_CMD_ROUTE_OPTION_MANY_MASK);
}
else {
- proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_route_opt_repair, tvb, offset, sizeof(guint8),
- route_options & ZBEE_NWK_CMD_ROUTE_OPTION_REPAIR);
+ proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_route_opt_repair, tvb, offset, sizeof(guint8), route_options & ZBEE_NWK_CMD_ROUTE_OPTION_REPAIR);
}
}
offset += sizeof(guint8);
@@ -1074,12 +968,9 @@ dissect_zbee_nwk_leave(tvbuff_t *tvb, proto_tree *tree, guint offset)
/* Get and display the leave options. */
leave_options = tvb_get_guint8(tvb, offset);
if (tree) {
- proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_leave_rejoin, tvb, offset, sizeof(guint8),
- leave_options & ZBEE_NWK_CMD_LEAVE_OPTION_REJOIN);
- proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_leave_request, tvb, offset, sizeof(guint8),
- leave_options & ZBEE_NWK_CMD_LEAVE_OPTION_REQUEST);
- proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_leave_children, tvb, offset, sizeof(guint8),
- leave_options & ZBEE_NWK_CMD_LEAVE_OPTION_CHILDREN);
+ proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_leave_rejoin, tvb, offset, sizeof(guint8), leave_options & ZBEE_NWK_CMD_LEAVE_OPTION_REJOIN);
+ proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_leave_request, tvb, offset, sizeof(guint8), leave_options & ZBEE_NWK_CMD_LEAVE_OPTION_REQUEST);
+ proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_leave_children, tvb, offset, sizeof(guint8), leave_options & ZBEE_NWK_CMD_LEAVE_OPTION_CHILDREN);
}
offset += sizeof(guint8);
@@ -1165,18 +1056,12 @@ dissect_zbee_nwk_rejoin_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_cinfo);
/* Add the capability info flags. */
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_alt_coord, tvb, offset, sizeof(guint8),
- capabilities & ZBEE_CINFO_ALT_COORD);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_type, tvb, offset, sizeof(guint8),
- capabilities & ZBEE_CINFO_FFD);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_power, tvb, offset, sizeof(guint8),
- capabilities & ZBEE_CINFO_POWER);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_idle_rx, tvb, offset, sizeof(guint8),
- capabilities & ZBEE_CINFO_IDLE_RX);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_security, tvb, offset, sizeof(guint8),
- capabilities & ZBEE_CINFO_SECURITY);
- proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_alloc, tvb, offset, sizeof(guint8),
- capabilities & ZBEE_CINFO_ALLOC);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_alt_coord, tvb, offset, sizeof(guint8), capabilities & ZBEE_CINFO_ALT_COORD);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_type, tvb, offset, sizeof(guint8), capabilities & ZBEE_CINFO_FFD);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_power, tvb, offset, sizeof(guint8), capabilities & ZBEE_CINFO_POWER);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_idle_rx, tvb, offset, sizeof(guint8), capabilities & ZBEE_CINFO_IDLE_RX);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_security, tvb, offset, sizeof(guint8), capabilities & ZBEE_CINFO_SECURITY);
+ proto_tree_add_boolean(field_tree, hf_zbee_nwk_cmd_cinfo_alloc, tvb, offset, sizeof(guint8), capabilities & ZBEE_CINFO_ALLOC);
}
offset += sizeof(guint8);
@@ -1262,10 +1147,8 @@ dissect_zbee_nwk_link_status(tvbuff_t *tvb, proto_tree *tree, guint offset)
options = tvb_get_guint8(tvb, offset);
link_count = options & ZBEE_NWK_CMD_LINK_OPTION_COUNT_MASK;
if (tree) {
- proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_link_last, tvb, offset, sizeof(guint8),
- options & ZBEE_NWK_CMD_LINK_OPTION_LAST_FRAME);
- proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_link_first, tvb, offset, sizeof(guint8),
- options & ZBEE_NWK_CMD_LINK_OPTION_FIRST_FRAME);
+ proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_link_last, tvb, offset, sizeof(guint8), options & ZBEE_NWK_CMD_LINK_OPTION_LAST_FRAME);
+ proto_tree_add_boolean(tree, hf_zbee_nwk_cmd_link_first, tvb, offset, sizeof(guint8), options & ZBEE_NWK_CMD_LINK_OPTION_FIRST_FRAME);
proto_tree_add_uint(tree, hf_zbee_nwk_cmd_link_count, tvb, offset, sizeof(guint8), link_count);
}
offset += sizeof(guint8);
@@ -1276,10 +1159,7 @@ dissect_zbee_nwk_link_status(tvbuff_t *tvb, proto_tree *tree, guint offset)
addr = tvb_get_letohs(tvb, offset);
options = tvb_get_guint8(tvb, offset+sizeof(guint16));
if (tree) {
- proto_tree_add_text(tree, tvb, offset, sizeof(guint16)+sizeof(guint8),
- "0x%04x, Incoming Cost: %d Outgoing Cost: %d", addr,
- options & ZBEE_NWK_CMD_LINK_INCOMMING_COST_MASK,
- (options & ZBEE_NWK_CMD_LINK_OUTGOING_COST_MASK)>>4);
+ proto_tree_add_text(tree, tvb, offset, sizeof(guint16)+sizeof(guint8), "0x%04x, Incoming Cost: %d Outgoing Cost: %d", addr, options & ZBEE_NWK_CMD_LINK_INCOMMING_COST_MASK, (options & ZBEE_NWK_CMD_LINK_OUTGOING_COST_MASK)>>4);
}
offset += (sizeof(guint16)+sizeof(guint8));
} /* for */
@@ -1457,7 +1337,7 @@ static void dissect_zbee_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
/* Update the info column. */
if(check_col(pinfo->cinfo, COL_INFO)) {
col_clear(pinfo->cinfo, COL_INFO);
- col_append_fstr(pinfo->cinfo, COL_INFO, "Beacon, Src: 0x%04x", packet->src16);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Beacon, Src: 0x%04x", packet->src.addr16);
}
/* Get and display the protocol id, must be 0 on all ZigBee beacons. */
@@ -1471,8 +1351,7 @@ static void dissect_zbee_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
temp = tvb_get_guint8(tvb, offset);
pinfo->zbee_stack_vers = version = zbee_get_bit_field(temp, ZBEE_NWK_BEACON_PROTOCOL_VERSION);
if (tree) {
- proto_tree_add_uint(beacon_tree, hf_zbee_beacon_stack_profile, tvb, offset, sizeof(guint8),
- zbee_get_bit_field(temp, ZBEE_NWK_BEACON_STACK_PROFILE));
+ proto_tree_add_uint(beacon_tree, hf_zbee_beacon_stack_profile, tvb, offset, sizeof(guint8), zbee_get_bit_field(temp, ZBEE_NWK_BEACON_STACK_PROFILE));
proto_tree_add_uint(beacon_tree, hf_zbee_beacon_version, tvb, offset, sizeof(guint8), version);
}
offset += sizeof(guint8);
@@ -1480,12 +1359,9 @@ static void dissect_zbee_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
/* Get and display the security level and flags. */
temp = tvb_get_guint8(tvb, offset);
if (tree) {
- proto_tree_add_boolean(beacon_tree, hf_zbee_beacon_router_capacity, tvb, offset, sizeof(guint8),
- zbee_get_bit_field(temp, ZBEE_NWK_BEACON_ROUTER_CAPACITY));
- proto_tree_add_uint(beacon_tree, hf_zbee_beacon_depth, tvb, offset, sizeof(guint8),
- zbee_get_bit_field(temp, ZBEE_NWK_BEACON_NETWORK_DEPTH));
- proto_tree_add_boolean(beacon_tree, hf_zbee_beacon_end_device_capacity, tvb, offset, sizeof(guint8),
- zbee_get_bit_field(temp, ZBEE_NWK_BEACON_END_DEVICE_CAPACITY));
+ proto_tree_add_boolean(beacon_tree, hf_zbee_beacon_router_capacity, tvb, offset, sizeof(guint8), zbee_get_bit_field(temp, ZBEE_NWK_BEACON_ROUTER_CAPACITY));
+ proto_tree_add_uint(beacon_tree, hf_zbee_beacon_depth, tvb, offset, sizeof(guint8), zbee_get_bit_field(temp, ZBEE_NWK_BEACON_NETWORK_DEPTH));
+ proto_tree_add_boolean(beacon_tree, hf_zbee_beacon_end_device_capacity, tvb, offset, sizeof(guint8), zbee_get_bit_field(temp, ZBEE_NWK_BEACON_END_DEVICE_CAPACITY));
}
offset += sizeof(guint8);
@@ -1493,8 +1369,7 @@ static void dissect_zbee_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
/* In ZigBee 2006 and later, the beacon contains an extended PAN ID. */
epid = tvb_get_letoh64(tvb, offset);
if (tree) {
- proto_tree_add_uint64_format_value(beacon_tree, hf_zbee_beacon_epid, tvb, offset, sizeof(guint64),
- epid, "%s", print_eui64(epid));
+ proto_tree_add_uint64_format_value(beacon_tree, hf_zbee_beacon_epid, tvb, offset, sizeof(guint64), epid, "%s", print_eui64(epid));
}
offset += sizeof(guint64);
@@ -1570,16 +1445,15 @@ void proto_register_zbee_nwk(void)
static hf_register_info hf[] = {
{ &hf_zbee_nwk_frame_type,
- { "Frame Type", "zbee.nwk.frame_type", FT_UINT16, BASE_HEX, VALS(zbee_nwk_frame_types),
- ZBEE_NWK_FCF_FRAME_TYPE, NULL, HFILL }},
+ { "Frame Type", "zbee.nwk.frame_type", FT_UINT16, BASE_HEX, VALS(zbee_nwk_frame_types), ZBEE_NWK_FCF_FRAME_TYPE,
+ NULL, HFILL }},
{ &hf_zbee_nwk_proto_version,
{ "Protocol Version", "zbee.nwk.proto_version", FT_UINT16, BASE_DEC, NULL, ZBEE_NWK_FCF_VERSION,
NULL, HFILL }},
{ &hf_zbee_nwk_discover_route,
- { "Discover Route", "zbee.nwk.discovery", FT_UINT16, BASE_HEX, VALS(zbee_nwk_discovery_modes),
- ZBEE_NWK_FCF_DISCOVER_ROUTE,
+ { "Discover Route", "zbee.nwk.discovery", FT_UINT16, BASE_HEX, VALS(zbee_nwk_discovery_modes), ZBEE_NWK_FCF_DISCOVER_ROUTE,
"Determines how route discovery may be handled, if at all.", HFILL }},
{ &hf_zbee_nwk_multicast,
@@ -1595,7 +1469,7 @@ void proto_register_zbee_nwk(void)
NULL, HFILL }},
{ &hf_zbee_nwk_ext_dst,
- { "Destination", "zbee.nwk.ext_dst", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_EXT_DEST,
+ { "Extended Destination", "zbee.nwk.ext_dst", FT_BOOLEAN, 16, NULL, ZBEE_NWK_FCF_EXT_DEST,
NULL, HFILL }},
{ &hf_zbee_nwk_ext_src,
@@ -1620,27 +1494,22 @@ void proto_register_zbee_nwk(void)
{ &hf_zbee_nwk_mcast_mode,
{ "Multicast Mode", "zbee.nwk.multicast.mode", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_MCAST_MODE,
- "Controls whether this packet is permitted to be routed through non-members of the multicast group.",
- HFILL }},
+ "Controls whether this packet is permitted to be routed through non-members of the multicast group.", HFILL }},
{ &hf_zbee_nwk_mcast_radius,
{ "Non-Member Radius", "zbee.nwk.multicast.radius", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_MCAST_RADIUS,
"Limits the range of multicast packets when being routed through non-members.", HFILL }},
{ &hf_zbee_nwk_mcast_max_radius,
- { "Max Non-Member Radius", "zbee.nwk.multicast.max_radius", FT_UINT8, BASE_DEC, NULL,
- ZBEE_NWK_MCAST_MAX_RADIUS, NULL, HFILL }},
+ { "Max Non-Member Radius", "zbee.nwk.multicast.max_radius", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_MCAST_MAX_RADIUS,
+ NULL, HFILL }},
{ &hf_zbee_nwk_dst64,
- { "Destination", "zbee.nwk.dst64", FT_UINT64, BASE_HEX, NULL, 0x0,
+ { "Extended Destination", "zbee.nwk.dst64", FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL }},
{ &hf_zbee_nwk_src64,
- { "Extended Source", "zbee.nwk.src64", FT_UINT64, BASE_HEX, NULL, 0x0,
- NULL, HFILL }},
-
- { &hf_zbee_nwk_src64_origin,
- { "Origin", "zbee.nwk.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ { "Extended Source", "zbee.nwk.scr64", FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL }},
{ &hf_zbee_nwk_relay_count,
@@ -1692,30 +1561,27 @@ void proto_register_zbee_nwk(void)
"A value specifying the efficiency of this route.", HFILL }},
{ &hf_zbee_nwk_cmd_route_opt_repair,
- { "Route Repair", "zbee.nwk.cmd.route.opts.repair", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_ROUTE_OPTION_REPAIR,
+ { "Route Repair", "zbee.nwk.cmd.route.opts.repair", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_ROUTE_OPTION_REPAIR,
"Flag identifying whether the route request command was to repair a failed route.", HFILL }},
{ &hf_zbee_nwk_cmd_route_opt_multicast,
- { "Multicast", "zbee.nwk.cmd.route.opts.mcast", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_ROUTE_OPTION_MCAST,
+ { "Multicast", "zbee.nwk.cmd.route.opts.mcast", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_ROUTE_OPTION_MCAST,
"Flag identifying this as a multicast route request.", HFILL }},
{ &hf_zbee_nwk_cmd_route_opt_dest_ext,
- { "Extended Destination", "zbee.nwk.cmd.route.opts.dest_ext", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_ROUTE_OPTION_DEST_EXT, NULL, HFILL }},
+ { "Extended Destination", "zbee.nwk.cmd.route.opts.dest_ext", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_ROUTE_OPTION_DEST_EXT,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_route_opt_resp_ext,
- { "Extended Responder", "zbee.nwk.cmd.route.opts.resp_ext", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_ROUTE_OPTION_RESP_EXT, NULL, HFILL }},
+ { "Extended Responder", "zbee.nwk.cmd.route.opts.resp_ext", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_ROUTE_OPTION_RESP_EXT,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_route_opt_orig_ext,
- { "Extended Originator", "zbee.nwk.cmd.route.opts.orig_ext", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_ROUTE_OPTION_ORIG_EXT, NULL, HFILL }},
+ { "Extended Originator", "zbee.nwk.cmd.route.opts.orig_ext", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_ROUTE_OPTION_ORIG_EXT,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_route_opt_many_to_one,
- { "Many-to-One Discovery", "zbee.nwk.cmd.route.opts.many2one", FT_UINT8, BASE_HEX,
- VALS(zbee_nwk_cmd_route_many_modes), ZBEE_NWK_CMD_ROUTE_OPTION_MANY_MASK,
+ { "Many-to-One Discovery", "zbee.nwk.cmd.route.opts.many2one", FT_UINT8, BASE_HEX, VALS(zbee_nwk_cmd_route_many_modes), ZBEE_NWK_CMD_ROUTE_OPTION_MANY_MASK,
NULL, HFILL }},
{ &hf_zbee_nwk_cmd_nwk_status,
@@ -1723,17 +1589,15 @@ void proto_register_zbee_nwk(void)
NULL, HFILL }},
{ &hf_zbee_nwk_cmd_leave_rejoin,
- { "Rejoin", "zbee.nwk.cmd.leave.rejoin", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_LEAVE_OPTION_REJOIN, "Flag instructing the device to rejoin the network.", HFILL }},
+ { "Rejoin", "zbee.nwk.cmd.leave.rejoin", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_LEAVE_OPTION_REJOIN,
+ "Flag instructing the device to rejoin the network.", HFILL }},
{ &hf_zbee_nwk_cmd_leave_request,
- { "Request", "zbee.nwk.cmd.leave.request", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_LEAVE_OPTION_REQUEST,
+ { "Request", "zbee.nwk.cmd.leave.request", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_LEAVE_OPTION_REQUEST,
"Flag identifying the direction of this command. 1=Request, 0=Indication", HFILL }},
{ &hf_zbee_nwk_cmd_leave_children,
- { "Remove Children", "zbee.nwk.cmd.leave.children", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_LEAVE_OPTION_CHILDREN,
+ { "Remove Children", "zbee.nwk.cmd.leave.children", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_LEAVE_OPTION_CHILDREN,
"Flag instructing the device to remove its children in addition to itself.", HFILL }},
{ &hf_zbee_nwk_cmd_relay_count,
@@ -1741,66 +1605,60 @@ void proto_register_zbee_nwk(void)
"Number of relays required to route to the destination.", HFILL }},
{ &hf_zbee_nwk_cmd_cinfo_alt_coord,
- { "Alternate Coordinator", "zbee.nwk.cmd.cinfo.alt_coord", FT_BOOLEAN, 8, NULL,
- IEEE802154_CMD_CINFO_ALT_PAN_COORD,
+ { "Alternate Coordinator", "zbee.nwk.cmd.cinfo.alt_coord", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALT_PAN_COORD,
"Indicates that the device is able to operate as a PAN coordinator.", HFILL }},
{ &hf_zbee_nwk_cmd_cinfo_type,
- { "Full-Function Device", "zbee.nwk.cmd.cinfo.ffd", FT_BOOLEAN, 8, NULL,
- IEEE802154_CMD_CINFO_DEVICE_TYPE, NULL, HFILL }},
+ { "Full-Function Device", "zbee.nwk.cmd.cinfo.ffd", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_DEVICE_TYPE,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_cinfo_power,
- { "AC Power", "zbee.nwk.cmd.cinfo.power", FT_BOOLEAN, 8, NULL,
- IEEE802154_CMD_CINFO_POWER_SRC, "Indicates this device is using AC/Mains power.", HFILL }},
+ { "AC Power", "zbee.nwk.cmd.cinfo.power", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_POWER_SRC,
+ "Indicates this device is using AC/Mains power.", HFILL }},
{ &hf_zbee_nwk_cmd_cinfo_idle_rx,
- { "Rx On When Idle", "zbee.nwk.cmd.cinfo.power", FT_BOOLEAN, 8, NULL,
- IEEE802154_CMD_CINFO_IDLE_RX,
+ { "Rx On When Idle", "zbee.nwk.cmd.cinfo.power", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_IDLE_RX,
"Indicates the receiver is active when the device is idle.", HFILL }},
{ &hf_zbee_nwk_cmd_cinfo_security,
- { "Security Capability", "zbee.nwk.cmd.cinfo.security", FT_BOOLEAN, 8, NULL,
- IEEE802154_CMD_CINFO_SEC_CAPABLE,
+ { "Security Capability", "zbee.nwk.cmd.cinfo.security", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_SEC_CAPABLE,
"Indicates this device is capable of performing encryption/decryption.", HFILL }},
{ &hf_zbee_nwk_cmd_cinfo_alloc,
- { "Allocate Short Address", "zbee.nwk.cmd.cinfo.alloc", FT_BOOLEAN, 8, NULL,
- IEEE802154_CMD_CINFO_ALLOC_ADDR,
+ { "Allocate Short Address", "zbee.nwk.cmd.cinfo.alloc", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALLOC_ADDR,
"Flag requesting the parent to allocate a short address for this device.", HFILL }},
{ &hf_zbee_nwk_cmd_rejoin_status,
- { "Status", "zbee.nwk.cmd.rejoin_status", FT_UINT8, BASE_HEX,
- VALS(zbee_nwk_rejoin_codes), 0x0, NULL, HFILL }},
+ { "Status", "zbee.nwk.cmd.rejoin_status", FT_UINT8, BASE_HEX, VALS(zbee_nwk_rejoin_codes), 0x0,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_link_last,
- { "Last Frame", "zbee.nwk.cmd.link.last", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_LINK_OPTION_LAST_FRAME,
+ { "Last Frame", "zbee.nwk.cmd.link.last", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_LINK_OPTION_LAST_FRAME,
"Flag indicating the last in a series of link status commands.", HFILL }},
{ &hf_zbee_nwk_cmd_link_first,
- { "First Frame", "zbee.nwk.cmd.link.first", FT_BOOLEAN, 8, NULL,
- ZBEE_NWK_CMD_LINK_OPTION_FIRST_FRAME,
+ { "First Frame", "zbee.nwk.cmd.link.first", FT_BOOLEAN, 8, NULL, ZBEE_NWK_CMD_LINK_OPTION_FIRST_FRAME,
"Flag indicating the first in a series of link status commands.", HFILL }},
{ &hf_zbee_nwk_cmd_link_count,
- { "Link Status Count", "zbee.nwk.cmd.link.count", FT_UINT8, BASE_DEC, NULL,
- ZBEE_NWK_CMD_LINK_OPTION_COUNT_MASK, NULL, HFILL }},
+ { "Link Status Count", "zbee.nwk.cmd.link.count", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_CMD_LINK_OPTION_COUNT_MASK,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_report_type,
- { "Report Type", "zbee.nwk.cmd.report.type", FT_UINT8, BASE_HEX,
- VALS(zbee_nwk_report_types), ZBEE_NWK_CMD_NWK_REPORT_ID_MASK, NULL, HFILL }},
+ { "Report Type", "zbee.nwk.cmd.report.type", FT_UINT8, BASE_HEX, VALS(zbee_nwk_report_types), ZBEE_NWK_CMD_NWK_REPORT_ID_MASK,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_report_count,
- { "Report Information Count", "zbee.nwk.cmd.report.count", FT_UINT8, BASE_DEC, NULL,
- ZBEE_NWK_CMD_NWK_REPORT_COUNT_MASK, NULL, HFILL }},
+ { "Report Information Count", "zbee.nwk.cmd.report.count", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_CMD_NWK_REPORT_COUNT_MASK,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_update_type,
- { "Update Type", "zbee.nwk.cmd.update.type", FT_UINT8, BASE_HEX,
- VALS(zbee_nwk_update_types), ZBEE_NWK_CMD_NWK_UPDATE_ID_MASK, NULL, HFILL }},
+ { "Update Type", "zbee.nwk.cmd.update.type", FT_UINT8, BASE_HEX, VALS(zbee_nwk_update_types), ZBEE_NWK_CMD_NWK_UPDATE_ID_MASK,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_update_count,
- { "Update Information Count", "zbee.nwk.cmd.update.count", FT_UINT8, BASE_DEC, NULL,
- ZBEE_NWK_CMD_NWK_UPDATE_COUNT_MASK, NULL, HFILL }},
+ { "Update Information Count", "zbee.nwk.cmd.update.count", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_CMD_NWK_UPDATE_COUNT_MASK,
+ NULL, HFILL }},
{ &hf_zbee_nwk_cmd_update_id,
{ "Update ID", "zbee.nwk.cmd.update.id", FT_UINT8, BASE_DEC, NULL, 0x0,
@@ -1815,8 +1673,8 @@ void proto_register_zbee_nwk(void)
NULL, HFILL }},
{ &hf_zbee_beacon_stack_profile,
- { "Stack Profile", "zbee.beacon.profile", FT_UINT8, BASE_HEX,
- VALS(zbee_nwk_stack_profiles), 0x0, NULL, HFILL }},
+ { "Stack Profile", "zbee.beacon.profile", FT_UINT8, BASE_HEX, VALS(zbee_nwk_stack_profiles), 0x0,
+ NULL, HFILL }},
{ &hf_zbee_beacon_version,
{ "Protocol Version", "zbee.beacon.version", FT_UINT8, BASE_DEC, NULL, 0x0,
@@ -1859,20 +1717,18 @@ void proto_register_zbee_nwk(void)
&ett_zbee_nwk_cmd_cinfo
};
- register_init_routine(proto_init_zbee_nwk);
-
/* Register the protocol with Wireshark. */
- proto_zbee_nwk = proto_register_protocol("ZigBee Network Layer", "ZigBee NWK", ZBEE_PROTOABBREV_NWK);
+ proto_zbee_nwk = proto_register_protocol("ZigBee Network Layer", "ZigBee NWK", "zbee.nwk");
proto_register_field_array(proto_zbee_nwk, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/* Register the dissectors with Wireshark. */
- register_dissector(ZBEE_PROTOABBREV_NWK, dissect_zbee_nwk, proto_zbee_nwk);
+ register_dissector("zbee.nwk", dissect_zbee_nwk, proto_zbee_nwk);
register_dissector("zbee.beacon", dissect_zbee_beacon, proto_zbee_nwk);
/* Register the Security dissector. */
zbee_security_register(NULL, proto_zbee_nwk);
-} /* proto_register_zbee_nwk */
+} /* proto_register_zbee */
/*FUNCTION:------------------------------------------------------
* NAME
@@ -1892,43 +1748,8 @@ void proto_reg_handoff_zbee_nwk(void)
aps_handle = find_dissector("zbee.aps");
/* Register our dissector with IEEE 802.15.4 */
- heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_zbee_nwk_heur, proto_zbee_nwk);
+ heur_dissector_add("wpan", dissect_zbee_nwk_heur, proto_zbee_nwk);
/* Handoff the ZigBee security dissector code. */
zbee_security_handoff();
} /* proto_reg_handoff_zbee */
-
-static void free_keyring_val(gpointer a)
-{
- GSList **slist = a;
- g_slist_free(*slist);
- return;
-}
-
-/*FUNCTION:------------------------------------------------------
- * NAME
- * proto_init_zbee_nwk
- * DESCRIPTION
- * Init routine for the nwk dissector. Creates a
- * hash table for mapping 16-bit to 64-bit addresses and
- * populates it with static address pairs from a UAT
- * preference table.
- * PARAMETERS
- * none
- * RETURNS
- * void
- *---------------------------------------------------------------
- */
-static void
-proto_init_zbee_nwk(void)
-{
- /* Destroy the hash tables, if they exist. */
- if (zbee_nwk_addr.short_table) g_hash_table_destroy(zbee_nwk_addr.short_table);
- if (zbee_nwk_addr.long_table) g_hash_table_destroy(zbee_nwk_addr.long_table);
- if (zbee_table_nwk_keyring) g_hash_table_destroy(zbee_table_nwk_keyring);
-
- /* (Re)create the hash tables. */
- zbee_nwk_addr.short_table = g_hash_table_new(ieee802154_short_addr_hash, ieee802154_short_addr_equal);
- zbee_nwk_addr.long_table = g_hash_table_new(g_int64_hash, g_int64_equal);
- zbee_table_nwk_keyring = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, free_keyring_val);
-} /* proto_init_zbee_nwk */
diff --git a/epan/dissectors/packet-zbee-nwk.h b/epan/dissectors/packet-zbee-nwk.h
index 9069e83961..b1e3da4fe4 100644
--- a/epan/dissectors/packet-zbee-nwk.h
+++ b/epan/dissectors/packet-zbee-nwk.h
@@ -21,7 +21,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PACKET_ZBEE_NWK_H
#define PACKET_ZBEE_NWK_H
@@ -122,11 +122,10 @@
#define ZBEE_NWK_STATUS_BAD_FRAME_COUNTER 0x11
#define ZBEE_NWK_STATUS_BAD_KEY_SEQNO 0x12
-#define ZBEE_SEC_CONST_KEYSIZE 16
-
typedef struct{
gboolean security;
gboolean discovery;
+ gboolean is_bcast;
gboolean multicast; /* ZigBee 2006 and Later */
gboolean route; /* ZigBee 2006 and Later */
gboolean ext_dst; /* ZigBee 2006 and Later */
@@ -149,33 +148,6 @@ typedef struct{
guint8 payload_len;
} zbee_nwk_packet;
-/* Key used for link key hash table. */
-typedef struct {
- guint64 lt_addr64; /* lesser than address */
- guint64 gt_addr64; /* greater than address */
-} table_link_key_t;
-
-/* Values in the key rings. */
-typedef struct {
- guint frame_num;
- gchar *label;
- guint8 key[ZBEE_SEC_CONST_KEYSIZE];
-} key_record_t;
-
-typedef struct {
- gint src_pan; /* source pan */
- gint ieee_src; /* short source address from mac */
- ieee802154_map_rec *map_rec; /* extended src from nwk */
- key_record_t *nwk; /* Network key found for this packet */
- key_record_t *link; /* Link key found for this packet */
-} zbee_nwk_hints_t;
-
-extern GHashTable *zbee_table_nwk_keyring;
-extern GHashTable *zbee_table_link_keyring;
-
-/* Key Types */
-#define ZBEE_USER_KEY 0x01
-
/* Beacon Definitions. */
#define ZBEE_NWK_BEACON_PROCOL_ID 0x00
#define ZBEE_NWK_BEACON_STACK_PROFILE 0x0f
diff --git a/epan/dissectors/packet-zbee-security.c b/epan/dissectors/packet-zbee-security.c
index 246dfcf445..2bde0c9b81 100644
--- a/epan/dissectors/packet-zbee-security.c
+++ b/epan/dissectors/packet-zbee-security.c
@@ -1,6 +1,6 @@
/* packet-zbee-security.c
* Dissector helper routines for encrypted ZigBee frames.
- * By Owen Kirby <osk@exegin.com>; portions by Fred Fierling <fff@exegin.com>
+ * By Owen Kirby <osk@exegin.com>
* Copyright 2009 Exegin Technologies Limited
*
* $Id$
@@ -38,8 +38,6 @@
#include <epan/prefs.h>
#include <epan/expert.h>
-#include <epan/uat.h>
-
/* We require libgcrpyt in order to decrypt ZigBee packets. Without it the best
* we can do is parse the security header and give up.
*/
@@ -47,36 +45,25 @@
#include <gcrypt.h>
#endif /* HAVE_LIBGCRYPT */
-#include "packet-ieee802154.h"
#include "packet-zbee.h"
-#include "packet-zbee-nwk.h"
#include "packet-zbee-security.h"
/* Helper Functions */
#ifdef HAVE_LIBGCRYPT
-static gboolean zbee_sec_ccm_decrypt(const gchar *, const gchar *, const gchar *, const gchar *, gchar *,
- guint, guint, guint);
-static guint8 * zbee_sec_key_hash(guint8 *, guint8, guint8 *);
-static void zbee_sec_make_nonce (zbee_security_packet *, guint8 *);
-static gboolean zbee_sec_decrypt_payload(zbee_security_packet *, const gchar *, const gchar, guint8 *,
- guint, guint, guint8 *);
+static gboolean zbee_sec_ccm_decrypt(const gchar *, const gchar *, const gchar *, const gchar *, gchar *, guint, guint, guint);
+static guint8 * zbee_sec_key_hash(guint8 *, guint8, packet_info *);
+static void zbee_sec_make_nonce (guint8 *, zbee_security_packet *);
#endif
-static gboolean zbee_security_parse_key(const gchar *, guint8 *, gboolean);
-static void proto_init_zbee_security(void);
+static void zbee_security_parse_prefs(void);
/* Field pointers. */
-#if 0
static int hf_zbee_sec_level = -1;
-#endif
-static int hf_zbee_sec_key_id = -1;
+static int hf_zbee_sec_key = -1;
static int hf_zbee_sec_nonce = -1;
static int hf_zbee_sec_counter = -1;
-static int hf_zbee_sec_src64 = -1;
-static int hf_zbee_sec_isrc64 = -1;
+static int hf_zbee_sec_src = -1;
static int hf_zbee_sec_key_seqno = -1;
static int hf_zbee_sec_mic = -1;
-static int hf_zbee_sec_key_origin = -1;
-static int hf_zbee_sec_src64_origin = -1;
/* Subtree pointers. */
static gint ett_zbee_sec = -1;
@@ -92,7 +79,6 @@ static const value_string zbee_sec_key_names[] = {
{ 0, NULL }
};
-#if 0
/* These aren't really used anymore, as ZigBee no longer includes them in the
* security control field. If we were to display them all we would ever see is
* security level 0.
@@ -108,7 +94,6 @@ static const value_string zbee_sec_level_names[] = {
{ ZBEE_SEC_ENC_MIC128, "Encryption, 128-bit MIC" },
{ 0, NULL }
};
-#endif
/* The ZigBee security level, in enum_val_t for the security preferences. */
static enum_val_t zbee_sec_level_enums[] = {
@@ -123,78 +108,22 @@ static enum_val_t zbee_sec_level_enums[] = {
{ NULL, NULL, 0 }
};
-static gint gPREF_zbee_sec_level = ZBEE_SEC_ENC_MIC32;
-static uat_t *zbee_sec_key_table_uat;
-
-static const value_string byte_order_vals[] = {
- { 0, "Normal"},
- { 1, "Reverse"},
- { 0, NULL }
-};
-
-/* UAT Key Entry */
-typedef struct _uat_key_record_t {
- gchar *string;
- gint byte_order;
- gchar *label;
- guint8 key[ZBEE_SEC_CONST_KEYSIZE];
-} uat_key_record_t;
-
-/* */
-static uat_key_record_t *uat_key_records = NULL;
-static guint num_uat_key_records = 0;
-
-static void* uat_key_record_copy_cb(void* n, const void* o, unsigned siz _U_) {
- uat_key_record_t* new_key = n;
- const uat_key_record_t* old_key = o;
-
- if (old_key->string) {
- new_key->string = g_strdup(old_key->string);
- } else {
- new_key->string = NULL;
- }
-
- if (old_key->label) {
- new_key->label = g_strdup(old_key->label);
- } else {
- new_key->label = NULL;
- }
-
- return new_key;
-}
-
-static void uat_key_record_update_cb(void* r, const char** err) {
- uat_key_record_t* rec = r;
-
- if (rec->string == NULL) {
- *err = ep_strdup_printf("Key can't be blank");
- } else {
- g_strstrip(rec->string);
-
- if (rec->string[0] != 0) {
- *err = NULL;
- if ( !zbee_security_parse_key(rec->string, rec->key, rec->byte_order) ) {
- *err = ep_strdup_printf("Expecting %d hexadecimal bytes or\n"
- "a %d character double-quoted string", ZBEE_SEC_CONST_KEYSIZE, ZBEE_SEC_CONST_KEYSIZE);
- }
- } else {
- *err = ep_strdup_printf("Key can't be blank");
- }
- }
-}
+/* Network Key. */
+static gboolean zbee_sec_have_nwk_key = FALSE;
+static guint8 zbee_sec_nwk_key[ZBEE_SEC_CONST_KEYSIZE];
-static void uat_key_record_free_cb(void*r) {
- uat_key_record_t* key = r;
+/* Trust-Center Link Key. */
+static gboolean zbee_sec_have_tclink_key = FALSE;
+static guint8 zbee_sec_tclink_key[ZBEE_SEC_CONST_KEYSIZE];
- if (key->string) g_free(key->string);
- if (key->label) g_free(key->label);
-}
+/* Trust-Center Extended Address */
+static guint64 zbee_sec_tcaddr = 0;
-UAT_CSTRING_CB_DEF(uat_key_records, string, uat_key_record_t)
-UAT_VS_DEF(uat_key_records, byte_order, uat_key_record_t, 0, "Normal")
-UAT_CSTRING_CB_DEF(uat_key_records, label, uat_key_record_t)
-
-static GSList *zbee_pc_keyring = NULL;
+/* ZigBee Security Preferences. */
+static gint gPREF_zbee_sec_level = ZBEE_SEC_ENC_MIC32;
+static const gchar * gPREF_zbee_sec_nwk_key = NULL;
+static const gchar * gPREF_zbee_sec_tcaddr = NULL;
+static const gchar * gPREF_zbee_sec_tclink_key = NULL;
/*
* Enable this macro to use libgcrypt's CBC_MAC mode for the authentication
@@ -208,8 +137,8 @@ static GSList *zbee_pc_keyring = NULL;
* NAME
* zbee_security_register
* DESCRIPTION
- * Called by proto_register_zbee_nwk() to initialize the security
- * dissectors.
+ * Called to initialize the security dissectors. Roughly the
+ * equivalent of proto_register_*
* PARAMETERS
* module_t zbee_prefs - Prefs module to load preferences under.
* RETURNS
@@ -219,13 +148,12 @@ static GSList *zbee_pc_keyring = NULL;
void zbee_security_register(module_t *zbee_prefs, int proto)
{
static hf_register_info hf[] = {
-#if 0
{ &hf_zbee_sec_level,
{ "Level", "zbee.sec.level", FT_UINT8, BASE_HEX, VALS(zbee_sec_level_names), ZBEE_SEC_CONTROL_LEVEL,
NULL, HFILL }},
-#endif
- { &hf_zbee_sec_key_id,
- { "Key Id", "zbee.sec.key", FT_UINT8, BASE_HEX, VALS(zbee_sec_key_names), ZBEE_SEC_CONTROL_KEY,
+
+ { &hf_zbee_sec_key,
+ { "Key", "zbee.sec.key", FT_UINT8, BASE_HEX, VALS(zbee_sec_key_names), ZBEE_SEC_CONTROL_KEY,
NULL, HFILL }},
{ &hf_zbee_sec_nonce,
@@ -236,8 +164,8 @@ void zbee_security_register(module_t *zbee_prefs, int proto)
{ "Frame Counter", "zbee.sec.counter", FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }},
- { &hf_zbee_sec_src64,
- { "Source", "zbee.sec.src64", FT_UINT64, BASE_HEX, NULL, 0x0,
+ { &hf_zbee_sec_src,
+ { "Source", "zbee.sec.src", FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL }},
{ &hf_zbee_sec_key_seqno,
@@ -246,11 +174,6 @@ void zbee_security_register(module_t *zbee_prefs, int proto)
{ &hf_zbee_sec_mic,
{ "Message Integrity Code", "zbee.sec.mic", FT_BYTES, BASE_NONE, NULL, 0x0,
-
- NULL, HFILL }},
-
- { &hf_zbee_sec_key_origin,
- { "Key Origin", "zbee.sec.key.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
NULL, HFILL }}
};
@@ -259,139 +182,138 @@ void zbee_security_register(module_t *zbee_prefs, int proto)
&ett_zbee_sec_control
};
- static uat_field_t key_uat_fields[] = {
- UAT_FLD_CSTRING(uat_key_records, string, "Key",
- "A 16-byte key in hexadecimal with optional dash-,\n"
- "colon-, or space-separator characters, or a\n"
- "a 16-character string in double-quotes."),
- UAT_FLD_VS(uat_key_records, byte_order, "Byte Order", byte_order_vals,
- "Byte order of key."),
- UAT_FLD_LSTRING(uat_key_records, label, "Label", "User label for key."),
- UAT_END_FIELDS
- };
-
/* If no prefs module was supplied, register our own. */
if (zbee_prefs == NULL) {
- zbee_prefs = prefs_register_protocol(proto, NULL);
+ zbee_prefs = prefs_register_protocol(proto, zbee_security_parse_prefs);
}
/* Register preferences */
prefs_register_enum_preference(zbee_prefs, "seclevel", "Security Level",
- "Specifies the security level to use in the\n"
- "decryption process. This value is ignored\n"
- "for ZigBee 2004 and unsecured networks.",
+ "Specifies the security level to use in the decryption process. This value is ignored for ZigBee 2004 and unsecured networks.",
&gPREF_zbee_sec_level, zbee_sec_level_enums, FALSE);
-
- zbee_sec_key_table_uat = uat_new("Pre-configured Keys",
- sizeof(uat_key_record_t),
- "zigbee_pc_keys",
- TRUE,
- (void*) &uat_key_records,
- &num_uat_key_records,
- UAT_CAT_FFMT,
- NULL, /* TODO: ptr to help manual? */
- uat_key_record_copy_cb,
- uat_key_record_update_cb,
- uat_key_record_free_cb,
- NULL, /* TODO: post_update */
- key_uat_fields );
-
- prefs_register_uat_preference(zbee_prefs,
- "key_table",
- "Pre-configured Keys",
- "Pre-configured link or network keys.",
- zbee_sec_key_table_uat);
+ prefs_register_string_preference(zbee_prefs, "nwkkey", "Network Key",
+ "Specifies the network key to use for decryption.",
+ &gPREF_zbee_sec_nwk_key);
+ prefs_register_string_preference(zbee_prefs, "tcaddr", "Trust Center Address",
+ "The Extended address of the trust center.",
+ &gPREF_zbee_sec_tcaddr);
+ prefs_register_string_preference(zbee_prefs, "tclinkkey", "Trust Center Link Key",
+ "Specifies the trust center link key to use for decryption.",
+ &gPREF_zbee_sec_tclink_key);
proto_register_field_array(proto, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
-
- /* Register the init routine. */
- register_init_routine(proto_init_zbee_security);
} /* zbee_security_register */
/*FUNCTION:------------------------------------------------------
* NAME
* zbee_security_parse_key
* DESCRIPTION
- * Parses a key string from left to right into a buffer with
- * increasing (normal byte order) or decreasing (reverse byte
- * order) address.
+ * Parses a key string into a buffer.
* PARAMETERS
- * const gchar *key_str - pointer to the string
- * guint8 *key_buf - destination buffer in memory
- * gboolean big_end - fill key_buf with incrementing address
+ * const gchar * key_str;
+ * guint8 key_buf;
* RETURNS
* gboolean
*---------------------------------------------------------------
*/
static gboolean
-zbee_security_parse_key(const gchar *key_str, guint8 *key_buf, gboolean byte_order)
+zbee_security_parse_key(const gchar *key_str, guint8 *key_buf)
{
- int i, j;
+ int i;
gchar temp;
- gboolean string_mode = FALSE;
/* Clear the key. */
memset(key_buf, 0, ZBEE_SEC_CONST_KEYSIZE);
if (key_str == NULL) {
return FALSE;
}
-
/*
- * Attempt to parse the key string. The key string must
- * be at least 16 pairs of hexidecimal digits with the
- * following optional separators: ':', '-', " ", or 16
- * alphanumeric characters after a double-quote.
+ * Attempt to parse the key string. The key string must represent
+ * exactly 16 bytes in hexadecimal format with the following
+ * separators: ':', '-', " ", or no separator at all. Start by
+ * getting the first character.
*/
- if ( (temp = *key_str++) == '"') {
- string_mode = TRUE;
- temp = *key_str++;
- }
-
- j = byte_order?ZBEE_SEC_CONST_KEYSIZE-1:0;
+ temp = *(key_str++);
for (i=ZBEE_SEC_CONST_KEYSIZE-1; i>=0; i--) {
- if ( string_mode ) {
- if ( g_ascii_isprint(temp) ) {
- key_buf[j] = temp;
- temp = *key_str++;
- } else {
- return FALSE;
- }
- }
- else {
- /* If this character is a separator, skip it. */
- if ( (temp == ':') || (temp == '-') || (temp == ' ') ) temp = *(key_str++);
-
- /* Process a nibble. */
- if ( g_ascii_isxdigit (temp) ) key_buf[j] = g_ascii_xdigit_value(temp)<<4;
- else return FALSE;
-
- /* Get the next nibble. */
- temp = *(key_str++);
-
- /* Process another nibble. */
- if ( g_ascii_isxdigit (temp) ) key_buf[j] |= g_ascii_xdigit_value(temp);
- else return FALSE;
-
- /* Get the next nibble. */
- temp = *(key_str++);
- }
-
- /* Move key_buf pointer */
- if ( byte_order ) {
- j--;
- } else {
- j++;
- }
-
+ /* If this character is a separator, skip it. */
+ if ((temp == ':') || (temp == '-') || (temp == ' ')) temp = *(key_str++);
+ /* Process this nibble. */
+ if (('0' <= temp) && (temp <= '9')) key_buf[i] |= ((temp-'0')<<4);
+ else if (('a' <= temp) && (temp <= 'f')) key_buf[i] |= ((temp-'a'+0x0a)<<4);
+ else if (('A' <= temp) && (temp <= 'F')) key_buf[i] |= ((temp-'A'+0x0A)<<4);
+ else return FALSE;
+ /* Get the next nibble. */
+ temp = *(key_str++);
+ /* Process this nibble. */
+ if (('0' <= temp) && (temp <= '9')) key_buf[i] |= (temp-'0');
+ else if (('a' <= temp) && (temp <= 'f')) key_buf[i] |= (temp-'a'+0x0a);
+ else if (('A' <= temp) && (temp <= 'F')) key_buf[i] |= (temp-'A'+0x0A);
+ else return FALSE;
+ /* Get the next nibble. */
+ temp = *(key_str++);
} /* for */
-
/* If we get this far, then the key was good. */
return TRUE;
} /* zbee_security_parse_key */
/*FUNCTION:------------------------------------------------------
* NAME
+ * zbee_security_parse_prefs
+ * DESCRIPTION
+ * Parses the security preferences into the parameters needed
+ * for decryption.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+static void
+zbee_security_parse_prefs(void)
+{
+ int i;
+ const gchar * str_ptr;
+ gchar temp;
+
+ /* Get the network key. */
+ zbee_sec_have_nwk_key = zbee_security_parse_key(gPREF_zbee_sec_nwk_key, zbee_sec_nwk_key);
+ /* Get the trust-center link key. */
+ zbee_sec_have_tclink_key = zbee_security_parse_key(gPREF_zbee_sec_tclink_key, zbee_sec_tclink_key);
+ /* Get the trust-center address. */
+ zbee_sec_tcaddr = 0;
+ str_ptr = gPREF_zbee_sec_tcaddr;
+ temp = *(str_ptr++);
+ for (i=0;i<(int)sizeof(guint64);i++) {
+ /* Except for the first octet, ensure the next character is a
+ * separator and skip over it.
+ */
+ if ((temp == ':') || (temp == '-')) temp = *(str_ptr++);
+ else if (i!=0) goto bad_tcaddr;
+ /* Process this nibble. */
+ if (('0' <= temp) && (temp <= '9')) zbee_sec_tcaddr |= ((guint64)(temp-'0'+0x00)<<(8*(sizeof(guint64)-i)-4));
+ else if (('a' <= temp) && (temp <= 'f')) zbee_sec_tcaddr |= ((guint64)(temp-'a'+0x0a)<<(8*(sizeof(guint64)-i)-4));
+ else if (('A' <= temp) && (temp <= 'F')) zbee_sec_tcaddr |= ((guint64)(temp-'A'+0x0A)<<(8*(sizeof(guint64)-i)-4));
+ else goto bad_tcaddr;
+ /* Get the next nibble. */
+ temp = *(str_ptr++);
+ /* Process this nibble. */
+ if (('0' <= temp) && (temp <= '9')) zbee_sec_tcaddr |= ((guint64)(temp-'0'+0x00)<<(8*(sizeof(guint64)-i)-8));
+ else if (('a' <= temp) && (temp <= 'f')) zbee_sec_tcaddr |= ((guint64)(temp-'a'+0x0a)<<(8*(sizeof(guint64)-i)-8));
+ else if (('A' <= temp) && (temp <= 'F')) zbee_sec_tcaddr |= ((guint64)(temp-'A'+0x0A)<<(8*(sizeof(guint64)-i)-8));
+ else goto bad_tcaddr;
+ /* Get the next nibble. */
+ temp = *(str_ptr++);
+ } /* for */
+ /* Done */
+ return;
+
+bad_tcaddr:
+ zbee_sec_tcaddr = 0;
+} /* zbee_security_parse_prefs */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
* zbee_security_handoff
* DESCRIPTION
* Hands off the security dissector.
@@ -406,6 +328,8 @@ zbee_security_handoff(void)
{
/* Lookup the data dissector. */
data_handle = find_dissector("data");
+ /* Parse the security prefs. */
+ zbee_security_parse_prefs();
} /* zbee_security_handoff */
/*FUNCTION:------------------------------------------------------
@@ -419,49 +343,35 @@ zbee_security_handoff(void)
* handle internally and return NULL.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
- * packet_info *pinfo - pointer to packet information fields
+ * packet_into *pinfo - pointer to packet information fields
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* guint offset - pointer to the start of the auxilliary security header.
- * guint64 src64 - extended source address, or 0 if unknown.
+ * guint64 src - extended source address, or 0 if unknown.
* RETURNS
* tvbuff_t *
*---------------------------------------------------------------
*/
tvbuff_t *
-dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint offset, guint64 src64)
+dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint offset, guint64 src)
{
- proto_tree *sec_tree = NULL;
- proto_item *sec_root;
- proto_tree *field_tree;
- proto_item *ti;
+ proto_tree * sec_tree = NULL;
+ proto_item * sec_root;
+ proto_tree * field_tree;
+ proto_item * ti;
zbee_security_packet packet;
guint mic_len;
guint payload_len;
- tvbuff_t *payload_tvb;
+ tvbuff_t * payload_tvb;
#ifdef HAVE_LIBGCRYPT
- const guint8 *enc_buffer;
- guint8 *dec_buffer;
- guint8 buffer[ZBEE_SEC_CONST_BLOCKSIZE+1];
- guint8 *key_buffer = buffer;
- gboolean decrypted;
- GSList **nwk_keyring;
- GSList *GSList_i;
- key_record_t *key_rec = NULL;
+ const guint8 * enc_buffer;
+ guint8 * dec_buffer;
+ guint8 * key_buffer;
+ guint8 nonce[ZBEE_SEC_CONST_NONCE_LEN];
#endif
- zbee_nwk_hints_t *nwk_hints;
- ieee802154_hints_t *ieee_hints;
- ieee802154_map_rec *map_rec = NULL;
-
- /* Init */
- memset(&packet, 0, sizeof(zbee_security_packet));
-
- /* Get pointers to any useful frame data from lower layers */
- nwk_hints = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name(ZBEE_PROTOABBREV_NWK));
- ieee_hints = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN));
-
- /* Create a subtree for the security information. */
+
+ /* Create a substree for the security information. */
if (tree) {
sec_root = proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "ZigBee Security Header");
sec_tree = proto_item_add_subtree(sec_root, ett_zbee_sec);
@@ -469,17 +379,14 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o
/* Get and display the Security control field */
packet.control = tvb_get_guint8(tvb, offset);
-
/* Patch the security level. */
packet.control &= ~ZBEE_SEC_CONTROL_LEVEL;
packet.control |= (ZBEE_SEC_CONTROL_LEVEL & gPREF_zbee_sec_level);
-
/*
* Eww, I think I just threw up a little... ZigBee requires this field
* to be patched before computing the MIC, but we don't have write-access
* to the tvbuff. So we need to allocate a copy of the whole thing just
- * so we can fix these 3 bits. Memory allocated by ep_tvb_memdup() is
- * automatically freed before the next packet is processed.
+ * so we can fix these 3 bits.
*/
#ifdef HAVE_LIBGCRYPT
enc_buffer = ep_tvb_memdup(tvb, 0, tvb_length(tvb));
@@ -491,16 +398,14 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o
((guint8 *)(enc_buffer))[offset] = packet.control;
#endif /* HAVE_LIBGCRYPT */
packet.level = zbee_get_bit_field(packet.control, ZBEE_SEC_CONTROL_LEVEL);
- packet.key_id = zbee_get_bit_field(packet.control, ZBEE_SEC_CONTROL_KEY);
+ packet.key = zbee_get_bit_field(packet.control, ZBEE_SEC_CONTROL_KEY);
packet.nonce = zbee_get_bit_field(packet.control, ZBEE_SEC_CONTROL_NONCE);
if (tree) {
ti = proto_tree_add_text(sec_tree, tvb, offset, sizeof(guint8), "Security Control Field");
field_tree = proto_item_add_subtree(ti, ett_zbee_sec_control);
- proto_tree_add_uint(field_tree, hf_zbee_sec_key_id, tvb, offset, sizeof(guint8),
- packet.control & ZBEE_SEC_CONTROL_KEY);
- proto_tree_add_boolean(field_tree, hf_zbee_sec_nonce, tvb, offset, sizeof(guint8),
- packet.control & ZBEE_SEC_CONTROL_NONCE);
+ proto_tree_add_uint(field_tree, hf_zbee_sec_key, tvb, offset, sizeof(guint8), packet.control & ZBEE_SEC_CONTROL_KEY);
+ proto_tree_add_boolean(field_tree, hf_zbee_sec_nonce, tvb, offset, sizeof(guint8), packet.control & ZBEE_SEC_CONTROL_NONCE);
}
offset += sizeof(guint8);
@@ -512,32 +417,21 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o
offset += sizeof(guint32);
if (packet.nonce) {
- /* Get and display the source address of the device that secured this payload. */
- packet.src64 = tvb_get_letoh64(tvb, offset);
+ /* Get and display the source address. */
+ packet.src = tvb_get_letoh64(tvb, offset);
if (tree) {
- proto_tree_add_eui64(sec_tree, hf_zbee_sec_src64, tvb, offset, sizeof(guint64), packet.src64);
+ proto_tree_add_eui64(sec_tree, hf_zbee_sec_src, tvb, offset, sizeof(guint64), packet.src);
}
offset += sizeof(guint64);
-
}
else {
- /* Look for a source address in hints */
- switch ( packet.key_id ) {
- case ZBEE_SEC_KEY_NWK:
- /* use the ieee extended source address for NWK decryption */
- if ( ieee_hints && (map_rec = ieee_hints->map_rec) ) packet.src64 = map_rec->addr64;
- else if (tree) proto_tree_add_text(sec_tree, tvb, 0, 0, "Source: Unknown");
- break;
-
- default:
- /* use the nwk extended source address for APS decryption */
- if ( nwk_hints && (map_rec = nwk_hints->map_rec) ) packet.src64 = map_rec->addr64;
- else if (tree) proto_tree_add_text(sec_tree, tvb, 0, 0, "Source: Unknown");
- break;
- }
+ /* This field is required in the security decryption process, so
+ * fill it in in case the higher layer provided it.
+ */
+ packet.src = src;
}
- if (packet.key_id == ZBEE_SEC_KEY_NWK) {
+ if (packet.key == ZBEE_SEC_KEY_NWK) {
/* Get and display the key sequence number. */
packet.key_seqno = tvb_get_guint8(tvb, offset);
if (tree) {
@@ -547,7 +441,7 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o
}
/* Determine the length of the MIC. */
- switch (packet.level) {
+ switch (packet.level){
case ZBEE_SEC_ENC:
case ZBEE_SEC_NONE:
default:
@@ -577,8 +471,7 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o
if (mic_len) {
/* Display the MIC. */
if (tree) {
- ti = proto_tree_add_bytes(sec_tree, hf_zbee_sec_mic, tvb, tvb_length(tvb)-mic_len,
- mic_len, ep_tvb_memdup(tvb, tvb_length(tvb)-mic_len, mic_len));
+ ti = proto_tree_add_bytes(sec_tree, hf_zbee_sec_mic, tvb, tvb_length(tvb)-mic_len, mic_len, ep_tvb_memdup(tvb, tvb_length(tvb)-mic_len, mic_len));
}
}
@@ -590,118 +483,105 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o
(packet.level == ZBEE_SEC_MIC32) ||
(packet.level == ZBEE_SEC_MIC64) ||
(packet.level == ZBEE_SEC_MIC128)) {
-
/* Payload is only integrity protected. Just return the sub-tvbuff. */
return tvb_new_subset(tvb, offset, payload_len, payload_len);
}
#ifdef HAVE_LIBGCRYPT
- /* Allocate memory to decrypt the payload into. */
- dec_buffer = g_malloc(payload_len);
+ /* Ensure we have enough security material to decrypt this payload. */
+ switch (packet.key) {
+ /* Network Keys use the shared network key. */
+ case ZBEE_SEC_KEY_NWK:
+ if (!zbee_sec_have_nwk_key) {
+ /* Without a key we can't decrypt (if we could what good would security be?)*/
+ goto decrypt_failed;
+ }
+ if (packet.src == 0) {
+ /* Without the extended source address, we can't create the nonce. */
+ goto decrypt_failed;
+ }
+ /* The key, is the network key. */
+ key_buffer = zbee_sec_nwk_key;
+ break;
- decrypted = FALSE;
- if ( packet.src64 ) {
- if (pinfo->fd->flags.visited) {
- if ( nwk_hints ) {
- /* Use previously found key */
- switch ( packet.key_id ) {
- case ZBEE_SEC_KEY_NWK:
- if ( key_rec = nwk_hints->nwk ) {
- decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
- payload_len, mic_len, nwk_hints->nwk->key);
- }
- break;
-
- default:
- if ( key_rec = nwk_hints->link ) {
- decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
- payload_len, mic_len, nwk_hints->link->key);
- }
- break;
- }
+ /* Link Key might use the trust center link key. */
+ case ZBEE_SEC_KEY_LINK:
+ if (!zbee_sec_have_tclink_key) {
+ /* Without a key we can't decrypt. */
+ goto decrypt_failed;
}
- } /* ( !pinfo->fd->flags.visited ) */
- else {
- /* We only search for sniffed keys in the first pass,
- * to save time, and because decrypting with keys
- * transported in future packets is cheating */
-
- /* Lookup NWK and link key in hash for this pan. */
- /* This overkill approach is a placeholder for a hash that looks up
- * a key ring for a link key associated with a pair of devices.
- */
- if ( nwk_hints ) {
- nwk_keyring = g_hash_table_lookup(zbee_table_nwk_keyring, &nwk_hints->src_pan);
-
- if ( nwk_keyring ) {
- GSList_i = *nwk_keyring;
- while ( GSList_i && !decrypted ) {
- decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
- payload_len, mic_len, ((key_record_t *)(GSList_i->data))->key);
-
- if (decrypted) {
- /* save pointer to the successful key record */
- switch (packet.key_id) {
- case ZBEE_SEC_KEY_NWK:
- key_rec = nwk_hints->nwk = GSList_i->data;
- break;
-
- default:
- key_rec = nwk_hints->link = GSList_i->data;
- break;
- }
- } else {
- GSList_i = g_slist_next(GSList_i);
- }
- }
- }
+ if ((packet.src == 0) && (zbee_sec_tcaddr == 0)){
+ /* Without the extended source address, we can't create the nonce. */
+ goto decrypt_failed;
}
-
- /* Loop through user's password table for preconfigured keys, our last resort */
- GSList_i = zbee_pc_keyring;
- while ( GSList_i && !decrypted ) {
- decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
- payload_len, mic_len, ((key_record_t *)(GSList_i->data))->key);
-
- if (decrypted) {
- /* save pointer to the successful key record */
- switch (packet.key_id) {
- case ZBEE_SEC_KEY_NWK:
- key_rec = nwk_hints->nwk = GSList_i->data;
- break;
-
- default:
- key_rec = nwk_hints->link = GSList_i->data;
- break;
- }
- } else {
- GSList_i = g_slist_next(GSList_i);
- }
+ else if (packet.src == 0) {
+ packet.src = zbee_sec_tcaddr;
}
- } /* ( ! pinfo->fd->flags.visited ) */
- } /* ( packet.src64 ) */
-
- if ( decrypted ) {
- if ( tree && key_rec ) {
- if ( key_rec->frame_num == ZBEE_SEC_PC_KEY ) {
- ti = proto_tree_add_text(sec_tree, tvb, 0, 0, "Decryption Key: %s", key_rec->label);
- } else {
- ti = proto_tree_add_uint(sec_tree, hf_zbee_sec_key_origin, tvb, 0, 0,
- key_rec->frame_num);
+ key_buffer = zbee_sec_tclink_key;
+ break;
+
+ /* Key-Transport Key should use the trust center link key. */
+ case ZBEE_SEC_KEY_TRANSPORT:
+ if (!zbee_sec_have_tclink_key) {
+ /* Without a key we can't decrypt. */
+ goto decrypt_failed;
}
- PROTO_ITEM_SET_GENERATED(ti);
- }
+ if ((packet.src == 0) && (zbee_sec_tcaddr == 0)){
+ /* Without the extended source address, we can't create the nonce. */
+ goto decrypt_failed;
+ }
+ else if (packet.src == 0) {
+ packet.src = zbee_sec_tcaddr;
+ }
+ key_buffer = zbee_sec_key_hash(zbee_sec_tclink_key, 0x00, pinfo);
+ break;
- /* Found a key that worked, setup the new tvbuff_t and return */
- payload_tvb = tvb_new_child_real_data(tvb, dec_buffer, payload_len, payload_len);
- tvb_set_free_cb(payload_tvb, g_free); /* set up callback to free dec_buffer */
- add_new_data_source(pinfo, payload_tvb, "Decrypted ZigBee Payload");
+ /* Key-Load Key should use the trust center link key. */
+ case ZBEE_SEC_KEY_LOAD:
+ if (!zbee_sec_have_tclink_key) {
+ /* Without a key we can't decrypt. */
+ goto decrypt_failed;
+ }
+ if ((packet.src == 0) && (zbee_sec_tcaddr == 0)){
+ /* Without the extended source address, we can't create the nonce. */
+ goto decrypt_failed;
+ }
+ else if (packet.src == 0) {
+ packet.src = zbee_sec_tcaddr;
+ }
+ key_buffer = zbee_sec_key_hash(zbee_sec_tclink_key, 0x02, pinfo);
+ break;
- /* Done! */
- return payload_tvb;
+ default:
+ goto decrypt_failed;
+ } /* switch */
+
+ /* Create the nonce. */
+ zbee_sec_make_nonce(nonce, &packet);
+ /* Allocate memory to decrypt the payload into. */
+ dec_buffer = g_malloc(payload_len);
+ /* Perform Decryption. */
+ if (!zbee_sec_ccm_decrypt(key_buffer, /* key */
+ nonce, /* Nonce */
+ enc_buffer, /* a, length l(a) */
+ enc_buffer+offset, /* c, length l(c) = l(m) + M */
+ dec_buffer, /* m, length l(m) */
+ offset, /* l(a) */
+ payload_len, /* l(m) */
+ mic_len)) { /* M */
+ /* Decryption Failed! */
+ g_free(dec_buffer);
+ goto decrypt_failed;
}
- g_free(dec_buffer);
+ /* Setup the new tvbuff_t and return */
+ payload_tvb = tvb_new_child_real_data(tvb, dec_buffer, payload_len, payload_len);
+ tvb_set_free_cb(payload_tvb, g_free);
+ add_new_data_source(pinfo, payload_tvb, "Decrypted ZigBee Payload");
+ /* Done! */
+ return payload_tvb;
+
+decrypt_failed:
#endif /* HAVE_LIBGCRYPT */
/* Add expert info. */
@@ -712,97 +592,35 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o
call_dissector(data_handle, payload_tvb, pinfo, tree);
/* Couldn't decrypt, so return NULL. */
return NULL;
+
} /* dissect_zbee_secure */
#ifdef HAVE_LIBGCRYPT
/*FUNCTION:------------------------------------------------------
* NAME
- * zbee_sec_decrypt_payload
- * DESCRIPTION
- * Creates a nonce and decrypts a secured payload.
- * PARAMETERS
- * gchar *nonce - Nonce Buffer.
- * zbee_security_packet *packet - Security information.
- * RETURNS
- * void
- *---------------------------------------------------------------
- */
-static gboolean
-zbee_sec_decrypt_payload(zbee_security_packet *packet, const gchar *enc_buffer, const gchar offset, guint8 *dec_buffer,
- guint payload_len, guint mic_len, guint8 *key)
-{
- guint8 nonce[ZBEE_SEC_CONST_NONCE_LEN];
- guint8 buffer[ZBEE_SEC_CONST_BLOCKSIZE+1];
- guint8 *key_buffer = buffer;
-
- switch (packet->key_id) {
- case ZBEE_SEC_KEY_NWK:
- /* Decrypt with the PAN's current network key */
- case ZBEE_SEC_KEY_LINK:
- /* Decrypt with the unhashed link key assigned by the trust center to this
- * source/destination pair */
- key_buffer = key;
- break;
-
- case ZBEE_SEC_KEY_TRANSPORT:
- /* Decrypt with a Key-Transport key, a hashed link key that protects network
- * keys sent from the trust center */
- zbee_sec_key_hash(key, 0x00, buffer);
- key_buffer = buffer;
- break;
-
- case ZBEE_SEC_KEY_LOAD:
- /* Decrypt with a Key-Load key, a hashed link key that protects link keys
- * sent from the trust center. */
- zbee_sec_key_hash(key, 0x02, buffer);
- key_buffer = buffer;
- break;
-
- default:
- break;
- } /* switch */
-
- /* Perform Decryption. */
- zbee_sec_make_nonce(packet, nonce);
-
- if ( zbee_sec_ccm_decrypt(key_buffer, /* key */
- nonce, /* Nonce */
- enc_buffer, /* a, length l(a) */
- enc_buffer+offset, /* c, length l(c) = l(m) + M */
- dec_buffer, /* m, length l(m) */
- offset, /* l(a) */
- payload_len, /* l(m) */
- mic_len) ) { /* M */
- return TRUE;
- }
- else return FALSE;
-}
-
-/*FUNCTION:------------------------------------------------------
- * NAME
* zbee_sec_make_nonce
* DESCRIPTION
* Fills in the ZigBee security nonce from the provided security
* packet structure.
* PARAMETERS
- * zbee_security_packet *packet - Security information.
* gchar *nonce - Nonce Buffer.
+ * zbee_security_packet *packet - Security information.
* RETURNS
* void
*---------------------------------------------------------------
*/
static void
-zbee_sec_make_nonce(zbee_security_packet *packet, guint8 *nonce)
+zbee_sec_make_nonce(guint8 *nonce, zbee_security_packet *packet)
{
/* First 8 bytes are the extended source address (little endian). */
- *(nonce++) = (guint8)((packet->src64)>>0 & 0xff);
- *(nonce++) = (guint8)((packet->src64)>>8 & 0xff);
- *(nonce++) = (guint8)((packet->src64)>>16 & 0xff);
- *(nonce++) = (guint8)((packet->src64)>>24 & 0xff);
- *(nonce++) = (guint8)((packet->src64)>>32 & 0xff);
- *(nonce++) = (guint8)((packet->src64)>>40 & 0xff);
- *(nonce++) = (guint8)((packet->src64)>>48 & 0xff);
- *(nonce++) = (guint8)((packet->src64)>>56 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>0 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>8 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>16 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>24 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>32 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>40 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>48 & 0xff);
+ *(nonce++) = (guint8)((packet->src)>>56 & 0xff);
/* Next 4 bytes are the frame counter (little endian). */
*(nonce++) = (guint8)((packet->counter)>>0 & 0xff);
*(nonce++) = (guint8)((packet->counter)>>8 & 0xff);
@@ -988,8 +806,7 @@ zbee_sec_ccm_decrypt(const gchar *key, /* Input */
for (i=0;i<l_a;i++,j++) {
if (j>=ZBEE_SEC_CONST_BLOCKSIZE) {
/* Generate the next cipher block. */
- if (gcry_cipher_encrypt(cipher_hd, cipher_out, ZBEE_SEC_CONST_BLOCKSIZE, cipher_in,
- ZBEE_SEC_CONST_BLOCKSIZE)) {
+ if (gcry_cipher_encrypt(cipher_hd, cipher_out, ZBEE_SEC_CONST_BLOCKSIZE, cipher_in, ZBEE_SEC_CONST_BLOCKSIZE)) {
gcry_cipher_close(cipher_hd);
return FALSE;
}
@@ -1007,8 +824,7 @@ zbee_sec_ccm_decrypt(const gchar *key, /* Input */
for (i=0; i<l_m; i++, j++) {
if (j>=ZBEE_SEC_CONST_BLOCKSIZE) {
/* Generate the next cipher block. */
- if (gcry_cipher_encrypt(cipher_hd, cipher_out, ZBEE_SEC_CONST_BLOCKSIZE, cipher_in,
- ZBEE_SEC_CONST_BLOCKSIZE)) {
+ if (gcry_cipher_encrypt(cipher_hd, cipher_out, ZBEE_SEC_CONST_BLOCKSIZE, cipher_in, ZBEE_SEC_CONST_BLOCKSIZE)) {
gcry_cipher_close(cipher_hd);
return FALSE;
}
@@ -1160,15 +976,15 @@ zbee_sec_hash(guint8 *input, guint input_len, guint8 *output)
* PARAMETERS
* guint8 *key - ZigBee Security Key (must be ZBEE_SEC_CONST_KEYSIZE) in length.
* guint8 input - ZigBee CCM* Nonce (must be ZBEE_SEC_CONST_NONCE_LEN) in length.
- * packet_info *pinfo - pointer to packet information fields
* RETURNS
* guint8*
*---------------------------------------------------------------
*/
static guint8 *
-zbee_sec_key_hash(guint8 *key, guint8 input, guint8 *hash_out)
+zbee_sec_key_hash(guint8 *key, guint8 input, packet_info *pinfo _U_)
{
guint8 hash_in[2*ZBEE_SEC_CONST_BLOCKSIZE];
+ guint8 * hash_out = ep_alloc(ZBEE_SEC_CONST_BLOCKSIZE+1);
int i;
static const guint8 ipad = 0x36;
static const guint8 opad = 0x5c;
@@ -1188,36 +1004,3 @@ zbee_sec_key_hash(guint8 *key, guint8 input, guint8 *hash_out)
return hash_out;
} /* zbee_sec_key_hash */
#endif /* HAVE_LIBGCRYPT */
-
-/*FUNCTION:------------------------------------------------------
- * NAME
- * proto_init_zbee_security
- * DESCRIPTION
- * Init routine for the
- * PARAMETERS
- * none
- * RETURNS
- * void
- *---------------------------------------------------------------
- */
-static void
-proto_init_zbee_security(void)
-{
- guint i;
- key_record_t key_record;
-
- /* empty the key ring */
- if (zbee_pc_keyring) {
- g_slist_free(zbee_pc_keyring);
- zbee_pc_keyring = NULL;
- }
-
- /* Load the pre-configured slist from the UAT. */
- for (i=0; (uat_key_records) && (i<num_uat_key_records) ; i++) {
- key_record.frame_num = ZBEE_SEC_PC_KEY; /* means it's a user PC key */
- key_record.label = se_strdup(uat_key_records[i].label);
- memcpy(&key_record.key, &uat_key_records[i].key, ZBEE_SEC_CONST_KEYSIZE);
-
- zbee_pc_keyring = g_slist_prepend(zbee_pc_keyring, se_memdup(&key_record, sizeof(key_record_t)));
- } /* for */
-} /* proto_init_zbee_security */
diff --git a/epan/dissectors/packet-zbee-security.h b/epan/dissectors/packet-zbee-security.h
index 56aee490e9..257de8302c 100644
--- a/epan/dissectors/packet-zbee-security.h
+++ b/epan/dissectors/packet-zbee-security.h
@@ -30,13 +30,13 @@
/* Structure containing the fields stored in the Aux Header */
typedef struct{
/* The fields of the Aux Header */
- guint8 control; /* needed to decrypt */
- guint32 counter; /* needed to decrypt */
- guint64 src64; /* needed to decrypt */
+ guint8 control;
+ guint32 counter;
+ guint64 src;
guint8 key_seqno;
guint8 level;
- guint8 key_id; /* needed to decrypt */
+ guint8 key;
gboolean nonce;
} zbee_security_packet;
@@ -64,6 +64,7 @@ typedef struct{
/* ZigBee Security Constants. */
#define ZBEE_SEC_CONST_L 2
#define ZBEE_SEC_CONST_NONCE_LEN (ZBEE_SEC_CONST_BLOCKSIZE-ZBEE_SEC_CONST_L-1)
+#define ZBEE_SEC_CONST_KEYSIZE 16
#define ZBEE_SEC_CONST_BLOCKSIZE 16
/* CCM* Flags */
@@ -71,9 +72,6 @@ typedef struct{
#define ZBEE_SEC_CCM_FLAG_M(m) ((((m-2)/2) & 0x7)<<3) /* 3-bit encoding of (M-2)/2 shifted 3 bits. */
#define ZBEE_SEC_CCM_FLAG_ADATA(l_a) ((l_a>0)?0x40:0x00) /* Adata flag. */
-/* Program Constants */
-#define ZBEE_SEC_PC_KEY 0
-
/* Init routine for the Security dissectors. */
extern void zbee_security_register (module_t *module, int proto);
extern void zbee_security_handoff (void);
diff --git a/epan/dissectors/packet-zbee.h b/epan/dissectors/packet-zbee.h
index e7aded465f..2e0f11af79 100644
--- a/epan/dissectors/packet-zbee.h
+++ b/epan/dissectors/packet-zbee.h
@@ -27,7 +27,7 @@
#define PACKET_ZBEE_H
/* IEEE 802.15.4 definitions. */
-#include "packet-ieee802154.h"
+#include <epan/dissectors/packet-ieee802154.h>
/* The ZigBee Broadcast Address */
#define ZBEE_BCAST_ALL 0xffff
@@ -576,12 +576,10 @@
#define ZBEE_MFG_KAGA "Kaga Electronics"
#define ZBEE_MFG_4_NOKS "4-noks s.r.l."
-/* Protocol Abbreviations */
-#define ZBEE_PROTOABBREV_NWK "zbee.nwk"
-#define ZBEE_PROTOABBREV_APS "zbee.aps"
-#define ZBEE_PROTOABBREV_APF "zbee.apf"
-
/* Helper Functions */
+extern proto_item *proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, gint64 value);
extern guint zbee_get_bit_field(guint input, guint mask);
#endif /* PACKET_ZBEE_H */
+