0b6ba26327dd02d56fdf96a4e2a0d35ade02905d
[obnox/wireshark/wip.git] / epan / dissectors / packet-scsi-osd.c
1 /* packet-scsi-osd.c
2  * Ronnie sahlberg 2006
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 2002 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <glib.h>
30 #include <string.h>
31 #include <epan/strutil.h>
32 #include <epan/packet.h>
33 #include <epan/prefs.h>
34 #include <epan/emem.h>
35 #include <epan/conversation.h>
36 #include <epan/tap.h>
37 #include "packet-fc.h"
38 #include "packet-scsi.h"
39 #include "packet-scsi-osd.h"
40
41 static int proto_scsi_osd               = -1;
42 int hf_scsi_osd_opcode                  = -1;
43 static int hf_scsi_osd_control          = -1;
44 static int hf_scsi_osd_add_cdblen       = -1;
45 static int hf_scsi_osd_svcaction        = -1;
46 static int hf_scsi_osd_option           = -1;
47 static int hf_scsi_osd_option_dpo       = -1;
48 static int hf_scsi_osd_option_fua       = -1;
49 static int hf_scsi_osd_getsetattrib     = -1;
50 static int hf_scsi_osd_timestamps_control       = -1;
51 static int hf_scsi_osd_formatted_capacity       = -1;
52 static int hf_scsi_osd_get_attributes_page      = -1;
53 static int hf_scsi_osd_get_attributes_allocation_length = -1;
54 static int hf_scsi_osd_retreived_attributes_offset = -1;
55 static int hf_scsi_osd_set_attributes_page      = -1;
56 static int hf_scsi_osd_set_attribute_length     = -1;
57 static int hf_scsi_osd_set_attribute_number     = -1;
58 static int hf_scsi_osd_set_attributes_offset    = -1;
59 static int hf_scsi_osd_capability_format        = -1;
60 static int hf_scsi_osd_key_version      = -1;
61 static int hf_scsi_osd_icva             = -1;
62 static int hf_scsi_osd_security_method  = -1;
63 static int hf_scsi_osd_capability_expiration_time= -1;
64 static int hf_scsi_osd_audit= -1;
65 static int hf_scsi_osd_capability_discriminator = -1;
66 static int hf_scsi_osd_object_created_time= -1;
67 static int hf_scsi_osd_object_type      = -1;
68 static int hf_scsi_osd_permission_bitmask= -1;
69 static int hf_scsi_osd_object_descriptor_type   = -1;
70 static int hf_scsi_osd_object_descriptor= -1;
71 static int hf_scsi_osd_ricv             = -1;
72 static int hf_scsi_osd_request_nonce    = -1;
73 static int hf_scsi_osd_diicvo           = -1;
74 static int hf_scsi_osd_doicvo           = -1;
75 static int hf_scsi_osd_requested_partition_id   = -1;
76 static int hf_scsi_osd_sortorder        = -1;
77 static int hf_scsi_osd_partition_id     = -1;
78 static int hf_scsi_osd_list_identifier  = -1;
79 static int hf_scsi_osd_allocation_length= -1;
80 static int hf_scsi_osd_initial_object_id= -1;
81
82 static gint ett_osd_option              = -1;
83
84
85 typedef struct _scsi_osd_extra_data_t {
86         guint16 svcaction;
87         guint8  gsatype;
88 } scsi_osd_extra_data_t;
89
90 static const true_false_string option_dpo_tfs = {
91         "DPO is SET",
92         "Dpo is NOT set"
93 };
94 static const true_false_string option_fua_tfs = {
95         "FUA is SET",
96         "Fua is NOT set"
97 };
98
99 /* OSD2 5.2.4 */
100 static void
101 dissect_osd_option(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
102 {
103         proto_tree *tree=NULL;
104         proto_item *it=NULL;
105         guint8 option;
106
107         option=tvb_get_guint8(tvb, offset);
108
109         if(parent_tree){
110                 it=proto_tree_add_item(parent_tree, hf_scsi_osd_option, tvb, offset, 1, 0);
111                 tree = proto_item_add_subtree(it, ett_osd_option);
112         }
113
114         proto_tree_add_item(tree, hf_scsi_osd_option_dpo, tvb, offset, 1, 0);
115         if(option&0x10){
116                 proto_item_append_text(tree, " DPO");
117         }
118
119         proto_tree_add_item(tree, hf_scsi_osd_option_fua, tvb, offset, 1, 0);
120         if(option&0x08){
121                 proto_item_append_text(tree, " FUA");
122         }
123 }
124
125
126 static const value_string scsi_osd_getsetattrib_vals[] = {
127     {2,         "Get an attributes page and set an attribute value"},
128     {3,         "Get and set attributes using a list"},
129     {0, NULL},
130 };
131 /* OSD2 5.2.2.1 */
132 static void
133 dissect_osd_getsetattrib(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
134 {
135         if(cdata && cdata->itlq && cdata->itlq->extra_data){
136                 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
137                 extra_data->gsatype=(tvb_get_guint8(tvb, offset)>>4)&0x03;
138         }
139         proto_tree_add_item(tree, hf_scsi_osd_getsetattrib, tvb, offset, 1, 0);
140 }
141
142
143 static const value_string scsi_osd_timestamps_control_vals[] = {
144     {0x00,      "Timestamps shall be updated"},
145     {0x7f,      "Timestamps shall not be updated"},
146     {0, NULL},
147 };
148 /* OSD2 5.2.8 */
149 static void
150 dissect_osd_timestamps_control(tvbuff_t *tvb, int offset, proto_tree *tree)
151 {
152         proto_tree_add_item(tree, hf_scsi_osd_timestamps_control, tvb, offset, 1, 0);
153 }
154
155
156 static void
157 dissect_osd_formatted_capacity(tvbuff_t *tvb, int offset, proto_tree *tree)
158 {
159         proto_tree_add_item(tree, hf_scsi_osd_formatted_capacity, tvb, offset, 8, 0);
160 }
161
162
163 /* do we need to store these in the itlq structure ?*/
164 static void
165 dissect_osd_attribute_parameters(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
166 {
167         guint8 gsatype=0;
168
169         if(cdata && cdata->itlq && cdata->itlq->extra_data){
170                 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
171                 gsatype=extra_data->gsatype;
172         } else {
173                 return;
174         }
175
176         switch(gsatype){
177         case 2: /* 5.2.2.2  attribute page */
178                 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_page, tvb, offset, 4, 0);
179                 offset+=4;
180                 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, 0);
181                 offset+=4;
182                 proto_tree_add_item(tree, hf_scsi_osd_retreived_attributes_offset, tvb, offset, 4, 0);
183                 offset+=4;
184                 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, 0);
185                 offset+=4;
186                 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, 0);
187                 offset+=4;
188                 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, 0);
189                 offset+=4;
190                 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_offset, tvb, offset, 4, 0);
191                 offset+=4;
192                 break;
193         case 3: /* 5.2.2.3  attribute list */
194 /*qqq*/
195                 break;
196         }
197 }
198
199
200 static const value_string scsi_osd_capability_format_vals[] = {
201     {0x00,      "No Capability"},
202     {0x01,      "SCSI OSD2 Capabilities"},
203     {0, NULL},
204 };
205 static const value_string scsi_osd_object_type_vals[] = {
206     {0x01,      "ROOT"},
207     {0x02,      "PARTITION"},
208     {0x40,      "COLLECTION"},
209     {0x80,      "USER"},
210     {0, NULL},
211 };
212 static const value_string scsi_osd_object_descriptor_type_vals[] = {
213     {0, "NONE: the object descriptor field shall be ignored"},
214     {1, "U/C: a single collection or user object"},
215     {2, "PAR: a single partition, including partition zero"},
216     {0, NULL},
217 };
218
219 /* 4.9.2.2 */
220 static void
221 dissect_osd_capability(tvbuff_t *tvb, int offset, proto_tree *tree)
222 {
223         /* capability format */
224         proto_tree_add_item(tree, hf_scsi_osd_capability_format, tvb, offset, 1, 0);
225         offset++;
226
227         /* key version and icva */
228         proto_tree_add_item(tree, hf_scsi_osd_key_version, tvb, offset, 1, 0);
229         proto_tree_add_item(tree, hf_scsi_osd_icva, tvb, offset, 1, 0);
230         offset++;
231
232         /* security method */
233         proto_tree_add_item(tree, hf_scsi_osd_security_method, tvb, offset, 1, 0);
234         offset++;
235
236         /* a reserved byte */
237         offset++;
238
239         /* capability expiration time */
240         proto_tree_add_item(tree, hf_scsi_osd_capability_expiration_time, tvb, offset, 6, 0);
241         offset+=6;
242
243         /* audit */
244         proto_tree_add_item(tree, hf_scsi_osd_audit, tvb, offset, 20, 0);
245         offset+=20;
246
247         /* capability discriminator */
248         proto_tree_add_item(tree, hf_scsi_osd_capability_discriminator, tvb, offset, 12, 0);
249         offset+=12;
250
251         /* object created time */
252         proto_tree_add_item(tree, hf_scsi_osd_object_created_time, tvb, offset, 6, 0);
253         offset+=6;
254
255         /* object type */
256         proto_tree_add_item(tree, hf_scsi_osd_object_type, tvb, offset, 1, 0);
257         offset++;
258
259         /* permission bitmask */
260 /*qqq should be broken out into a helper and have the individual bits dissected */
261         proto_tree_add_item(tree, hf_scsi_osd_permission_bitmask, tvb, offset, 5, 0);
262         offset+=5;
263
264         /* a reserved byte */
265         offset++;
266
267         /* object descriptor type */
268         proto_tree_add_item(tree, hf_scsi_osd_object_descriptor_type, tvb, offset, 1, 0);
269         offset++;
270
271         /* object descriptor */
272         proto_tree_add_item(tree, hf_scsi_osd_object_descriptor, tvb, offset, 24, 0);
273         offset+=24;
274 }
275
276
277
278 /* 5.2.6 */
279 static void
280 dissect_osd_security_parameters(tvbuff_t *tvb, int offset, proto_tree *tree)
281 {
282         /* request integrity check value */
283         proto_tree_add_item(tree, hf_scsi_osd_ricv, tvb, offset, 20, 0);
284         offset+=20;
285
286         /* request nonce */
287         proto_tree_add_item(tree, hf_scsi_osd_request_nonce, tvb, offset, 12, 0);
288         offset+=12;
289
290         /* data in integrity check value offset */
291         proto_tree_add_item(tree, hf_scsi_osd_diicvo, tvb, offset, 4, 0);
292         offset+=4;
293
294         /* data out integrity check value offset */
295         proto_tree_add_item(tree, hf_scsi_osd_doicvo, tvb, offset, 4, 0);
296         offset+=4;
297 }
298
299 static void
300 dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
301                         guint offset, gboolean isreq, gboolean iscdb,
302                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
303 {
304         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
305         if(isreq && iscdb){
306                 /* options byte */
307                 dissect_osd_option(tvb, offset, tree);
308                 offset++;
309
310                 /* getset attributes byte */
311                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
312                 offset++;
313
314                 /* timestamps control */
315                 dissect_osd_timestamps_control(tvb, offset, tree);
316                 offset++;
317
318                 /* 23 reserved bytes */
319                 offset+=23;
320
321                 /* formatted capacity */
322                 dissect_osd_formatted_capacity(tvb, offset, tree);
323                 offset+=8;
324
325                 /* 8 reserved bytes */
326                 offset+=8;
327
328                 /* attribute parameters */
329                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
330                 offset+=28;
331
332                 /* capability */
333                 dissect_osd_capability(tvb, offset, tree);
334                 offset+=80;
335
336                 /* security parameters */
337                 dissect_osd_security_parameters(tvb, offset, tree);
338                 offset+=40;
339         }
340
341         /* dissecting the DATA OUT */
342         if(isreq && !iscdb){
343                 /* no data out for format osd */
344         }
345
346         /* dissecting the DATA IN */
347         if(!isreq && !iscdb){
348                 /* no data in for format osd */
349         }
350         
351 }
352
353
354 static void
355 dissect_osd_requested_partition_id(tvbuff_t *tvb, int offset, proto_tree *tree)
356 {
357         /* request partition id */
358         proto_tree_add_item(tree, hf_scsi_osd_requested_partition_id, tvb, offset, 8, 0);
359         offset+=8;
360 }
361
362 static void
363 dissect_osd_partition_id(tvbuff_t *tvb, int offset, proto_tree *tree)
364 {
365         /* request partition id */
366         proto_tree_add_item(tree, hf_scsi_osd_partition_id, tvb, offset, 8, 0);
367         offset+=8;
368 }
369
370
371
372 static void
373 dissect_osd_create_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
374                         guint offset, gboolean isreq, gboolean iscdb,
375                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
376 {
377         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
378         if(isreq && iscdb){
379                 /* options byte */
380                 dissect_osd_option(tvb, offset, tree);
381                 offset++;
382
383                 /* getset attributes byte */
384                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
385                 offset++;
386
387                 /* timestamps control */
388                 dissect_osd_timestamps_control(tvb, offset, tree);
389                 offset++;
390
391                 /* 3 reserved bytes */
392                 offset+=3;
393
394                 /* requested partiton id */
395                 dissect_osd_requested_partition_id(tvb, offset, tree);
396                 offset+=8;
397
398                 /* 28 reserved bytes */
399                 offset+=28;
400
401                 /* attribute parameters */
402                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
403                 offset+=28;
404
405                 /* capability */
406                 dissect_osd_capability(tvb, offset, tree);
407                 offset+=80;
408
409                 /* security parameters */
410                 dissect_osd_security_parameters(tvb, offset, tree);
411                 offset+=40;
412         }
413
414         /* dissecting the DATA OUT */
415         if(isreq && !iscdb){
416                 /* no data out for create partition */
417         }
418
419         /* dissecting the DATA IN */
420         if(!isreq && !iscdb){
421                 /* no data in for create partition */
422         }
423         
424 }
425
426 static const value_string scsi_osd_sort_order_vals[] = {
427     {0x00,      "Ascending numeric value"},
428     {0, NULL},
429 };
430 static void
431 dissect_osd_sortorder(tvbuff_t *tvb, int offset, proto_tree *tree)
432 {
433         /* sort order */
434         proto_tree_add_item(tree, hf_scsi_osd_sortorder, tvb, offset, 1, 0);
435         offset++;
436 }
437
438 static void
439 dissect_osd_list_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
440 {
441         /* list identifier */
442         proto_tree_add_item(tree, hf_scsi_osd_list_identifier, tvb, offset, 4, 0);
443         offset+=4;
444 }
445
446 static void
447 dissect_osd_allocation_length(tvbuff_t *tvb, int offset, proto_tree *tree)
448 {
449         /* allocation length */
450         proto_tree_add_item(tree, hf_scsi_osd_allocation_length, tvb, offset, 8, 0);
451         offset+=8;
452 }
453
454 static void
455 dissect_osd_initial_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
456 {
457         /* initial object id */
458         proto_tree_add_item(tree, hf_scsi_osd_initial_object_id, tvb, offset, 8, 0);
459         offset+=8;
460 }
461
462 static void
463 dissect_osd_list(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
464                         guint offset, gboolean isreq, gboolean iscdb,
465                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
466 {
467         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
468         if(isreq && iscdb){
469                 /* options byte */
470                 dissect_osd_option(tvb, offset, tree);
471                 offset++;
472
473                 /* getset attributes byte / sort order */
474                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
475                 dissect_osd_sortorder(tvb, offset, tree);
476                 offset++;
477
478                 /* timestamps control */
479                 dissect_osd_timestamps_control(tvb, offset, tree);
480                 offset++;
481
482                 /* 3 reserved bytes */
483                 offset+=3;
484
485                 /* partiton id */
486                 dissect_osd_partition_id(tvb, offset, tree);
487                 offset+=8;
488
489                 /* 8 reserved bytes */
490                 offset+=8;
491
492                 /* list identifier */
493                 dissect_osd_list_identifier(tvb, offset, tree);
494                 offset+=4;
495
496                 /* allocation length */
497                 dissect_osd_allocation_length(tvb, offset, tree);
498                 offset+=8;
499
500                 /* initial object id */
501                 dissect_osd_initial_object_id(tvb, offset, tree);
502                 offset+=8;
503
504                 /* attribute parameters */
505                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
506                 offset+=28;
507
508                 /* capability */
509                 dissect_osd_capability(tvb, offset, tree);
510                 offset+=80;
511
512                 /* security parameters */
513                 dissect_osd_security_parameters(tvb, offset, tree);
514                 offset+=40;
515         }
516
517         /* dissecting the DATA OUT */
518         if(isreq && !iscdb){
519                 /* no data out for LIST */
520         }
521
522         /* dissecting the DATA IN */
523         if(!isreq && !iscdb){
524                 /* dissection of the LIST DATA-IN */
525 /* qqq to be added ... */
526         }
527         
528 }
529
530
531 /* OSD Service Actions */
532 #define OSD_FORMAT_OSD          0x8801
533 #define OSD_LIST                0x8803
534 #define OSD_CREATE_PARTITION    0x880b
535 static const value_string scsi_osd_svcaction_vals[] = {
536     {OSD_FORMAT_OSD,            "Format OSD"},
537     {OSD_LIST,                  "List"},
538     {OSD_CREATE_PARTITION,      "Create Partition"},
539     {0, NULL},
540 };
541
542 /* OSD Service Action dissectors */
543 typedef struct _scsi_osd_svcaction_t {
544         guint16 svcaction;
545         scsi_dissector_t dissector;
546 } scsi_osd_svcaction_t;
547 static const scsi_osd_svcaction_t scsi_osd_svcaction[] = {
548     {OSD_FORMAT_OSD,            dissect_osd_format_osd},
549     {OSD_LIST,                  dissect_osd_list},
550     {OSD_CREATE_PARTITION,      dissect_osd_create_partition},
551     {0, NULL},
552 };
553
554 static scsi_dissector_t
555 find_svcaction_dissector(guint16 svcaction)
556 {
557         const scsi_osd_svcaction_t *sa=scsi_osd_svcaction;
558
559         while(sa&&sa->dissector){
560                 if(sa->svcaction==svcaction){
561                         return sa->dissector;
562                 }
563                 sa++;
564         }
565         return NULL;
566 }
567
568
569
570 static void
571 dissect_osd_opcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
572                         guint offset, gboolean isreq, gboolean iscdb,
573                         guint payload_len, scsi_task_data_t *cdata)
574 {
575         guint16 svcaction=0;
576         scsi_dissector_t dissector;
577
578         if(!tree) {
579                 return;
580         }
581
582         /* dissecting the CDB */
583         if (isreq && iscdb) {
584                 proto_tree_add_item (tree, hf_scsi_osd_control, tvb, offset, 1, 0);
585                 offset++;
586
587                 /* 5 reserved bytes */
588                 offset+=5;
589
590                 proto_tree_add_item (tree, hf_scsi_osd_add_cdblen, tvb, offset, 1, 0);
591                 offset++;
592
593                 svcaction=tvb_get_ntohs(tvb, offset);
594                 if(cdata && cdata->itlq){
595                         /* We must store the service action for this itlq
596                          * so we can indentify what the data contains
597                          */
598                         if((!pinfo->fd->flags.visited) && (!cdata->itlq->extra_data)){
599                                 scsi_osd_extra_data_t *extra_data;
600
601                                 extra_data=se_alloc(sizeof(scsi_osd_extra_data_t));
602                                 extra_data->svcaction=svcaction;
603                                 extra_data->gsatype=0;
604                                 cdata->itlq->extra_data=extra_data;
605                         }
606                 }
607                 proto_tree_add_item (tree, hf_scsi_osd_svcaction, tvb, offset, 2, 0);
608                 offset+=2;
609
610
611                 if(check_col(pinfo->cinfo, COL_INFO)){
612                         col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
613                                 val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
614                 }
615                 dissector=find_svcaction_dissector(svcaction);
616                 if(dissector){
617                         (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata);
618                 }
619                 return;
620         }
621
622         /* If it was not a CDB, try to find the service action and pass it
623          * off to the service action dissector
624          */
625         if(cdata && cdata->itlq && cdata->itlq->extra_data){
626                 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
627                 svcaction=extra_data->svcaction;
628         }
629         if(check_col(pinfo->cinfo, COL_INFO)){
630                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
631                         val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
632         }
633         if(svcaction){
634                 proto_item *it;
635                 it=proto_tree_add_uint_format(tree, hf_scsi_osd_svcaction, tvb, 0, 0, svcaction, "Service Action: 0x%04x", svcaction);
636                 PROTO_ITEM_SET_GENERATED(it);
637         }
638         dissector=find_svcaction_dissector(svcaction);
639         if(dissector){
640                 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata);
641         }
642
643 }
644
645
646 /* OSD Commands */
647 const value_string scsi_osd_vals[] = {
648     {SCSI_SPC2_INQUIRY                  , "Inquiry"},
649     {SCSI_SPC2_LOGSELECT                , "Log Select"},
650     {SCSI_SPC2_LOGSENSE                 , "Log Sense"},
651     {SCSI_SPC2_MODESELECT10             , "Mode Select(10)"},
652     {SCSI_SPC2_MODESENSE10              , "Mode Sense(10)"},
653     {SCSI_SPC2_PERSRESVIN               , "Persistent Reserve In"},
654     {SCSI_SPC2_PERSRESVOUT              , "Persistent Reserve Out"},
655     {SCSI_SPC2_REPORTLUNS               , "Report LUNs"},
656     {SCSI_OSD_OPCODE                    , "OSD Command" },
657     {0, NULL},
658 };
659
660
661
662 scsi_cdb_table_t scsi_osd_table[256] = {
663 /*OSD 0x00*/{NULL},
664 /*OSD 0x01*/{NULL},
665 /*OSD 0x02*/{NULL},
666 /*OSD 0x03*/{NULL},
667 /*OSD 0x04*/{NULL},
668 /*OSD 0x05*/{NULL},
669 /*OSD 0x06*/{NULL},
670 /*OSD 0x07*/{NULL},
671 /*OSD 0x08*/{NULL},
672 /*OSD 0x09*/{NULL},
673 /*OSD 0x0a*/{NULL},
674 /*OSD 0x0b*/{NULL},
675 /*OSD 0x0c*/{NULL},
676 /*OSD 0x0d*/{NULL},
677 /*OSD 0x0e*/{NULL},
678 /*OSD 0x0f*/{NULL},
679 /*OSD 0x10*/{NULL},
680 /*OSD 0x11*/{NULL},
681 /*OSD 0x12*/{dissect_spc3_inquiry},
682 /*OSD 0x13*/{NULL},
683 /*OSD 0x14*/{NULL},
684 /*OSD 0x15*/{NULL},
685 /*OSD 0x16*/{NULL},
686 /*OSD 0x17*/{NULL},
687 /*OSD 0x18*/{NULL},
688 /*OSD 0x19*/{NULL},
689 /*OSD 0x1a*/{NULL},
690 /*OSD 0x1b*/{NULL},
691 /*OSD 0x1c*/{NULL},
692 /*OSD 0x1d*/{NULL},
693 /*OSD 0x1e*/{NULL},
694 /*OSD 0x1f*/{NULL},
695 /*OSD 0x20*/{NULL},
696 /*OSD 0x21*/{NULL},
697 /*OSD 0x22*/{NULL},
698 /*OSD 0x23*/{NULL},
699 /*OSD 0x24*/{NULL},
700 /*OSD 0x25*/{NULL},
701 /*OSD 0x26*/{NULL},
702 /*OSD 0x27*/{NULL},
703 /*OSD 0x28*/{NULL},
704 /*OSD 0x29*/{NULL},
705 /*OSD 0x2a*/{NULL},
706 /*OSD 0x2b*/{NULL},
707 /*OSD 0x2c*/{NULL},
708 /*OSD 0x2d*/{NULL},
709 /*OSD 0x2e*/{NULL},
710 /*OSD 0x2f*/{NULL},
711 /*OSD 0x30*/{NULL},
712 /*OSD 0x31*/{NULL},
713 /*OSD 0x32*/{NULL},
714 /*OSD 0x33*/{NULL},
715 /*OSD 0x34*/{NULL},
716 /*OSD 0x35*/{NULL},
717 /*OSD 0x36*/{NULL},
718 /*OSD 0x37*/{NULL},
719 /*OSD 0x38*/{NULL},
720 /*OSD 0x39*/{NULL},
721 /*OSD 0x3a*/{NULL},
722 /*OSD 0x3b*/{NULL},
723 /*OSD 0x3c*/{NULL},
724 /*OSD 0x3d*/{NULL},
725 /*OSD 0x3e*/{NULL},
726 /*OSD 0x3f*/{NULL},
727 /*OSD 0x40*/{NULL},
728 /*OSD 0x41*/{NULL},
729 /*OSD 0x42*/{NULL},
730 /*OSD 0x43*/{NULL},
731 /*OSD 0x44*/{NULL},
732 /*OSD 0x45*/{NULL},
733 /*OSD 0x46*/{NULL},
734 /*OSD 0x47*/{NULL},
735 /*OSD 0x48*/{NULL},
736 /*OSD 0x49*/{NULL},
737 /*OSD 0x4a*/{NULL},
738 /*OSD 0x4b*/{NULL},
739 /*OSD 0x4c*/{dissect_spc3_logselect},
740 /*OSD 0x4d*/{dissect_spc3_logsense},
741 /*OSD 0x4e*/{NULL},
742 /*OSD 0x4f*/{NULL},
743 /*OSD 0x50*/{NULL},
744 /*OSD 0x51*/{NULL},
745 /*OSD 0x52*/{NULL},
746 /*OSD 0x53*/{NULL},
747 /*OSD 0x54*/{NULL},
748 /*OSD 0x55*/{dissect_spc3_modeselect10},
749 /*OSD 0x56*/{NULL},
750 /*OSD 0x57*/{NULL},
751 /*OSD 0x58*/{NULL},
752 /*OSD 0x59*/{NULL},
753 /*OSD 0x5a*/{dissect_spc3_modesense10},
754 /*OSD 0x5b*/{NULL},
755 /*OSD 0x5c*/{NULL},
756 /*OSD 0x5d*/{NULL},
757 /*OSD 0x5e*/{dissect_spc3_persistentreservein},
758 /*OSD 0x5f*/{dissect_spc3_persistentreserveout},
759 /*OSD 0x60*/{NULL},
760 /*OSD 0x61*/{NULL},
761 /*OSD 0x62*/{NULL},
762 /*OSD 0x63*/{NULL},
763 /*OSD 0x64*/{NULL},
764 /*OSD 0x65*/{NULL},
765 /*OSD 0x66*/{NULL},
766 /*OSD 0x67*/{NULL},
767 /*OSD 0x68*/{NULL},
768 /*OSD 0x69*/{NULL},
769 /*OSD 0x6a*/{NULL},
770 /*OSD 0x6b*/{NULL},
771 /*OSD 0x6c*/{NULL},
772 /*OSD 0x6d*/{NULL},
773 /*OSD 0x6e*/{NULL},
774 /*OSD 0x6f*/{NULL},
775 /*OSD 0x70*/{NULL},
776 /*OSD 0x71*/{NULL},
777 /*OSD 0x72*/{NULL},
778 /*OSD 0x73*/{NULL},
779 /*OSD 0x74*/{NULL},
780 /*OSD 0x75*/{NULL},
781 /*OSD 0x76*/{NULL},
782 /*OSD 0x77*/{NULL},
783 /*OSD 0x78*/{NULL},
784 /*OSD 0x79*/{NULL},
785 /*OSD 0x7a*/{NULL},
786 /*OSD 0x7b*/{NULL},
787 /*OSD 0x7c*/{NULL},
788 /*OSD 0x7d*/{NULL},
789 /*OSD 0x7e*/{NULL},
790 /*OSD 0x7f*/{dissect_osd_opcode},
791 /*OSD 0x80*/{NULL},
792 /*OSD 0x81*/{NULL},
793 /*OSD 0x82*/{NULL},
794 /*OSD 0x83*/{NULL},
795 /*OSD 0x84*/{NULL},
796 /*OSD 0x85*/{NULL},
797 /*OSD 0x86*/{NULL},
798 /*OSD 0x87*/{NULL},
799 /*OSD 0x88*/{NULL},
800 /*OSD 0x89*/{NULL},
801 /*OSD 0x8a*/{NULL},
802 /*OSD 0x8b*/{NULL},
803 /*OSD 0x8c*/{NULL},
804 /*OSD 0x8d*/{NULL},
805 /*OSD 0x8e*/{NULL},
806 /*OSD 0x8f*/{NULL},
807 /*OSD 0x90*/{NULL},
808 /*OSD 0x91*/{NULL},
809 /*OSD 0x92*/{NULL},
810 /*OSD 0x93*/{NULL},
811 /*OSD 0x94*/{NULL},
812 /*OSD 0x95*/{NULL},
813 /*OSD 0x96*/{NULL},
814 /*OSD 0x97*/{NULL},
815 /*OSD 0x98*/{NULL},
816 /*OSD 0x99*/{NULL},
817 /*OSD 0x9a*/{NULL},
818 /*OSD 0x9b*/{NULL},
819 /*OSD 0x9c*/{NULL},
820 /*OSD 0x9d*/{NULL},
821 /*OSD 0x9e*/{NULL},
822 /*OSD 0x9f*/{NULL},
823 /*OSD 0xa0*/{dissect_spc3_reportluns},
824 /*OSD 0xa1*/{NULL},
825 /*OSD 0xa2*/{NULL},
826 /*OSD 0xa3*/{NULL},
827 /*OSD 0xa4*/{NULL},
828 /*OSD 0xa5*/{NULL},
829 /*OSD 0xa6*/{NULL},
830 /*OSD 0xa7*/{NULL},
831 /*OSD 0xa8*/{NULL},
832 /*OSD 0xa9*/{NULL},
833 /*OSD 0xaa*/{NULL},
834 /*OSD 0xab*/{NULL},
835 /*OSD 0xac*/{NULL},
836 /*OSD 0xad*/{NULL},
837 /*OSD 0xae*/{NULL},
838 /*OSD 0xaf*/{NULL},
839 /*OSD 0xb0*/{NULL},
840 /*OSD 0xb1*/{NULL},
841 /*OSD 0xb2*/{NULL},
842 /*OSD 0xb3*/{NULL},
843 /*OSD 0xb4*/{NULL},
844 /*OSD 0xb5*/{NULL},
845 /*OSD 0xb6*/{NULL},
846 /*OSD 0xb7*/{NULL},
847 /*OSD 0xb8*/{NULL},
848 /*OSD 0xb9*/{NULL},
849 /*OSD 0xba*/{NULL},
850 /*OSD 0xbb*/{NULL},
851 /*OSD 0xbc*/{NULL},
852 /*OSD 0xbd*/{NULL},
853 /*OSD 0xbe*/{NULL},
854 /*OSD 0xbf*/{NULL},
855 /*OSD 0xc0*/{NULL},
856 /*OSD 0xc1*/{NULL},
857 /*OSD 0xc2*/{NULL},
858 /*OSD 0xc3*/{NULL},
859 /*OSD 0xc4*/{NULL},
860 /*OSD 0xc5*/{NULL},
861 /*OSD 0xc6*/{NULL},
862 /*OSD 0xc7*/{NULL},
863 /*OSD 0xc8*/{NULL},
864 /*OSD 0xc9*/{NULL},
865 /*OSD 0xca*/{NULL},
866 /*OSD 0xcb*/{NULL},
867 /*OSD 0xcc*/{NULL},
868 /*OSD 0xcd*/{NULL},
869 /*OSD 0xce*/{NULL},
870 /*OSD 0xcf*/{NULL},
871 /*OSD 0xd0*/{NULL},
872 /*OSD 0xd1*/{NULL},
873 /*OSD 0xd2*/{NULL},
874 /*OSD 0xd3*/{NULL},
875 /*OSD 0xd4*/{NULL},
876 /*OSD 0xd5*/{NULL},
877 /*OSD 0xd6*/{NULL},
878 /*OSD 0xd7*/{NULL},
879 /*OSD 0xd8*/{NULL},
880 /*OSD 0xd9*/{NULL},
881 /*OSD 0xda*/{NULL},
882 /*OSD 0xdb*/{NULL},
883 /*OSD 0xdc*/{NULL},
884 /*OSD 0xdd*/{NULL},
885 /*OSD 0xde*/{NULL},
886 /*OSD 0xdf*/{NULL},
887 /*OSD 0xe0*/{NULL},
888 /*OSD 0xe1*/{NULL},
889 /*OSD 0xe2*/{NULL},
890 /*OSD 0xe3*/{NULL},
891 /*OSD 0xe4*/{NULL},
892 /*OSD 0xe5*/{NULL},
893 /*OSD 0xe6*/{NULL},
894 /*OSD 0xe7*/{NULL},
895 /*OSD 0xe8*/{NULL},
896 /*OSD 0xe9*/{NULL},
897 /*OSD 0xea*/{NULL},
898 /*OSD 0xeb*/{NULL},
899 /*OSD 0xec*/{NULL},
900 /*OSD 0xed*/{NULL},
901 /*OSD 0xee*/{NULL},
902 /*OSD 0xef*/{NULL},
903 /*OSD 0xf0*/{NULL},
904 /*OSD 0xf1*/{NULL},
905 /*OSD 0xf2*/{NULL},
906 /*OSD 0xf3*/{NULL},
907 /*OSD 0xf4*/{NULL},
908 /*OSD 0xf5*/{NULL},
909 /*OSD 0xf6*/{NULL},
910 /*OSD 0xf7*/{NULL},
911 /*OSD 0xf8*/{NULL},
912 /*OSD 0xf9*/{NULL},
913 /*OSD 0xfa*/{NULL},
914 /*OSD 0xfb*/{NULL},
915 /*OSD 0xfc*/{NULL},
916 /*OSD 0xfd*/{NULL},
917 /*OSD 0xfe*/{NULL},
918 /*OSD 0xff*/{NULL}
919 };
920
921
922
923
924 void
925 proto_register_scsi_osd(void)
926 {
927         static hf_register_info hf[] = {
928         { &hf_scsi_osd_opcode,
929           {"OSD Opcode", "scsi.osd.opcode", FT_UINT8, BASE_HEX,
930            VALS (scsi_osd_vals), 0x0, "", HFILL}},
931         { &hf_scsi_osd_control,
932           {"Control", "scsi.osd.cdb.control", FT_UINT8, BASE_HEX,
933            NULL, 0x0, "", HFILL}},
934         { &hf_scsi_osd_add_cdblen,
935           {"Additional CDB Length", "scsi.osd.addcdblen", FT_UINT8, BASE_DEC,
936            NULL, 0x0, "", HFILL}},
937         { &hf_scsi_osd_svcaction,
938           {"Service Action", "scsi.osd.svcaction", FT_UINT16, BASE_HEX,
939            VALS(scsi_osd_svcaction_vals), 0x0, "", HFILL}},
940         { &hf_scsi_osd_option,
941           {"Option", "scsi.osd.option", FT_UINT8, BASE_HEX,
942            NULL, 0x0, "", HFILL}},
943         { &hf_scsi_osd_option_dpo,
944           {"DPO", "scsi.osd.option.dpo", FT_BOOLEAN, 8,
945            TFS(&option_dpo_tfs), 0x10, "", HFILL}},
946         { &hf_scsi_osd_option_fua,
947           {"FUA", "scsi.osd.option.fua", FT_BOOLEAN, 8,
948            TFS(&option_fua_tfs), 0x08, "", HFILL}},
949         { &hf_scsi_osd_getsetattrib,
950           {"GET/SET CDBFMT", "scsi.osd.getset", FT_UINT8, BASE_HEX,
951            VALS(scsi_osd_getsetattrib_vals), 0x30, "", HFILL}},
952         { &hf_scsi_osd_timestamps_control,
953           {"Timestamps Control", "scsi.osd.timestamps_control", FT_UINT8, BASE_HEX,
954            VALS(scsi_osd_timestamps_control_vals), 0x0, "", HFILL}},
955         { &hf_scsi_osd_formatted_capacity,
956           {"Formatted Capacity", "scsi.osd.formatted_capacity", FT_UINT64, BASE_DEC,
957            NULL, 0x0, "", HFILL}},
958         { &hf_scsi_osd_get_attributes_page,
959           {"Get Attributes Page", "scsi.osd.get_attributes_page", FT_UINT32, BASE_HEX,
960            NULL, 0x0, "", HFILL}},
961         { &hf_scsi_osd_get_attributes_allocation_length,
962           {"Get Attributes Allocation Length", "scsi.osd.get_attributes_allocation_length", FT_UINT32, BASE_HEX,
963            NULL, 0x0, "", HFILL}},
964         { &hf_scsi_osd_retreived_attributes_offset,
965           {"Retreived Attributes Offset", "scsi.osd.retreived_attributes_offset", FT_UINT32, BASE_HEX,
966            NULL, 0x0, "", HFILL}},
967         { &hf_scsi_osd_set_attributes_page,
968           {"Set Attributes Page", "scsi.osd.set_attributes_page", FT_UINT32, BASE_HEX,
969            NULL, 0x0, "", HFILL}},
970         { &hf_scsi_osd_set_attribute_length,
971           {"Set Attribute Length", "scsi.osd.set_attribute_length", FT_UINT32, BASE_HEX,
972            NULL, 0x0, "", HFILL}},
973         { &hf_scsi_osd_set_attribute_number,
974           {"Set Attribute Number", "scsi.osd.set_attribute_number", FT_UINT32, BASE_HEX,
975            NULL, 0x0, "", HFILL}},
976         { &hf_scsi_osd_set_attributes_offset,
977           {"Set Attributes Offset", "scsi.osd.set_attributes_offset", FT_UINT32, BASE_HEX,
978            NULL, 0x0, "", HFILL}},
979         { &hf_scsi_osd_capability_format,
980           {"Capability Format", "scsi.osd.capability_format", FT_UINT8, BASE_HEX,
981            VALS(scsi_osd_capability_format_vals), 0x0f, "", HFILL}},
982         { &hf_scsi_osd_key_version,
983           {"Key Version", "scsi.osd.key_version", FT_UINT8, BASE_HEX,
984            NULL, 0xf0, "", HFILL}},
985         { &hf_scsi_osd_icva,
986           {"Integrity Check Value Algorithm", "scsi.osd.icva", FT_UINT8, BASE_HEX,
987            NULL, 0x0f, "", HFILL}},
988         { &hf_scsi_osd_security_method,
989           {"Security Method", "scsi.osd.security_method", FT_UINT8, BASE_HEX,
990            NULL, 0x0f, "", HFILL}},
991         { &hf_scsi_osd_capability_expiration_time,
992           {"Capability Expiration Time", "scsi.osd.capability_expiration_time", FT_BYTES, BASE_HEX,
993            NULL, 0, "", HFILL}},
994         { &hf_scsi_osd_audit,
995           {"Audit", "scsi.osd.audit", FT_BYTES, BASE_HEX,
996            NULL, 0, "", HFILL}},
997         { &hf_scsi_osd_capability_discriminator,
998           {"Capability Discriminator", "scsi.osd.capability_descriminator", FT_BYTES, BASE_HEX,
999            NULL, 0, "", HFILL}},
1000         { &hf_scsi_osd_object_created_time,
1001           {"Object Created Time", "scsi.osd.object_created_time", FT_BYTES, BASE_HEX,
1002            NULL, 0, "", HFILL}},
1003         { &hf_scsi_osd_object_type,
1004           {"Object Type", "scsi.osd.object_type", FT_UINT8, BASE_HEX,
1005            VALS(scsi_osd_object_type_vals), 0, "", HFILL}},
1006         { &hf_scsi_osd_permission_bitmask,
1007           {"Permission Bitmask", "scsi.osd.permission_bitmask", FT_BYTES, BASE_HEX,
1008            NULL, 0, "", HFILL}},
1009         { &hf_scsi_osd_object_descriptor_type,
1010           {"Object Descriptor Type", "scsi.osd.object_descriptor_type", FT_UINT8, BASE_HEX,
1011            VALS(scsi_osd_object_descriptor_type_vals), 0xf0, "", HFILL}},
1012         { &hf_scsi_osd_object_descriptor,
1013           {"Object Descriptor", "scsi.osd.object_descriptor", FT_BYTES, BASE_HEX,
1014            NULL, 0, "", HFILL}},
1015         { &hf_scsi_osd_ricv,
1016           {"Request Integrity Check value", "scsi.osd.ricv", FT_BYTES, BASE_HEX,
1017            NULL, 0, "", HFILL}},
1018         { &hf_scsi_osd_request_nonce,
1019           {"Request Nonce", "scsi.osd.request_nonce", FT_BYTES, BASE_HEX,
1020            NULL, 0, "", HFILL}},
1021         { &hf_scsi_osd_diicvo,
1022           {"Data-In Integrity Check Value Offset", "scsi.osd.diicvo", FT_UINT32, BASE_DEC,
1023            NULL, 0, "", HFILL}},
1024         { &hf_scsi_osd_doicvo,
1025           {"Data-Out Integrity Check Value Offset", "scsi.osd.doicvo", FT_UINT32, BASE_DEC,
1026            NULL, 0, "", HFILL}},
1027         { &hf_scsi_osd_requested_partition_id,
1028           {"Requested Partition Id", "scsi.osd.requested_partition_id", FT_BYTES, BASE_HEX,
1029            NULL, 0, "", HFILL}},
1030         { &hf_scsi_osd_sortorder,
1031           {"Sort Order", "scsi.osd.sort_order", FT_UINT8, BASE_DEC,
1032            VALS(scsi_osd_sort_order_vals), 0x0f, "", HFILL}},
1033         { &hf_scsi_osd_partition_id,
1034           {"Partition Id", "scsi.osd.partition_id", FT_BYTES, BASE_HEX,
1035            NULL, 0, "", HFILL}},
1036         { &hf_scsi_osd_list_identifier,
1037           {"List Identifier", "scsi.osd.list_identifier", FT_UINT32, BASE_DEC,
1038            NULL, 0, "", HFILL}},
1039         { &hf_scsi_osd_allocation_length,
1040           {"Allocation Length", "scsi.osd.allocation_length", FT_UINT64, BASE_DEC,
1041            NULL, 0, "", HFILL}},
1042         { &hf_scsi_osd_initial_object_id,
1043           {"Initial Object Id", "scsi.osd.initial_object_id", FT_BYTES, BASE_HEX,
1044            NULL, 0, "", HFILL}},
1045         };
1046
1047         /* Setup protocol subtree array */
1048         static gint *ett[] = {
1049                 &ett_osd_option,
1050         };
1051
1052         /* Register the protocol name and description */
1053         proto_scsi_osd = proto_register_protocol("SCSI_OSD", "SCSI_OSD", "scsi_osd");
1054
1055         /* Required function calls to register the header fields and subtrees used */
1056         proto_register_field_array(proto_scsi_osd, hf, array_length(hf));
1057         proto_register_subtree_array(ett, array_length(ett));
1058 }
1059
1060 void
1061 proto_reg_handoff_scsi_osd(void)
1062 {
1063 }
1064