diff options
author | Anish Bhatt <anish@chelsio.com> | 2015-04-23 15:31:01 -0700 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2015-05-29 05:22:15 +0000 |
commit | b610db61da2253d16f37c9265254a7b19b8d259d (patch) | |
tree | 25e33bc3cd19763bdf17048ae18d869fe64571ad | |
parent | afb0791e0c0920346cfc9a13e7b8c9639f6cce92 (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.c | 4 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.c | 169 |
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, |