diff options
author | Martin Kaiser <wireshark@kaiser.cx> | 2017-08-13 19:12:36 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2017-09-12 05:04:05 +0000 |
commit | 293df7cccbc3092a1cebf8ad9b7ed289f1a7decb (patch) | |
tree | c6dbd9f9067626e8ff61fd3215afdb418bf307ad /epan/dissectors/packet-iso14443.c | |
parent | 8c74580773e52b3de1b97c42cb425131f041b9cc (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.c | 101 |
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); |