aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-usb-ccid.c
diff options
context:
space:
mode:
authormorriss <morriss@f5534014-38df-0310-8fa8-9805f1628bb7>2012-06-20 13:30:07 +0000
committermorriss <morriss@f5534014-38df-0310-8fa8-9805f1628bb7>2012-06-20 13:30:07 +0000
commitc8391561bf16bde475344593e7987bc45c94944e (patch)
tree7f1ac290c1925812ef8d63c739a0e558ed2cd958 /epan/dissectors/packet-usb-ccid.c
parentade3bd548ae4b02c8cb9bb8344b9329997ed62d8 (diff)
Use separate filters for the RTT found on a SACK and the RTT found on a
DATA chunk: having them in both places is helpful when looking at the messages but having them separate is helpful when graphing the RTTs. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@43406 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-usb-ccid.c')
-rw-r--r--epan/dissectors/packet-usb-ccid.c320
1 files changed, 185 insertions, 135 deletions
diff --git a/epan/dissectors/packet-usb-ccid.c b/epan/dissectors/packet-usb-ccid.c
index c2f60fd46d..05e1d18040 100644
--- a/epan/dissectors/packet-usb-ccid.c
+++ b/epan/dissectors/packet-usb-ccid.c
@@ -146,7 +146,9 @@ static gint ett_ccid = -1;
/* Table of payload types - adapted from the I2C dissector */
enum {
SUB_DATA = 0,
+ SUB_ISO7816,
SUB_GSM_SIM,
+ SUB_PN532_ACS_PSEUDO_APDU,
SUB_MAX
};
@@ -167,167 +169,211 @@ dissect_ccid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBCCID");
col_set_str(pinfo->cinfo, COL_INFO, "CCID Packet");
- if (tree) {
- /* Start with a top-level item to add everything else to */
+ /* Start with a top-level item to add everything else to */
+ item = proto_tree_add_item(tree, proto_ccid, tvb, 0, -1, ENC_NA);
+ ccid_tree = proto_item_add_subtree(item, ett_ccid);
- item = proto_tree_add_item(tree, proto_ccid, tvb, 0, -1, ENC_NA);
- ccid_tree = proto_item_add_subtree(item, ett_ccid);
+ proto_tree_add_item(ccid_tree, hf_ccid_bMessageType, tvb, 0, 1, ENC_NA);
+ cmd = tvb_get_guint8(tvb, 0);
- proto_tree_add_item(ccid_tree, hf_ccid_bMessageType, tvb, 0, 1, ENC_NA);
- cmd = tvb_get_guint8(tvb, 0);
+ switch (cmd) {
- switch (cmd) {
+ case PC_RDR_SET_PARAMS:
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bProtocolNum, tvb, 7, 1, ENC_LITTLE_ENDIAN);
- case PC_RDR_SET_PARAMS:
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bProtocolNum, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ /* Placeholder for abRFU */
+ proto_tree_add_text(ccid_tree, tvb, 8, 2, "Reserved for Future Use");
- /* Placeholder for abRFU */
- proto_tree_add_text(ccid_tree, tvb, 8, 2, "Reserved for Future Use");
+ next_tvb = tvb_new_subset_remaining(tvb, 10);
+ call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, ccid_tree);
- next_tvb = tvb_new_subset_remaining(tvb, 10);
- call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, ccid_tree);
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Set Parameters");
+ break;
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Set Parameters");
- break;
+ case PC_RDR_ICC_ON:
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bPowerSelect, tvb, 7, 1, ENC_LITTLE_ENDIAN);
- case PC_RDR_ICC_ON:
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bPowerSelect, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ /* Placeholder for abRFU */
+ proto_tree_add_text(ccid_tree, tvb, 8, 2, "Reserved for Future Use");
- /* Placeholder for abRFU */
- proto_tree_add_text(ccid_tree, tvb, 8, 2, "Reserved for Future Use");
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: ICC Power On");
+ break;
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: ICC Power On");
- break;
+ case PC_RDR_ICC_OFF:
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- case PC_RDR_ICC_OFF:
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ /* Placeholder for abRFU */
+ proto_tree_add_text(ccid_tree, tvb, 7, 3, "Reserved for Future Use");
- /* Placeholder for abRFU */
- proto_tree_add_text(ccid_tree, tvb, 7, 3, "Reserved for Future Use");
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: ICC Power Off");
+ break;
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: ICC Power Off");
- break;
+ case PC_RDR_GET_SLOT_STATUS:
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- case PC_RDR_GET_SLOT_STATUS:
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ /* Placeholder for abRFU */
+ proto_tree_add_text(ccid_tree, tvb, 7, 3, "Reserved for Future Use");
- /* Placeholder for abRFU */
- proto_tree_add_text(ccid_tree, tvb, 7, 3, "Reserved for Future Use");
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Get Slot Status");
+ break;
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Get Slot Status");
- break;
+ case PC_RDR_SECURE:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Secure");
+ break;
- case PC_RDR_SECURE:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Secure");
- break;
+ case PC_RDR_T0APDU:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: T=0 APDU");
+ break;
- case PC_RDR_T0APDU:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: T=0 APDU");
- break;
+ case PC_RDR_ESCAPE:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Escape");
+ break;
- case PC_RDR_ESCAPE:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Escape");
- break;
+ case PC_RDR_GET_PARAMS:
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- case PC_RDR_GET_PARAMS:
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ /* Placeholder for abRFU */
+ proto_tree_add_text(ccid_tree, tvb, 7, 3, "Reserved for Future Use");
- /* Placeholder for abRFU */
- proto_tree_add_text(ccid_tree, tvb, 7, 3, "Reserved for Future Use");
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Get Parameters");
+ break;
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Get Parameters");
- break;
+ case PC_RDR_RESET_PARAMS:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Reset Parameters");
+ break;
- case PC_RDR_RESET_PARAMS:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Reset Parameters");
- break;
+ case PC_RDR_ICC_CLOCK:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: ICC Clock");
+ break;
- case PC_RDR_ICC_CLOCK:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: ICC Clock");
- break;
+ case PC_RDR_XFR_BLOCK:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Transfer Block");
- case PC_RDR_XFR_BLOCK:
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bBWI, tvb, 7, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_wLevelParameter, tvb, 8, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bBWI, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_wLevelParameter, tvb, 8, 2, ENC_LITTLE_ENDIAN);
- next_tvb = tvb_new_subset_remaining(tvb, 10);
+ next_tvb = tvb_new_subset_remaining(tvb, 10);
+ /* See if the dissector isn't Data */
if (sub_selected != SUB_DATA) {
- call_dissector(sub_handles[sub_selected], next_tvb, pinfo, tree);
- } else {
- call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree);
- }
-
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Transfer Block");
- break;
-
- case PC_RDR_MECH:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Mechanical");
- break;
-
- case PC_RDR_ABORT:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Abort");
- break;
-
- case PC_RDR_DATA_CLOCK:
- col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Set Data Rate and Clock Frequency");
- break;
-
- case RDR_PC_DATA_BLOCK:
- col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Data Block");
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bStatus, tvb, 7, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bError, tvb, 8, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bChainParameter, tvb, 9, 1, ENC_LITTLE_ENDIAN);
-
- next_tvb = tvb_new_subset_remaining(tvb, 10);
+
+ /* See if we're in PN532-with-ACS PseudoHeader Mode */
+ if (sub_selected == SUB_PN532_ACS_PSEUDO_APDU) {
+
+ /* See if the payload starts with 0xD4 (Host -> PN532) */
+ if (tvb_get_guint8(tvb, 15) == 0xD4) {
+
+ /* Skip the 5 byte ACS Pseudo-Header */
+ call_dissector(sub_handles[sub_selected], tvb_new_subset_remaining(tvb, 15), pinfo, tree);
+ }
+
+ else {
+
+ /* We've probably got an APDU addressed elsewhere */
+ call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree);
+ }
+ }
+
+ else if (sub_selected == SUB_ISO7816) {
+ /* sent/received is from the perspective of the card reader */
+ pinfo->p2p_dir = P2P_DIR_SENT;
+ call_dissector(sub_handles[SUB_ISO7816], next_tvb, pinfo, tree);
+ }
+
+ /* The user probably wanted GSM SIM, or something else */
+ else {
+ call_dissector(sub_handles[sub_selected], next_tvb, pinfo, tree);
+ }
+
+ }
+
+ /* The user only wants plain data */
+ else {
+ call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree);
+ }
+
+ break;
+
+ case PC_RDR_MECH:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Mechanical");
+ break;
+
+ case PC_RDR_ABORT:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Abort");
+ break;
+
+ case PC_RDR_DATA_CLOCK:
+ col_set_str(pinfo->cinfo, COL_INFO, "PC to Reader: Set Data Rate and Clock Frequency");
+ break;
+
+ case RDR_PC_DATA_BLOCK:
+ col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Data Block");
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bStatus, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bError, tvb, 8, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bChainParameter, tvb, 9, 1, ENC_LITTLE_ENDIAN);
+
+ next_tvb = tvb_new_subset_remaining(tvb, 10);
+
+ /* If the user has opted to use the PN532 dissector for PC -> Reader comms, then use it here */
+ if (sub_selected == SUB_PN532_ACS_PSEUDO_APDU && tvb_get_guint8(tvb, 10) == 0xD5) {
+ call_dissector(sub_handles[SUB_PN532_ACS_PSEUDO_APDU], next_tvb, pinfo, ccid_tree);
+ }
+
+ else if (sub_selected == SUB_ISO7816) {
+ pinfo->p2p_dir = P2P_DIR_RECV;
+ call_dissector(sub_handles[SUB_ISO7816], next_tvb, pinfo, tree);
+ }
+
+ else {
call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, ccid_tree);
- break;
-
- case RDR_PC_SLOT_STATUS:
- proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bStatus, tvb, 7, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bError, tvb, 8, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ccid_tree, hf_ccid_bClockStatus, tvb, 9, 1, ENC_LITTLE_ENDIAN);
-
- col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Slot Status");
- break;
-
- case RDR_PC_PARAMS:
- col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Parameters");
- break;
-
- case RDR_PC_ESCAPE:
- col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Escape");
- break;
-
- case RDR_PC_DATA_CLOCK:
- col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Data Rate and Clock Frequency");
- break;
-
- default:
- col_set_str(pinfo->cinfo, COL_INFO, "Unknown type");
- break;
}
+
+ break;
+
+ case RDR_PC_SLOT_STATUS:
+ proto_tree_add_item(ccid_tree, hf_ccid_dwLength, tvb, 1, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSlot, tvb, 5, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bSeq, tvb, 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bStatus, tvb, 7, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bError, tvb, 8, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ccid_tree, hf_ccid_bClockStatus, tvb, 9, 1, ENC_LITTLE_ENDIAN);
+
+ col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Slot Status");
+ break;
+
+ case RDR_PC_PARAMS:
+ col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Parameters");
+ break;
+
+ case RDR_PC_ESCAPE:
+ col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Escape");
+ break;
+
+ case RDR_PC_DATA_CLOCK:
+ col_set_str(pinfo->cinfo, COL_INFO, "Reader to PC: Data Rate and Clock Frequency");
+ break;
+
+ default:
+ col_set_str(pinfo->cinfo, COL_INFO, "Unknown type");
+ break;
}
}
@@ -381,16 +427,18 @@ proto_register_ccid(void)
static const enum_val_t sub_enum_vals[] = {
{ "data", "Data", SUB_DATA },
+ { "iso7816", "Generic ISO 7816", SUB_ISO7816 },
{ "gsm_sim", "GSM SIM", SUB_GSM_SIM },
+ { "pn532", "NXP PN532 with ACS Pseudo-Header", SUB_PN532_ACS_PSEUDO_APDU},
{ NULL, NULL, 0 }
};
-
+
module_t *pref_mod;
-
+
proto_ccid = proto_register_protocol("USB CCID", "USBCCID", "usbccid");
proto_register_field_array(proto_ccid, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
-
+
pref_mod = prefs_register_protocol(proto_ccid, NULL);
prefs_register_enum_preference(pref_mod, "prtype", "PC -> Reader Payload Type", "How commands from the PC to the reader are interpreted",
&sub_selected, sub_enum_vals, FALSE);
@@ -409,9 +457,11 @@ proto_reg_handoff_ccid(void)
usb_ccid_bulk_handle = find_dissector("usbccid");
dissector_add_uint("usb.bulk", IF_CLASS_SMART_CARD, usb_ccid_bulk_handle);
-
+
sub_handles[SUB_DATA] = find_dissector("data");
+ sub_handles[SUB_ISO7816] = find_dissector("iso7816");
sub_handles[SUB_GSM_SIM] = find_dissector("gsm_sim");
+ sub_handles[SUB_PN532_ACS_PSEUDO_APDU] = find_dissector("pn532");
}
/*