ieee802154: Use ACK tracking to add generated addresses to ACKs

Change-Id: I86a0aae9409ab5f81a70560997c637f8f16718fa
Reviewed-on: https://code.wireshark.org/review/35754
Petri-Dish: Jim Young <jim.young.ws@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Kenneth Soerensen 2020-01-07 17:08:12 +01:00 committed by Anders Broman
parent e7a8c94aa7
commit 9e135f8748
2 changed files with 144 additions and 71 deletions

View File

@ -681,13 +681,17 @@ typedef struct _ieee802154_transaction_t {
guint32 ack_frame;
nstime_t rqst_time;
nstime_t ack_time;
gboolean rqst_dst_pan_present;
gboolean rqst_src_pan_present;
guint16 rqst_dst_pan;
guint16 rqst_src_pan;
} ieee802154_transaction_t;
static wmem_tree_t *transaction_unmatched_pdus;
static wmem_tree_t *transaction_matched_pdus;
static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, guint32 *key);
static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, guint32 *key);
static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, const ieee802154_packet *packet, guint32 *key);
static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, const ieee802154_packet *packet, guint32 *key);
/* Initialize Subtree Pointers */
static gint ett_ieee802154_nonask_phy = -1;
@ -1316,7 +1320,7 @@ static conversation_t *_find_or_create_conversation(packet_info *pinfo, const ad
}
/* ======================================================================= */
static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, guint32 *key)
static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, const ieee802154_packet *packet, guint32 *key)
{
ieee802154_transaction_t *ieee802154_trans;
wmem_tree_key_t ieee802154_key[3];
@ -1335,6 +1339,14 @@ static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tre
ieee802154_trans = wmem_new(wmem_file_scope(), ieee802154_transaction_t);
copy_address_wmem(wmem_file_scope(), &ieee802154_trans->rqst_src_addr, src_addr);
copy_address_wmem(wmem_file_scope(), &ieee802154_trans->rqst_dst_addr, dst_addr);
if (packet->dst_pan_present) {
ieee802154_trans->rqst_dst_pan_present = TRUE;
ieee802154_trans->rqst_dst_pan = packet->dst_pan;
}
if (packet->src_pan_present) {
ieee802154_trans->rqst_src_pan_present = TRUE;
ieee802154_trans->rqst_src_pan = packet->src_pan;
}
ieee802154_trans->rqst_frame = pinfo->num;
ieee802154_trans->ack_frame = 0;
ieee802154_trans->rqst_time = pinfo->abs_ts;
@ -1375,7 +1387,7 @@ static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tre
return ieee802154_trans;
} /* transaction_start() */
static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, guint32 *key)
static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const address *src_addr, const address *dst_addr, const ieee802154_packet *packet, guint32 *key)
{
ieee802154_transaction_t *ieee802154_trans = NULL;
wmem_tree_key_t ieee802154_key[3];
@ -1446,6 +1458,67 @@ static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree
}
}
if (packet->dst_pan_present == FALSE) {
if (ieee802154_trans->rqst_src_pan_present) {
it = proto_tree_add_uint(tree, hf_ieee802154_dst_panID, NULL, 0, 0, ieee802154_trans->rqst_src_pan);
proto_item_set_generated(it);
}
else if (ieee802154_trans->rqst_dst_pan_present) {
it = proto_tree_add_uint(tree, hf_ieee802154_dst_panID, NULL, 0, 0, ieee802154_trans->rqst_dst_pan);
proto_item_set_generated(it);
}
}
if ((packet->src_pan_present == FALSE) && (ieee802154_trans->rqst_src_pan_present) && (ieee802154_trans->rqst_dst_pan_present)) {
it = proto_tree_add_uint(tree, hf_ieee802154_src_panID, NULL, 0, 0, ieee802154_trans->rqst_dst_pan);
proto_item_set_generated(it);
}
if (dst_addr->type == AT_NONE) {
if (ieee802154_trans->rqst_src_addr.type == ieee802_15_4_short_address_type) {
guint16 ieee_802_15_4_short_addr = pletoh16(ieee802154_trans->rqst_src_addr.data);
it = proto_tree_add_uint(tree, hf_ieee802154_dst16, NULL, 0, 0, ieee_802_15_4_short_addr);
proto_item_set_generated(it);
it = proto_tree_add_uint(tree, hf_ieee802154_addr16, NULL, 0, 0, ieee_802_15_4_short_addr);
proto_item_set_hidden(it);
proto_item_set_generated(it);
}
else if (ieee802154_trans->rqst_src_addr.type == AT_EUI64) {
guint64 ieee_802_15_4_ext_addr = pntoh64(ieee802154_trans->rqst_src_addr.data);
it = proto_tree_add_eui64(tree, hf_ieee802154_dst64, NULL, 0, 0, ieee_802_15_4_ext_addr);
proto_item_set_generated(it);
it = proto_tree_add_eui64(tree, hf_ieee802154_addr64, NULL, 0, 0, ieee_802_15_4_ext_addr);
proto_item_set_hidden(it);
proto_item_set_generated(it);
}
}
if (src_addr->type == AT_NONE) {
if (ieee802154_trans->rqst_dst_addr.type == ieee802_15_4_short_address_type) {
guint16 ieee_802_15_4_short_addr = pletoh16(ieee802154_trans->rqst_dst_addr.data);
it = proto_tree_add_uint(tree, hf_ieee802154_src16, NULL, 0, 0, ieee_802_15_4_short_addr);
proto_item_set_generated(it);
it = proto_tree_add_uint(tree, hf_ieee802154_addr16, NULL, 0, 0, ieee_802_15_4_short_addr);
proto_item_set_hidden(it);
proto_item_set_generated(it);
}
else if (ieee802154_trans->rqst_dst_addr.type == AT_EUI64) {
guint64 ieee_802_15_4_ext_addr = pntoh64(ieee802154_trans->rqst_dst_addr.data);
it = proto_tree_add_eui64(tree, hf_ieee802154_src64, NULL, 0, 0, ieee_802_15_4_ext_addr);
proto_item_set_generated(it);
it = proto_tree_add_eui64(tree, hf_ieee802154_addr64, NULL, 0, 0, ieee_802_15_4_ext_addr);
proto_item_set_hidden(it);
proto_item_set_generated(it);
}
}
/* Print state tracking in the tree */
it = proto_tree_add_uint(tree, hf_ieee802154_ack_to, NULL, 0, 0, ieee802154_trans->rqst_frame);
proto_item_set_generated(it);
@ -2148,6 +2221,26 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
return;
}
if ((packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE)) {
_find_or_create_conversation(pinfo, &pinfo->dl_src, &pinfo->dl_dst);
}
if (ieee802154_ack_tracking && fcs_ok && (packet->ack_request || packet->frame_type == IEEE802154_FCF_ACK)) {
guint32 key[2] = {0};
key[0] = packet->seqno;
if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
key[1] = pinfo->rec->rec_header.packet_header.interface_id;
}
if (packet->ack_request) {
transaction_start(pinfo, ieee802154_tree, &pinfo->dl_src, &pinfo->dl_dst, packet, key);
}
else {
transaction_end(pinfo, ieee802154_tree, &pinfo->dl_src, &pinfo->dl_dst, packet, key);
}
}
tvbuff_t* payload = ieee802154_decrypt_payload(no_fcs_tvb, mhr_len, pinfo, ieee802154_tree, packet);
if (payload) {
guint pie_size = ieee802154_dissect_payload_ies(payload, pinfo, ieee802154_tree, packet);
@ -2187,26 +2280,6 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
}
}
if ((packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE)) {
_find_or_create_conversation(pinfo, &pinfo->dl_src, &pinfo->dl_dst);
}
if (ieee802154_ack_tracking && fcs_ok && (packet->ack_request || packet->frame_type == IEEE802154_FCF_ACK)) {
guint32 key[2] = {0};
key[0] = packet->seqno;
if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
key[1] = pinfo->rec->rec_header.packet_header.interface_id;
}
if (packet->ack_request) {
transaction_start(pinfo, ieee802154_tree, &pinfo->dl_src, &pinfo->dl_dst, key);
}
else {
transaction_end(pinfo, ieee802154_tree, &pinfo->dl_src, &pinfo->dl_dst, key);
}
}
tap_queue_packet(ieee802154_tap, pinfo, NULL);
}
@ -2218,8 +2291,6 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
proto_item *hidden_item;
proto_item *ti;
guint offset = 0;
gboolean dstPanPresent = FALSE;
gboolean srcPanPresent = FALSE;
ieee802154_packet *packet = wmem_new0(wmem_packet_scope(), ieee802154_packet);
ieee802154_short_addr addr16;
ieee802154_hints_t *ieee_hints;
@ -2304,10 +2375,10 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
}
/* The source PAN ID is always omitted in multipurpose frames */
srcPanPresent = FALSE;
packet->src_pan_present = FALSE;
if (packet->pan_id_present) {
dstPanPresent = TRUE;
packet->dst_pan_present = TRUE;
}
}
else if (packet->version == IEEE802154_VERSION_RESERVED) {
@ -2321,12 +2392,12 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* if both destination and source */
(packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) { /* addressing information is present */
if (packet->pan_id_compression == 1) { /* PAN IDs are identical */
dstPanPresent = TRUE;
srcPanPresent = FALSE; /* source PAN ID is omitted */
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE; /* source PAN ID is omitted */
}
else { /* PAN IDs are different, both shall be included in the frame */
dstPanPresent = TRUE;
srcPanPresent = TRUE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = TRUE;
}
}
else {
@ -2338,18 +2409,18 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
/* only either the destination or the source addressing information is present */
if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) { /* Not Present */
dstPanPresent = TRUE;
srcPanPresent = FALSE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE;
}
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) { /* Present */
dstPanPresent = FALSE;
srcPanPresent = TRUE;
packet->dst_pan_present = FALSE;
packet->src_pan_present = TRUE;
}
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) { /* Not Present */
dstPanPresent = FALSE;
srcPanPresent = FALSE;
packet->dst_pan_present = FALSE;
packet->src_pan_present = FALSE;
}
else {
expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_addressing);
@ -2393,99 +2464,99 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->pan_id_compression == 0)) {
dstPanPresent = FALSE;
srcPanPresent = FALSE;
packet->dst_pan_present = FALSE;
packet->src_pan_present = FALSE;
}
/* Row 2 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->pan_id_compression == 1)) {
dstPanPresent = TRUE;
srcPanPresent = FALSE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE;
}
/* Row 3 */
else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->pan_id_compression == 0)) {
dstPanPresent = TRUE;
srcPanPresent = FALSE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE;
}
/* Row 4 */
else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->pan_id_compression == 1)) {
dstPanPresent = FALSE;
srcPanPresent = FALSE;
packet->dst_pan_present = FALSE;
packet->src_pan_present = FALSE;
}
/* Row 5 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
(packet->pan_id_compression == 0)) {
dstPanPresent = FALSE;
srcPanPresent = TRUE;
packet->dst_pan_present = FALSE;
packet->src_pan_present = TRUE;
}
/* Row 6 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */
(packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */
(packet->pan_id_compression == 1)) {
dstPanPresent = FALSE;
srcPanPresent = FALSE;
packet->dst_pan_present = FALSE;
packet->src_pan_present = FALSE;
}
/* Row 7 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->pan_id_compression == 0)) {
dstPanPresent = TRUE;
srcPanPresent = FALSE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE;
}
/* Row 8 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->pan_id_compression == 1)) {
dstPanPresent = FALSE;
srcPanPresent = FALSE;
packet->dst_pan_present = FALSE;
packet->src_pan_present = FALSE;
}
/* Row 9 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->pan_id_compression == 0)) {
dstPanPresent = TRUE;
srcPanPresent = (ieee802154e_compatibility ? FALSE : TRUE);
packet->dst_pan_present = TRUE;
packet->src_pan_present = (ieee802154e_compatibility ? FALSE : TRUE);
}
/* Row 10 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->pan_id_compression == 0)) {
dstPanPresent = TRUE;
srcPanPresent = (ieee802154e_compatibility ? FALSE : TRUE);
packet->dst_pan_present = TRUE;
packet->src_pan_present = (ieee802154e_compatibility ? FALSE : TRUE);
}
/* Row 11 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->pan_id_compression == 0)) {
dstPanPresent = TRUE;
srcPanPresent = (ieee802154e_compatibility ? FALSE : TRUE);
packet->dst_pan_present = TRUE;
packet->src_pan_present = (ieee802154e_compatibility ? FALSE : TRUE);
}
/* Row 12 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->pan_id_compression == 1)) {
dstPanPresent = TRUE;
srcPanPresent = FALSE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE;
}
/* Row 13 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->pan_id_compression == 1)) {
dstPanPresent = TRUE;
srcPanPresent = FALSE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE;
}
/* Row 14 */
else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */
(packet->pan_id_compression == 1)) {
dstPanPresent = TRUE;
srcPanPresent = FALSE;
packet->dst_pan_present = TRUE;
packet->src_pan_present = FALSE;
}
else {
expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_panid_compression2);
@ -2493,8 +2564,8 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
}
}
else { /* Frame Type is neither Beacon, Data, Ack, nor Command: PAN ID Compression is not used */
dstPanPresent = FALSE; /* no PAN ID will */
srcPanPresent = FALSE; /* be present */
packet->dst_pan_present = FALSE; /* no PAN ID will */
packet->src_pan_present = FALSE; /* be present */
}
}
else {
@ -2508,7 +2579,7 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
*/
/* Destination PAN Id */
if (dstPanPresent) {
if (packet->dst_pan_present) {
packet->dst_pan = tvb_get_letohs(tvb, offset);
if (ieee802154_tree) {
proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_panID, tvb, offset, 2, packet->dst_pan);
@ -2569,13 +2640,13 @@ ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
}
/* Source PAN Id */
if (srcPanPresent) {
if (packet->src_pan_present) {
packet->src_pan = tvb_get_letohs(tvb, offset);
proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src_panID, tvb, offset, 2, packet->src_pan);
offset += 2;
}
else {
if (dstPanPresent) {
if (packet->dst_pan_present) {
packet->src_pan = packet->dst_pan;
}
else {

View File

@ -410,6 +410,8 @@ typedef struct {
/* Determined during processing of Header IE*/
gboolean payload_ie_present;
/* Addressing Info. */
gboolean dst_pan_present;
gboolean src_pan_present;
guint16 dst_pan;
guint16 src_pan;
guint16 dst16;