aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnish Bhatt <anish@chelsio.com>2015-04-23 15:31:01 -0700
committerAnders Broman <a.broman58@gmail.com>2015-05-29 05:22:15 +0000
commitb610db61da2253d16f37c9265254a7b19b8d259d (patch)
tree25e33bc3cd19763bdf17048ae18d869fe64571ad
parentafb0791e0c0920346cfc9a13e7b8c9639f6cce92 (diff)
Update scsi lun id dissector, add support to handle all 4 addressing
methods Bug 11078 Change-Id: I7a9ff07d83b4bb5f5512c04d71aa7f1d3baa0edd Reviewed-on: https://code.wireshark.org/review/8181 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/dissectors/packet-iscsi.c4
-rw-r--r--epan/dissectors/packet-scsi.c169
2 files changed, 142 insertions, 31 deletions
diff --git a/epan/dissectors/packet-iscsi.c b/epan/dissectors/packet-iscsi.c
index 1e79d01d26..3a0ac1239a 100644
--- a/epan/dissectors/packet-iscsi.c
+++ b/epan/dissectors/packet-iscsi.c
@@ -2105,10 +2105,6 @@ dissect_iscsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean chec
if(tvb_get_letohs(tvb,offset+2)){
return 0;
}
- /* last 6 bytes of LUN are always 0 */
- if(tvb_get_ntoh48(tvb, offset+10)){
- return 0;
- }
/* if expected data transfer length is set, W and/or R have to be set */
if(tvb_get_ntohl(tvb,offset+20)){
if(!(tvb_get_guint8(tvb, offset+1)&0x60)){
diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c
index b47831f5aa..914df400f0 100644
--- a/epan/dissectors/packet-scsi.c
+++ b/epan/dissectors/packet-scsi.c
@@ -173,7 +173,11 @@ static int hf_scsi_inq_rmb = -1;
static int hf_scsi_inq_version = -1;
static int hf_scsi_lun_address_mode = -1;
static int hf_scsi_lun = -1;
+static int hf_scsi_lun_extended = -1;
+static int hf_scsi_extended_add_method_len = -1;
+static int hf_scsi_extended_add_method = -1;
static int hf_scsi_bus = -1;
+static int hf_scsi_target = -1;
static int hf_scsi_modesns_errrep = -1;
static int hf_scsi_modesns_tst = -1;
static int hf_scsi_modesns_qmod = -1;
@@ -738,6 +742,7 @@ static gint ett_scsi_fragments = -1;
static gint ett_scsi_fragment = -1;
static gint ett_persresv_control = -1;
static gint ett_scsi_lun = -1;
+static gint ett_scsi_lun_unit = -1;
static gint ett_scsi_prevent_allow = -1;
static gint ett_command_descriptor = -1;
static gint ett_timeout_descriptor = -1;
@@ -855,8 +860,9 @@ static const value_string scsi_spc_vals[] = {
static value_string_ext scsi_spc_vals_ext = VALUE_STRING_EXT_INIT(scsi_spc_vals);
static const value_string scsi_lun_address_mode_vals[] = {
- { 0, "Single Level LUN Structure" },
+ { 0, "Peripheral Device Addressing Method" },
{ 1, "Flat Space Addressing Method" },
+ { 2, "Logical Unit Addressing Method" },
{ 3, "Extended Logical Unit Addressing" },
{ 0, NULL }
};
@@ -4987,31 +4993,125 @@ dissect_spc_reportdeviceidentifier(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
void
dissect_scsi_lun(proto_tree *tree, tvbuff_t *tvb, guint offset) {
proto_item *ti;
- proto_tree *tt = proto_tree_add_subtree(tree, tvb, offset, 8, ett_scsi_lun, &ti, "LUN: ");
- guint8 address_mode;
+ proto_tree *tt, *tl = proto_tree_add_subtree(tree, tvb, offset, 8, ett_scsi_lun, &ti, "LUN");
+ guint8 address_mode, lun_len = 0, ea_code = 0, len_code = 0, lun_count = 0, complex_lun = 0;
guint16 lun = 0;
+ const gchar *str = NULL;
- address_mode = tvb_get_guint8(tvb, offset) >> 6;
- proto_tree_add_item(tt, hf_scsi_lun_address_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
-
- switch (address_mode) {
- case 0:
- proto_tree_add_item(tt, hf_scsi_bus, tvb, offset, 1, ENC_BIG_ENDIAN);
- lun = tvb_get_guint8(tvb, offset + 1);
- proto_tree_add_uint(tt, hf_scsi_lun, tvb, offset + 1, 1, lun);
- break;
- case 1:
- lun = tvb_get_ntohs(tvb, offset) & 0x3fff;
- proto_tree_add_uint(tt, hf_scsi_lun, tvb, offset, 2, lun);
- break;
-/*
- This mode is complex. Lets implement it if/once we see this mode used in the wild.
- case 3:
- break;
- */
+ if (tvb_get_ntoh48(tvb, offset) << 16) {
+ /* Pedantically change LUN to LUNs */
+ proto_item_append_text(tl, "s");
+ complex_lun = 1;
}
- proto_item_append_text(ti, "%d (%s)", lun, val_to_str(address_mode, scsi_lun_address_mode_vals, "Unknown Address Mode:%d"));
+ while (lun_len < 8) {
+ lun = tvb_get_ntohs(tvb, offset + lun_len);
+ /* Don't skip the first non-zero LUN */
+ if (lun_len && !lun)
+ break;
+
+ address_mode = tvb_get_guint8(tvb, offset + lun_len);
+ if ((address_mode >> 6) < 0x3)
+ len_code = 2;
+ else {
+ len_code = (address_mode & 0x30) >> 4;
+ len_code = 2 + (len_code * 2);
+ }
+
+ if (complex_lun) {
+ /* Add lun subtrees only for complex luns */
+ tt = proto_tree_add_subtree(tl, tvb, offset + lun_len, len_code, ett_scsi_lun_unit, &ti, "LUN");
+ proto_item_append_text(tt, " %d", lun_count++);
+ } else
+ tt = tl;
+
+ /* Peripheral and Simple logical unit addressing share the same identifier, with bus defining the difference */
+ if (!address_mode)
+ proto_tree_add_uint_format_value(tt, hf_scsi_lun_address_mode, tvb, offset + lun_len, 1, (address_mode >> 6),
+ "Simple logical unit addressing (0x0%x)", address_mode >> 6);
+ else
+ proto_tree_add_item(tt, hf_scsi_lun_address_mode, tvb, offset + lun_len, 1, ENC_BIG_ENDIAN);
+
+ switch (address_mode >> 6) {
+ case 0:
+ /* Simple logical unit addressing method has no bus id */
+ if (address_mode) {
+ proto_tree_add_bits_item(tt, hf_scsi_bus, tvb, (offset + lun_len) * 8 + 2, 0x6, ENC_BIG_ENDIAN);
+ lun = tvb_get_guint8(tvb, offset + lun_len + 1);
+ proto_tree_add_uint(tt, hf_scsi_lun, tvb, offset + lun_len + 1, 1, lun);
+ } else {
+ lun &= 0x3fff;
+ proto_tree_add_bits_item(tt, hf_scsi_lun, tvb, (offset + lun_len) * 8 + 2, 0xe, ENC_BIG_ENDIAN);
+ }
+ lun_len += len_code;
+ break;
+
+ case 1:
+ lun &= 0x3fff;
+ proto_tree_add_bits_item(tt, hf_scsi_lun, tvb, (offset + lun_len) * 8 + 2, 0xe, ENC_BIG_ENDIAN);
+ lun_len += len_code;
+ break;
+ case 2:
+ proto_tree_add_item(tt, hf_scsi_target, tvb, offset + lun_len, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_bits_item(tt, hf_scsi_bus, tvb, (offset + lun_len + 1) * 8, 0x3, ENC_BIG_ENDIAN);
+ proto_tree_add_bits_item(tt, hf_scsi_lun, tvb, (offset + lun_len + 1) * 8 + 3, 0x5, ENC_BIG_ENDIAN);
+ lun_len += len_code;
+ break;
+ case 3:
+ ea_code = address_mode & 0xf;
+ lun = len_code;
+ len_code = (address_mode & 0x30) >> 4;
+
+ ti = proto_tree_add_item(tt, hf_scsi_extended_add_method_len, tvb, offset + lun_len, 1, ENC_BIG_ENDIAN);
+ proto_item_append_text(ti, " (%d bytes)", lun);
+
+ ti = proto_tree_add_item(tt, hf_scsi_extended_add_method, tvb, offset + lun_len, 1, ENC_BIG_ENDIAN);
+
+ str = NULL;
+ switch(ea_code) {
+ case 0x1:
+ if (!len_code) {
+ str = "Well known logical unit";
+ proto_tree_add_item(tt, hf_scsi_lun, tvb, offset + lun_len + 1, 1, ENC_BIG_ENDIAN);
+ }
+ break;
+ case 0x2:
+ if (len_code == 0x1)
+ str = "Extended flat space addressing";
+ else if (len_code == 0x2)
+ str = "Long extended flat space addressing";
+ if (str)
+ proto_tree_add_item(tt, hf_scsi_lun_extended, tvb, offset + lun_len + 1, lun - 1, ENC_BIG_ENDIAN);
+ break;
+ case 0xe:
+ if (len_code == 0x3)
+ str = "Reserved for FC-SB-5";
+ break;
+ case 0xf:
+ /* The contents of all hierarchical LUN structure addressing fields following a logical unit not specified addressing
+ * method addressing field shall be ignored. [SAM5] 4.7.7.5.4 */
+ if (len_code == 0x3) {
+ proto_item_append_text(ti, " (Logical unit not specified)");
+ return;
+ }
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ len_code = (guint8)lun;
+ if (!str)
+ str = "Reserved";
+
+ proto_item_append_text(ti, " (%s)", str);
+ lun_len += len_code;
+ break;
+
+ default:
+ break;
+ }
+ }
}
void
@@ -6950,14 +7050,28 @@ proto_register_scsi(void)
{"Maximum Sense Data Length", "scsi.spc.modepage.msdl", FT_UINT8, BASE_DEC,
NULL, 0, NULL, HFILL}},
{ &hf_scsi_lun,
- { "LUN", "scsi.lun", FT_UINT16, BASE_DEC,
- NULL, 0, "Logical Unit Number", HFILL }},
+ { "LUN", "scsi.lun", FT_UINT16, BASE_HEX,
+ NULL, 0, "Logical Unit Number", HFILL }},
+ { &hf_scsi_lun_extended,
+ { "LUN", "scsi.lun_long", FT_UINT64, BASE_HEX,
+ NULL, 0, "Logical Unit Number", HFILL }},
+ /* hf_scsi_bus has length of 0x6 with 2bit offset, or 0x3 with no offset
+ so we handle it with add_bits_item */
{ &hf_scsi_bus,
- { "BUS", "scsi.bus", FT_UINT8, BASE_DEC,
- NULL, 0x3f, NULL, HFILL }},
+ { "BUS", "scsi.bus", FT_UINT8, BASE_HEX,
+ NULL, 0, NULL, HFILL }},
+ { &hf_scsi_target,
+ { "Target", "scsi.target", FT_UINT8, BASE_HEX,
+ NULL, 0x3f, NULL, HFILL }},
{ &hf_scsi_lun_address_mode,
- { "Address Mode", "scsi.lun.address_mode", FT_UINT8, BASE_DEC,
+ { "Address Mode", "scsi.lun.address_mode", FT_UINT8, BASE_HEX,
VALS(scsi_lun_address_mode_vals), 0xc0, "Addressing mode for the LUN", HFILL }},
+ { &hf_scsi_extended_add_method_len,
+ { "Extended Address Method Length", "scsi.lun.extended_address_method.len", FT_UINT8, BASE_HEX,
+ NULL, 0x30, "Extended Address Method Specific Field", HFILL }},
+ { &hf_scsi_extended_add_method,
+ { "Extended Address Method", "scsi.lun.extended_address_method", FT_UINT8, BASE_HEX,
+ NULL, 0xf, "Extended Logical Unit Addressing", HFILL }},
{ &hf_scsi_prevent_allow_flags,
{"Prevent Allow Flags", "scsi.prevent_allow.flags", FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL}},
@@ -7403,6 +7517,7 @@ proto_register_scsi(void)
&ett_scsi_fragment,
&ett_persresv_control,
&ett_scsi_lun,
+ &ett_scsi_lun_unit,
&ett_scsi_prevent_allow,
&ett_command_descriptor,
&ett_timeout_descriptor,