Tighten heuristic checks for IEEE 802.15.4 protocols, and add Decode-As by PANID for when we still get it wrong.

Change-Id: Icc2b274d2478a9426da881998bbbbfb3bf34ec4a
Reviewed-on: https://code.wireshark.org/review/1167
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Owen Kirby 2014-04-17 23:33:42 -04:00 committed by Anders Broman
parent 19c1989cfa
commit 177c6556f7
7 changed files with 459 additions and 200 deletions

View File

@ -453,7 +453,7 @@ struct lowpan_nhdr {
/* Dissector prototypes */
static void proto_init_6lowpan (void);
static void prefs_6lowpan_apply (void);
static void dissect_6lowpan (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static int dissect_6lowpan (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
static tvbuff_t * dissect_6lowpan_ipv6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static tvbuff_t * dissect_6lowpan_hc1 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size, guint8 *siid, guint8 *diid);
static tvbuff_t * dissect_6lowpan_bc0 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@ -850,34 +850,41 @@ lowpan_parse_nhc_proto(tvbuff_t *tvb, gint offset)
static gboolean
dissect_6lowpan_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
guint offset = 0;
/* Check for valid patterns. */
do {
for (;;) {
/* Parse patterns until we find a match. */
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) break;
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) break;
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_BC0_BITS) == LOWPAN_PATTERN_BC0) break;
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) break;
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_MESH_BITS) == LOWPAN_PATTERN_MESH)
{
ieee802154_packet *packet = (ieee802154_packet *)data;
DISSECTOR_ASSERT(packet);
if (!(packet->dst_pan == IEEE802154_BCAST_PAN && packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT &&
packet->dst16 == IEEE802154_BCAST_ADDR && packet->frame_type != IEEE802154_FCF_BEACON &&
packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT && tvb_get_bits8(tvb, 2, 4) ==
ZBEE_VERSION_GREEN_POWER))
{
break;
}
if (!tvb_reported_length_remaining(tvb, offset)) return FALSE;
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) break;
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) break;
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_BC0_BITS) == LOWPAN_PATTERN_BC0) {
/* Broadcast headers must be followed by another valid header. */
offset += 2;
continue;
}
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) break;
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAGN) break;
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) break;
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_MESH_BITS) == LOWPAN_PATTERN_MESH) {
/* Mesh headers must be followed by another valid header. */
guint8 mesh = tvb_get_guint8(tvb, offset++);
offset += (mesh & LOWPAN_MESH_HEADER_V) ? sizeof(guint16) : sizeof(guint64);
offset += (mesh & LOWPAN_MESH_HEADER_F) ? sizeof(guint16) : sizeof(guint64);
if ((mesh & LOWPAN_MESH_HEADER_HOPS) == LOWPAN_MESH_HEADER_HOPS) offset++;
continue;
}
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) {
/* First fragment headers must be followed by another valid header. */
offset += 4;
continue;
}
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAGN) break;
/* If we get here, then we couldn't match to any pattern. */
return FALSE;
} while(0);
} /* for */
/* If we get here, then we found a matching pattern. */
dissect_6lowpan(tvb, pinfo, tree);
dissect_6lowpan(tvb, pinfo, tree, data);
return TRUE;
} /* dissect_6lowpan_heur */
@ -890,12 +897,13 @@ dissect_6lowpan_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
* tvb ; packet buffer.
* pinfo ; packet info.
* tree ; protocol display tree.
* data ; Packet data (ieee 802.15.4).
* RETURNS
* void ;
* int ; Length of data processed, or 0 if not 6LoWPAN.
*---------------------------------------------------------------
*/
static void
dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static int
dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
proto_tree *volatile lowpan_tree = NULL;
proto_item *volatile lowpan_root = NULL;
@ -919,11 +927,11 @@ dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Mesh and Broadcast headers always come first in a 6LoWPAN frame. */
if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_MESH_BITS) == LOWPAN_PATTERN_MESH) {
next = dissect_6lowpan_mesh(next, pinfo, lowpan_tree);
if (!next) return;
if (!next) return tvb_captured_length(tvb);
}
if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_BC0_BITS) == LOWPAN_PATTERN_BC0) {
next = dissect_6lowpan_bc0(next, pinfo, lowpan_tree);
if (!next) return;
if (!next) return tvb_captured_length(tvb);
}
/* After the mesh and broadcast headers, process dispatch codes recursively. */
@ -948,13 +956,14 @@ dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Unknown 6LoWPAN dispatch type */
else {
dissect_6lowpan_unknown(next, pinfo, lowpan_tree);
return;
return tvb_captured_length(tvb);
}
/* The last step should have returned an uncompressed IPv6 datagram. */
if (next) {
call_dissector(ipv6_handle, next, pinfo, tree);
}
return tvb_captured_length(tvb);
} /* dissect_6lowpan */
/*FUNCTION:------------------------------------------------------
@ -2154,18 +2163,13 @@ dissect_6lowpan_mesh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_bits_item(flag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_MESH_BITS, ENC_BIG_ENDIAN);
proto_tree_add_boolean(flag_tree, hf_6lowpan_mesh_v, tvb, offset, (int)sizeof(guint8), mesh_header & LOWPAN_MESH_HEADER_V);
proto_tree_add_boolean(flag_tree, hf_6lowpan_mesh_f, tvb, offset, (int)sizeof(guint8), mesh_header & LOWPAN_MESH_HEADER_F);
if ((mesh_header & LOWPAN_MESH_HEADER_HOPS)==15)
{
guint8 HopsLeft;
proto_tree_add_uint(flag_tree, hf_6lowpan_mesh_hops, tvb, offset, (int)sizeof(guint8), mesh_header & LOWPAN_MESH_HEADER_HOPS);
offset += (int)sizeof(guint8);
HopsLeft=tvb_get_guint8(tvb, offset);
proto_tree_add_uint(mesh_tree, hf_6lowpan_mesh_hops8, tvb, offset, (int)sizeof(guint8), HopsLeft);
}
else
proto_tree_add_uint(flag_tree, hf_6lowpan_mesh_hops, tvb, offset, (int)sizeof(guint8), mesh_header & LOWPAN_MESH_HEADER_HOPS);
proto_tree_add_uint(flag_tree, hf_6lowpan_mesh_hops, tvb, offset, 1, mesh_header & LOWPAN_MESH_HEADER_HOPS);
}
offset += (int)sizeof(guint8);
if ((mesh_header & LOWPAN_MESH_HEADER_HOPS) == LOWPAN_MESH_HEADER_HOPS) {
if (tree) proto_tree_add_item(mesh_tree, hf_6lowpan_mesh_hops8, tvb, offset, 1, ENC_NA);
offset += (int)sizeof(guint8);
}
/* Get and display the originator address. */
if (!(mesh_header & LOWPAN_MESH_HEADER_V)) {
@ -2456,7 +2460,14 @@ dissect_6lowpan_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Get and display the pattern. */
if (tree) {
proto_tree_add_bits_item(tree, hf_6lowpan_pattern, tvb, 0, 8, ENC_BIG_ENDIAN);
/* Give a special case for NALP. */
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
proto_tree_add_bits_item(tree, hf_6lowpan_pattern, tvb, 0, LOWPAN_PATTERN_IPHC_BITS, ENC_BIG_ENDIAN);
}
else {
guint8 pattern = tvb_get_guint8(tvb, 0);
proto_tree_add_uint_bits_format_value(tree, hf_6lowpan_pattern, tvb, 0, 8, pattern, "Unknown (0x%02x)", pattern);
}
}
/* Create a tvbuff subset for the remaining data. */
@ -2745,7 +2756,7 @@ proto_register_6lowpan(void)
expert_register_field_array(expert_6lowpan, ei, array_length(ei));
/* Register the dissector with wireshark. */
register_dissector("6lowpan", dissect_6lowpan, proto_6lowpan);
new_register_dissector("6lowpan", dissect_6lowpan, proto_6lowpan);
/* Register the dissector init function */
register_init_routine(proto_init_6lowpan);
@ -2849,6 +2860,7 @@ proto_reg_handoff_6lowpan(void)
ipv6_handle = find_dissector("ipv6");
/* Register the 6LoWPAN dissector with IEEE 802.15.4 */
dissector_add_handle(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector("6lowpan"));
heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_6lowpan_heur, proto_6lowpan);
} /* proto_reg_handoff_6lowpan */

View File

@ -66,6 +66,7 @@
#include <glib.h>
#include <epan/wmem/wmem.h>
#include <epan/decode_as.h>
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <wsutil/pint.h>
@ -175,6 +176,7 @@ static void dissect_ieee802154_fcf (tvbuff_t *, packet_info *, proto_tr
static void dissect_ieee802154_superframe (tvbuff_t *, packet_info *, proto_tree *, guint *);
static void dissect_ieee802154_gtsinfo (tvbuff_t *, packet_info *, proto_tree *, guint *);
static void dissect_ieee802154_pendaddr (tvbuff_t *, packet_info *, proto_tree *, guint *);
static void dissect_ieee802154_command (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
static void dissect_ieee802154_assoc_req (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
static void dissect_ieee802154_assoc_rsp (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
static void dissect_ieee802154_disassoc (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
@ -295,8 +297,15 @@ static expert_field ei_ieee802154_decrypt_error = EI_INIT;
static expert_field ei_ieee802154_dst = EI_INIT;
static expert_field ei_ieee802154_src = EI_INIT;
/* Dissector handles */
/*
* Dissector handles
* - beacon dissection is always heuristic.
* - the PANID table is for stateful dissectors only (ie: Decode-As)
* - otherwise, data dissectors fall back to the heuristic dissectors.
*/
static dissector_handle_t data_handle;
static dissector_table_t panid_dissector_table;
static heur_dissector_list_t ieee802154_beacon_subdissector_list;
static heur_dissector_list_t ieee802154_heur_subdissector_list;
/* Name Strings */
@ -381,7 +390,6 @@ static gboolean ieee802154_extend_auth = TRUE;
#define IEEE802154_CRC_XOROUT 0xFFFF
#define ieee802154_crc_tvb(tvb, offset) (crc16_ccitt_tvb_seed(tvb, offset, IEEE802154_CRC_SEED) ^ IEEE802154_CRC_XOROUT)
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_ieee802154_fcf
@ -768,10 +776,14 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
}
offset += 2;
}
else {
/* Set the panID field in case the intra-pan condition was met. */
/* Set the panID field in case the intra-pan condition was met. */
else if (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) {
packet->src_pan = packet->dst_pan;
}
/* If all else fails, consider it a broadcast PANID. */
else {
packet->src_pan = IEEE802154_BCAST_PAN;
}
if (ieee_hints) {
ieee_hints->src_pan = packet->src_pan;
@ -1068,108 +1080,40 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
saved_proto = pinfo->current_proto;
/* Try to dissect the payload. */
TRY {
if ((packet->frame_type == IEEE802154_FCF_BEACON) ||
(packet->frame_type == IEEE802154_FCF_DATA)) {
/* Beacon and Data packets contain a payload. */
if ((fcs_ok || !ieee802154_fcs_ok) && (tvb_reported_length(payload_tvb)>0)) {
/* Attempt heuristic subdissection. */
if (!dissector_try_heuristic(ieee802154_heur_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) {
/* Could not subdissect, call the data dissector instead. */
call_dissector(data_handle, payload_tvb, pinfo, tree);
}
}
else {
/* If no sub-dissector was called, call the data dissector. */
switch (packet->frame_type) {
case IEEE802154_FCF_BEACON:
if (!dissector_try_heuristic(ieee802154_beacon_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) {
/* Could not subdissect, call the data dissector instead. */
call_dissector(data_handle, payload_tvb, pinfo, tree);
}
}
/* If the packet is a command, try to dissect the payload. */
else if (packet->frame_type == IEEE802154_FCF_CMD) {
switch (packet->command_id) {
case IEEE802154_CMD_ASRQ:
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_NONE));
dissect_ieee802154_assoc_req(payload_tvb, pinfo, ieee802154_tree, packet);
break;
case IEEE802154_FCF_CMD:
dissect_ieee802154_command(payload_tvb, pinfo, ieee802154_tree, packet);
break;
case IEEE802154_FCF_DATA:
/* Sanity-check. */
if ((!fcs_ok && ieee802154_fcs_ok) || !tvb_reported_length(payload_tvb)) {
call_dissector(data_handle, payload_tvb, pinfo, tree);
break;
case IEEE802154_CMD_ASRSP:
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_EXT));
dissect_ieee802154_assoc_rsp(payload_tvb, pinfo, ieee802154_tree, packet);
}
/* Try the PANID dissector table for stateful dissection. */
if (dissector_try_uint_new(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, TRUE, packet)) {
break;
case IEEE802154_CMD_DISAS:
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_EXT));
dissect_ieee802154_disassoc(payload_tvb, pinfo, ieee802154_tree, packet);
}
/* Try again with the destination PANID (if different) */
if (((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) ||
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) &&
(packet->dst_pan != packet->src_pan) &&
dissector_try_uint_new(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, TRUE, packet)) {
break;
case IEEE802154_CMD_DATA_RQ:
IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id, packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE);
/* No payload expected. */
break;
case IEEE802154_CMD_PANID_ERR:
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_EXT));
/* No payload expected. */
break;
case IEEE802154_CMD_ORPH_NOTIF:
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->src_pan == IEEE802154_BCAST_PAN) &&
(packet->dst_pan == IEEE802154_BCAST_PAN));
/* No payload expected. */
break;
case IEEE802154_CMD_BCN_RQ:
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_pan == IEEE802154_BCAST_PAN));
/* No payload expected. */
break;
case IEEE802154_CMD_COORD_REAL:
IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
(packet->dst_pan == IEEE802154_BCAST_PAN) &&
(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);
}
dissect_ieee802154_realign(payload_tvb, pinfo, ieee802154_tree, packet);
break;
case IEEE802154_CMD_GTS_REQ:
/* Check that the addressing is correct for this command type. */
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));
dissect_ieee802154_gtsreq(payload_tvb, pinfo, ieee802154_tree, packet);
break;
default:
/* Unknown Command */
call_dissector(data_handle, payload_tvb, pinfo, ieee802154_tree);
break;
} /* switch */
}
/* Otherwise, dump whatever is left over to the data dissector. */
else {
}
/* Try heuristic dissection. */
if (dissector_try_heuristic(ieee802154_heur_subdissector_list, payload_tvb, pinfo, tree, packet)) break;
/* Fall-through to dump undissectable payloads. */
default:
/* Could not subdissect, call the data dissector instead. */
call_dissector(data_handle, payload_tvb, pinfo, tree);
}
} /* switch */
}
CATCH_ALL {
/*
@ -1751,6 +1695,103 @@ dissect_ieee802154_gtsreq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
}
} /* dissect_ieee802154_gtsreq */
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_ieee802154_command
* DESCRIPTION
* Subdissector routine all commands.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* packet_info *pinfo - pointer to packet information fields (unused).
* proto_tree *tree - pointer to protocol tree.
* ieee802154_packet *packet - IEEE 802.15.4 packet information (unused).
* RETURNS
* void
*---------------------------------------------------------------
*/
static void
dissect_ieee802154_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet)
{
switch (packet->command_id) {
case IEEE802154_CMD_ASRQ:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
(packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE));
dissect_ieee802154_assoc_req(tvb, pinfo, tree, packet);
break;
case IEEE802154_CMD_ASRSP:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
dissect_ieee802154_assoc_rsp(tvb, pinfo, tree, packet);
break;
case IEEE802154_CMD_DISAS:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
dissect_ieee802154_disassoc(tvb, pinfo, tree, packet);
return;
case IEEE802154_CMD_DATA_RQ:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE);
/* No payload expected. */
break;
case IEEE802154_CMD_PANID_ERR:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
/* No payload expected. */
break;
case IEEE802154_CMD_ORPH_NOTIF:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, 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->src_pan == IEEE802154_BCAST_PAN) &&
(packet->dst_pan == IEEE802154_BCAST_PAN));
/* No payload expected. */
break;
case IEEE802154_CMD_BCN_RQ:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, 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_pan == IEEE802154_BCAST_PAN));
/* No payload expected. */
break;
case IEEE802154_CMD_COORD_REAL:
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id,
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
(packet->dst_pan == IEEE802154_BCAST_PAN) &&
(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, tree, packet->command_id, packet->dst16 == IEEE802154_BCAST_ADDR);
}
dissect_ieee802154_realign(tvb, pinfo, tree, packet);
return;
case IEEE802154_CMD_GTS_REQ:
/* Check that the addressing is correct for this command type. */
IEEE802154_CMD_ADDR_CHECK(pinfo, tree, 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));
dissect_ieee802154_gtsreq(tvb, pinfo, tree, packet);
return;
} /* switch */
/* Dump unexpected, or unknown command payloads. */
call_dissector(data_handle, tvb, pinfo, tree);
} /* dissect_ieee802154_command */
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_ieee802154_decrypt
@ -2338,7 +2379,6 @@ gboolean ieee802154_long_addr_invalidate(guint64 long_addr, guint fnum)
return FALSE;
} /* ieee802154_long_addr_invalidate */
/*FUNCTION:------------------------------------------------------
* NAME
* proto_init_ieee802154
@ -2374,6 +2414,23 @@ proto_init_ieee802154(void)
} /* for */
} /* proto_init_ieee802154 */
/* Returns the prompt string for the Decode-As dialog. */
static void ieee802154_da_prompt(packet_info *pinfo _U_, gchar* result)
{
ieee802154_hints_t *hints;
hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IEEE 802.15.4 PAN 0x%04x as", hints->src_pan);
} /* iee802154_da_prompt */
/* Returns the value to index the panid decode table with (source PAN)*/
static gpointer ieee802154_da_value(packet_info *pinfo _U_)
{
ieee802154_hints_t *hints;
hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
return GUINT_TO_POINTER(hints->src_pan);
} /* iee802154_da_value */
/*FUNCTION:------------------------------------------------------
* NAME
@ -2693,6 +2750,14 @@ void proto_register_ieee802154(void)
UAT_END_FIELDS
};
static build_valid_func ieee802154_da_build_value[1] = {ieee802154_da_value};
static decode_as_value_t ieee802154_da_values = {ieee802154_da_prompt, 1, ieee802154_da_build_value};
static decode_as_t ieee802154_da = {
IEEE802154_PROTOABBREV_WPAN, "PAN", IEEE802154_PROTOABBREV_WPAN_PANID,
1, 0, &ieee802154_da_values, NULL, NULL,
decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL
};
/* Register the init routine. */
register_init_routine(proto_init_ieee802154);
@ -2765,13 +2830,18 @@ void proto_register_ieee802154(void)
&ieee802154_extend_auth);
/* Register the subdissector list */
panid_dissector_table = register_dissector_table(IEEE802154_PROTOABBREV_WPAN_PANID, "IEEE 802.15.4 PANID", FT_UINT16, BASE_HEX);
register_heur_dissector_list(IEEE802154_PROTOABBREV_WPAN, &ieee802154_heur_subdissector_list);
register_heur_dissector_list(IEEE802154_PROTOABBREV_WPAN_BEACON, &ieee802154_beacon_subdissector_list);
/* Register dissectors with Wireshark. */
register_dissector(IEEE802154_PROTOABBREV_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);
/* Register a Decode-As handler. */
register_decode_as(&ieee802154_da);
} /* proto_register_ieee802154 */

View File

@ -26,7 +26,10 @@
#define PACKET_IEEE802154_H
/* Protocol Abbreviation */
#define IEEE802154_PROTOABBREV_WPAN "wpan"
#define IEEE802154_PROTOABBREV_WPAN "wpan"
#define IEEE802154_PROTOABBREV_WPAN_BEACON "wpan.beacon"
/* PANID dissector list is for Decode-As and stateful dissection only. */
#define IEEE802154_PROTOABBREV_WPAN_PANID "wpan.panid"
/* Packet Overhead from MAC header + footer (excluding addressing) */
#define IEEE802154_MAX_FRAME_LEN 127

View File

@ -97,7 +97,7 @@ void proto_reg_handoff_lwm(void);
static dissector_handle_t data_handle;
/* Dissection Routines. */
static void dissect_lwm (tvbuff_t *, packet_info *, proto_tree *);
static int dissect_lwm (tvbuff_t *, packet_info *, proto_tree *, void *data);
static int dissect_lwm_cmd_frame_ack (tvbuff_t *, packet_info *, proto_tree *);
static int dissect_lwm_cmd_frame_route_err (tvbuff_t *, packet_info *, proto_tree *);
static int dissect_lwm_cmd_frame_route_req (tvbuff_t *, packet_info *, proto_tree *);
@ -172,16 +172,18 @@ static const value_string lwm_cmd_multi_names[] = {
*---------------------------------------------------------------
*/
static gboolean
dissect_lwm_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
dissect_lwm_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
/* 1) first byte must have bits 0000xxxx */
if(tvb_get_guint8(tvb, 0) & LWM_FCF_RESERVED)
return (FALSE);
dissect_lwm(tvb, pinfo, tree);
return (TRUE);
/* The header should be at least long enough for the base header. */
if (tvb_reported_length(tvb) < LWM_HEADER_BASE_LEN)
return (FALSE);
dissect_lwm(tvb, pinfo, tree, data);
return (TRUE);
} /* dissect_lwm_heur */
/*FUNCTION:------------------------------------------------------
@ -194,10 +196,10 @@ dissect_lwm_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
* packet_info *pinfo - pointer to packet information fields
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* RETURNS
* void
* int - length of data processed, or 0 if not LWM.
*---------------------------------------------------------------
*/
static void dissect_lwm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static int dissect_lwm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
guint lwm_header_len;
@ -378,7 +380,7 @@ static void dissect_lwm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
expert_add_info(pinfo, lwm_tree, &ei_lwm_empty_payload);
col_append_str(pinfo->cinfo, COL_INFO, "[Empty LwMesh Payload]");
return;
return tvb_captured_length(tvb);
}
new_tvb = tvb_new_subset_remaining(tvb, lwm_header_len);
@ -403,11 +405,9 @@ static void dissect_lwm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvb_reported_length(new_tvb) - LWM_MIC_LEN);
tvb_set_reported_length(new_tvb, tvb_reported_length(new_tvb) - LWM_MIC_LEN);
call_dissector(data_handle, new_tvb, pinfo, lwm_tree);
return;
}
/*stack command endpoint 0 and not secured*/
if( (lwm_src_endp == 0) && (lwm_dst_endp == 0) ){
else if( (lwm_src_endp == 0) && (lwm_dst_endp == 0) ){
proto_tree *lwm_cmd_tree;
guint8 lwm_cmd;
guint len;
@ -451,8 +451,7 @@ static void dissect_lwm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/*Unknown command*/
expert_add_info_format(pinfo, lwm_cmd_tree, &ei_lwm_mal_error, "Unknown command");
call_dissector(data_handle, new_tvb, pinfo, lwm_cmd_tree);
return;
break;
return tvb_captured_length(tvb);
}
proto_item_set_len(ti, len);
@ -468,16 +467,13 @@ static void dissect_lwm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
new_tvb = tvb_new_subset_remaining(new_tvb, len);
call_dissector(data_handle, new_tvb, pinfo, lwm_tree);
}
return;
}
else{
/*unknown data*/
call_dissector(data_handle, new_tvb, pinfo, lwm_tree);
return;
}
} /* dissect_lwm*/
return tvb_captured_length(tvb);
} /* dissect_lwm */
/*FUNCTION:------------------------------------------------------
* NAME
@ -797,7 +793,7 @@ void proto_register_lwm(void)
expert_register_field_array(expert_lwm, ei, array_length(ei));
/* Register dissector with Wireshark. */
register_dissector("lwm", dissect_lwm, proto_lwm);
new_register_dissector("lwm", dissect_lwm, proto_lwm);
} /* proto_register_lwm */
@ -818,6 +814,7 @@ void proto_reg_handoff_lwm(void)
data_handle = find_dissector("data");
/* Register our dissector with IEEE 802.15.4 */
dissector_add_handle(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector("lwm"));
heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_lwm_heur, proto_lwm);
} /* proto_reg_handoff_lwm */

View File

@ -42,7 +42,6 @@
#include "packet-zbee-zcl.h"
#include <wsutil/wsgcrypt.h>
void proto_register_zbee_nwk_gp(void);
void proto_reg_handoff_zbee_nwk_gp(void);
@ -1394,14 +1393,13 @@ dissect_zbee_nwk_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d
add_new_data_source(pinfo, payload_tvb, "Decrypted GP Payload");
dissect_zbee_nwk_gp_cmd(payload_tvb, pinfo, nwk_tree, data);
g_free(dec_buffer);
return packet.payload_len;
} else {
g_free(dec_buffer);
payload_tvb = tvb_new_subset(tvb, offset - packet.payload_len - packet.mic_size, packet.payload_len, -1);
call_dissector(data_handle, payload_tvb, pinfo, tree);
}
}
return 0;
return tvb_captured_length(tvb);
} /* dissect_zbee_nwk_gp */
/*FUNCTION:------------------------------------------------------
@ -1421,25 +1419,27 @@ dissect_zbee_nwk_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d
static gboolean
dissect_zbee_nwk_heur_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
ieee802154_packet *packet = (ieee802154_packet *)data;
ieee802154_packet *packet = (ieee802154_packet *)data;
guint8 fcf;
/* All ZigBee frames must always have a 16-bit source address. */
if ( (packet == NULL) ||
(packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) ) {
return FALSE;
}
/* We must have the IEEE 802.15.4 headers. */
if (packet == NULL) return FALSE;
/* ZigBee green power never uses 16-bit source addresses. */
if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) return FALSE;
/* Skip ZigBee beacons. */
if ((packet->frame_type == IEEE802154_FCF_BEACON) && (tvb_get_guint8(tvb, 0) == ZBEE_NWK_BEACON_PROCOL_ID))
return FALSE;
/* If the frame type and version are not sane, then it's probably not ZGP. */
fcf = tvb_get_guint8(tvb, 0);
if (zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_VERSION) != ZBEE_VERSION_GREEN_POWER) return FALSE;
if (!try_val_to_str(zbee_get_bit_field(fcf, ZBEE_NWK_FCF_FRAME_TYPE), zbee_nwk_gp_frame_types)) return FALSE;
/* ZigBee greenpower frames are either sent to broadcast or the extended address. */
if (packet->dst_pan == IEEE802154_BCAST_PAN && packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT &&
packet->dst16 == IEEE802154_BCAST_ADDR && packet->frame_type != IEEE802154_FCF_BEACON) {
packet->dst16 == IEEE802154_BCAST_ADDR) {
dissect_zbee_nwk_gp(tvb, pinfo, tree, data);
return TRUE;
}
/* 64-bit destination addressing mode support. */
if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT && packet->frame_type != IEEE802154_FCF_BEACON) {
if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
dissect_zbee_nwk_gp(tvb, pinfo, tree, data);
return TRUE;
}
@ -1753,6 +1753,7 @@ proto_reg_handoff_zbee_nwk_gp(void)
/* Find the other dissectors we need. */
data_handle = find_dissector("data");
/* Register our dissector with IEEE 802.15.4. */
dissector_add_handle(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector(ZBEE_PROTOABBREV_NWK_GP));
heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_zbee_nwk_heur_gp, proto_zbee_nwk_gp);
} /* proto_reg_handoff_zbee */

View File

@ -48,6 +48,7 @@
static int dissect_zbee_nwk (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
static void dissect_zbee_nwk_cmd (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, zbee_nwk_packet* packet);
static int dissect_zbee_beacon (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
static int dissect_zbip_beacon (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
/* Command Dissector Helpers */
static guint dissect_zbee_nwk_route_req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
@ -142,6 +143,12 @@ static int hf_zbee_beacon_epid = -1;
static int hf_zbee_beacon_tx_offset = -1;
static int hf_zbee_beacon_update_id = -1;
static int hf_zbip_beacon_allow_join = -1;
static int hf_zbip_beacon_router_capacity = -1;
static int hf_zbip_beacon_host_capacity = -1;
static int hf_zbip_beacon_unsecure = -1;
static int hf_zbip_beacon_network_id = -1;
static gint ett_zbee_nwk = -1;
static gint ett_zbee_beacon = -1;
static gint ett_zbee_nwk_fcf = -1;
@ -304,29 +311,23 @@ static gboolean
dissect_zbee_nwk_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
ieee802154_packet *packet = (ieee802154_packet *)data;
guint16 fcf;
guint ver;
/* All ZigBee frames must always have a 16-bit source address. */
if ( (packet == NULL) ||
(packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) ) {
return FALSE;
}
/* ZigBee MAC frames must always contain a 16-bit destination address. */
if ( (packet->frame_type == IEEE802154_FCF_DATA) &&
(packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) ) {
dissect_zbee_nwk(tvb, pinfo, tree, packet);
return TRUE;
}
/* ZigBee MAC Beacons must have the first byte (protocol ID) equal to the
* ZigBee protocol ID. */
if ( (packet->frame_type == IEEE802154_FCF_BEACON) &&
(tvb_get_guint8(tvb, 0) == ZBEE_NWK_BEACON_PROCOL_ID) ) {
dissect_zbee_beacon(tvb, pinfo, tree, packet);
return TRUE;
}
/* If we get this far, then this packet did not meet the requirements for
* a ZigBee frame.
*/
return FALSE;
/* All ZigBee frames must always have a 16-bit source and destination address. */
if (packet == NULL) return FALSE;
if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) return FALSE;
if (packet->dst_addr_mode != IEEE802154_FCF_ADDR_SHORT) return FALSE;
/* If the frame type and version are not sane, then it's probably not ZigBee. */
fcf = tvb_get_letohs(tvb, 0);
ver = zbee_get_bit_field(fcf, ZBEE_NWK_FCF_VERSION);
if ((ver < ZBEE_VERSION_2004) || (ver > ZBEE_VERSION_2007)) return FALSE;
if (!try_val_to_str(zbee_get_bit_field(fcf, ZBEE_NWK_FCF_FRAME_TYPE), zbee_nwk_frame_types)) return FALSE;
/* Assume it's ZigBee */
dissect_zbee_nwk(tvb, pinfo, tree, packet);
return TRUE;
} /* dissect_zbee_heur */
/*FUNCTION:------------------------------------------------------
@ -713,7 +714,7 @@ dissect_zbee_nwk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
/* TODO: add check for FCF proto versions. */
dissect_zbee_nwk_full(tvb, pinfo, tree, data);
}
return 0;
return tvb_captured_length(tvb);
}
/*FUNCTION:------------------------------------------------------
@ -1403,6 +1404,34 @@ dissect_zbee_nwk_update(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gui
return offset;
} /* dissect_zbee_nwk_update */
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zbee_beacon_heur
* DESCRIPTION
* Heuristic interpreter for the ZigBee PRO beacon dissectors.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* packet_into *pinfo - pointer to packet information fields
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* RETURNS
* Boolean value, whether it handles the packet or not.
*---------------------------------------------------------------
*/
static gboolean
dissect_zbee_beacon_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
ieee802154_packet *packet = (ieee802154_packet *)data;
/* All ZigBee frames must always have a 16-bit source address. */
if (!packet) return FALSE;
if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) return FALSE;
/* ZigBee beacons begin with a protocol identifier. */
if (tvb_get_guint8(tvb, 0) != ZBEE_NWK_BEACON_PROTOCOL_ID) return FALSE;
dissect_zbee_beacon(tvb, pinfo, tree, packet);
return TRUE;
} /* dissect_zbee_beacon_heur */
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zbee_beacon
@ -1517,6 +1546,117 @@ static int dissect_zbee_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
return tvb_length(tvb);
} /* dissect_zbee_beacon */
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zbip_beacon_heur
* DESCRIPTION
* Heuristic interpreter for the ZigBee IP beacon dissectors.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* packet_into *pinfo - pointer to packet information fields
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* RETURNS
* Boolean value, whether it handles the packet or not.
*---------------------------------------------------------------
*/
static gboolean
dissect_zbip_beacon_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
ieee802154_packet *packet = (ieee802154_packet *)data;
/* All ZigBee frames must always have a 16-bit source address. */
if (!packet) return FALSE;
if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) return FALSE;
/* ZigBee beacons begin with a protocol identifier. */
if (tvb_get_guint8(tvb, 0) != ZBEE_IP_BEACON_PROTOCOL_ID) return FALSE;
dissect_zbip_beacon(tvb, pinfo, tree, packet);
return TRUE;
} /* dissect_zbip_beacon_heur */
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zbip_beacon
* DESCRIPTION
* Dissector for ZigBee IP beacons.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* packet_into *pinfo - pointer to packet information fields
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* RETURNS
* void
*---------------------------------------------------------------
*/
static int dissect_zbip_beacon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
ieee802154_packet *packet = (ieee802154_packet *)data;
proto_item *beacon_root = NULL;
proto_tree *beacon_tree = NULL;
guint offset = 0;
guint8 proto_id;
char *ssid;
/* Reject the packet if data is NULL */
if (!packet) return 0;
/* Add ourself to the protocol column. */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee IP");
/* Create the tree for this beacon. */
if (tree) {
beacon_root = proto_tree_add_protocol_format(tree, proto_zbee_nwk, tvb, 0, tvb_length(tvb), "ZigBee IP Beacon");
beacon_tree = proto_item_add_subtree(beacon_root, ett_zbee_beacon);
}
/* Update the info column. */
col_clear(pinfo->cinfo, COL_INFO);
col_append_fstr(pinfo->cinfo, COL_INFO, "Beacon, Src: 0x%04x", packet->src16);
/* Get and display the protocol id, must be 0x02 on all ZigBee beacons. */
proto_id = tvb_get_guint8(tvb, offset);
if (tree) {
proto_tree_add_uint(beacon_tree, hf_zbee_beacon_protocol, tvb, offset, 1, proto_id);
}
offset += 1;
/* Get and display the beacon flags */
if (tree) {
proto_tree_add_item(beacon_tree, hf_zbip_beacon_allow_join, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(beacon_tree, hf_zbip_beacon_router_capacity, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(beacon_tree, hf_zbip_beacon_host_capacity, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(beacon_tree, hf_zbip_beacon_unsecure, tvb, offset, 1, ENC_BIG_ENDIAN);
}
offset += 1;
/* Get and display the network ID. */
if (tree) {
proto_tree_add_item(beacon_tree, hf_zbip_beacon_network_id, tvb, offset, 16, ENC_ASCII|ENC_NA);
}
ssid = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 16, ENC_ASCII|ENC_NA);
col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID: %s", ssid);
offset += 16;
/* Check for leftover bytes. */
if (offset < tvb_length(tvb)) {
/* TODO: There are TLV's to parse. */
/* Bytes leftover! */
guint leftover_len = tvb_length(tvb) - offset;
tvbuff_t *leftover_tvb = tvb_new_subset(tvb, offset, leftover_len, leftover_len);
proto_tree *root = NULL;
/* Correct the length of the beacon tree. */
if (tree) {
root = proto_tree_get_root(tree);
proto_item_set_len(beacon_root, offset);
}
/* Dump the leftover to the data dissector. */
call_dissector(data_handle, leftover_tvb, pinfo, root);
}
return tvb_length(tvb);
} /* dissect_zbip_beacon */
/*FUNCTION:------------------------------------------------------
* NAME
* proto_register_zbee_nwk
@ -1807,7 +1947,28 @@ void proto_register_zbee_nwk(void)
{ &hf_zbee_beacon_update_id,
{ "Update ID", "zbee_beacon.update_id", FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }}
NULL, HFILL }},
{ &hf_zbip_beacon_allow_join,
{ "Allow Join", "zbip_beacon.allow_join", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_ALLOW_JOIN,
NULL, HFILL }},
{ &hf_zbip_beacon_router_capacity,
{ "Router Capacity", "zbip_beacon.router", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_ROUTER_CAPACITY,
"Whether this device can accept new routers on the network.", HFILL }},
{ &hf_zbip_beacon_host_capacity,
{ "Host Capacity", "zbip_beacon.host", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_HOST_CAPACITY,
"Whether this device can accept new host on the network.", HFILL }},
{ &hf_zbip_beacon_unsecure,
{ "Unsecure Network", "zbip_beacon.unsecure", FT_BOOLEAN, 8, NULL, ZBEE_IP_BEACON_UNSECURE,
"Indicates that this network is not using link layer security.", HFILL }},
{ &hf_zbip_beacon_network_id,
{ "Network ID", "zbip_beacon.network_id", FT_STRING, BASE_NONE, NULL, 0x0,
"A string that uniquely identifies this network.", HFILL }},
};
/* NWK Layer subtrees */
@ -1842,6 +2003,7 @@ void proto_register_zbee_nwk(void)
/* Register the dissectors with Wireshark. */
new_register_dissector(ZBEE_PROTOABBREV_NWK, dissect_zbee_nwk, proto_zbee_nwk);
new_register_dissector("zbee_beacon", dissect_zbee_beacon, proto_zbee_nwk);
new_register_dissector("zbip_beacon", dissect_zbip_beacon, proto_zbee_nwk);
/* Register the Security dissector. */
zbee_security_register(NULL, proto_zbee_nwk);
@ -1866,6 +2028,9 @@ void proto_reg_handoff_zbee_nwk(void)
zbee_gp_handle = find_dissector(ZBEE_PROTOABBREV_NWK_GP);
/* Register our dissector with IEEE 802.15.4 */
dissector_add_handle(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector(ZBEE_PROTOABBREV_NWK));
heur_dissector_add(IEEE802154_PROTOABBREV_WPAN_BEACON, dissect_zbee_beacon_heur, proto_zbee_nwk);
heur_dissector_add(IEEE802154_PROTOABBREV_WPAN_BEACON, dissect_zbip_beacon_heur, proto_zbee_nwk);
heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_zbee_nwk_heur, proto_zbee_nwk);
/* Handoff the ZigBee security dissector code. */

View File

@ -184,12 +184,23 @@ extern GHashTable *zbee_table_link_keyring;
/* Key Types */
#define ZBEE_USER_KEY 0x01
/* Beacon Definitions. */
#define ZBEE_NWK_BEACON_PROCOL_ID 0x00
/* ZigBee PRO beacons */
#define ZBEE_NWK_BEACON_PROTOCOL_ID 0x00
#define ZBEE_NWK_BEACON_STACK_PROFILE 0x0f
#define ZBEE_NWK_BEACON_PROTOCOL_VERSION 0xf0
#define ZBEE_NWK_BEACON_ROUTER_CAPACITY 0x04
#define ZBEE_NWK_BEACON_NETWORK_DEPTH 0x78
#define ZBEE_NWK_BEACON_END_DEVICE_CAPACITY 0x80
/* ZigBee IP beacons */
#define ZBEE_IP_BEACON_PROTOCOL_ID 0x02
#define ZBEE_IP_BEACON_ALLOW_JOIN 0x01
#define ZBEE_IP_BEACON_ROUTER_CAPACITY 0x02
#define ZBEE_IP_BEACON_HOST_CAPACITY 0x04
#define ZBEE_IP_BEACON_UNSECURE 0x80 /* Undocumented bit for test networks. */
#define ZBEE_IP_BEACON_TLV_LENGTH_MASK 0x0f
#define ZBEE_IP_BEACON_TLV_TYPE_MASK 0xf0
#define ZBEE_IP_BEACON_TLV_TYPE_LFDI 0x0
#endif /* PACKET_ZBEE_NWK_H */