Update Free Software Foundation address.
[metze/wireshark/wip.git] / epan / dissectors / packet-scsi-ssc.c
1 /* based on SSC3 spec */
2 /* TODO:
3  * dissect READPOSITION data
4  * dissect REPORTDENSITYSUPPORT data
5  */
6 /* packet-scsi-ssc.c
7  * Dissector for the SCSI SSC commandset
8  * Extracted from packet-scsi.c
9  *
10  * Dinesh G Dutt (ddutt@cisco.com)
11  * Ronnie sahlberg 2006
12  *
13  * $Id$
14  *
15  * Wireshark - Network traffic analyzer
16  * By Gerald Combs <gerald@wireshark.org>
17  * Copyright 2002 Gerald Combs
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <glib.h>
39 #include <epan/strutil.h>
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
42 #include <epan/tap.h>
43 #include "packet-scsi.h"
44 #include "packet-fc.h"
45 #include "packet-scsi-ssc.h"
46 #include "packet-scsi-smc.h"
47
48
49 static int proto_scsi_ssc               = -1;
50 int hf_scsi_ssc_opcode                  = -1;
51 static int hf_scsi_ssc_rdwr6_xferlen    = -1;
52 static int hf_scsi_ssc_ver16_verlen     = -1;
53 static int hf_scsi_ssc_locate10_loid    = -1;
54 static int hf_scsi_ssc_locate16_loid    = -1;
55 static int hf_scsi_ssc_space6_code      = -1;
56 static int hf_scsi_ssc_space6_count     = -1;
57 static int hf_scsi_ssc_space16_count    = -1;
58 static int hf_scsi_ssc_erase_flags              = -1;
59 static int hf_scsi_ssc_fcs                      = -1;
60 static int hf_scsi_ssc_lcs                      = -1;
61 static int hf_scsi_ssc_erase_immed              = -1;
62 static int hf_scsi_ssc_long                     = -1;
63 static int hf_scsi_ssc_partition                = -1;
64 static int hf_scsi_ssc_lbi                      = -1;
65 static int hf_scsi_ssc_verify                   = -1;
66 static int hf_scsi_ssc_immed                    = -1;
67 static int hf_scsi_ssc_formatmedium_flags       = -1;
68 static int hf_scsi_ssc_format                   = -1;
69 static int hf_scsi_ssc_rdwr10_xferlen           = -1;
70 static int hf_scsi_ssc_loadunload_immed_flags   = -1;
71 static int hf_scsi_ssc_loadunload_flags         = -1;
72 static int hf_scsi_ssc_hold                     = -1;
73 static int hf_scsi_ssc_eot                      = -1;
74 static int hf_scsi_ssc_reten                    = -1;
75 static int hf_scsi_ssc_load                     = -1;
76 static int hf_scsi_ssc_locate_flags             = -1;
77 static int hf_scsi_ssc_bt                       = -1;
78 static int hf_scsi_ssc_cp                       = -1;
79 static int hf_scsi_ssc_dest_type                = -1;
80 static int hf_scsi_ssc_bam_flags                = -1;
81 static int hf_scsi_ssc_bam                      = -1;
82 static int hf_scsi_ssc_read6_flags              = -1;
83 static int hf_scsi_ssc_sili                     = -1;
84 static int hf_scsi_ssc_fixed                    = -1;
85 static int hf_scsi_ssc_bytord                   = -1;
86 static int hf_scsi_ssc_bytcmp                   = -1;
87 static int hf_scsi_ssc_verify16_immed           = -1;
88 static int hf_scsi_ssc_medium_type              = -1;
89 static int hf_scsi_ssc_media                    = -1;
90 static int hf_scsi_ssc_capacity_prop_value      = -1;
91
92 static gint ett_scsi_erase                      = -1;
93 static gint ett_scsi_formatmedium               = -1;
94 static gint ett_scsi_loadunload_immed           = -1;
95 static gint ett_scsi_loadunload                 = -1;
96 static gint ett_scsi_locate                     = -1;
97 static gint ett_scsi_bam                        = -1;
98 static gint ett_scsi_read6                      = -1;
99
100
101 static void
102 dissect_ssc_read6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
103                     guint offset, gboolean isreq, gboolean iscdb,
104                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
105 {
106     static const int *read6_fields[] = {
107         &hf_scsi_ssc_sili,
108         &hf_scsi_ssc_fixed,
109         NULL
110     };
111
112     if (isreq) {
113         if (check_col (pinfo->cinfo, COL_INFO))
114             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
115                              tvb_get_ntoh24 (tvb, offset+1));
116     }
117
118     if (tree && isreq && iscdb) {
119         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
120             ett_scsi_read6, read6_fields, ENC_BIG_ENDIAN);
121         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+1, 3, ENC_BIG_ENDIAN);
122         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
123             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
124     }
125 }
126
127 static void
128 dissect_ssc_recoverbuffereddata (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
129                     guint offset, gboolean isreq, gboolean iscdb,
130                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
131 {
132     static const int *recover_fields[] = {
133         &hf_scsi_ssc_sili,
134         &hf_scsi_ssc_fixed,
135         NULL
136     };
137
138     if (isreq) {
139         if (check_col (pinfo->cinfo, COL_INFO))
140             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
141                              tvb_get_ntoh24 (tvb, offset+1));
142     }
143
144     if (tree && isreq && iscdb) {
145         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
146             ett_scsi_read6, recover_fields, ENC_BIG_ENDIAN);
147         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+1, 3, ENC_BIG_ENDIAN);
148         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
149             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
150     }
151 }
152
153 static void
154 dissect_ssc_reportdensitysupport (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
155                     guint offset, gboolean isreq, gboolean iscdb,
156                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
157 {
158     static const int *rd_fields[] = {
159         &hf_scsi_ssc_medium_type,
160         &hf_scsi_ssc_media,
161         NULL
162     };
163
164     if (isreq) {
165         if (check_col (pinfo->cinfo, COL_INFO))
166             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
167                              tvb_get_ntoh24 (tvb, offset+1));
168     }
169
170     if(!tree)
171         return;
172
173     if (isreq && iscdb) {
174         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
175             ett_scsi_read6, rd_fields, ENC_BIG_ENDIAN);
176         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+6, 2, ENC_BIG_ENDIAN);
177         proto_tree_add_bitmask(tree, tvb, offset+8, hf_scsi_control,
178             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
179     } else {
180         /* XXX decode the data */
181     }
182 }
183
184 static void
185 dissect_ssc_readreverse6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
186                     guint offset, gboolean isreq, gboolean iscdb,
187                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
188 {
189     static const int *rr6_fields[] = {
190         &hf_scsi_ssc_bytord,
191         &hf_scsi_ssc_sili,
192         &hf_scsi_ssc_fixed,
193         NULL
194     };
195
196     if (isreq) {
197         if (check_col (pinfo->cinfo, COL_INFO))
198             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
199                              tvb_get_ntoh24 (tvb, offset+1));
200     }
201
202     if (tree && isreq && iscdb) {
203         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
204             ett_scsi_read6, rr6_fields, ENC_BIG_ENDIAN);
205         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+1, 3, ENC_BIG_ENDIAN);
206         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
207             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
208     }
209 }
210
211 static void
212 dissect_ssc_read16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
213                     guint offset, gboolean isreq, gboolean iscdb,
214                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
215 {
216     static const int *read6_fields[] = {
217         &hf_scsi_ssc_sili,
218         &hf_scsi_ssc_fixed,
219         NULL
220     };
221
222     if (isreq) {
223         if (check_col (pinfo->cinfo, COL_INFO))
224             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
225                              tvb_get_ntoh24 (tvb, offset+1));
226     }
227
228     if (tree && isreq && iscdb) {
229         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
230             ett_scsi_read6, read6_fields, ENC_BIG_ENDIAN);
231         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+2, 1, ENC_BIG_ENDIAN);
232         proto_tree_add_item (tree, hf_scsi_ssc_locate16_loid, tvb, offset+3, 8, ENC_BIG_ENDIAN);
233         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+11, 3, ENC_BIG_ENDIAN);
234         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
235             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
236     }
237 }
238
239 static void
240 dissect_ssc_write16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
241                     guint offset, gboolean isreq, gboolean iscdb,
242                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
243 {
244     static const int *write16_fields[] = {
245         &hf_scsi_ssc_fcs,
246         &hf_scsi_ssc_lcs,
247         &hf_scsi_ssc_fixed,
248         NULL
249     };
250
251     if (isreq) {
252         if (check_col (pinfo->cinfo, COL_INFO))
253             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
254                              tvb_get_ntoh24 (tvb, offset+1));
255     }
256
257     if (tree && isreq && iscdb) {
258         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
259             ett_scsi_read6, write16_fields, ENC_BIG_ENDIAN);
260         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+2, 1, ENC_BIG_ENDIAN);
261         proto_tree_add_item (tree, hf_scsi_ssc_locate16_loid, tvb, offset+3, 8, ENC_BIG_ENDIAN);
262         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+11, 3, ENC_BIG_ENDIAN);
263         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
264             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
265     }
266 }
267
268 static void
269 dissect_ssc_writefilemarks16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
270                     guint offset, gboolean isreq, gboolean iscdb,
271                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
272 {
273     static const int *wf16_fields[] = {
274         &hf_scsi_ssc_fcs,
275         &hf_scsi_ssc_lcs,
276         &hf_scsi_ssc_immed,
277         NULL
278     };
279
280     if (isreq) {
281         if (check_col (pinfo->cinfo, COL_INFO))
282             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
283                              tvb_get_ntoh24 (tvb, offset+1));
284     }
285
286     if (tree && isreq && iscdb) {
287         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
288             ett_scsi_read6, wf16_fields, ENC_BIG_ENDIAN);
289         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+2, 1, ENC_BIG_ENDIAN);
290         proto_tree_add_item (tree, hf_scsi_ssc_locate16_loid, tvb, offset+3, 8, ENC_BIG_ENDIAN);
291         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+11, 3, ENC_BIG_ENDIAN);
292         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
293             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
294     }
295 }
296
297 static void
298 dissect_ssc_verify16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
299                     guint offset, gboolean isreq, gboolean iscdb,
300                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
301 {
302     static const int *verify16_fields[] = {
303         &hf_scsi_ssc_verify16_immed,
304         &hf_scsi_ssc_bytcmp,
305         &hf_scsi_ssc_fixed,
306         NULL
307     };
308
309     if (isreq) {
310         if (check_col (pinfo->cinfo, COL_INFO))
311             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
312                              tvb_get_ntoh24 (tvb, offset+1));
313     }
314
315     if (tree && isreq && iscdb) {
316         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
317             ett_scsi_read6, verify16_fields, ENC_BIG_ENDIAN);
318         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+2, 1, ENC_BIG_ENDIAN);
319         proto_tree_add_item (tree, hf_scsi_ssc_locate16_loid, tvb, offset+3, 8, ENC_BIG_ENDIAN);
320         proto_tree_add_item (tree, hf_scsi_ssc_ver16_verlen, tvb, offset+11, 3, ENC_BIG_ENDIAN);
321         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
322             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
323     }
324 }
325
326 static void
327 dissect_ssc_verify6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
328                     guint offset, gboolean isreq, gboolean iscdb,
329                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
330 {
331     static const int *verify6_fields[] = {
332         &hf_scsi_ssc_verify16_immed,
333         &hf_scsi_ssc_bytcmp,
334         &hf_scsi_ssc_fixed,
335         NULL
336     };
337
338     if (isreq) {
339         if (check_col (pinfo->cinfo, COL_INFO))
340             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
341                              tvb_get_ntoh24 (tvb, offset+1));
342     }
343
344     if (tree && isreq && iscdb) {
345         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
346             ett_scsi_read6, verify6_fields, ENC_BIG_ENDIAN);
347         proto_tree_add_item (tree, hf_scsi_ssc_ver16_verlen, tvb, offset+1, 3, ENC_BIG_ENDIAN);
348         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
349             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
350     }
351 }
352
353 static void
354 dissect_ssc_readreverse16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
355                     guint offset, gboolean isreq, gboolean iscdb,
356                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
357 {
358     static const int *rr16_fields[] = {
359         &hf_scsi_ssc_bytord,
360         &hf_scsi_ssc_sili,
361         &hf_scsi_ssc_fixed,
362         NULL
363     };
364
365     if (isreq) {
366         if (check_col (pinfo->cinfo, COL_INFO))
367             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
368                              tvb_get_ntoh24 (tvb, offset+1));
369     }
370
371     if (tree && isreq && iscdb) {
372         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
373             ett_scsi_read6, rr16_fields, ENC_BIG_ENDIAN);
374         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+2, 1, ENC_BIG_ENDIAN);
375         proto_tree_add_item (tree, hf_scsi_ssc_locate16_loid, tvb, offset+3, 8, ENC_BIG_ENDIAN);
376         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+11, 3, ENC_BIG_ENDIAN);
377         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
378             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
379     }
380 }
381
382 static void
383 dissect_ssc_write6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
384                     guint offset, gboolean isreq, gboolean iscdb,
385                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
386 {
387     static const int *write6_fields[] = {
388         &hf_scsi_ssc_immed,
389         NULL
390     };
391
392     if (isreq && iscdb) {
393         if (check_col (pinfo->cinfo, COL_INFO))
394             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
395                              tvb_get_ntoh24 (tvb, offset+1));
396     }
397
398     if (tree && isreq && iscdb) {
399         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
400             ett_scsi_read6, write6_fields, ENC_BIG_ENDIAN);
401         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+1, 3, ENC_BIG_ENDIAN);
402         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
403             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
404     }
405 }
406
407 static void
408 dissect_ssc_writefilemarks6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
409                     guint offset, gboolean isreq, gboolean iscdb,
410                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
411 {
412     static const int *wf6_fields[] = {
413         &hf_scsi_ssc_immed,
414         NULL
415     };
416
417     if (isreq) {
418         if (check_col (pinfo->cinfo, COL_INFO))
419             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
420                              tvb_get_ntoh24 (tvb, offset+1));
421     }
422
423     if (tree && isreq && iscdb) {
424         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
425             ett_scsi_read6, wf6_fields, ENC_BIG_ENDIAN);
426         proto_tree_add_item (tree, hf_scsi_ssc_rdwr6_xferlen, tvb, offset+1, 3, ENC_BIG_ENDIAN);
427         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
428             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
429     }
430 }
431
432 static void
433 dissect_ssc_loadunload (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
434                     guint offset, gboolean isreq, gboolean iscdb,
435                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
436 {
437     static const int *loadunload_immed_fields[] = {
438         &hf_scsi_ssc_immed,
439         NULL
440     };
441     static const int *loadunload_fields[] = {
442         &hf_scsi_ssc_hold,
443         &hf_scsi_ssc_eot,
444         &hf_scsi_ssc_reten,
445         &hf_scsi_ssc_load,
446         NULL
447     };
448
449     if (isreq && iscdb) {
450         if (check_col (pinfo->cinfo, COL_INFO))
451             col_append_fstr (pinfo->cinfo, COL_INFO, "(Immed: %u)",
452                              tvb_get_guint8 (tvb, offset) & 0x01);
453     }
454
455     if (!tree)
456         return;
457
458
459     if (isreq && iscdb) {
460         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_loadunload_immed_flags,
461             ett_scsi_loadunload_immed, loadunload_immed_fields, ENC_BIG_ENDIAN);
462         proto_tree_add_bitmask(tree, tvb, offset+3, hf_scsi_ssc_loadunload_flags,
463             ett_scsi_loadunload, loadunload_fields, ENC_BIG_ENDIAN);
464         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
465             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
466     }
467 }
468
469
470 static void
471 dissect_ssc_readblocklimits (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
472                     guint offset, gboolean isreq, gboolean iscdb,
473                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
474 {
475     guint8 granularity;
476
477     if (!tree)
478         return;
479
480     if (isreq && iscdb) {
481         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
482             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
483     }
484     else if (!iscdb) {
485         granularity = tvb_get_guint8 (tvb, offset);
486         proto_tree_add_text (tree, tvb, offset, 1, "Granularity: %u (%u %s)",
487                              granularity, 1 << granularity,
488                              plurality(1 << granularity, "byte", "bytes"));
489         proto_tree_add_text (tree, tvb, offset+1, 3, "Maximum Block Length Limit: %u bytes",
490                              tvb_get_ntoh24 (tvb, offset+1));
491         proto_tree_add_text (tree, tvb, offset+4, 2, "Minimum Block Length Limit: %u bytes",
492                              tvb_get_ntohs (tvb, offset+4));
493     }
494 }
495
496 static void
497 dissect_ssc_rewind (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
498                     guint offset, gboolean isreq, gboolean iscdb,
499                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
500 {
501     static const int *rewind_fields[] = {
502         &hf_scsi_ssc_immed,
503         NULL
504     };
505
506     if (!tree)
507         return;
508
509     if (isreq && iscdb) {
510         if (check_col (pinfo->cinfo, COL_INFO))
511             col_append_fstr (pinfo->cinfo, COL_INFO, "(Immed: %u)",
512                              tvb_get_guint8 (tvb, offset) & 0x01);
513
514         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags, ett_scsi_read6, rewind_fields, ENC_BIG_ENDIAN);
515         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
516             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
517     }
518 }
519
520 static void
521 dissect_ssc_setcapacity (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
522                     guint offset, gboolean isreq, gboolean iscdb,
523                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
524 {
525     static const int *sc_fields[] = {
526         &hf_scsi_ssc_immed,
527         NULL
528     };
529
530     if (!tree)
531         return;
532
533     if (isreq && iscdb) {
534         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_read6_flags,
535             ett_scsi_read6, sc_fields, ENC_BIG_ENDIAN);
536         proto_tree_add_item (tree, hf_scsi_ssc_capacity_prop_value, tvb, offset+2, 2, ENC_BIG_ENDIAN);
537         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
538             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
539     }
540 }
541
542
543 static void
544 dissect_ssc_locate10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
545                     guint offset, gboolean isreq, gboolean iscdb,
546                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
547 {
548     static const int *locate_fields[] = {
549         &hf_scsi_ssc_bt,
550         &hf_scsi_ssc_cp,
551         &hf_scsi_ssc_immed,
552         NULL
553     };
554
555     if (!tree)
556         return;
557
558     if (isreq && iscdb) {
559         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_locate_flags,
560             ett_scsi_locate, locate_fields, ENC_BIG_ENDIAN);
561         proto_tree_add_item (tree, hf_scsi_ssc_locate10_loid, tvb, offset+2, 4, ENC_BIG_ENDIAN);
562         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+7, 1, ENC_BIG_ENDIAN);
563         proto_tree_add_bitmask(tree, tvb, offset+8, hf_scsi_control,
564             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
565     }
566 }
567
568
569 static void
570 dissect_ssc_locate16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
571                     guint offset, gboolean isreq, gboolean iscdb,
572                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
573 {
574     static const int *locate_fields[] = {
575         &hf_scsi_ssc_dest_type,
576         &hf_scsi_ssc_cp,
577         &hf_scsi_ssc_immed,
578         NULL
579     };
580     static const int *bam_fields[] = {
581         &hf_scsi_ssc_bam,
582         NULL
583     };
584
585     if (!tree)
586         return;
587
588     if (isreq && iscdb) {
589         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_locate_flags,
590             ett_scsi_locate, locate_fields, ENC_BIG_ENDIAN);
591         proto_tree_add_bitmask(tree, tvb, offset+1, hf_scsi_ssc_bam_flags,
592             ett_scsi_bam, bam_fields, ENC_BIG_ENDIAN);
593         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+2, 1, ENC_BIG_ENDIAN);
594         proto_tree_add_item (tree, hf_scsi_ssc_locate16_loid, tvb, offset+3, 8, ENC_BIG_ENDIAN);
595         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
596             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
597     }
598 }
599
600
601 static void
602 dissect_ssc_erase6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
603                     guint offset, gboolean isreq, gboolean iscdb,
604                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
605 {
606     guint8 flags;
607
608     if (isreq && iscdb) {
609         if (!tree)
610             return;
611
612         flags = tvb_get_guint8 (tvb, offset);
613         proto_tree_add_text (tree, tvb, offset, 1,
614                              "IMMED: %u, LONG: %u",
615                              (flags & 0x02) >> 1,
616                              flags & 0x01);
617
618         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
619             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
620     }
621 }
622
623
624 static void
625 dissect_ssc_erase16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
626                     guint offset, gboolean isreq, gboolean iscdb,
627                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
628 {
629     static const int *erase16_fields[] = {
630         &hf_scsi_ssc_fcs,
631         &hf_scsi_ssc_lcs,
632         &hf_scsi_ssc_erase_immed,
633         &hf_scsi_ssc_long,
634         NULL
635     };
636
637     if (!tree)
638         return;
639
640     if (isreq && iscdb) {
641         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_erase_flags,
642             ett_scsi_erase, erase16_fields, ENC_BIG_ENDIAN);
643         proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset+2, 1, ENC_BIG_ENDIAN);
644         proto_tree_add_item (tree, hf_scsi_ssc_lbi, tvb, offset+3, 8, ENC_BIG_ENDIAN);
645         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
646             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
647     }
648 }
649
650 static void
651 dissect_ssc_space6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
652                     guint offset, gboolean isreq, gboolean iscdb,
653                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
654 {
655     if (!tree)
656         return;
657
658     if (isreq && iscdb) {
659         proto_tree_add_item (tree, hf_scsi_ssc_space6_code, tvb, offset, 1, ENC_BIG_ENDIAN);
660         proto_tree_add_item (tree, hf_scsi_ssc_space6_count, tvb, offset+1, 3, ENC_BIG_ENDIAN);
661         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
662             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
663     }
664 }
665
666 static void
667 dissect_ssc_space16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
668                     guint offset, gboolean isreq, gboolean iscdb,
669                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
670 {
671     if (!tree)
672         return;
673
674     if (isreq && iscdb) {
675         proto_tree_add_item (tree, hf_scsi_ssc_space6_code, tvb, offset, 1, ENC_BIG_ENDIAN);
676         proto_tree_add_item (tree, hf_scsi_ssc_space16_count, tvb, offset+3, 8, ENC_BIG_ENDIAN);
677         proto_tree_add_text (tree, tvb, offset+11, 2,
678                              "Parameter Len: %u",
679                              tvb_get_ntohs (tvb, offset+11));
680         proto_tree_add_bitmask(tree, tvb, offset+14, hf_scsi_control,
681             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
682     }
683 }
684
685 static const value_string space6_code_vals[] = {
686     {0, "Logical Blocks"},
687     {1, "Filemarks"},
688     {2, "Sequential Filemarks"},
689     {3, "End-Of-Data"},
690     {0, NULL}
691 };
692
693 static const value_string format_vals[] = {
694     {0x0, "Use default format"},
695     {0x1, "Partition medium"},
696     {0x2, "Default format then partition"},
697     {0, NULL}
698 };
699
700 static const value_string dest_type_vals[] = {
701     {0, "Logical Object Identifier"},
702     {1, "Logical File Identifier"},
703     {0, NULL}
704 };
705
706 static void
707 dissect_ssc_formatmedium (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
708                     guint offset, gboolean isreq, gboolean iscdb,
709                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
710 {
711     static const int *formatmedium_fields[] = {
712         &hf_scsi_ssc_verify,
713         &hf_scsi_ssc_immed,
714         NULL
715     };
716
717     if (!tree)
718         return;
719
720     if (isreq && iscdb) {
721         proto_tree_add_bitmask(tree, tvb, offset, hf_scsi_ssc_formatmedium_flags,
722             ett_scsi_formatmedium, formatmedium_fields, ENC_BIG_ENDIAN);
723         proto_tree_add_item (tree, hf_scsi_ssc_format, tvb, offset+1, 1, ENC_BIG_ENDIAN);
724         proto_tree_add_item (tree, hf_scsi_ssc_rdwr10_xferlen, tvb, offset+2, 2, ENC_BIG_ENDIAN);
725         proto_tree_add_bitmask(tree, tvb, offset+4, hf_scsi_control,
726             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
727     }
728 }
729
730
731 #define BCU  0x20
732 #define BYCU 0x10
733 #define MPU  0x08
734 #define BPU  0x04
735
736 static void
737 dissect_ssc_readposition (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
738                     guint offset, gboolean isreq, gboolean iscdb,
739                     guint payload_len _U_, scsi_task_data_t *cdata)
740 {
741     gint service_action;
742     guint8 flags;
743
744     if (!tree)
745         return;
746
747     if (isreq && iscdb) {
748         service_action = tvb_get_guint8 (tvb, offset) & 0x1F;
749         proto_tree_add_text (tree, tvb, offset, 1,
750                              "Service Action: %s",
751                              val_to_str (service_action,
752                                          service_action_vals,
753                                          "Unknown (0x%02x)"));
754         /* Remember the service action so we can decode the reply */
755         if (cdata != NULL) {
756             cdata->itlq->flags = service_action;
757         }
758         proto_tree_add_text (tree, tvb, offset+6, 2,
759                              "Parameter Len: %u",
760                              tvb_get_ntohs (tvb, offset+6));
761         proto_tree_add_bitmask(tree, tvb, offset+8, hf_scsi_control,
762             ett_scsi_control, cdb_control_fields, ENC_BIG_ENDIAN);
763     }
764     else if (!isreq) {
765         if (cdata)
766             service_action = cdata->itlq->flags;
767         else
768             service_action = -1; /* unknown */
769         switch (service_action) {
770         case SHORT_FORM_BLOCK_ID:
771         case SHORT_FORM_VENDOR_SPECIFIC:
772             flags = tvb_get_guint8 (tvb, offset);
773             proto_tree_add_text (tree, tvb, offset, 1,
774                              "BOP: %u, EOP: %u, BCU: %u, BYCU: %u, BPU: %u, PERR: %u",
775                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
776                              (flags & BCU) >> 5, (flags & BYCU) >> 4,
777                              (flags & BPU) >> 2, (flags & 0x02) >> 1);
778             offset += 1;
779
780             proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset, 1, ENC_BIG_ENDIAN);
781             offset += 1;
782
783             offset += 2; /* reserved */
784
785             if (!(flags & BPU)) {
786                 proto_tree_add_text (tree, tvb, offset, 4,
787                                      "First Block Location: %u",
788                                      tvb_get_ntohl (tvb, offset));
789                 offset += 4;
790
791                 proto_tree_add_text (tree, tvb, offset, 4,
792                                      "Last Block Location: %u",
793                                      tvb_get_ntohl (tvb, offset));
794                 offset += 4;
795             } else
796                 offset += 8;
797
798             offset += 1; /* reserved */
799
800             if (!(flags & BCU)) {
801                 proto_tree_add_text (tree, tvb, offset, 3,
802                                      "Number of Blocks in Buffer: %u",
803                                      tvb_get_ntoh24 (tvb, offset));
804             }
805             offset += 3;
806
807             if (!(flags & BYCU)) {
808                 proto_tree_add_text (tree, tvb, offset, 4,
809                                      "Number of Bytes in Buffer: %u",
810                                      tvb_get_ntohl (tvb, offset));
811             }
812             offset += 4;
813             break;
814
815         case LONG_FORM:
816             flags = tvb_get_guint8 (tvb, offset);
817             proto_tree_add_text (tree, tvb, offset, 1,
818                              "BOP: %u, EOP: %u, MPU: %u, BPU: %u",
819                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
820                              (flags & MPU) >> 3, (flags & BPU) >> 2);
821             offset += 1;
822
823             offset += 3; /* reserved */
824
825             if (!(flags & BPU)) {
826                 proto_tree_add_text (tree, tvb, offset, 4,
827                                      "Partition Number: %u",
828                                      tvb_get_ntohl (tvb, offset));
829                 offset += 4;
830
831                 proto_tree_add_text (tree, tvb, offset, 8,
832                                      "Block Number: %" G_GINT64_MODIFIER "u",
833                                      tvb_get_ntoh64 (tvb, offset));
834                  offset += 8;
835             } else
836                 offset += 12;
837
838             if (!(flags & MPU)) {
839                 proto_tree_add_text (tree, tvb, offset, 8,
840                                      "File Number: %" G_GINT64_MODIFIER "u",
841                                      tvb_get_ntoh64 (tvb, offset));
842                 offset += 8;
843
844                 proto_tree_add_text (tree, tvb, offset, 8,
845                                      "Set Number: %" G_GINT64_MODIFIER "u",
846                                      tvb_get_ntoh64 (tvb, offset));
847                 offset += 8;
848             } else
849                 offset += 16;
850             break;
851
852         case EXTENDED_FORM:
853             flags = tvb_get_guint8 (tvb, offset);
854             proto_tree_add_text (tree, tvb, offset, 1,
855                              "BOP: %u, EOP: %u, BCU: %u, BYCU: %u, MPU: %u, BPU: %u, PERR: %u",
856                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
857                              (flags & BCU) >> 5, (flags & BYCU) >> 4,
858                              (flags & MPU) >> 3, (flags & BPU) >> 2,
859                              (flags & 0x02) >> 1);
860             offset += 1;
861
862             proto_tree_add_item (tree, hf_scsi_ssc_partition, tvb, offset, 1, ENC_BIG_ENDIAN);
863             offset += 1;
864
865             proto_tree_add_text (tree, tvb, offset, 2,
866                                  "Additional Length: %u",
867                                  tvb_get_ntohs (tvb, offset));
868             offset += 2;
869
870             offset += 1; /* reserved */
871
872             if (!(flags & BCU)) {
873                 proto_tree_add_text (tree, tvb, offset, 3,
874                                      "Number of Blocks in Buffer: %u",
875                                      tvb_get_ntoh24 (tvb, offset));
876             }
877             offset += 3;
878
879             if (!(flags & BPU)) {
880                 proto_tree_add_text (tree, tvb, offset, 8,
881                                      "First Block Location: %" G_GINT64_MODIFIER "u",
882                                      tvb_get_ntoh64 (tvb, offset));
883                 offset += 8;
884
885                 proto_tree_add_text (tree, tvb, offset, 8,
886                                      "Last Block Location: %" G_GINT64_MODIFIER "u",
887                                      tvb_get_ntoh64 (tvb, offset));
888                 offset += 8;
889             } else
890                 offset += 16;
891
892             offset += 1; /* reserved */
893
894             if (!(flags & BYCU)) {
895                 proto_tree_add_text (tree, tvb, offset, 8,
896                                      "Number of Bytes in Buffer: %" G_GINT64_MODIFIER "u",
897                                      tvb_get_ntoh64 (tvb, offset));
898             }
899             offset += 8;
900             break;
901
902         default:
903             break;
904         }
905     }
906 }
907
908
909
910
911
912 /* SSC Commands */
913 const value_string scsi_ssc_vals[] = {
914     {SCSI_SSC_ERASE_6                      , "Erase(6)"},
915     {SCSI_SSC_ERASE_16                     , "Erase(16)"},
916     {SCSI_SPC_EXTCOPY                      , "Extended Copy"},
917     {SCSI_SSC_FORMAT_MEDIUM                , "Format Medium"},
918     {SCSI_SPC_INQUIRY                      , "Inquiry"},
919     {SCSI_SSC_LOAD_UNLOAD                  , "Load Unload"},
920     {SCSI_SSC_LOCATE_10                    , "Locate(10)"},
921     {SCSI_SSC_LOCATE_16                    , "Locate(16)"},
922     {SCSI_SPC_LOGSELECT                    , "Log Select"},
923     {SCSI_SPC_LOGSENSE                     , "Log Sense"},
924     {SCSI_SPC_MODESELECT6                  , "Mode Select(6)"},
925     {SCSI_SPC_RESERVE6                     , "Reserve(6)"},
926     {SCSI_SPC_RELEASE6                     , "Release(6)"},
927     {SCSI_SPC_MODESELECT10                 , "Mode Select(10)"},
928     {SCSI_SPC_MODESENSE6                   , "Mode Sense(6)"},
929     {SCSI_SPC_MODESENSE10                  , "Mode Sense(10)"},
930     {SCSI_SMC_MOVE_MEDIUM                  , "Move Medium"},
931     {SCSI_SMC_MOVE_MEDIUM_ATTACHED         , "Move Medium Attached"},
932     {SCSI_SPC_PERSRESVIN                   , "Persistent Reserve In"},
933     {SCSI_SPC_PERSRESVOUT                  , "Persistent Reserve Out"},
934     {SCSI_SPC_PREVMEDREMOVAL               , "Prevent/Allow Medium Removal"},
935     {SCSI_SSC_READ6                        , "Read(6)"},
936     {SCSI_SSC_READ_16                      , "Read(16)"},
937     {SCSI_SSC_READ_BLOCK_LIMITS            , "Read Block Limits"},
938     {SCSI_SMC_READ_ELEMENT_STATUS          , "Read Element Status"},
939     {SCSI_SMC_READ_ELEMENT_STATUS_ATTACHED , "Read Element Status Attached"},
940     {SCSI_SSC_READ_POSITION                , "Read Position"},
941     {SCSI_SSC_READ_REVERSE_6               , "Read Reverse(6)"},
942     {SCSI_SSC_READ_REVERSE_16              , "Read Reverse(16)"},
943     {SCSI_SSC_RECOVER_BUFFERED_DATA        , "Recover Buffered Data"},
944     {SCSI_SSC_REPORT_DENSITY_SUPPORT       , "Report Density Support"},
945     {SCSI_SPC_REPORTLUNS                   , "Report LUNs"},
946     {SCSI_SPC_REQSENSE                     , "Request Sense"},
947     {SCSI_SSC_REWIND                       , "Rewind"},
948     {SCSI_SPC_SENDDIAG                     , "Send Diagnostic"},
949     {SCSI_SSC_SET_CAPACITY                 , "Set Capacity"},
950     {SCSI_SSC_SPACE_6                      , "Space(6)"},
951     {SCSI_SSC_SPACE_16                     , "Space(16)"},
952     {SCSI_SPC_TESTUNITRDY                  , "Test Unit Ready"},
953     {SCSI_SSC_VERIFY_6                     , "Verify(6)"},
954     {SCSI_SSC_VERIFY_16                    , "Verify(16)"},
955     {SCSI_SSC_WRITE6                       , "Write(6)"},
956     {SCSI_SSC_WRITE_16                     , "Write(16)"},
957     {SCSI_SPC_WRITEBUFFER                  , "Write Buffer"},
958     {SCSI_SSC_WRITE_FILEMARKS_16           , "Write Filemarks(16)"},
959     {SCSI_SSC_WRITE_FILEMARKS_6            , "Write Filemarks(6)"},
960     {0, NULL}
961 };
962
963
964 scsi_cdb_table_t scsi_ssc_table[256] = {
965 /*SPC 0x00*/{dissect_spc_testunitready},
966 /*SSC 0x01*/{dissect_ssc_rewind},
967 /*SSC 0x02*/{NULL},
968 /*SPC 0x03*/{dissect_spc_requestsense},
969 /*SSC 0x04*/{dissect_ssc_formatmedium},
970 /*SSC 0x05*/{dissect_ssc_readblocklimits},
971 /*SSC 0x06*/{NULL},
972 /*SSC 0x07*/{NULL},
973 /*SSC 0x08*/{dissect_ssc_read6},
974 /*SSC 0x09*/{NULL},
975 /*SSC 0x0a*/{dissect_ssc_write6},
976 /*SSC 0x0b*/{dissect_ssc_setcapacity},
977 /*SSC 0x0c*/{NULL},
978 /*SSC 0x0d*/{NULL},
979 /*SSC 0x0e*/{NULL},
980 /*SSC 0x0f*/{dissect_ssc_readreverse6},
981 /*SSC 0x10*/{dissect_ssc_writefilemarks6},
982 /*SSC 0x11*/{dissect_ssc_space6},
983 /*SPC 0x12*/{dissect_spc_inquiry},
984 /*SSC 0x13*/{dissect_ssc_verify6},
985 /*SSC 0x14*/{dissect_ssc_recoverbuffereddata},
986 /*SPC 0x15*/{dissect_spc_modeselect6},
987 /*SSC 0x16*/{dissect_spc_reserve6},
988 /*SSC 0x17*/{dissect_spc_release6},
989 /*SSC 0x18*/{NULL},
990 /*SSC 0x19*/{dissect_ssc_erase6},
991 /*SPC 0x1a*/{dissect_spc_modesense6},
992 /*SSC 0x1b*/{dissect_ssc_loadunload},
993 /*SSC 0x1c*/{NULL},
994 /*SPC 0x1d*/{dissect_spc_senddiagnostic},
995 /*SSC 0x1e*/{dissect_spc_preventallowmediaremoval},
996 /*SSC 0x1f*/{NULL},
997 /*SSC 0x20*/{NULL},
998 /*SSC 0x21*/{NULL},
999 /*SSC 0x22*/{NULL},
1000 /*SSC 0x23*/{NULL},
1001 /*SSC 0x24*/{NULL},
1002 /*SSC 0x25*/{NULL},
1003 /*SSC 0x26*/{NULL},
1004 /*SSC 0x27*/{NULL},
1005 /*SSC 0x28*/{NULL},
1006 /*SSC 0x29*/{NULL},
1007 /*SSC 0x2a*/{NULL},
1008 /*SSC 0x2b*/{dissect_ssc_locate10},
1009 /*SSC 0x2c*/{NULL},
1010 /*SSC 0x2d*/{NULL},
1011 /*SSC 0x2e*/{NULL},
1012 /*SSC 0x2f*/{NULL},
1013 /*SSC 0x30*/{NULL},
1014 /*SSC 0x31*/{NULL},
1015 /*SSC 0x32*/{NULL},
1016 /*SSC 0x33*/{NULL},
1017 /*SSC 0x34*/{dissect_ssc_readposition},
1018 /*SSC 0x35*/{NULL},
1019 /*SSC 0x36*/{NULL},
1020 /*SSC 0x37*/{NULL},
1021 /*SSC 0x38*/{NULL},
1022 /*SSC 0x39*/{NULL},
1023 /*SSC 0x3a*/{NULL},
1024 /*SPC 0x3b*/{dissect_spc_writebuffer},
1025 /*SSC 0x3c*/{NULL},
1026 /*SSC 0x3d*/{NULL},
1027 /*SSC 0x3e*/{NULL},
1028 /*SSC 0x3f*/{NULL},
1029 /*SSC 0x40*/{NULL},
1030 /*SSC 0x41*/{NULL},
1031 /*SSC 0x42*/{NULL},
1032 /*SSC 0x43*/{NULL},
1033 /*SSC 0x44*/{dissect_ssc_reportdensitysupport},
1034 /*SSC 0x45*/{NULL},
1035 /*SSC 0x46*/{NULL},
1036 /*SSC 0x47*/{NULL},
1037 /*SSC 0x48*/{NULL},
1038 /*SSC 0x49*/{NULL},
1039 /*SSC 0x4a*/{NULL},
1040 /*SSC 0x4b*/{NULL},
1041 /*SPC 0x4c*/{dissect_spc_logselect},
1042 /*SPC 0x4d*/{dissect_spc_logsense},
1043 /*SSC 0x4e*/{NULL},
1044 /*SSC 0x4f*/{NULL},
1045 /*SSC 0x50*/{NULL},
1046 /*SSC 0x51*/{NULL},
1047 /*SSC 0x52*/{NULL},
1048 /*SSC 0x53*/{NULL},
1049 /*SSC 0x54*/{NULL},
1050 /*SPC 0x55*/{dissect_spc_modeselect10},
1051 /*SSC 0x56*/{NULL},
1052 /*SSC 0x57*/{NULL},
1053 /*SSC 0x58*/{NULL},
1054 /*SSC 0x59*/{NULL},
1055 /*SPC 0x5a*/{dissect_spc_modesense10},
1056 /*SSC 0x5b*/{NULL},
1057 /*SSC 0x5c*/{NULL},
1058 /*SSC 0x5d*/{NULL},
1059 /*SPC 0x5e*/{dissect_spc_persistentreservein},
1060 /*SPC 0x5f*/{dissect_spc_persistentreserveout},
1061 /*SSC 0x60*/{NULL},
1062 /*SSC 0x61*/{NULL},
1063 /*SSC 0x62*/{NULL},
1064 /*SSC 0x63*/{NULL},
1065 /*SSC 0x64*/{NULL},
1066 /*SSC 0x65*/{NULL},
1067 /*SSC 0x66*/{NULL},
1068 /*SSC 0x67*/{NULL},
1069 /*SSC 0x68*/{NULL},
1070 /*SSC 0x69*/{NULL},
1071 /*SSC 0x6a*/{NULL},
1072 /*SSC 0x6b*/{NULL},
1073 /*SSC 0x6c*/{NULL},
1074 /*SSC 0x6d*/{NULL},
1075 /*SSC 0x6e*/{NULL},
1076 /*SSC 0x6f*/{NULL},
1077 /*SSC 0x70*/{NULL},
1078 /*SSC 0x71*/{NULL},
1079 /*SSC 0x72*/{NULL},
1080 /*SSC 0x73*/{NULL},
1081 /*SSC 0x74*/{NULL},
1082 /*SSC 0x75*/{NULL},
1083 /*SSC 0x76*/{NULL},
1084 /*SSC 0x77*/{NULL},
1085 /*SSC 0x78*/{NULL},
1086 /*SSC 0x79*/{NULL},
1087 /*SSC 0x7a*/{NULL},
1088 /*SSC 0x7b*/{NULL},
1089 /*SSC 0x7c*/{NULL},
1090 /*SSC 0x7d*/{NULL},
1091 /*SSC 0x7e*/{NULL},
1092 /*SSC 0x7f*/{NULL},
1093 /*SSC 0x80*/{dissect_ssc_writefilemarks16},
1094 /*SSC 0x81*/{dissect_ssc_readreverse16},
1095 /*SSC 0x82*/{NULL},
1096 /*SPC 0x83*/{dissect_spc_extcopy},
1097 /*SSC 0x84*/{NULL},
1098 /*SSC 0x85*/{NULL},
1099 /*SSC 0x86*/{NULL},
1100 /*SSC 0x87*/{NULL},
1101 /*SSC 0x88*/{dissect_ssc_read16},
1102 /*SSC 0x89*/{NULL},
1103 /*SSC 0x8a*/{dissect_ssc_write16},
1104 /*SSC 0x8b*/{NULL},
1105 /*SSC 0x8c*/{NULL},
1106 /*SSC 0x8d*/{NULL},
1107 /*SSC 0x8e*/{NULL},
1108 /*SSC 0x8f*/{dissect_ssc_verify16},
1109 /*SSC 0x90*/{NULL},
1110 /*SSC 0x91*/{dissect_ssc_space16},
1111 /*SSC 0x92*/{dissect_ssc_locate16},
1112 /*SSC 0x93*/{dissect_ssc_erase16},
1113 /*SSC 0x94*/{NULL},
1114 /*SSC 0x95*/{NULL},
1115 /*SSC 0x96*/{NULL},
1116 /*SSC 0x97*/{NULL},
1117 /*SSC 0x98*/{NULL},
1118 /*SSC 0x99*/{NULL},
1119 /*SSC 0x9a*/{NULL},
1120 /*SSC 0x9b*/{NULL},
1121 /*SSC 0x9c*/{NULL},
1122 /*SSC 0x9d*/{NULL},
1123 /*SSC 0x9e*/{NULL},
1124 /*SSC 0x9f*/{NULL},
1125 /*SPC 0xa0*/{dissect_spc_reportluns},
1126 /*SSC 0xa1*/{NULL},
1127 /*SSC 0xa2*/{NULL},
1128 /*SSC 0xa3*/{NULL},
1129 /*SSC 0xa4*/{NULL},
1130 /*SSC 0xa5*/{dissect_smc_movemedium},
1131 /*SSC 0xa6*/{NULL},
1132 /*SSC 0xa7*/{dissect_smc_movemedium},
1133 /*SSC 0xa8*/{NULL},
1134 /*SSC 0xa9*/{NULL},
1135 /*SSC 0xaa*/{NULL},
1136 /*SSC 0xab*/{NULL},
1137 /*SSC 0xac*/{NULL},
1138 /*SSC 0xad*/{NULL},
1139 /*SSC 0xae*/{NULL},
1140 /*SSC 0xaf*/{NULL},
1141 /*SSC 0xb0*/{NULL},
1142 /*SSC 0xb1*/{NULL},
1143 /*SSC 0xb2*/{NULL},
1144 /*SSC 0xb3*/{NULL},
1145 /*SSC 0xb4*/{dissect_smc_readelementstatus},
1146 /*SSC 0xb5*/{NULL},
1147 /*SSC 0xb6*/{NULL},
1148 /*SSC 0xb7*/{NULL},
1149 /*SSC 0xb8*/{dissect_smc_readelementstatus},
1150 /*SSC 0xb9*/{NULL},
1151 /*SSC 0xba*/{NULL},
1152 /*SSC 0xbb*/{NULL},
1153 /*SSC 0xbc*/{NULL},
1154 /*SSC 0xbd*/{NULL},
1155 /*SSC 0xbe*/{NULL},
1156 /*SSC 0xbf*/{NULL},
1157 /*SSC 0xc0*/{NULL},
1158 /*SSC 0xc1*/{NULL},
1159 /*SSC 0xc2*/{NULL},
1160 /*SSC 0xc3*/{NULL},
1161 /*SSC 0xc4*/{NULL},
1162 /*SSC 0xc5*/{NULL},
1163 /*SSC 0xc6*/{NULL},
1164 /*SSC 0xc7*/{NULL},
1165 /*SSC 0xc8*/{NULL},
1166 /*SSC 0xc9*/{NULL},
1167 /*SSC 0xca*/{NULL},
1168 /*SSC 0xcb*/{NULL},
1169 /*SSC 0xcc*/{NULL},
1170 /*SSC 0xcd*/{NULL},
1171 /*SSC 0xce*/{NULL},
1172 /*SSC 0xcf*/{NULL},
1173 /*SSC 0xd0*/{NULL},
1174 /*SSC 0xd1*/{NULL},
1175 /*SSC 0xd2*/{NULL},
1176 /*SSC 0xd3*/{NULL},
1177 /*SSC 0xd4*/{NULL},
1178 /*SSC 0xd5*/{NULL},
1179 /*SSC 0xd6*/{NULL},
1180 /*SSC 0xd7*/{NULL},
1181 /*SSC 0xd8*/{NULL},
1182 /*SSC 0xd9*/{NULL},
1183 /*SSC 0xda*/{NULL},
1184 /*SSC 0xdb*/{NULL},
1185 /*SSC 0xdc*/{NULL},
1186 /*SSC 0xdd*/{NULL},
1187 /*SSC 0xde*/{NULL},
1188 /*SSC 0xdf*/{NULL},
1189 /*SSC 0xe0*/{NULL},
1190 /*SSC 0xe1*/{NULL},
1191 /*SSC 0xe2*/{NULL},
1192 /*SSC 0xe3*/{NULL},
1193 /*SSC 0xe4*/{NULL},
1194 /*SSC 0xe5*/{NULL},
1195 /*SSC 0xe6*/{NULL},
1196 /*SSC 0xe7*/{NULL},
1197 /*SSC 0xe8*/{NULL},
1198 /*SSC 0xe9*/{NULL},
1199 /*SSC 0xea*/{NULL},
1200 /*SSC 0xeb*/{NULL},
1201 /*SSC 0xec*/{NULL},
1202 /*SSC 0xed*/{NULL},
1203 /*SSC 0xee*/{NULL},
1204 /*SSC 0xef*/{NULL},
1205 /*SSC 0xf0*/{NULL},
1206 /*SSC 0xf1*/{NULL},
1207 /*SSC 0xf2*/{NULL},
1208 /*SSC 0xf3*/{NULL},
1209 /*SSC 0xf4*/{NULL},
1210 /*SSC 0xf5*/{NULL},
1211 /*SSC 0xf6*/{NULL},
1212 /*SSC 0xf7*/{NULL},
1213 /*SSC 0xf8*/{NULL},
1214 /*SSC 0xf9*/{NULL},
1215 /*SSC 0xfa*/{NULL},
1216 /*SSC 0xfb*/{NULL},
1217 /*SSC 0xfc*/{NULL},
1218 /*SSC 0xfd*/{NULL},
1219 /*SSC 0xfe*/{NULL},
1220 /*SSC 0xff*/{NULL}
1221 };
1222
1223
1224
1225 void
1226 proto_register_scsi_ssc(void)
1227 {
1228         static hf_register_info hf[] = {
1229         { &hf_scsi_ssc_opcode,
1230           {"SSC Opcode", "scsi.ssc.opcode", FT_UINT8, BASE_HEX,
1231            VALS (scsi_ssc_vals), 0x0, NULL, HFILL}},
1232         { &hf_scsi_ssc_rdwr6_xferlen,
1233           {"Transfer Length", "scsi.ssc.rdwr6.xferlen", FT_UINT24, BASE_DEC, NULL, 0x0,
1234            NULL, HFILL}},
1235         { &hf_scsi_ssc_ver16_verlen,
1236           {"Verification Length", "scsi.ssc.verify16.verify_len", FT_UINT24, BASE_DEC, NULL, 0x0,
1237            NULL, HFILL}},
1238         { &hf_scsi_ssc_locate10_loid,
1239           {"Logical Object Identifier", "scsi.ssc.locate10.loid", FT_UINT32, BASE_DEC, NULL, 0x0,
1240            NULL, HFILL}},
1241         { &hf_scsi_ssc_locate16_loid,
1242           {"Logical Identifier", "scsi.ssc.locate16.loid", FT_UINT64, BASE_DEC, NULL, 0x0,
1243            NULL, HFILL}},
1244         { &hf_scsi_ssc_space6_count,
1245           {"Count", "scsi.ssc.space6.count", FT_INT24, BASE_DEC, NULL, 0x0,
1246            NULL, HFILL}},
1247         { &hf_scsi_ssc_space6_code,
1248           {"Code", "scsi.ssc.space6.code", FT_UINT8, BASE_HEX,
1249           VALS(space6_code_vals), 0x0f,
1250            NULL, HFILL}},
1251         { &hf_scsi_ssc_space16_count,
1252           {"Count", "scsi.ssc.space16.count", FT_UINT64, BASE_DEC, NULL, 0x0,
1253            NULL, HFILL}},
1254         { &hf_scsi_ssc_rdwr10_xferlen,
1255           {"Transfer Length", "scsi.ssc.rdwr10.xferlen", FT_UINT16, BASE_DEC, NULL,
1256            0x0, NULL, HFILL}},
1257         { &hf_scsi_ssc_erase_flags,
1258           {"Flags", "scsi.ssc.erase_flags", FT_UINT8, BASE_HEX,
1259            NULL, 0x0, NULL, HFILL}},
1260         { &hf_scsi_ssc_fcs,
1261           {"FCS", "scsi.ssc.fcs", FT_BOOLEAN, 8,
1262            NULL, 0x08, NULL, HFILL}},
1263         { &hf_scsi_ssc_lcs,
1264           {"LCS", "scsi.ssc.lcs", FT_BOOLEAN, 8,
1265            NULL, 0x04, NULL, HFILL}},
1266         { &hf_scsi_ssc_erase_immed,
1267           {"IMMED", "scsi.ssc.erase_immed", FT_BOOLEAN, 8,
1268            NULL, 0x02, NULL, HFILL}},
1269         { &hf_scsi_ssc_long,
1270           {"LONG", "scsi.ssc.long", FT_BOOLEAN, 8,
1271            NULL, 0x01, NULL, HFILL}},
1272         { &hf_scsi_ssc_partition,
1273           {"Partition", "scsi.ssc.partition", FT_UINT8, BASE_HEX,
1274            NULL, 0x0, NULL, HFILL}},
1275         { &hf_scsi_ssc_lbi,
1276           {"Logical Block Identifier", "scsi.ssc.lbi", FT_UINT64, BASE_HEX,
1277            NULL, 0x0, NULL, HFILL}},
1278         { &hf_scsi_ssc_verify,
1279           {"VERIFY", "scsi.ssc.verify", FT_BOOLEAN, 8,
1280            NULL, 0x02, NULL, HFILL}},
1281         { &hf_scsi_ssc_immed,
1282           {"IMMED", "scsi.ssc.immed", FT_BOOLEAN, 8,
1283            NULL, 0x01, NULL, HFILL}},
1284         { &hf_scsi_ssc_formatmedium_flags,
1285           {"Flags", "scsi.ssc.formatmedium_flags", FT_UINT8, BASE_HEX,
1286            NULL, 0x0, NULL, HFILL}},
1287         { &hf_scsi_ssc_format,
1288           {"Format", "scsi.ssc.format", FT_UINT8, BASE_HEX,
1289            VALS(format_vals), 0x0f, NULL, HFILL}},
1290         { &hf_scsi_ssc_loadunload_immed_flags,
1291           {"Immed", "scsi.ssc.loadunload_immed_flags", FT_UINT8, BASE_HEX,
1292            NULL, 0x0, NULL, HFILL}},
1293         { &hf_scsi_ssc_loadunload_flags,
1294           {"Flags", "scsi.ssc.loadunload_flags", FT_UINT8, BASE_HEX,
1295            NULL, 0x0, NULL, HFILL}},
1296         { &hf_scsi_ssc_hold,
1297           {"HOLD", "scsi.ssc.hold", FT_BOOLEAN, 8,
1298            NULL, 0x08, NULL, HFILL}},
1299         { &hf_scsi_ssc_eot,
1300           {"EOT", "scsi.ssc.eot", FT_BOOLEAN, 8,
1301            NULL, 0x04, NULL, HFILL}},
1302         { &hf_scsi_ssc_reten,
1303           {"RETEN", "scsi.ssc.reten", FT_BOOLEAN, 8,
1304            NULL, 0x02, NULL, HFILL}},
1305         { &hf_scsi_ssc_load,
1306           {"LOAD", "scsi.ssc.load", FT_BOOLEAN, 8,
1307            NULL, 0x01, NULL, HFILL}},
1308         { &hf_scsi_ssc_locate_flags,
1309           {"Flags", "scsi.ssc.locate_flags", FT_UINT8, BASE_HEX,
1310            NULL, 0x0, NULL, HFILL}},
1311         { &hf_scsi_ssc_bt,
1312           {"BT", "scsi.ssc.bt", FT_BOOLEAN, 8,
1313            NULL, 0x04, NULL, HFILL}},
1314         { &hf_scsi_ssc_cp,
1315           {"CP", "scsi.ssc.cp", FT_BOOLEAN, 8,
1316            NULL, 0x02, NULL, HFILL}},
1317         { &hf_scsi_ssc_dest_type,
1318           {"Dest Type", "scsi.ssc.dest_type", FT_UINT8, BASE_HEX,
1319            VALS(dest_type_vals), 0x18, NULL, HFILL}},
1320         { &hf_scsi_ssc_bam_flags,
1321           {"Flags", "scsi.ssc.bam_flags", FT_UINT8, BASE_HEX,
1322            NULL, 0x0, NULL, HFILL}},
1323         { &hf_scsi_ssc_bam,
1324           {"BAM", "scsi.ssc.bam", FT_BOOLEAN, 8,
1325            NULL, 0x01, NULL, HFILL}},
1326         { &hf_scsi_ssc_read6_flags,
1327           {"Flags", "scsi.ssc.read6_flags", FT_UINT8, BASE_HEX,
1328            NULL, 0x0, NULL, HFILL}},
1329         { &hf_scsi_ssc_sili,
1330           {"SILI", "scsi.ssc.sili", FT_BOOLEAN, 8,
1331            NULL, 0x02, NULL, HFILL}},
1332         { &hf_scsi_ssc_fixed,
1333           {"FIXED", "scsi.ssc.fixed", FT_BOOLEAN, 8,
1334            NULL, 0x01, NULL, HFILL}},
1335         { &hf_scsi_ssc_bytord,
1336           {"BYTORD", "scsi.ssc.bytord", FT_BOOLEAN, 8,
1337            NULL, 0x04, NULL, HFILL}},
1338         { &hf_scsi_ssc_bytcmp,
1339           {"BYTCMP", "scsi.ssc.bytcmp", FT_BOOLEAN, 8,
1340            NULL, 0x02, NULL, HFILL}},
1341         { &hf_scsi_ssc_verify16_immed,
1342           {"IMMED", "scsi.ssc.verify16_immed", FT_BOOLEAN, 8,
1343            NULL, 0x04, NULL, HFILL}},
1344         { &hf_scsi_ssc_medium_type,
1345           {"Medium Type", "scsi.ssc.medium_type", FT_BOOLEAN, 8,
1346            NULL, 0x02, NULL, HFILL}},
1347         { &hf_scsi_ssc_media,
1348           {"Media", "scsi.ssc.media", FT_BOOLEAN, 8,
1349            NULL, 0x01, NULL, HFILL}},
1350         { &hf_scsi_ssc_capacity_prop_value,
1351           {"Capacity Proportion Value", "scsi.ssc.cpv", FT_UINT16, BASE_DEC,
1352            NULL, 0, NULL, HFILL}},
1353         };
1354
1355
1356         /* Setup protocol subtree array */
1357         static gint *ett[] = {
1358                 &ett_scsi_erase,
1359                 &ett_scsi_formatmedium,
1360                 &ett_scsi_loadunload_immed,
1361                 &ett_scsi_loadunload,
1362                 &ett_scsi_locate,
1363                 &ett_scsi_bam,
1364                 &ett_scsi_read6
1365         };
1366
1367
1368         /* Register the protocol name and description */
1369         proto_scsi_ssc = proto_register_protocol("SCSI_SSC", "SCSI_SSC", "scsi_ssc");
1370
1371         /* Required function calls to register the header fields and subtrees used */
1372         proto_register_field_array(proto_scsi_ssc, hf, array_length(hf));
1373
1374         proto_register_subtree_array(ett, array_length(ett));
1375
1376 }
1377
1378 void
1379 proto_reg_handoff_scsi_ssc(void)
1380 {
1381 }
1382