forked from osmocom/wireshark
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:
parent
19c1989cfa
commit
177c6556f7
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue