aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-usb-masstorage.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-10-18 12:00:38 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-10-18 12:00:38 +0000
commitb3301320c1e427e634fd5019b3bccfc1c20a663e (patch)
tree070eaab0c57485b3c7120fe331d94d6336a6295c /epan/dissectors/packet-usb-masstorage.c
parent232e884ca140fd4146f1b96b4cfc6c3a5ae80c94 (diff)
add dissection of DATA IN/OUT and SCSI RESPONSE to the usb mass storage dissector
svn path=/trunk/; revision=19590
Diffstat (limited to 'epan/dissectors/packet-usb-masstorage.c')
-rw-r--r--epan/dissectors/packet-usb-masstorage.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/epan/dissectors/packet-usb-masstorage.c b/epan/dissectors/packet-usb-masstorage.c
index a02a79550c..81669d1dc2 100644
--- a/epan/dissectors/packet-usb-masstorage.c
+++ b/epan/dissectors/packet-usb-masstorage.c
@@ -41,6 +41,9 @@ static int hf_usb_ms_dCBWDataTransferLength = -1;
static int hf_usb_ms_dCBWFlags = -1;
static int hf_usb_ms_dCBWLUN = -1;
static int hf_usb_ms_dCBWCBLength = -1;
+static int hf_usb_ms_dCSWSignature = -1;
+static int hf_usb_ms_dCSWDataResidue = -1;
+static int hf_usb_ms_dCSWStatus = -1;
static gint ett_usb_ms = -1;
@@ -51,13 +54,21 @@ typedef struct _usb_ms_conv_info_t {
emem_tree_t *itlq; /* pinfo->fd->num */
} usb_ms_conv_info_t;
+
+static const value_string status_vals[] = {
+ {0x00, "Command Passed"},
+ {0x01, "Command Failed"},
+ {0x02, "Phase Error"},
+ {0, NULL}
+};
+
static void
dissect_usb_ms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
usb_conv_info_t *usb_conv_info;
usb_ms_conv_info_t *usb_ms_conv_info;
proto_tree *tree=NULL;
- guint32 signature;
+ guint32 signature=0;
int offset=0;
gboolean is_request;
itl_nexus_t *itl;
@@ -91,7 +102,11 @@ dissect_usb_ms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
signature=tvb_get_letohl(tvb, offset);
- /* is this a CDB ? */
+
+
+ /*
+ * SCSI CDB inside CBW
+ */
if(is_request&&(signature==0x43425355)&&(tvb_length(tvb)==31)){
tvbuff_t *cdb_tvb;
int cdbrlen, cdblen;
@@ -168,7 +183,68 @@ dissect_usb_ms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
cdb_tvb=tvb_new_subset(tvb, offset, cdblen, cdbrlen);
dissect_scsi_cdb(cdb_tvb, pinfo, parent_tree, SCSI_DEV_UNKNOWN, itlq, itl);
}
+ return;
+ }
+
+
+ /*
+ * SCSI RESPONSE inside CSW
+ */
+ if((!is_request)&&(signature==0x53425355)&&(tvb_length(tvb)==13)){
+ guint8 status;
+
+ /* dCSWSignature */
+ proto_tree_add_item(tree, hf_usb_ms_dCSWSignature, tvb, offset, 4, TRUE);
+ offset+=4;
+
+ /* dCSWTag */
+ proto_tree_add_item(tree, hf_usb_ms_dCBWTag, tvb, offset, 4, TRUE);
+ offset+=4;
+
+ /* dCSWDataResidue */
+ proto_tree_add_item(tree, hf_usb_ms_dCSWDataResidue, tvb, offset, 4, TRUE);
+ offset+=4;
+
+ /* dCSWStatus */
+ proto_tree_add_item(tree, hf_usb_ms_dCSWStatus, tvb, offset, 1, TRUE);
+ status=tvb_get_guint8(tvb, offset);
+ offset+=1;
+
+ itlq=(itlq_nexus_t *)se_tree_lookup32_le(usb_ms_conv_info->itlq, pinfo->fd->num);
+ if(!itlq){
+ return;
+ }
+ itlq->last_exchange_frame=pinfo->fd->num;
+
+ itl=(itl_nexus_t *)se_tree_lookup32(usb_ms_conv_info->itl, itlq->lun);
+ if(!itl){
+ return;
+ }
+
+ if(!status){
+ dissect_scsi_rsp(tvb, pinfo, parent_tree, itlq, itl, 0);
+ } else {
+ /* just send "check condition" */
+ dissect_scsi_rsp(tvb, pinfo, parent_tree, itlq, itl, 0x02);
+ }
+ return;
+ }
+
+ /*
+ * Ok it was neither CDB not STATUS so just assume it is either data in/out
+ */
+ itlq=(itlq_nexus_t *)se_tree_lookup32_le(usb_ms_conv_info->itlq, pinfo->fd->num);
+ if(!itlq){
+ return;
}
+
+ itl=(itl_nexus_t *)se_tree_lookup32(usb_ms_conv_info->itl, itlq->lun);
+ if(!itl){
+ return;
+ }
+
+ dissect_scsi_payload(tvb, pinfo, parent_tree, is_request, itlq, itl, 0);
+
}
void
@@ -199,6 +275,18 @@ proto_register_usb_ms(void)
{ "CDB Length", "usbms.dCBWCBLength", FT_UINT8, BASE_HEX,
NULL, 0x1f, "", HFILL }},
+ { &hf_usb_ms_dCSWSignature,
+ { "Signature", "usbms.dCSWSignature", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "", HFILL }},
+
+ { &hf_usb_ms_dCSWDataResidue,
+ { "DataResidue", "usbms.dCSWDataResidue", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "", HFILL }},
+
+ { &hf_usb_ms_dCSWStatus,
+ { "Status", "usbms.dCSWStatus", FT_UINT8, BASE_HEX,
+ VALS(status_vals), 0x0, "", HFILL }},
+
};
static gint *usb_ms_subtrees[] = {