2
* Dissector for the SCSI SMC commandset
3
* Extracted from packet-scsi.c
5
* Dinesh G Dutt (ddutt@cisco.com)
8
* $Id: packet-scsi-smc.c 19964 2006-11-23 09:21:16Z sahlberg $
10
* Wireshark - Network traffic analyzer
11
* By Gerald Combs <gerald@wireshark.org>
12
* Copyright 2002 Gerald Combs
14
* This program is free software; you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License
16
* as published by the Free Software Foundation; either version 2
17
* of the License, or (at your option) any later version.
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, write to the Free Software
26
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35
#include <epan/strutil.h>
36
#include <epan/packet.h>
37
#include <epan/prefs.h>
38
#include <epan/emem.h>
39
#include <epan/conversation.h>
41
#include "packet-scsi.h"
42
#include "packet-fc.h"
43
#include "packet-scsi-smc.h"
46
static int proto_scsi_smc = -1;
47
int hf_scsi_smc_opcode = -1;
52
dissect_smc2_movemedium (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
53
guint offset, gboolean isreq, gboolean iscdb,
54
guint payload_len _U_, scsi_task_data_t *cdata _U_)
58
if (tree && isreq && iscdb) {
59
proto_tree_add_text (tree, tvb, offset+1, 2,
60
"Medium Transport Address: %u",
61
tvb_get_ntohs (tvb, offset+1));
62
proto_tree_add_text (tree, tvb, offset+3, 2,
64
tvb_get_ntohs (tvb, offset+3));
65
proto_tree_add_text (tree, tvb, offset+5, 2,
66
"Destination Address: %u",
67
tvb_get_ntohs (tvb, offset+5));
68
flags = tvb_get_guint8 (tvb, offset+9);
69
proto_tree_add_text (tree, tvb, offset+9, 1,
70
"INV: %u", flags & 0x01);
71
flags = tvb_get_guint8 (tvb, offset+10);
72
proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
74
"Vendor Unique = %u, NACA = %u, Link = %u",
75
flags & 0xC0, flags & 0x4, flags & 0x1);
84
static const value_string element_type_code_vals[] = {
85
{0x0, "All element types"},
86
{MT_ELEM, "Medium transport element"},
87
{ST_ELEM, "Storage element"},
88
{I_E_ELEM, "Import/export element"},
89
{DT_ELEM, "Data transfer element"},
104
dissect_scsi_smc2_volume_tag (tvbuff_t *tvb, packet_info *pinfo _U_,
105
proto_tree *tree, guint offset,
111
tvb_memcpy (tvb, (guint8 *)volid, offset, 32);
121
proto_tree_add_text (tree, tvb, offset, 36,
122
"%s: Volume Identification = \"%s\", Volume Sequence Number = %u",
123
name, volid, tvb_get_ntohs (tvb, offset+34));
128
dissect_scsi_smc2_element (tvbuff_t *tvb, packet_info *pinfo _U_,
129
proto_tree *tree, guint offset,
130
guint elem_bytecnt, guint8 elem_type,
136
if (elem_bytecnt < 2)
138
proto_tree_add_text (tree, tvb, offset, 2,
139
"Element Address: %u",
140
tvb_get_ntohs (tvb, offset));
144
if (elem_bytecnt < 1)
146
flags = tvb_get_guint8 (tvb, offset);
150
proto_tree_add_text (tree, tvb, offset, 1,
151
"EXCEPT: %u, FULL: %u",
152
(flags & EXCEPT) >> 2, flags & 0x01);
157
proto_tree_add_text (tree, tvb, offset, 1,
158
"ACCESS: %u, EXCEPT: %u, FULL: %u",
160
(flags & EXCEPT) >> 2, flags & 0x01);
164
proto_tree_add_text (tree, tvb, offset, 1,
165
"cmc: %u, INENAB: %u, EXENAB: %u, ACCESS: %u, EXCEPT: %u, IMPEXP: %u, FULL: %u",
170
(flags & EXCEPT) >> 2,
178
if (elem_bytecnt < 1)
180
offset += 1; /* reserved */
183
if (elem_bytecnt < 2)
185
if (flags & EXCEPT) {
186
proto_tree_add_text (tree, tvb, offset, 2,
187
"Additional Sense Code+Qualifier: %s",
188
val_to_str (tvb_get_ntohs (tvb, offset),
189
scsi_asc_val, "Unknown (0x%04x)"));
194
if (elem_bytecnt < 3)
199
flags = tvb_get_guint8 (tvb, offset);
200
if (flags & LU_VALID) {
201
proto_tree_add_text (tree, tvb, offset, 1,
202
"NOT BUS: %u, ID VALID: %u, LU VALID: 1, LUN: %u",
204
(flags & ID_VALID) >> 5,
206
} else if (flags & ID_VALID) {
207
proto_tree_add_text (tree, tvb, offset, 1,
208
"ID VALID: 1, LU VALID: 0");
210
proto_tree_add_text (tree, tvb, offset, 1,
211
"ID VALID: 0, LU VALID: 0");
214
if (flags & ID_VALID) {
215
proto_tree_add_text (tree, tvb, offset, 1,
216
"SCSI Bus Address: %u",
217
tvb_get_guint8 (tvb, offset));
220
offset += 1; /* reserved */
224
offset += 3; /* reserved */
229
if (elem_bytecnt < 3)
231
flags = tvb_get_guint8 (tvb, offset);
232
if (flags & SVALID) {
233
proto_tree_add_text (tree, tvb, offset, 1,
234
"SVALID: 1, INVERT: %u",
235
(flags & 0x40) >> 6);
237
proto_tree_add_text (tree, tvb, offset, 2,
238
"Source Storage Element Address: %u",
239
tvb_get_ntohs (tvb, offset));
242
proto_tree_add_text (tree, tvb, offset, 1,
248
if (voltag_flags & PVOLTAG) {
249
if (elem_bytecnt < 36)
251
dissect_scsi_smc2_volume_tag (tvb, pinfo, tree, offset,
252
"Primary Volume Tag Information");
257
if (voltag_flags & AVOLTAG) {
258
if (elem_bytecnt < 36)
260
dissect_scsi_smc2_volume_tag (tvb, pinfo, tree, offset,
261
"Alternate Volume Tag Information");
266
if (elem_bytecnt < 1)
268
flags = tvb_get_guint8 (tvb, offset);
269
proto_tree_add_text (tree, tvb, offset, 1,
271
val_to_str (flags & 0x0F,
272
scsi_devid_codeset_val,
273
"Unknown (0x%02x)"));
277
if (elem_bytecnt < 1)
279
flags = tvb_get_guint8 (tvb, offset);
280
proto_tree_add_text (tree, tvb, offset, 1,
281
"Identifier Type: %s",
282
val_to_str ((flags & 0x0F),
283
scsi_devid_idtype_val,
284
"Unknown (0x%02x)"));
288
if (elem_bytecnt < 1)
290
offset += 1; /* reserved */
293
if (elem_bytecnt < 1)
295
ident_len = tvb_get_guint8 (tvb, offset);
296
proto_tree_add_text (tree, tvb, offset, 1,
297
"Identifier Length: %u",
302
if (ident_len != 0) {
303
if (elem_bytecnt < ident_len)
305
proto_tree_add_text (tree, tvb, offset, ident_len,
307
tvb_bytes_to_str (tvb, offset, ident_len));
309
elem_bytecnt -= ident_len;
311
if (elem_bytecnt != 0) {
312
proto_tree_add_text (tree, tvb, offset, elem_bytecnt,
313
"Vendor-specific Data: %s",
314
tvb_bytes_to_str (tvb, offset, elem_bytecnt));
320
dissect_scsi_smc2_elements (tvbuff_t *tvb, packet_info *pinfo,
321
proto_tree *tree, guint offset,
322
guint desc_bytecnt, guint8 elem_type,
323
guint8 voltag_flags, guint16 elem_desc_len)
327
while (desc_bytecnt != 0) {
328
elem_bytecnt = elem_desc_len;
329
if (elem_bytecnt > desc_bytecnt)
330
elem_bytecnt = desc_bytecnt;
331
dissect_scsi_smc2_element (tvb, pinfo, tree, offset, elem_bytecnt,
332
elem_type, voltag_flags);
333
offset += elem_bytecnt;
334
desc_bytecnt -= elem_bytecnt;
340
dissect_smc2_readelementstatus (tvbuff_t *tvb, packet_info *pinfo,
341
proto_tree *tree, guint offset, gboolean isreq,
343
guint payload_len _U_, scsi_task_data_t *cdata _U_)
346
guint numelem, bytecnt, desc_bytecnt;
349
guint16 elem_desc_len;
354
if (isreq && iscdb) {
355
flags = tvb_get_guint8 (tvb, offset);
356
proto_tree_add_text (tree, tvb, offset, 1,
357
"VOLTAG: %u, Element Type Code: %s",
359
val_to_str (flags & 0xF, element_type_code_vals,
361
proto_tree_add_text (tree, tvb, offset+1, 2,
362
"Starting Element Address: %u",
363
tvb_get_ntohs (tvb, offset+1));
364
proto_tree_add_text (tree, tvb, offset+3, 2,
365
"Number of Elements: %u",
366
tvb_get_ntohs (tvb, offset+3));
367
flags = tvb_get_guint8 (tvb, offset+4);
368
proto_tree_add_text (tree, tvb, offset+4, 1,
369
"CURDATA: %u, DVCID: %u",
370
(flags & 0x02) >> 1, flags & 0x01);
371
proto_tree_add_text (tree, tvb, offset+6, 3,
372
"Allocation Length: %u",
373
tvb_get_ntoh24 (tvb, offset+6));
374
flags = tvb_get_guint8 (tvb, offset+10);
375
proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
377
"Vendor Unique = %u, NACA = %u, Link = %u",
378
flags & 0xC0, flags & 0x4, flags & 0x1);
381
proto_tree_add_text (tree, tvb, offset, 2,
382
"First Element Address Reported: %u",
383
tvb_get_ntohs (tvb, offset));
385
numelem = tvb_get_ntohs (tvb, offset);
386
proto_tree_add_text (tree, tvb, offset, 2,
387
"Number of Elements Available: %u", numelem);
389
offset += 1; /* reserved */
390
bytecnt = tvb_get_ntoh24 (tvb, offset);
391
proto_tree_add_text (tree, tvb, offset, 3,
392
"Byte Count of Report Available: %u", bytecnt);
394
while (bytecnt != 0) {
397
elem_type = tvb_get_guint8 (tvb, offset);
398
proto_tree_add_text (tree, tvb, offset, 1,
399
"Element Type Code: %s",
400
val_to_str (elem_type, element_type_code_vals,
407
voltag_flags = tvb_get_guint8 (tvb, offset);
408
proto_tree_add_text (tree, tvb, offset, 1,
409
"PVOLTAG: %u, AVOLTAG: %u",
410
(voltag_flags & PVOLTAG) >> 7,
411
(voltag_flags & AVOLTAG) >> 6);
417
elem_desc_len = tvb_get_ntohs (tvb, offset);
418
proto_tree_add_text (tree, tvb, offset, 2,
419
"Element Descriptor Length: %u",
426
offset += 1; /* reserved */
431
desc_bytecnt = tvb_get_ntoh24 (tvb, offset);
432
proto_tree_add_text (tree, tvb, offset, 3,
433
"Byte Count Of Descriptor Data Available: %u",
438
if (desc_bytecnt > bytecnt)
439
desc_bytecnt = bytecnt;
440
dissect_scsi_smc2_elements (tvb, pinfo, tree, offset,
441
desc_bytecnt, elem_type,
442
voltag_flags, elem_desc_len);
443
offset += desc_bytecnt;
444
bytecnt -= desc_bytecnt;
452
const value_string scsi_smc_vals[] = {
453
{SCSI_SMC2_EXCHANGE_MEDIUM , "Exchange Medium"},
454
{SCSI_SMC2_INITIALIZE_ELEMENT_STATUS , "Initialize Element Status"},
455
{SCSI_SMC2_INITIALIZE_ELEMENT_STATUS_RANGE, "Initialize Element Status With Range"},
456
{SCSI_SPC2_INQUIRY , "Inquiry"},
457
{SCSI_SPC2_LOGSELECT , "Log Select"},
458
{SCSI_SPC2_LOGSENSE , "Log Sense"},
459
{SCSI_SPC2_MODESELECT6 , "Mode Select(6)"},
460
{SCSI_SPC2_MODESELECT10 , "Mode Select(10)"},
461
{SCSI_SPC2_MODESENSE6 , "Mode Sense(6)"},
462
{SCSI_SPC2_MODESENSE10 , "Mode Sense(10)"},
463
{SCSI_SMC2_MOVE_MEDIUM , "Move Medium"},
464
{SCSI_SMC2_MOVE_MEDIUM_ATTACHED , "Move Medium Attached"},
465
{SCSI_SPC2_PERSRESVIN , "Persistent Reserve In"},
466
{SCSI_SPC2_PERSRESVOUT , "Persistent Reserve Out"},
467
{SCSI_SMC2_POSITION_TO_ELEMENT , "Position To Element"},
468
{SCSI_SPC2_PREVMEDREMOVAL , "Prevent/Allow Medium Removal"},
469
{SCSI_SMC2_READ_ATTRIBUTE , "Read Attribute"},
470
{SCSI_SMC2_READ_ELEMENT_STATUS , "Read Element Status"},
471
{SCSI_SMC2_READ_ELEMENT_STATUS_ATTACHED , "Read Element Status Attached"},
472
{SCSI_SPC2_RELEASE6 , "Release(6)"},
473
{SCSI_SPC2_RELEASE10 , "Release(10)"},
474
{SCSI_SPC2_REPORTLUNS , "Report LUNs"},
475
{SCSI_SPC2_REQSENSE , "Request Sense"},
476
{SCSI_SMC2_REQUEST_VOLUME_ELEMENT_ADDRESS , "Request Volume Element Address"},
477
{SCSI_SPC2_RESERVE6 , "Reserve(6)"},
478
{SCSI_SPC2_RESERVE10 , "Reserve(10)"},
479
{SCSI_SMC2_SEND_VOLUME_TAG , "Send Volume Tag"},
480
{SCSI_SPC2_SENDDIAG , "Send Diagnostic"},
481
{SCSI_SPC2_TESTUNITRDY , "Test Unit Ready"},
482
{SCSI_SMC2_WRITE_ATTRIBUTE , "Write Attribute"},
483
{SCSI_SPC2_WRITEBUFFER , "Write Buffer"},
487
scsi_cdb_table_t scsi_smc_table[256] = {
488
/*SPC 0x00*/{dissect_spc3_testunitready},
491
/*SPC 0x03*/{dissect_spc3_requestsense},
506
/*SPC 0x12*/{dissect_spc3_inquiry},
509
/*SPC 0x15*/{dissect_spc3_modeselect6},
510
/*SPC 0x16*/{dissect_spc2_reserve6},
511
/*SPC 0x17*/{dissect_spc2_release6},
514
/*SPC 0x1a*/{dissect_spc3_modesense6},
517
/*SPC 0x1d*/{dissect_spc3_senddiagnostic},
518
/*SMC 0x1e*/{dissect_spc3_preventallowmediaremoval},
547
/*SPC 0x3b*/{dissect_spc3_writebuffer},
564
/*SPC 0x4c*/{dissect_spc3_logselect},
565
/*SPC 0x4d*/{dissect_spc3_logsense},
573
/*SPC 0x55*/{dissect_spc3_modeselect10},
574
/*SPC 0x56*/{dissect_spc2_reserve10},
575
/*SPC 0x57*/{dissect_spc2_release10},
578
/*SPC 0x5a*/{dissect_spc3_modesense10},
582
/*SPC 0x5e*/{dissect_spc3_persistentreservein},
583
/*SPC 0x5f*/{dissect_spc3_persistentreserveout},
648
/*SPC 0xa0*/{dissect_spc3_reportluns},
653
/*SMC 0xa5*/{dissect_smc2_movemedium},
655
/*SMC 0xa7*/{dissect_smc2_movemedium},
668
/*SMC 0xb4*/{dissect_smc2_readelementstatus},
672
/*SMC 0xb8*/{dissect_smc2_readelementstatus},
748
proto_register_scsi_smc(void)
750
static hf_register_info hf[] = {
751
{ &hf_scsi_smc_opcode,
752
{"SMC Opcode", "scsi.smc.opcode", FT_UINT8, BASE_HEX,
753
VALS (scsi_smc_vals), 0x0, "", HFILL}},
757
/* Setup protocol subtree array */
759
static gint *ett[] = {
763
/* Register the protocol name and description */
764
proto_scsi_smc = proto_register_protocol("SCSI_SMC", "SCSI_SMC", "scsi_smc");
766
/* Required function calls to register the header fields and subtrees used */
767
proto_register_field_array(proto_scsi_smc, hf, array_length(hf));
769
proto_register_subtree_array(ett, array_length(ett));
774
proto_reg_handoff_scsi_smc(void)