MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-rfid-felica.c
blob52d61781d577e5956ee8e910f001816a85569efc
1 /*
2 * Dissector for the Sony FeliCa Protocol
4 * References:
5 * http://www.sony.net/Products/felica/business/tech-support/data/fl_usmnl_1.2.pdf
6 * http://www.sony.net/Products/felica/business/tech-support/data/fp_usmnl_1.11.pdf
7 * http://www.sony.net/Products/felica/business/tech-support/data/format_sequence_guidelines_1.1.pdf
8 * http://www.sony.net/Products/felica/business/tech-support/data/card_usersmanual_2.0.pdf
9 * http://code.google.com/u/101410204121169118393/updates
10 * https://github.com/codebutler/farebot/wiki/Suica
12 * Copyright 2012, Tyson Key <tyson.key@gmail.com>
14 * $Id$
16 * Wireshark - Network traffic analyzer
17 * By Gerald Combs <gerald@wireshark.org>
18 * Copyright 1998 Gerald Combs
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include "config.h"
38 #include <glib.h>
40 #include <epan/packet.h>
41 #include <epan/strutil.h>
43 static int proto_felica = -1;
45 /* Opcodes */
46 static int hf_felica_opcode = -1;
48 /* System Code */
49 static int hf_felica_sys_code = -1;
51 /* Timeslot */
52 static int hf_felica_timeslot = -1;
54 /* Manufacture ID/NFCID2 */
55 static int hf_felica_idm = -1;
57 /* Request Code */
58 static int hf_felica_req_code = -1;
60 /* Manufacture Parameter/PAD */
61 static int hf_felica_pnm = -1;
63 /* Number of Services */
65 static int hf_felica_nbr_of_svcs = -1;
67 static int hf_felica_svc_code = -1;
69 static int hf_felica_nbr_of_blocks = -1;
70 static int hf_felica_block_nbr = -1;
72 /* Status flag 1 */
73 static int hf_felica_status_flag1 = -1;
75 /* Status flag 2 */
76 static int hf_felica_status_flag2 = -1;
78 /* - Commands - */
79 #define CMD_POLLING 0x00
80 #define CMD_REQ_SVC 0x02
81 #define CMD_REQ_RES 0x04
82 #define CMD_READ_WO_ENCRYPTION 0x06
83 #define CMD_WRITE_WO_ENCRYPTION 0x08
84 #define CMD_SEARCH_SVC_CODE 0x0A
85 #define CMD_REQ_SYS_CODE 0x0C
86 #define CMD_AUTH_1 0x10
87 #define CMD_AUTH_2 0x12
88 #define CMD_READ 0x14
89 #define CMD_WRITE 0x16
90 #define CMD_REQ_SVC_V2 0x32
91 #define CMD_REQ_SYS_STATUS 0x38
92 #define CMD_REQ_SPEC_VER 0x3C
93 #define CMD_RESET_MODE 0x3E
94 #define CMD_AUTH1_V2 0x40
95 #define CMD_AUTH2_V2 0x42
96 #define CMD_READ_V2 0x44
97 #define CMD_WRITE_V2 0x46
98 #define CMD_REQ_UPDATE_RAND_ID 0x4C
100 /* - Responses - */
101 #define RES_POLLING 0x01
102 #define RES_REQ_SVC 0x03
103 #define RES_REQ_RES 0x05
104 #define RES_READ_WO_ENCRYPTION 0x07
105 #define RES_WRITE_WO_ENCRYPTION 0x09
106 #define RES_SEARCH_SVC_CODE 0x0B
107 #define RES_REQ_SYS_CODE 0x0D
108 #define RES_AUTH_1 0x11
109 #define RES_AUTH_2 0x13
110 #define RES_READ 0x15
111 #define RES_WRITE 0x17
112 #define RES_REQ_SVC_V2 0x33
113 #define RES_REQ_SYS_STATUS 0x39
114 #define RES_REQ_SPEC_VER 0x3D
115 #define RES_RESET_MODE 0x3F
116 #define RES_AUTH1_V2 0x41
117 #define RES_AUTH2_V2 0x43
118 #define RES_READ_V2 0x45
119 #define RES_WRITE_V2 0x47
120 #define RES_REQ_UPDATE_RAND_ID 0x4D
122 /* - Request Codes - */
123 #define RC_NO_REQ 0x00
124 #define RC_SYS_REQ 0x01
125 #define RC_COM_PERF_REQ 0x02
127 /* - System Codes - */
129 /* FeliCa Lite/DFC */
130 #define SC_FELICA_LITE 0x88b4
132 /* NFC Forum NDEF */
133 #define SC_NFC_FORUM 0x12fc
135 /* FeliCa Networks' Common Area */
136 #define SC_FELICA_NW_COMMON_AREA 0xfe00
138 /* FeliCa Plug (NFC Dynamic Tag) */
139 #define SC_FELICA_PLUG 0xfee1
141 /* Japanese transit card */
142 #define SC_IRUCA 0xde80
144 /* "...return a response to the Polling command, regardless
145 of its System Code" */
147 #define SC_DOUBLE_WILDCARD 0xffff
149 static const value_string felica_opcodes[] = {
150 /* Commands */
151 {CMD_POLLING, "Polling"},
152 {CMD_REQ_SVC, "Request Service"},
153 {CMD_REQ_RES, "Request Response"},
154 {CMD_READ_WO_ENCRYPTION, "Read Without Encryption"},
155 {CMD_WRITE_WO_ENCRYPTION, "Write Without Encryption"},
156 {CMD_SEARCH_SVC_CODE, "Search Service Code"},
157 {CMD_REQ_SYS_CODE, "Request System Code"},
158 {CMD_AUTH_1, "Authentication1"},
159 {CMD_AUTH_2, "Authentication2"},
160 {CMD_READ, "Read"},
161 {CMD_WRITE, "Write"},
162 {CMD_REQ_SVC_V2, "Request Service v2"},
163 {CMD_REQ_SYS_STATUS, "Get System Status"},
164 {CMD_REQ_SPEC_VER, "Request Specification Version"},
165 {CMD_RESET_MODE, "Reset Mode"},
166 {CMD_AUTH1_V2, "Authentication1 v2"},
167 {CMD_AUTH2_V2, "Authentication2 v2"},
168 {CMD_READ_V2, "Read v2"},
169 {CMD_WRITE_V2, "Write v2"},
170 {CMD_REQ_UPDATE_RAND_ID, "Update Random ID"},
171 /* End of commands */
173 /* Responses */
174 {RES_POLLING, "Polling (Response)"},
175 {RES_REQ_SVC, "Request Service (Response)"},
176 {RES_REQ_RES, "Request Response (Response)"},
177 {RES_READ_WO_ENCRYPTION, "Read Without Encryption (Response)"},
178 {RES_WRITE_WO_ENCRYPTION, "Write Without Encryption (Response)"},
179 {RES_SEARCH_SVC_CODE, "Search Service Code (Response)"},
180 {RES_REQ_SYS_CODE, "Request System Code (Response)"},
181 {RES_AUTH_1, "Authentication1 (Response)"},
182 {RES_AUTH_2, "Authentication2 (Response)"},
183 {RES_READ, "Read (Response)"},
184 {RES_WRITE, "Write (Response)"},
185 {RES_REQ_SVC_V2, "Request Service v2 (Response)"},
186 {RES_REQ_SYS_STATUS, "Get System Status (Response)"},
187 {RES_REQ_SPEC_VER, "Request Specification Version (Response)"},
188 {RES_RESET_MODE, "Reset Mode (Response)"},
189 {RES_AUTH1_V2, "Authentication1 v2 (Response)"},
190 {RES_AUTH2_V2, "Authentication2 v2 (Response)"},
191 {RES_READ_V2, "Read v2 (Response)"},
192 {RES_WRITE_V2, "Write v2 (Response)"},
193 {RES_REQ_UPDATE_RAND_ID, "Update Random ID"},
194 /* End of responses */
196 {0x00, NULL}
199 static const value_string felica_req_codes[] = {
200 {RC_NO_REQ, "No Request"},
201 {RC_SYS_REQ, "System Code Request"},
202 {RC_COM_PERF_REQ, "Communication Performance Request"},
204 /* Others are reserved for future use */
206 /* End of request codes */
207 {0x00, NULL}
210 static const value_string felica_sys_codes[] = {
211 {SC_FELICA_LITE, "FeliCa Lite"},
212 {SC_FELICA_PLUG, "FeliCa Plug (NFC Dynamic Tag)"},
213 {SC_NFC_FORUM, "NFC Forum (NDEF)"},
214 {SC_FELICA_NW_COMMON_AREA, "FeliCa Networks Common Area"},
215 {SC_IRUCA, "IruCa"},
216 {SC_DOUBLE_WILDCARD, "Wildcard"},
218 /* End of system codes */
219 {0x00, NULL}
222 static dissector_handle_t data_handle=NULL;
224 /* Forward-declare the dissector functions */
225 static void dissect_felica(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
227 /* Subtree handles: set by register_subtree_array */
228 static gint ett_felica = -1;
230 static void dissect_felica(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
232 proto_item *item;
233 proto_tree *felica_tree = NULL;
234 guint8 opcode;
235 guint8 rwe_pos = 0;
236 tvbuff_t *rwe_resp_data_tvb;
238 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FeliCa");
240 if (tree) {
241 /* Start with a top-level item to add everything else to */
242 item = proto_tree_add_item(tree, proto_felica, tvb, 0, -1, ENC_NA);
243 felica_tree = proto_item_add_subtree(item, ett_felica);
245 opcode = tvb_get_guint8(tvb, 0);
246 col_set_str(pinfo->cinfo, COL_INFO,
247 val_to_str_const(opcode, felica_opcodes, "Unknown"));
249 if (tree) {
250 proto_tree_add_item(felica_tree, hf_felica_opcode, tvb, 0, 1, ENC_NA);
253 switch (opcode) {
255 case CMD_POLLING:
256 if (tree) {
257 proto_tree_add_item(felica_tree, hf_felica_sys_code, tvb, 1, 2, ENC_BIG_ENDIAN);
258 proto_tree_add_item(felica_tree, hf_felica_req_code, tvb, 3, 1, ENC_BIG_ENDIAN);
259 proto_tree_add_item(felica_tree, hf_felica_timeslot, tvb, 4, 1, ENC_BIG_ENDIAN);
261 break;
263 case RES_POLLING:
264 if (tree) {
265 proto_tree_add_item(felica_tree, hf_felica_idm, tvb, 1, 8, ENC_BIG_ENDIAN);
266 proto_tree_add_item(felica_tree, hf_felica_pnm, tvb, 9, 8, ENC_BIG_ENDIAN);
268 if (tvb_reported_length(tvb) == 19)
269 proto_tree_add_item(felica_tree, hf_felica_sys_code, tvb, 17, 2, ENC_BIG_ENDIAN);
272 * Request data - 0 or 2 bytes long; data corresponding to request
273 * code; only if request code of command packet is not 00 and
274 * corresponds to request data
277 break;
279 case CMD_REQ_SVC:
280 /* TODO */
281 break;
283 case RES_REQ_SVC:
284 /* TODO */
285 break;
287 case CMD_REQ_RES:
288 /* TODO */
289 break;
291 case RES_REQ_RES:
292 /* TODO */
293 break;
295 case CMD_READ_WO_ENCRYPTION:
296 if (tree) {
297 proto_tree_add_item(felica_tree, hf_felica_idm, tvb, 1, 8, ENC_BIG_ENDIAN);
298 proto_tree_add_item(felica_tree, hf_felica_nbr_of_svcs, tvb, 9, 1, ENC_BIG_ENDIAN);
300 /* Service codes are always 2 bytes in length */
302 /* There can technically be multiple Service Codes - although my traces only contain 1 */
303 proto_tree_add_item(felica_tree, hf_felica_svc_code, tvb, 10, 2, ENC_BIG_ENDIAN);
305 /* Number of Blocks - 1byte */
306 proto_tree_add_item(felica_tree, hf_felica_nbr_of_blocks, tvb, 12, 1, ENC_BIG_ENDIAN);
308 /* Iterate through the block list, and update the tree */
309 for (rwe_pos = 0; rwe_pos < tvb_get_guint8(tvb, 12); rwe_pos++) {
310 proto_tree_add_uint(felica_tree, hf_felica_block_nbr, tvb,
311 13 + 2 * rwe_pos, 2, tvb_get_guint8(tvb, 14 + 2 * rwe_pos));
314 break;
316 case RES_READ_WO_ENCRYPTION:
317 if (tree) {
318 proto_tree_add_item(felica_tree, hf_felica_idm, tvb, 1, 8, ENC_BIG_ENDIAN);
319 proto_tree_add_item(felica_tree, hf_felica_status_flag1, tvb, 9, 1, ENC_BIG_ENDIAN);
320 proto_tree_add_item(felica_tree, hf_felica_status_flag2, tvb, 10, 1, ENC_BIG_ENDIAN);
321 proto_tree_add_item(felica_tree, hf_felica_nbr_of_blocks, tvb, 11, 1, ENC_BIG_ENDIAN);
323 rwe_resp_data_tvb = tvb_new_subset_remaining(tvb, 12);
324 call_dissector(data_handle, rwe_resp_data_tvb, pinfo, tree);
325 break;
327 case CMD_WRITE_WO_ENCRYPTION:
328 /* TODO */
329 break;
331 case RES_WRITE_WO_ENCRYPTION:
332 /* TODO */
333 break;
335 case CMD_SEARCH_SVC_CODE:
336 /* TODO */
337 break;
339 case RES_SEARCH_SVC_CODE:
340 /* TODO */
341 break;
343 case CMD_REQ_SYS_CODE:
344 /* TODO */
345 break;
347 case RES_REQ_SYS_CODE:
348 /* TODO */
349 break;
351 case CMD_AUTH_1:
352 /* TODO */
353 break;
355 case RES_AUTH_1:
356 /* TODO */
357 break;
359 case CMD_AUTH_2:
360 /* TODO */
361 break;
363 case RES_AUTH_2:
364 /* TODO */
365 break;
367 case CMD_READ:
368 /* TODO */
369 break;
371 case RES_READ:
372 /* TODO */
373 break;
375 case CMD_WRITE:
376 /* TODO */
377 break;
379 case RES_WRITE:
380 /* TODO */
381 break;
383 case CMD_REQ_SVC_V2:
384 /* TODO */
385 break;
387 case RES_REQ_SVC_V2:
388 /* TODO */
389 break;
391 case CMD_REQ_SYS_STATUS:
392 /* TODO */
393 break;
395 case RES_REQ_SYS_STATUS:
396 /* TODO */
397 break;
399 case CMD_REQ_SPEC_VER:
400 /* TODO */
401 break;
403 case RES_REQ_SPEC_VER:
404 /* TODO */
405 break;
407 case CMD_RESET_MODE:
408 /* TODO */
409 break;
411 case RES_RESET_MODE:
412 /* TODO */
413 break;
415 case CMD_AUTH1_V2:
416 /* TODO */
417 break;
419 case RES_AUTH1_V2:
420 /* TODO */
421 break;
423 case CMD_AUTH2_V2:
424 /* TODO */
425 break;
427 case RES_AUTH2_V2:
428 /* TODO */
429 break;
431 case CMD_READ_V2:
432 /* TODO */
433 break;
435 case RES_READ_V2:
436 /* TODO */
437 break;
439 case CMD_WRITE_V2:
440 /* TODO */
441 break;
443 case RES_WRITE_V2:
444 /* TODO */
445 break;
447 case CMD_REQ_UPDATE_RAND_ID:
448 /* TODO */
449 break;
451 case RES_REQ_UPDATE_RAND_ID:
452 /* TODO */
453 break;
455 default:
456 break;
460 void
461 proto_register_felica(void)
463 static hf_register_info hf[] = {
465 {&hf_felica_opcode,
466 { "Opcode", "felica.opcode",
467 FT_UINT8, BASE_HEX, VALS(felica_opcodes), 0x0,
468 NULL, HFILL }
471 /* Request Code */
472 {&hf_felica_req_code,
473 { "Request Code", "felica.req.code",
474 FT_UINT8, BASE_HEX, VALS(felica_req_codes), 0x0,
475 NULL, HFILL }
478 {&hf_felica_idm,
479 { "IDm (Manufacture ID)/NFCID2", "felica.idm",
480 FT_UINT64, BASE_HEX, NULL, 0x0,
481 NULL, HFILL }
484 /* System Code */
485 {&hf_felica_sys_code,
486 { "System Code", "felica.sys_code",
487 FT_UINT16, BASE_HEX, VALS(felica_sys_codes), 0x0,
488 NULL, HFILL }
491 /* Service Code */
492 {&hf_felica_svc_code,
493 { "Service Code", "felica.svc_code",
494 FT_UINT16, BASE_HEX, NULL, 0x0,
495 NULL, HFILL }
498 /* Parameter/PAD */
499 {&hf_felica_pnm,
500 { "PNm (Manufacture Parameter)/PAD", "felica.pnm",
501 FT_UINT64, BASE_HEX, NULL, 0x0,
502 NULL, HFILL }
505 /* Number of Services */
506 {&hf_felica_nbr_of_svcs,
507 { "Number of Services", "felica.svcs",
508 FT_UINT8, BASE_DEC, NULL, 0x0,
509 NULL, HFILL }
512 /* Number of Blocks */
513 {&hf_felica_nbr_of_blocks,
514 { "Number of Blocks", "felica.blocks",
515 FT_UINT8, BASE_DEC, NULL, 0x0,
516 NULL, HFILL }
519 /* Block ID */
520 {&hf_felica_block_nbr,
521 { "Block Number", "felica.block.nbr",
522 FT_UINT8, BASE_DEC, NULL, 0x0,
523 NULL, HFILL }
526 /* Status Flag 1 */
527 {&hf_felica_status_flag1,
528 { "Status Flag 1", "felica.status.flag1",
529 FT_UINT8, BASE_HEX, NULL, 0x0,
530 NULL, HFILL }
533 /* Status Flag 2 */
534 {&hf_felica_status_flag2,
535 { "Status Flag 2", "felica.status.flag2",
536 FT_UINT8, BASE_HEX, NULL, 0x0,
537 NULL, HFILL }
540 /* Timeslot */
541 {&hf_felica_timeslot,
542 { "Timeslot", "felica.timeslot",
543 FT_UINT8, BASE_HEX, NULL, 0x0,
544 NULL, HFILL }
548 static gint *ett[] = {
549 &ett_felica
552 proto_felica = proto_register_protocol("Sony FeliCa", "FeliCa", "felica");
553 proto_register_field_array(proto_felica, hf, array_length(hf));
554 proto_register_subtree_array(ett, array_length(ett));
556 register_dissector("felica", dissect_felica, proto_felica);
559 /* Handler registration */
560 void
561 proto_reg_handoff_felica(void)
563 data_handle = find_dissector("data");
566 * Editor modelines - http://www.wireshark.org/tools/modelines.html
568 * Local variables:
569 * c-basic-offset: 4
570 * tab-width: 8
571 * indent-tabs-mode: nil
572 * End:
574 * ex: set shiftwidth=4 tabstop=8 expandtab:
575 * :indentSize=4:tabSize=8:noTabs=true: