aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-wisun.c
diff options
context:
space:
mode:
authorRobert Sauter <sauter@locoslab.com>2018-02-16 12:58:12 +0100
committerStig Bjørlykke <stig@bjorlykke.org>2018-02-17 18:14:35 +0000
commitf0393a5975e96665c6d828ec2d7d103372e18acd (patch)
tree54525040c2ab75816890612e0be43ab58c776584 /epan/dissectors/packet-wisun.c
parent306c1c85cdf321ba81e5ccf0c6299182f66ea34c (diff)
wisun: Add EDFE support
During an EDFE exchange the source addresses are omitted after the first frame. Restore the information to enable decryption and 6LoWPAN reassembly. Change-Id: I9660c81e0536cea56caf104a16e41eaf6c123e09 Reviewed-on: https://code.wireshark.org/review/25819 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
Diffstat (limited to 'epan/dissectors/packet-wisun.c')
-rw-r--r--epan/dissectors/packet-wisun.c84
1 files changed, 80 insertions, 4 deletions
diff --git a/epan/dissectors/packet-wisun.c b/epan/dissectors/packet-wisun.c
index c7980cf776..863fb5b7c0 100644
--- a/epan/dissectors/packet-wisun.c
+++ b/epan/dissectors/packet-wisun.c
@@ -22,12 +22,26 @@
#include <epan/etypes.h>
#include <epan/oui.h>
#include <wsutil/pint.h>
+#include <wmem/wmem_map.h>
+#include <wmem/wmem_tree.h>
#include "packet-ieee802154.h"
void proto_register_wisun(void);
void proto_reg_handoff_wisun(void);
+/* EDFE support */
+typedef struct {
+ ieee802154_map_rec initiator; // use start_fnum and end_fnum to record exchange start/end
+ ieee802154_map_rec target;
+} edfe_exchange_t;
+
+// for each exchange, maps both source address and destination address to a
+// (distinct) tree that uses the frame number of the first exchange frame to
+// map to the shared edfe_exchange_t
+static wmem_map_t* edfe_byaddr;
+
+
/* Wi-SUN Header IE Sub-ID Values. */
#define WISUN_SUBID_UTT 1
#define WISUN_SUBID_BT 2
@@ -243,6 +257,7 @@ static expert_field ei_wisun_subid_unsupported = EI_INIT;
static expert_field ei_wisun_wsie_short_format = EI_INIT;
static expert_field ei_wisun_wsie_unsupported = EI_INIT;
static expert_field ei_wisun_usie_channel_plan_invalid = EI_INIT;
+static expert_field ei_wisun_edfe_start_not_found = EI_INIT;
static int
wisun_add_wbxml_uint(tvbuff_t *tvb, proto_tree *tree, int hf, guint offset)
@@ -288,15 +303,71 @@ dissect_wisun_btie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guin
return 6;
}
+static void
+edfe_insert_exchange(guint64* addr, edfe_exchange_t* exchange)
+{
+ wmem_tree_t* byframe = (wmem_tree_t *)wmem_map_lookup(edfe_byaddr, addr);
+ if (!byframe) {
+ byframe = wmem_tree_new(wmem_file_scope());
+ wmem_map_insert(edfe_byaddr, addr, byframe);
+ }
+ wmem_tree_insert32(byframe, exchange->initiator.start_fnum, exchange);
+}
+
static int
-dissect_wisun_fcie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
+dissect_wisun_fcie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, ieee802154_packet *packet)
{
nstime_t ts;
ts.secs = 0;
- ts.nsecs = tvb_get_guint8(tvb, offset) * 1000000UL;
+ guint8 tx = tvb_get_guint8(tvb, offset);
+ ts.nsecs = tx * 1000000;
proto_tree_add_time(tree, hf_wisun_fcie_tx, tvb, offset, 1, &ts);
- ts.nsecs = tvb_get_guint8(tvb, offset+1) * 1000000UL;
+ guint8 rx = tvb_get_guint8(tvb, offset + 1);
+ ts.nsecs = rx * 1000000;
proto_tree_add_time(tree, hf_wisun_fcie_rx, tvb, offset + 1, 1, &ts);
+
+ // EDFE processing
+ ieee802154_hints_t* hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
+ proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
+ if (packet && hints && packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
+ // first packet has source address
+ if (!hints->map_rec && packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
+ edfe_exchange_t* ex = wmem_new(wmem_file_scope(), edfe_exchange_t);
+ ex->initiator.proto = ex->target.proto = "Wi-SUN";
+ ex->initiator.addr64 = packet->src64;
+ ex->target.addr64 = packet->dst64;
+ ex->initiator.start_fnum = pinfo->num;
+ ex->initiator.end_fnum = ~(guint)0;
+ edfe_insert_exchange(&ex->initiator.addr64, ex);
+ edfe_insert_exchange(&ex->target.addr64, ex);
+ } else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) {
+ if (!hints->map_rec) {
+ wmem_tree_t* byframe = (wmem_tree_t *)wmem_map_lookup(edfe_byaddr, &packet->dst64);
+ if (byframe) {
+ edfe_exchange_t *ex = (edfe_exchange_t *)wmem_tree_lookup32_le(byframe, pinfo->num);
+ if (ex && pinfo->num <= ex->initiator.end_fnum) {
+ hints->map_rec = ex->initiator.addr64 == packet->dst64 ? &ex->target : &ex->initiator;
+ if (tx == 0 && rx == 0) {
+ // last frame
+ ex->initiator.end_fnum = pinfo->num;
+ }
+ }
+ }
+ }
+ if (hints->map_rec) {
+ // Set address to ensure that 6LoWPAN reassembly works
+ // Adapted from packet-ieee802.15.4.c
+ guint64 *p_addr = wmem_new(pinfo->pool, guint64);
+ /* Copy and convert the address to network byte order. */
+ *p_addr = pntoh64(&(hints->map_rec->addr64));
+ set_address(&pinfo->dl_src, AT_EUI64, 8, p_addr);
+ copy_address_shallow(&pinfo->src, &pinfo->dl_src);
+ } else {
+ expert_add_info(pinfo, tree, &ei_wisun_edfe_start_not_found);
+ }
+ }
+ }
+
return 2;
}
@@ -321,6 +392,7 @@ dissect_wisun_hie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
guint offset;
proto_tree *subtree;
guint8 subid = tvb_get_guint8(tvb, 2);
+ ieee802154_packet *packet = (ieee802154_packet*)data;
offset = 3;
switch (subid) {
@@ -336,7 +408,7 @@ dissect_wisun_hie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
case WISUN_SUBID_FC:
subtree = wisun_create_hie_tree(tvb, tree, hf_wisun_fcie, ett_wisun_fcie);
- offset += dissect_wisun_fcie(tvb, pinfo, subtree, offset);
+ offset += dissect_wisun_fcie(tvb, pinfo, subtree, offset, packet);
break;
case WISUN_SUBID_RSL:
@@ -1057,6 +1129,8 @@ void proto_register_wisun(void)
"Invalid Channel Plan", EXPFILL }},
{ &ei_wisun_wsie_unsupported, { "wisun.wsie.unsupported", PI_PROTOCOL, PI_WARN,
"Unsupported Sub-IE ID", EXPFILL }},
+ { &ei_wisun_edfe_start_not_found, { "wisun.edfe.start_not_found", PI_SEQUENCE, PI_WARN,
+ "EDFE Transfer: start frame not found", EXPFILL }},
};
expert_module_t* expert_wisun;
@@ -1071,6 +1145,8 @@ void proto_register_wisun(void)
expert_register_field_array(expert_wisun, ei, array_length(ei));
register_dissector("wisun.sec", dissect_wisun_sec, proto_wisun_sec);
+
+ edfe_byaddr = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_int64_hash, g_int64_equal);
}
void proto_reg_handoff_wisun(void)