diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-rfid-felica.c | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-rfid-felica.c')
-rw-r--r-- | epan/dissectors/packet-rfid-felica.c | 548 |
1 files changed, 548 insertions, 0 deletions
diff --git a/epan/dissectors/packet-rfid-felica.c b/epan/dissectors/packet-rfid-felica.c new file mode 100644 index 0000000..86e2de9 --- /dev/null +++ b/epan/dissectors/packet-rfid-felica.c @@ -0,0 +1,548 @@ +/* + * Dissector for the Sony FeliCa Protocol + * + * References: + * http://www.sony.net/Products/felica/business/tech-support/data/fl_usmnl_1.2.pdf + * http://www.sony.net/Products/felica/business/tech-support/data/fp_usmnl_1.11.pdf + * http://www.sony.net/Products/felica/business/tech-support/data/format_sequence_guidelines_1.1.pdf + * http://www.sony.net/Products/felica/business/tech-support/data/card_usersmanual_2.0.pdf + * http://code.google.com/u/101410204121169118393/updates + * https://github.com/codebutler/farebot/wiki/Suica + * + * Copyright 2012, Tyson Key <tyson.key@gmail.com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + */ + +#include "config.h" + +#include <epan/packet.h> + +void proto_register_felica(void); + +static int proto_felica = -1; + +/* Opcodes */ +static int hf_felica_opcode = -1; + +/* System Code */ +static int hf_felica_sys_code = -1; + +/* Timeslot */ +static int hf_felica_timeslot = -1; + +/* Manufacture ID/NFCID2 */ +static int hf_felica_idm = -1; + +/* Request Code */ +static int hf_felica_req_code = -1; + +/* Manufacture Parameter/PAD */ +static int hf_felica_pnm = -1; + +/* Number of Services */ + +static int hf_felica_nbr_of_svcs = -1; + +static int hf_felica_svc_code = -1; + +static int hf_felica_nbr_of_blocks = -1; +static int hf_felica_block_nbr = -1; + +/* Status flag 1 */ +static int hf_felica_status_flag1 = -1; + +/* Status flag 2 */ +static int hf_felica_status_flag2 = -1; + +/* - Commands - */ +#define CMD_POLLING 0x00 +#define CMD_REQ_SVC 0x02 +#define CMD_REQ_RES 0x04 +#define CMD_READ_WO_ENCRYPTION 0x06 +#define CMD_WRITE_WO_ENCRYPTION 0x08 +#define CMD_SEARCH_SVC_CODE 0x0A +#define CMD_REQ_SYS_CODE 0x0C +#define CMD_AUTH_1 0x10 +#define CMD_AUTH_2 0x12 +#define CMD_READ 0x14 +#define CMD_WRITE 0x16 +#define CMD_REQ_SVC_V2 0x32 +#define CMD_REQ_SYS_STATUS 0x38 +#define CMD_REQ_SPEC_VER 0x3C +#define CMD_RESET_MODE 0x3E +#define CMD_AUTH1_V2 0x40 +#define CMD_AUTH2_V2 0x42 +#define CMD_READ_V2 0x44 +#define CMD_WRITE_V2 0x46 +#define CMD_REQ_UPDATE_RAND_ID 0x4C + +/* - Responses - */ +#define RES_POLLING 0x01 +#define RES_REQ_SVC 0x03 +#define RES_REQ_RES 0x05 +#define RES_READ_WO_ENCRYPTION 0x07 +#define RES_WRITE_WO_ENCRYPTION 0x09 +#define RES_SEARCH_SVC_CODE 0x0B +#define RES_REQ_SYS_CODE 0x0D +#define RES_AUTH_1 0x11 +#define RES_AUTH_2 0x13 +#define RES_READ 0x15 +#define RES_WRITE 0x17 +#define RES_REQ_SVC_V2 0x33 +#define RES_REQ_SYS_STATUS 0x39 +#define RES_REQ_SPEC_VER 0x3D +#define RES_RESET_MODE 0x3F +#define RES_AUTH1_V2 0x41 +#define RES_AUTH2_V2 0x43 +#define RES_READ_V2 0x45 +#define RES_WRITE_V2 0x47 +#define RES_REQ_UPDATE_RAND_ID 0x4D + +/* - Request Codes - */ +#define RC_NO_REQ 0x00 +#define RC_SYS_REQ 0x01 +#define RC_COM_PERF_REQ 0x02 + +/* - System Codes - */ + +/* FeliCa Lite/DFC */ +#define SC_FELICA_LITE 0x88b4 + +/* NFC Forum NDEF */ +#define SC_NFC_FORUM 0x12fc + +/* FeliCa Networks' Common Area */ +#define SC_FELICA_NW_COMMON_AREA 0xfe00 + +/* FeliCa Plug (NFC Dynamic Tag) */ +#define SC_FELICA_PLUG 0xfee1 + +/* Japanese transit card */ +#define SC_IRUCA 0xde80 + +/* "...return a response to the Polling command, regardless + of its System Code" */ + +#define SC_DOUBLE_WILDCARD 0xffff + +static const value_string felica_opcodes[] = { + /* Commands */ + {CMD_POLLING, "Polling"}, + {CMD_REQ_SVC, "Request Service"}, + {CMD_REQ_RES, "Request Response"}, + {CMD_READ_WO_ENCRYPTION, "Read Without Encryption"}, + {CMD_WRITE_WO_ENCRYPTION, "Write Without Encryption"}, + {CMD_SEARCH_SVC_CODE, "Search Service Code"}, + {CMD_REQ_SYS_CODE, "Request System Code"}, + {CMD_AUTH_1, "Authentication1"}, + {CMD_AUTH_2, "Authentication2"}, + {CMD_READ, "Read"}, + {CMD_WRITE, "Write"}, + {CMD_REQ_SVC_V2, "Request Service v2"}, + {CMD_REQ_SYS_STATUS, "Get System Status"}, + {CMD_REQ_SPEC_VER, "Request Specification Version"}, + {CMD_RESET_MODE, "Reset Mode"}, + {CMD_AUTH1_V2, "Authentication1 v2"}, + {CMD_AUTH2_V2, "Authentication2 v2"}, + {CMD_READ_V2, "Read v2"}, + {CMD_WRITE_V2, "Write v2"}, + {CMD_REQ_UPDATE_RAND_ID, "Update Random ID"}, + /* End of commands */ + + /* Responses */ + {RES_POLLING, "Polling (Response)"}, + {RES_REQ_SVC, "Request Service (Response)"}, + {RES_REQ_RES, "Request Response (Response)"}, + {RES_READ_WO_ENCRYPTION, "Read Without Encryption (Response)"}, + {RES_WRITE_WO_ENCRYPTION, "Write Without Encryption (Response)"}, + {RES_SEARCH_SVC_CODE, "Search Service Code (Response)"}, + {RES_REQ_SYS_CODE, "Request System Code (Response)"}, + {RES_AUTH_1, "Authentication1 (Response)"}, + {RES_AUTH_2, "Authentication2 (Response)"}, + {RES_READ, "Read (Response)"}, + {RES_WRITE, "Write (Response)"}, + {RES_REQ_SVC_V2, "Request Service v2 (Response)"}, + {RES_REQ_SYS_STATUS, "Get System Status (Response)"}, + {RES_REQ_SPEC_VER, "Request Specification Version (Response)"}, + {RES_RESET_MODE, "Reset Mode (Response)"}, + {RES_AUTH1_V2, "Authentication1 v2 (Response)"}, + {RES_AUTH2_V2, "Authentication2 v2 (Response)"}, + {RES_READ_V2, "Read v2 (Response)"}, + {RES_WRITE_V2, "Write v2 (Response)"}, + {RES_REQ_UPDATE_RAND_ID, "Update Random ID"}, + /* End of responses */ + + {0x00, NULL} +}; + +static const value_string felica_req_codes[] = { + {RC_NO_REQ, "No Request"}, + {RC_SYS_REQ, "System Code Request"}, + {RC_COM_PERF_REQ, "Communication Performance Request"}, + + /* Others are reserved for future use */ + + /* End of request codes */ + {0x00, NULL} +}; + +static const value_string felica_sys_codes[] = { + {SC_FELICA_LITE, "FeliCa Lite"}, + {SC_FELICA_PLUG, "FeliCa Plug (NFC Dynamic Tag)"}, + {SC_NFC_FORUM, "NFC Forum (NDEF)"}, + {SC_FELICA_NW_COMMON_AREA, "FeliCa Networks Common Area"}, + {SC_IRUCA, "IruCa"}, + {SC_DOUBLE_WILDCARD, "Wildcard"}, + + /* End of system codes */ + {0x00, NULL} +}; + +/* Subtree handles: set by register_subtree_array */ +static gint ett_felica = -1; + +static int dissect_felica(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + proto_item *item; + proto_tree *felica_tree; + guint8 opcode; + guint8 rwe_pos = 0; + tvbuff_t *rwe_resp_data_tvb; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "FeliCa"); + + /* Start with a top-level item to add everything else to */ + item = proto_tree_add_item(tree, proto_felica, tvb, 0, -1, ENC_NA); + felica_tree = proto_item_add_subtree(item, ett_felica); + + opcode = tvb_get_guint8(tvb, 0); + col_set_str(pinfo->cinfo, COL_INFO, + val_to_str_const(opcode, felica_opcodes, "Unknown")); + + proto_tree_add_item(felica_tree, hf_felica_opcode, tvb, 0, 1, ENC_BIG_ENDIAN); + + switch (opcode) { + + case CMD_POLLING: + if (tree) { + proto_tree_add_item(felica_tree, hf_felica_sys_code, tvb, 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(felica_tree, hf_felica_req_code, tvb, 3, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(felica_tree, hf_felica_timeslot, tvb, 4, 1, ENC_BIG_ENDIAN); + } + break; + + case RES_POLLING: + if (tree) { + proto_tree_add_item(felica_tree, hf_felica_idm, tvb, 1, 8, ENC_BIG_ENDIAN); + proto_tree_add_item(felica_tree, hf_felica_pnm, tvb, 9, 8, ENC_BIG_ENDIAN); + + if (tvb_reported_length(tvb) == 19) + proto_tree_add_item(felica_tree, hf_felica_sys_code, tvb, 17, 2, ENC_BIG_ENDIAN); + + /* + * Request data - 0 or 2 bytes long; data corresponding to request + * code; only if request code of command packet is not 00 and + * corresponds to request data + */ + } + break; + + case CMD_REQ_SVC: + /* TODO */ + break; + + case RES_REQ_SVC: + /* TODO */ + break; + + case CMD_REQ_RES: + /* TODO */ + break; + + case RES_REQ_RES: + /* TODO */ + break; + + case CMD_READ_WO_ENCRYPTION: + if (tree) { + proto_tree_add_item(felica_tree, hf_felica_idm, tvb, 1, 8, ENC_BIG_ENDIAN); + proto_tree_add_item(felica_tree, hf_felica_nbr_of_svcs, tvb, 9, 1, ENC_BIG_ENDIAN); + + /* Service codes are always 2 bytes in length */ + + /* There can technically be multiple Service Codes - although my traces only contain 1 */ + proto_tree_add_item(felica_tree, hf_felica_svc_code, tvb, 10, 2, ENC_BIG_ENDIAN); + + /* Number of Blocks - 1byte */ + proto_tree_add_item(felica_tree, hf_felica_nbr_of_blocks, tvb, 12, 1, ENC_BIG_ENDIAN); + + /* Iterate through the block list, and update the tree */ + for (rwe_pos = 0; rwe_pos < tvb_get_guint8(tvb, 12); rwe_pos++) { + proto_tree_add_item(felica_tree, hf_felica_block_nbr, tvb, + 13 + 2 * rwe_pos, 2, ENC_NA); + } + } + break; + + case RES_READ_WO_ENCRYPTION: + if (tree) { + proto_tree_add_item(felica_tree, hf_felica_idm, tvb, 1, 8, ENC_BIG_ENDIAN); + proto_tree_add_item(felica_tree, hf_felica_status_flag1, tvb, 9, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(felica_tree, hf_felica_status_flag2, tvb, 10, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(felica_tree, hf_felica_nbr_of_blocks, tvb, 11, 1, ENC_BIG_ENDIAN); + } + rwe_resp_data_tvb = tvb_new_subset_remaining(tvb, 12); + call_data_dissector(rwe_resp_data_tvb, pinfo, tree); + break; + + case CMD_WRITE_WO_ENCRYPTION: + /* TODO */ + break; + + case RES_WRITE_WO_ENCRYPTION: + /* TODO */ + break; + + case CMD_SEARCH_SVC_CODE: + /* TODO */ + break; + + case RES_SEARCH_SVC_CODE: + /* TODO */ + break; + + case CMD_REQ_SYS_CODE: + /* TODO */ + break; + + case RES_REQ_SYS_CODE: + /* TODO */ + break; + + case CMD_AUTH_1: + /* TODO */ + break; + + case RES_AUTH_1: + /* TODO */ + break; + + case CMD_AUTH_2: + /* TODO */ + break; + + case RES_AUTH_2: + /* TODO */ + break; + + case CMD_READ: + /* TODO */ + break; + + case RES_READ: + /* TODO */ + break; + + case CMD_WRITE: + /* TODO */ + break; + + case RES_WRITE: + /* TODO */ + break; + + case CMD_REQ_SVC_V2: + /* TODO */ + break; + + case RES_REQ_SVC_V2: + /* TODO */ + break; + + case CMD_REQ_SYS_STATUS: + /* TODO */ + break; + + case RES_REQ_SYS_STATUS: + /* TODO */ + break; + + case CMD_REQ_SPEC_VER: + /* TODO */ + break; + + case RES_REQ_SPEC_VER: + /* TODO */ + break; + + case CMD_RESET_MODE: + /* TODO */ + break; + + case RES_RESET_MODE: + /* TODO */ + break; + + case CMD_AUTH1_V2: + /* TODO */ + break; + + case RES_AUTH1_V2: + /* TODO */ + break; + + case CMD_AUTH2_V2: + /* TODO */ + break; + + case RES_AUTH2_V2: + /* TODO */ + break; + + case CMD_READ_V2: + /* TODO */ + break; + + case RES_READ_V2: + /* TODO */ + break; + + case CMD_WRITE_V2: + /* TODO */ + break; + + case RES_WRITE_V2: + /* TODO */ + break; + + case CMD_REQ_UPDATE_RAND_ID: + /* TODO */ + break; + + case RES_REQ_UPDATE_RAND_ID: + /* TODO */ + break; + + default: + break; + } + return tvb_captured_length(tvb); +} + +void +proto_register_felica(void) +{ + static hf_register_info hf[] = { + + {&hf_felica_opcode, + { "Opcode", "felica.opcode", + FT_UINT8, BASE_HEX, VALS(felica_opcodes), 0x0, + NULL, HFILL } + }, + + /* Request Code */ + {&hf_felica_req_code, + { "Request Code", "felica.req.code", + FT_UINT8, BASE_HEX, VALS(felica_req_codes), 0x0, + NULL, HFILL } + }, + + {&hf_felica_idm, + { "IDm (Manufacture ID)/NFCID2", "felica.idm", + FT_UINT64, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + + /* System Code */ + {&hf_felica_sys_code, + { "System Code", "felica.sys_code", + FT_UINT16, BASE_HEX, VALS(felica_sys_codes), 0x0, + NULL, HFILL } + }, + + /* Service Code */ + {&hf_felica_svc_code, + { "Service Code", "felica.svc_code", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + + /* Parameter/PAD */ + {&hf_felica_pnm, + { "PNm (Manufacture Parameter)/PAD", "felica.pnm", + FT_UINT64, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + + /* Number of Services */ + {&hf_felica_nbr_of_svcs, + { "Number of Services", "felica.svcs", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + + /* Number of Blocks */ + {&hf_felica_nbr_of_blocks, + { "Number of Blocks", "felica.blocks", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + + /* Block ID */ + {&hf_felica_block_nbr, + { "Block Number", "felica.block.nbr", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + + /* Status Flag 1 */ + {&hf_felica_status_flag1, + { "Status Flag 1", "felica.status.flag1", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + + /* Status Flag 2 */ + {&hf_felica_status_flag2, + { "Status Flag 2", "felica.status.flag2", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + + /* Timeslot */ + {&hf_felica_timeslot, + { "Timeslot", "felica.timeslot", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + } + }; + + static gint *ett[] = { + &ett_felica + }; + + proto_felica = proto_register_protocol("Sony FeliCa", "FeliCa", "felica"); + proto_register_field_array(proto_felica, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + register_dissector("felica", dissect_felica, proto_felica); +} + +/* +* Editor modelines - https://www.wireshark.org/tools/modelines.html +* +* Local variables: +* c-basic-offset: 4 +* tab-width: 8 +* indent-tabs-mode: nil +* End: +* +* ex: set shiftwidth=4 tabstop=8 expandtab: +* :indentSize=4:tabSize=8:noTabs=true: +*/ |