Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-rfid-mifare.c
blob2a2f8def66ee1a365f1d068ea8c9c100c1ac7986
1 /* packet-rfid-mifare.c
2 * Dissector for the NXP MiFare Protocol
4 * References:
5 * http://code.google.com/p/nfc-tools/source/browse/trunk/libfreefare/libfreefare/mifare_classic.c
6 * http://www.nxp.com/documents/data_sheet/MF1S703x.pdf
7 * http://www.nxp.com/documents/application_note/AN1304.pdf
9 * Copyright 2011, Tyson Key <tyson.key@gmail.com>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include "config.h"
21 #include <epan/packet.h>
23 void proto_register_mifare(void);
25 static int proto_mifare;
27 static int hf_mifare_command;
28 static int hf_mifare_block_address;
29 static int hf_mifare_key_a;
30 static int hf_mifare_key_b;
31 static int hf_mifare_uid;
32 static int hf_mifare_operand;
33 static int hf_mifare_payload;
35 #define AUTH_A 0x60
36 #define AUTH_B 0x61
37 #define READ 0x30
38 #define WRITE 0xA0
39 #define TRANSFER 0xB0
40 #define DECREMENT 0xC0
41 #define INCREMENT 0xC1
42 #define RESTORE 0xC2
44 static const value_string hf_mifare_commands[] = {
45 {AUTH_A, "AUTH_A"},
46 {AUTH_B, "AUTH_B"},
47 {READ, "READ"},
48 {WRITE, "WRITE"},
49 {TRANSFER, "TRANSFER"},
50 {DECREMENT, "DECREMENT"},
51 {INCREMENT, "INCREMENT"},
52 {RESTORE, "RESTORE"},
54 /* End of commands */
55 {0x00, NULL}
58 /* Subtree handles: set by register_subtree_array */
59 static int ett_mifare;
61 static int
62 dissect_mifare(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
64 proto_item *item;
65 proto_tree *mifare_tree;
66 uint8_t cmd;
69 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MiFare");
70 col_clear(pinfo->cinfo, COL_INFO);
72 /* Start with a top-level item to add everything else to */
74 item = proto_tree_add_item(tree, proto_mifare, tvb, 0, -1, ENC_NA);
75 mifare_tree = proto_item_add_subtree(item, ett_mifare);
77 proto_tree_add_item(mifare_tree, hf_mifare_command, tvb, 0, 1, ENC_BIG_ENDIAN);
78 cmd = tvb_get_uint8(tvb, 0);
81 switch (cmd) {
83 case AUTH_A:
84 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
85 proto_tree_add_item(mifare_tree, hf_mifare_key_a, tvb, 2, 6, ENC_BIG_ENDIAN);
86 proto_tree_add_item(mifare_tree, hf_mifare_uid, tvb, 8, 4, ENC_BIG_ENDIAN);
87 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Authenticate with Key A");
88 break;
90 case AUTH_B:
91 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
92 proto_tree_add_item(mifare_tree, hf_mifare_key_b, tvb, 2, 6, ENC_BIG_ENDIAN);
93 proto_tree_add_item(mifare_tree, hf_mifare_uid, tvb, 8, 4, ENC_BIG_ENDIAN);
94 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Authenticate with Key B");
95 break;
97 case READ:
98 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
99 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Read");
100 break;
102 case WRITE:
103 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Write");
105 /* LibNFC and the TouchATag-branded reader don't expose the 2-byte CRC
106 or 4-bit NAK, as per MF1S703x, so we pretend that they don't exist.
108 I've never seen traces with those data structures before, either... */
110 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
112 proto_tree_add_item(mifare_tree, hf_mifare_payload, tvb, 2, -1, ENC_NA);
113 break;
115 case TRANSFER:
116 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
117 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Transfer");
118 break;
120 case DECREMENT:
121 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
122 proto_tree_add_item(mifare_tree, hf_mifare_operand, tvb, 2, 4, ENC_BIG_ENDIAN);
123 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Decrement");
124 break;
126 case INCREMENT:
127 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
128 proto_tree_add_item(mifare_tree, hf_mifare_operand, tvb, 2, 4, ENC_BIG_ENDIAN);
129 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Increment");
130 break;
132 case RESTORE:
133 proto_tree_add_item(mifare_tree, hf_mifare_block_address, tvb, 1, 1, ENC_BIG_ENDIAN);
134 proto_tree_add_item(mifare_tree, hf_mifare_operand, tvb, 2, 4, ENC_BIG_ENDIAN);
135 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Restore");
136 break;
138 default:
139 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Unknown");
140 break;
142 return tvb_captured_length(tvb);
145 void
146 proto_register_mifare(void)
148 static hf_register_info hf[] = {
150 {&hf_mifare_command,
151 { "Command", "mifare.cmd", FT_UINT8, BASE_HEX,
152 VALS(hf_mifare_commands), 0x0, NULL, HFILL }},
153 {&hf_mifare_block_address,
154 { "Block Address", "mifare.block.addr", FT_UINT8, BASE_DEC,
155 NULL, 0x0, NULL, HFILL }},
156 {&hf_mifare_key_a,
157 { "Key A", "mifare.key.a", FT_UINT64, BASE_HEX,
158 NULL, 0x0, NULL, HFILL }},
159 {&hf_mifare_key_b,
160 { "Key B", "mifare.key.b", FT_UINT64, BASE_HEX,
161 NULL, 0x0, NULL, HFILL }},
162 {&hf_mifare_uid,
163 { "UID", "mifare.uid", FT_UINT32, BASE_HEX,
164 NULL, 0x0, NULL, HFILL }},
165 {&hf_mifare_operand,
166 { "Operand", "mifare.operand", FT_INT32, BASE_DEC,
167 NULL, 0x0, NULL, HFILL }},
168 {&hf_mifare_payload,
169 { "Payload", "mifare.payload", FT_BYTES, BASE_NONE,
170 NULL, 0x0, NULL, HFILL }}
173 static int *ett[] = {
174 &ett_mifare
177 proto_mifare = proto_register_protocol("NXP MiFare", "MiFare", "mifare");
178 proto_register_field_array(proto_mifare, hf, array_length(hf));
179 proto_register_subtree_array(ett, array_length(ett));
181 register_dissector("mifare", dissect_mifare, proto_mifare);
185 * Editor modelines - https://www.wireshark.org/tools/modelines.html
187 * Local variables:
188 * c-basic-offset: 4
189 * tab-width: 8
190 * indent-tabs-mode: nil
191 * End:
193 * ex: set shiftwidth=4 tabstop=8 expandtab:
194 * :indentSize=4:tabSize=8:noTabs=true: