2 * Routines for decoding SCSI CDBs and responses
3 * Author: Dinesh G Dutt (ddutt@cisco.com)
5 * $Id: packet-scsi.c,v 1.3 2002/01/21 07:36:41 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 2002 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * Some Notes on using the SCSI Decoder:
29 * The SCSI decoder has been built right now that it is invoked directly by the
30 * SCSI transport layers as compared to the standard mechanism of being invoked
31 * via a dissector chain. There are multiple reasons for this:
32 * - The SCSI CDB is typically embedded inside the transport alongwith other
33 * header fields that have nothing to do with SCSI. So, it is required to be
34 * invoked on a embedded subset of the packet.
35 * - Originally, Ethereal couldn't do filtering on protocol trees that were not
38 * There are four main routines that are provided:
39 * o dissect_scsi_cdb - invoked on receiving a SCSI Command
40 * void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *, guint,
42 * o dissect_scsi_payload - invoked to decode SCSI responses
43 * void dissect_scsi_payload (tvbuff_t *, packet_info *, proto_tree *, guint,
45 * The final parameter is the length of the response field that is negotiated
46 * as part of the SCSI transport layer. If this is not tracked by the
47 * transport, it can be set to 0.
48 * o dissect_scsi_rsp - invoked to destroy the data structures associated with a
50 * void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *);
51 * o dissect_scsi_snsinfo - invoked to decode the sense data provided in case of
53 * void dissect_scsi_snsinfo (tvbuff_t *, packet_info *, proto_tree *, guint,
56 * In addition to this, the other requirement made from the transport is to
57 * provide a unique way to determine a SCSI task. In Fibre channel networks,
58 * this is the exchange ID pair alongwith the source/destination addresses; in
59 * iSCSI it is the initiator task tag along with the src/dst address and port
60 * numbers. This is to be provided to the SCSI decoder via the private_data
61 * field in the packet_info data structure. The private_data field is treated
62 * as a 32-bit field to uniquely identify a SCSI task.
64 * This decoder attempts to track the type of SCSI device based on the response
65 * to the Inquiry command. If the trace does not contain an Inquiry command,
66 * the decoding of the commands is done as per a user preference. Currently,
67 * only SBC (disks) and SSC (tapes) are the alternatives offered. The basic
68 * SCSI command set (SPC-2/3) is decoded for all SCSI devices. If there is a
69 * mixture of devices in the trace, some with Inquiry response and some
70 * without, the user preference is used only for those devices whose type the
71 * decoder has not been able to determine.
78 #ifdef HAVE_SYS_TYPES_H
79 # include <sys/types.h>
84 #include <epan/strutil.h>
85 #include <epan/conversation.h>
87 #include "packet-scsi.h"
89 static int proto_scsi = -1;
90 static int hf_scsi_spcopcode = -1;
91 static int hf_scsi_sbcopcode = -1;
92 static int hf_scsi_control = -1;
93 static int hf_scsi_inquiry_flags = -1;
94 static int hf_scsi_inquiry_evpd_page = -1;
95 static int hf_scsi_inquiry_cmdt_page = -1;
96 static int hf_scsi_alloclen = -1;
97 static int hf_scsi_logsel_flags = -1;
98 static int hf_scsi_log_pc = -1;
99 static int hf_scsi_paramlen = -1;
100 static int hf_scsi_logsns_flags = -1;
101 static int hf_scsi_logsns_pagecode = -1;
102 static int hf_scsi_paramlen16 = -1;
103 static int hf_scsi_modesel_flags = -1;
104 static int hf_scsi_alloclen16 = -1;
105 static int hf_scsi_modesns_pc = -1;
106 static int hf_scsi_modesns_pagecode = -1;
107 static int hf_scsi_modesns_flags = -1;
108 static int hf_scsi_persresvin_svcaction = -1;
109 static int hf_scsi_persresvout_svcaction = -1;
110 static int hf_scsi_persresv_scope = -1;
111 static int hf_scsi_persresv_type = -1;
112 static int hf_scsi_release_flags = -1;
113 static int hf_scsi_release_thirdpartyid = -1;
114 static int hf_scsi_alloclen32 = -1;
115 static int hf_scsi_formatunit_flags = -1;
116 static int hf_scsi_formatunit_interleave = -1;
117 static int hf_scsi_formatunit_vendor = -1;
118 static int hf_scsi_rdwr6_lba = -1;
119 static int hf_scsi_rdwr6_xferlen = -1;
120 static int hf_scsi_rdwr10_lba = -1;
121 static int hf_scsi_read_flags = -1;
122 static int hf_scsi_rdwr12_xferlen = -1;
123 static int hf_scsi_rdwr16_lba = -1;
124 static int hf_scsi_readcapacity_flags = -1;
125 static int hf_scsi_readcapacity_lba = -1;
126 static int hf_scsi_readcapacity_pmi = -1;
127 static int hf_scsi_rdwr10_xferlen = -1;
128 static int hf_scsi_readdefdata_flags = -1;
129 static int hf_scsi_cdb_defectfmt = -1;
130 static int hf_scsi_reassignblks_flags = -1;
131 static int hf_scsi_inq_devtype = -1;
132 static int hf_scsi_inq_version = -1;
133 static int hf_scsi_rluns_lun = -1;
134 static int hf_scsi_rluns_multilun = -1;
135 static int hf_scsi_modesns_errrep = -1;
136 static int hf_scsi_modesns_tst = -1;
137 static int hf_scsi_modesns_qmod = -1;
138 static int hf_scsi_modesns_qerr = -1;
139 static int hf_scsi_modesns_rac = -1;
140 static int hf_scsi_modesns_tas = -1;
141 static int hf_scsi_protocol = -1;
142 static int hf_scsi_sns_errtype = -1;
143 static int hf_scsi_snskey = -1;
144 static int hf_scsi_snsinfo = -1;
145 static int hf_scsi_addlsnslen = -1;
146 static int hf_scsi_asc = -1;
147 static int hf_scsi_ascascq = -1;
148 static int hf_scsi_ascq = -1;
149 static int hf_scsi_fru = -1;
150 static int hf_scsi_sksv = -1;
151 static int hf_scsi_inq_normaca = -1;
152 static int hf_scsi_persresv_key = -1;
153 static int hf_scsi_persresv_scopeaddr = -1;
154 static int hf_scsi_sscopcode = -1;
157 static gint ett_scsi = -1;
158 static gint ett_scsi_page = -1;
159 static gint scsi_def_devtype = SCSI_DEV_SBC;
161 /* The next two structures are used to track SCSI req/rsp */
162 typedef struct _scsi_task_key {
166 typedef struct _scsi_task_data {
168 scsi_device_type devtype;
169 guint8 flags; /* used by SCSI Inquiry */
172 /* The next two data structures are used to track SCSI device type */
173 typedef struct _scsi_devtype_key {
175 } scsi_devtype_key_t;
177 typedef struct _scsi_devtype_data {
178 scsi_device_type devtype;
179 } scsi_devtype_data_t;
181 static GHashTable *scsi_req_hash = NULL;
182 static GMemChunk *scsi_req_keys = NULL;
183 static GMemChunk *scsi_req_vals = NULL;
184 static guint32 scsi_init_count = 25;
186 static GHashTable *scsidev_req_hash = NULL;
187 static GMemChunk *scsidev_req_keys = NULL;
188 static GMemChunk *scsidev_req_vals = NULL;
189 static guint32 scsidev_init_count = 25;
191 static dissector_handle_t data_handle;
197 scsi_equal(gconstpointer v, gconstpointer w)
199 scsi_task_key_t *v1 = (scsi_task_key_t *)v;
200 scsi_task_key_t *v2 = (scsi_task_key_t *)w;
202 return (v1->conv_idx == v2->conv_idx);
206 scsi_hash (gconstpointer v)
208 scsi_task_key_t *key = (scsi_task_key_t *)v;
217 scsidev_equal (gconstpointer v, gconstpointer w)
219 scsi_devtype_key_t *k1 = (scsi_devtype_key_t *)v;
220 scsi_devtype_key_t *k2 = (scsi_devtype_key_t *)w;
222 if (ADDRESSES_EQUAL (&k1->devid, &k2->devid))
229 scsidev_hash (gconstpointer v)
231 scsi_devtype_key_t *key = (scsi_devtype_key_t *)v;
236 for (i = 0; i < key->devid.len; i++)
237 val += key->devid.data[i];
238 val += key->devid.type;
243 static scsi_task_data_t *
244 scsi_new_task (packet_info *pinfo)
246 scsi_task_data_t *cdata = NULL;
247 scsi_task_key_t ckey, *req_key;
248 conversation_t *conversation;
250 if ((pinfo != NULL) && (pinfo->private_data)) {
251 ckey.conv_idx = (guint32)pinfo->private_data;
253 cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
256 req_key = g_mem_chunk_alloc (scsi_req_keys);
257 req_key->conv_idx = (guint32 )pinfo->private_data;
259 cdata = g_mem_chunk_alloc (scsi_req_vals);
261 g_hash_table_insert (scsi_req_hash, req_key, cdata);
267 static scsi_task_data_t *
268 scsi_find_task (packet_info *pinfo)
270 scsi_task_data_t *cdata = NULL;
271 scsi_task_key_t ckey, *req_key;
272 conversation_t *conversation;
274 if ((pinfo != NULL) && (pinfo->private_data)) {
275 ckey.conv_idx = (guint32)pinfo->private_data;
277 cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
284 scsi_end_task (packet_info *pinfo)
286 scsi_task_data_t *cdata = NULL;
287 scsi_task_key_t ckey, *req_key;
288 conversation_t *conversation;
290 if ((pinfo != NULL) && (pinfo->private_data)) {
291 ckey.conv_idx = (guint32)pinfo->private_data;
292 cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
295 g_mem_chunk_free (scsi_req_vals, cdata);
296 g_hash_table_remove (scsi_req_hash, &ckey);
302 * Protocol initialization
305 scsi_init_protocol(void)
308 g_mem_chunk_destroy(scsi_req_keys);
310 g_mem_chunk_destroy(scsi_req_vals);
311 if (scsidev_req_keys)
312 g_mem_chunk_destroy (scsidev_req_keys);
313 if (scsidev_req_vals)
314 g_mem_chunk_destroy (scsidev_req_vals);
316 g_hash_table_destroy(scsi_req_hash);
317 if (scsidev_req_hash)
318 g_hash_table_destroy (scsidev_req_hash);
320 scsi_req_hash = g_hash_table_new(scsi_hash, scsi_equal);
321 scsi_req_keys = g_mem_chunk_new("scsi_req_keys",
322 sizeof(scsi_task_key_t),
324 sizeof(scsi_task_key_t),
326 scsi_req_vals = g_mem_chunk_new("scsi_req_vals",
327 sizeof(scsi_task_data_t),
329 sizeof(scsi_task_data_t),
331 scsidev_req_hash = g_hash_table_new (scsidev_hash, scsidev_equal);
332 scsidev_req_keys = g_mem_chunk_new("scsidev_req_keys",
333 sizeof(scsi_devtype_key_t),
335 sizeof(scsi_devtype_key_t),
337 scsidev_req_vals = g_mem_chunk_new("scsidev_req_vals",
338 sizeof(scsi_devtype_data_t),
340 sizeof(scsi_devtype_data_t),
345 dissect_scsi_evpd (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
346 guint offset, guint tot_len)
348 proto_tree *evpd_tree;
350 guint pcode, plen, i, idlen;
355 pcode = tvb_get_guint8 (tvb, offset+1);
356 plen = tvb_get_guint8 (tvb, offset+3);
357 ti = proto_tree_add_text (tree, tvb, offset, plen+4, "Page Code: %s",
358 val_to_str (pcode, scsi_evpd_pagecode_val,
359 "Unknown (0x%08x)"));
360 evpd_tree = proto_item_add_subtree (ti, ett_scsi_page);
362 proto_tree_add_text (evpd_tree, tvb, offset, 1,
363 "Peripheral Qualifier: 0x%x",
364 (tvb_get_guint8 (tvb, offset) & 0xF0)>>4);
365 proto_tree_add_item (evpd_tree, hf_scsi_inq_devtype, tvb, offset,
367 proto_tree_add_text (evpd_tree, tvb, offset+1, 1,
369 val_to_str (pcode, scsi_evpd_pagecode_val,
370 "Unknown (0x%02x)"));
371 proto_tree_add_text (evpd_tree, tvb, offset+3, 1,
372 "Page Length: %u", plen);
375 case SCSI_EVPD_SUPPPG:
376 for (i = 0; i < plen; i++) {
377 proto_tree_add_text (evpd_tree, tvb, offset+i, 1,
378 "Supported Page: %s",
379 val_to_str (tvb_get_guint8 (tvb, offset+i),
380 scsi_evpd_pagecode_val,
381 "Unknown (0x%02x)"));
384 case SCSI_EVPD_DEVID:
386 flags = tvb_get_guint8 (tvb, offset);
387 proto_tree_add_text (evpd_tree, tvb, offset, 1,
389 val_to_str (plen & 0x0F,
390 scsi_devid_codeset_val,
391 "Unknown (0x%02x)"));
392 flags = tvb_get_guint8 (tvb, offset+1);
393 proto_tree_add_text (evpd_tree, tvb, offset+1, 1,
395 val_to_str ((flags & 0x30) >> 4,
396 scsi_devid_assoc_val,
397 "Unknown (0x%02x)"));
398 proto_tree_add_text (evpd_tree, tvb, offset+1, 1,
399 "Identifier Type: %s",
400 val_to_str ((flags & 0x0F),
401 scsi_devid_idtype_val,
402 "Unknown (0x%02x)"));
403 idlen = tvb_get_guint8 (tvb, offset+3);
404 proto_tree_add_text (evpd_tree, tvb, offset+3, 1,
405 "Identifier Length: %u", idlen);
406 proto_tree_add_text (evpd_tree, tvb, offset+4, idlen,
408 tvb_bytes_to_str (tvb, offset+4,
414 case SCSI_EVPD_DEVSERNUM:
416 tvb_get_nstringz0 (tvb, offset, plen, str);
417 proto_tree_add_text (evpd_tree, tvb, offset, plen,
418 "Product Serial Number: %s", str);
425 dissect_scsi_cmddt (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
426 guint offset, guint tot_len)
428 proto_tree *cmdt_tree;
430 guint opcode, plen, i;
434 plen = tvb_get_guint8 (tvb, offset+5);
435 ti = proto_tree_add_text (tree, tvb, offset, plen, "Command Data");
436 cmdt_tree = proto_item_add_subtree (ti, ett_scsi_page);
438 proto_tree_add_text (cmdt_tree, tvb, offset, 1,
439 "Peripheral Qualifier: 0x%x",
440 (tvb_get_guint8 (tvb, offset) & 0xF0)>>4);
441 proto_tree_add_item (cmdt_tree, hf_scsi_inq_devtype, tvb, offset,
443 proto_tree_add_text (cmdt_tree, tvb, offset+1, 1, "Support: %s",
444 match_strval (tvb_get_guint8 (tvb, offset+1) & 0x7,
445 scsi_cmdt_supp_val));
446 proto_tree_add_text (cmdt_tree, tvb, offset+2, 1, "Version: %s",
447 val_to_str (tvb_get_guint8 (tvb, offset+2),
449 "Unknown (0x%02x)"));
450 proto_tree_add_text (cmdt_tree, tvb, offset+5, 1, "CDB Size: %u",
456 dissect_scsi_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
457 guint offset, gboolean isreq, gboolean iscdb,
458 guint32 payload_len, scsi_task_data_t *cdata)
462 guint tot_len, pcode, plen, replen;
463 conversation_t *conversation;
464 scsi_device_type dev = 0;
465 scsi_devtype_data_t *devdata = NULL;
466 scsi_devtype_key_t dkey, *req_key;
471 if (isreq && iscdb) {
472 flags = tvb_get_guint8 (tvb, offset);
474 cdata->flags = flags;
477 proto_tree_add_uint_format (tree, hf_scsi_inquiry_flags, tvb, offset, 1,
478 flags, "CMDT = %u, EVPD = %u",
479 flags & 0x2, flags & 0x1);
481 proto_tree_add_item (tree, hf_scsi_inquiry_evpd_page, tvb, offset+1,
484 else if (flags & 0x2) {
485 proto_tree_add_item (tree, hf_scsi_inquiry_cmdt_page, tvb, offset+1,
489 proto_tree_add_uint (tree, hf_scsi_alloclen, tvb, offset+3, 1, 0);
490 flags = tvb_get_guint8 (tvb, offset+4);
491 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
493 "Vendor Unique = %u, NACA = %u, Link = %u",
494 flags & 0xC0, flags & 0x4, flags & 0x1);
497 if (cdata && (cdata->flags & 0x1)) {
498 dissect_scsi_evpd (tvb, pinfo, tree, offset, payload_len);
501 else if (cdata && (cdata->flags & 0x2)) {
502 dissect_scsi_cmddt (tvb, pinfo, tree, offset, payload_len);
506 /* Add device type to list of known devices & their types */
507 COPY_ADDRESS (&(dkey.devid), &(pinfo->src));
508 devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
511 req_key = g_mem_chunk_alloc (scsidev_req_keys);
512 COPY_ADDRESS (&(req_key->devid), &(pinfo->src));
514 devdata = g_mem_chunk_alloc (scsidev_req_vals);
515 devdata->devtype = tvb_get_guint8 (tvb, offset) & 0x10;
517 g_hash_table_insert (scsidev_req_hash, req_key, devdata);
520 proto_tree_add_text (tree, tvb, offset, 1, "Peripheral Qualifier: 0x%x",
521 (tvb_get_guint8 (tvb, offset) & 0xF0)>>4);
522 proto_tree_add_item (tree, hf_scsi_inq_devtype, tvb, offset, 1, 0);
523 proto_tree_add_item (tree, hf_scsi_inq_version, tvb, offset+2, 1, 0);
525 flags = tvb_get_guint8 (tvb, offset+3);
526 proto_tree_add_item_hidden (tree, hf_scsi_inq_normaca, tvb,
528 proto_tree_add_text (tree, tvb, offset+3, 1, "NormACA: %u, HiSup: %u",
529 ((flags & 0x20) >> 5), ((flags & 0x10) >> 4));
530 tot_len = tvb_get_guint8 (tvb, offset+4);
531 proto_tree_add_text (tree, tvb, offset+4, 1, "Additional Length: %u",
533 flags = tvb_get_guint8 (tvb, offset+6);
534 proto_tree_add_text (tree, tvb, offset+6, 1,
535 "BQue: %u, SES: %u, MultiP: %u, Addr16: %u",
536 ((flags & 0x80) >> 7), (flags & 0x40) >> 6,
537 (flags & 10) >> 4, (flags & 0x01));
538 flags = tvb_get_guint8 (tvb, offset+7);
539 proto_tree_add_text (tree, tvb, offset+7, 1,
540 "RelAdr: %u, Linked: %u, CmdQue: %u",
541 (flags & 0x80) >> 7, (flags & 0x08) >> 3,
542 (flags & 0x02) >> 1);
543 tvb_get_nstringz0 (tvb, offset+8, 8, str);
544 proto_tree_add_text (tree, tvb, offset+8, 8, "Vendor Id: %s", str);
545 tvb_get_nstringz0 (tvb, offset+16, 16, str);
546 proto_tree_add_text (tree, tvb, offset+16, 16, "Product ID: %s", str);
547 tvb_get_nstringz0 (tvb, offset+32, 4, str);
548 proto_tree_add_text (tree, tvb, offset+32, 4, "Product Revision: %s",
552 if ((tot_len > 58) && tvb_bytes_exist (tvb, offset, 16)) {
553 for (i = 0; i < 8; i++) {
554 proto_tree_add_text (tree, tvb, offset, 2,
555 "Vendor Descriptor %u: %s",
557 val_to_str (tvb_get_ntohs (tvb, offset),
559 "Unknown (0x%04x)"));
567 dissect_scsi_extcopy (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
568 guint offset, gboolean isreq, gboolean iscdb)
574 dissect_scsi_logselect (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
575 guint offset, gboolean isreq, gboolean iscdb)
582 if (isreq && iscdb) {
583 flags = tvb_get_guint8 (tvb, offset);
585 proto_tree_add_uint_format (tree, hf_scsi_logsel_flags, tvb, offset, 1,
586 flags, "PCR = %u, SP = %u", flags & 0x2,
588 proto_tree_add_uint_format (tree, hf_scsi_log_pc, tvb, offset+1, 1,
589 tvb_get_guint8 (tvb, offset+1),
590 "PC: 0x%x", flags & 0xC0);
591 proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
593 flags = tvb_get_guint8 (tvb, offset+8);
594 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
596 "Vendor Unique = %u, NACA = %u, Link = %u",
597 flags & 0xC0, flags & 0x4, flags & 0x1);
604 dissect_scsi_logsense (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
605 guint offset, gboolean isreq, gboolean iscdb)
612 if (isreq && iscdb) {
613 flags = tvb_get_guint8 (tvb, offset);
615 proto_tree_add_uint_format (tree, hf_scsi_logsns_flags, tvb, offset, 1,
616 flags, "PPC = %u, SP = %u", flags & 0x2,
618 proto_tree_add_uint_format (tree, hf_scsi_log_pc, tvb, offset+1, 1,
619 tvb_get_guint8 (tvb, offset+1),
620 "PC: 0x%x", flags & 0xC0);
621 proto_tree_add_item (tree, hf_scsi_logsns_pagecode, tvb, offset+1,
623 proto_tree_add_text (tree, tvb, offset+4, 2, "Parameter Pointer: 0x%04x",
624 tvb_get_ntohs (tvb, offset+4));
625 proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
627 flags = tvb_get_guint8 (tvb, offset+8);
628 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
630 "Vendor Unique = %u, NACA = %u, Link = %u",
631 flags & 0xC0, flags & 0x4, flags & 0x1);
638 dissect_scsi_modepage (tvbuff_t *tvb, packet_info *pinfo, proto_tree *scsi_tree,
641 guint8 pcode, plen, flags, proto;
645 pcode = tvb_get_guint8 (tvb, offset);
646 plen = tvb_get_guint8 (tvb, offset+1);
648 ti = proto_tree_add_text (scsi_tree, tvb, offset, plen+2, "%s Mode Page",
649 val_to_str (pcode & 0x3F, scsi_modesns_page_val,
650 "Unknown (0x%08x)"));
651 tree = proto_item_add_subtree (ti, ett_scsi_page);
652 proto_tree_add_text (tree, tvb, offset, 1, "PS: %u", (pcode & 0x80) >> 8);
654 proto_tree_add_item (tree, hf_scsi_modesns_pagecode, tvb, offset, 1, 0);
655 proto_tree_add_text (tree, tvb, offset+1, 1, "Page Length: %u",
658 if (!tvb_bytes_exist (tvb, offset, plen)) {
664 case SCSI_MODEPAGE_CTL:
665 flags = tvb_get_guint8 (tvb, offset+2);
666 proto_tree_add_item (tree, hf_scsi_modesns_tst, tvb, offset+2, 1, 0);
667 proto_tree_add_text (tree, tvb, offset+2, 1,
668 "Global Logging Target Save Disable: %u, Report Log Exception Condition: %u",
669 (flags & 0x2) >> 1, (flags & 0x1));
670 flags = tvb_get_guint8 (tvb, offset+3);
671 proto_tree_add_item (tree, hf_scsi_modesns_qmod, tvb, offset+3, 1, 0);
672 proto_tree_add_item (tree, hf_scsi_modesns_qerr, tvb, offset+3, 1, 0);
673 proto_tree_add_text (tree, tvb, offset+3, 1, "Disable Queuing: %u",
675 flags = tvb_get_guint8 (tvb, offset+4);
676 proto_tree_add_item (tree, hf_scsi_modesns_rac, tvb, offset+4, 1, 0);
677 proto_tree_add_item (tree, hf_scsi_modesns_tas, tvb, offset+4, 1, 0);
678 proto_tree_add_text (tree, tvb, offset+4, 1,
679 "SWP: %u, RAERP: %u, UAAERP: %u, EAERP: %u",
680 (flags & 0x8) >> 3, (flags & 0x4) >> 2,
681 (flags & 0x2) >> 2, (flags & 0x1));
682 proto_tree_add_text (tree, tvb, offset+5, 1, "Autoload Mode: 0x%x",
683 tvb_get_guint8 (tvb, offset+5) & 0x7);
684 proto_tree_add_text (tree, tvb, offset+6, 2,
685 "Ready AER Holdoff Period: %u ms",
686 tvb_get_ntohs (tvb, offset+6));
687 proto_tree_add_text (tree, tvb, offset+8, 2,
688 "Busy Timeout Period: %u ms",
689 tvb_get_ntohs (tvb, offset+8)*100);
690 proto_tree_add_text (tree, tvb, offset+10, 2,
691 "Extended Self-Test Completion Time: %u",
692 tvb_get_ntohs (tvb, offset+10));
694 case SCSI_MODEPAGE_DISCON:
695 proto_tree_add_text (tree, tvb, offset+2, 1, "Buffer Full Ratio: %u",
696 tvb_get_guint8 (tvb, offset+2));
697 proto_tree_add_text (tree, tvb, offset+3, 1, "Buffer Empty Ratio: %u",
698 tvb_get_guint8 (tvb, offset+3));
699 proto_tree_add_text (tree, tvb, offset+4, 2, "Bus Inactivity Limit: %u",
700 tvb_get_ntohs (tvb, offset+4));
701 proto_tree_add_text (tree, tvb, offset+6, 2, "Disconnect Time Limit: %u",
702 tvb_get_ntohs (tvb, offset+6));
703 proto_tree_add_text (tree, tvb, offset+8, 2, "Connect Time Limit: %u",
704 tvb_get_ntohs (tvb, offset+8));
705 proto_tree_add_text (tree, tvb, offset+10, 2,
706 "Maximum Burst Size: %u bytes",
707 tvb_get_ntohs (tvb, offset+10)*512);
708 flags = tvb_get_guint8 (tvb, offset+12);
709 proto_tree_add_text (tree, tvb, offset+12, 1,
710 "EMDP: %u, FAA: %u, FAB: %u, FAC: %u",
711 (flags & 0x80) >> 7, (flags & 0x40) >> 6,
712 (flags & 0x20) >> 5, (flags & 0x10) >> 4);
713 proto_tree_add_text (tree, tvb, offset+14, 2,
714 "First Burst Size: %u bytes",
715 tvb_get_ntohs (tvb, offset+14)*512);
717 case SCSI_MODEPAGE_INFOEXCP:
718 flags = tvb_get_guint8 (tvb, offset+2);
719 proto_tree_add_text (tree, tvb, offset+2, 1,
720 "Perf: %u, EBF: %u, EWasc: %u, DExcpt: %u, Test: %u, LogErr: %u",
721 (flags & 0x80) >> 7, (flags & 0x20) >> 5,
722 (flags & 0x10) >> 4, (flags & 0x08) >> 3,
723 (flags & 0x04) >> 2, (flags & 0x01));
724 if (!((flags & 0x10) >> 4) && ((flags & 0x08) >> 3)) {
725 proto_tree_add_item_hidden (tree, hf_scsi_modesns_errrep, tvb,
729 proto_tree_add_item (tree, hf_scsi_modesns_errrep, tvb, offset+3, 1, 0);
731 proto_tree_add_text (tree, tvb, offset+4, 4, "Interval Timer: %u",
732 tvb_get_ntohl (tvb, offset+4));
733 proto_tree_add_text (tree, tvb, offset+8, 4, "Report Count: %u",
734 tvb_get_ntohl (tvb, offset+8));
736 case SCSI_MODEPAGE_PWR:
737 flags = tvb_get_guint8 (tvb, offset+3);
738 proto_tree_add_text (tree, tvb, offset+3, 1, "Idle: %u, Standby: %u",
739 (flags & 0x2) >> 1, (flags & 0x1));
740 proto_tree_add_text (tree, tvb, offset+4, 2,
741 "Idle Condition Timer: %u ms",
742 tvb_get_ntohs (tvb, offset+4) * 100);
743 proto_tree_add_text (tree, tvb, offset+6, 2,
744 "Standby Condition Timer: %u ms",
745 tvb_get_ntohs (tvb, offset+6) * 100);
747 case SCSI_MODEPAGE_LUN:
749 case SCSI_MODEPAGE_PORT:
750 proto = tvb_get_guint8 (tvb, offset+2) & 0x0F;
751 proto_tree_add_item (tree, hf_scsi_protocol, tvb, offset+2, 1, 0);
752 if (proto == SCSI_PROTO_FCP) {
753 flags = tvb_get_guint8 (tvb, offset+3);
754 proto_tree_add_text (tree, tvb, offset+3, 1,
755 "DTFD: %u, PLPB: %u, DDIS: %u, DLM: %u, RHA: %u, ALWI: %u, DTIPE: %u, DTOLI:%u",
756 (flags & 0x80) >> 7, (flags & 0x40) >> 6,
757 (flags & 0x20) >> 5, (flags & 0x10) >> 4,
758 (flags & 0x08) >> 3, (flags & 0x04) >> 2,
759 (flags & 0x02) >> 1, (flags & 0x1));
760 proto_tree_add_text (tree, tvb, offset+6, 1, "RR_TOV Units: %s",
761 val_to_str (tvb_get_guint8 (tvb, offset+6) & 0x7,
763 "Unknown (0x%02x)"));
764 proto_tree_add_text (tree, tvb, offset+7, 1, "RR_TOV: %u",
765 tvb_get_guint8 (tvb, offset+7));
767 else if (proto == SCSI_PROTO_iSCSI) {
772 case SCSI_MODEPAGE_FMTDEV:
773 proto_tree_add_text (tree, tvb, offset+2, 2, "Tracks Per Zone: %u",
774 tvb_get_ntohs (tvb, offset+2));
775 proto_tree_add_text (tree, tvb, offset+4, 2,
776 "Alternate Sectors Per Zone: %u",
777 tvb_get_ntohs (tvb, offset+4));
778 proto_tree_add_text (tree, tvb, offset+6, 2,
779 "Alternate Tracks Per Zone: %u",
780 tvb_get_ntohs (tvb, offset+6));
781 proto_tree_add_text (tree, tvb, offset+8, 2,
782 "Alternate Tracks Per LU: %u",
783 tvb_get_ntohs (tvb, offset+8));
784 proto_tree_add_text (tree, tvb, offset+10, 2, "Sectors Per Track: %u",
785 tvb_get_ntohs (tvb, offset+10));
786 proto_tree_add_text (tree, tvb, offset+12, 2,
787 "Data Bytes Per Physical Sector: %u",
788 tvb_get_ntohs (tvb, offset+12));
789 proto_tree_add_text (tree, tvb, offset+14, 2, "Interleave: %u",
790 tvb_get_ntohs (tvb, offset+14));
791 proto_tree_add_text (tree, tvb, offset+16, 2, "Track Skew Factor: %u",
792 tvb_get_ntohs (tvb, offset+16));
793 proto_tree_add_text (tree, tvb, offset+18, 2,
794 "Cylinder Skew Factor: %u",
795 tvb_get_ntohs (tvb, offset+18));
796 flags = tvb_get_guint8 (tvb, offset+20);
797 proto_tree_add_text (tree, tvb, offset+20, 1,
798 "SSEC: %u, HSEC: %u, RMB: %u, SURF: %u",
799 (flags & 0x80) >> 7, (flags & 0x40) >> 6,
800 (flags & 0x20) >> 5, (flags & 0x10) >> 4);
802 case SCSI_MODEPAGE_RDWRERR:
803 flags = tvb_get_guint8 (tvb, offset+2);
804 proto_tree_add_text (tree, tvb, offset+2, 1,
805 "AWRE: %u, ARRE: %u, TB: %u, RC: %u, EER: %u, PER: %u, DTE: %u, DCR: %u",
806 (flags & 0x80) >> 7, (flags & 0x40) >> 6,
807 (flags & 0x20) >> 5, (flags & 0x10) >> 4,
808 (flags & 0x08) >> 3, (flags & 0x04) >> 2,
809 (flags & 0x02) >> 1, (flags & 0x01));
810 proto_tree_add_text (tree, tvb, offset+3, 1, "Read Retry Count: %u",
811 tvb_get_guint8 (tvb, offset+3));
812 proto_tree_add_text (tree, tvb, offset+4, 1, "Correction Span: %u",
813 tvb_get_guint8 (tvb, offset+4));
814 proto_tree_add_text (tree, tvb, offset+5, 1, "Head Offset Count: %u",
815 tvb_get_guint8 (tvb, offset+5));
816 proto_tree_add_text (tree, tvb, offset+6, 1,
817 "Data Strobe Offset Count: %u",
818 tvb_get_guint8 (tvb, offset+6));
819 proto_tree_add_text (tree, tvb, offset+8, 1, "Write Retry Count: %u",
820 tvb_get_guint8 (tvb, offset+8));
821 proto_tree_add_text (tree, tvb, offset+10, 2,
822 "Recovery Time Limit: %u ms",
823 tvb_get_ntohs (tvb, offset+10));
825 case SCSI_MODEPAGE_DISKGEOM:
826 proto_tree_add_text (tree, tvb, offset+2, 3, "Number of Cylinders: %u",
827 tvb_get_ntoh24 (tvb, offset+2));
828 proto_tree_add_text (tree, tvb, offset+5, 1, "Number of Heads: %u",
829 tvb_get_guint8 (tvb, offset+5));
830 proto_tree_add_text (tree, tvb, offset+6, 3,
831 "Starting Cyl Pre-compensation: %u",
832 tvb_get_ntoh24 (tvb, offset+6));
833 proto_tree_add_text (tree, tvb, offset+9, 3,
834 "Starting Cyl-reduced Write Current: %u",
835 tvb_get_ntoh24 (tvb, offset+9));
836 proto_tree_add_text (tree, tvb, offset+12, 2, "Device Step Rate: %u",
837 tvb_get_ntohs (tvb, offset+12));
838 proto_tree_add_text (tree, tvb, offset+14, 3, "Landing Zone Cyl: %u",
839 tvb_get_ntoh24 (tvb, offset+14));
840 proto_tree_add_text (tree, tvb, offset+18, 1, "Rotational Offset: %u",
841 tvb_get_guint8 (tvb, offset+18));
842 proto_tree_add_text (tree, tvb, offset+20, 2,
843 "Medium Rotation Rate: %u",
844 tvb_get_ntohs (tvb, offset+20));
846 case SCSI_MODEPAGE_FLEXDISK:
848 case SCSI_MODEPAGE_VERERR:
850 case SCSI_MODEPAGE_CACHE:
851 flags = tvb_get_guint8 (tvb, offset+2);
852 proto_tree_add_text (tree, tvb, offset+2, 1,
853 "IC: %u, ABPF: %u, CAP %u, Disc: %u, Size: %u, WCE: %u, MF: %u, RCD: %u",
854 (flags & 0x80) >> 7, (flags & 0x40) >> 6,
855 (flags & 0x20) >> 5, (flags & 0x10) >> 4,
856 (flags & 0x08) >> 3, (flags & 0x04) >> 2,
857 (flags & 0x02) >> 1, (flags & 0x01));
858 flags = tvb_get_guint8 (tvb, offset+3);
859 proto_tree_add_text (tree, tvb, offset+3, 1,
860 "Demand Read Retention Priority: %u, Write Retention Priority: %u",
861 (flags & 0xF0) >> 4, (flags & 0x0F));
862 proto_tree_add_text (tree, tvb, offset+4, 2,
863 "Disable Pre-fetch Xfer Len: %u",
864 tvb_get_ntohs (tvb, offset+4));
865 proto_tree_add_text (tree, tvb, offset+6, 2, "Minimum Pre-Fetch: %u",
866 tvb_get_ntohs (tvb, offset+6));
867 proto_tree_add_text (tree, tvb, offset+8, 2, "Maximum Pre-Fetch: %u",
868 tvb_get_ntohs (tvb, offset+8));
869 proto_tree_add_text (tree, tvb, offset+10, 2,
870 "Maximum Pre-Fetch Ceiling: %u",
871 tvb_get_ntohs (tvb, offset+10));
872 flags = tvb_get_guint8 (tvb, offset+12);
873 proto_tree_add_text (tree, tvb, offset+12, 1,
874 "FSW: %u, LBCSS: %u, DRA: %u, Vendor Specific: %u",
875 (flags & 0x80) >> 7, (flags & 0x40) >> 6,
876 (flags & 0x20) >> 5, (flags & 0x1F) >> 4);
877 proto_tree_add_text (tree, tvb, offset+13, 1,
878 "Number of Cache Segments: %u",
879 tvb_get_guint8 (tvb, offset+13));
880 proto_tree_add_text (tree, tvb, offset+14, 2, "Cache Segment Size: %u",
881 tvb_get_ntohs (tvb, offset+14));
882 proto_tree_add_text (tree, tvb, offset+17, 3,
883 "Non-Cache Segment Size: %u",
884 tvb_get_ntoh24 (tvb, offset+17));
886 case SCSI_MODEPAGE_PERDEV:
888 case SCSI_MODEPAGE_MEDTYPE:
890 case SCSI_MODEPAGE_NOTPART:
892 case SCSI_MODEPAGE_XORCTL:
895 proto_tree_add_text (tree, tvb, offset, plen,
903 dissect_scsi_modeselect6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
904 guint offset, gboolean isreq, gboolean iscdb,
908 guint tot_len, desclen, plen;
913 if (isreq && iscdb) {
914 flags = tvb_get_guint8 (tvb, offset);
916 proto_tree_add_uint_format (tree, hf_scsi_modesel_flags, tvb, offset, 1,
917 flags, "PF = %u, SP = %u", flags & 0x10,
919 proto_tree_add_item (tree, hf_scsi_paramlen, tvb, offset+3, 1, 0);
921 flags = tvb_get_guint8 (tvb, offset+4);
922 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
924 "Vendor Unique = %u, NACA = %u, Link = %u",
925 flags & 0xC0, flags & 0x4, flags & 0x1);
928 /* Mode Parameter has the following format:
929 * Mode Parameter Header
930 * - Mode Data Len, Medium Type, Dev Specific Parameter,
932 * Block Descriptor (s)
933 * - Number of blocks, density code, block length
935 * - Page code, Page length, Page Parameters
937 tot_len = tvb_get_guint8 (tvb, offset);
938 proto_tree_add_text (tree, tvb, offset, 1, "Mode Data Length: %u",
940 proto_tree_add_text (tree, tvb, offset+1, 1, "Medium Type: 0x%02x",
941 tvb_get_guint8 (tvb, offset+1));
942 proto_tree_add_text (tree, tvb, offset+2, 1,
943 "Device-Specific Parameter: 0x%02x",
944 tvb_get_guint8 (tvb, offset+2));
945 desclen = tvb_get_guint8 (tvb, offset+3);
946 proto_tree_add_text (tree, tvb, offset+3, 1,
947 "Block Descriptor Length: %u", desclen);
949 tot_len -= 3; /* tot_len does not include the len field */
951 proto_tree_add_text (tree, tvb, offset, 4, "No. of Blocks: %u",
952 tvb_get_ntohl (tvb, offset));
953 proto_tree_add_text (tree, tvb, offset+4, 1, "Density Code: 0x%02x",
954 tvb_get_guint8 (tvb, offset+4));
955 proto_tree_add_text (tree, tvb, offset+5, 3, "Block Length: %u",
956 tvb_get_ntoh24 (tvb, offset+5));
957 offset += 8; /* increment the offset by 8 */
958 tot_len -= 8; /* subtract by the block desc len */
960 /* offset points to the start of the mode page */
961 while ((tot_len > offset) && tvb_bytes_exist (tvb, offset, 2)) {
962 plen = dissect_scsi_modepage (tvb, pinfo, tree, offset);
969 dissect_scsi_modeselect10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
970 guint offset, gboolean isreq, gboolean iscdb,
975 guint tot_len, desclen, plen;
980 if (isreq && iscdb) {
981 flags = tvb_get_guint8 (tvb, offset);
983 proto_tree_add_uint_format (tree, hf_scsi_modesel_flags, tvb, offset, 1,
984 flags, "PF = %u, SP = %u", flags & 0x10,
986 proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
988 flags = tvb_get_guint8 (tvb, offset+8);
989 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
991 "Vendor Unique = %u, NACA = %u, Link = %u",
992 flags & 0xC0, flags & 0x4, flags & 0x1);
995 /* Mode Parameter has the following format:
996 * Mode Parameter Header
997 * - Mode Data Len, Medium Type, Dev Specific Parameter,
999 * Block Descriptor (s)
1000 * - Number of blocks, density code, block length
1002 * - Page code, Page length, Page Parameters
1004 tot_len = tvb_get_ntohs (tvb, offset);
1005 proto_tree_add_text (tree, tvb, offset, 2, "Mode Data Length: %u",
1007 proto_tree_add_text (tree, tvb, offset+2, 1, "Medium Type: 0x%02x",
1008 tvb_get_guint8 (tvb, offset+2));
1009 proto_tree_add_text (tree, tvb, offset+3, 1,
1010 "Device-Specific Parameter: 0x%02x",
1011 tvb_get_guint8 (tvb, offset+3));
1012 longlba = tvb_get_guint8 (tvb, offset+4) & 0x1;
1013 proto_tree_add_text (tree, tvb, offset+4, 1, "LongLBA: %u", longlba);
1014 desclen = tvb_get_guint8 (tvb, offset+6);
1015 proto_tree_add_text (tree, tvb, offset+6, 1,
1016 "Block Descriptor Length: %u", desclen);
1018 tot_len -= 6; /* tot_len does not include the len field */
1020 proto_tree_add_text (tree, tvb, offset, 8, "No. of Blocks: %s",
1021 bytes_to_str (tvb_get_ptr (tvb, offset, 8),
1023 proto_tree_add_text (tree, tvb, offset+8, 1, "Density Code: 0x%02x",
1024 tvb_get_guint8 (tvb, offset+4));
1025 proto_tree_add_text (tree, tvb, offset+12, 4, "Block Length: %u",
1026 tvb_get_ntohl (tvb, offset+12));
1027 offset += 16; /* increment the offset by 8 */
1028 tot_len -= 16; /* subtract by the block desc len */
1030 /* offset points to the start of the mode page */
1031 while ((tot_len > offset) && tvb_bytes_exist (tvb, offset, 2)) {
1032 offset += dissect_scsi_modepage (tvb, pinfo, tree, offset);
1038 dissect_scsi_modesense6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1039 guint offset, gboolean isreq, gboolean iscdb,
1042 guint8 flags, pcode;
1043 guint tot_len, desclen, plen;
1048 if (isreq && iscdb) {
1049 flags = tvb_get_guint8 (tvb, offset);
1051 proto_tree_add_uint_format (tree, hf_scsi_modesns_flags, tvb, offset, 1,
1052 flags, "DBD = %u", flags & 0x8);
1053 proto_tree_add_item (tree, hf_scsi_modesns_pc, tvb, offset+1, 1, 0);
1054 proto_tree_add_item (tree, hf_scsi_modesns_pagecode, tvb, offset+1, 1,
1056 proto_tree_add_item (tree, hf_scsi_alloclen, tvb, offset+3, 1, 0);
1058 flags = tvb_get_guint8 (tvb, offset+4);
1059 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1061 "Vendor Unique = %u, NACA = %u, Link = %u",
1062 flags & 0xC0, flags & 0x4, flags & 0x1);
1065 /* Mode sense response has the following format:
1066 * Mode Parameter Header
1067 * - Mode Data Len, Medium Type, Dev Specific Parameter,
1069 * Block Descriptor (s)
1070 * - Number of blocks, density code, block length
1072 * - Page code, Page length, Page Parameters
1074 tot_len = tvb_get_guint8 (tvb, offset);
1075 proto_tree_add_text (tree, tvb, offset, 1, "Mode Data Length: %u",
1077 proto_tree_add_text (tree, tvb, offset+1, 1, "Medium Type: 0x%02x",
1078 tvb_get_guint8 (tvb, offset+1));
1079 proto_tree_add_text (tree, tvb, offset+2, 1,
1080 "Device-Specific Parameter: 0x%02x",
1081 tvb_get_guint8 (tvb, offset+2));
1082 desclen = tvb_get_guint8 (tvb, offset+3);
1083 proto_tree_add_text (tree, tvb, offset+3, 1,
1084 "Block Descriptor Length: %u", desclen);
1086 /* The actual payload is the min of the length in the response & the
1087 * space allocated by the initiator as specified in the request.
1089 if (payload_len && (tot_len > payload_len))
1090 tot_len = payload_len;
1092 proto_tree_add_text (tree, tvb, offset, 4, "No. of Blocks: %u",
1093 tvb_get_ntohl (tvb, offset));
1094 proto_tree_add_text (tree, tvb, offset+4, 1, "Density Code: 0x%02x",
1095 tvb_get_guint8 (tvb, offset+4));
1096 proto_tree_add_text (tree, tvb, offset+5, 3, "Block Length: %u",
1097 tvb_get_ntoh24 (tvb, offset+5));
1098 offset += 8; /* increment the offset by 8 */
1100 /* offset points to the start of the mode page */
1101 while ((tot_len > offset) && tvb_bytes_exist (tvb, offset, 2)) {
1102 plen = dissect_scsi_modepage (tvb, pinfo, tree, offset);
1109 dissect_scsi_modesense10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1110 guint offset, gboolean isreq, gboolean iscdb,
1113 guint8 flags, pcode;
1115 guint tot_len, desclen, plen;
1120 if (isreq && iscdb) {
1121 flags = tvb_get_guint8 (tvb, offset);
1123 proto_tree_add_uint_format (tree, hf_scsi_modesns_flags, tvb, offset, 1,
1124 flags, "LLBAA = %u, DBD = %u", flags & 0x10,
1126 proto_tree_add_item (tree, hf_scsi_modesns_pc, tvb, offset+1, 1, 0);
1127 proto_tree_add_item (tree, hf_scsi_modesns_pagecode, tvb, offset+1, 1,
1129 proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
1131 flags = tvb_get_guint8 (tvb, offset+8);
1132 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1134 "Vendor Unique = %u, NACA = %u, Link = %u",
1135 flags & 0xC0, flags & 0x4, flags & 0x1);
1138 /* Mode sense response has the following format:
1139 * Mode Parameter Header
1140 * - Mode Data Len, Medium Type, Dev Specific Parameter,
1142 * Block Descriptor (s)
1143 * - Number of blocks, density code, block length
1145 * - Page code, Page length, Page Parameters
1147 tot_len = tvb_get_ntohs (tvb, offset);
1148 proto_tree_add_text (tree, tvb, offset, 2, "Mode Data Length: %u",
1150 proto_tree_add_text (tree, tvb, offset+2, 1, "Medium Type: 0x%02x",
1151 tvb_get_guint8 (tvb, offset+2));
1152 proto_tree_add_text (tree, tvb, offset+3, 1,
1153 "Device-Specific Parameter: 0x%02x",
1154 tvb_get_guint8 (tvb, offset+3));
1155 longlba = tvb_get_guint8 (tvb, offset+4) & 0x1;
1156 proto_tree_add_text (tree, tvb, offset+4, 1, "LongLBA: %u", longlba);
1157 desclen = tvb_get_guint8 (tvb, offset+6);
1158 proto_tree_add_text (tree, tvb, offset+6, 1,
1159 "Block Descriptor Length: %u", desclen);
1161 tot_len -= 6; /* tot_len does not include the len field */
1163 proto_tree_add_text (tree, tvb, offset, 8, "No. of Blocks: %s",
1164 bytes_to_str (tvb_get_ptr (tvb, offset, 8),
1166 proto_tree_add_text (tree, tvb, offset+8, 1, "Density Code: 0x%02x",
1167 tvb_get_guint8 (tvb, offset+4));
1168 proto_tree_add_text (tree, tvb, offset+12, 4, "Block Length: %u",
1169 tvb_get_ntohl (tvb, offset+12));
1170 offset += 16; /* increment the offset by 8 */
1171 tot_len -= 16; /* subtract by the block desc len */
1173 /* offset points to the start of the mode page */
1174 while ((tot_len > offset) && tvb_bytes_exist (tvb, offset, 2)) {
1175 offset += dissect_scsi_modepage (tvb, pinfo, tree, offset);
1181 dissect_scsi_persresvin (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1182 guint offset, gboolean isreq, gboolean iscdb,
1183 scsi_task_data_t *cdata, guint payload_len)
1192 if (isreq && iscdb) {
1193 proto_tree_add_item (tree, hf_scsi_persresvin_svcaction, tvb, offset+1,
1195 proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
1197 flags = tvb_get_guint8 (tvb, offset+8);
1198 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1200 "Vendor Unique = %u, NACA = %u, Link = %u",
1201 flags & 0xC0, flags & 0x4, flags & 0x1);
1202 /* We store the service action since we want to interpret the data */
1203 cdata->flags = tvb_get_guint8 (tvb, offset+1);
1207 flags = cdata->flags;
1212 proto_tree_add_text (tree, tvb, offset, 4, "Generation Number: 0x%08x",
1213 tvb_get_ntohl (tvb, offset));
1214 len = tvb_get_ntohl (tvb, offset+4);
1215 proto_tree_add_text (tree, tvb, offset, 4, "Additional Length: %u",
1217 len = (payload_len > len) ? len : payload_len;
1219 if ((flags & 0x1F) == SCSI_SPC2_RESVIN_SVCA_RDKEYS) {
1220 /* XXX - what if len is < 8? That may be illegal, but
1221 that doesn't make it impossible.... */
1222 numrec = (len - 8)/8;
1225 for (i = 0; i < numrec; i++) {
1226 proto_tree_add_item (tree, hf_scsi_persresv_key, tvb, offset,
1231 else if ((flags & 0x1F) == SCSI_SPC2_RESVIN_SVCA_RDRESV) {
1232 proto_tree_add_item (tree, hf_scsi_persresv_key, tvb, offset+8,
1234 proto_tree_add_item (tree, hf_scsi_persresv_scopeaddr, tvb,
1236 proto_tree_add_item (tree, hf_scsi_persresv_scope, tvb, offset+13,
1238 proto_tree_add_item (tree, hf_scsi_persresv_type, tvb, offset+13,
1245 dissect_scsi_persresvout (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1246 guint offset, gboolean isreq, gboolean iscdb,
1247 scsi_task_data_t *cdata, guint payload_len)
1254 if (isreq && iscdb) {
1255 proto_tree_add_item (tree, hf_scsi_persresvin_svcaction, tvb, offset,
1257 proto_tree_add_item (tree, hf_scsi_persresv_scope, tvb, offset+1, 1, 0);
1258 proto_tree_add_item (tree, hf_scsi_persresv_type, tvb, offset+1, 1, 0);
1259 proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
1261 flags = tvb_get_guint8 (tvb, offset+8);
1262 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1264 "Vendor Unique = %u, NACA = %u, Link = %u",
1265 flags & 0xC0, flags & 0x4, flags & 0x1);
1272 dissect_scsi_release6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1273 guint offset, gboolean isreq, gboolean iscdb)
1280 if (isreq && iscdb) {
1281 flags = tvb_get_guint8 (tvb, offset+4);
1282 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1284 "Vendor Unique = %u, NACA = %u, Link = %u",
1285 flags & 0xC0, flags & 0x4, flags & 0x1);
1290 dissect_scsi_release10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1291 guint offset, gboolean isreq, gboolean iscdb)
1298 if (isreq && iscdb) {
1299 flags = tvb_get_guint8 (tvb, offset);
1301 proto_tree_add_uint_format (tree, hf_scsi_release_flags, tvb, offset, 1,
1303 "Flags: 3rd Party ID = %u, LongID = %u",
1304 flags & 0x10, flags & 0x2);
1305 if ((flags & 0x12) == 0x10) {
1306 proto_tree_add_item (tree, hf_scsi_release_thirdpartyid, tvb,
1309 proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
1311 flags = tvb_get_guint8 (tvb, offset+8);
1312 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1314 "Vendor Unique = %u, NACA = %u, Link = %u",
1315 flags & 0xC0, flags & 0x4, flags & 0x1);
1320 dissect_scsi_reportdeviceid (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1321 guint offset, gboolean isreq, gboolean iscdb)
1327 dissect_scsi_reportluns (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1328 guint offset, gboolean isreq, gboolean iscdb)
1336 if (isreq && iscdb) {
1337 proto_tree_add_item (tree, hf_scsi_alloclen32, tvb, offset+5, 4, 0);
1339 flags = tvb_get_guint8 (tvb, offset+10);
1340 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
1342 "Vendor Unique = %u, NACA = %u, Link = %u",
1343 flags & 0xC0, flags & 0x4, flags & 0x1);
1346 numelem = tvb_get_ntohl (tvb, offset);
1347 proto_tree_add_text (tree, tvb, offset, 4, "LUN List Length: %u",
1350 for (i = 0; i < numelem/8; i++) {
1351 if (!tvb_get_guint8 (tvb, offset))
1352 proto_tree_add_item (tree, hf_scsi_rluns_lun, tvb, offset+1, 1,
1355 proto_tree_add_item (tree, hf_scsi_rluns_multilun, tvb, offset,
1363 dissect_scsi_reqsense (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1364 guint offset, gboolean isreq, gboolean iscdb)
1371 if (isreq && iscdb) {
1372 proto_tree_add_item (tree, hf_scsi_alloclen, tvb, offset+3, 1, 0);
1374 flags = tvb_get_guint8 (tvb, offset+4);
1375 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1377 "Vendor Unique = %u, NACA = %u, Link = %u",
1378 flags & 0xC0, flags & 0x4, flags & 0x1);
1383 dissect_scsi_reserve6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1384 guint offset, gboolean isreq, gboolean iscdb)
1391 if (isreq && iscdb) {
1392 flags = tvb_get_guint8 (tvb, offset+4);
1393 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1395 "Vendor Unique = %u, NACA = %u, Link = %u",
1396 flags & 0xC0, flags & 0x4, flags & 0x1);
1401 dissect_scsi_reserve10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1402 guint offset, gboolean isreq, gboolean iscdb)
1409 if (isreq && iscdb) {
1410 flags = tvb_get_guint8 (tvb, offset);
1412 proto_tree_add_uint_format (tree, hf_scsi_release_flags, tvb, offset, 1,
1414 "Flags: 3rd Party ID = %u, LongID = %u",
1415 flags & 0x10, flags & 0x2);
1416 if ((flags & 0x12) == 0x10) {
1417 proto_tree_add_item (tree, hf_scsi_release_thirdpartyid, tvb,
1420 proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
1422 flags = tvb_get_guint8 (tvb, offset+8);
1423 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1425 "Vendor Unique = %u, NACA = %u, Link = %u",
1426 flags & 0xC0, flags & 0x4, flags & 0x1);
1431 dissect_scsi_testunitrdy (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1432 guint offset, gboolean isreq, gboolean iscdb)
1439 if (isreq && iscdb) {
1440 flags = tvb_get_guint8 (tvb, offset+4);
1441 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1443 "Vendor Unique = %u, NACA = %u, Link = %u",
1444 flags & 0xC0, flags & 0x4, flags & 0x1);
1449 dissect_scsi_formatunit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1450 guint offset, gboolean isreq, gboolean iscdb)
1457 if (isreq && iscdb) {
1458 flags = tvb_get_guint8 (tvb, offset);
1459 proto_tree_add_uint_format (tree, hf_scsi_formatunit_flags, tvb, offset,
1461 "Flags: Longlist = %u, FMTDATA = %u, CMPLIST = %u",
1462 flags & 0x20, flags & 0x8, flags & 0x4);
1463 proto_tree_add_item (tree, hf_scsi_cdb_defectfmt, tvb, offset, 1, 0);
1464 proto_tree_add_item (tree, hf_scsi_formatunit_vendor, tvb, offset+1,
1466 proto_tree_add_item (tree, hf_scsi_formatunit_interleave, tvb, offset+2,
1468 flags = tvb_get_guint8 (tvb, offset+4);
1469 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1471 "Vendor Unique = %u, NACA = %u, Link = %u",
1472 flags & 0xC0, flags & 0x4, flags & 0x1);
1477 dissect_scsi_rdwr6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1478 guint offset, gboolean isreq, gboolean iscdb)
1483 if (check_col (pinfo->cinfo, COL_INFO))
1484 col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%06x, Len: %u)",
1485 tvb_get_ntoh24 (tvb, offset),
1486 tvb_get_guint8 (tvb, offset+3));
1489 if (tree && isreq && iscdb) {
1490 proto_tree_add_item (tree, hf_scsi_rdwr6_lba, tvb, offset, 3, 0);
1491 proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+3, 1, 0);
1492 flags = tvb_get_guint8 (tvb, offset+4);
1493 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1495 "Vendor Unique = %u, NACA = %u, Link = %u",
1496 flags & 0xC0, flags & 0x4, flags & 0x1);
1501 dissect_scsi_rdwr10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1502 guint offset, gboolean isreq, gboolean iscdb)
1507 if (check_col (pinfo->cinfo, COL_INFO))
1508 col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
1509 tvb_get_ntohl (tvb, offset+1),
1510 tvb_get_ntohs (tvb, offset+6));
1513 if (tree && isreq && iscdb) {
1514 flags = tvb_get_guint8 (tvb, offset);
1516 proto_tree_add_uint_format (tree, hf_scsi_read_flags, tvb, offset, 1,
1518 "DPO = %u, FUA = %u, RelAddr = %u",
1519 flags & 0x10, flags & 0x8, flags & 0x1);
1520 proto_tree_add_item (tree, hf_scsi_rdwr10_lba, tvb, offset+1, 4, 0);
1521 proto_tree_add_item (tree, hf_scsi_rdwr10_xferlen, tvb, offset+6, 2, 0);
1522 flags = tvb_get_guint8 (tvb, offset+8);
1523 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1525 "Vendor Unique = %u, NACA = %u, Link = %u",
1526 flags & 0xC0, flags & 0x4, flags & 0x1);
1531 dissect_scsi_rdwr12 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1532 guint offset, gboolean isreq, gboolean iscdb)
1537 if (check_col (pinfo->cinfo, COL_INFO))
1538 col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
1539 tvb_get_ntohl (tvb, offset+1),
1540 tvb_get_ntohl (tvb, offset+5));
1543 if (tree && isreq && iscdb) {
1544 flags = tvb_get_guint8 (tvb, offset);
1546 proto_tree_add_uint_format (tree, hf_scsi_read_flags, tvb, offset, 1,
1548 "DPO = %u, FUA = %u, RelAddr = %u",
1549 flags & 0x10, flags & 0x8, flags & 0x1);
1550 proto_tree_add_item (tree, hf_scsi_rdwr10_lba, tvb, offset+1, 4, 0);
1551 proto_tree_add_item (tree, hf_scsi_rdwr12_xferlen, tvb, offset+5, 4, 0);
1552 flags = tvb_get_guint8 (tvb, offset+10);
1553 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
1555 "Vendor Unique = %u, NACA = %u, Link = %u",
1556 flags & 0xC0, flags & 0x4, flags & 0x1);
1561 dissect_scsi_rdwr16 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1562 guint offset, gboolean isreq, gboolean iscdb)
1566 if (tree && isreq && iscdb) {
1567 flags = tvb_get_guint8 (tvb, offset);
1569 proto_tree_add_uint_format (tree, hf_scsi_read_flags, tvb, offset, 1,
1571 "DPO = %u, FUA = %u, RelAddr = %u",
1572 flags & 0x10, flags & 0x8, flags & 0x1);
1573 proto_tree_add_item (tree, hf_scsi_rdwr16_lba, tvb, offset+1, 8, 0);
1574 proto_tree_add_item (tree, hf_scsi_rdwr12_xferlen, tvb, offset+9, 4, 0);
1575 flags = tvb_get_guint8 (tvb, offset+14);
1576 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+14, 1,
1578 "Vendor Unique = %u, NACA = %u, Link = %u",
1579 flags & 0xC0, flags & 0x4, flags & 0x1);
1584 dissect_scsi_readcapacity (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1585 guint offset, gboolean isreq, gboolean iscdb)
1593 if (isreq && iscdb) {
1594 flags = tvb_get_guint8 (tvb, offset);
1596 proto_tree_add_uint_format (tree, hf_scsi_readcapacity_flags, tvb,
1598 "LongLBA = %u, RelAddr = %u",
1599 flags & 0x2, flags & 0x1);
1600 proto_tree_add_item (tree, hf_scsi_readcapacity_lba, tvb, offset+1,
1602 proto_tree_add_item (tree, hf_scsi_readcapacity_pmi, tvb, offset+7,
1605 flags = tvb_get_guint8 (tvb, offset+8);
1606 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1608 "Vendor Unique = %u, NACA = %u, Link = %u",
1609 flags & 0xC0, flags & 0x4, flags & 0x1);
1612 len = tvb_get_ntohl (tvb, offset);
1613 proto_tree_add_text (tree, tvb, offset, 4, "LBA: %u (%u MB)",
1614 len, len/(1024*1024));
1615 proto_tree_add_text (tree, tvb, offset+4, 4, "Block Length: %u bytes",
1616 tvb_get_ntohl (tvb, offset+4));
1621 dissect_scsi_readdefdata10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1622 guint offset, gboolean isreq, gboolean iscdb)
1629 if (isreq && iscdb) {
1630 flags = tvb_get_guint8 (tvb, offset);
1632 proto_tree_add_uint_format (tree, hf_scsi_readdefdata_flags, tvb,
1633 offset, 1, flags, "PLIST = %u, GLIST = %u",
1634 flags & 0x10, flags & 0x8);
1635 proto_tree_add_item (tree, hf_scsi_cdb_defectfmt, tvb, offset, 1, 0);
1636 proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
1637 flags = tvb_get_guint8 (tvb, offset+8);
1638 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1640 "Vendor Unique = %u, NACA = %u, Link = %u",
1641 flags & 0xC0, flags & 0x4, flags & 0x1);
1646 dissect_scsi_readdefdata12 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1647 guint offset, gboolean isreq, gboolean iscdb)
1654 if (isreq && iscdb) {
1655 flags = tvb_get_guint8 (tvb, offset);
1657 proto_tree_add_uint_format (tree, hf_scsi_readdefdata_flags, tvb,
1658 offset, 1, flags, "PLIST = %u, GLIST = %u",
1659 flags & 0x10, flags & 0x8);
1660 proto_tree_add_item (tree, hf_scsi_cdb_defectfmt, tvb, offset, 1, 0);
1661 proto_tree_add_item (tree, hf_scsi_alloclen32, tvb, offset+5, 4, 0);
1662 flags = tvb_get_guint8 (tvb, offset+10);
1663 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
1665 "Vendor Unique = %u, NACA = %u, Link = %u",
1666 flags & 0xC0, flags & 0x4, flags & 0x1);
1671 dissect_scsi_reassignblks (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1672 guint offset, gboolean isreq, gboolean iscdb)
1679 if (isreq && iscdb) {
1680 flags = tvb_get_guint8 (tvb, offset);
1682 proto_tree_add_uint_format (tree, hf_scsi_reassignblks_flags, tvb,
1684 "LongLBA = %u, LongList = %u",
1685 flags & 0x2, flags & 0x1);
1686 flags = tvb_get_guint8 (tvb, offset+4);
1687 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1689 "Vendor Unique = %u, NACA = %u, Link = %u",
1690 flags & 0xC0, flags & 0x4, flags & 0x1);
1695 dissect_scsi_rsp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1697 /* Nothing to do here, just blow up the data structures for this SCSI
1700 scsi_end_task (pinfo);
1705 dissect_scsi_snsinfo (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1706 guint offset, guint snslen)
1710 proto_tree *sns_tree;
1711 scsi_device_type dev = 0;
1712 scsi_devtype_key_t dkey;
1713 scsi_devtype_data_t *devdata;
1715 scsi_end_task (pinfo);
1718 ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
1719 snslen, "SCSI: SNS Info");
1720 sns_tree = proto_item_add_subtree (ti, ett_scsi);
1722 flags = tvb_get_guint8 (tvb, offset);
1723 proto_tree_add_text (sns_tree, tvb, offset, 1, "Valid: %u",
1724 (flags & 0x80) >> 7);
1725 proto_tree_add_item (sns_tree, hf_scsi_sns_errtype, tvb, offset, 1, 0);
1726 flags = tvb_get_guint8 (tvb, offset+2);
1727 proto_tree_add_text (sns_tree, tvb, offset+2, 1,
1728 "Filemark: %u, EOM: %u, ILI: %u",
1729 (flags & 0x80) >> 7, (flags & 0x40) >> 6,
1730 (flags & 0x20) >> 5);
1731 proto_tree_add_item (sns_tree, hf_scsi_snskey, tvb, offset+2, 1, 0);
1732 proto_tree_add_item (sns_tree, hf_scsi_snsinfo, tvb, offset+3, 4, 0);
1733 proto_tree_add_item (sns_tree, hf_scsi_addlsnslen, tvb, offset+7, 1, 0);
1734 proto_tree_add_text (sns_tree, tvb, offset+8, 4,
1735 "Command-Specific Information: %s",
1736 tvb_bytes_to_str (tvb, offset+8, 4));
1737 proto_tree_add_item (sns_tree, hf_scsi_ascascq, tvb, offset+12, 2, 0);
1738 proto_tree_add_item_hidden (sns_tree, hf_scsi_asc, tvb, offset+12, 1, 0);
1739 proto_tree_add_item_hidden (sns_tree, hf_scsi_ascq, tvb, offset+13,
1741 proto_tree_add_item (sns_tree, hf_scsi_fru, tvb, offset+14, 1, 0);
1742 proto_tree_add_item (sns_tree, hf_scsi_sksv, tvb, offset+15, 1, 0);
1743 proto_tree_add_text (sns_tree, tvb, offset+15, 3,
1744 "Sense Key Specific: %s",
1745 tvb_bytes_to_str (tvb, offset+15, 3));
1750 dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1751 guint start, guint cdblen)
1755 proto_tree *scsi_tree = NULL;
1757 scsi_cmnd_type cmd = 0; /* 0 is undefined type */
1758 scsi_device_type devtype = 0;
1760 conversation_t *conversation;
1761 scsi_task_data_t *cdata;
1762 scsi_task_key_t ckey, *req_key;
1763 scsi_devtype_key_t dkey;
1764 scsi_devtype_data_t *devdata;
1766 opcode = tvb_get_guint8 (tvb, offset);
1768 /* Identify target if possible */
1769 COPY_ADDRESS (&(dkey.devid), &pinfo->dst);
1771 devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
1773 if (devdata != NULL) {
1774 devtype = devdata->devtype;
1777 devtype = (scsi_device_type)scsi_def_devtype;
1780 if ((valstr = match_strval (opcode, scsi_spc2_val)) == NULL) {
1781 if (devtype == SCSI_DEV_SBC) {
1782 valstr = match_strval (opcode, scsi_sbc2_val);
1783 cmd = SCSI_CMND_SBC2;
1786 /* Right now, the only choices are SBC or SSC. If we ever expand
1787 * this to decode other device types, this piece of code needs to
1790 valstr = match_strval (opcode, scsi_ssc2_val);
1791 cmd = SCSI_CMND_SSC2;
1795 cmd = SCSI_CMND_SPC2;
1798 if (valstr != NULL) {
1799 if (check_col (pinfo->cinfo, COL_INFO)) {
1800 col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI: %s", valstr);
1804 if (check_col (pinfo->cinfo, COL_INFO)) {
1805 col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI Command: 0x%02x", opcode);
1809 cdata = scsi_new_task (pinfo);
1812 cdata->opcode = opcode;
1813 cdata->devtype = cmd;
1817 ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, start,
1818 cdblen, "SCSI CDB");
1819 scsi_tree = proto_item_add_subtree (ti, ett_scsi);
1821 if (valstr != NULL) {
1822 if (cmd == SCSI_CMND_SPC2) {
1823 proto_tree_add_uint_format (scsi_tree, hf_scsi_spcopcode, tvb,
1825 tvb_get_guint8 (tvb, offset),
1826 "Opcode: %s (0x%02x)", valstr,
1829 else if (cmd == SCSI_CMND_SBC2) {
1830 proto_tree_add_uint_format (scsi_tree, hf_scsi_sbcopcode, tvb,
1832 tvb_get_guint8 (tvb, offset),
1833 "Opcode: %s (0x%02x)", valstr,
1837 proto_tree_add_uint_format (scsi_tree, hf_scsi_sscopcode, tvb,
1839 tvb_get_guint8 (tvb, offset),
1840 "Opcode: %s (0x%02x)", valstr,
1845 proto_tree_add_item (scsi_tree, hf_scsi_sbcopcode, tvb, offset, 1, 0);
1849 if (cmd == SCSI_CMND_SPC2) {
1851 case SCSI_SPC2_INQUIRY:
1852 dissect_scsi_inquiry (tvb, pinfo, scsi_tree, offset+1, TRUE,
1856 case SCSI_SPC2_EXTCOPY:
1857 dissect_scsi_extcopy (tvb, pinfo, scsi_tree, offset+1, TRUE,
1861 case SCSI_SPC2_LOGSELECT:
1862 dissect_scsi_logselect (tvb, pinfo, scsi_tree, offset+1, TRUE,
1866 case SCSI_SPC2_LOGSENSE:
1867 dissect_scsi_logsense (tvb, pinfo, scsi_tree, offset+1, TRUE,
1871 case SCSI_SPC2_MODESELECT6:
1872 dissect_scsi_modeselect6 (tvb, pinfo, scsi_tree, offset+1,
1876 case SCSI_SPC2_MODESELECT10:
1877 dissect_scsi_modeselect10 (tvb, pinfo, scsi_tree, offset+1,
1881 case SCSI_SPC2_MODESENSE6:
1882 dissect_scsi_modesense6 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1886 case SCSI_SPC2_MODESENSE10:
1887 dissect_scsi_modesense10 (tvb, pinfo, scsi_tree, offset+1,
1891 case SCSI_SPC2_PERSRESVIN:
1892 dissect_scsi_persresvin (tvb, pinfo, scsi_tree, offset+1, TRUE,
1896 case SCSI_SPC2_PERSRESVOUT:
1897 dissect_scsi_persresvout (tvb, pinfo, scsi_tree, offset+1,
1898 TRUE, TRUE, cdata, 0);
1901 case SCSI_SPC2_RELEASE6:
1902 dissect_scsi_release6 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1906 case SCSI_SPC2_RELEASE10:
1907 dissect_scsi_release10 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1911 case SCSI_SPC2_REPORTDEVICEID:
1912 dissect_scsi_reportdeviceid (tvb, pinfo, scsi_tree, offset+1,
1916 case SCSI_SPC2_REPORTLUNS:
1917 dissect_scsi_reportluns (tvb, pinfo, scsi_tree, offset+1, TRUE,
1921 case SCSI_SPC2_REQSENSE:
1922 dissect_scsi_reqsense (tvb, pinfo, scsi_tree, offset+1, TRUE,
1926 case SCSI_SPC2_RESERVE6:
1927 dissect_scsi_reserve6 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1931 case SCSI_SPC2_RESERVE10:
1932 dissect_scsi_reserve10 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1936 case SCSI_SPC2_TESTUNITRDY:
1937 dissect_scsi_testunitrdy (tvb, pinfo, scsi_tree, offset+1,
1942 call_dissector (data_handle, tvb, pinfo, scsi_tree);
1946 else if (cmd == SCSI_CMND_SBC2) {
1949 case SCSI_SBC2_FORMATUNIT:
1950 dissect_scsi_formatunit (tvb, pinfo, scsi_tree, offset+1, TRUE,
1954 case SCSI_SBC2_READ6:
1955 dissect_scsi_rdwr6 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1959 case SCSI_SBC2_READ10:
1960 dissect_scsi_rdwr10 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1964 case SCSI_SBC2_READ12:
1965 dissect_scsi_rdwr12 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1969 case SCSI_SBC2_READ16:
1970 dissect_scsi_rdwr16 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1974 case SCSI_SBC2_READCAPACITY:
1975 dissect_scsi_readcapacity (tvb, pinfo, scsi_tree, offset+1,
1979 case SCSI_SBC2_READDEFDATA10:
1980 dissect_scsi_readdefdata10 (tvb, pinfo, scsi_tree, offset+1,
1984 case SCSI_SBC2_READDEFDATA12:
1985 dissect_scsi_readdefdata12 (tvb, pinfo, scsi_tree, offset+1,
1989 case SCSI_SBC2_REASSIGNBLKS:
1990 dissect_scsi_reassignblks (tvb, pinfo, scsi_tree, offset+1,
1994 case SCSI_SBC2_WRITE6:
1995 dissect_scsi_rdwr6 (tvb, pinfo, scsi_tree, offset+1, TRUE,
1999 case SCSI_SBC2_WRITE10:
2000 dissect_scsi_rdwr10 (tvb, pinfo, scsi_tree, offset+1, TRUE,
2004 case SCSI_SBC2_WRITE12:
2005 dissect_scsi_rdwr12 (tvb, pinfo, scsi_tree, offset+1, TRUE,
2009 case SCSI_SBC2_WRITE16:
2010 dissect_scsi_rdwr16 (tvb, pinfo, scsi_tree, offset+1, TRUE,
2015 call_dissector (data_handle, tvb, pinfo, scsi_tree);
2019 else if (cmd == SCSI_CMND_SSC2) {
2020 call_dissector (data_handle, tvb, pinfo, scsi_tree);
2025 dissect_scsi (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2030 dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2031 guint offset, gboolean isreq, guint32 payload_len)
2034 proto_tree *scsi_tree;
2035 guint8 opcode = 0xFF;
2036 scsi_cmnd_type cmd = 0; /* 0 is undefined type */
2038 scsi_device_type dev = 0;
2039 scsi_task_data_t *cdata = NULL;
2040 scsi_devtype_key_t dkey;
2041 scsi_devtype_data_t *devdata;
2043 cdata = scsi_find_task (pinfo);
2046 /* we have no record of this exchange and so we can't dissect the
2052 opcode = cdata->opcode;
2053 cmd = cdata->devtype;
2056 if (cmd == SCSI_CMND_SPC2) {
2057 ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
2059 "SCSI Payload (%s %s)",
2063 isreq ? "Request" : "Response");
2065 else if (cmd == SCSI_CMND_SBC2) {
2066 ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
2068 "SCSI Payload (%s %s)",
2072 isreq ? "Request" : "Response");
2075 ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
2077 "SCSI Payload (0x%02x %s)",
2079 isreq ? "Request" : "Response");
2082 scsi_tree = proto_item_add_subtree (ti, ett_scsi);
2084 if (cmd == SCSI_CMND_SPC2) {
2086 case SCSI_SPC2_INQUIRY:
2087 dissect_scsi_inquiry (tvb, pinfo, scsi_tree, offset, isreq,
2088 FALSE, payload_len, cdata);
2091 case SCSI_SPC2_EXTCOPY:
2092 dissect_scsi_extcopy (tvb, pinfo, scsi_tree, offset, isreq,
2096 case SCSI_SPC2_LOGSELECT:
2097 dissect_scsi_logselect (tvb, pinfo, scsi_tree, offset, isreq,
2101 case SCSI_SPC2_LOGSENSE:
2102 dissect_scsi_logsense (tvb, pinfo, scsi_tree, offset, isreq,
2106 case SCSI_SPC2_MODESELECT6:
2107 dissect_scsi_modeselect6 (tvb, pinfo, scsi_tree, offset,
2108 isreq, FALSE, payload_len);
2111 case SCSI_SPC2_MODESELECT10:
2112 dissect_scsi_modeselect10 (tvb, pinfo, scsi_tree, offset,
2113 isreq, FALSE, payload_len);
2116 case SCSI_SPC2_MODESENSE6:
2117 dissect_scsi_modesense6 (tvb, pinfo, scsi_tree, offset, isreq,
2118 FALSE, payload_len);
2121 case SCSI_SPC2_MODESENSE10:
2122 dissect_scsi_modesense10 (tvb, pinfo, scsi_tree, offset,
2123 isreq, FALSE, payload_len);
2126 case SCSI_SPC2_PERSRESVIN:
2127 dissect_scsi_persresvin (tvb, pinfo, scsi_tree, offset, isreq,
2128 FALSE, cdata, payload_len);
2131 case SCSI_SPC2_PERSRESVOUT:
2132 dissect_scsi_persresvout (tvb, pinfo, scsi_tree, offset,
2133 isreq, FALSE, cdata, payload_len);
2136 case SCSI_SPC2_RELEASE6:
2137 dissect_scsi_release6 (tvb, pinfo, scsi_tree, offset, isreq,
2141 case SCSI_SPC2_RELEASE10:
2142 dissect_scsi_release10 (tvb, pinfo, scsi_tree, offset, isreq,
2146 case SCSI_SPC2_REPORTDEVICEID:
2147 dissect_scsi_reportdeviceid (tvb, pinfo, scsi_tree, offset,
2151 case SCSI_SPC2_REPORTLUNS:
2152 dissect_scsi_reportluns (tvb, pinfo, scsi_tree, offset, isreq,
2156 case SCSI_SPC2_REQSENSE:
2157 dissect_scsi_reqsense (tvb, pinfo, scsi_tree, offset, isreq,
2161 case SCSI_SPC2_RESERVE6:
2162 dissect_scsi_reserve6 (tvb, pinfo, scsi_tree, offset, isreq,
2166 case SCSI_SPC2_RESERVE10:
2167 dissect_scsi_reserve10 (tvb, pinfo, scsi_tree, offset, isreq,
2171 case SCSI_SPC2_TESTUNITRDY:
2172 dissect_scsi_testunitrdy (tvb, pinfo, scsi_tree, offset,
2177 call_dissector (data_handle, tvb, pinfo, scsi_tree);
2181 else if (cmd == SCSI_CMND_SBC2) {
2184 case SCSI_SBC2_FORMATUNIT:
2185 dissect_scsi_formatunit (tvb, pinfo, scsi_tree, offset, isreq,
2189 case SCSI_SBC2_READ6:
2190 dissect_scsi_rdwr6 (tvb, pinfo, scsi_tree, offset, isreq,
2194 case SCSI_SBC2_READ10:
2195 dissect_scsi_rdwr10 (tvb, pinfo, scsi_tree, offset, isreq,
2199 case SCSI_SBC2_READ12:
2200 dissect_scsi_rdwr12 (tvb, pinfo, scsi_tree, offset, isreq,
2204 case SCSI_SBC2_READ16:
2205 dissect_scsi_rdwr16 (tvb, pinfo, scsi_tree, offset, isreq,
2209 case SCSI_SBC2_READCAPACITY:
2210 dissect_scsi_readcapacity (tvb, pinfo, scsi_tree, offset,
2214 case SCSI_SBC2_READDEFDATA10:
2215 dissect_scsi_readdefdata10 (tvb, pinfo, scsi_tree, offset,
2219 case SCSI_SBC2_READDEFDATA12:
2220 dissect_scsi_readdefdata12 (tvb, pinfo, scsi_tree, offset,
2224 case SCSI_SBC2_REASSIGNBLKS:
2225 dissect_scsi_reassignblks (tvb, pinfo, scsi_tree, offset,
2229 case SCSI_SBC2_WRITE6:
2230 dissect_scsi_rdwr6 (tvb, pinfo, scsi_tree, offset, isreq,
2234 case SCSI_SBC2_WRITE10:
2235 dissect_scsi_rdwr10 (tvb, pinfo, scsi_tree, offset, isreq,
2239 case SCSI_SBC2_WRITE12:
2240 dissect_scsi_rdwr12 (tvb, pinfo, scsi_tree, offset, isreq,
2244 case SCSI_SBC2_WRITE16:
2245 dissect_scsi_rdwr16 (tvb, pinfo, scsi_tree, offset, isreq,
2250 call_dissector (data_handle, tvb, pinfo, scsi_tree);
2255 call_dissector (data_handle, tvb, pinfo, scsi_tree);
2261 proto_register_scsi (void)
2263 /* Setup list of header fields See Section 1.6.1 for details*/
2264 static hf_register_info hf[] = {
2265 { &hf_scsi_spcopcode,
2266 {"SPC-2 Opcode", "scsi.spc.opcode", FT_UINT8, BASE_HEX,
2267 VALS (scsi_spc2_val), 0x0, "", HFILL}},
2268 { &hf_scsi_sbcopcode,
2269 {"SBC-2 Opcode", "scsi.sbc.opcode", FT_UINT8, BASE_HEX,
2270 VALS (scsi_sbc2_val), 0x0, "", HFILL}},
2271 { &hf_scsi_sscopcode,
2272 {"SSC-2 Opcode", "scsi.ssc.opcode", FT_UINT8, BASE_HEX,
2273 VALS (scsi_ssc2_val), 0x0, "", HFILL}},
2275 {"Control", "scsi.cdb.control", FT_UINT8, BASE_HEX, NULL, 0x0, "",
2277 { &hf_scsi_inquiry_flags,
2278 {"Flags", "scsi.inquiry.flags", FT_UINT8, BASE_BIN, NULL, 0x0, "",
2280 { &hf_scsi_inquiry_evpd_page,
2281 {"EVPD Page Code", "scsi.inquiry.evpd.pagecode", FT_UINT8, BASE_HEX,
2282 VALS (scsi_evpd_pagecode_val), 0x0, "", HFILL}},
2283 { &hf_scsi_inquiry_cmdt_page,
2284 {"CMDT Page Code", "scsi.inquiry.cmdt.pagecode", FT_UINT8, BASE_HEX,
2285 NULL, 0x0, "", HFILL}},
2286 { &hf_scsi_alloclen,
2287 {"Allocation Length", "scsi.cdb.alloclen", FT_UINT8, BASE_DEC, NULL,
2289 { &hf_scsi_logsel_flags,
2290 {"Flags", "scsi.logsel.flags", FT_UINT8, BASE_BIN, NULL, 0x0, "",
2293 {"Page Control", "scsi.log.pc", FT_UINT8, BASE_BIN,
2294 VALS (scsi_logsel_pc_val), 0xC0, "", HFILL}},
2295 { &hf_scsi_paramlen,
2296 {"Parameter Length", "scsi.cdb.paramlen", FT_UINT8, BASE_DEC, NULL,
2298 { &hf_scsi_logsns_flags,
2299 {"Flags", "scsi.logsns.flags", FT_UINT16, BASE_BIN, NULL, 0x0, "",
2301 { &hf_scsi_logsns_pagecode,
2302 {"Page Code", "scsi.logsns.pagecode", FT_UINT8, BASE_HEX,
2303 VALS (scsi_logsns_page_val), 0x3F0, "", HFILL}},
2304 { &hf_scsi_paramlen16,
2305 {"Parameter Length", "scsi.cdb.paramlen16", FT_UINT16, BASE_DEC, NULL,
2307 { &hf_scsi_modesel_flags,
2308 {"Mode Sense/Select Flags", "scsi.cdb.mode.flags", FT_UINT8, BASE_BIN,
2309 NULL, 0x0, "", HFILL}},
2310 { &hf_scsi_alloclen16,
2311 {"Allocation Length", "scsi.cdb.alloclen16", FT_UINT16, BASE_DEC,
2312 NULL, 0x0, "", HFILL}},
2313 { &hf_scsi_modesns_pc,
2314 {"Page Control", "scsi.mode.pc", FT_UINT8, BASE_BIN,
2315 VALS (scsi_modesns_pc_val), 0xC0, "", HFILL}},
2316 { &hf_scsi_modesns_pagecode,
2317 {"Page Code", "scsi.mode.pagecode", FT_UINT8, BASE_HEX,
2318 VALS (scsi_modesns_page_val), 0x3F, "", HFILL}},
2319 { &hf_scsi_modesns_flags,
2320 {"Flags", "scsi.mode.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
2322 { &hf_scsi_persresvin_svcaction,
2323 {"Service Action", "scsi.persresvin.svcaction", FT_UINT8, BASE_HEX,
2324 VALS (scsi_persresvin_svcaction_val), 0x0F, "", HFILL}},
2325 { &hf_scsi_persresvout_svcaction,
2326 {"Service Action", "scsi.persresvout.svcaction", FT_UINT8, BASE_HEX,
2327 VALS (scsi_persresvout_svcaction_val), 0x0F, "", HFILL}},
2328 { &hf_scsi_persresv_scope,
2329 {"Reservation Scope", "scsi.persresv.scope", FT_UINT8, BASE_HEX,
2330 VALS (scsi_persresv_scope_val), 0xF0, "", HFILL}},
2331 { &hf_scsi_persresv_type,
2332 {"Reservation Type", "scsi.persresv.type", FT_UINT8, BASE_HEX,
2333 VALS (scsi_persresv_type_val), 0x0F, "", HFILL}},
2334 { &hf_scsi_release_flags,
2335 {"Release Flags", "scsi.release.flags", FT_UINT8, BASE_BIN, NULL,
2337 { &hf_scsi_release_thirdpartyid,
2338 {"Third-Party ID", "scsi.release.thirdpartyid", FT_BYTES, BASE_HEX,
2339 NULL, 0x0, "", HFILL}},
2340 { &hf_scsi_alloclen32,
2341 {"Allocation Length", "scsi.cdb.alloclen32", FT_UINT32, BASE_DEC,
2342 NULL, 0x0, "", HFILL}},
2343 { &hf_scsi_formatunit_flags,
2344 {"Flags", "scsi.formatunit.flags", FT_UINT8, BASE_BIN, NULL, 0xF8,
2346 { &hf_scsi_cdb_defectfmt,
2347 {"Defect List Format", "scsi.cdb.defectfmt", FT_UINT8, BASE_BIN,
2348 NULL, 0x7, "", HFILL}},
2349 { &hf_scsi_formatunit_interleave,
2350 {"Interleave", "scsi.formatunit.interleave", FT_UINT16, BASE_HEX,
2351 NULL, 0x0, "", HFILL}},
2352 { &hf_scsi_formatunit_vendor,
2353 {"Vendor Unique", "scsi.formatunit.vendor", FT_UINT8, BASE_HEX, NULL,
2355 { &hf_scsi_rdwr6_lba,
2356 {"Logical Block Address (LBA)", "scsi.rdwr6.lba", FT_UINT24, BASE_DEC,
2357 NULL, 0x0FFFFF, "", HFILL}},
2358 { &hf_scsi_rdwr6_xferlen,
2359 {"Transfer Length", "scsi.rdwr6.xferlen", FT_UINT8, BASE_DEC, NULL, 0x0,
2361 { &hf_scsi_rdwr10_lba,
2362 {"Logical Block Address (LBA)", "scsi.rdwr10.lba", FT_UINT32, BASE_DEC,
2363 NULL, 0x0, "", HFILL}},
2364 { &hf_scsi_rdwr10_xferlen,
2365 {"Transfer Length", "scsi.rdwr10.xferlen", FT_UINT16, BASE_DEC, NULL,
2367 { &hf_scsi_read_flags,
2368 {"Flags", "scsi.read.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
2370 { &hf_scsi_rdwr12_xferlen,
2371 {"Transfer Length", "scsi.rdwr12.xferlen", FT_UINT32, BASE_DEC, NULL,
2373 { &hf_scsi_rdwr16_lba,
2374 {"Logical Block Address (LBA)", "scsi.rdwr16.lba", FT_BYTES, BASE_DEC,
2375 NULL, 0x0, "", HFILL}},
2376 { &hf_scsi_readcapacity_flags,
2377 {"Flags", "scsi.readcapacity.flags", FT_UINT8, BASE_BIN, NULL, 0x0,
2379 { &hf_scsi_readcapacity_lba,
2380 {"Logical Block Address", "scsi.readcapacity.lba", FT_UINT32, BASE_DEC,
2381 NULL, 0x0, "", HFILL}},
2382 { &hf_scsi_readcapacity_pmi,
2383 {"PMI", "scsi.readcapacity.pmi", FT_UINT8, BASE_BIN, NULL, 0x1, "",
2385 { &hf_scsi_readdefdata_flags,
2386 {"Flags", "scsi.readdefdata.flags", FT_UINT8, BASE_BIN, NULL, 0x0, "",
2388 { &hf_scsi_reassignblks_flags,
2389 {"Flags", "scsi.reassignblks.flags", FT_UINT8, BASE_BIN, NULL, 0x0, "",
2391 { &hf_scsi_inq_devtype,
2392 {"Device Type", "scsi.inquiry.devtype", FT_UINT8, BASE_HEX,
2393 VALS (scsi_devtype_val), 0x0F, "", HFILL}},
2394 { & hf_scsi_inq_version,
2395 {"Version", "scsi.inquiry.version", FT_UINT8, BASE_HEX,
2396 VALS (scsi_inquiry_vers_val), 0x0, "", HFILL}},
2397 { &hf_scsi_inq_normaca,
2398 {"NormACA", "scsi.inquiry.normaca", FT_UINT8, BASE_HEX, NULL, 0x20,
2400 { &hf_scsi_rluns_lun,
2401 {"LUN", "scsi.reportluns.lun", FT_UINT8, BASE_DEC, NULL, 0x0, "",
2403 { &hf_scsi_rluns_multilun,
2404 {"Multi-level LUN", "scsi.reportluns.mlun", FT_BYTES, BASE_HEX, NULL,
2406 { &hf_scsi_modesns_errrep,
2407 {"MRIE", "scsi.mode.mrie", FT_UINT8, BASE_HEX,
2408 VALS (scsi_modesns_mrie_val), 0x0F, "", HFILL}},
2409 { &hf_scsi_modesns_tst,
2410 {"Task Set Type", "scsi.mode.tst", FT_UINT8, BASE_BIN,
2411 VALS (scsi_modesns_tst_val), 0xE0, "", HFILL}},
2412 { &hf_scsi_modesns_qmod,
2413 {"Queue Algorithm Modifier", "scsi.mode.qmod", FT_UINT8, BASE_HEX,
2414 VALS (scsi_modesns_qmod_val), 0xF0, "", HFILL}},
2415 { &hf_scsi_modesns_qerr,
2416 {"Queue Error Management", "scsi.mode.qerr", FT_BOOLEAN, BASE_HEX,
2417 TFS (&scsi_modesns_qerr_val), 0x2, "", HFILL}},
2418 { &hf_scsi_modesns_tas,
2419 {"Task Aborted Status", "scsi.mode.tac", FT_BOOLEAN, BASE_HEX,
2420 TFS (&scsi_modesns_tas_val), 0x80, "", HFILL}},
2421 { &hf_scsi_modesns_rac,
2422 {"Report a Check", "ssci.mode.rac", FT_BOOLEAN, BASE_HEX,
2423 TFS (&scsi_modesns_rac_val), 0x40, "", HFILL}},
2424 { &hf_scsi_protocol,
2425 {"Protocol", "scsi.proto", FT_UINT8, BASE_DEC, VALS (scsi_proto_val),
2427 { &hf_scsi_sns_errtype,
2428 {"SNS Error Type", "scsi.sns.errtype", FT_UINT8, BASE_HEX,
2429 VALS (scsi_sns_errtype_val), 0x7F, "", HFILL}},
2431 {"Sense Key", "scsi.sns.key", FT_UINT8, BASE_HEX,
2432 VALS (scsi_sensekey_val), 0x0F, "", HFILL}},
2434 {"Sense Info", "scsi.sns.info", FT_UINT32, BASE_HEX, NULL, 0x0, "",
2436 { &hf_scsi_addlsnslen,
2437 {"Additional Sense Length", "scsi.sns.addlen", FT_UINT8, BASE_DEC,
2438 NULL, 0x0, "", HFILL}},
2440 {"Additional Sense Code", "scsi.sns.asc", FT_UINT8, BASE_HEX, NULL,
2443 {"Additional Sense Code Qualifier", "scsi.sns.ascq", FT_UINT8,
2444 BASE_HEX, NULL, 0x0, "", HFILL}},
2446 {"Additional Sense Code+Qualifier", "scsi.sns.ascascq", FT_UINT16,
2447 BASE_HEX, VALS (scsi_asc_val), 0x0, "", HFILL}},
2449 {"Field Replaceable Unit Code", "scsi.sns.fru", FT_UINT8, BASE_HEX,
2450 NULL, 0x0, "", HFILL}},
2452 {"SKSV", "scsi.sns.sksv", FT_BOOLEAN, BASE_HEX, NULL, 0x80, "",
2454 { &hf_scsi_persresv_key,
2455 {"Reservation Key", "scsi.spc2.resv.key", FT_BYTES, BASE_HEX, NULL,
2457 { &hf_scsi_persresv_scopeaddr,
2458 {"Scope Address", "scsi.spc2.resv.scopeaddr", FT_BYTES, BASE_HEX, NULL,
2462 /* Setup protocol subtree array */
2463 static gint *ett[] = {
2467 module_t *scsi_module;
2469 /* Register the protocol name and description */
2470 proto_scsi = proto_register_protocol("SCSI", "SCSI", "scsi");
2472 /* Required function calls to register the header fields and subtrees used */
2473 proto_register_field_array(proto_scsi, hf, array_length(hf));
2474 proto_register_subtree_array(ett, array_length(ett));
2475 register_init_routine (&scsi_init_protocol);
2476 register_dissector ("SCSI", dissect_scsi, proto_scsi);
2477 data_handle = find_dissector ("data");
2479 /* add preferences to decode SCSI message */
2480 scsi_module = prefs_register_protocol (proto_scsi, NULL);
2481 prefs_register_enum_preference (scsi_module, "decode_scsi_messages_as",
2482 "Decode SCSI Messages As",
2483 "When Target Cannot Be Identified, Decode SCSI Messages As",
2484 &scsi_def_devtype, scsi_devtype_options, TRUE);