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