Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-iso14443.c
blob0cdf0eb0df883b2a415bd31f6aa688f2fe83ed5e
1 /* packet-iso14443.c
2 * Routines for ISO14443 dissection
3 * Copyright 2015-2016, Martin Kaiser <martin@kaiser.cx>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 /* ISO14443 is a set of standards describing the communication between a
13 * card reader and a contactless smartcard.
15 * This dissector handles the initialization messages defined in
16 * ISO14443-3 and the activation and protocol messages from ISO14443-4
18 * The standards are available as "final committee drafts" from
19 * http://wg8.de/wg8n1496_17n3613_Ballot_FCD14443-3.pdf
20 * http://wg8.de/wg8n1344_17n3269_Ballot_FCD14443-4.pdf
22 * The pcap input format for this dissector is documented at
23 * http://www.kaiser.cx/pcap-iso14443.html.
27 #include "config.h"
28 #include <epan/packet.h>
29 #include <epan/expert.h>
30 #include <epan/decode_as.h>
31 #include <epan/conversation.h>
32 #include <epan/tfs.h>
33 #include <epan/reassemble.h>
34 #include <epan/crc16-tvb.h>
36 #include <wiretap/wtap.h>
38 #include <wsutil/pow2.h>
40 /* Proximity Integrated Circuit Card, i.e. the smartcard */
41 #define ADDR_PICC "PICC"
42 /* Proximity Coupling Device, i.e. the card reader */
43 #define ADDR_PCD "PCD"
45 /* event byte in the PCAP ISO14443 pseudo-header */
46 #define ISO14443_EVT_DATA_PICC_TO_PCD 0xFF
47 #define ISO14443_EVT_DATA_PCD_TO_PICC 0xFE
48 #define ISO14443_EVT_FIELD_OFF 0xFD
49 #define ISO14443_EVT_FIELD_ON 0xFC
50 #define ISO14443_EVT_DATA_PICC_TO_PCD_CRC_DROPPED 0xFB
51 #define ISO14443_EVT_DATA_PCD_TO_PICC_CRC_DROPPED 0xFA
53 static const value_string iso14443_event[] = {
54 { ISO14443_EVT_DATA_PICC_TO_PCD, "Data transfer PICC -> PCD" },
55 { ISO14443_EVT_DATA_PCD_TO_PICC, "Data transfer PCD -> PICC" },
56 { ISO14443_EVT_FIELD_ON, "Field on" },
57 { ISO14443_EVT_FIELD_OFF, "Field off" },
58 { ISO14443_EVT_DATA_PICC_TO_PCD_CRC_DROPPED,
59 "Data transfer PICC -> PCD (CRC bytes were dropped)" },
60 { ISO14443_EVT_DATA_PCD_TO_PICC_CRC_DROPPED,
61 "Data transfer PCD -> PICC (CRC bytes were dropped)" },
62 { 0, NULL }
65 #define IS_DATA_TRANSFER(e) \
66 ((e)==ISO14443_EVT_DATA_PICC_TO_PCD || \
67 (e)==ISO14443_EVT_DATA_PCD_TO_PICC || \
68 (e)==ISO14443_EVT_DATA_PICC_TO_PCD_CRC_DROPPED || \
69 (e)==ISO14443_EVT_DATA_PCD_TO_PICC_CRC_DROPPED)
71 typedef enum _iso14443_cmd_t {
72 CMD_TYPE_WUPA, /* REQA, WUPA or ATQA */
73 CMD_TYPE_WUPB, /* REQB, WUPB or ATQB */
74 CMD_TYPE_HLTA,
75 CMD_TYPE_UID, /* anticollision or selection commands
76 and their answers */
77 CMD_TYPE_ATS, /* RATS or ATS */
78 CMD_TYPE_ATTRIB, /* Attrib or the answer to Attrib */
79 CMD_TYPE_BLOCK, /* I-, R- or S-blocks */
80 CMD_TYPE_UNKNOWN
81 } iso14443_cmd_t;
83 static wmem_tree_t *transactions;
85 typedef struct _iso14443_transaction_t {
86 uint32_t rqst_frame;
87 uint32_t resp_frame;
88 iso14443_cmd_t cmd;
89 } iso14443_transaction_t;
91 typedef enum _iso14443_type_t {
92 ISO14443_A,
93 ISO14443_B,
94 ISO14443_UNKNOWN
95 } iso14443_type_t;
97 static const value_string iso14443_short_frame[] = {
98 { 0x26 , "REQA" },
99 { 0x52 , "WUPA" },
100 { 0, NULL }
103 /* the bit rate definitions in the attrib message */
104 #define BITRATE_106 0x00
105 #define BITRATE_212 0x01
106 #define BITRATE_424 0x02
107 #define BITRATE_847 0x03
109 static const value_string iso14443_bitrates[] = {
110 { BITRATE_106, "106 kbit/s" },
111 { BITRATE_212, "212 kbit/s" },
112 { BITRATE_424, "424 kbit/s" },
113 { BITRATE_847, "827 kbit/s" },
114 { 0, NULL }
117 /* convert a length code into the length it encodes
118 code_to_len[x] is the length encoded by x
119 this conversion is used for type A's FSCI and FSDI and for type B's
120 maximum frame size */
121 static const uint16_t code_to_len[] = {
122 16, 24, 32, 40, 48, 64, 96, 128, 256, 512, 1024, 2048, 4096
124 #define LEN_CODE_MAX array_length(code_to_len)
126 /* the bits in the ATS' TO byte indicating which other bytes are transmitted */
127 #define HAVE_TC1 0x40
128 #define HAVE_TB1 0x20
129 #define HAVE_TA1 0x10
131 #define I_BLOCK_TYPE 0x00
132 #define R_BLOCK_TYPE 0x02
133 #define S_BLOCK_TYPE 0x03
134 static const value_string iso14443_block_type[] = {
135 { I_BLOCK_TYPE , "I-block" },
136 { R_BLOCK_TYPE , "R-block" },
137 { S_BLOCK_TYPE , "S-block" },
138 { 0, NULL }
141 #define S_CMD_DESELECT 0x00
142 #define S_CMD_WTX 0x03
143 #define S_CMD_NONE 0xFF
145 static const value_string iso14443_s_block_cmd[] = {
146 { S_CMD_DESELECT , "Deselect" },
147 { S_CMD_WTX , "WTX" },
148 { 0, NULL }
151 static const true_false_string tfs_wupb_reqb = { "WUPB", "REQB" };
152 static const true_false_string tfs_compliant_not_compliant = { "Compliant", "Not compliant" };
153 static const true_false_string tfs_incomplete_complete = { "Incomplete", "Complete" };
154 static const true_false_string tfs_iso_propr = { "As defined in ISO14443-3", "Proprietary" };
155 static const true_false_string tfs_not_required_required = { "Not required", "Required" };
156 static const true_false_string tfs_nak_ack = { "NAK", "ACK" };
158 #define CT_BYTE 0x88
160 #define CRC_LEN 2
162 /* we'll only ever have a single circuit,
163 only one card can be active at a time */
164 #define ISO14443_CIRCUIT_ID 0
166 void proto_register_iso14443(void);
167 void proto_reg_handoff_iso14443(void);
169 static int proto_iso14443;
171 static dissector_handle_t iso14443_handle;
173 static dissector_table_t iso14443_cmd_type_table;
175 static dissector_table_t iso14443_subdissector_table;
177 static int ett_iso14443;
178 static int ett_iso14443_hdr;
179 static int ett_iso14443_msg;
180 static int ett_iso14443_app_data;
181 static int ett_iso14443_prot_inf;
182 static int ett_iso14443_bit_rate;
183 static int ett_iso14443_prot_type;
184 static int ett_iso14443_ats_t0;
185 static int ett_iso14443_ats_ta1;
186 static int ett_iso14443_ats_tb1;
187 static int ett_iso14443_ats_tc1;
188 static int ett_iso14443_attr_p1;
189 static int ett_iso14443_attr_p2;
190 static int ett_iso14443_attr_p3;
191 static int ett_iso14443_attr_p4;
192 static int ett_iso14443_pcb;
193 static int ett_iso14443_inf;
194 static int ett_iso14443_frag;
195 static int ett_iso14443_frags;
197 static int hf_iso14443_hdr_ver;
198 static int hf_iso14443_event;
199 static int hf_iso14443_len_field;
200 static int hf_iso14443_resp_to;
201 static int hf_iso14443_resp_in;
202 static int hf_iso14443_short_frame;
203 static int hf_iso14443_atqa_rfu1;
204 static int hf_iso14443_atqa_rfu2;
205 static int hf_iso14443_propr_coding;
206 static int hf_iso14443_uid_bits;
207 static int hf_iso14443_uid_size;
208 static int hf_iso14443_max_frame_size;
209 static int hf_iso14443_bit_frame_anticoll;
210 static int hf_iso14443_apf;
211 static int hf_iso14443_afi;
212 static int hf_iso14443_ext_atqb;
213 /* if this is present but unset, we have a REQB */
214 static int hf_iso14443_wupb;
215 static int hf_iso14443_n;
216 static int hf_iso14443_atqb_start;
217 static int hf_iso14443_app_data;
218 static int hf_iso14443_num_afi_apps;
219 static int hf_iso14443_total_num_apps;
220 static int hf_iso14443_prot_inf;
221 static int hf_iso14443_bit_rate_cap;
222 static int hf_iso14443_same_bit_rate;
223 static int hf_iso14443_picc_pcd_847;
224 static int hf_iso14443_picc_pcd_424;
225 static int hf_iso14443_picc_pcd_212;
226 static int hf_iso14443_pcd_picc_847;
227 static int hf_iso14443_pcd_picc_424;
228 static int hf_iso14443_pcd_picc_212;
229 static int hf_iso14443_max_frame_size_code;
230 static int hf_iso14443_prot_type;
231 static int hf_iso14443_min_tr2;
232 static int hf_iso14443_4_compl_atqb;
233 static int hf_iso14443_fwi;
234 static int hf_iso14443_sfgi;
235 static int hf_iso14443_adc;
236 static int hf_iso14443_nad_supported;
237 static int hf_iso14443_cid_supported;
238 static int hf_iso14443_hlta;
239 static int hf_iso14443_sel;
240 static int hf_iso14443_nvb;
241 static int hf_iso14443_4_compl_sak;
242 static int hf_iso14443_uid_complete;
243 static int hf_iso14443_ct;
244 static int hf_iso14443_uid_cln;
245 static int hf_iso14443_bcc;
246 static int hf_iso14443_rats_start;
247 static int hf_iso14443_fsdi;
248 static int hf_iso14443_fsd;
249 static int hf_iso14443_cid;
250 static int hf_iso14443_tl;
251 static int hf_iso14443_t0;
252 static int hf_iso14443_tc1_transmitted;
253 static int hf_iso14443_tb1_transmitted;
254 static int hf_iso14443_ta1_transmitted;
255 static int hf_iso14443_fsci;
256 static int hf_iso14443_fsc;
257 static int hf_iso14443_tc1;
258 static int hf_iso14443_tb1;
259 static int hf_iso14443_ta1;
260 static int hf_iso14443_same_d;
261 static int hf_iso14443_ds8;
262 static int hf_iso14443_ds4;
263 static int hf_iso14443_ds2;
264 static int hf_iso14443_dr8;
265 static int hf_iso14443_dr4;
266 static int hf_iso14443_dr2;
267 static int hf_iso14443_hist_bytes;
268 static int hf_iso14443_attrib_start;
269 static int hf_iso14443_pupi;
270 static int hf_iso14443_param1;
271 static int hf_iso14443_min_tr0;
272 static int hf_iso14443_min_tr1;
273 static int hf_iso14443_eof;
274 static int hf_iso14443_sof;
275 static int hf_iso14443_param2;
276 static int hf_iso14443_bitrate_picc_pcd;
277 static int hf_iso14443_bitrate_pcd_picc;
278 static int hf_iso14443_param3;
279 static int hf_iso14443_param4;
280 static int hf_iso14443_mbli;
281 static int hf_iso14443_pcb;
282 static int hf_iso14443_block_type;
283 static int hf_iso14443_i_blk_chaining;
284 static int hf_iso14443_cid_following;
285 static int hf_iso14443_nad_following;
286 static int hf_iso14443_nak;
287 static int hf_iso14443_blk_num;
288 static int hf_iso14443_s_blk_cmd;
289 static int hf_iso14443_pwr_lvl_ind;
290 static int hf_iso14443_wtxm;
291 static int hf_iso14443_inf;
292 static int hf_iso14443_frags;
293 static int hf_iso14443_frag;
294 static int hf_iso14443_frag_overlap;
295 static int hf_iso14443_frag_overlap_conflicts;
296 static int hf_iso14443_frag_multiple_tails;
297 static int hf_iso14443_frag_too_long_frag;
298 static int hf_iso14443_frag_err;
299 static int hf_iso14443_frag_cnt;
300 static int hf_iso14443_reass_in;
301 static int hf_iso14443_reass_len;
302 static int hf_iso14443_crc;
303 static int hf_iso14443_crc_status;
305 static int * const bit_rate_fields[] = {
306 &hf_iso14443_same_bit_rate,
307 &hf_iso14443_picc_pcd_847,
308 &hf_iso14443_picc_pcd_424,
309 &hf_iso14443_picc_pcd_212,
310 &hf_iso14443_pcd_picc_847,
311 &hf_iso14443_pcd_picc_424,
312 &hf_iso14443_pcd_picc_212,
313 NULL
316 static int * const ats_ta1_fields[] = {
317 &hf_iso14443_same_d,
318 &hf_iso14443_ds8,
319 &hf_iso14443_ds4,
320 &hf_iso14443_ds2,
321 &hf_iso14443_dr8,
322 &hf_iso14443_dr4,
323 &hf_iso14443_dr2,
324 NULL
327 static expert_field ei_iso14443_unknown_cmd;
328 static expert_field ei_iso14443_wrong_crc;
329 static expert_field ei_iso14443_uid_inval_size;
331 static reassembly_table i_block_reassembly_table;
333 static const fragment_items i_block_frag_items = {
334 &ett_iso14443_frag,
335 &ett_iso14443_frags,
337 &hf_iso14443_frags,
338 &hf_iso14443_frag,
339 &hf_iso14443_frag_overlap,
340 &hf_iso14443_frag_overlap_conflicts,
341 &hf_iso14443_frag_multiple_tails,
342 &hf_iso14443_frag_too_long_frag,
343 &hf_iso14443_frag_err,
344 &hf_iso14443_frag_cnt,
346 &hf_iso14443_reass_in,
347 &hf_iso14443_reass_len,
348 NULL,
349 "I-block fragments"
353 static int
354 dissect_iso14443_cmd_type_wupa(tvbuff_t *tvb, packet_info *pinfo,
355 proto_tree *tree, void *data _U_)
357 proto_item *ti = proto_tree_get_parent(tree);
358 int offset = 0;
359 uint8_t uid_bits, uid_size = 0;
361 if (pinfo->p2p_dir == P2P_DIR_SENT) {
362 const char *sf_str;
363 sf_str = try_val_to_str(
364 tvb_get_uint8(tvb, 0), iso14443_short_frame);
365 proto_tree_add_item(tree, hf_iso14443_short_frame,
366 tvb, offset, 1, ENC_BIG_ENDIAN);
367 offset++;
368 if (sf_str) {
369 proto_item_append_text(ti, ": %s", sf_str);
370 col_set_str(pinfo->cinfo, COL_INFO, sf_str);
373 else if (pinfo->p2p_dir == P2P_DIR_RECV) {
374 uint16_t atqa;
375 proto_item *pi_uid;
377 atqa = tvb_get_letohs(tvb, offset);
378 col_set_str(pinfo->cinfo, COL_INFO, "ATQA");
379 proto_item_append_text(ti, ": ATQA 0x%04x", atqa);
381 proto_tree_add_item(tree, hf_iso14443_atqa_rfu1,
382 tvb, offset, 2, ENC_LITTLE_ENDIAN);
383 proto_tree_add_item(tree, hf_iso14443_propr_coding,
384 tvb, offset, 2, ENC_LITTLE_ENDIAN);
386 uid_bits = (atqa & 0xC0) >> 6;
387 if (uid_bits == 0x00)
388 uid_size = 4;
389 else if (uid_bits == 0x01)
390 uid_size = 7;
391 else if (uid_bits == 0x02)
392 uid_size = 10;
394 pi_uid = proto_tree_add_item(tree, hf_iso14443_uid_bits,
395 tvb, offset, 2, ENC_LITTLE_ENDIAN);
396 if (uid_size != 0) {
397 proto_item *pi_uid_size;
398 pi_uid_size = proto_tree_add_uint(tree, hf_iso14443_uid_size,
399 tvb, offset+1, 1, uid_size);
400 proto_item_set_generated(pi_uid_size);
402 else {
403 expert_add_info(pinfo, pi_uid, &ei_iso14443_uid_inval_size);
406 proto_tree_add_item(tree, hf_iso14443_atqa_rfu2,
407 tvb, offset, 2, ENC_LITTLE_ENDIAN);
408 proto_tree_add_item(tree, hf_iso14443_bit_frame_anticoll,
409 tvb, offset, 2, ENC_LITTLE_ENDIAN);
411 offset += 2;
414 return offset;
418 static int dissect_iso14443_atqb(tvbuff_t *tvb, int offset,
419 packet_info *pinfo, proto_tree *tree, bool crc_dropped)
421 proto_item *ti = proto_tree_get_parent(tree);
422 proto_item *app_data_it, *prot_inf_it, *prot_type_it;
423 proto_tree *app_data_tree, *prot_inf_tree, *prot_type_tree;
424 int app_data_offset, rem_len;
425 bool nad_supported, cid_supported;
426 uint8_t max_frame_size_code, fwi;
427 proto_item *pi;
428 bool iso14443_adc;
429 uint8_t prot_inf_len = 0;
431 col_set_str(pinfo->cinfo, COL_INFO, "ATQB");
432 proto_item_append_text(ti, ": ATQB");
433 proto_tree_add_item(tree, hf_iso14443_atqb_start,
434 tvb, offset, 1, ENC_BIG_ENDIAN);
435 offset++;
437 proto_tree_add_item(tree, hf_iso14443_pupi,
438 tvb, offset, 4, ENC_BIG_ENDIAN);
439 offset += 4;
441 app_data_offset = offset;
442 app_data_it = proto_tree_add_item(tree, hf_iso14443_app_data,
443 tvb, offset, 4, ENC_BIG_ENDIAN);
444 offset += 4;
446 /* we should not link the protocol info length to the "extended
447 ATQB supported" field in the WUPB - even if the PCD supports
448 extended ATQB, the PICC may still send a basic one */
449 rem_len = tvb_reported_length_remaining(tvb, offset);
450 if (!crc_dropped) {
451 if (rem_len == 5 || rem_len == 6)
452 prot_inf_len = rem_len - 2;
454 else if (rem_len == 3 || rem_len == 4)
455 prot_inf_len = rem_len;
456 /* XXX - exception if (prot_inf_len==0) */
458 prot_inf_it = proto_tree_add_item(tree, hf_iso14443_prot_inf,
459 tvb, offset, prot_inf_len, ENC_BIG_ENDIAN);
460 prot_inf_tree = proto_item_add_subtree(
461 prot_inf_it, ett_iso14443_prot_inf);
462 /* bit rate info are applicable only if b4 is 0 */
463 if (!(tvb_get_uint8(tvb, offset) & 0x08)) {
464 proto_tree_add_bitmask_with_flags(prot_inf_tree, tvb, offset,
465 hf_iso14443_bit_rate_cap, ett_iso14443_bit_rate,
466 bit_rate_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
468 offset++;
469 max_frame_size_code = (tvb_get_uint8(tvb, offset) & 0xF0) >> 4;
470 proto_tree_add_uint_bits_format_value(prot_inf_tree,
471 hf_iso14443_max_frame_size_code,
472 tvb, offset*8, 4, max_frame_size_code, ENC_BIG_ENDIAN, "%d",
473 max_frame_size_code);
474 if (max_frame_size_code < LEN_CODE_MAX) {
475 pi = proto_tree_add_uint(prot_inf_tree, hf_iso14443_max_frame_size,
476 tvb, offset, 1, code_to_len[max_frame_size_code]);
477 proto_item_set_generated(pi);
479 prot_type_it = proto_tree_add_item(prot_inf_tree, hf_iso14443_prot_type,
480 tvb, offset, 1, ENC_BIG_ENDIAN);
481 prot_type_tree = proto_item_add_subtree(
482 prot_type_it, ett_iso14443_prot_type);
483 proto_tree_add_item(prot_type_tree, hf_iso14443_min_tr2,
484 tvb, offset, 1, ENC_BIG_ENDIAN);
485 proto_tree_add_item(prot_type_tree, hf_iso14443_4_compl_atqb,
486 tvb, offset, 1, ENC_BIG_ENDIAN);
487 offset++;
488 fwi = (tvb_get_uint8(tvb, offset) & 0xF0) >> 4;
489 proto_tree_add_uint_bits_format_value(prot_inf_tree, hf_iso14443_fwi,
490 tvb, offset*8, 4, fwi, ENC_BIG_ENDIAN, "%d", fwi);
491 iso14443_adc = tvb_get_uint8(tvb, offset) & 0x04;
492 proto_tree_add_item(prot_inf_tree, hf_iso14443_adc,
493 tvb, offset, 1, ENC_BIG_ENDIAN);
494 if (iso14443_adc) {
495 app_data_tree = proto_item_add_subtree(
496 app_data_it, ett_iso14443_app_data);
497 proto_tree_add_item(app_data_tree, hf_iso14443_afi,
498 tvb, app_data_offset, 1, ENC_BIG_ENDIAN);
499 app_data_offset++;
500 /* XXX - CRC_B app */
501 app_data_offset += 2;
502 proto_tree_add_item(app_data_tree, hf_iso14443_num_afi_apps,
503 tvb, app_data_offset, 1, ENC_BIG_ENDIAN);
504 proto_tree_add_item(app_data_tree, hf_iso14443_total_num_apps,
505 tvb, app_data_offset, 1, ENC_BIG_ENDIAN);
508 nad_supported = tvb_get_uint8(tvb, offset) & 0x02;
509 proto_tree_add_boolean_bits_format_value(prot_inf_tree,
510 hf_iso14443_nad_supported, tvb, 8*offset+6, 1, nad_supported,
511 ENC_BIG_ENDIAN, "%s", tfs_get_string(nad_supported, &tfs_supported_not_supported));
512 cid_supported = tvb_get_uint8(tvb, offset) & 0x01;
513 proto_tree_add_boolean_bits_format_value(prot_inf_tree,
514 hf_iso14443_cid_supported, tvb, 8*offset+7, 1, cid_supported,
515 ENC_BIG_ENDIAN, "%s", tfs_get_string(cid_supported, &tfs_supported_not_supported));
516 offset++;
518 /* XXX - extended ATQB */
519 if (prot_inf_len>3)
520 offset++;
522 if (!crc_dropped) {
523 proto_tree_add_checksum(tree, tvb, offset,
524 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
525 crc16_ccitt_tvb_offset(tvb, 0, offset),
526 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
527 offset += CRC_LEN;
530 return offset;
534 static int
535 dissect_iso14443_cmd_type_wupb(tvbuff_t *tvb, packet_info *pinfo,
536 proto_tree *tree, void *data)
538 proto_item *ti = proto_tree_get_parent(tree);
539 bool crc_dropped = (bool)GPOINTER_TO_UINT(data);
540 int offset = 0;
541 uint8_t param;
542 const char *msg_type;
544 if (pinfo->p2p_dir == P2P_DIR_SENT) {
545 proto_tree_add_item(tree, hf_iso14443_apf,
546 tvb, offset, 1, ENC_BIG_ENDIAN);
547 offset++;
548 proto_tree_add_item(tree, hf_iso14443_afi,
549 tvb, offset, 1, ENC_BIG_ENDIAN);
550 offset++;
552 param = tvb_get_uint8(tvb, offset);
553 proto_tree_add_item(tree, hf_iso14443_ext_atqb,
554 tvb, offset, 1, ENC_BIG_ENDIAN);
555 proto_tree_add_item(tree, hf_iso14443_wupb,
556 tvb, offset, 1, ENC_BIG_ENDIAN);
557 msg_type = tfs_get_string(param & 0x08, &tfs_wupb_reqb);
558 col_set_str(pinfo->cinfo, COL_INFO, msg_type);
559 proto_item_append_text(ti, ": %s", msg_type);
560 proto_tree_add_uint_bits_format_value(tree, hf_iso14443_n,
561 tvb, offset*8+5, 3, pow2(uint32_t, param&0x07),
562 ENC_BIG_ENDIAN, "%u", pow2(uint32_t, param&0x07));
563 offset++;
565 if (!crc_dropped) {
566 proto_tree_add_checksum(tree, tvb, offset,
567 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
568 crc16_ccitt_tvb_offset(tvb, 0, offset),
569 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
570 offset += CRC_LEN;
573 else if (pinfo->p2p_dir == P2P_DIR_RECV) {
574 offset = dissect_iso14443_atqb(tvb, offset, pinfo, tree, crc_dropped);
577 return offset;
581 static int
582 dissect_iso14443_cmd_type_hlta(tvbuff_t *tvb, packet_info *pinfo,
583 proto_tree *tree, void *data)
585 bool crc_dropped = (bool)GPOINTER_TO_UINT(data);
586 proto_item *ti = proto_tree_get_parent(tree);
587 int offset = 0;
589 col_set_str(pinfo->cinfo, COL_INFO, "HLTA");
590 proto_item_append_text(ti, ": HLTA");
591 proto_tree_add_item(tree, hf_iso14443_hlta,
592 tvb, offset, 2, ENC_BIG_ENDIAN);
593 offset += 2;
595 if (!crc_dropped) {
596 proto_tree_add_checksum(tree, tvb, offset,
597 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
598 crc16_iso14443a_tvb_offset(tvb, 0, offset),
599 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
600 offset += CRC_LEN;
603 return offset;
607 static int dissect_iso14443_uid_part(
608 tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
610 uint8_t uid_len = 4;
612 if (tvb_get_uint8(tvb, offset) == CT_BYTE) {
613 proto_tree_add_item(tree, hf_iso14443_ct, tvb, offset, 1, ENC_NA);
614 offset++;
615 uid_len = 3;
618 proto_tree_add_item(tree, hf_iso14443_uid_cln, tvb, offset, uid_len, ENC_NA);
619 offset += uid_len;
620 proto_tree_add_item(tree, hf_iso14443_bcc, tvb, offset, 1, ENC_BIG_ENDIAN);
621 offset++;
623 return offset;
627 static int
628 dissect_iso14443_cmd_type_uid(tvbuff_t *tvb, packet_info *pinfo,
629 proto_tree *tree, void *data)
631 bool crc_dropped = (bool)GPOINTER_TO_UINT(data);
632 proto_item *ti = proto_tree_get_parent(tree);
633 int offset = 0;
635 if (pinfo->p2p_dir == P2P_DIR_SENT) {
636 proto_tree_add_item(tree, hf_iso14443_sel,
637 tvb, offset, 1, ENC_BIG_ENDIAN);
638 offset++;
639 proto_tree_add_item(tree, hf_iso14443_nvb,
640 tvb, offset, 1, ENC_BIG_ENDIAN);
641 offset++;
643 if (tvb_reported_length_remaining(tvb, offset) == 0) {
644 col_set_str(pinfo->cinfo, COL_INFO, "Anticollision");
645 proto_item_append_text(ti, ": Anticollision");
647 else {
648 col_set_str(pinfo->cinfo, COL_INFO, "Select");
649 proto_item_append_text(ti, ": Select");
650 offset = dissect_iso14443_uid_part(tvb, offset, pinfo, tree);
651 if (!crc_dropped) {
652 proto_tree_add_checksum(tree, tvb, offset,
653 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
654 crc16_iso14443a_tvb_offset(tvb, 0, offset),
655 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
656 offset += CRC_LEN;
660 else if (pinfo->p2p_dir == P2P_DIR_RECV) {
661 if (tvb_reported_length_remaining(tvb, offset) <= 3) {
662 col_set_str(pinfo->cinfo, COL_INFO, "SAK");
663 proto_item_append_text(ti, ": SAK");
664 proto_tree_add_item(tree, hf_iso14443_4_compl_sak,
665 tvb, offset, 1, ENC_BIG_ENDIAN);
666 proto_tree_add_item(tree, hf_iso14443_uid_complete,
667 tvb, offset, 1, ENC_BIG_ENDIAN);
668 offset++;
669 if (!crc_dropped) {
670 proto_tree_add_checksum(tree, tvb, offset,
671 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
672 crc16_iso14443a_tvb_offset(tvb, 0, offset),
673 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
674 offset += CRC_LEN;
677 else if (tvb_reported_length_remaining(tvb, offset) == 5) {
678 col_set_str(pinfo->cinfo, COL_INFO, "UID");
679 offset = dissect_iso14443_uid_part(tvb, offset, pinfo, tree);
683 return offset;
687 static int dissect_iso14443_ats(tvbuff_t *tvb, int offset,
688 packet_info *pinfo, proto_tree *tree, bool crc_dropped)
690 proto_item *ti = proto_tree_get_parent(tree);
691 conversation_t *conv;
692 uint8_t tl, t0 = 0, fsci, fwi, sfgi;
693 proto_item *t0_it, *tb1_it, *tc1_it, *pi;
694 proto_tree *t0_tree, *tb1_tree, *tc1_tree;
695 int offset_tl, hist_len;
696 bool nad_supported, cid_supported;
698 col_set_str(pinfo->cinfo, COL_INFO, "ATS");
699 proto_item_append_text(ti, ": ATS");
701 conv = conversation_new_by_id(pinfo->num, CONVERSATION_ISO14443, ISO14443_CIRCUIT_ID);
702 conversation_add_proto_data(conv, proto_iso14443, GUINT_TO_POINTER((unsigned)ISO14443_A));
704 offset_tl = offset;
705 tl = tvb_get_uint8(tvb, offset);
706 proto_tree_add_item(tree, hf_iso14443_tl,
707 tvb, offset, 1, ENC_BIG_ENDIAN);
708 offset++;
709 /* the length in TL includes the TL byte itself */
710 if (tl >= 2) {
711 t0 = tvb_get_uint8(tvb, offset);
712 t0_it = proto_tree_add_item(tree, hf_iso14443_t0,
713 tvb, offset, 1, ENC_BIG_ENDIAN);
714 t0_tree = proto_item_add_subtree(t0_it, ett_iso14443_ats_t0);
715 proto_tree_add_item(t0_tree, hf_iso14443_tc1_transmitted,
716 tvb, offset, 1, ENC_BIG_ENDIAN);
717 proto_tree_add_item(t0_tree, hf_iso14443_tb1_transmitted,
718 tvb, offset, 1, ENC_BIG_ENDIAN);
719 proto_tree_add_item(t0_tree, hf_iso14443_ta1_transmitted,
720 tvb, offset, 1, ENC_BIG_ENDIAN);
721 fsci = t0 & 0x0F;
722 proto_tree_add_item(t0_tree, hf_iso14443_fsci,
723 tvb, offset, 1, ENC_BIG_ENDIAN);
724 if (fsci < LEN_CODE_MAX) {
725 pi = proto_tree_add_uint(t0_tree, hf_iso14443_fsc,
726 tvb, offset, 1, code_to_len[fsci]);
727 proto_item_set_generated(pi);
729 offset++;
731 if (t0 & HAVE_TA1) {
732 proto_tree_add_bitmask_with_flags(tree, tvb, offset,
733 hf_iso14443_ta1, ett_iso14443_ats_ta1,
734 ats_ta1_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
735 offset++;
737 if (t0 & HAVE_TB1) {
738 tb1_it = proto_tree_add_item(tree, hf_iso14443_tb1,
739 tvb, offset, 1, ENC_BIG_ENDIAN);
740 tb1_tree = proto_item_add_subtree(tb1_it, ett_iso14443_ats_tb1);
741 fwi = (tvb_get_uint8(tvb, offset) & 0xF0) >> 4;
742 proto_tree_add_uint_bits_format_value(tb1_tree, hf_iso14443_fwi,
743 tvb, offset*8, 4, fwi, ENC_BIG_ENDIAN, "%d", fwi);
744 sfgi = tvb_get_uint8(tvb, offset) & 0x0F;
745 proto_tree_add_uint_bits_format_value(tb1_tree, hf_iso14443_sfgi,
746 tvb, offset*8+4, 4, sfgi, ENC_BIG_ENDIAN, "%d", sfgi);
747 offset++;
749 if (t0 & HAVE_TC1) {
750 tc1_it = proto_tree_add_item(tree, hf_iso14443_tc1,
751 tvb, offset, 1, ENC_BIG_ENDIAN);
752 tc1_tree = proto_item_add_subtree(tc1_it, ett_iso14443_ats_tc1);
754 cid_supported = tvb_get_uint8(tvb, offset) & 0x02;
755 proto_tree_add_boolean_bits_format_value(tc1_tree,
756 hf_iso14443_cid_supported, tvb, 8*offset+6, 1, cid_supported,
757 ENC_BIG_ENDIAN, "%s", tfs_get_string(cid_supported, &tfs_supported_not_supported));
758 nad_supported = tvb_get_uint8(tvb, offset) & 0x01;
759 proto_tree_add_boolean_bits_format_value(tc1_tree,
760 hf_iso14443_nad_supported, tvb, 8*offset+7, 1, nad_supported,
761 ENC_BIG_ENDIAN, "%s", tfs_get_string(nad_supported, &tfs_supported_not_supported));
762 offset++;
764 hist_len = tl - (offset - offset_tl);
765 if (hist_len > 0) {
766 proto_tree_add_item(tree, hf_iso14443_hist_bytes,
767 tvb, offset, hist_len, ENC_NA);
768 offset += hist_len;
770 if (!crc_dropped) {
771 proto_tree_add_checksum(tree, tvb, offset,
772 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
773 crc16_iso14443a_tvb_offset(tvb, 0, offset),
774 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
775 offset += CRC_LEN;
778 return offset;
782 static int
783 dissect_iso14443_cmd_type_ats(tvbuff_t *tvb, packet_info *pinfo,
784 proto_tree *tree, void *data)
786 bool crc_dropped = (bool)GPOINTER_TO_UINT(data);
787 proto_item *ti = proto_tree_get_parent(tree);
788 int offset = 0;
789 uint8_t fsdi, cid;
790 proto_item *pi;
792 if (pinfo->p2p_dir == P2P_DIR_SENT) {
793 col_set_str(pinfo->cinfo, COL_INFO, "RATS");
794 proto_item_append_text(ti, ": RATS");
796 proto_tree_add_item(tree, hf_iso14443_rats_start,
797 tvb, offset, 1, ENC_BIG_ENDIAN);
798 offset++;
799 fsdi = tvb_get_uint8(tvb, offset) >> 4;
800 proto_tree_add_uint_bits_format_value(tree, hf_iso14443_fsdi,
801 tvb, offset*8, 4, fsdi, ENC_BIG_ENDIAN, "%d", fsdi);
802 if (fsdi < LEN_CODE_MAX) {
803 pi = proto_tree_add_uint(tree, hf_iso14443_fsd,
804 tvb, offset, 1, code_to_len[fsdi]);
805 proto_item_set_generated(pi);
807 cid = tvb_get_uint8(tvb, offset) & 0x0F;
808 proto_tree_add_uint_bits_format_value(tree, hf_iso14443_cid,
809 tvb, offset*8+4, 4, cid, ENC_BIG_ENDIAN, "%d", cid);
810 offset++;
811 if (!crc_dropped) {
812 proto_tree_add_checksum(tree, tvb, offset,
813 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
814 crc16_iso14443a_tvb_offset(tvb, 0, offset),
815 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
816 offset += CRC_LEN;
819 else if (pinfo->p2p_dir == P2P_DIR_RECV) {
820 offset = dissect_iso14443_ats(tvb, offset, pinfo, tree, crc_dropped);
823 return offset;
827 static int dissect_iso14443_attrib(tvbuff_t *tvb, int offset,
828 packet_info *pinfo, proto_tree *tree, bool crc_dropped)
830 proto_item *ti = proto_tree_get_parent(tree);
831 proto_item *p1_it, *p2_it, *p3_it, *p4_it, *pi;
832 proto_tree *p1_tree, *p2_tree, *p3_tree, *p4_tree;
833 uint8_t max_frame_size_code, cid;
834 int hl_inf_len;
836 col_set_str(pinfo->cinfo, COL_INFO, "Attrib");
837 proto_item_append_text(ti, ": Attrib");
839 proto_tree_add_item(tree, hf_iso14443_attrib_start,
840 tvb, offset, 1, ENC_BIG_ENDIAN);
841 offset++;
842 proto_tree_add_item(tree, hf_iso14443_pupi,
843 tvb, offset, 4, ENC_BIG_ENDIAN);
844 offset += 4;
846 p1_it = proto_tree_add_item(tree, hf_iso14443_param1,
847 tvb, offset, 1, ENC_BIG_ENDIAN);
848 p1_tree = proto_item_add_subtree( p1_it, ett_iso14443_attr_p1);
849 proto_tree_add_item(p1_tree, hf_iso14443_min_tr0,
850 tvb, offset, 1, ENC_BIG_ENDIAN);
851 proto_tree_add_item(p1_tree, hf_iso14443_min_tr1,
852 tvb, offset, 1, ENC_BIG_ENDIAN);
853 proto_tree_add_item(p1_tree, hf_iso14443_eof,
854 tvb, offset, 1, ENC_BIG_ENDIAN);
855 proto_tree_add_item(p1_tree, hf_iso14443_sof,
856 tvb, offset, 1, ENC_BIG_ENDIAN);
857 offset++;
859 p2_it = proto_tree_add_item(tree, hf_iso14443_param2,
860 tvb, offset, 1, ENC_BIG_ENDIAN);
861 p2_tree = proto_item_add_subtree( p2_it, ett_iso14443_attr_p2);
862 proto_tree_add_item(p2_tree, hf_iso14443_bitrate_picc_pcd,
863 tvb, offset, 1, ENC_BIG_ENDIAN);
864 proto_tree_add_item(p2_tree, hf_iso14443_bitrate_pcd_picc,
865 tvb, offset, 1, ENC_BIG_ENDIAN);
866 max_frame_size_code = tvb_get_uint8(tvb, offset) & 0x0F;
867 proto_tree_add_uint_bits_format_value(p2_tree,
868 hf_iso14443_max_frame_size_code,
869 tvb, offset*8+4, 4, max_frame_size_code, ENC_BIG_ENDIAN, "%d",
870 max_frame_size_code);
871 if (max_frame_size_code < LEN_CODE_MAX) {
872 pi = proto_tree_add_uint(p2_tree, hf_iso14443_max_frame_size,
873 tvb, offset, 1, code_to_len[max_frame_size_code]);
874 proto_item_set_generated(pi);
876 offset++;
878 p3_it = proto_tree_add_item(tree, hf_iso14443_param3,
879 tvb, offset, 1, ENC_BIG_ENDIAN);
880 p3_tree = proto_item_add_subtree(p3_it, ett_iso14443_attr_p3);
881 proto_tree_add_item(p3_tree, hf_iso14443_min_tr2,
882 tvb, offset, 1, ENC_BIG_ENDIAN);
883 proto_tree_add_item(p3_tree, hf_iso14443_4_compl_atqb,
884 tvb, offset, 1, ENC_BIG_ENDIAN);
885 offset++;
887 p4_it = proto_tree_add_item(tree, hf_iso14443_param4,
888 tvb, offset, 1, ENC_BIG_ENDIAN);
889 p4_tree = proto_item_add_subtree(p4_it, ett_iso14443_attr_p4);
890 cid = tvb_get_uint8(tvb, offset) & 0x0F;
891 proto_tree_add_uint_bits_format_value(p4_tree, hf_iso14443_cid,
892 tvb, offset*8+4, 4, cid, ENC_BIG_ENDIAN, "%d", cid);
893 offset++;
895 hl_inf_len = crc_dropped ?
896 tvb_reported_length_remaining(tvb, offset) :
897 tvb_reported_length_remaining(tvb, offset) - CRC_LEN;
898 if (hl_inf_len > 0) {
899 offset += hl_inf_len;
901 if (!crc_dropped) {
902 proto_tree_add_checksum(tree, tvb, offset,
903 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
904 crc16_ccitt_tvb_offset(tvb, 0, offset),
905 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
906 offset += CRC_LEN;
909 return offset;
913 static int
914 dissect_iso14443_cmd_type_attrib(tvbuff_t *tvb, packet_info *pinfo,
915 proto_tree *tree, void *data)
917 bool crc_dropped = (bool)GPOINTER_TO_UINT(data);
918 proto_item *ti = proto_tree_get_parent(tree);
919 int offset = 0;
920 uint8_t mbli, cid;
921 int hl_resp_len;
922 conversation_t *conv;
924 if (pinfo->p2p_dir == P2P_DIR_SENT) {
925 offset = dissect_iso14443_attrib(
926 tvb, offset, pinfo, tree, crc_dropped);
928 else if (pinfo->p2p_dir == P2P_DIR_RECV) {
929 col_set_str(pinfo->cinfo, COL_INFO, "Response to Attrib");
930 proto_item_append_text(ti, ": Response to Attrib");
932 conv = conversation_new_by_id(pinfo->num, CONVERSATION_ISO14443, ISO14443_CIRCUIT_ID);
933 conversation_add_proto_data(conv, proto_iso14443, GUINT_TO_POINTER((unsigned)ISO14443_B));
935 mbli = tvb_get_uint8(tvb, offset) >> 4;
936 proto_tree_add_uint_bits_format_value(tree, hf_iso14443_mbli,
937 tvb, offset*8, 4, mbli, ENC_BIG_ENDIAN, "%d", mbli);
938 cid = tvb_get_uint8(tvb, offset) & 0x0F;
939 proto_tree_add_uint_bits_format_value(tree, hf_iso14443_cid,
940 tvb, offset*8+4, 4, cid, ENC_BIG_ENDIAN, "%d", cid);
941 offset++;
943 hl_resp_len = crc_dropped ?
944 tvb_reported_length_remaining(tvb, offset) :
945 tvb_reported_length_remaining(tvb, offset) - CRC_LEN;
946 if (hl_resp_len > 0) {
947 offset += hl_resp_len;
950 if (!crc_dropped) {
951 proto_tree_add_checksum(tree, tvb, offset,
952 hf_iso14443_crc, hf_iso14443_crc_status, &ei_iso14443_wrong_crc, pinfo,
953 crc16_ccitt_tvb_offset(tvb, 0, offset),
954 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
955 offset += CRC_LEN;
959 return offset;
963 static int
964 dissect_iso14443_cmd_type_block(tvbuff_t *tvb, packet_info *pinfo,
965 proto_tree *tree, void *data)
967 bool crc_dropped = (bool)GPOINTER_TO_UINT(data);
968 proto_item *ti = proto_tree_get_parent(tree);
969 int offset = 0;
970 uint8_t pcb, block_type;
971 const char *bt_str;
972 proto_item *pcb_ti, *inf_ti;
973 proto_tree *pcb_tree, *inf_tree;
974 bool has_cid, has_nad = false;
975 uint8_t s_cmd = S_CMD_NONE;
976 uint8_t inf_len;
978 pcb = tvb_get_uint8(tvb, offset);
979 block_type = (pcb & 0xC0) >> 6;
980 bt_str = try_val_to_str(block_type, iso14443_block_type);
981 if (bt_str) {
982 proto_item_append_text(ti, ": %s", bt_str);
983 col_set_str(pinfo->cinfo, COL_INFO, bt_str);
985 has_cid = ((pcb & 0x08) != 0);
987 pcb_ti = proto_tree_add_item(tree, hf_iso14443_pcb,
988 tvb, offset, 1, ENC_BIG_ENDIAN);
989 pcb_tree = proto_item_add_subtree(pcb_ti, ett_iso14443_pcb);
990 proto_tree_add_item(pcb_tree, hf_iso14443_block_type,
991 tvb, offset, 1, ENC_BIG_ENDIAN);
993 switch (block_type) {
994 case I_BLOCK_TYPE:
995 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
996 (pcb & 0x10) ? "Chaining" : "No chaining");
997 proto_tree_add_item(pcb_tree, hf_iso14443_i_blk_chaining,
998 tvb, offset, 1, ENC_BIG_ENDIAN);
999 proto_tree_add_item(pcb_tree, hf_iso14443_cid_following,
1000 tvb, offset, 1, ENC_BIG_ENDIAN);
1001 has_nad = ((pcb & 0x40) != 0);
1002 proto_tree_add_item(pcb_tree, hf_iso14443_nad_following,
1003 tvb, offset, 1, ENC_BIG_ENDIAN);
1004 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
1005 "Block number %d", pcb & 0x01);
1006 proto_tree_add_item(pcb_tree, hf_iso14443_blk_num,
1007 tvb, offset, 1, ENC_BIG_ENDIAN);
1008 break;
1010 case R_BLOCK_TYPE:
1011 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
1012 tfs_get_string(pcb & 0x10, &tfs_nak_ack));
1013 proto_tree_add_item(pcb_tree, hf_iso14443_nak,
1014 tvb, offset, 1, ENC_BIG_ENDIAN);
1015 proto_tree_add_item(pcb_tree, hf_iso14443_cid_following,
1016 tvb, offset, 1, ENC_BIG_ENDIAN);
1017 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
1018 "Block number %d", pcb & 0x01);
1019 proto_tree_add_item(pcb_tree, hf_iso14443_blk_num,
1020 tvb, offset, 1, ENC_BIG_ENDIAN);
1021 break;
1023 case S_BLOCK_TYPE:
1024 s_cmd = (pcb & 0x30) >> 4;
1025 proto_tree_add_item(pcb_tree, hf_iso14443_s_blk_cmd,
1026 tvb, offset, 1, ENC_BIG_ENDIAN);
1027 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
1028 val_to_str(s_cmd, iso14443_s_block_cmd,
1029 "Unknown (0x%02x)"));
1030 proto_tree_add_item(pcb_tree, hf_iso14443_cid_following,
1031 tvb, offset, 1, ENC_BIG_ENDIAN);
1032 break;
1034 default:
1035 /* Report an error? b8 = 0, b7 = 1 */
1036 break;
1038 offset++;
1040 if (has_cid)
1041 offset++;
1042 if (has_nad)
1043 offset++;
1045 switch (block_type) {
1046 case I_BLOCK_TYPE:
1047 inf_len = crc_dropped ?
1048 tvb_reported_length_remaining(tvb, offset) :
1049 tvb_reported_length_remaining(tvb, offset) - 2;
1050 break;
1052 /* R-blocks have no payload */
1054 case S_BLOCK_TYPE:
1055 inf_len = 1;
1056 break;
1058 default:
1059 inf_len = 0;
1060 break;
1064 if (inf_len > 0) {
1065 inf_ti = proto_tree_add_item(tree, hf_iso14443_inf,
1066 tvb, offset, inf_len, ENC_NA);
1067 if (block_type == S_BLOCK_TYPE) {
1068 if (s_cmd == S_CMD_WTX) {
1069 inf_tree = proto_item_add_subtree(inf_ti, ett_iso14443_inf);
1070 if (pinfo->p2p_dir == P2P_DIR_RECV) {
1071 proto_tree_add_item(inf_tree, hf_iso14443_pwr_lvl_ind,
1072 tvb, offset, 1, ENC_BIG_ENDIAN);
1074 proto_tree_add_item(inf_tree, hf_iso14443_wtxm,
1075 tvb, offset, 1, ENC_BIG_ENDIAN);
1079 if (block_type == I_BLOCK_TYPE) {
1080 fragment_head *frag_msg;
1081 tvbuff_t *inf_tvb, *payload_tvb;
1083 /* see the comment in dissect_dvbci_tpdu (packet-dvbci.c) */
1084 inf_tvb = tvb_new_subset_length(tvb, offset, inf_len);
1085 frag_msg = fragment_add_seq_next(&i_block_reassembly_table,
1086 inf_tvb, 0, pinfo, 0, NULL, inf_len,
1087 (pcb & 0x10) ? 1 : 0);
1089 payload_tvb = process_reassembled_data(inf_tvb, 0, pinfo,
1090 "Reassembled APDU", frag_msg,
1091 &i_block_frag_items, NULL, tree);
1093 if (payload_tvb) {
1094 if (!dissector_try_payload_with_data(iso14443_subdissector_table,
1095 payload_tvb, pinfo, tree, true, NULL)) {
1096 call_data_dissector(payload_tvb, pinfo, tree);
1101 offset += inf_len;
1104 if (!crc_dropped) {
1105 iso14443_type_t t = ISO14443_UNKNOWN;
1106 conversation_t *conv;
1107 uint32_t computed_checksum = 0;
1108 unsigned flags = PROTO_CHECKSUM_NO_FLAGS;
1110 conv = find_conversation_by_id(pinfo->num, CONVERSATION_ISO14443, ISO14443_CIRCUIT_ID);
1111 if (conv)
1112 t = (iso14443_type_t)GPOINTER_TO_UINT(conversation_get_proto_data(conv, proto_iso14443));
1114 if (t == ISO14443_A) {
1115 computed_checksum = crc16_iso14443a_tvb_offset(tvb, 0, offset);
1116 flags |= PROTO_CHECKSUM_VERIFY;
1118 else if (t == ISO14443_B) {
1119 computed_checksum = crc16_ccitt_tvb_offset(tvb, 0, offset);
1120 flags |= PROTO_CHECKSUM_VERIFY;
1123 proto_tree_add_checksum(tree, tvb, offset,
1124 hf_iso14443_crc, hf_iso14443_crc_status,
1125 &ei_iso14443_wrong_crc, pinfo, computed_checksum,
1126 ENC_LITTLE_ENDIAN, flags);
1127 offset += CRC_LEN;
1130 return offset;
1134 static int
1135 iso14443_set_addrs(uint8_t event, packet_info *pinfo)
1137 if (!IS_DATA_TRANSFER(event))
1138 return -1;
1140 /* pinfo->p2p_dir is from the perspective of the card reader,
1141 like in iso7816
1142 i.e sent is from reader to card, received is from card to reader */
1143 if (event == ISO14443_EVT_DATA_PCD_TO_PICC ||
1144 event == ISO14443_EVT_DATA_PCD_TO_PICC_CRC_DROPPED) {
1146 set_address(&pinfo->src, AT_STRINGZ,
1147 (int)strlen(ADDR_PCD)+1, ADDR_PCD);
1148 set_address(&pinfo->dst, AT_STRINGZ,
1149 (int)strlen(ADDR_PICC)+1 , ADDR_PICC);
1151 pinfo->p2p_dir = P2P_DIR_SENT;
1153 else {
1154 set_address(&pinfo->src, AT_STRINGZ,
1155 (int)strlen(ADDR_PICC)+1 , ADDR_PICC);
1156 set_address(&pinfo->dst, AT_STRINGZ,
1157 (int)strlen(ADDR_PCD)+1, ADDR_PCD);
1159 pinfo->p2p_dir = P2P_DIR_RECV;
1162 return 1;
1166 static inline bool
1167 iso14443_block_pcb(uint8_t byte)
1169 if ((byte & 0xE2) == 0x02) {
1170 /* I-block */
1171 return true;
1173 else if ((byte & 0xE6) == 0xA2) {
1174 /* R-block */
1175 return true;
1177 else if ((byte & 0xC7) == 0xC2) {
1178 /* S-block */
1179 return true;
1182 return false;
1186 static iso14443_transaction_t *
1187 iso14443_get_transaction(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1189 proto_item *it;
1190 wmem_tree_key_t key[3];
1191 iso14443_transaction_t *iso14443_trans = NULL;
1192 /* Is the current message a Waiting-Time-Extension request or response? */
1193 uint32_t wtx = (tvb_get_uint8(tvb, 0) & 0xF7) == 0xF2;
1195 /* When going backwards from the current message, we want to link wtx
1196 messages only to other wtx messages (and non-wtx messages to non-wtx,
1197 respectively). For this to work, the wtx flag must be the first
1198 component of the key. */
1199 key[0].length = 1;
1200 key[0].key = &wtx;
1201 key[1].length = 1;
1202 key[1].key = &pinfo->num;
1203 key[2].length = 0;
1204 key[2].key = NULL;
1206 /* Is this a request message? WTX requests are sent by the PICC, all
1207 other requests are sent by the PCD. */
1208 if (((pinfo->p2p_dir == P2P_DIR_SENT) && !wtx) ||
1209 ((pinfo->p2p_dir == P2P_DIR_RECV) && wtx)) {
1210 if (PINFO_FD_VISITED(pinfo)) {
1211 iso14443_trans =
1212 (iso14443_transaction_t *)wmem_tree_lookup32_array(
1213 transactions, key);
1214 if (iso14443_trans && iso14443_trans->rqst_frame==pinfo->num &&
1215 iso14443_trans->resp_frame!=0) {
1216 it = proto_tree_add_uint(tree, hf_iso14443_resp_in,
1217 NULL, 0, 0, iso14443_trans->resp_frame);
1218 proto_item_set_generated(it);
1221 else {
1222 iso14443_trans =
1223 wmem_new(wmem_file_scope(), iso14443_transaction_t);
1224 iso14443_trans->rqst_frame = pinfo->num;
1225 iso14443_trans->resp_frame = 0;
1226 iso14443_trans->cmd = CMD_TYPE_UNKNOWN;
1227 wmem_tree_insert32_array(transactions, key, (void *)iso14443_trans);
1230 else if (((pinfo->p2p_dir == P2P_DIR_SENT) && wtx) ||
1231 ((pinfo->p2p_dir == P2P_DIR_RECV) && !wtx)) {
1232 iso14443_trans = (iso14443_transaction_t *)wmem_tree_lookup32_array_le(
1233 transactions, key);
1234 if (iso14443_trans && iso14443_trans->resp_frame==0) {
1235 /* there's a pending request, this packet is the response */
1236 iso14443_trans->resp_frame = pinfo->num;
1239 if (iso14443_trans && iso14443_trans->resp_frame == pinfo->num) {
1240 it = proto_tree_add_uint(tree, hf_iso14443_resp_to,
1241 NULL, 0, 0, iso14443_trans->rqst_frame);
1242 proto_item_set_generated(it);
1246 return iso14443_trans;
1250 static iso14443_cmd_t iso14443_get_cmd_type(
1251 tvbuff_t *tvb, packet_info *pinfo, iso14443_transaction_t *trans)
1253 uint8_t first_byte;
1255 first_byte = tvb_get_uint8(tvb, 0);
1257 if (pinfo->p2p_dir == P2P_DIR_SENT) {
1258 if (tvb_reported_length(tvb) == 1) {
1259 return CMD_TYPE_WUPA;
1261 else if (first_byte == 0x05) {
1262 return CMD_TYPE_WUPB;
1264 else if (first_byte == 0x50) {
1265 return CMD_TYPE_HLTA;
1267 else if (first_byte == 0x1D) {
1268 return CMD_TYPE_ATTRIB;
1270 else if (first_byte == 0xE0) {
1271 return CMD_TYPE_ATS;
1273 else if ((first_byte & 0xF8) == 0x90) {
1274 return CMD_TYPE_UID;
1276 else if (iso14443_block_pcb(first_byte)) {
1277 return CMD_TYPE_BLOCK;
1280 else if (pinfo->p2p_dir == P2P_DIR_RECV) {
1281 if (trans->cmd != CMD_TYPE_UNKNOWN) {
1282 return trans->cmd;
1284 else if (iso14443_block_pcb(first_byte)) {
1285 return CMD_TYPE_BLOCK;
1288 /* we don't try to detect any response messages based on their
1289 length - depending on the log tool, two trailing CRC bytes
1290 may be added or not */
1293 return CMD_TYPE_UNKNOWN;
1297 static int
1298 dissect_iso14443_msg(tvbuff_t *tvb, packet_info *pinfo,
1299 proto_tree *tree, uint8_t event)
1301 bool crc_dropped = false;
1302 iso14443_transaction_t *iso14443_trans;
1303 iso14443_cmd_t cmd;
1304 proto_tree *msg_tree;
1305 int ret;
1307 if (event == ISO14443_EVT_DATA_PICC_TO_PCD_CRC_DROPPED ||
1308 event == ISO14443_EVT_DATA_PCD_TO_PICC_CRC_DROPPED) {
1309 crc_dropped = true;
1312 iso14443_trans = iso14443_get_transaction(tvb, pinfo, tree);
1313 if (!iso14443_trans)
1314 return -1;
1316 cmd = iso14443_get_cmd_type(tvb, pinfo, iso14443_trans);
1317 if (cmd != CMD_TYPE_UNKNOWN)
1318 iso14443_trans->cmd = cmd;
1320 msg_tree = proto_tree_add_subtree(
1321 tree, tvb, 0, -1, ett_iso14443_msg, NULL, "Message");
1323 ret = dissector_try_uint_with_data(iso14443_cmd_type_table, cmd,
1324 tvb, pinfo, msg_tree, false, GUINT_TO_POINTER((unsigned)crc_dropped));
1325 if (ret == 0) {
1326 proto_tree_add_expert(tree, pinfo, &ei_iso14443_unknown_cmd,
1327 tvb, 0, tvb_captured_length(tvb));
1328 ret = tvb_captured_length(tvb);
1331 return ret;
1335 static int dissect_iso14443(tvbuff_t *tvb,
1336 packet_info *pinfo, proto_tree *tree, void *data _U_)
1338 int packet_len;
1339 int offset = 0, offset_ver, offset_evt, offset_len_field;
1340 int ret;
1341 uint8_t version, event;
1342 const char *event_str;
1343 uint16_t len_field;
1344 proto_item *tree_ti;
1345 proto_tree *iso14443_tree, *hdr_tree;
1346 tvbuff_t *payload_tvb;
1347 conversation_t *conv;
1349 if (tvb_captured_length(tvb) < 4)
1350 return 0;
1352 offset_ver = offset;
1353 version = tvb_get_uint8(tvb, offset++);
1354 if (version != 0)
1355 return 0;
1357 offset_evt = offset;
1358 event = tvb_get_uint8(tvb, offset++);
1359 event_str = try_val_to_str(event, iso14443_event);
1360 if (!event_str)
1361 return 0;
1363 packet_len = tvb_reported_length(tvb);
1364 offset_len_field = offset;
1365 len_field = tvb_get_ntohs(tvb, offset);
1366 if (len_field != (packet_len-4))
1367 return 0;
1368 offset += 2;
1370 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISO 14443");
1371 col_clear(pinfo->cinfo, COL_INFO);
1373 tree_ti = proto_tree_add_protocol_format(tree, proto_iso14443,
1374 tvb, 0, tvb_reported_length(tvb), "ISO 14443");
1375 iso14443_tree = proto_item_add_subtree(tree_ti, ett_iso14443);
1377 hdr_tree = proto_tree_add_subtree(iso14443_tree,
1378 tvb, 0, offset, ett_iso14443_hdr, NULL, "Pseudo header");
1380 proto_tree_add_item(hdr_tree, hf_iso14443_hdr_ver,
1381 tvb, offset_ver, 1, ENC_BIG_ENDIAN);
1382 proto_tree_add_item(hdr_tree, hf_iso14443_event,
1383 tvb, offset_evt, 1, ENC_BIG_ENDIAN);
1384 proto_tree_add_item(hdr_tree, hf_iso14443_len_field,
1385 tvb, offset_len_field, 2, ENC_BIG_ENDIAN);
1387 if (IS_DATA_TRANSFER(event)) {
1388 iso14443_set_addrs(event, pinfo);
1390 payload_tvb = tvb_new_subset_remaining(tvb, offset);
1391 ret = dissect_iso14443_msg(payload_tvb, pinfo, iso14443_tree, event);
1392 if (ret > 0)
1393 offset += ret;
1395 else {
1396 col_set_str(pinfo->cinfo, COL_INFO, event_str);
1398 /* all events that are not data transfers close the connection
1399 to the card (e.g. the field is switched on or off) */
1400 conv = find_conversation_by_id(pinfo->num, CONVERSATION_ISO14443, ISO14443_CIRCUIT_ID);
1401 if (conv)
1402 conv->last_frame = pinfo->num;
1405 return offset;
1409 void
1410 proto_register_iso14443(void)
1412 static hf_register_info hf[] = {
1413 { &hf_iso14443_hdr_ver,
1414 { "Version", "iso14443.hdr_version",
1415 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1417 { &hf_iso14443_event,
1418 { "Event", "iso14443.event",
1419 FT_UINT8, BASE_HEX, VALS(iso14443_event), 0, NULL, HFILL }
1421 { &hf_iso14443_len_field,
1422 { "Length field", "iso14443.length_field",
1423 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
1425 { &hf_iso14443_resp_in,
1426 { "Response In", "iso14443.resp_in",
1427 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0, NULL, HFILL }
1429 { &hf_iso14443_resp_to,
1430 { "Response To", "iso14443.resp_to",
1431 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0, NULL, HFILL }
1433 { &hf_iso14443_short_frame,
1434 { "Short frame", "iso14443.short_frame",
1435 FT_UINT8, BASE_HEX, VALS(iso14443_short_frame), 0, NULL, HFILL }
1437 { &hf_iso14443_atqa_rfu1,
1438 { "RFU", "iso14443.atqa_rfu",
1439 FT_UINT16, BASE_HEX, NULL, 0xF000, NULL, HFILL }
1441 { &hf_iso14443_atqa_rfu2,
1442 { "RFU", "iso14443.atqa_rfu",
1443 FT_UINT16, BASE_HEX, NULL, 0x0020, NULL, HFILL }
1445 { &hf_iso14443_propr_coding,
1446 { "Proprietary coding", "iso14443.propr_coding",
1447 FT_UINT16, BASE_HEX, NULL, 0x0F00, NULL, HFILL }
1449 { &hf_iso14443_uid_bits,
1450 { "UID bits", "iso14443.uid_bits",
1451 FT_UINT16, BASE_HEX, NULL, 0x00C0, NULL, HFILL }
1453 { &hf_iso14443_uid_size,
1454 { "UID size", "iso14443.uid_size",
1455 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
1457 { &hf_iso14443_max_frame_size,
1458 { "Maximum frame size", "iso14443.max_frame_size",
1459 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
1461 { &hf_iso14443_bit_frame_anticoll,
1462 { "Bit frame anticollision", "iso14443.bit_frame_anticoll",
1463 FT_UINT16, BASE_HEX, NULL, 0x001F, NULL, HFILL }
1465 { &hf_iso14443_apf,
1466 { "Anticollision prefix", "iso14443.apf",
1467 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1469 { &hf_iso14443_afi,
1470 { "Application Family Identifier", "iso14443.afi",
1471 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1473 { &hf_iso14443_ext_atqb,
1474 { "Extended ATQB", "iso14443.ext_atqb", FT_BOOLEAN, 8,
1475 TFS(&tfs_supported_not_supported), 0x10, NULL, HFILL }
1477 { &hf_iso14443_wupb,
1478 { "WUPB/REQB", "iso14443.wupb",
1479 FT_BOOLEAN, 8, TFS(&tfs_wupb_reqb), 0x08, NULL, HFILL }
1481 { &hf_iso14443_n,
1482 { "N", "iso14443.n",
1483 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1485 { &hf_iso14443_atqb_start,
1486 { "Start byte", "iso14443.atqb_start",
1487 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1489 { &hf_iso14443_app_data,
1490 { "Application data", "iso14443.application_data",
1491 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
1493 { &hf_iso14443_num_afi_apps,
1494 { "Number of applications for this AFI", "iso14443.num_afi_apps",
1495 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1497 { &hf_iso14443_total_num_apps,
1498 { "Total number of applications", "iso14443.total_num_apps",
1499 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1501 { &hf_iso14443_prot_inf,
1502 { "Protocol info", "iso14443.protocol_info",
1503 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
1505 { &hf_iso14443_bit_rate_cap,
1506 { "Bit rate capability", "iso14443.bit_rate_cap",
1507 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1509 { &hf_iso14443_same_bit_rate,
1510 { "Same bit rate in both directions", "iso14443.same_bit_rate",
1511 FT_BOOLEAN, 8, TFS(&tfs_required_not_required), 0x80, NULL, HFILL }
1513 { &hf_iso14443_picc_pcd_847,
1514 { "PICC to PCD, 847kbit/s", "iso14443.picc_pcd_847", FT_BOOLEAN, 8,
1515 TFS(&tfs_supported_not_supported), 0x40, NULL, HFILL }
1517 { &hf_iso14443_picc_pcd_424,
1518 { "PICC to PCD, 424kbit/s", "iso14443.picc_pcd_424", FT_BOOLEAN, 8,
1519 TFS(&tfs_supported_not_supported), 0x20, NULL, HFILL }
1521 { &hf_iso14443_picc_pcd_212,
1522 { "PICC to PCD, 212kbit/s", "iso14443.picc_pcd_212", FT_BOOLEAN, 8,
1523 TFS(&tfs_supported_not_supported), 0x10, NULL, HFILL }
1525 { &hf_iso14443_pcd_picc_847,
1526 { "PCD to PICC, 847kbit/s", "iso14443.pcd_picc_847", FT_BOOLEAN, 8,
1527 TFS(&tfs_supported_not_supported), 0x04, NULL, HFILL }
1529 { &hf_iso14443_pcd_picc_424,
1530 { "PCD to PICC, 424kbit/s", "iso14443.pcd_picc_424", FT_BOOLEAN, 8,
1531 TFS(&tfs_supported_not_supported), 0x02, NULL, HFILL }
1533 { &hf_iso14443_pcd_picc_212,
1534 { "PCD to PICC, 212kbit/s", "iso14443.pcd_picc_212", FT_BOOLEAN, 8,
1535 TFS(&tfs_supported_not_supported), 0x01, NULL, HFILL }
1537 { &hf_iso14443_max_frame_size_code,
1538 { "Max frame size code", "iso14443.max_frame_size_code",
1539 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1541 { &hf_iso14443_prot_type,
1542 { "Protocol type", "iso14443.protocol_type",
1543 FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
1545 /* we're using min tr2 in two different places (atqb and attrib)
1546 the relative position within the byte is identical so we can
1547 set the mask here */
1548 { &hf_iso14443_min_tr2,
1549 { "Minimum TR2", "iso14443.min_tr2",
1550 FT_UINT8, BASE_HEX, NULL, 0x06, NULL, HFILL }
1552 /* the same goes for the 14443-4 compliant flag */
1553 { &hf_iso14443_4_compl_atqb,
1554 { "Compliant with ISO 14443-4", "iso14443.4_compliant", FT_BOOLEAN, 8,
1555 TFS(&tfs_compliant_not_compliant), 0x01, NULL, HFILL }
1557 { &hf_iso14443_fwi,
1558 { "FWI", "iso14443.fwi", FT_UINT8, BASE_DEC,
1559 NULL, 0, NULL, HFILL }
1561 { &hf_iso14443_sfgi,
1562 { "SFGI", "iso14443.sfgi", FT_UINT8, BASE_DEC,
1563 NULL, 0, NULL, HFILL }
1565 { &hf_iso14443_adc,
1566 { "Application Data Coding", "iso14443.adc", FT_BOOLEAN, 8,
1567 TFS(&tfs_iso_propr), 0x04, NULL, HFILL }
1569 { &hf_iso14443_nad_supported,
1570 { "NAD", "iso14443.nad_supported", FT_BOOLEAN, BASE_NONE,
1571 TFS(&tfs_supported_not_supported), 0, NULL, HFILL }
1573 { &hf_iso14443_cid_supported,
1574 { "CID", "iso14443.cid_supported", FT_BOOLEAN, BASE_NONE,
1575 TFS(&tfs_supported_not_supported), 0, NULL, HFILL }
1577 { &hf_iso14443_hlta,
1578 { "HLTA", "iso14443.hlta",
1579 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
1581 { &hf_iso14443_sel,
1582 { "SEL", "iso14443.sel",
1583 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1585 { &hf_iso14443_nvb,
1586 { "NVB", "iso14443.nvb",
1587 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1589 { &hf_iso14443_4_compl_sak,
1590 { "Compliant with ISO 14443-4", "iso14443.4_compliant", FT_BOOLEAN, 8,
1591 TFS(&tfs_compliant_not_compliant), 0x20, NULL, HFILL }
1593 { &hf_iso14443_uid_complete,
1594 { "UID complete", "iso14443.uid_complete", FT_BOOLEAN, 8,
1595 TFS(&tfs_incomplete_complete), 0x04, NULL, HFILL }
1597 { &hf_iso14443_ct,
1598 { "CT", "iso14443.ct",
1599 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1601 { &hf_iso14443_uid_cln,
1602 { "UID_CLn", "iso14443.uid_cln",
1603 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
1605 { &hf_iso14443_bcc,
1606 { "BCC", "iso14443.bcc",
1607 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1609 { &hf_iso14443_rats_start,
1610 { "Start byte", "iso14443.rats_start",
1611 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1613 { &hf_iso14443_fsdi,
1614 { "FSDI", "iso14443.fsdi",
1615 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
1617 { &hf_iso14443_fsd,
1618 { "FSD", "iso14443.fsd",
1619 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
1621 { &hf_iso14443_cid,
1622 { "CID", "iso14443.cid",
1623 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1625 { &hf_iso14443_tl,
1626 { "Length byte TL", "iso14443.tl",
1627 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1629 { &hf_iso14443_t0,
1630 { "Format byte T0", "iso14443.t0",
1631 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1633 { &hf_iso14443_tc1_transmitted,
1634 { "TC(1) transmitted", "iso14443.tc1_transmitted",
1635 FT_BOOLEAN, 8, NULL, HAVE_TC1, NULL, HFILL }
1637 { &hf_iso14443_tb1_transmitted,
1638 { "TB(1) transmitted", "iso14443.tb1_transmitted",
1639 FT_BOOLEAN, 8, NULL, HAVE_TB1, NULL, HFILL }
1641 { &hf_iso14443_ta1_transmitted,
1642 { "TA(1) transmitted", "iso14443.ta1_transmitted",
1643 FT_BOOLEAN, 8, NULL, HAVE_TA1, NULL, HFILL }
1645 { &hf_iso14443_fsci,
1646 { "FSCI", "iso14443.fsci",
1647 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1649 { &hf_iso14443_fsc,
1650 { "FSC", "iso14443.fsc",
1651 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
1653 { &hf_iso14443_tc1,
1654 { "Interface byte TC1", "iso14443.tc1",
1655 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1657 { &hf_iso14443_tb1,
1658 { "Interface byte TB1", "iso14443.tb1",
1659 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1661 { &hf_iso14443_ta1,
1662 { "Interface byte TA1", "iso14443.ta1",
1663 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1665 { &hf_iso14443_same_d,
1666 { "Same D for both directions", "iso14443.same_d", FT_BOOLEAN, 8,
1667 TFS(&tfs_required_not_required), 0x80, NULL, HFILL }
1669 { &hf_iso14443_ds8,
1670 { "DS=8", "iso14443.ds8", FT_BOOLEAN, 8,
1671 TFS(&tfs_supported_not_supported), 0x40, NULL, HFILL }
1673 { &hf_iso14443_ds4,
1674 { "DS=4", "iso14443.ds4", FT_BOOLEAN, 8,
1675 TFS(&tfs_supported_not_supported), 0x20, NULL, HFILL }
1677 { &hf_iso14443_ds2,
1678 { "DS=2", "iso14443.ds2", FT_BOOLEAN, 8,
1679 TFS(&tfs_supported_not_supported), 0x10, NULL, HFILL }
1681 { &hf_iso14443_dr8,
1682 { "DR=8", "iso14443.dr8", FT_BOOLEAN, 8,
1683 TFS(&tfs_supported_not_supported), 0x04, NULL, HFILL }
1685 { &hf_iso14443_dr4,
1686 { "DR=4", "iso14443.dr4", FT_BOOLEAN, 8,
1687 TFS(&tfs_supported_not_supported), 0x02, NULL, HFILL }
1689 { &hf_iso14443_dr2,
1690 { "DR=2", "iso14443.dr2", FT_BOOLEAN, 8,
1691 TFS(&tfs_supported_not_supported), 0x01, NULL, HFILL }
1693 { &hf_iso14443_hist_bytes,
1694 { "Historical bytes", "iso14443.hist_bytes",
1695 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
1697 { &hf_iso14443_attrib_start,
1698 { "Start byte", "iso14443.attrib_start",
1699 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1701 { &hf_iso14443_pupi,
1702 { "PUPI", "iso14443.pupi",
1703 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
1705 { &hf_iso14443_param1,
1706 { "Param 1", "iso14443.param1",
1707 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1709 { &hf_iso14443_min_tr0,
1710 { "Minimum TR0", "iso14443.min_tr0",
1711 FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
1713 { &hf_iso14443_min_tr1,
1714 { "Minimum TR1", "iso14443.min_tr1",
1715 FT_UINT8, BASE_HEX, NULL, 0x30, NULL, HFILL }
1717 { &hf_iso14443_eof,
1718 { "EOF", "iso14443.eof", FT_BOOLEAN, 8,
1719 TFS(&tfs_not_required_required), 0x08, NULL, HFILL }
1721 { &hf_iso14443_sof,
1722 { "SOF", "iso14443.sof", FT_BOOLEAN, 8,
1723 TFS(&tfs_not_required_required), 0x04, NULL, HFILL }
1725 { &hf_iso14443_param2,
1726 { "Param 2", "iso14443.param2",
1727 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1729 { &hf_iso14443_bitrate_picc_pcd,
1730 { "Bit rate PICC to PCD", "iso14443.bitrate_picc_pcd", FT_UINT8,
1731 BASE_HEX, VALS(iso14443_bitrates), 0xC0, NULL, HFILL }
1733 { &hf_iso14443_bitrate_pcd_picc,
1734 { "Bit rate PCD to PICC", "iso14443.bitrate_pcd_picc", FT_UINT8,
1735 BASE_HEX, VALS(iso14443_bitrates), 0x30, NULL, HFILL }
1737 { &hf_iso14443_param3,
1738 { "Param 3", "iso14443.param3",
1739 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1741 { &hf_iso14443_param4,
1742 { "Param 4", "iso14443.param4",
1743 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1745 { &hf_iso14443_mbli,
1746 { "MBLI", "iso14443.mbli",
1747 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1749 { &hf_iso14443_pcb,
1750 { "PCB", "iso14443.pcb",
1751 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
1753 { &hf_iso14443_block_type,
1754 { "Block type", "iso14443.block_type", FT_UINT8,
1755 BASE_HEX, VALS(iso14443_block_type), 0xC0, NULL, HFILL }
1757 { &hf_iso14443_i_blk_chaining,
1758 { "Chaining", "iso14443.i_block_chaining", FT_BOOLEAN, 8,
1759 TFS(&tfs_set_notset), 0x10, NULL, HFILL }
1761 { &hf_iso14443_cid_following,
1762 { "CID following", "iso14443.cid_following", FT_BOOLEAN, 8,
1763 NULL, 0x08, NULL, HFILL }
1765 { &hf_iso14443_nad_following,
1766 { "NAD following", "iso14443.nad_following", FT_BOOLEAN, 8,
1767 NULL, 0x04, NULL, HFILL }
1769 { &hf_iso14443_nak,
1770 { "NAK/ACK", "iso14443.nak", FT_BOOLEAN, 8,
1771 TFS(&tfs_nak_ack), 0x10, NULL, HFILL }
1773 { &hf_iso14443_blk_num,
1774 { "Block number", "iso14443.block_number",
1775 FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL }
1777 { &hf_iso14443_s_blk_cmd,
1778 { "Command", "iso14443.s_block_cmd", FT_UINT8,
1779 BASE_HEX, VALS(iso14443_s_block_cmd), 0x30, NULL, HFILL }
1781 { &hf_iso14443_pwr_lvl_ind,
1782 { "Power level indication", "iso14443.pwr_lvl_ind",
1783 FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
1785 { &hf_iso14443_wtxm,
1786 { "WTXM", "iso14443.wtxm",
1787 FT_UINT8, BASE_DEC, NULL, 0x3F, NULL, HFILL }
1789 { &hf_iso14443_inf,
1790 { "INF", "iso14443.inf",
1791 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
1793 { &hf_iso14443_frags,
1794 { "Apdu fragments", "iso14443.apdu_fragments",
1795 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
1797 { &hf_iso14443_frag,
1798 { "Apdu fragment", "iso14443.apdu_fragment",
1799 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
1801 { &hf_iso14443_frag_overlap,
1802 { "Apdu fragment overlap", "iso14443.apdu_fragment.overlap",
1803 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
1805 { &hf_iso14443_frag_overlap_conflicts,
1806 { "Apdu fragment overlapping with conflicting data",
1807 "iso14443.apdu_fragment.overlap.conflicts",
1808 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
1810 { &hf_iso14443_frag_multiple_tails,
1811 { "Apdu has multiple tail fragments",
1812 "iso14443.apdu_fragment.multiple_tails",
1813 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
1815 { &hf_iso14443_frag_too_long_frag,
1816 { "Apdu fragment too long", "iso14443.apdu_fragment.too_long_fragment",
1817 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
1819 { &hf_iso14443_frag_err,
1820 { "Apdu defragmentation error", "iso14443.apdu_fragment.error",
1821 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
1823 { &hf_iso14443_frag_cnt,
1824 { "Apdu fragment count", "iso14443.apdu_fragment.count",
1825 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
1827 { &hf_iso14443_reass_in,
1828 { "Apdu reassembled in", "iso14443.apdu_reassembled.in",
1829 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
1831 { &hf_iso14443_reass_len,
1832 { "Reassembled apdu length", "iso14443.apdu_reassembled.length",
1833 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
1835 { &hf_iso14443_crc,
1836 { "CRC", "iso14443.crc",
1837 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
1839 { &hf_iso14443_crc_status,
1840 { "CRC Status", "iso14443.crc.status",
1841 FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0, NULL, HFILL }
1845 static int *ett[] = {
1846 &ett_iso14443,
1847 &ett_iso14443_hdr,
1848 &ett_iso14443_msg,
1849 &ett_iso14443_app_data,
1850 &ett_iso14443_prot_inf,
1851 &ett_iso14443_bit_rate,
1852 &ett_iso14443_prot_type,
1853 &ett_iso14443_ats_t0,
1854 &ett_iso14443_ats_ta1,
1855 &ett_iso14443_ats_tb1,
1856 &ett_iso14443_ats_tc1,
1857 &ett_iso14443_attr_p1,
1858 &ett_iso14443_attr_p2,
1859 &ett_iso14443_attr_p3,
1860 &ett_iso14443_attr_p4,
1861 &ett_iso14443_pcb,
1862 &ett_iso14443_inf,
1863 &ett_iso14443_frag,
1864 &ett_iso14443_frags
1867 static ei_register_info ei[] = {
1868 { &ei_iso14443_unknown_cmd,
1869 { "iso14443.cmd.unknown", PI_PROTOCOL, PI_WARN,
1870 "Unknown ISO1443 command", EXPFILL }
1872 { &ei_iso14443_wrong_crc,
1873 { "iso14443.crc.wrong", PI_PROTOCOL, PI_WARN, "Wrong CRC", EXPFILL }
1875 { &ei_iso14443_uid_inval_size,
1876 { "iso14443.uid.invalid_size", PI_PROTOCOL, PI_WARN,
1877 "Invalid UID size", EXPFILL }
1881 expert_module_t* expert_iso14443;
1883 proto_iso14443 = proto_register_protocol("ISO/IEC 14443", "ISO 14443", "iso14443");
1884 proto_register_field_array(proto_iso14443, hf, array_length(hf));
1885 proto_register_subtree_array(ett, array_length(ett));
1886 expert_iso14443 = expert_register_protocol(proto_iso14443);
1887 expert_register_field_array(expert_iso14443, ei, array_length(ei));
1889 iso14443_cmd_type_table = register_dissector_table(
1890 "iso14443.cmd_type", "ISO14443 Command Type",
1891 proto_iso14443, FT_UINT8, BASE_DEC);
1893 reassembly_table_register(&i_block_reassembly_table,
1894 &addresses_reassembly_table_functions);
1896 iso14443_handle =
1897 register_dissector("iso14443", dissect_iso14443, proto_iso14443);
1899 transactions = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1901 iso14443_subdissector_table =
1902 register_decode_as_next_proto(proto_iso14443,
1903 "iso14443.subdissector", "ISO14443 payload subdissector", NULL);
1907 void
1908 proto_reg_handoff_iso14443(void)
1910 dissector_handle_t cmd_type_handle;
1912 dissector_add_uint("wtap_encap", WTAP_ENCAP_ISO14443, iso14443_handle);
1914 cmd_type_handle = create_dissector_handle(
1915 dissect_iso14443_cmd_type_wupa, proto_iso14443);
1916 dissector_add_uint("iso14443.cmd_type", CMD_TYPE_WUPA, cmd_type_handle);
1918 cmd_type_handle = create_dissector_handle(
1919 dissect_iso14443_cmd_type_wupb, proto_iso14443);
1920 dissector_add_uint("iso14443.cmd_type", CMD_TYPE_WUPB, cmd_type_handle);
1922 cmd_type_handle = create_dissector_handle(
1923 dissect_iso14443_cmd_type_hlta, proto_iso14443);
1924 dissector_add_uint("iso14443.cmd_type", CMD_TYPE_HLTA, cmd_type_handle);
1926 cmd_type_handle = create_dissector_handle(
1927 dissect_iso14443_cmd_type_uid, proto_iso14443);
1928 dissector_add_uint("iso14443.cmd_type", CMD_TYPE_UID, cmd_type_handle);
1930 cmd_type_handle = create_dissector_handle(
1931 dissect_iso14443_cmd_type_ats, proto_iso14443);
1932 dissector_add_uint("iso14443.cmd_type", CMD_TYPE_ATS, cmd_type_handle);
1934 cmd_type_handle = create_dissector_handle(
1935 dissect_iso14443_cmd_type_attrib, proto_iso14443);
1936 dissector_add_uint("iso14443.cmd_type", CMD_TYPE_ATTRIB, cmd_type_handle);
1938 cmd_type_handle = create_dissector_handle(
1939 dissect_iso14443_cmd_type_block, proto_iso14443);
1940 dissector_add_uint("iso14443.cmd_type", CMD_TYPE_BLOCK, cmd_type_handle);
1945 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1947 * Local variables:
1948 * c-basic-offset: 4
1949 * tab-width: 8
1950 * indent-tabs-mode: nil
1951 * End:
1953 * vi: set shiftwidth=4 tabstop=8 expandtab:
1954 * :indentSize=4:tabSize=8:noTabs=true: