diff options
author | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2013-12-23 13:45:07 +0000 |
---|---|---|
committer | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2013-12-23 13:45:07 +0000 |
commit | 5742802a738bcb78847d0d36b9935baab87f6c52 (patch) | |
tree | ede3cd85acf33e67c8cea57eaf92bb91943f0c2f /epan | |
parent | 9d688a9fdec1344255b5bfc168b37715d00d8c04 (diff) |
From Yaniv Kaul via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9551
Dissect SCSI XCOPY and RECEIVE COPY Parameters commands
From me :
Fix encoding-args
Fix trailing whitespace
svn path=/trunk/; revision=54381
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-iscsi.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi-sbc.c | 5 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.c | 466 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.h | 3 |
4 files changed, 467 insertions, 9 deletions
diff --git a/epan/dissectors/packet-iscsi.c b/epan/dissectors/packet-iscsi.c index 093dca00a3..1cf84a717e 100644 --- a/epan/dissectors/packet-iscsi.c +++ b/epan/dissectors/packet-iscsi.c @@ -2625,7 +2625,7 @@ proto_register_iscsi(void) }, { &hf_iscsi_DataSegmentLength, { "DataSegmentLength", "iscsi.datasegmentlength", - FT_UINT32, BASE_HEX, NULL, 0, + FT_UINT32, BASE_DEC_HEX, NULL, 0, "Data segment length (bytes)", HFILL } }, { &hf_iscsi_TotalAHSLength, diff --git a/epan/dissectors/packet-scsi-sbc.c b/epan/dissectors/packet-scsi-sbc.c index 67c9fc375e..6da6471b6b 100644 --- a/epan/dissectors/packet-scsi-sbc.c +++ b/epan/dissectors/packet-scsi-sbc.c @@ -1245,7 +1245,7 @@ dissect_sbc_sanitize (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree_add_item (tree, hf_scsi_sbc_sanitize_pattern, tvb, offset+4, -1, - ENC_BIG_ENDIAN); + ENC_NA); } } @@ -1541,6 +1541,7 @@ static const value_string scsi_sbc_vals[] = { /* 0x81 */ {SCSI_SBC_REBUILD16 , "Rebuild(16)"}, /* 0x82 */ {SCSI_SBC_REGENERATE16 , "Regenerate(16)"}, /* 0x83 */ {SCSI_SPC_EXTCOPY , "Extended Copy"}, + /* 0x84 */ {SCSI_SPC_RECVCOPY , "Receive Copy"}, /* 0x88 */ {SCSI_SBC_READ16 , "Read(16)"}, /* 0x89 */ {SCSI_SBC_COMPARENWRITE , "Compare & Write(16)"}, /* 0x8A */ {SCSI_SBC_WRITE16 , "Write(16)"}, @@ -1697,7 +1698,7 @@ scsi_cdb_table_t scsi_sbc_table[256] = { /*SBC 0x81*/{NULL}, /*SBC 0x82*/{NULL}, /*SPC 0x83*/{dissect_spc_extcopy}, -/*SBC 0x84*/{NULL}, +/*SBC 0x84*/{dissect_spc_recvcopy}, /*SBC 0x85*/{NULL}, /*SBC 0x86*/{NULL}, /*SBC 0x87*/{NULL}, diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c index 821037ae37..60b3bb1783 100644 --- a/epan/dissectors/packet-scsi.c +++ b/epan/dissectors/packet-scsi.c @@ -84,6 +84,7 @@ #include <glib.h> #include <epan/packet.h> #include <epan/strutil.h> +#include <epan/to_str.h> #include <epan/prefs.h> #include <epan/wmem/wmem.h> #include <epan/conversation.h> @@ -669,6 +670,58 @@ static int hf_scsi_ssc2_modepage_rewind_on_reset = -1; static int hf_scsi_mmc5_modepage_upc = -1; static int hf_scsi_ssc2_modepage_idp = -1; static int hf_scsi_ssc2_modepage_perswp = -1; +static int hf_scsi_spc_xcopy_service = -1; +static int hf_scsi_spc_recv_copy_service = -1; +static int hf_scsi_spc_xcopy_param_list_len = -1; +static int hf_scsi_spc_xcopy_param_list_format = -1; +static int hf_scsi_spc_xcopy_cscd_desc_list_len = -1; +static int hf_scsi_spc_xcopy_head_cscd_desc_list_len = -1; +static int hf_scsi_spc_xcopy_head_cscd_desc_type_code = -1; +static int hf_scsi_spc_xcopy_cscd_desc_type_code = -1; +static int hf_scsi_spc_xcopy_inline_data_len = -1; +static int hf_scsi_spc_xcopy_seg_desc_list_len = -1; +static int hf_scsi_spc_xcopy_list_id = -1; +static int hf_scsi_spc_xcopy_rel_init_port_id = -1; +static int hf_scsi_spc_xcopy_per_dev_type_byte = -1; +static int hf_scsi_spc_xcopy_per_dev_type = -1; +static int hf_scsi_spc_xcopy_lu_type = -1; +static int hf_scsi_spc_xcopy_disk_block_len = -1; +static int hf_scsi_spc_xcopy_cscd_desc_code_set = -1; +static int hf_scsi_spc_xcopy_cscd_desc_assoc = -1; +static int hf_scsi_spc_xcopy_cscd_desc_des_type = -1; +static int hf_scsi_spc_xcopy_cscd_desc_des_len = -1; +static int hf_scsi_spc_xcopy_seg_desc_type = -1; +static int hf_scsi_spc_xcopy_seg_desc_dc = -1; +static int hf_scsi_spc_xcopy_seg_desc_cat = -1; +static int hf_scsi_spc_xcopy_seg_des_src_desc_id = -1; +static int hf_scsi_spc_xcopy_seg_des_dest_desc_id = -1; +static int hf_scsi_spc_xcopy_num_of_blocks = -1; +static int hf_scsi_spc_xcopy_param_list_id_usage = -1; +static int hf_scsi_spc_xcopy_param_str = -1; +static int hf_scsi_spc_xcopy_param_priority = -1; +static int hf_scsi_spc_xcopy_param_byte = -1; +static int hf_scsi_spc_xcopy_source_lba = -1; +static int hf_scsi_spc_xcopy_dest_lba = -1; +static int hf_scsi_recv_copy_max_cscd_desc_count = -1; +static int hf_scsi_recv_copy_max_seg_desc_count = -1; +static int hf_scsi_recv_copy_max_desc_list_len = -1; +static int hf_scsi_recv_copy_max_seg_len = -1; +static int hf_scsi_recv_copy_max_inline_data_len = -1; +static int hf_scsi_recv_copy_held_data_limit = -1; +static int hf_scsi_recv_copy_max_stream_dev_trans_size = -1; +static int hf_scsi_recv_copy_snlid = -1; +static int hf_scsi_recv_copy_avail_data = -1; +static int hf_scsi_recv_copy_total_con_copies = -1; +static int hf_scsi_recv_copy_max_con_copies = -1; +static int hf_scsi_recv_copy_data_seg_gran = -1; +static int hf_scsi_recv_copy_inline_data_gran = -1; +static int hf_scsi_recv_copy_held_data_gran = -1; +static int hf_scsi_recv_copy_implemented_desc_list_len = -1; +static int hf_scsi_reserved_8 = -1; +static int hf_scsi_reserved_16 = -1; +static int hf_scsi_reserved_24 = -1; +static int hf_scsi_reserved_32 = -1; +static int hf_scsi_reserved_64 = -1; static gint ett_scsi = -1; static gint ett_scsi_page = -1; @@ -694,6 +747,14 @@ static gint ett_timeout_descriptor = -1; static gint ett_sense_descriptor = -1; static gint ett_sense_osd_not_initiated = -1; static gint ett_sense_osd_completed = -1; +static gint ett_xcopy_per_dev_type = -1; +static gint ett_xcopy_param_byte = -1; +static gint ett_scsi_xcopy_cscds = -1; +static gint ett_scsi_xcopy_cscd = -1; +static gint ett_scsi_xcopy_dev_params = -1; +static gint ett_scsi_xcopy_segs = -1; +static gint ett_scsi_xcopy_seg = -1; +static gint ett_scsi_xcopy_seg_param = -1; /* Generated from convert_proto_tree_add_text.pl */ static expert_field ei_scsi_unknown_scsi_exchange = EI_INIT; @@ -784,6 +845,7 @@ static const value_string scsi_spc_vals[] = { /* 0x5F */ {SCSI_SPC_PERSRESVOUT , "Persistent Reserve Out"}, /* 0x7F */ {SCSI_SPC_VARLENCDB , "Variable Length CDB"}, /* 0x83 */ {SCSI_SPC_EXTCOPY , "Extended Copy"}, + /* 0x84 */ {SCSI_SPC_RECVCOPY , "Receive Copy"}, /* 0x84 */ {SCSI_SPC_RCVCOPYRESULTS , "Receive Copy Results"}, /* 0x86 */ {SCSI_SPC_ACCESS_CONTROL_IN , "Access Control In"}, /* 0x87 */ {SCSI_SPC_ACCESS_CONTROL_OUT , "Access Control Out"}, @@ -2967,6 +3029,13 @@ dissect_spc_inq_reladrflags(tvbuff_t *tvb, int offset, proto_tree *tree, int ver return offset; } +static const int *peripheral_fields[] = { + &hf_scsi_inq_qualifier, + &hf_scsi_inq_devtype, + NULL +}; + + void dissect_spc_inquiry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gboolean isreq, @@ -2985,11 +3054,6 @@ dissect_spc_inquiry(tvbuff_t *tvb, packet_info *pinfo, &hf_scsi_inq_control_obs2, NULL }; - static const int *peripheral_fields[] = { - &hf_scsi_inq_qualifier, - &hf_scsi_inq_devtype, - NULL - }; static const int *aca_fields_spc[] = { &hf_scsi_inq_aerc, /* obsolete in spc3 and forward */ &hf_scsi_inq_trmtsk,/* obsolete in spc2 and forward */ @@ -3148,15 +3212,344 @@ dissect_spc_inquiry(tvbuff_t *tvb, packet_info *pinfo, } } +#define XCOPY_LID1 0 +#define XCOPY_LID4 1 +static const value_string extcopy_service_vals[] = { + { XCOPY_LID1, "Extended Copy (LID1)" }, + { XCOPY_LID4, "Extended Copy (LID4)" }, + { 0, NULL } +}; + +#define RECV_COPY_PARAMS 0x3 +static const value_string recv_copy_service_vals[] = { + { 0x6, "Receive Copy Data (LID4)" }, + { 0x1, "Receive Copy Data (LID1)" }, + { RECV_COPY_PARAMS, "Receive Copy Parameters" }, + { 0x4, "Receive Copy Failure details" }, + { 0x5, "Receive Copy Status (LID4)" }, + { 0x0, "Receive Copy Status (LID1)" }, + { 0, NULL } +}; + + +static const value_string cscd_desc_type_code_vals[] = { + { 0xE0, "Fibre Channel N_Port_Name CSCD descriptor" }, + { 0xE1, "Fibre Channel N_Port_ID CSCD descriptor" }, + { 0xE2, "Fibre Channel N_Port_ID With N_Port_Name Checking CSCD descriptor" }, + { 0xE3, "Parallel Interface T_L CSCD descriptor" }, + { 0xE4, "Identification Descriptor CSCD descriptor" }, + { 0xFF, "Extension descriptor" }, + { 0, NULL } +}; + +static const int *per_dev_type_bitmask_fields[] = { + &hf_scsi_spc_xcopy_lu_type, + &hf_scsi_spc_xcopy_per_dev_type, + NULL +}; + +static const int *xcopy_param_list_bits[] = { + &hf_scsi_spc_xcopy_param_str, + &hf_scsi_spc_xcopy_param_list_id_usage, + &hf_scsi_spc_xcopy_param_priority, + NULL +}; + +#define BLOCK_DEV_0 0x0 +#define BLOCK_DEV_4 0x4 +#define BLOCK_DEV_5 0x5 +#define BLOCK_DEV_7 0x7 +#define BLOCK_DEV_E 0xE + +static const value_string per_dev_type_vals[] = { + { BLOCK_DEV_0, "Block devices" }, + { 0x1, "Sequential access devices" }, + { 0x3, "Processor devices" }, + { BLOCK_DEV_4, "Block devices" }, + { BLOCK_DEV_5, "Block devices" }, + { BLOCK_DEV_7, "Block devices" }, + { BLOCK_DEV_E, "Block devices" }, + { 0, NULL } +}; + +static const value_string lu_type_vals[] = { + { 0, "Logical Unit Number" }, + { 1, "Proxy Token" }, + { 2, "Reserved" }, + { 3, "Reserved" }, + { 0, NULL } +}; + +#define BLOCK_TO_BLOCK 2 + +static const range_string desc_type_rval[] = { + { 0x0, 0x0, "Block to stream" }, + { 0x1, 0x1, "Stream to block" }, + { BLOCK_TO_BLOCK, BLOCK_TO_BLOCK, "Block to block" }, + { 0x3, 0x3, "Stream to stream" }, + { 0x4, 0x4, "Inline to stream" }, + { 0x5, 0x5, "Embedded to strem" }, + { 0x6, 0x6, "Stream to discard" }, + { 0x7, 0x7, "Verify CSCD" }, + { 0x0, 0xBF, "Segment descriptors" }, + { 0xC, 0xDF, "Vendor-specific descriptors" }, + { 0xE0, 0xE0, "Fibre Channel N_Port_Name CSCD descriptor" }, + { 0xE1, 0xE1, "Fibre Channel N_Port_ID CSCD descriptor" }, + { 0xE2, 0xE2, "Fibre Channel N_Port_ID With N_Port_Name Checking CSCD descriptor" }, + { 0xE3, 0xE3, "Parallel Interface T_L CSCD descriptor" }, + { 0xE4, 0xE4, "Identification Descriptor CSCD descriptor" }, + { 0xE5, 0xFE, "CSCD descriptors" }, + { 0xFF, 0xFF, "CSCD descriptor extension" }, + { 0, 0, NULL } +}; + void dissect_spc_extcopy(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint offset _U_, gboolean isreq _U_, gboolean iscdb _U_, guint payload_len _U_, scsi_task_data_t *cdata _U_) { + guint8 serv_action, cscd_desc_type, dev_type, des_len, code_set, des_type, seg_type; + guint16 cscd_desc_list_len, seg_desc_len; + guint32 param_list_len, seg_desc_list_len, inline_data_len, i; + proto_tree *cscds_tree = NULL, *dev_tree = NULL, *cscd_tree = NULL, *segs_tree = NULL, *seg_tree = NULL, *seg_param_tree = NULL; + proto_item *ti; + + if (isreq && iscdb) { + proto_tree_add_item(tree, hf_scsi_spc_xcopy_service, tvb, offset, 1, ENC_NA); + serv_action = tvb_get_guint8(tvb, offset) & 0x1F; + if (cdata) { + cdata->itlq->flags = serv_action; + } + offset += 1; + + proto_tree_add_item(tree, hf_scsi_reserved_64, tvb, offset, 8, ENC_NA); + offset += 8; + proto_tree_add_item(tree, hf_scsi_spc_xcopy_param_list_len, tvb, offset, 4, ENC_BIG_ENDIAN); + param_list_len = tvb_get_ntohl(tvb, offset); + offset += 4; + + proto_tree_add_item(tree, hf_scsi_reserved_8, tvb, offset, 1, ENC_NA); + offset+= 1; + proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_control, + ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN); + offset += 1; + offset += (param_list_len - 15); + } else { + if (cdata) { + serv_action = cdata->itlq->flags; + } + else { + return; + } + if (serv_action == XCOPY_LID1){ + proto_tree_add_item(tree, hf_scsi_spc_xcopy_list_id, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_spc_xcopy_param_byte, ett_xcopy_param_byte, xcopy_param_list_bits, ENC_NA); + offset += 1; + proto_tree_add_item(tree, hf_scsi_spc_xcopy_cscd_desc_list_len, tvb, offset, 2, ENC_BIG_ENDIAN); + cscd_desc_list_len = tvb_get_ntohs(tvb, offset); + offset += 2; + proto_tree_add_item(tree, hf_scsi_reserved_32, tvb, offset, 4, ENC_NA); + offset += 4; + proto_tree_add_item(tree, hf_scsi_spc_xcopy_seg_desc_list_len, tvb, offset, 4, ENC_BIG_ENDIAN); + seg_desc_list_len = tvb_get_ntohl(tvb, offset); + offset += 4; + proto_tree_add_item(tree, hf_scsi_spc_xcopy_inline_data_len, tvb, offset, 4, ENC_BIG_ENDIAN); + inline_data_len = tvb_get_ntohl(tvb, offset); + offset += 4; + if (cscd_desc_list_len > 0) { + ti = proto_tree_add_text(tree, tvb, offset, cscd_desc_list_len, "CSCD (Copy Source and Copy Destination) descriptors (%u bytes)", cscd_desc_list_len); + cscds_tree = proto_item_add_subtree(ti, ett_scsi_xcopy_cscds); + i = 1; + while(cscd_desc_list_len > 0) { + cscd_desc_type = tvb_get_guint8(tvb, offset); + if (cscd_desc_type == 0xEA || cscd_desc_type == 0xEB) { /* both types occupy 64 bytes overall, everything else is 32 bytes */ + ti = proto_tree_add_text(cscds_tree, tvb, offset, 64, "CSCD descriptor #%u", i); + } else { + ti = proto_tree_add_text(cscds_tree, tvb, offset, 32, "CSCD descriptor #%u", i); + } + i++; + cscd_tree = proto_item_add_subtree(ti, ett_scsi_xcopy_cscd); + proto_tree_add_item(cscd_tree, hf_scsi_spc_xcopy_cscd_desc_type_code, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_bitmask(cscd_tree, tvb, offset, hf_scsi_spc_xcopy_per_dev_type_byte, ett_xcopy_per_dev_type, per_dev_type_bitmask_fields, ENC_NA); + dev_type = tvb_get_guint8(tvb, offset) & 0x1F; + offset += 1; + proto_tree_add_item(cscd_tree, hf_scsi_spc_xcopy_rel_init_port_id, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_text(cscd_tree, tvb, offset, 24, "CSCD descriptor parameters"); + proto_tree_add_item(cscd_tree, hf_scsi_spc_xcopy_cscd_desc_code_set, tvb, offset, 1, ENC_NA); + code_set = tvb_get_guint8(tvb, offset) & 0x0F; + offset += 1; + proto_tree_add_item(cscd_tree, hf_scsi_spc_xcopy_cscd_desc_assoc, tvb, offset, 1, ENC_NA); + proto_tree_add_item(cscd_tree, hf_scsi_spc_xcopy_cscd_desc_des_type, tvb, offset, 1, ENC_NA); + des_type = tvb_get_guint8(tvb, offset) & 0x0F; + offset += 1; + proto_tree_add_item(cscd_tree, hf_scsi_reserved_8, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(cscd_tree, hf_scsi_spc_xcopy_cscd_desc_des_len, tvb, offset, 1, ENC_NA); + des_len = tvb_get_guint8(tvb, offset); + offset += 1; + proto_tree_add_text(cscd_tree, tvb, offset, 20, "Designator (20 bytes, zero padded, used length %u)", des_len); + if (code_set == CODESET_BINARY && des_type == 3) { /* des_type 3 = WWN */ + proto_tree_add_text(cscd_tree, tvb, offset, 8, "WWN: %s", tvb_fcwwn_to_str(tvb, offset)); + } + offset += 20; + ti = proto_tree_add_text(cscd_tree, tvb, offset, 4, "Device type specific parameters"); + dev_tree = proto_item_add_subtree(ti, ett_scsi_xcopy_dev_params); + if (dev_type == BLOCK_DEV_0 || dev_type == BLOCK_DEV_4 || dev_type == BLOCK_DEV_5 || dev_type == BLOCK_DEV_7 || dev_type == BLOCK_DEV_E) { + proto_tree_add_text(dev_tree, tvb, offset, 1, "Reserved|PAD|Reserved"); + offset += 1; /*TODO: dissect this byte */ + proto_tree_add_item(dev_tree, hf_scsi_spc_xcopy_disk_block_len, tvb, offset, 3, ENC_BIG_ENDIAN); + offset += 3; + } else { + offset += 4; + } + cscd_desc_list_len -= 32; + if (cscd_desc_type == 0xEA || cscd_desc_type == 0xEB) { /* both types occupy 64 bytes overall, everything else is 32 bytes */ + offset += 32; + cscd_desc_list_len -= 32; + } + } + } + if (seg_desc_list_len > 0) { + ti = proto_tree_add_text(tree, tvb, offset, seg_desc_list_len, "Segment descriptor list (%u bytes)", seg_desc_list_len); + segs_tree = proto_item_add_subtree(ti, ett_scsi_xcopy_segs); + i = 1; + while(seg_desc_list_len > 0) { + seg_desc_len = tvb_get_ntohs(tvb, offset + 2); + ti = proto_tree_add_text(segs_tree, tvb, offset, seg_desc_len + 4, "Segment descriptor #%u", i); + i++; + seg_tree = proto_item_add_subtree(ti, ett_scsi_xcopy_seg); + proto_tree_add_item(seg_tree, hf_scsi_spc_xcopy_seg_desc_type, tvb, offset, 1, ENC_NA); + seg_type = tvb_get_guint8(tvb, offset); + offset += 1; + proto_tree_add_item(seg_tree, hf_scsi_spc_xcopy_seg_desc_dc, tvb, offset, 1, ENC_NA); + proto_tree_add_item(seg_tree, hf_scsi_spc_xcopy_seg_desc_cat, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_text(seg_tree, tvb, offset, 2, "Segment descriptor length (bytes): %u", seg_desc_len); + offset += 2; + proto_tree_add_item(seg_tree, hf_scsi_spc_xcopy_seg_des_src_desc_id, tvb, offset, 2, ENC_NA); + offset += 2; + proto_tree_add_item(seg_tree, hf_scsi_spc_xcopy_seg_des_dest_desc_id, tvb, offset, 2, ENC_NA); + offset += 2; + ti = proto_tree_add_text(seg_tree, tvb, offset, seg_desc_len - 4, "Segment descriptor parameters"); + seg_param_tree = proto_item_add_subtree(ti, ett_scsi_xcopy_seg_param); + seg_desc_list_len -= (seg_desc_len + 4); + if (seg_type == BLOCK_TO_BLOCK) { + proto_tree_add_item(seg_param_tree, hf_scsi_reserved_16, tvb, offset, 2, ENC_NA); + offset += 2; + proto_tree_add_item(seg_param_tree, hf_scsi_spc_xcopy_num_of_blocks, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(seg_param_tree, hf_scsi_spc_xcopy_source_lba, tvb, offset, 8, ENC_BIG_ENDIAN); + offset += 8; + proto_tree_add_item(seg_param_tree, hf_scsi_spc_xcopy_dest_lba, tvb, offset, 8, ENC_BIG_ENDIAN); + offset += 8; + } else { + offset += (seg_desc_len - 4); + } + } + } + if (inline_data_len > 0) { + proto_tree_add_text(tree, tvb, offset, inline_data_len, "Inline data (%u bytes)", inline_data_len); + offset += inline_data_len; + } + } else if (serv_action == XCOPY_LID4) { + proto_tree_add_item(tree, hf_scsi_spc_xcopy_param_list_format, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_spc_xcopy_param_byte, ett_xcopy_param_byte, xcopy_param_list_bits, ENC_NA); + offset += 1; + proto_tree_add_item(tree, hf_scsi_spc_xcopy_head_cscd_desc_list_len, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_scsi_spc_xcopy_head_cscd_desc_type_code, tvb, offset, 1, ENC_NA); + offset += 1; + } + } + +} + +void dissect_spc_recvcopy(tvbuff_t *tvb _U_, packet_info *pinfo _U_, + proto_tree *tree _U_, guint offset _U_, + gboolean isreq _U_, gboolean iscdb _U_, + guint payload_len _U_, scsi_task_data_t *cdata _U_) +{ + guint8 serv_action, imp_desc_list_len; + if (isreq && iscdb) { + proto_tree_add_item(tree, hf_scsi_spc_recv_copy_service, tvb, offset, 1, ENC_NA); + serv_action = tvb_get_guint8(tvb, offset) & 0x1F; + if (cdata) { + cdata->itlq->flags = serv_action; + } + offset += 1; + proto_tree_add_item(tree, hf_scsi_reserved_64, tvb, offset, 8, ENC_NA); + offset += 8; + proto_tree_add_item(tree, hf_scsi_alloclen32, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_scsi_reserved_8, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_control, + ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN); + offset += 1; + + } else { + if (cdata) { + serv_action = cdata->itlq->flags; + } + else { + return; + } + if (serv_action == RECV_COPY_PARAMS) { + proto_tree_add_item(tree, hf_scsi_recv_copy_avail_data, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_scsi_recv_copy_snlid, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(tree, hf_scsi_reserved_24, tvb, offset, 3, ENC_NA); + offset += 3; + proto_tree_add_item(tree, hf_scsi_recv_copy_max_cscd_desc_count, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_scsi_recv_copy_max_seg_desc_count, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_scsi_recv_copy_max_desc_list_len, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_scsi_recv_copy_max_seg_len, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_scsi_recv_copy_max_inline_data_len, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_scsi_recv_copy_held_data_limit, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_scsi_recv_copy_max_stream_dev_trans_size, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_scsi_reserved_16, tvb, offset, 2, ENC_NA); + offset += 2; + proto_tree_add_item(tree, hf_scsi_recv_copy_total_con_copies, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_scsi_recv_copy_max_con_copies, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(tree, hf_scsi_recv_copy_data_seg_gran, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(tree, hf_scsi_recv_copy_inline_data_gran, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(tree, hf_scsi_recv_copy_held_data_gran, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(tree, hf_scsi_reserved_24, tvb, offset, 3, ENC_NA); + offset += 3; + proto_tree_add_item(tree, hf_scsi_recv_copy_implemented_desc_list_len, tvb, offset, 1, ENC_NA); + imp_desc_list_len = tvb_get_guint8(tvb, offset); + offset += 1; + while (imp_desc_list_len > 0) { + proto_tree_add_item(tree, hf_scsi_spc_xcopy_cscd_desc_type_code, tvb, offset, 1, ENC_NA); + offset += 1; + imp_desc_list_len--; + } + } else { + proto_tree_add_text(tree, tvb, offset, 0, "Unknown serv_action %u", serv_action); + } + } } + static int dissect_scsi_log_page(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset) @@ -5328,7 +5721,7 @@ static scsi_cdb_table_t spc[256] = { /*SPC 0x81*/{NULL}, /*SPC 0x82*/{NULL}, /*SPC 0x83*/{dissect_spc_extcopy}, - /*SPC 0x84*/{NULL}, + /*SPC 0x84*/{dissect_spc_recvcopy}, /*SPC 0x85*/{NULL}, /*SPC 0x86*/{NULL}, /*SPC 0x87*/{NULL}, @@ -6934,6 +7327,59 @@ proto_register_scsi(void) { &hf_scsi_smc_modepage_dt_ne_mt, { "DT<>MT", "scsi.mode.smc.dt_ne_mt", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }}, { &hf_scsi_sns_eom, { "EOM", "scsi.sns.eom", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }}, { &hf_scsi_sns_ili, { "ILI", "scsi.sns.ili", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_service, { "Service action", "scsi.extcopy.service_action", FT_UINT8, BASE_HEX, VALS(extcopy_service_vals), 0x0, NULL, HFILL }}, + { &hf_scsi_spc_recv_copy_service, { "Service action", "scsi.recv_copy.service_action", FT_UINT8, BASE_HEX, VALS(recv_copy_service_vals), 0x1F, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_param_list_len, { "Parameter list length (bytes)", "scsi.extcopy.param_list_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_param_list_format, { "List format", "scsi.extcopy.list_format", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_head_cscd_desc_list_len, { "Header cscd descriptor list length", "scsi.extcopy.hdr_cscd_list_len", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_cscd_desc_list_len, { "CSCD descriptor list length", "scsi.extcopy.cscd_list_len", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_inline_data_len, { "Inline data length", "scsi.extcopy.inline_data_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_seg_desc_list_len, { "Segment descriptor list length", "scsi.extcopy.seg_desc_list_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_list_id, { "List ID", "scsi.extcopy.list_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_head_cscd_desc_type_code, { "Header CSCD description type code", "scsi.extcopy.head_cscd_desc_type_code", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_cscd_desc_type_code, { "CSCD description type code", "scsi.cscd_desc_type_code", FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(desc_type_rval), 0x0, NULL, HFILL}}, + { &hf_scsi_spc_xcopy_rel_init_port_id, { "Relative Initiator Port ID", "scsi.extcopy.rel_init_port_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_per_dev_type, { "Peripherial Device Type", "scsi.extcopy.per_dev_type", FT_UINT8, BASE_DEC, VALS(per_dev_type_vals), 0x1F, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_lu_type, { "LU type", "scsi.extcopy.lu_type", FT_UINT8, BASE_DEC, VALS(lu_type_vals), 0xC0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_per_dev_type_byte, { "Peripherial Device Type bits", "scsi.extcopy.per_dev_type_byte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_disk_block_len, { "Disk block length", "scsi.extcopy.disk_block_len", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_cscd_desc_code_set, { "CSCD descriptor code set", "scsi.extcopy.cscd_code_set", FT_UINT8, BASE_DEC, VALS(scsi_devid_codeset_val), 0x0F, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_cscd_desc_assoc, { "CSCD descriptor association", "scsi.extcopy.cscd_assoc", FT_UINT8, BASE_DEC, VALS(scsi_devid_assoc_val), 0x30, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_cscd_desc_des_type, { "CSCD descriptor designator type", "scsi.extcopy.cscd_des_type", FT_UINT8, BASE_DEC, VALS(scsi_devid_idtype_val), 0x0F, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_cscd_desc_des_len, { "CSCD descriptor desginator length", "scsi.extcopy.cscd_des_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_seg_desc_type, { "Segment descriptor type code", "scsi.extcopy.seg_desc_type", FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(desc_type_rval), 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_seg_desc_dc, { "Segment descriptor designation count bit", "scsi.extcopy.seg_desc_dc", FT_UINT8, BASE_DEC, NULL, 0x2, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_seg_desc_cat, { "Segment descriptor CAT bit", "scsi.extcopy.seg_desc_cat", FT_UINT8, BASE_DEC, NULL, 0x1, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_seg_des_src_desc_id, { "Segment descriptor source ID", "scsi.extcopy.seg_desc_src_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_seg_des_dest_desc_id, { "Segment descriptor destination ID", "scsi.extcopy.seg_desc_dest_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_num_of_blocks, { "Number of blocks", "scsi.extcopy.seg_desc_num_of_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_param_list_id_usage, { "List ID usage", "scsi.extcopy.xcopy_param_list_id_usage", FT_UINT8, BASE_HEX, NULL, 0x18, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_param_str, { "Sequential strip bit (str)", "scsi.extcopy.xcopy_param_str", FT_UINT8, BASE_HEX, NULL, 0x20, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_param_priority, { "Priority", "scsi.extcopy.xcopy_param_priority", FT_UINT8, BASE_HEX, NULL, 0x7, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_param_byte, { "Extended copy Parameters: str, list ID usage, priority", "scsi.extcopy.xcopy_params_byte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_source_lba, { "Source LBA", "scsi.extcopy.source_lba", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_spc_xcopy_dest_lba, { "Source LBA", "scsi.extcopy.source_lba", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_max_cscd_desc_count, { "Max. CSCD descriptors count", "scsi.recv_copy.max_cscd_desc_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_max_seg_desc_count, { "Max. segment descriptors count", "scsi.recv_copy.max_seg_desc_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_max_desc_list_len, { "Max. descriptor list length", "scsi.recv_copy.max_desc_list_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_max_seg_len, { "Max. segment length", "scsi.recv_copy.max_seg_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_max_inline_data_len, { "Max. inline data length", "scsi.recv_copy.max_inline_data_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_held_data_limit, { "Held data limit", "scsi.recv_copy.max_held_data_limit", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_max_stream_dev_trans_size, { "Max. stream device transfer size", "scsi.recv_copy.max_stream_dev_trans_size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_snlid, { "SNLID bit", "scsi.recv_copy.snlid", FT_UINT8, BASE_DEC, NULL, 0x1, NULL, HFILL }}, + { &hf_scsi_recv_copy_avail_data, { "Available data", "scsi.recv_copy.avail_data", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_total_con_copies, { "Total number of concurrent copies", "scsi.recv_copy.total_con_copies", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_max_con_copies, { "Max. number of concurrent copies", "scsi.recv_copy.max_con_copies", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_data_seg_gran, { "Data segment granularity", "scsi.recv_copy.data_seg_gran", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_inline_data_gran, { "Inline data granularity", "scsi.recv_copy.inline_data_gran", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_held_data_gran, { "Held data granularity", "scsi.recv_copy.held_data_gran", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_recv_copy_implemented_desc_list_len, { "Implemented description list length", "scsi.recv_copy.implemented_desc_list_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_reserved_8, { "Reserved (1 byte)", "scsi.reserved", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_reserved_16, { "Reserved (2 bytes)", "scsi.reserved2", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_reserved_24, { "Reserved (3 bytes)", "scsi.reserved3", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_reserved_32, { "Reserved (4 bytes)", "scsi.reserved4", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_scsi_reserved_64, { "Reserved (8 bytes)", "scsi.reserved8", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }} + }; /* Setup protocol subtree array */ @@ -6962,6 +7408,14 @@ proto_register_scsi(void) &ett_sense_descriptor, &ett_sense_osd_not_initiated, &ett_sense_osd_completed, + &ett_xcopy_per_dev_type, + &ett_scsi_xcopy_dev_params, + &ett_scsi_xcopy_cscds, + &ett_scsi_xcopy_cscd, + &ett_scsi_xcopy_segs, + &ett_scsi_xcopy_seg, + &ett_scsi_xcopy_seg_param, + &ett_xcopy_param_byte, }; static ei_register_info ei[] = { diff --git a/epan/dissectors/packet-scsi.h b/epan/dissectors/packet-scsi.h index 240365426a..7205262ef4 100644 --- a/epan/dissectors/packet-scsi.h +++ b/epan/dissectors/packet-scsi.h @@ -116,6 +116,7 @@ typedef struct _scsi_cdb_table_t { #define SCSI_SPC_COPY_AND_VERIFY 0x3A #define SCSI_SPC_INQUIRY 0x12 #define SCSI_SPC_EXTCOPY 0x83 +#define SCSI_SPC_RECVCOPY 0x84 #define SCSI_SPC_LOGSELECT 0x4C #define SCSI_SPC_LOGSENSE 0x4D #define SCSI_SPC_MODESELECT6 0x15 @@ -162,6 +163,8 @@ void dissect_spc_reserve10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t void dissect_spc_release10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_); void dissect_spc_senddiagnostic (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_); void dissect_spc_extcopy (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_); +void dissect_spc_recvcopy (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset, gboolean isreq, gboolean iscdb, guint payload_len _U_, scsi_task_data_t *cdata _U_); + |