aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-iso14443.c
diff options
context:
space:
mode:
authorMartin Kaiser <wireshark@kaiser.cx>2017-08-13 19:12:36 +0200
committerAnders Broman <a.broman58@gmail.com>2017-09-12 05:04:05 +0000
commit293df7cccbc3092a1cebf8ad9b7ed289f1a7decb (patch)
treec6dbd9f9067626e8ff61fd3215afdb418bf307ad /epan/dissectors/packet-iso14443.c
parent8c74580773e52b3de1b97c42cb425131f041b9cc (diff)
iso14443: reassemble APDUs from I-blocks
Extract the payload from I-blocks and support reassembly of APDUs that are encapsulated in I-blocks. ISO14443 assumes that the fragments arrive in order and no fragments are missing. For now, we pass the reassembled APDU to the data dissector. Change-Id: I526f6e6d699b2a1dfc4593536154bc9b58dea96e Reviewed-on: https://code.wireshark.org/review/23506 Reviewed-by: Martin Kaiser <wireshark@kaiser.cx> Petri-Dish: Martin Kaiser <wireshark@kaiser.cx> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-iso14443.c')
-rw-r--r--epan/dissectors/packet-iso14443.c101
1 files changed, 100 insertions, 1 deletions
diff --git a/epan/dissectors/packet-iso14443.c b/epan/dissectors/packet-iso14443.c
index 5f640d25db..cc58046a72 100644
--- a/epan/dissectors/packet-iso14443.c
+++ b/epan/dissectors/packet-iso14443.c
@@ -42,6 +42,7 @@
#include <epan/expert.h>
#include <epan/circuit.h>
#include <epan/tfs.h>
+#include <epan/reassemble.h>
#include <wiretap/wtap.h>
#include <epan/crc16-tvb.h>
@@ -182,6 +183,8 @@ static int ett_iso14443_attr_p2 = -1;
static int ett_iso14443_attr_p3 = -1;
static int ett_iso14443_pcb = -1;
static int ett_iso14443_inf = -1;
+static int ett_iso14443_frag = -1;
+static int ett_iso14443_frags = -1;
static int hf_iso14443_hdr_ver = -1;
static int hf_iso14443_event = -1;
@@ -276,6 +279,16 @@ static int hf_iso14443_s_blk_cmd = -1;
static int hf_iso14443_pwr_lvl_ind = -1;
static int hf_iso14443_wtxm = -1;
static int hf_iso14443_inf = -1;
+static int hf_iso14443_frags = -1;
+static int hf_iso14443_frag = -1;
+static int hf_iso14443_frag_overlap = -1;
+static int hf_iso14443_frag_overlap_conflicts = -1;
+static int hf_iso14443_frag_multiple_tails = -1;
+static int hf_iso14443_frag_too_long_frag = -1;
+static int hf_iso14443_frag_err = -1;
+static int hf_iso14443_frag_cnt = -1;
+static int hf_iso14443_reass_in = -1;
+static int hf_iso14443_reass_len = -1;
static int hf_iso14443_crc = -1;
static int hf_iso14443_crc_status = -1;
@@ -305,6 +318,27 @@ static expert_field ei_iso14443_unknown_cmd = EI_INIT;
static expert_field ei_iso14443_wrong_crc = EI_INIT;
static expert_field ei_iso14443_uid_inval_size = EI_INIT;
+static reassembly_table i_block_reassembly_table;
+
+static const fragment_items i_block_frag_items _U_ = {
+ &ett_iso14443_frag,
+ &ett_iso14443_frags,
+
+ &hf_iso14443_frags,
+ &hf_iso14443_frag,
+ &hf_iso14443_frag_overlap,
+ &hf_iso14443_frag_overlap_conflicts,
+ &hf_iso14443_frag_multiple_tails,
+ &hf_iso14443_frag_too_long_frag,
+ &hf_iso14443_frag_err,
+ &hf_iso14443_frag_cnt,
+
+ &hf_iso14443_reass_in,
+ &hf_iso14443_reass_len,
+ NULL,
+ "I-block fragments"
+};
+
static int
dissect_iso14443_cmd_type_wupa(tvbuff_t *tvb, packet_info *pinfo,
@@ -1021,6 +1055,9 @@ dissect_iso14443_cmd_type_block(tvbuff_t *tvb, packet_info *pinfo,
}
if (inf_len > 0) {
+ fragment_head *frag_msg;
+ tvbuff_t *payload_tvb;
+
inf_ti = proto_tree_add_item(tree, hf_iso14443_inf,
tvb, offset, inf_len, ENC_NA);
if (block_type == S_BLOCK_TYPE) {
@@ -1034,6 +1071,21 @@ dissect_iso14443_cmd_type_block(tvbuff_t *tvb, packet_info *pinfo,
tvb, offset, 1, ENC_BIG_ENDIAN);
}
}
+
+ if (block_type == I_BLOCK_TYPE) {
+ frag_msg = fragment_add_seq_next(&i_block_reassembly_table,
+ tvb, offset, pinfo, 0, NULL, inf_len, (pcb & 0x10) ? 1 : 0);
+
+ payload_tvb = process_reassembled_data(tvb, offset, pinfo,
+ "Reassembled APDU", frag_msg,
+ &i_block_frag_items, NULL, tree);
+
+ if (payload_tvb) {
+ /* XXX - forward to the actual upper layer protocol */
+ call_data_dissector(payload_tvb, pinfo, tree);
+ }
+ }
+
offset += inf_len;
}
@@ -1710,6 +1762,48 @@ proto_register_iso14443(void)
{ "INF", "iso14443.inf",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
},
+ { &hf_iso14443_frags,
+ { "Tpdu fragments", "iso14443.tpdu_fragments",
+ FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_frag,
+ { "Tpdu fragment", "iso14443.tpdu_fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_frag_overlap,
+ { "Tpdu fragment overlap", "iso14443.tpdu_fragment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_frag_overlap_conflicts,
+ { "Tpdu fragment overlapping with conflicting data",
+ "iso14443.tpdu_fragment.overlap.conflicts",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_frag_multiple_tails,
+ { "Tpdu has multiple tail fragments",
+ "iso14443.tpdu_fragment.multiple_tails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_frag_too_long_frag,
+ { "Tpdu fragment too long", "iso14443.tpdu_fragment.too_long_fragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_frag_err,
+ { "Tpdu defragmentation error", "iso14443.tpdu_fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_frag_cnt,
+ { "Tpdu fragment count", "iso14443.tpdu_fragment.count",
+ FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_reass_in,
+ { "Tpdu reassembled in", "iso14443.tpdu_reassembled.in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_iso14443_reass_len,
+ { "Reassembled tpdu length", "iso14443.tpdu_reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
+ },
{ &hf_iso14443_crc,
{ "CRC", "iso14443.crc",
FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
@@ -1736,7 +1830,9 @@ proto_register_iso14443(void)
&ett_iso14443_attr_p2,
&ett_iso14443_attr_p3,
&ett_iso14443_pcb,
- &ett_iso14443_inf
+ &ett_iso14443_inf,
+ &ett_iso14443_frag,
+ &ett_iso14443_frags
};
static ei_register_info ei[] = {
@@ -1766,6 +1862,9 @@ proto_register_iso14443(void)
"iso14443.cmd_type", "ISO14443 Command Type",
proto_iso14443, FT_UINT8, BASE_DEC);
+ reassembly_table_register(&i_block_reassembly_table,
+ &addresses_reassembly_table_functions);
+
iso14443_handle =
register_dissector("iso14443", dissect_iso14443, proto_iso14443);