aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-iso14443.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-iso14443.c')
-rw-r--r--epan/dissectors/packet-iso14443.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/epan/dissectors/packet-iso14443.c b/epan/dissectors/packet-iso14443.c
index b6b463dc17..5f640d25db 100644
--- a/epan/dissectors/packet-iso14443.c
+++ b/epan/dissectors/packet-iso14443.c
@@ -1113,15 +1113,33 @@ iso14443_block_pcb(guint8 byte)
static iso14443_transaction_t *
-iso14443_get_transaction(packet_info *pinfo, proto_tree *tree)
+iso14443_get_transaction(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *it;
+ wmem_tree_key_t key[3];
iso14443_transaction_t *iso14443_trans = NULL;
-
- if (pinfo->p2p_dir == P2P_DIR_SENT) {
+ /* Is the current message a Waiting-Time-Extension request or response? */
+ gboolean wtx = (tvb_get_guint8(tvb, 0) & 0xF7) == 0xF2;
+
+ /* When going backwards from the current message, we want to link wtx
+ messages only to other wtx messages (and non-wtx messages to non-wtx,
+ respectively). For this to work, the wtx flag must be the first
+ component of the key. */
+ key[0].length = 1;
+ key[0].key = &wtx;
+ key[1].length = 1;
+ key[1].key = &pinfo->num;
+ key[2].length = 0;
+ key[2].key = NULL;
+
+ /* Is this a request message? WTX requests are sent by the PICC, all
+ other requests are sent by the PCD. */
+ if (((pinfo->p2p_dir == P2P_DIR_SENT) && !wtx) ||
+ ((pinfo->p2p_dir == P2P_DIR_RECV) && wtx)) {
if (PINFO_FD_VISITED(pinfo)) {
- iso14443_trans = (iso14443_transaction_t *)wmem_tree_lookup32(
- transactions, pinfo->num);
+ iso14443_trans =
+ (iso14443_transaction_t *)wmem_tree_lookup32_array(
+ transactions, key);
if (iso14443_trans && iso14443_trans->rqst_frame==pinfo->num &&
iso14443_trans->resp_frame!=0) {
it = proto_tree_add_uint(tree, hf_iso14443_resp_in,
@@ -1130,17 +1148,17 @@ iso14443_get_transaction(packet_info *pinfo, proto_tree *tree)
}
}
else {
- iso14443_trans = wmem_new(wmem_file_scope(), iso14443_transaction_t);
+ iso14443_trans =
+ wmem_new(wmem_file_scope(), iso14443_transaction_t);
iso14443_trans->rqst_frame = pinfo->num;
iso14443_trans->resp_frame = 0;
- /* iso14443_trans->ctrl = ctrl; */
- wmem_tree_insert32(transactions,
- iso14443_trans->rqst_frame, (void *)iso14443_trans);
+ wmem_tree_insert32_array(transactions, key, (void *)iso14443_trans);
}
}
- else if (pinfo->p2p_dir == P2P_DIR_RECV) {
- iso14443_trans = (iso14443_transaction_t *)wmem_tree_lookup32_le(
- transactions, pinfo->num);
+ else if (((pinfo->p2p_dir == P2P_DIR_SENT) && wtx) ||
+ ((pinfo->p2p_dir == P2P_DIR_RECV) && !wtx)) {
+ iso14443_trans = (iso14443_transaction_t *)wmem_tree_lookup32_array_le(
+ transactions, key);
if (iso14443_trans && iso14443_trans->resp_frame==0) {
/* there's a pending request, this packet is the response */
iso14443_trans->resp_frame = pinfo->num;
@@ -1219,7 +1237,7 @@ dissect_iso14443_msg(tvbuff_t *tvb, packet_info *pinfo,
crc_dropped = TRUE;
}
- iso14443_trans = iso14443_get_transaction(pinfo, tree);
+ iso14443_trans = iso14443_get_transaction(tvb, pinfo, tree);
if (!iso14443_trans)
return -1;