* Routines for decoding SCSI CDBs and responses
* Author: Dinesh G Dutt (ddutt@cisco.com)
*
- * $Id: packet-scsi.c,v 1.26 2003/03/08 08:02:19 guy Exp $
+ * $Id: packet-scsi.c,v 1.33 2003/09/03 20:58:09 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#include <glib.h>
#include <string.h>
#include <epan/strutil.h>
-#include <epan/conversation.h>
+#include <epan/packet.h>
#include <epan/int-64bit.h>
#include "prefs.h"
#include "packet-scsi.h"
static int hf_scsi_inquiry_cmdt_page = -1;
static int hf_scsi_alloclen = -1;
static int hf_scsi_logsel_flags = -1;
-static int hf_scsi_log_pc = -1;
+static int hf_scsi_logsel_pc = -1;
static int hf_scsi_paramlen = -1;
static int hf_scsi_logsns_flags = -1;
+static int hf_scsi_logsns_pc = -1;
static int hf_scsi_logsns_pagecode = -1;
static int hf_scsi_paramlen16 = -1;
static int hf_scsi_modesel_flags = -1;
{0, NULL},
};
+#define SCSI_EVPD_SUPPPG 0x00
+#define SCSI_EVPD_DEVSERNUM 0x80
+#define SCSI_EVPD_OPER 0x81
+#define SCSI_EVPD_ASCIIOPER 0x82
+#define SCSI_EVPD_DEVID 0x83
+
static const value_string scsi_evpd_pagecode_val[] = {
- {0x00, "Supported Vital Product Data Pages"},
- {0x80, "Unit Serial Number Page"},
- {0x82, "ASCII Implemented Operating Definition Page"},
- {0x01, "ASCII Information Page"},
- {0x02, "ASCII Information Page"},
- {0x03, "ASCII Information Page"},
- {0x04, "ASCII Information Page"},
- {0x05, "ASCII Information Page"},
- {0x06, "ASCII Information Page"},
- {0x07, "ASCII Information Page"},
- {0x83, "Device Identification Page"},
+ {SCSI_EVPD_SUPPPG, "Supported Vital Product Data Pages"},
+ {0x01, "ASCII Information Page"},
+ {0x02, "ASCII Information Page"},
+ {0x03, "ASCII Information Page"},
+ {0x04, "ASCII Information Page"},
+ {0x05, "ASCII Information Page"},
+ {0x06, "ASCII Information Page"},
+ {0x07, "ASCII Information Page"},
+ /* XXX - 0x01 through 0x7F are all ASCII information pages */
+ {SCSI_EVPD_DEVSERNUM, "Unit Serial Number Page"},
+ {SCSI_EVPD_OPER, "Implemented Operating Definition Page"},
+ {SCSI_EVPD_ASCIIOPER, "ASCII Implemented Operating Definition Page"},
+ {SCSI_EVPD_DEVID, "Device Identification Page"},
{0, NULL},
};
{0, NULL},
};
-static const value_string scsi_modesense_medtype_val[] = {
- {0, "Default"},
- {1, "Flexible Disk, Single-sided"},
- {2, "Flexible Disk, Double-sided"},
+static const value_string scsi_modesense_medtype_sbc_val[] = {
+ {0x00, "Default"},
+ {0x01, "Flexible disk, single-sided; unspecified medium"},
+ {0x02, "Flexible disk, double-sided; unspecified medium"},
+ {0x05, "Flexible disk, single-sided, single density; 200mm/8in diameter"},
+ {0x06, "Flexible disk, double-sided, single density; 200mm/8in diameter"},
+ {0x09, "Flexible disk, single-sided, double density; 200mm/8in diameter"},
+ {0x0A, "Flexible disk, double-sided, double density; 200mm/8in diameter"},
+ {0x0D, "Flexible disk, single-sided, single density; 130mm/5.25in diameter"},
+ {0x12, "Flexible disk, double-sided, single density; 130mm/5.25in diameter"},
+ {0x16, "Flexible disk, single-sided, double density; 130mm/5.25in diameter"},
+ {0x1A, "Flexible disk, double-sided, double density; 130mm/5.25in diameter"},
+ {0x1E, "Flexible disk, double-sided; 90mm/3.5in diameter"},
+ {0x40, "Direct-access magnetic tape, 12 tracks"},
+ {0x44, "Direct-access magnetic tape, 24 tracks"},
{0, NULL},
};
{0, NULL},
};
-#define SCSI_EVPD_SUPPPG 0
-#define SCSI_EVPD_ASCIIOPER 0x82
-#define SCSI_EVPD_DEVID 0x83
-#define SCSI_EVPD_DEVSERNUM 0x80
-
-static const value_string scsi_inq_evpd_val[] = {
- {SCSI_EVPD_SUPPPG, "Supported Vital Product Data Page"},
- {SCSI_EVPD_ASCIIOPER, "ASCII Implemented Operating Definition Page"},
- {SCSI_EVPD_DEVID, "Device ID Page"},
- {SCSI_EVPD_DEVSERNUM, "Unit Serial Number Page"},
- {0x0, NULL},
-};
-
/* Command Support Data "Support" field definitions */
static const value_string scsi_cmdt_supp_val[] = {
{0, "Data not currently available"},
{0, NULL},
};
+#define CODESET_BINARY 1
+#define CODESET_ASCII 2
+
static const value_string scsi_devid_codeset_val[] = {
- {0, "Reserved"},
- {1, "Identifier field contains binary values"},
- {2, "Identifier field contains ASCII graphic codes"},
- {0, NULL},
+ {0, "Reserved"},
+ {CODESET_BINARY, "Identifier field contains binary values"},
+ {CODESET_ASCII, "Identifier field contains ASCII graphic codes"},
+ {0, NULL},
};
static const value_string scsi_devid_assoc_val[] = {
proto_tree *evpd_tree;
proto_item *ti;
guint pcode, plen, i, idlen;
- guint8 flags;
+ guint8 codeset, flags;
char str[256+1];
if (tree) {
break;
case SCSI_EVPD_DEVID:
while (plen != 0) {
- flags = tvb_get_guint8 (tvb, offset);
+ codeset = tvb_get_guint8 (tvb, offset) & 0x0F;
proto_tree_add_text (evpd_tree, tvb, offset, 1,
"Code Set: %s",
- val_to_str (flags & 0x0F,
+ val_to_str (codeset,
scsi_devid_codeset_val,
"Unknown (0x%02x)"));
- flags = tvb_get_guint8 (tvb, offset+1);
- proto_tree_add_text (evpd_tree, tvb, offset+1, 1,
+ plen -= 1;
+ offset += 1;
+
+ if (plen < 1) {
+ proto_tree_add_text (evpd_tree, tvb, offset, 0,
+ "Product data goes past end of page");
+ break;
+ }
+ flags = tvb_get_guint8 (tvb, offset);
+ proto_tree_add_text (evpd_tree, tvb, offset, 1,
"Association: %s",
val_to_str ((flags & 0x30) >> 4,
scsi_devid_assoc_val,
"Unknown (0x%02x)"));
- proto_tree_add_text (evpd_tree, tvb, offset+1, 1,
+ proto_tree_add_text (evpd_tree, tvb, offset, 1,
"Identifier Type: %s",
val_to_str ((flags & 0x0F),
scsi_devid_idtype_val,
"Unknown (0x%02x)"));
- idlen = tvb_get_guint8 (tvb, offset+3);
- if (idlen > plen) {
- proto_tree_add_text (evpd_tree, tvb, offset+3, 1,
- "Identifier Length: %u (greater than page length %u",
- idlen, plen);
+ plen -= 1;
+ offset += 1;
+
+ /* Skip reserved byte */
+ if (plen < 1) {
+ proto_tree_add_text (evpd_tree, tvb, offset, 0,
+ "Product data goes past end of page");
break;
}
- proto_tree_add_text (evpd_tree, tvb, offset+3, 1,
+ plen -= 1;
+ offset += 1;
+
+ if (plen < 1) {
+ proto_tree_add_text (evpd_tree, tvb, offset, 0,
+ "Product data goes past end of page");
+ break;
+ }
+ idlen = tvb_get_guint8 (tvb, offset);
+ proto_tree_add_text (evpd_tree, tvb, offset, 1,
"Identifier Length: %u", idlen);
+ plen -= 1;
+ offset += 1;
+
if (idlen != 0) {
- proto_tree_add_text (evpd_tree, tvb, offset+4, idlen,
- "Identifier: %s",
- tvb_bytes_to_str (tvb, offset+4,
- idlen));
+ if (plen < idlen) {
+ proto_tree_add_text (evpd_tree, tvb, offset, 0,
+ "Product data goes past end of page");
+ break;
+ }
+ if (codeset == CODESET_ASCII) {
+ proto_tree_add_text (evpd_tree, tvb, offset, idlen,
+ "Identifier: %s",
+ tvb_format_text (tvb, offset,
+ idlen));
+ } else {
+ /*
+ * XXX - decode this based on the identifier type,
+ * if the codeset is CODESET_BINARY?
+ */
+ proto_tree_add_text (evpd_tree, tvb, offset, idlen,
+ "Identifier: %s",
+ tvb_bytes_to_str (tvb, offset,
+ idlen));
+ }
+ plen -= idlen;
+ offset += idlen;
}
- plen -= idlen;
- offset += idlen;
}
break;
case SCSI_EVPD_DEVSERNUM:
- str[0] = '\0';
- tvb_get_nstringz0 (tvb, offset, MIN(plen, sizeof(str) - 1), str);
- proto_tree_add_text (evpd_tree, tvb, offset, plen,
- "Product Serial Number: %s", str);
+ if (plen > 0) {
+ tvb_memcpy (tvb, str, offset, MIN(plen, sizeof(str) - 1));
+ str[sizeof(str) - 1] = '\0';
+ proto_tree_add_text (evpd_tree, tvb, offset, plen,
+ "Product Serial Number: %s", str);
+ }
break;
}
}
"RelAdr: %u, Linked: %u, CmdQue: %u",
(flags & 0x80) >> 7, (flags & 0x08) >> 3,
(flags & 0x02) >> 1);
- tvb_get_nstringz0 (tvb, offset+8, 8, str);
+ tvb_memcpy (tvb, str, offset+8, 8);
+ str[8] = '\0';
proto_tree_add_text (tree, tvb, offset+8, 8, "Vendor Id: %s", str);
- tvb_get_nstringz0 (tvb, offset+16, 16, str);
+ tvb_memcpy (tvb, str, offset+16, 16);
+ str[16] = '\0';
proto_tree_add_text (tree, tvb, offset+16, 16, "Product ID: %s", str);
- tvb_get_nstringz0 (tvb, offset+32, 4, str);
+ tvb_memcpy (tvb, str, offset+32, 4);
+ str[4] = '\0';
proto_tree_add_text (tree, tvb, offset+32, 4, "Product Revision: %s",
str);
proto_tree_add_uint_format (tree, hf_scsi_logsel_flags, tvb, offset, 1,
flags, "PCR = %u, SP = %u", flags & 0x2,
flags & 0x1);
- proto_tree_add_uint_format (tree, hf_scsi_log_pc, tvb, offset+1, 1,
+ proto_tree_add_uint_format (tree, hf_scsi_logsel_pc, tvb, offset+1, 1,
tvb_get_guint8 (tvb, offset+1),
"PC: 0x%x", flags & 0xC0);
proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
proto_tree_add_uint_format (tree, hf_scsi_logsns_flags, tvb, offset, 1,
flags, "PPC = %u, SP = %u", flags & 0x2,
flags & 0x1);
- proto_tree_add_uint_format (tree, hf_scsi_log_pc, tvb, offset+1, 1,
+ proto_tree_add_uint_format (tree, hf_scsi_logsns_pc, tvb, offset+1, 1,
tvb_get_guint8 (tvb, offset+1),
"PC: 0x%x", flags & 0xC0);
proto_tree_add_item (tree, hf_scsi_logsns_pagecode, tvb, offset+1,
if (payload_len < 1)
return;
- proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
- tvb_get_guint8 (tvb, offset));
+ switch (devtype) {
+
+ case SCSI_DEV_SBC:
+ proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: %s",
+ val_to_str(tvb_get_guint8 (tvb, offset),
+ scsi_modesense_medtype_sbc_val,
+ "Unknown (0x%02x)"));
+ break;
+
+ default:
+ proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
+ tvb_get_guint8 (tvb, offset));
+ break;
+ }
offset += 1;
payload_len -= 1;
if (payload_len < 1)
return;
- proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
- tvb_get_guint8 (tvb, offset));
+ switch (devtype) {
+
+ case SCSI_DEV_SBC:
+ proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: %s",
+ val_to_str(tvb_get_guint8 (tvb, offset),
+ scsi_modesense_medtype_sbc_val,
+ "Unknown (0x%02x)"));
+ break;
+
+ default:
+ proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
+ tvb_get_guint8 (tvb, offset));
+ break;
+ }
offset += 1;
payload_len -= 1;
proto_tree_add_text (tree, tvb, offset, 2,
"Additional Sense Code+Qualifier: %s",
val_to_str (tvb_get_ntohs (tvb, offset),
- scsi_asc_val, "Unknown"));
+ scsi_asc_val, "Unknown (0x%04x)"));
}
offset += 2;
elem_bytecnt -= 2;
{ &hf_scsi_logsel_flags,
{"Flags", "scsi.logsel.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
HFILL}},
- { &hf_scsi_log_pc,
- {"Page Control", "scsi.log.pc", FT_UINT8, BASE_DEC,
+ { &hf_scsi_logsel_pc,
+ {"Page Control", "scsi.logsel.pc", FT_UINT8, BASE_DEC,
VALS (scsi_logsel_pc_val), 0xC0, "", HFILL}},
{ &hf_scsi_paramlen,
{"Parameter Length", "scsi.cdb.paramlen", FT_UINT8, BASE_DEC, NULL,
{ &hf_scsi_logsns_flags,
{"Flags", "scsi.logsns.flags", FT_UINT16, BASE_HEX, NULL, 0x0, "",
HFILL}},
+ { &hf_scsi_logsns_pc,
+ {"Page Control", "scsi.logsns.pc", FT_UINT8, BASE_DEC,
+ VALS (scsi_logsns_pc_val), 0xC0, "", HFILL}},
{ &hf_scsi_logsns_pagecode,
{"Page Code", "scsi.logsns.pagecode", FT_UINT8, BASE_HEX,
VALS (scsi_logsns_page_val), 0x3F0, "", HFILL}},
VALS (scsi_qualifier_val), 0xE0, "", HFILL}},
{ &hf_scsi_inq_devtype,
{"Peripheral Device Type", "scsi.inquiry.devtype", FT_UINT8, BASE_HEX,
- VALS (scsi_devtype_val), 0x1F, "", HFILL}},
+ VALS (scsi_devtype_val), SCSI_DEV_BITS, "", HFILL}},
{ & hf_scsi_inq_version,
{"Version", "scsi.inquiry.version", FT_UINT8, BASE_HEX,
VALS (scsi_inquiry_vers_val), 0x0, "", HFILL}},