aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-btmesh.c
diff options
context:
space:
mode:
authorPiotr Winiarczyk <wino45@gmail.com>2019-04-22 23:53:41 +0200
committerAnders Broman <a.broman58@gmail.com>2019-04-25 03:46:17 +0000
commit4828e45432af003c0c171d1ca511e6ae1dc5fa73 (patch)
tree4a2654a23334c0e4e64c50edf062700fda8c2b7c /epan/dissectors/packet-btmesh.c
parent5ae6a9bea6ba943e6c674799a7b906b3dffed157 (diff)
BTMESH: Adding defragmentation of messages
Adding defragmentation of control and access layer messages. Adding dissection of Friend Update and Heartbeat control messages. Bug: 15722 Change-Id: Ib6d8899a2d089dfa3b3eee6cd3e5248b8dc26aff Reviewed-on: https://code.wireshark.org/review/32948 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-btmesh.c')
-rw-r--r--epan/dissectors/packet-btmesh.c673
1 files changed, 576 insertions, 97 deletions
diff --git a/epan/dissectors/packet-btmesh.c b/epan/dissectors/packet-btmesh.c
index 2d4ede2865..47bbbe4b57 100644
--- a/epan/dissectors/packet-btmesh.c
+++ b/epan/dissectors/packet-btmesh.c
@@ -21,6 +21,9 @@
#include <epan/expert.h>
#include <stdio.h>
#include <epan/uat.h>
+#include <epan/reassemble.h>
+
+#define BTMESH_NOT_USED 0
void proto_register_btmesh(void);
@@ -73,37 +76,66 @@ static int hf_btmesh_obo = -1;
static int hf_btmesh_seqzero = -1;
static int hf_btmesh_rfu = -1;
static int hf_btmesh_blockack = -1;
-static int hf_btmesh_criteria_rfu = -1;
-static int hf_btmesh_padding = -1;
-static int hf_btmesh_fsn = -1;
-static int hf_btmesh_criteria_rssifactor = -1;
-static int hf_btmesh_criteria_receivewindowfactor = -1;
-static int hf_btmesh_criteria_minqueuesizelog = -1;
-static int hf_btmesh_receivedelay = -1;
-static int hf_btmesh_polltimeout = -1;
-static int hf_btmesh_previousaddress = -1;
-static int hf_btmesh_numelements = -1;
-static int hf_btmesh_lpncounter = -1;
-static int hf_btmesh_receivewindow = -1;
-static int hf_btmesh_queuesize = -1;
-static int hf_btmesh_subscriptionlistsize = -1;
-static int hf_btmesh_rssi = -1;
-static int hf_btmesh_friendcounter = -1;
-static int hf_btmesh_lpnaddress = -1;
-static int hf_btmesh_transactionnumber = -1;
+static int hf_btmesh_cntr_criteria_rfu = -1;
+static int hf_btmesh_cntr_padding = -1;
+static int hf_btmesh_cntr_fsn = -1;
+
+static int hf_btmesh_cntr_key_refresh_flag = -1;
+static int hf_btmesh_cntr_iv_update_flag = -1;
+static int hf_btmesh_cntr_flags_rfu = -1;
+static int hf_btmesh_cntr_iv_index = -1;
+static int hf_btmesh_cntr_md = -1;
+
+static int hf_btmesh_cntr_heartbeat_rfu = -1;
+static int hf_btmesh_cntr_init_ttl = -1;
+static int hf_btmesh_cntr_feature_relay = -1;
+static int hf_btmesh_cntr_feature_proxy = -1;
+static int hf_btmesh_cntr_feature_friend = -1;
+static int hf_btmesh_cntr_feature_low_power = -1;
+static int hf_btmesh_cntr_feature_rfu = -1;
+
+static int hf_btmesh_cntr_criteria_rssifactor = -1;
+static int hf_btmesh_cntr_criteria_receivewindowfactor = -1;
+static int hf_btmesh_cntr_criteria_minqueuesizelog = -1;
+static int hf_btmesh_cntr_receivedelay = -1;
+static int hf_btmesh_cntr_polltimeout = -1;
+static int hf_btmesh_cntr_previousaddress = -1;
+static int hf_btmesh_cntr_numelements = -1;
+static int hf_btmesh_cntr_lpncounter = -1;
+static int hf_btmesh_cntr_receivewindow = -1;
+static int hf_btmesh_cntr_queuesize = -1;
+static int hf_btmesh_cntr_subscriptionlistsize = -1;
+static int hf_btmesh_cntr_rssi = -1;
+static int hf_btmesh_cntr_friendcounter = -1;
+static int hf_btmesh_cntr_lpnaddress = -1;
+static int hf_btmesh_cntr_transactionnumber = -1;
static int hf_btmesh_enc_access_pld = -1;
static int hf_btmesh_transtmic = -1;
static int hf_btmesh_szmic = -1;
static int hf_btmesh_seqzero_data = -1;
static int hf_btmesh_sego = -1;
static int hf_btmesh_segn = -1;
+static int hf_btmesh_seg_rfu = -1;
static int hf_btmesh_segment = -1;
+static int hf_btmesh_cntr_unknown_payload = -1;
+
+static int hf_btmesh_segmented_access_fragments = -1;
+static int hf_btmesh_segmented_access_fragment = -1;
+static int hf_btmesh_segmented_access_fragment_overlap = -1;
+static int hf_btmesh_segmented_access_fragment_overlap_conflict = -1;
+static int hf_btmesh_segmented_access_fragment_multiple_tails = -1;
+static int hf_btmesh_segmented_access_fragment_too_long_fragment = -1;
+static int hf_btmesh_segmented_access_fragment_error = -1;
+static int hf_btmesh_segmented_access_fragment_count = -1;
+static int hf_btmesh_segmented_access_reassembled_length = -1;
static int ett_btmesh = -1;
static int ett_btmesh_net_pdu = -1;
static int ett_btmesh_transp_pdu = -1;
static int ett_btmesh_transp_ctrl_msg = -1;
static int ett_btmesh_upper_transp_acc_pdu = -1;
+static int ett_btmesh_segmented_access_fragments = -1;
+static int ett_btmesh_segmented_access_fragment = -1;
static expert_field ei_btmesh_not_decoded_yet = EI_INIT;
@@ -146,6 +178,24 @@ static const value_string btmesh_ctrl_opcode_vals[] = {
{ 0, NULL }
};
+static const value_string btmesh_cntr_key_refresh_flag_vals[] = {
+ { 0x0, "Not-In-Phase2" },
+ { 0x1, "In-Phase2" },
+ { 0, NULL }
+};
+
+static const value_string btmesh_cntr_iv_update_flag_vals[] = {
+ { 0x0, "Normal operation" },
+ { 0x1, "IV Update active" },
+ { 0, NULL }
+};
+
+static const value_string btmesh_cntr_md_vals[] = {
+ { 0x0, "Friend Queue is empty" },
+ { 0x1, "Friend Queue is not empty" },
+ { 0, NULL }
+};
+
static const true_false_string btmesh_obo = {
"Friend node that is acknowledging this message on behalf of a Low Power node",
"Node that is directly addressed by the received message"
@@ -179,12 +229,152 @@ static const value_string btmesh_criteria_minqueuesizelog_vals[] = {
{ 0, NULL }
};
-static const value_string btmesh_szmic_vals[] = {
+static const value_string btmesh_szmic_vals[] = {
{ 0x0, "32-bit" },
{ 0x1, "64-bit" },
{ 0, NULL }
};
+/* Upper Transport Message reassembly */
+
+static reassembly_table upper_transport_reassembly_table;
+
+static const fragment_items btmesh_segmented_access_frag_items = {
+ &ett_btmesh_segmented_access_fragments,
+ &ett_btmesh_segmented_access_fragment,
+
+ &hf_btmesh_segmented_access_fragments,
+ &hf_btmesh_segmented_access_fragment,
+ &hf_btmesh_segmented_access_fragment_overlap,
+ &hf_btmesh_segmented_access_fragment_overlap_conflict,
+ &hf_btmesh_segmented_access_fragment_multiple_tails,
+ &hf_btmesh_segmented_access_fragment_too_long_fragment,
+ &hf_btmesh_segmented_access_fragment_error,
+ &hf_btmesh_segmented_access_fragment_count,
+ NULL,
+ &hf_btmesh_segmented_access_reassembled_length,
+ /* Reassembled data field */
+ NULL,
+ "fragments"
+};
+
+static int hf_btmesh_segmented_control_fragments = -1;
+static int hf_btmesh_segmented_control_fragment = -1;
+static int hf_btmesh_segmented_control_fragment_overlap = -1;
+static int hf_btmesh_segmented_control_fragment_overlap_conflict = -1;
+static int hf_btmesh_segmented_control_fragment_multiple_tails = -1;
+static int hf_btmesh_segmented_control_fragment_too_long_fragment = -1;
+static int hf_btmesh_segmented_control_fragment_error = -1;
+static int hf_btmesh_segmented_control_fragment_count = -1;
+static int hf_btmesh_segmented_control_reassembled_length = -1;
+
+static int ett_btmesh_segmented_control_fragments = -1;
+static int ett_btmesh_segmented_control_fragment = -1;
+
+static const fragment_items btmesh_segmented_control_frag_items = {
+ &ett_btmesh_segmented_control_fragments,
+ &ett_btmesh_segmented_control_fragment,
+
+ &hf_btmesh_segmented_control_fragments,
+ &hf_btmesh_segmented_control_fragment,
+ &hf_btmesh_segmented_control_fragment_overlap,
+ &hf_btmesh_segmented_control_fragment_overlap_conflict,
+ &hf_btmesh_segmented_control_fragment_multiple_tails,
+ &hf_btmesh_segmented_control_fragment_too_long_fragment,
+ &hf_btmesh_segmented_control_fragment_error,
+ &hf_btmesh_segmented_control_fragment_count,
+ NULL,
+ &hf_btmesh_segmented_control_reassembled_length,
+ /* Reassembled data field */
+ NULL,
+ "fragments"
+};
+
+typedef struct _upper_transport_fragment_key {
+ guint16 src;
+ guint16 seq0;
+} upper_transport_fragment_key;
+
+static guint
+upper_transport_fragment_hash(gconstpointer k)
+{
+ const upper_transport_fragment_key* key = (const upper_transport_fragment_key*) k;
+ guint hash_val;
+
+ hash_val = key->src;
+ hash_val += ( ((guint)key->seq0) << 16);
+ return hash_val;
+}
+
+static gint
+upper_transport_fragment_equal(gconstpointer k1, gconstpointer k2)
+{
+ const upper_transport_fragment_key* key1 = (const upper_transport_fragment_key*) k1;
+ const upper_transport_fragment_key* key2 = (const upper_transport_fragment_key*) k2;
+
+ return ((key1->src == key2->src) && (key1->seq0 == key2->seq0)
+ ? TRUE : FALSE);
+}
+
+static void *
+upper_transport_fragment_temporary_key(const packet_info *pinfo _U_, const guint32 id _U_,
+ const void *data)
+{
+ upper_transport_fragment_key *key = g_slice_new(upper_transport_fragment_key);
+ const upper_transport_fragment_key *pkt = (const upper_transport_fragment_key *)data;
+
+ key->src = pkt->src;
+ key->seq0 = pkt->seq0;
+
+ return key;
+}
+
+static void
+upper_transport_fragment_free_temporary_key(gpointer ptr)
+{
+ upper_transport_fragment_key *key = (upper_transport_fragment_key *)ptr;
+
+ g_slice_free(upper_transport_fragment_key, key);
+}
+
+static void *
+upper_transport_fragment_persistent_key(const packet_info *pinfo _U_, const guint32 id _U_,
+ const void *data)
+{
+ upper_transport_fragment_key *key = g_slice_new(upper_transport_fragment_key);
+ const upper_transport_fragment_key *pkt = (const upper_transport_fragment_key *)data;
+
+ key->src = pkt->src;
+ key->seq0 = pkt->seq0;
+
+ return key;
+}
+
+static void
+upper_transport_fragment_free_persistent_key(gpointer ptr)
+{
+ upper_transport_fragment_key *key = (upper_transport_fragment_key *)ptr;
+ if (key) {
+ g_slice_free(upper_transport_fragment_key, key);
+ }
+}
+
+static const reassembly_table_functions upper_transport_reassembly_table_functions = {
+ upper_transport_fragment_hash,
+ upper_transport_fragment_equal,
+ upper_transport_fragment_temporary_key,
+ upper_transport_fragment_persistent_key,
+ upper_transport_fragment_free_temporary_key,
+ upper_transport_fragment_free_persistent_key
+};
+
+static void
+upper_transport_init_routine(void)
+{
+ reassembly_table_register(&upper_transport_reassembly_table, &upper_transport_reassembly_table_functions);
+}
+
+
/* A BT Mesh dissector is not realy useful without decryption as all packets are encrypted. Just leave a stub dissector outside of*/
#if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
@@ -227,7 +417,6 @@ s1(guint8 *m, size_t mlen, guint8 *salt)
/* Now close the mac handle */
gcry_mac_close(mac_hd);
-
return TRUE;
}
@@ -475,9 +664,10 @@ btmesh_deobfuscate(tvbuff_t *tvb, packet_info *pinfo, int offset _U_, uat_btmesh
}
static void
-dissect_btmesh_transport_constrol_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint32 opcode)
+dissect_btmesh_transport_control_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint32 opcode)
{
proto_tree *sub_tree;
+
sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_btmesh_transp_ctrl_msg, NULL, "Transport Control Message %s",
val_to_str_const(opcode, btmesh_ctrl_opcode_vals, "Unknown"));
@@ -485,101 +675,121 @@ dissect_btmesh_transport_constrol_message(tvbuff_t *tvb, packet_info *pinfo, pro
case 1:
/* 3.6.5.1 Friend Poll */
/* Padding 7 bits */
- proto_tree_add_item(sub_tree, hf_btmesh_padding, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_padding, tvb, offset, 1, ENC_BIG_ENDIAN);
/* FSN 1 bit*/
- proto_tree_add_item(sub_tree, hf_btmesh_fsn, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_fsn, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
case 2:
/* 3.6.5.2 Friend Update */
/* Flags 1 octet */
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_key_refresh_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_iv_update_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_flags_rfu, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
/* IV Index 4 octets*/
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_iv_index, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
/* MD 1 octet */
- proto_tree_add_expert(sub_tree, pinfo, &ei_btmesh_not_decoded_yet, tvb, offset, -1);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_md, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
break;
case 3:
/* Friend Request */
/* Criteria 1 octet */
/* RFU 1 bit */
- proto_tree_add_item(sub_tree, hf_btmesh_criteria_rfu, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_criteria_rfu, tvb, offset, 1, ENC_BIG_ENDIAN);
/* RSSIFactor 2 bits */
- proto_tree_add_item(sub_tree, hf_btmesh_criteria_rssifactor, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_criteria_rssifactor, tvb, offset, 1, ENC_BIG_ENDIAN);
/* ReceiveWindowFactor 2 bits */
- proto_tree_add_item(sub_tree, hf_btmesh_criteria_receivewindowfactor, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_criteria_receivewindowfactor, tvb, offset, 1, ENC_BIG_ENDIAN);
/* MinQueueSizeLog 3 bits */
- proto_tree_add_item(sub_tree, hf_btmesh_criteria_minqueuesizelog, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_criteria_minqueuesizelog, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* ReceiveDelay 1 octet */
- proto_tree_add_item(sub_tree, hf_btmesh_receivedelay, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_receivedelay, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* PollTimeout 3 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_polltimeout, tvb, offset, 3, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_polltimeout, tvb, offset, 3, ENC_BIG_ENDIAN);
offset+=3;
/* PreviousAddress 2 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_previousaddress, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_previousaddress, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
/* NumElements 1 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_numelements, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_numelements, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* LPNCounter 1 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_lpncounter, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_lpncounter, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
case 4:
/* 3.6.5.4 Friend Offer */
/* ReceiveWindow 1 octet */
- proto_tree_add_item(sub_tree, hf_btmesh_receivewindow, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_receivewindow, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* QueueSize 1 octet */
- proto_tree_add_item(sub_tree, hf_btmesh_queuesize, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_queuesize, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* SubscriptionListSize 1 octet */
- proto_tree_add_item(sub_tree, hf_btmesh_subscriptionlistsize, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_subscriptionlistsize, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* RSSI 1 octet */
- proto_tree_add_item(sub_tree, hf_btmesh_rssi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_rssi, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* FriendCounter 2 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_friendcounter, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_friendcounter, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
case 5:
/* 3.6.5.5 Friend Clear */
/* LPNAddress 2 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_lpnaddress, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_lpnaddress, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 2;
/* LPNCounter 2 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_lpncounter, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_lpncounter, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
case 6:
/* 3.6.5.6 Friend Clear Confirm */
/* LPNAddress 2 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_lpnaddress, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_lpnaddress, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 2;
/* LPNCounter 2 octets */
- proto_tree_add_item(sub_tree, hf_btmesh_lpncounter, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_lpncounter, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
case 7:
/* 3.6.5.7 Friend Subscription List Add */
/* TransactionNumber 1 octet */
- proto_tree_add_item(sub_tree, hf_btmesh_transactionnumber, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_transactionnumber, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* AddressList 2 * N */
proto_tree_add_expert(sub_tree, pinfo, &ei_btmesh_not_decoded_yet, tvb, offset, -1);
break;
case 8:
/* 3.6.5.8 Friend Subscription List Remove */
- proto_tree_add_item(sub_tree, hf_btmesh_transactionnumber, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_transactionnumber, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* AddressList 2 * N */
proto_tree_add_expert(sub_tree, pinfo, &ei_btmesh_not_decoded_yet, tvb, offset, -1);
break;
case 9:
/* 3.6.5.9 Friend Subscription List Confirm */
- proto_tree_add_item(sub_tree, hf_btmesh_transactionnumber, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_transactionnumber, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
break;
case 10:
/* 3.6.5.10 Heartbeat */
+ /* RFU & InitTTL */
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_heartbeat_rfu, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_init_ttl, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ /* Features */
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_feature_relay, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_feature_proxy, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_feature_friend, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_feature_low_power, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_feature_rfu, tvb, offset, 2, ENC_BIG_ENDIAN);
+ break;
default:
+ //Payload
+ proto_tree_add_item(sub_tree, hf_btmesh_cntr_unknown_payload, tvb, offset, -1, ENC_NA);
proto_tree_add_expert(sub_tree, pinfo, &ei_btmesh_not_decoded_yet, tvb, offset, -1);
break;
}
@@ -596,28 +806,85 @@ dissect_btmesh_transport_access_message(tvbuff_t *tvb, packet_info *pinfo _U_, p
proto_tree_add_item(sub_tree, hf_btmesh_enc_access_pld, tvb, offset, length - transmic_size, ENC_NA);
offset += (length - transmic_size);
- proto_tree_add_item(sub_tree, hf_btmesh_transtmic, tvb, offset, transmic_size, ENC_BIG_ENDIAN);
-
+ proto_tree_add_item(sub_tree, hf_btmesh_transtmic, tvb, offset, transmic_size, ENC_NA);
}
static void
-dissect_btmesh_transport_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean cntrl)
+dissect_btmesh_transport_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean cntrl, guint32 src)
{
proto_tree *sub_tree;
proto_item *ti;
int offset = 0;
- guint32 value, opcode;
+ guint32 seg, opcode, rfu;
+ guint32 seqzero, sego, segn;
/* We receive the full decrypted buffer including DST, skip to opcode */
offset += 2;
sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_btmesh_transp_pdu, &ti, "Lower Transport PDU");
if (cntrl) {
- proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_cntr_seg, tvb, offset, 1, ENC_BIG_ENDIAN, &value);
- if (value) {
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_cntr_seg, tvb, offset, 1, ENC_BIG_ENDIAN, &seg);
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_cntr_opcode, tvb, offset, 1, ENC_BIG_ENDIAN, &opcode);
+ offset++;
+
+ if (seg) {
/* Segmented */
+ fragment_head *fd_head = NULL;
+
+ /* RFU */
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_seg_rfu, tvb, offset, 3, ENC_BIG_ENDIAN, &rfu);
+ /* SeqZero 13 */
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_seqzero_data, tvb, offset, 3, ENC_BIG_ENDIAN, &seqzero);
+ /* SegO 5 Segment Offset number */
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_sego, tvb, offset, 3, ENC_BIG_ENDIAN, &sego);
+ /* SegN 5 Last Segment number */
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_segn, tvb, offset, 3, ENC_BIG_ENDIAN, &segn);
+ offset += 3;
+
+ /* Segment */
+ proto_tree_add_item(sub_tree, hf_btmesh_segment, tvb, offset, -1, ENC_NA);
+
+ upper_transport_fragment_key frg_key;
+ /* src is 15 bit, seqzero is 13 bit*/
+ frg_key.src = src;
+ frg_key.seq0 = seqzero;
+
+ if (!pinfo->fd->visited) {
+ guint32 total_length = 0;
+ if (segn == sego) {
+ total_length = segn * 8 + tvb_captured_length_remaining(tvb, offset);
+ }
+
+ /* Last fragment can be delivered out of order, and can be the first one. */
+ fd_head = fragment_get(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key);
+
+ if ((fd_head) && (total_length)) {
+ fragment_set_tot_len(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key, total_length);
+ }
+ fd_head = fragment_add(&upper_transport_reassembly_table,
+ tvb, offset, pinfo,
+ BTMESH_NOT_USED, &frg_key,
+ 8 * sego,
+ tvb_captured_length_remaining(tvb, offset),
+ ( segn == 0 ? FALSE : TRUE) );
+
+ if ((!fd_head) && (total_length)) {
+ fragment_set_tot_len(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key, total_length);
+ }
+ } else {
+ fd_head = fragment_get(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key);
+ if (fd_head && (fd_head->flags&FD_DEFRAGMENTED)) {
+ tvbuff_t *next_tvb;
+ next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Control PDU", fd_head, &btmesh_segmented_control_frag_items, NULL, sub_tree);
+ if (next_tvb) {
+ col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled)");
+ dissect_btmesh_transport_control_message(next_tvb, pinfo, tree, 0, opcode);
+ } else {
+ col_append_fstr(pinfo->cinfo, COL_INFO," (Message fragment %u)", sego);
+ }
+ }
+ }
+
} else {
- proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_cntr_opcode, tvb, offset, 1, ENC_BIG_ENDIAN, &opcode);
- offset++;
col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
val_to_str_const(opcode, btmesh_ctrl_opcode_vals, "Unknown"));
if (opcode == 0) {
@@ -632,11 +899,11 @@ dissect_btmesh_transport_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
proto_tree_add_item(sub_tree, hf_btmesh_blockack, tvb, offset, 4, ENC_BIG_ENDIAN);
return;
}
- dissect_btmesh_transport_constrol_message(tvb, pinfo, tree, offset, opcode);
+ dissect_btmesh_transport_control_message(tvb, pinfo, tree, offset, opcode);
}
} else {
/* Access message */
- guint32 seg, afk, aid, szmic;
+ guint32 afk, aid, szmic;
/* Access message */
proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_acc_seg, tvb, offset, 1, ENC_BIG_ENDIAN, &seg);
/* AKF 1 Application Key Flag */
@@ -646,17 +913,61 @@ dissect_btmesh_transport_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
offset++;
if (seg) {
/* Segmented */
+ fragment_head *fd_head = NULL;
+
/* SZMIC 1 Size of TransMIC */
proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_szmic, tvb, offset, 3, ENC_BIG_ENDIAN, &szmic);
/* SeqZero 13 Least significant bits of SeqAuth */
- proto_tree_add_item(sub_tree, hf_btmesh_seqzero_data, tvb, offset, 3, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_seqzero_data, tvb, offset, 3, ENC_BIG_ENDIAN, &seqzero);
/* SegO 5 Segment Offset number */
- proto_tree_add_item(sub_tree, hf_btmesh_sego, tvb, offset, 3, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_sego, tvb, offset, 3, ENC_BIG_ENDIAN, &sego);
/* SegN 5 Last Segment number */
- proto_tree_add_item(sub_tree, hf_btmesh_segn, tvb, offset, 3, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(sub_tree, hf_btmesh_segn, tvb, offset, 3, ENC_BIG_ENDIAN, &segn);
offset += 3;
+
/* Segment m 8 to 96 Segment m of the Upper Transport Access PDU */
proto_tree_add_item(sub_tree, hf_btmesh_segment, tvb, offset, -1, ENC_NA);
+
+ upper_transport_fragment_key frg_key;
+ /* src is 15 bit, seqzero is 13 bit*/
+ frg_key.src = src;
+ frg_key.seq0 = seqzero;
+
+ if (!pinfo->fd->visited) {
+ guint32 total_length = 0;
+ if (segn == sego) {
+ total_length = segn * 12 + tvb_captured_length_remaining(tvb, offset);
+ }
+
+ /* Last fragment can be delivered out of order, and can be the first one. */
+ fd_head = fragment_get(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key);
+
+ if ((fd_head) && (total_length)) {
+ fragment_set_tot_len(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key, total_length);
+ }
+ fd_head = fragment_add(&upper_transport_reassembly_table,
+ tvb, offset, pinfo,
+ BTMESH_NOT_USED, &frg_key,
+ 12 * sego,
+ tvb_captured_length_remaining(tvb, offset),
+ ( segn == 0 ? FALSE : TRUE) );
+
+ if ((!fd_head) && (total_length)) {
+ fragment_set_tot_len(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key, total_length);
+ }
+ } else {
+ fd_head = fragment_get(&upper_transport_reassembly_table, pinfo, BTMESH_NOT_USED, &frg_key);
+ if (fd_head && (fd_head->flags&FD_DEFRAGMENTED)) {
+ tvbuff_t *next_tvb;
+ next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Access PDU", fd_head, &btmesh_segmented_access_frag_items, NULL, sub_tree);
+ if (next_tvb) {
+ col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled)");
+ dissect_btmesh_transport_access_message(next_tvb, pinfo, tree, 0, (szmic ? 8 : 4 ));
+ } else {
+ col_append_fstr(pinfo->cinfo, COL_INFO," (Message fragment %u)", sego);
+ }
+ }
+ }
} else {
proto_item_set_len(ti, 1);
dissect_btmesh_transport_access_message(tvb, pinfo, tree, offset, 4/*TransMic is 32 bits*/);
@@ -826,7 +1137,7 @@ dissect_btmesh_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *da
offset += net_mic_size;
if (de_cry_tvb) {
- dissect_btmesh_transport_pdu(de_cry_tvb, pinfo, netw_tree, cntrl);
+ dissect_btmesh_transport_pdu(de_cry_tvb, pinfo, netw_tree, cntrl, src);
}
} else {
proto_tree_add_item(sub_tree, hf_btmesh_obfuscated, tvb, offset, 6, ENC_NA);
@@ -1128,96 +1439,161 @@ proto_register_btmesh(void)
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_criteria_rfu,
- { "RFU", "btmesh.criteria.rfu",
+ { &hf_btmesh_cntr_criteria_rfu,
+ { "RFU", "btmesh.cntr.criteria.rfu",
FT_UINT8, BASE_DEC, NULL, 0x80,
NULL, HFILL }
},
- { &hf_btmesh_padding,
- { "Padding", "btmesh.padding",
+ { &hf_btmesh_cntr_padding,
+ { "Padding", "btmesh.cntr.padding",
FT_UINT8, BASE_DEC, NULL, 0xfe,
NULL, HFILL }
},
- { &hf_btmesh_fsn,
- { "Friend Sequence Number(FSN)", "btmesh.fsn",
+ { &hf_btmesh_cntr_fsn,
+ { "Friend Sequence Number(FSN)", "btmesh.cntr.fsn",
FT_UINT8, BASE_DEC, NULL, 0x01,
NULL, HFILL }
},
- { &hf_btmesh_criteria_rssifactor,
- { "RSSIFactor", "btmesh.criteria.rssifactor",
+ { &hf_btmesh_cntr_key_refresh_flag,
+ { "Key Refresh Flag", "btmesh.cntr.keyrefreshflag",
+ FT_UINT8, BASE_DEC, VALS(btmesh_cntr_key_refresh_flag_vals), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_iv_update_flag,
+ { "IV Update Flag", "btmesh.cntr.ivupdateflag",
+ FT_UINT8, BASE_DEC, VALS(btmesh_cntr_iv_update_flag_vals), 0x02,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_flags_rfu,
+ { "IV Update Flag", "btmesh.cntr.flagsrfu",
+ FT_UINT8, BASE_DEC, NULL, 0xFC,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_iv_index,
+ { "IV Index", "btmesh.cntr.ivindex",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_md,
+ { "MD (More Data)", "btmesh.cntr.md",
+ FT_UINT8, BASE_DEC, VALS(btmesh_cntr_md_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_criteria_rssifactor,
+ { "RSSIFactor", "btmesh.cntr.criteria.rssifactor",
FT_UINT8, BASE_DEC, VALS(btmesh_criteria_rssifactor_vals), 0x60,
NULL, HFILL }
},
- { &hf_btmesh_criteria_receivewindowfactor,
- { "ReceiveWindowFactor", "btmesh.criteria.receivewindowfactor",
+ { &hf_btmesh_cntr_criteria_receivewindowfactor,
+ { "ReceiveWindowFactor", "btmesh.cntr.criteria.receivewindowfactor",
FT_UINT8, BASE_DEC, VALS(btmesh_criteria_receivewindowfactor_vals), 0x18,
NULL, HFILL }
},
- { &hf_btmesh_criteria_minqueuesizelog,
- { "MinQueueSizeLog", "btmesh.criteria.minqueuesizelog",
+ { &hf_btmesh_cntr_criteria_minqueuesizelog,
+ { "MinQueueSizeLog", "btmesh.cntr.criteria.minqueuesizelog",
FT_UINT8, BASE_DEC, VALS(btmesh_criteria_minqueuesizelog_vals), 0x07,
NULL, HFILL }
},
- { &hf_btmesh_receivedelay,
- { "ReceiveDelay", "btmesh.receivedelay",
+ { &hf_btmesh_cntr_receivedelay,
+ { "ReceiveDelay", "btmesh.cntr.receivedelay",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_polltimeout,
- { "PollTimeout", "btmesh.polltimeout",
+ { &hf_btmesh_cntr_polltimeout,
+ { "PollTimeout", "btmesh.cntr.polltimeout",
FT_UINT24, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_previousaddress,
- { "PreviousAddress", "btmesh.previousaddress",
+ { &hf_btmesh_cntr_previousaddress,
+ { "PreviousAddress", "btmesh.cntr.previousaddress",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_numelements,
- { "NumElements", "btmesh.numelements",
+ { &hf_btmesh_cntr_numelements,
+ { "NumElements", "btmesh.cntr.numelements",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_lpncounter,
- { "LPNCounter", "btmesh.lpncounter",
+ { &hf_btmesh_cntr_lpncounter,
+ { "LPNCounter", "btmesh.cntr.lpncounter",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_receivewindow,
- { "ReceiveWindow", "btmesh.receivewindow",
+ { &hf_btmesh_cntr_receivewindow,
+ { "ReceiveWindow", "btmesh.cntr.receivewindow",
FT_UINT8, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_queuesize,
- { "QueueSize", "btmesh.queuesize",
+ { &hf_btmesh_cntr_queuesize,
+ { "QueueSize", "btmesh.cntr.queuesize",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_subscriptionlistsize,
- { "SubscriptionListSize", "btmesh.subscriptionlistsize",
+ { &hf_btmesh_cntr_subscriptionlistsize,
+ { "SubscriptionListSize", "btmesh.cntr.subscriptionlistsize",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_rssi,
- { "RSSI", "btmesh.rssi",
+ { &hf_btmesh_cntr_rssi,
+ { "RSSI", "btmesh.cntr.rssi",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_friendcounter,
- { "FriendCounter", "btmesh.friendcounter",
+ { &hf_btmesh_cntr_friendcounter,
+ { "FriendCounter", "btmesh.cntr.friendcounter",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_lpnaddress,
- { "LPNAddress", "btmesh.lpnaddress",
+ { &hf_btmesh_cntr_lpnaddress,
+ { "LPNAddress", "btmesh.cntr.lpnaddress",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_btmesh_transactionnumber,
- { "TransactionNumber", "btmesh.transactionnumber",
+ { &hf_btmesh_cntr_transactionnumber,
+ { "TransactionNumber", "btmesh.cntr.transactionnumber",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_btmesh_cntr_heartbeat_rfu,
+ { "Reserved for Future Use", "btmesh.cntr.heartbeatrfu",
+ FT_UINT8, BASE_DEC, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_init_ttl,
+ { "InitTTL", "btmesh.cntr.initttl",
+ FT_UINT8, BASE_DEC, NULL, 0x7F,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_feature_relay,
+ { "Relay feature in use", "btmesh.cntr.feature.relay",
+ FT_BOOLEAN, 16, TFS(&tfs_true_false), 0x0001,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_feature_proxy,
+ { "Proxy feature in use", "btmesh.cntr.feature.proxy",
+ FT_BOOLEAN, 16, TFS(&tfs_true_false), 0x0002,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_feature_friend,
+ { "Friend feature in use", "btmesh.cntr.feature.friend",
+ FT_BOOLEAN, 16, TFS(&tfs_true_false), 0x0004,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_feature_low_power,
+ { "Low Power feature in use", "btmesh.cntr.feature.lowpower",
+ FT_BOOLEAN, 16, TFS(&tfs_true_false), 0x0008,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_feature_rfu,
+ { "Reserved for Future Use", "btmesh.cntr.feature.rfu",
+ FT_UINT16, BASE_DEC, NULL, 0xfff0,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_cntr_unknown_payload,
+ { "Unknown Control Message payload", "btmesh.cntr.unknownpayload",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_btmesh_enc_access_pld,
{ "Encrypted Access Payload", "btmesh.enc_access_pld",
FT_BYTES, BASE_NONE, NULL, 0x0,
@@ -1225,7 +1601,7 @@ proto_register_btmesh(void)
},
{ &hf_btmesh_transtmic,
{ "TransMIC", "btmesh.transtmic",
- FT_UINT32, BASE_HEX, NULL, 0x0,
+ FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_btmesh_szmic,
@@ -1235,7 +1611,7 @@ proto_register_btmesh(void)
},
{ &hf_btmesh_seqzero_data,
{ "SeqZero", "btmesh.seqzero_data",
- FT_UINT24, BASE_DEC, NULL, 0x3ffc00,
+ FT_UINT24, BASE_DEC, NULL, 0x7ffc00,
NULL, HFILL }
},
{ &hf_btmesh_sego,
@@ -1248,11 +1624,108 @@ proto_register_btmesh(void)
FT_UINT24, BASE_DEC, NULL, 0x00001f,
NULL, HFILL }
},
+ { &hf_btmesh_seg_rfu,
+ { "RFU", "btmesh.seg.rfu",
+ FT_UINT24, BASE_DEC, NULL, 0x800000,
+ NULL, HFILL }
+ },
{ &hf_btmesh_segment,
{ "Segment", "btmesh.segment",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
+ //Access Message Reassembly
+ { &hf_btmesh_segmented_access_fragments,
+ { "Reassembled Segmented Access Message Fragments", "btmesh.segmented.access.fragments",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ "Segmented Access Message Fragments", HFILL }
+ },
+ { &hf_btmesh_segmented_access_fragment,
+ { "Segmented Access Message Fragment", "btmesh.segmented.access.fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_segmented_access_fragment_overlap,
+ { "Fragment overlap", "btmesh.segmented.access.fragment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment overlaps with other fragments", HFILL }
+ },
+ { &hf_btmesh_segmented_access_fragment_overlap_conflict,
+ { "Conflicting data in fragment overlap", "btmesh.segmented.access.fragment.overlap.conflict",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping fragments contained conflicting data", HFILL }
+ },
+ { &hf_btmesh_segmented_access_fragment_multiple_tails,
+ { "Multiple tail fragments found", "btmesh.segmented.access.fragment.multipletails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when defragmenting the packet", HFILL }
+ },
+ { &hf_btmesh_segmented_access_fragment_too_long_fragment,
+ { "Fragment too long", "btmesh.segmented.access.fragment.toolongfragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment contained data past end of packet", HFILL }
+ },
+ { &hf_btmesh_segmented_access_fragment_error,
+ { "Defragmentation error", "btmesh.segmented.access.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Defragmentation error due to illegal fragments", HFILL }
+ },
+ { &hf_btmesh_segmented_access_fragment_count,
+ { "Fragment count", "btmesh.segmented.access.fragment.count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_segmented_access_reassembled_length,
+ { "Reassembled Segmented Access Message length", "btmesh.segmented.access.reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "The total length of the reassembled payload", HFILL }
+ },
+ //Control Message Reassembly
+ { &hf_btmesh_segmented_control_fragments,
+ { "Reassembled Segmented Control Message Fragments", "btmesh.segmented.control.fragments",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ "Segmented Access Message Fragments", HFILL }
+ },
+ { &hf_btmesh_segmented_control_fragment,
+ { "Segmented Control Message Fragment", "btmesh.segmented.control.fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_segmented_control_fragment_overlap,
+ { "Fragment overlap", "btmesh.segmented.control.fragment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment overlaps with other fragments", HFILL }
+ },
+ { &hf_btmesh_segmented_control_fragment_overlap_conflict,
+ { "Conflicting data in fragment overlap", "btmesh.segmented.control.fragment.overlap.conflict",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping fragments contained conflicting data", HFILL }
+ },
+ { &hf_btmesh_segmented_control_fragment_multiple_tails,
+ { "Multiple tail fragments found", "btmesh.segmented.control.fragment.multipletails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when defragmenting the packet", HFILL }
+ },
+ { &hf_btmesh_segmented_control_fragment_too_long_fragment,
+ { "Fragment too long", "btmesh.segmented.control.fragment.toolongfragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment contained data past end of packet", HFILL }
+ },
+ { &hf_btmesh_segmented_control_fragment_error,
+ { "Defragmentation error", "btmesh.segmented.control.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Defragmentation error due to illegal fragments", HFILL }
+ },
+ { &hf_btmesh_segmented_control_fragment_count,
+ { "Fragment count", "btmesh.segmented.control.fragment.count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_btmesh_segmented_control_reassembled_length,
+ { "Reassembled Segmented Control Message length", "btmesh.segmented.control.reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "The total length of the reassembled payload", HFILL }
+ },
};
static gint *ett[] = {
@@ -1261,6 +1734,10 @@ proto_register_btmesh(void)
&ett_btmesh_transp_pdu,
&ett_btmesh_transp_ctrl_msg,
&ett_btmesh_upper_transp_acc_pdu,
+ &ett_btmesh_segmented_access_fragments,
+ &ett_btmesh_segmented_access_fragment,
+ &ett_btmesh_segmented_control_fragments,
+ &ett_btmesh_segmented_control_fragment,
};
static ei_register_info ei[] = {
@@ -1314,6 +1791,8 @@ proto_register_btmesh(void)
btmesh_uat);
register_dissector("btmesh.msg", dissect_btmesh_msg, proto_btmesh);
+
+ register_init_routine(&upper_transport_init_routine);
}
/*