b5d7e448d9eea5644d11746f2805bb72dd1c1e63
[obnox/wireshark/wip.git] / epan / dissectors / packet-scsi-osd.c
1 /* packet-scsi-osd.c
2  * Ronnie sahlberg 2006
3  * Joe Breher 2006
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 2002 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <string.h>
32 #include <epan/strutil.h>
33 #include <epan/packet.h>
34 #include <epan/prefs.h>
35 #include <epan/emem.h>
36 #include <epan/conversation.h>
37 #include <epan/tap.h>
38 #include "packet-scsi.h"
39 #include "packet-fc.h"
40 #include "packet-scsi-osd.h"
41
42
43 static int proto_scsi_osd               = -1;
44 int hf_scsi_osd_opcode                  = -1;
45 static int hf_scsi_osd_control          = -1;
46 static int hf_scsi_osd_add_cdblen       = -1;
47 static int hf_scsi_osd_svcaction        = -1;
48 static int hf_scsi_osd_option           = -1;
49 static int hf_scsi_osd_option_dpo       = -1;
50 static int hf_scsi_osd_option_fua       = -1;
51 static int hf_scsi_osd_getsetattrib     = -1;
52 static int hf_scsi_osd_timestamps_control       = -1;
53 static int hf_scsi_osd_formatted_capacity       = -1;
54 static int hf_scsi_osd_get_attributes_page      = -1;
55 static int hf_scsi_osd_get_attributes_allocation_length = -1;
56 static int hf_scsi_osd_get_attributes_list_length= -1;
57 static int hf_scsi_osd_get_attributes_list_offset= -1;
58 static int hf_scsi_osd_retreived_attributes_offset = -1;
59 static int hf_scsi_osd_set_attributes_page      = -1;
60 static int hf_scsi_osd_set_attribute_length     = -1;
61 static int hf_scsi_osd_set_attribute_number     = -1;
62 static int hf_scsi_osd_set_attributes_offset    = -1;
63 static int hf_scsi_osd_set_attributes_list_length= -1;
64 static int hf_scsi_osd_set_attributes_list_offset= -1;
65 static int hf_scsi_osd_capability_format        = -1;
66 static int hf_scsi_osd_key_version      = -1;
67 static int hf_scsi_osd_icva             = -1;
68 static int hf_scsi_osd_security_method  = -1;
69 static int hf_scsi_osd_capability_expiration_time= -1;
70 static int hf_scsi_osd_audit= -1;
71 static int hf_scsi_osd_capability_discriminator = -1;
72 static int hf_scsi_osd_object_created_time= -1;
73 static int hf_scsi_osd_object_type      = -1;
74 static int hf_scsi_osd_permissions      = -1;
75 static int hf_scsi_osd_permissions_read = -1;
76 static int hf_scsi_osd_permissions_write        = -1;
77 static int hf_scsi_osd_permissions_get_attr     = -1;
78 static int hf_scsi_osd_permissions_set_attr     = -1;
79 static int hf_scsi_osd_permissions_create       = -1;
80 static int hf_scsi_osd_permissions_remove       = -1;
81 static int hf_scsi_osd_permissions_obj_mgmt     = -1;
82 static int hf_scsi_osd_permissions_append       = -1;
83 static int hf_scsi_osd_permissions_dev_mgmt     = -1;
84 static int hf_scsi_osd_permissions_global       = -1;
85 static int hf_scsi_osd_permissions_pol_sec      = -1;
86 static int hf_scsi_osd_object_descriptor_type   = -1;
87 static int hf_scsi_osd_object_descriptor= -1;
88 static int hf_scsi_osd_ricv             = -1;
89 static int hf_scsi_osd_request_nonce    = -1;
90 static int hf_scsi_osd_diicvo           = -1;
91 static int hf_scsi_osd_doicvo           = -1;
92 static int hf_scsi_osd_requested_partition_id   = -1;
93 static int hf_scsi_osd_sortorder        = -1;
94 static int hf_scsi_osd_partition_id     = -1;
95 static int hf_scsi_osd_list_identifier  = -1;
96 static int hf_scsi_osd_allocation_length= -1;
97 static int hf_scsi_osd_length= -1;
98 static int hf_scsi_osd_starting_byte_address    = -1;
99 static int hf_scsi_osd_initial_object_id= -1;
100 static int hf_scsi_osd_additional_length= -1;
101 static int hf_scsi_osd_continuation_object_id= -1;
102 static int hf_scsi_osd_list_flags_lstchg= -1;
103 static int hf_scsi_osd_list_flags_root= -1;
104 static int hf_scsi_osd_user_object_id= -1;
105 static int hf_scsi_osd_requested_user_object_id = -1;
106 static int hf_scsi_osd_number_of_user_objects   = -1;
107 static int hf_scsi_osd_key_to_set               = -1;
108 static int hf_scsi_osd_set_key_version          = -1;
109 static int hf_scsi_osd_key_identifier           = -1;
110 static int hf_scsi_osd_seed                     = -1;
111 static int hf_scsi_osd_collection_fcr           = -1;
112 static int hf_scsi_osd_collection_object_id     = -1;
113 static int hf_scsi_osd_requested_collection_object_id   = -1;
114 static int hf_scsi_osd_partition_created_in     = -1;
115 static int hf_scsi_osd_partition_removed_in     = -1;
116 static int hf_scsi_osd_flush_scope              = -1;
117 static int hf_scsi_osd_flush_collection_scope   = -1;
118
119 static gint ett_osd_option              = -1;
120 static gint ett_osd_partition           = -1;
121 static gint ett_osd_attribute_parameters= -1;
122 static gint ett_osd_capability          = -1;
123 static gint ett_osd_permission_bitmask  = -1;
124 static gint ett_osd_security_parameters = -1;
125
126
127
128 /* There will be one such structure create for each conversation ontop of which
129  * there is an OSD session
130  */
131 typedef struct _scsi_osd_conv_info_t {
132         emem_tree_t *luns;
133 } scsi_osd_conv_info_t;
134
135 /* there will be one such structure created for each lun for each conversation
136  * that is handled by the OSD dissector
137  */
138 typedef struct _scsi_osd_lun_info_t {
139         emem_tree_t *partitions;
140 } scsi_osd_lun_info_t;
141
142 typedef void (*scsi_osd_dissector_t)(tvbuff_t *tvb, packet_info *pinfo,
143                 proto_tree *tree, guint offset,
144                 gboolean isreq, gboolean iscdb,
145                 guint32 payload_len, scsi_task_data_t *cdata,
146                 scsi_osd_conv_info_t *conv_info,
147                 scsi_osd_lun_info_t *lun_info
148                 );
149
150 /* One such structure is created per conversation/lun/partition to
151  * keep track of when partitions are created/used/destroyed
152  */
153 typedef struct _partition_info_t {
154         int created_in;
155         int removed_in;
156 } partition_info_t;
157
158
159 /* This is a set of extra data specific to OSD that we need to attach to every
160  * task.
161  */
162 typedef struct _scsi_osd_extra_data_t {
163         guint16 svcaction;
164         guint8  gsatype;
165         union {
166                 struct {        /* gsatype: attribute list */
167                         guint32 get_list_length;
168                         guint32 get_list_offset;
169                         guint32 get_list_allocation_length;
170                         guint32 retreived_list_offset;
171                         guint32 set_list_length;
172                         guint32 set_list_offset;
173                 };
174         };
175 } scsi_osd_extra_data_t;
176
177 static const true_false_string option_dpo_tfs = {
178         "DPO is SET",
179         "Dpo is NOT set"
180 };
181 static const true_false_string option_fua_tfs = {
182         "FUA is SET",
183         "Fua is NOT set"
184 };
185
186 /* OSD2 5.2.4 */
187 static void
188 dissect_osd_option(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
189 {
190         proto_tree *tree=NULL;
191         proto_item *it=NULL;
192         guint8 option;
193
194         option=tvb_get_guint8(tvb, offset);
195
196         if(parent_tree){
197                 it=proto_tree_add_item(parent_tree, hf_scsi_osd_option, tvb, offset, 1, 0);
198                 tree = proto_item_add_subtree(it, ett_osd_option);
199         }
200
201         proto_tree_add_item(tree, hf_scsi_osd_option_dpo, tvb, offset, 1, 0);
202         if(option&0x10){
203                 proto_item_append_text(tree, " DPO");
204         }
205
206         proto_tree_add_item(tree, hf_scsi_osd_option_fua, tvb, offset, 1, 0);
207         if(option&0x08){
208                 proto_item_append_text(tree, " FUA");
209         }
210 }
211
212
213 static const value_string scsi_osd_getsetattrib_vals[] = {
214     {2,         "Get an attributes page and set an attribute value"},
215     {3,         "Get and set attributes using a list"},
216     {0, NULL},
217 };
218 /* OSD2 5.2.2.1 */
219 static void
220 dissect_osd_getsetattrib(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
221 {
222         if(cdata && cdata->itlq && cdata->itlq->extra_data){
223                 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
224                 extra_data->gsatype=(tvb_get_guint8(tvb, offset)>>4)&0x03;
225         }
226         proto_tree_add_item(tree, hf_scsi_osd_getsetattrib, tvb, offset, 1, 0);
227 }
228
229
230 static const value_string scsi_osd_timestamps_control_vals[] = {
231     {0x00,      "Timestamps shall be updated"},
232     {0x7f,      "Timestamps shall not be updated"},
233     {0, NULL},
234 };
235 /* OSD2 5.2.8 */
236 static void
237 dissect_osd_timestamps_control(tvbuff_t *tvb, int offset, proto_tree *tree)
238 {
239         proto_tree_add_item(tree, hf_scsi_osd_timestamps_control, tvb, offset, 1, 0);
240 }
241
242
243 static void
244 dissect_osd_formatted_capacity(tvbuff_t *tvb, int offset, proto_tree *tree)
245 {
246         proto_tree_add_item(tree, hf_scsi_osd_formatted_capacity, tvb, offset, 8, 0);
247 }
248
249
250 static void
251 dissect_osd_attribute_parameters(tvbuff_t *tvb, int offset, proto_tree *parent_tree, scsi_task_data_t *cdata)
252 {
253         guint8 gsatype=0;
254         proto_item *item=NULL;
255         proto_tree *tree=NULL;
256         scsi_osd_extra_data_t *extra_data=NULL;
257
258         if(parent_tree){
259                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
260                     "Attribute Parameters");
261                 tree = proto_item_add_subtree(item, ett_osd_attribute_parameters);
262         }
263                 
264         if(cdata && cdata->itlq && cdata->itlq->extra_data){
265                 extra_data=cdata->itlq->extra_data;
266                 gsatype=extra_data->gsatype;
267         } else {
268                 return;
269         }
270
271         switch(gsatype){
272         case 2: /* 5.2.2.2  attribute page */
273                 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_page, tvb, offset, 4, 0);
274                 offset+=4;
275                 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, 0);
276                 offset+=4;
277                 proto_tree_add_item(tree, hf_scsi_osd_retreived_attributes_offset, tvb, offset, 4, 0);
278                 offset+=4;
279                 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, 0);
280                 offset+=4;
281                 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, 0);
282                 offset+=4;
283                 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, 0);
284                 offset+=4;
285                 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_offset, tvb, offset, 4, 0);
286                 offset+=4;
287                 break;
288         case 3: /* 5.2.2.3  attribute list */
289                 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_list_length, tvb, offset, 4, 0);
290                 extra_data->get_list_length=tvb_get_ntohl(tvb, offset);
291                 offset+=4;
292
293                 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_list_offset, tvb, offset, 4, 0);
294                 extra_data->get_list_offset=tvb_get_ntohl(tvb, offset);
295                 offset+=4;
296
297                 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, 0);
298                 extra_data->get_list_allocation_length=tvb_get_ntohl(tvb, offset);
299                 offset+=4;
300
301                 proto_tree_add_item(tree, hf_scsi_osd_retreived_attributes_offset, tvb, offset, 4, 0);
302                 extra_data->retreived_list_offset=tvb_get_ntohl(tvb, offset);
303                 offset+=4;
304
305                 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_list_length, tvb, offset, 4, 0);
306                 extra_data->set_list_length=tvb_get_ntohl(tvb, offset);
307                 offset+=4;
308
309                 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_list_offset, tvb, offset, 4, 0);
310                 extra_data->set_list_offset=tvb_get_ntohl(tvb, offset);
311                 offset+=4;
312
313                 /* 4 reserved bytes */
314                 offset+=4;
315
316                 break;
317         }
318 }
319
320
321 static void
322 dissect_osd_attribute_data_out(tvbuff_t *tvb, int offset _U_, proto_tree *tree, scsi_task_data_t *cdata)
323 {
324         guint8 gsatype=0;
325         scsi_osd_extra_data_t *extra_data=NULL;
326
327         if(cdata && cdata->itlq && cdata->itlq->extra_data){
328                 extra_data=cdata->itlq->extra_data;
329                 gsatype=extra_data->gsatype;
330         } else {
331                 return;
332         }
333
334         switch(gsatype){
335         case 2: /* 5.2.2.2  attribute page */
336 /*qqq*/
337                 break;
338         case 3: /* 5.2.2.3  attribute list */
339                 if(extra_data->get_list_length){
340                         proto_tree_add_text(tree, tvb, extra_data->get_list_offset, extra_data->get_list_length, "Get Attributes Data");
341                 }
342                 if(extra_data->set_list_length){
343                         proto_tree_add_text(tree, tvb, extra_data->set_list_offset, extra_data->set_list_length, "Set Attributes Data");
344                 }
345                 break;
346         }
347 }
348
349
350 static void
351 dissect_osd_attribute_data_in(tvbuff_t *tvb, int offset _U_, proto_tree *tree, scsi_task_data_t *cdata)
352 {
353         guint8 gsatype=0;
354         scsi_osd_extra_data_t *extra_data=NULL;
355
356         if(cdata && cdata->itlq && cdata->itlq->extra_data){
357                 extra_data=cdata->itlq->extra_data;
358                 gsatype=extra_data->gsatype;
359         } else {
360                 return;
361         }
362
363         switch(gsatype){
364         case 2: /* 5.2.2.2  attribute page */
365 /*qqq*/
366                 break;
367         case 3: /* 5.2.2.3  attribute list */
368                 if(extra_data->get_list_allocation_length){
369                         proto_tree_add_text(tree, tvb, extra_data->retreived_list_offset, extra_data->get_list_allocation_length, "Get Attributes Data");
370                 }
371                 break;
372         }
373 }
374
375
376 static const value_string scsi_osd_capability_format_vals[] = {
377     {0x00,      "No Capability"},
378     {0x01,      "SCSI OSD Capabilities"},
379     {0, NULL},
380 };
381 static const value_string scsi_osd_object_type_vals[] = {
382     {0x01,      "ROOT"},
383     {0x02,      "PARTITION"},
384     {0x40,      "COLLECTION"},
385     {0x80,      "USER"},
386     {0, NULL},
387 };
388 static const value_string scsi_osd_object_descriptor_type_vals[] = {
389     {0, "NONE: the object descriptor field shall be ignored"},
390     {1, "U/C: a single collection or user object"},
391     {2, "PAR: a single partition, including partition zero"},
392     {0, NULL},
393 };
394
395 static const true_false_string permissions_read_tfs = {
396         "READ is SET",
397         "Read is NOT set"
398 };
399 static const true_false_string permissions_write_tfs = {
400         "WRITE is SET",
401         "Write is NOT set"
402 };
403 static const true_false_string permissions_get_attr_tfs = {
404         "GET_ATTR is SET",
405         "Get_attr is NOT set"
406 };
407 static const true_false_string permissions_set_attr_tfs = {
408         "SET_ATTR is SET",
409         "Set_attr is NOT set"
410 };
411 static const true_false_string permissions_create_tfs = {
412         "CREATE is SET",
413         "Create is NOT set"
414 };
415 static const true_false_string permissions_remove_tfs = {
416         "REMOVE is SET",
417         "Remove is NOT set"
418 };
419 static const true_false_string permissions_obj_mgmt_tfs = {
420         "OBJ_MGMT is SET",
421         "Obj_mgmt is NOT set"
422 };
423 static const true_false_string permissions_append_tfs = {
424         "APPEND is SET",
425         "Append is NOT set"
426 };
427 static const true_false_string permissions_dev_mgmt_tfs = {
428         "DEV_MGMT is SET",
429         "Dev_mgmt is NOT set"
430 };
431 static const true_false_string permissions_global_tfs = {
432         "GLOBAL is SET",
433         "Global is NOT set"
434 };
435 static const true_false_string permissions_pol_sec_tfs = {
436         "POL/SEC is SET",
437         "Pol/sec is NOT set"
438 };
439 /* OSD 4.9.2.2.1 */
440 static void
441 dissect_osd_permissions(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
442 {
443         proto_tree *tree=NULL;
444         proto_item *it=NULL;
445         guint16 permissions;
446
447         permissions=tvb_get_ntohs(tvb, offset); 
448
449         if(parent_tree){
450                 it=proto_tree_add_item(parent_tree, hf_scsi_osd_permissions, tvb, offset, 2, 0);
451                 tree = proto_item_add_subtree(it, ett_osd_permission_bitmask);
452         }
453
454         proto_tree_add_item(tree, hf_scsi_osd_permissions_read, tvb, offset, 2, 0);
455         if(permissions&0x8000){
456                 proto_item_append_text(tree, " READ");
457         }
458         proto_tree_add_item(tree, hf_scsi_osd_permissions_write, tvb, offset, 2, 0);
459         if(permissions&0x4000){
460                 proto_item_append_text(tree, " WRITE");
461         }
462         proto_tree_add_item(tree, hf_scsi_osd_permissions_get_attr, tvb, offset, 2, 0);
463         if(permissions&0x2000){
464                 proto_item_append_text(tree, " GET_ATTR");
465         }
466         proto_tree_add_item(tree, hf_scsi_osd_permissions_set_attr, tvb, offset, 2, 0);
467         if(permissions&0x1000){
468                 proto_item_append_text(tree, " SET_ATTR");
469         }
470         proto_tree_add_item(tree, hf_scsi_osd_permissions_create, tvb, offset, 2, 0);
471         if(permissions&0x0800){
472                 proto_item_append_text(tree, " CREATE");
473         }
474         proto_tree_add_item(tree, hf_scsi_osd_permissions_remove, tvb, offset, 2, 0);
475         if(permissions&0x0400){
476                 proto_item_append_text(tree, " REMOVE");
477         }
478         proto_tree_add_item(tree, hf_scsi_osd_permissions_obj_mgmt, tvb, offset, 2, 0);
479         if(permissions&0x0200){
480                 proto_item_append_text(tree, " OBJ_MGMT");
481         }
482         proto_tree_add_item(tree, hf_scsi_osd_permissions_append, tvb, offset, 2, 0);
483         if(permissions&0x0100){
484                 proto_item_append_text(tree, " APPEND");
485         }
486         proto_tree_add_item(tree, hf_scsi_osd_permissions_dev_mgmt, tvb, offset, 2, 0);
487         if(permissions&0x0080){
488                 proto_item_append_text(tree, " DEV_MGMT");
489         }
490         proto_tree_add_item(tree, hf_scsi_osd_permissions_global, tvb, offset, 2, 0);
491         if(permissions&0x0040){
492                 proto_item_append_text(tree, " GLOBAL");
493         }
494         proto_tree_add_item(tree, hf_scsi_osd_permissions_pol_sec, tvb, offset, 2, 0);
495         if(permissions&0x0020){
496                 proto_item_append_text(tree, " POL/SEC");
497         }
498 }
499
500 /* 4.9.2.2 */
501 static void
502 dissect_osd_capability(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
503 {
504         proto_item *item=NULL;
505         proto_tree *tree=NULL;
506
507         if(parent_tree){
508                 item = proto_tree_add_text(parent_tree, tvb, offset, 80,
509                     "Capability");
510                 tree = proto_item_add_subtree(item, ett_osd_capability);
511         }
512                 
513         /* capability format */
514         proto_tree_add_item(tree, hf_scsi_osd_capability_format, tvb, offset, 1, 0);
515         offset++;
516
517         /* key version and icva */
518         proto_tree_add_item(tree, hf_scsi_osd_key_version, tvb, offset, 1, 0);
519         proto_tree_add_item(tree, hf_scsi_osd_icva, tvb, offset, 1, 0);
520         offset++;
521
522         /* security method */
523         proto_tree_add_item(tree, hf_scsi_osd_security_method, tvb, offset, 1, 0);
524         offset++;
525
526         /* a reserved byte */
527         offset++;
528
529         /* capability expiration time */
530         proto_tree_add_item(tree, hf_scsi_osd_capability_expiration_time, tvb, offset, 6, 0);
531         offset+=6;
532
533         /* audit */
534         proto_tree_add_item(tree, hf_scsi_osd_audit, tvb, offset, 20, 0);
535         offset+=20;
536
537         /* capability discriminator */
538         proto_tree_add_item(tree, hf_scsi_osd_capability_discriminator, tvb, offset, 12, 0);
539         offset+=12;
540
541         /* object created time */
542         proto_tree_add_item(tree, hf_scsi_osd_object_created_time, tvb, offset, 6, 0);
543         offset+=6;
544
545         /* object type */
546         proto_tree_add_item(tree, hf_scsi_osd_object_type, tvb, offset, 1, 0);
547         offset++;
548
549         /* permission bitmask */
550         dissect_osd_permissions(tvb, offset, tree);
551         offset+=5;
552
553         /* a reserved byte */
554         offset++;
555
556         /* object descriptor type */
557         proto_tree_add_item(tree, hf_scsi_osd_object_descriptor_type, tvb, offset, 1, 0);
558         offset++;
559
560         /* object descriptor */
561         proto_tree_add_item(tree, hf_scsi_osd_object_descriptor, tvb, offset, 24, 0);
562         offset+=24;
563 }
564
565
566
567 /* 5.2.6 */
568 static void
569 dissect_osd_security_parameters(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
570 {
571         proto_item *item=NULL;
572         proto_tree *tree=NULL;
573
574         if(parent_tree){
575                 item = proto_tree_add_text(parent_tree, tvb, offset, 40,
576                     "Security Parameters");
577                 tree = proto_item_add_subtree(item, ett_osd_security_parameters);
578         }
579                 
580         /* request integrity check value */
581         proto_tree_add_item(tree, hf_scsi_osd_ricv, tvb, offset, 20, 0);
582         offset+=20;
583
584         /* request nonce */
585         proto_tree_add_item(tree, hf_scsi_osd_request_nonce, tvb, offset, 12, 0);
586         offset+=12;
587
588         /* data in integrity check value offset */
589         proto_tree_add_item(tree, hf_scsi_osd_diicvo, tvb, offset, 4, 0);
590         offset+=4;
591
592         /* data out integrity check value offset */
593         proto_tree_add_item(tree, hf_scsi_osd_doicvo, tvb, offset, 4, 0);
594         offset+=4;
595 }
596
597 static void
598 dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
599                         guint offset, gboolean isreq, gboolean iscdb,
600                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
601                         scsi_osd_conv_info_t *conv_info _U_,
602                         scsi_osd_lun_info_t *lun_info _U_)
603 {
604         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
605         if(isreq && iscdb){
606                 /* options byte */
607                 dissect_osd_option(tvb, offset, tree);
608                 offset++;
609
610                 /* getset attributes byte */
611                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
612                 offset++;
613
614                 /* timestamps control */
615                 dissect_osd_timestamps_control(tvb, offset, tree);
616                 offset++;
617
618                 /* 23 reserved bytes */
619                 offset+=23;
620
621                 /* formatted capacity */
622                 dissect_osd_formatted_capacity(tvb, offset, tree);
623                 offset+=8;
624
625                 /* 8 reserved bytes */
626                 offset+=8;
627
628                 /* attribute parameters */
629                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
630                 offset+=28;
631
632                 /* capability */
633                 dissect_osd_capability(tvb, offset, tree);
634                 offset+=80;
635
636                 /* security parameters */
637                 dissect_osd_security_parameters(tvb, offset, tree);
638                 offset+=40;
639         }
640
641         /* dissecting the DATA OUT */
642         if(isreq && !iscdb){
643                 /* attribute data out */
644                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
645
646                 /* no data out for format osd */
647         }
648
649         /* dissecting the DATA IN */
650         if(!isreq && !iscdb){
651                 /* attribute data in */
652                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
653
654                 /* no data in for format osd */
655         }
656         
657 }
658
659
660 static void
661 dissect_osd_partition_id(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index, scsi_osd_lun_info_t *lun_info, gboolean is_created, gboolean is_removed)
662 {
663         proto_item *item=NULL;
664         guint64 partition_id;
665
666         /* partition id */
667         item=proto_tree_add_item(tree, hf_index, tvb, offset, 8, 0);
668         partition_id=tvb_get_ntoh64(tvb, offset);
669         if(!partition_id){
670                 proto_item_append_text(item, " (ROOT partition)");
671         } else {
672                 partition_info_t *part_info;
673                 emem_tree_key_t pikey[2];
674                 proto_tree *partition_tree=NULL;
675
676                 pikey[0].length=2;
677                 pikey[0].key=(guint32 *)&partition_id;
678                 pikey[1].length=0;
679                 part_info=se_tree_lookup32_array(lun_info->partitions, &pikey[0]);
680                 if(!part_info){
681                         part_info=se_alloc(sizeof(partition_info_t));
682                         part_info->created_in=0;
683                         part_info->removed_in=0;
684
685                         pikey[0].length=2;
686                         pikey[0].key=(guint32 *)&partition_id;
687                         pikey[1].length=0;
688                         se_tree_insert32_array(lun_info->partitions, &pikey[0], part_info);
689                 }
690                 if(is_created){
691                         part_info->created_in=pinfo->fd->num;
692                 }
693                 if(is_removed){
694                         part_info->removed_in=pinfo->fd->num;
695                 }
696                 if(item){
697                         partition_tree=proto_item_add_subtree(item, ett_osd_partition);
698                 }
699                 if(part_info->created_in){
700                         proto_item *tmp_item;
701                         tmp_item=proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_created_in, tvb, 0, 0, part_info->created_in);
702                         PROTO_ITEM_SET_GENERATED(tmp_item);
703                 }
704                 if(part_info->removed_in){
705                         proto_item *tmp_item;
706                         tmp_item=proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_removed_in, tvb, 0, 0, part_info->removed_in);
707                         PROTO_ITEM_SET_GENERATED(tmp_item);
708                 }
709         }
710         offset+=8;
711 }
712
713
714
715 static void
716 dissect_osd_create_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
717                         guint offset, gboolean isreq, gboolean iscdb,
718                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
719                         scsi_osd_conv_info_t *conv_info _U_,
720                         scsi_osd_lun_info_t *lun_info)
721 {
722         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
723         if(isreq && iscdb){
724                 /* options byte */
725                 dissect_osd_option(tvb, offset, tree);
726                 offset++;
727
728                 /* getset attributes byte */
729                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
730                 offset++;
731
732                 /* timestamps control */
733                 dissect_osd_timestamps_control(tvb, offset, tree);
734                 offset++;
735
736                 /* 3 reserved bytes */
737                 offset+=3;
738
739                 /* requested partiton id */
740                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_requested_partition_id, lun_info, TRUE, FALSE);
741                 offset+=8;
742
743                 /* 28 reserved bytes */
744                 offset+=28;
745
746                 /* attribute parameters */
747                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
748                 offset+=28;
749
750                 /* capability */
751                 dissect_osd_capability(tvb, offset, tree);
752                 offset+=80;
753
754                 /* security parameters */
755                 dissect_osd_security_parameters(tvb, offset, tree);
756                 offset+=40;
757         }
758
759         /* dissecting the DATA OUT */
760         if(isreq && !iscdb){
761                 /* attribute data out */
762                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
763
764                 /* no data out for create partition */
765         }
766
767         /* dissecting the DATA IN */
768         if(!isreq && !iscdb){
769                 /* attribute data in */
770                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
771
772                 /* no data in for create partition */
773         }
774         
775 }
776
777 static const value_string scsi_osd_sort_order_vals[] = {
778     {0x00,      "Ascending numeric value"},
779     {0, NULL},
780 };
781 static void
782 dissect_osd_sortorder(tvbuff_t *tvb, int offset, proto_tree *tree)
783 {
784         /* sort order */
785         proto_tree_add_item(tree, hf_scsi_osd_sortorder, tvb, offset, 1, 0);
786         offset++;
787 }
788
789 static void
790 dissect_osd_list_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
791 {
792         /* list identifier */
793         proto_tree_add_item(tree, hf_scsi_osd_list_identifier, tvb, offset, 4, 0);
794         offset+=4;
795 }
796
797 static void
798 dissect_osd_allocation_length(tvbuff_t *tvb, int offset, proto_tree *tree)
799 {
800         /* allocation length */
801         proto_tree_add_item(tree, hf_scsi_osd_allocation_length, tvb, offset, 8, 0);
802         offset+=8;
803 }
804
805 static void
806 dissect_osd_initial_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
807 {
808         /* initial object id */
809         proto_tree_add_item(tree, hf_scsi_osd_initial_object_id, tvb, offset, 8, 0);
810         offset+=8;
811 }
812
813 static void
814 dissect_osd_additional_length(tvbuff_t *tvb, int offset, proto_tree *tree)
815 {
816         /* additional length */
817         proto_tree_add_item(tree, hf_scsi_osd_additional_length, tvb, offset, 8, 0);
818         offset+=8;
819 }
820
821
822 static void
823 dissect_osd_continuation_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
824 {
825         /* continuation object id */
826         proto_tree_add_item(tree, hf_scsi_osd_continuation_object_id, tvb, offset, 8, 0);
827         offset+=8;
828 }
829
830 static const true_false_string list_lstchg_tfs = {
831         "List has CHANGED since the first List command",
832         "List has NOT changed since first command"
833 };
834 static const true_false_string list_root_tfs = {
835         "Objects are from root and are PARTITION IDs",
836         "Objects are from a partition and are USER OBJECTs"
837 };
838
839 static void
840 dissect_osd_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
841 {
842         /* user object id */
843         proto_tree_add_item(tree, hf_scsi_osd_user_object_id, tvb, offset, 8, 0);
844         offset+=8;
845 }
846
847 static void
848 dissect_osd_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
849                         guint offset, gboolean isreq, gboolean iscdb,
850                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
851                         scsi_osd_conv_info_t *conv_info _U_,
852                         scsi_osd_lun_info_t *lun_info)
853 {
854         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
855         if(isreq && iscdb){
856                 /* options byte */
857                 dissect_osd_option(tvb, offset, tree);
858                 offset++;
859
860                 /* getset attributes byte / sort order */
861                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
862                 dissect_osd_sortorder(tvb, offset, tree);
863                 offset++;
864
865                 /* timestamps control */
866                 dissect_osd_timestamps_control(tvb, offset, tree);
867                 offset++;
868
869                 /* 3 reserved bytes */
870                 offset+=3;
871
872                 /* partiton id */
873                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
874                 offset+=8;
875
876                 /* 8 reserved bytes */
877                 offset+=8;
878
879                 /* list identifier */
880                 dissect_osd_list_identifier(tvb, offset, tree);
881                 offset+=4;
882
883                 /* allocation length */
884                 dissect_osd_allocation_length(tvb, offset, tree);
885                 offset+=8;
886
887                 /* initial object id */
888                 dissect_osd_initial_object_id(tvb, offset, tree);
889                 offset+=8;
890
891                 /* attribute parameters */
892                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
893                 offset+=28;
894
895                 /* capability */
896                 dissect_osd_capability(tvb, offset, tree);
897                 offset+=80;
898
899                 /* security parameters */
900                 dissect_osd_security_parameters(tvb, offset, tree);
901                 offset+=40;
902         }
903
904         /* dissecting the DATA OUT */
905         if(isreq && !iscdb){
906                 /* attribute data out */
907                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
908
909                 /* no data out for LIST */
910         }
911
912         /* dissecting the DATA IN */
913         if(!isreq && !iscdb){
914                 guint64 additional_length;
915                 gboolean is_root;
916
917                 /* attribute data in */
918                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
919
920                 /* dissection of the LIST DATA-IN */
921                 /* additional length */
922                 additional_length=tvb_get_ntoh64(tvb, offset);
923                 dissect_osd_additional_length(tvb, offset, tree);
924                 offset+=8;
925
926                 /* continuation object id */
927                 dissect_osd_continuation_object_id(tvb, offset, tree);
928                 offset+=8;
929
930                 /* list identifier */
931                 dissect_osd_list_identifier(tvb, offset, tree);
932                 offset+=4;
933
934                 /* 3 reserved bytes */
935                 offset+=3;
936
937                 /* LSTCHG and ROOT flags */
938                 proto_tree_add_item(tree, hf_scsi_osd_list_flags_lstchg, tvb, offset, 1, 0);
939                 proto_tree_add_item(tree, hf_scsi_osd_list_flags_root, tvb, offset, 1, 0);
940                 is_root=tvb_get_guint8(tvb, offset)&0x01;
941                 offset++;
942
943
944                 /* list of user object ids or partition ids */
945                 while(additional_length > (offset-8)){
946                         if(is_root){
947                                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
948                         } else {
949                                 dissect_osd_user_object_id(tvb, offset, tree);
950                         }
951                         offset+=8;
952                 }
953         }
954         
955 }
956
957 static void
958 dissect_osd_requested_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
959 {
960         /* request user object id */
961         proto_tree_add_item(tree, hf_scsi_osd_requested_user_object_id, tvb, offset, 8, 0);
962         offset+=8;
963 }
964
965 static void
966 dissect_osd_number_of_user_objects(tvbuff_t *tvb, int offset, proto_tree *tree)
967 {
968         /* number_of_user_objects */
969         proto_tree_add_item(tree, hf_scsi_osd_number_of_user_objects, tvb, offset, 2, 0);
970         offset+=2;
971 }
972
973 static void
974 dissect_osd_create(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
975                         guint offset, gboolean isreq, gboolean iscdb,
976                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
977                         scsi_osd_conv_info_t *conv_info _U_,
978                         scsi_osd_lun_info_t *lun_info)
979 {
980         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
981         if(isreq && iscdb){
982                 /* options byte */
983                 dissect_osd_option(tvb, offset, tree);
984                 offset++;
985
986                 /* getset attributes byte */
987                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
988                 offset++;
989
990                 /* timestamps control */
991                 dissect_osd_timestamps_control(tvb, offset, tree);
992                 offset++;
993
994                 /* 3 reserved bytes */
995                 offset+=3;
996
997                 /* partiton id */
998                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
999                 offset+=8;
1000
1001                 /* requested user_object id */
1002                 dissect_osd_requested_user_object_id(tvb, offset, tree);
1003                 offset+=8;
1004
1005                 /* 4 reserved bytes */
1006                 offset+=4;
1007
1008                 /* number of user objects */
1009                 dissect_osd_number_of_user_objects(tvb, offset, tree);
1010                 offset+=2;
1011
1012                 /* 14 reserved bytes */
1013                 offset+=14;
1014
1015                 /* attribute parameters */
1016                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1017                 offset+=28;
1018
1019                 /* capability */
1020                 dissect_osd_capability(tvb, offset, tree);
1021                 offset+=80;
1022
1023                 /* security parameters */
1024                 dissect_osd_security_parameters(tvb, offset, tree);
1025                 offset+=40;
1026         }
1027
1028         /* dissecting the DATA OUT */
1029         if(isreq && !iscdb){
1030                 /* attribute data out */
1031                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1032
1033                 /* no data out for create */
1034         }
1035
1036         /* dissecting the DATA IN */
1037         if(!isreq && !iscdb){
1038                 /* attribute data in */
1039                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1040
1041                 /* no data in for create */
1042         }
1043         
1044 }
1045
1046
1047 static void
1048 dissect_osd_remove_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1049                         guint offset, gboolean isreq, gboolean iscdb,
1050                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1051                         scsi_osd_conv_info_t *conv_info _U_,
1052                         scsi_osd_lun_info_t *lun_info)
1053 {
1054         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1055         if(isreq && iscdb){
1056                 /* options byte */
1057                 dissect_osd_option(tvb, offset, tree);
1058                 offset++;
1059
1060                 /* getset attributes byte */
1061                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1062                 offset++;
1063
1064                 /* timestamps control */
1065                 dissect_osd_timestamps_control(tvb, offset, tree);
1066                 offset++;
1067
1068                 /* 3 reserved bytes */
1069                 offset+=3;
1070
1071                 /* partiton id */
1072                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, TRUE);
1073                 offset+=8;
1074
1075                 /* 28 reserved bytes */
1076                 offset+=28;
1077
1078                 /* attribute parameters */
1079                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1080                 offset+=28;
1081
1082                 /* capability */
1083                 dissect_osd_capability(tvb, offset, tree);
1084                 offset+=80;
1085
1086                 /* security parameters */
1087                 dissect_osd_security_parameters(tvb, offset, tree);
1088                 offset+=40;
1089         }
1090
1091         /* dissecting the DATA OUT */
1092         if(isreq && !iscdb){
1093                 /* attribute data out */
1094                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1095
1096                 /* no data out for remove partition */
1097         }
1098
1099         /* dissecting the DATA IN */
1100         if(!isreq && !iscdb){
1101                 /* attribute data in */
1102                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1103
1104                 /* no data in for remove partition */
1105         }
1106         
1107 }
1108
1109 static const value_string key_to_set_vals[] = {
1110     {1, "Root"},
1111     {2, "Partition"},
1112     {3, "Working"},
1113     {0, NULL},
1114 };
1115 static void
1116 dissect_osd_key_to_set(tvbuff_t *tvb, int offset, proto_tree *tree)
1117 {
1118         proto_tree_add_item(tree, hf_scsi_osd_key_to_set, tvb, offset, 1, 0);
1119 }
1120
1121 static void
1122 dissect_osd_set_key_version(tvbuff_t *tvb, int offset, proto_tree *tree)
1123 {
1124         proto_tree_add_item(tree, hf_scsi_osd_set_key_version, tvb, offset, 1, 0);
1125 }
1126
1127 static void
1128 dissect_osd_key_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
1129 {
1130         proto_tree_add_item(tree, hf_scsi_osd_key_identifier, tvb, offset, 7, 0);
1131 }
1132
1133 static void
1134 dissect_osd_seed(tvbuff_t *tvb, int offset, proto_tree *tree)
1135 {
1136         proto_tree_add_item(tree, hf_scsi_osd_seed, tvb, offset, 20, 0);
1137 }
1138
1139 static void
1140 dissect_osd_set_key(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1141                         guint offset, gboolean isreq, gboolean iscdb,
1142                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1143                         scsi_osd_conv_info_t *conv_info _U_,
1144                         scsi_osd_lun_info_t *lun_info)
1145 {
1146         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1147         if(isreq && iscdb){
1148                 /* a reserved byte */
1149                 offset++;
1150
1151                 /* getset attributes byte and key to set*/
1152                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1153                 dissect_osd_key_to_set(tvb, offset, tree);
1154                 offset++;
1155
1156                 /* timestamps control */
1157                 dissect_osd_timestamps_control(tvb, offset, tree);
1158                 offset++;
1159
1160                 /* 3 reserved bytes */
1161                 offset+=3;
1162
1163                 /* partiton id */
1164                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1165                 offset+=8;
1166
1167                 /* key version */
1168                 dissect_osd_set_key_version(tvb, offset, tree);
1169                 offset++;
1170
1171                 /* key identifier */
1172                 dissect_osd_key_identifier(tvb, offset, tree);
1173                 offset+=7;
1174
1175                 /* seed */
1176                 dissect_osd_seed(tvb, offset, tree);
1177                 offset+=20;
1178
1179                 /* attribute parameters */
1180                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1181                 offset+=28;
1182
1183                 /* capability */
1184                 dissect_osd_capability(tvb, offset, tree);
1185                 offset+=80;
1186
1187                 /* security parameters */
1188                 dissect_osd_security_parameters(tvb, offset, tree);
1189                 offset+=40;
1190         }
1191
1192         /* dissecting the DATA OUT */
1193         if(isreq && !iscdb){
1194                 /* attribute data out */
1195                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1196
1197                 /* no data out for set key */
1198         }
1199
1200         /* dissecting the DATA IN */
1201         if(!isreq && !iscdb){
1202                 /* attribute data in */
1203                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1204
1205                 /* no data in for set key */
1206         }
1207         
1208 }
1209
1210 static void
1211 dissect_osd_remove(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1212                         guint offset, gboolean isreq, gboolean iscdb,
1213                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1214                         scsi_osd_conv_info_t *conv_info _U_,
1215                         scsi_osd_lun_info_t *lun_info)
1216 {
1217         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1218         if(isreq && iscdb){
1219                 /* options byte */
1220                 dissect_osd_option(tvb, offset, tree);
1221                 offset++;
1222
1223                 /* getset attributes byte */
1224                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1225                 offset++;
1226
1227                 /* timestamps control */
1228                 dissect_osd_timestamps_control(tvb, offset, tree);
1229                 offset++;
1230
1231                 /* 3 reserved bytes */
1232                 offset+=3;
1233
1234                 /* partiton id */
1235                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1236                 offset+=8;
1237
1238                 /* user object id */
1239                 dissect_osd_user_object_id(tvb, offset, tree);
1240                 offset+=8;
1241
1242                 /* 20 reserved bytes */
1243                 offset+=20;
1244
1245                 /* attribute parameters */
1246                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1247                 offset+=28;
1248
1249                 /* capability */
1250                 dissect_osd_capability(tvb, offset, tree);
1251                 offset+=80;
1252
1253                 /* security parameters */
1254                 dissect_osd_security_parameters(tvb, offset, tree);
1255                 offset+=40;
1256         }
1257
1258         /* dissecting the DATA OUT */
1259         if(isreq && !iscdb){
1260                 /* attribute data out */
1261                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1262
1263                 /* no data out for remove */
1264         }
1265
1266         /* dissecting the DATA IN */
1267         if(!isreq && !iscdb){
1268                 /* attribute data in */
1269                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1270
1271                 /* no data in for remove */
1272         }
1273         
1274 }
1275
1276 static const true_false_string collection_fcr_tfs = {
1277         "FCR is SET",
1278         "Fcr is NOR set"
1279 };
1280 static void
1281 dissect_osd_collection_fcr(tvbuff_t *tvb, int offset, proto_tree *tree)
1282 {
1283         proto_tree_add_item(tree, hf_scsi_osd_collection_fcr, tvb, offset, 1, 0);
1284 }
1285
1286 static void
1287 dissect_osd_collection_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1288 {
1289         /* collection object id */
1290         proto_tree_add_item(tree, hf_scsi_osd_collection_object_id, tvb, offset, 8, 0);
1291         offset+=8;
1292 }
1293
1294
1295 static void
1296 dissect_osd_remove_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1297                         guint offset, gboolean isreq, gboolean iscdb,
1298                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1299                         scsi_osd_conv_info_t *conv_info _U_,
1300                         scsi_osd_lun_info_t *lun_info)
1301 {
1302         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1303         if(isreq && iscdb){
1304                 /* options byte */
1305                 dissect_osd_option(tvb, offset, tree);
1306                 offset++;
1307
1308                 /* getset attributes byte */
1309                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1310                 dissect_osd_collection_fcr(tvb, offset, tree);
1311                 offset++;
1312
1313                 /* timestamps control */
1314                 dissect_osd_timestamps_control(tvb, offset, tree);
1315                 offset++;
1316
1317                 /* 3 reserved bytes */
1318                 offset+=3;
1319
1320                 /* partiton id */
1321                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1322                 offset+=8;
1323
1324                 /* collection object id */
1325                 dissect_osd_collection_object_id(tvb, offset, tree);
1326                 offset+=8;
1327
1328                 /* 20 reserved bytes */
1329                 offset+=20;
1330
1331                 /* attribute parameters */
1332                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1333                 offset+=28;
1334
1335                 /* capability */
1336                 dissect_osd_capability(tvb, offset, tree);
1337                 offset+=80;
1338
1339                 /* security parameters */
1340                 dissect_osd_security_parameters(tvb, offset, tree);
1341                 offset+=40;
1342         }
1343
1344         /* dissecting the DATA OUT */
1345         if(isreq && !iscdb){
1346                 /* attribute data out */
1347                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1348
1349                 /* no data out for remove collection */
1350         }
1351
1352         /* dissecting the DATA IN */
1353         if(!isreq && !iscdb){
1354                 /* attribute data in */
1355                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1356
1357                 /* no data in for remove collection */
1358         }
1359         
1360 }
1361
1362
1363 static void
1364 dissect_osd_length(tvbuff_t *tvb, int offset, proto_tree *tree)
1365 {
1366         /* length */
1367         proto_tree_add_item(tree, hf_scsi_osd_length, tvb, offset, 8, 0);
1368         offset+=8;
1369 }
1370
1371 static void
1372 dissect_osd_starting_byte_address(tvbuff_t *tvb, int offset, proto_tree *tree)
1373 {
1374         /* starting_byte_address */
1375         proto_tree_add_item(tree, hf_scsi_osd_starting_byte_address, tvb, offset, 8, 0);
1376         offset+=8;
1377 }
1378
1379
1380 static void
1381 dissect_osd_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1382                         guint offset, gboolean isreq, gboolean iscdb,
1383                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1384                         scsi_osd_conv_info_t *conv_info _U_,
1385                         scsi_osd_lun_info_t *lun_info)
1386 {
1387         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1388         if(isreq && iscdb){
1389                 /* options byte */
1390                 dissect_osd_option(tvb, offset, tree);
1391                 offset++;
1392
1393                 /* getset attributes byte / sort order */
1394                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1395                 dissect_osd_sortorder(tvb, offset, tree);
1396                 offset++;
1397
1398                 /* timestamps control */
1399                 dissect_osd_timestamps_control(tvb, offset, tree);
1400                 offset++;
1401
1402                 /* 3 reserved bytes */
1403                 offset+=3;
1404
1405                 /* partiton id */
1406                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1407                 offset+=8;
1408
1409                 /* user object id */
1410                 dissect_osd_user_object_id(tvb, offset, tree);
1411                 offset+=8;
1412
1413                 /* 4 reserved bytes */
1414                 offset+=4;
1415
1416                 /* length */
1417                 dissect_osd_length(tvb, offset, tree);
1418                 offset+=8;
1419
1420                 /* starting byte address */
1421                 dissect_osd_starting_byte_address(tvb, offset, tree);
1422                 offset+=8;
1423
1424                 /* attribute parameters */
1425                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1426                 offset+=28;
1427
1428                 /* capability */
1429                 dissect_osd_capability(tvb, offset, tree);
1430                 offset+=80;
1431
1432                 /* security parameters */
1433                 dissect_osd_security_parameters(tvb, offset, tree);
1434                 offset+=40;
1435         }
1436
1437         /* dissecting the DATA OUT */
1438         if(isreq && !iscdb){
1439                 /* attribute data out */
1440                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1441
1442                 /* xxx should dissect the data ? */
1443         }
1444
1445         /* dissecting the DATA IN */
1446         if(!isreq && !iscdb){
1447                 /* attribute data in */
1448                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1449
1450                 /* no data in for WRITE */
1451         }
1452         
1453 }
1454
1455
1456 static void
1457 dissect_osd_requested_collection_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1458 {
1459         /* requested collection object id */
1460         proto_tree_add_item(tree, hf_scsi_osd_requested_collection_object_id, tvb, offset, 8, 0);
1461         offset+=8;
1462 }
1463
1464
1465 static void
1466 dissect_osd_create_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1467                         guint offset, gboolean isreq, gboolean iscdb,
1468                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1469                         scsi_osd_conv_info_t *conv_info _U_,
1470                         scsi_osd_lun_info_t *lun_info)
1471 {
1472         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1473         if(isreq && iscdb){
1474                 /* options byte */
1475                 dissect_osd_option(tvb, offset, tree);
1476                 offset++;
1477
1478                 /* getset attributes byte */
1479                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1480                 dissect_osd_collection_fcr(tvb, offset, tree);
1481                 offset++;
1482
1483                 /* timestamps control */
1484                 dissect_osd_timestamps_control(tvb, offset, tree);
1485                 offset++;
1486
1487                 /* 3 reserved bytes */
1488                 offset+=3;
1489
1490                 /* partiton id */
1491                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1492                 offset+=8;
1493
1494                 /* requested collection object id */
1495                 dissect_osd_requested_collection_object_id(tvb, offset, tree);
1496                 offset+=8;
1497
1498                 /* 20 reserved bytes */
1499                 offset+=20;
1500
1501                 /* attribute parameters */
1502                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1503                 offset+=28;
1504
1505                 /* capability */
1506                 dissect_osd_capability(tvb, offset, tree);
1507                 offset+=80;
1508
1509                 /* security parameters */
1510                 dissect_osd_security_parameters(tvb, offset, tree);
1511                 offset+=40;
1512         }
1513
1514         /* dissecting the DATA OUT */
1515         if(isreq && !iscdb){
1516                 /* attribute data out */
1517                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1518
1519                 /* no data out for create collection */
1520         }
1521
1522         /* dissecting the DATA IN */
1523         if(!isreq && !iscdb){
1524                 /* attribute data in */
1525                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1526
1527                 /* no data in for create collection */
1528         }
1529         
1530 }
1531
1532
1533 static const value_string flush_scope_vals[] = {
1534         {0,     "User object data and attributes"},
1535         {1,     "User object attributes only"},
1536         {0, NULL}
1537 };
1538
1539 static void
1540 dissect_osd_flush_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
1541 {
1542         /* flush scope */
1543         proto_tree_add_item(tree, hf_scsi_osd_flush_scope, tvb, offset, 1, 0);
1544         offset++;
1545 }
1546
1547 static void
1548 dissect_osd_flush(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1549                         guint offset, gboolean isreq, gboolean iscdb,
1550                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1551                         scsi_osd_conv_info_t *conv_info _U_,
1552                         scsi_osd_lun_info_t *lun_info)
1553 {
1554         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1555         if(isreq && iscdb){
1556                 /* options byte */
1557                 dissect_osd_flush_scope(tvb, offset, tree);
1558                 offset++;
1559
1560                 /* getset attributes byte */
1561                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1562                 dissect_osd_collection_fcr(tvb, offset, tree);
1563                 offset++;
1564
1565                 /* timestamps control */
1566                 dissect_osd_timestamps_control(tvb, offset, tree);
1567                 offset++;
1568
1569                 /* 3 reserved bytes */
1570                 offset+=3;
1571
1572                 /* partiton id */
1573                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1574                 offset+=8;
1575
1576                 /* user object id */
1577                 dissect_osd_user_object_id(tvb, offset, tree);
1578                 offset+=8;
1579
1580                 /* 20 reserved bytes */
1581                 offset+=20;
1582
1583                 /* attribute parameters */
1584                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1585                 offset+=28;
1586
1587                 /* capability */
1588                 dissect_osd_capability(tvb, offset, tree);
1589                 offset+=80;
1590
1591                 /* security parameters */
1592                 dissect_osd_security_parameters(tvb, offset, tree);
1593                 offset+=40;
1594         }
1595
1596         /* dissecting the DATA OUT */
1597         if(isreq && !iscdb){
1598                 /* attribute data out */
1599                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1600
1601                 /* no data out for flush */
1602         }
1603
1604         /* dissecting the DATA IN */
1605         if(!isreq && !iscdb){
1606                 /* attribute data in */
1607                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1608
1609                 /* no data in for flush */
1610         }
1611         
1612 }
1613
1614
1615 static const value_string flush_collection_scope_vals[] = {
1616         {0,     "List of user objects contained in the collection"},
1617         {1,     "Collection attributes only"},
1618         {2,     "List of user objects and collection attributes"},
1619         {0, NULL}
1620 };
1621
1622 static void
1623 dissect_osd_flush_collection_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
1624 {
1625         /* flush collection scope */
1626         proto_tree_add_item(tree, hf_scsi_osd_flush_collection_scope, tvb, offset, 1, 0);
1627         offset++;
1628 }
1629
1630 static void
1631 dissect_osd_flush_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1632                         guint offset, gboolean isreq, gboolean iscdb,
1633                         guint payload_len _U_, scsi_task_data_t *cdata _U_,
1634                         scsi_osd_conv_info_t *conv_info _U_,
1635                         scsi_osd_lun_info_t *lun_info)
1636 {
1637         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
1638         if(isreq && iscdb){
1639                 /* options byte */
1640                 dissect_osd_flush_collection_scope(tvb, offset, tree);
1641                 offset++;
1642
1643                 /* getset attributes byte */
1644                 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1645                 dissect_osd_collection_fcr(tvb, offset, tree);
1646                 offset++;
1647
1648                 /* timestamps control */
1649                 dissect_osd_timestamps_control(tvb, offset, tree);
1650                 offset++;
1651
1652                 /* 3 reserved bytes */
1653                 offset+=3;
1654
1655                 /* partiton id */
1656                 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1657                 offset+=8;
1658
1659                 /* collection object id */
1660                 dissect_osd_collection_object_id(tvb, offset, tree);
1661                 offset+=8;
1662
1663                 /* 20 reserved bytes */
1664                 offset+=20;
1665
1666                 /* attribute parameters */
1667                 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
1668                 offset+=28;
1669
1670                 /* capability */
1671                 dissect_osd_capability(tvb, offset, tree);
1672                 offset+=80;
1673
1674                 /* security parameters */
1675                 dissect_osd_security_parameters(tvb, offset, tree);
1676                 offset+=40;
1677         }
1678
1679         /* dissecting the DATA OUT */
1680         if(isreq && !iscdb){
1681                 /* attribute data out */
1682                 dissect_osd_attribute_data_out(tvb, offset, tree, cdata);
1683
1684                 /* no data out for flush collection */
1685         }
1686
1687         /* dissecting the DATA IN */
1688         if(!isreq && !iscdb){
1689                 /* attribute data in */
1690                 dissect_osd_attribute_data_in(tvb, offset, tree, cdata);
1691
1692                 /* no data in for flush collection */
1693         }
1694         
1695 }
1696
1697
1698
1699 /* OSD Service Actions */
1700 #define OSD_FORMAT_OSD          0x8801
1701 #define OSD_CREATE              0x8802
1702 #define OSD_LIST                0x8803
1703 #define OSD_WRITE               0x8806
1704 #define OSD_FLUSH               0x8808
1705 #define OSD_REMOVE              0x880a
1706 #define OSD_CREATE_PARTITION    0x880b
1707 #define OSD_REMOVE_PARTITION    0x880c
1708 #define OSD_CREATE_COLLECTION   0x8815
1709 #define OSD_REMOVE_COLLECTION   0x8816
1710 #define OSD_SET_KEY             0x8818
1711 #define OSD_FLUSH_COLLECTION    0x881a
1712 static const value_string scsi_osd_svcaction_vals[] = {
1713     {OSD_FORMAT_OSD,            "Format OSD"},
1714     {OSD_CREATE,                "Create"},
1715     {OSD_LIST,                  "List"},
1716     {OSD_WRITE,                 "Write"},
1717     {OSD_FLUSH,                 "Flush"},
1718     {OSD_REMOVE,                "Remove"},
1719     {OSD_CREATE_PARTITION,      "Create Partition"},
1720     {OSD_REMOVE_PARTITION,      "Remove Partition"},
1721     {OSD_CREATE_COLLECTION,     "Create Collection"},
1722     {OSD_REMOVE_COLLECTION,     "Remove Collection"},
1723     {OSD_SET_KEY,               "Set Key"},
1724     {OSD_FLUSH_COLLECTION,      "Flush Collection"},
1725     {0, NULL},
1726 };
1727
1728 /* OSD Service Action dissectors */
1729 typedef struct _scsi_osd_svcaction_t {
1730         guint16 svcaction;
1731         scsi_osd_dissector_t dissector;
1732 } scsi_osd_svcaction_t;
1733 static const scsi_osd_svcaction_t scsi_osd_svcaction[] = {
1734     {OSD_FORMAT_OSD,            dissect_osd_format_osd},
1735     {OSD_CREATE,                dissect_osd_create},
1736     {OSD_LIST,                  dissect_osd_list},
1737     {OSD_WRITE,                 dissect_osd_write},
1738     {OSD_FLUSH,                 dissect_osd_flush},
1739     {OSD_REMOVE,                dissect_osd_remove},
1740     {OSD_CREATE_PARTITION,      dissect_osd_create_partition},
1741     {OSD_REMOVE_PARTITION,      dissect_osd_remove_partition},
1742     {OSD_CREATE_COLLECTION,     dissect_osd_create_collection},
1743     {OSD_REMOVE_COLLECTION,     dissect_osd_remove_collection},
1744     {OSD_SET_KEY,               dissect_osd_set_key},
1745     {OSD_FLUSH_COLLECTION,      dissect_osd_flush_collection},
1746     {0, NULL},
1747 };
1748
1749 static scsi_osd_dissector_t
1750 find_svcaction_dissector(guint16 svcaction)
1751 {
1752         const scsi_osd_svcaction_t *sa=scsi_osd_svcaction;
1753
1754         while(sa&&sa->dissector){
1755                 if(sa->svcaction==svcaction){
1756                         return sa->dissector;
1757                 }
1758                 sa++;
1759         }
1760         return NULL;
1761 }
1762
1763
1764
1765 static void
1766 dissect_osd_opcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1767                         guint offset, gboolean isreq, gboolean iscdb,
1768                         guint payload_len, scsi_task_data_t *cdata)
1769 {
1770         guint16 svcaction=0;
1771         scsi_osd_dissector_t dissector;
1772         scsi_osd_conv_info_t *conv_info=NULL;
1773         scsi_osd_lun_info_t *lun_info=NULL;
1774
1775         if(!tree) {
1776                 return;
1777         }
1778
1779         /* We must have an itl an itlq and a conversation */
1780         if(!cdata || !cdata->itl || !cdata->itl->conversation || !cdata->itlq){
1781                 return;
1782         }
1783         /* make sure we have a conversation info for this */
1784         conv_info=conversation_get_proto_data(cdata->itl->conversation, proto_scsi_osd);
1785         if(!conv_info){
1786                 conv_info=se_alloc(sizeof(scsi_osd_conv_info_t));
1787                 conv_info->luns=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SCSI OSD luns tree");
1788                 conversation_add_proto_data(cdata->itl->conversation, proto_scsi_osd, conv_info);
1789         }
1790         /* make sure we have a lun_info structure for this */
1791         lun_info=se_tree_lookup32(conv_info->luns, cdata->itlq->lun);
1792         if(!lun_info){
1793                 lun_info=se_alloc(sizeof(scsi_osd_lun_info_t));
1794                 lun_info->partitions=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SCSI OSD partitions tree");
1795                 se_tree_insert32(conv_info->luns, cdata->itlq->lun, (void *)lun_info);
1796         }
1797
1798         /* dissecting the CDB */
1799         if (isreq && iscdb) {
1800                 proto_tree_add_item (tree, hf_scsi_osd_control, tvb, offset, 1, 0);
1801                 offset++;
1802
1803                 /* 5 reserved bytes */
1804                 offset+=5;
1805
1806                 proto_tree_add_item (tree, hf_scsi_osd_add_cdblen, tvb, offset, 1, 0);
1807                 offset++;
1808
1809                 svcaction=tvb_get_ntohs(tvb, offset);
1810                 if(cdata && cdata->itlq){
1811                         /* We must store the service action for this itlq
1812                          * so we can indentify what the data contains
1813                          */
1814                         if((!pinfo->fd->flags.visited) && (!cdata->itlq->extra_data)){
1815                                 scsi_osd_extra_data_t *extra_data;
1816
1817                                 extra_data=se_alloc(sizeof(scsi_osd_extra_data_t));
1818                                 extra_data->svcaction=svcaction;
1819                                 extra_data->gsatype=0;
1820                                 cdata->itlq->extra_data=extra_data;
1821                         }
1822                 }
1823                 proto_tree_add_item (tree, hf_scsi_osd_svcaction, tvb, offset, 2, 0);
1824                 offset+=2;
1825
1826
1827                 if(check_col(pinfo->cinfo, COL_INFO)){
1828                         col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
1829                                 val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
1830                 }
1831                 dissector=find_svcaction_dissector(svcaction);
1832                 if(dissector){
1833                         (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
1834                 }
1835                 return;
1836         }
1837
1838         /* If it was not a CDB, try to find the service action and pass it
1839          * off to the service action dissector
1840          */
1841         if(cdata && cdata->itlq && cdata->itlq->extra_data){
1842                 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
1843                 svcaction=extra_data->svcaction;
1844         }
1845         if(check_col(pinfo->cinfo, COL_INFO)){
1846                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
1847                         val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
1848         }
1849         if(svcaction){
1850                 proto_item *it;
1851                 it=proto_tree_add_uint_format(tree, hf_scsi_osd_svcaction, tvb, 0, 0, svcaction, "Service Action: 0x%04x", svcaction);
1852                 PROTO_ITEM_SET_GENERATED(it);
1853         }
1854         dissector=find_svcaction_dissector(svcaction);
1855         if(dissector){
1856                 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
1857         }
1858
1859 }
1860
1861
1862 /* OSD Commands */
1863 const value_string scsi_osd_vals[] = {
1864     {SCSI_SPC2_INQUIRY                  , "Inquiry"},
1865     {SCSI_SPC2_LOGSELECT                , "Log Select"},
1866     {SCSI_SPC2_LOGSENSE                 , "Log Sense"},
1867     {SCSI_SPC2_MODESELECT10             , "Mode Select(10)"},
1868     {SCSI_SPC2_MODESENSE10              , "Mode Sense(10)"},
1869     {SCSI_SPC2_PERSRESVIN               , "Persistent Reserve In"},
1870     {SCSI_SPC2_PERSRESVOUT              , "Persistent Reserve Out"},
1871     {SCSI_SPC2_REPORTLUNS               , "Report LUNs"},
1872     {SCSI_OSD_OPCODE                    , "OSD Command" },
1873     {0, NULL},
1874 };
1875
1876
1877
1878 scsi_cdb_table_t scsi_osd_table[256] = {
1879 /*OSD 0x00*/{NULL},
1880 /*OSD 0x01*/{NULL},
1881 /*OSD 0x02*/{NULL},
1882 /*OSD 0x03*/{NULL},
1883 /*OSD 0x04*/{NULL},
1884 /*OSD 0x05*/{NULL},
1885 /*OSD 0x06*/{NULL},
1886 /*OSD 0x07*/{NULL},
1887 /*OSD 0x08*/{NULL},
1888 /*OSD 0x09*/{NULL},
1889 /*OSD 0x0a*/{NULL},
1890 /*OSD 0x0b*/{NULL},
1891 /*OSD 0x0c*/{NULL},
1892 /*OSD 0x0d*/{NULL},
1893 /*OSD 0x0e*/{NULL},
1894 /*OSD 0x0f*/{NULL},
1895 /*OSD 0x10*/{NULL},
1896 /*OSD 0x11*/{NULL},
1897 /*OSD 0x12*/{dissect_spc3_inquiry},
1898 /*OSD 0x13*/{NULL},
1899 /*OSD 0x14*/{NULL},
1900 /*OSD 0x15*/{NULL},
1901 /*OSD 0x16*/{NULL},
1902 /*OSD 0x17*/{NULL},
1903 /*OSD 0x18*/{NULL},
1904 /*OSD 0x19*/{NULL},
1905 /*OSD 0x1a*/{NULL},
1906 /*OSD 0x1b*/{NULL},
1907 /*OSD 0x1c*/{NULL},
1908 /*OSD 0x1d*/{NULL},
1909 /*OSD 0x1e*/{NULL},
1910 /*OSD 0x1f*/{NULL},
1911 /*OSD 0x20*/{NULL},
1912 /*OSD 0x21*/{NULL},
1913 /*OSD 0x22*/{NULL},
1914 /*OSD 0x23*/{NULL},
1915 /*OSD 0x24*/{NULL},
1916 /*OSD 0x25*/{NULL},
1917 /*OSD 0x26*/{NULL},
1918 /*OSD 0x27*/{NULL},
1919 /*OSD 0x28*/{NULL},
1920 /*OSD 0x29*/{NULL},
1921 /*OSD 0x2a*/{NULL},
1922 /*OSD 0x2b*/{NULL},
1923 /*OSD 0x2c*/{NULL},
1924 /*OSD 0x2d*/{NULL},
1925 /*OSD 0x2e*/{NULL},
1926 /*OSD 0x2f*/{NULL},
1927 /*OSD 0x30*/{NULL},
1928 /*OSD 0x31*/{NULL},
1929 /*OSD 0x32*/{NULL},
1930 /*OSD 0x33*/{NULL},
1931 /*OSD 0x34*/{NULL},
1932 /*OSD 0x35*/{NULL},
1933 /*OSD 0x36*/{NULL},
1934 /*OSD 0x37*/{NULL},
1935 /*OSD 0x38*/{NULL},
1936 /*OSD 0x39*/{NULL},
1937 /*OSD 0x3a*/{NULL},
1938 /*OSD 0x3b*/{NULL},
1939 /*OSD 0x3c*/{NULL},
1940 /*OSD 0x3d*/{NULL},
1941 /*OSD 0x3e*/{NULL},
1942 /*OSD 0x3f*/{NULL},
1943 /*OSD 0x40*/{NULL},
1944 /*OSD 0x41*/{NULL},
1945 /*OSD 0x42*/{NULL},
1946 /*OSD 0x43*/{NULL},
1947 /*OSD 0x44*/{NULL},
1948 /*OSD 0x45*/{NULL},
1949 /*OSD 0x46*/{NULL},
1950 /*OSD 0x47*/{NULL},
1951 /*OSD 0x48*/{NULL},
1952 /*OSD 0x49*/{NULL},
1953 /*OSD 0x4a*/{NULL},
1954 /*OSD 0x4b*/{NULL},
1955 /*OSD 0x4c*/{dissect_spc3_logselect},
1956 /*OSD 0x4d*/{dissect_spc3_logsense},
1957 /*OSD 0x4e*/{NULL},
1958 /*OSD 0x4f*/{NULL},
1959 /*OSD 0x50*/{NULL},
1960 /*OSD 0x51*/{NULL},
1961 /*OSD 0x52*/{NULL},
1962 /*OSD 0x53*/{NULL},
1963 /*OSD 0x54*/{NULL},
1964 /*OSD 0x55*/{dissect_spc3_modeselect10},
1965 /*OSD 0x56*/{NULL},
1966 /*OSD 0x57*/{NULL},
1967 /*OSD 0x58*/{NULL},
1968 /*OSD 0x59*/{NULL},
1969 /*OSD 0x5a*/{dissect_spc3_modesense10},
1970 /*OSD 0x5b*/{NULL},
1971 /*OSD 0x5c*/{NULL},
1972 /*OSD 0x5d*/{NULL},
1973 /*OSD 0x5e*/{dissect_spc3_persistentreservein},
1974 /*OSD 0x5f*/{dissect_spc3_persistentreserveout},
1975 /*OSD 0x60*/{NULL},
1976 /*OSD 0x61*/{NULL},
1977 /*OSD 0x62*/{NULL},
1978 /*OSD 0x63*/{NULL},
1979 /*OSD 0x64*/{NULL},
1980 /*OSD 0x65*/{NULL},
1981 /*OSD 0x66*/{NULL},
1982 /*OSD 0x67*/{NULL},
1983 /*OSD 0x68*/{NULL},
1984 /*OSD 0x69*/{NULL},
1985 /*OSD 0x6a*/{NULL},
1986 /*OSD 0x6b*/{NULL},
1987 /*OSD 0x6c*/{NULL},
1988 /*OSD 0x6d*/{NULL},
1989 /*OSD 0x6e*/{NULL},
1990 /*OSD 0x6f*/{NULL},
1991 /*OSD 0x70*/{NULL},
1992 /*OSD 0x71*/{NULL},
1993 /*OSD 0x72*/{NULL},
1994 /*OSD 0x73*/{NULL},
1995 /*OSD 0x74*/{NULL},
1996 /*OSD 0x75*/{NULL},
1997 /*OSD 0x76*/{NULL},
1998 /*OSD 0x77*/{NULL},
1999 /*OSD 0x78*/{NULL},
2000 /*OSD 0x79*/{NULL},
2001 /*OSD 0x7a*/{NULL},
2002 /*OSD 0x7b*/{NULL},
2003 /*OSD 0x7c*/{NULL},
2004 /*OSD 0x7d*/{NULL},
2005 /*OSD 0x7e*/{NULL},
2006 /*OSD 0x7f*/{dissect_osd_opcode},
2007 /*OSD 0x80*/{NULL},
2008 /*OSD 0x81*/{NULL},
2009 /*OSD 0x82*/{NULL},
2010 /*OSD 0x83*/{NULL},
2011 /*OSD 0x84*/{NULL},
2012 /*OSD 0x85*/{NULL},
2013 /*OSD 0x86*/{NULL},
2014 /*OSD 0x87*/{NULL},
2015 /*OSD 0x88*/{NULL},
2016 /*OSD 0x89*/{NULL},
2017 /*OSD 0x8a*/{NULL},
2018 /*OSD 0x8b*/{NULL},
2019 /*OSD 0x8c*/{NULL},
2020 /*OSD 0x8d*/{NULL},
2021 /*OSD 0x8e*/{NULL},
2022 /*OSD 0x8f*/{NULL},
2023 /*OSD 0x90*/{NULL},
2024 /*OSD 0x91*/{NULL},
2025 /*OSD 0x92*/{NULL},
2026 /*OSD 0x93*/{NULL},
2027 /*OSD 0x94*/{NULL},
2028 /*OSD 0x95*/{NULL},
2029 /*OSD 0x96*/{NULL},
2030 /*OSD 0x97*/{NULL},
2031 /*OSD 0x98*/{NULL},
2032 /*OSD 0x99*/{NULL},
2033 /*OSD 0x9a*/{NULL},
2034 /*OSD 0x9b*/{NULL},
2035 /*OSD 0x9c*/{NULL},
2036 /*OSD 0x9d*/{NULL},
2037 /*OSD 0x9e*/{NULL},
2038 /*OSD 0x9f*/{NULL},
2039 /*OSD 0xa0*/{dissect_spc3_reportluns},
2040 /*OSD 0xa1*/{NULL},
2041 /*OSD 0xa2*/{NULL},
2042 /*OSD 0xa3*/{NULL},
2043 /*OSD 0xa4*/{NULL},
2044 /*OSD 0xa5*/{NULL},
2045 /*OSD 0xa6*/{NULL},
2046 /*OSD 0xa7*/{NULL},
2047 /*OSD 0xa8*/{NULL},
2048 /*OSD 0xa9*/{NULL},
2049 /*OSD 0xaa*/{NULL},
2050 /*OSD 0xab*/{NULL},
2051 /*OSD 0xac*/{NULL},
2052 /*OSD 0xad*/{NULL},
2053 /*OSD 0xae*/{NULL},
2054 /*OSD 0xaf*/{NULL},
2055 /*OSD 0xb0*/{NULL},
2056 /*OSD 0xb1*/{NULL},
2057 /*OSD 0xb2*/{NULL},
2058 /*OSD 0xb3*/{NULL},
2059 /*OSD 0xb4*/{NULL},
2060 /*OSD 0xb5*/{NULL},
2061 /*OSD 0xb6*/{NULL},
2062 /*OSD 0xb7*/{NULL},
2063 /*OSD 0xb8*/{NULL},
2064 /*OSD 0xb9*/{NULL},
2065 /*OSD 0xba*/{NULL},
2066 /*OSD 0xbb*/{NULL},
2067 /*OSD 0xbc*/{NULL},
2068 /*OSD 0xbd*/{NULL},
2069 /*OSD 0xbe*/{NULL},
2070 /*OSD 0xbf*/{NULL},
2071 /*OSD 0xc0*/{NULL},
2072 /*OSD 0xc1*/{NULL},
2073 /*OSD 0xc2*/{NULL},
2074 /*OSD 0xc3*/{NULL},
2075 /*OSD 0xc4*/{NULL},
2076 /*OSD 0xc5*/{NULL},
2077 /*OSD 0xc6*/{NULL},
2078 /*OSD 0xc7*/{NULL},
2079 /*OSD 0xc8*/{NULL},
2080 /*OSD 0xc9*/{NULL},
2081 /*OSD 0xca*/{NULL},
2082 /*OSD 0xcb*/{NULL},
2083 /*OSD 0xcc*/{NULL},
2084 /*OSD 0xcd*/{NULL},
2085 /*OSD 0xce*/{NULL},
2086 /*OSD 0xcf*/{NULL},
2087 /*OSD 0xd0*/{NULL},
2088 /*OSD 0xd1*/{NULL},
2089 /*OSD 0xd2*/{NULL},
2090 /*OSD 0xd3*/{NULL},
2091 /*OSD 0xd4*/{NULL},
2092 /*OSD 0xd5*/{NULL},
2093 /*OSD 0xd6*/{NULL},
2094 /*OSD 0xd7*/{NULL},
2095 /*OSD 0xd8*/{NULL},
2096 /*OSD 0xd9*/{NULL},
2097 /*OSD 0xda*/{NULL},
2098 /*OSD 0xdb*/{NULL},
2099 /*OSD 0xdc*/{NULL},
2100 /*OSD 0xdd*/{NULL},
2101 /*OSD 0xde*/{NULL},
2102 /*OSD 0xdf*/{NULL},
2103 /*OSD 0xe0*/{NULL},
2104 /*OSD 0xe1*/{NULL},
2105 /*OSD 0xe2*/{NULL},
2106 /*OSD 0xe3*/{NULL},
2107 /*OSD 0xe4*/{NULL},
2108 /*OSD 0xe5*/{NULL},
2109 /*OSD 0xe6*/{NULL},
2110 /*OSD 0xe7*/{NULL},
2111 /*OSD 0xe8*/{NULL},
2112 /*OSD 0xe9*/{NULL},
2113 /*OSD 0xea*/{NULL},
2114 /*OSD 0xeb*/{NULL},
2115 /*OSD 0xec*/{NULL},
2116 /*OSD 0xed*/{NULL},
2117 /*OSD 0xee*/{NULL},
2118 /*OSD 0xef*/{NULL},
2119 /*OSD 0xf0*/{NULL},
2120 /*OSD 0xf1*/{NULL},
2121 /*OSD 0xf2*/{NULL},
2122 /*OSD 0xf3*/{NULL},
2123 /*OSD 0xf4*/{NULL},
2124 /*OSD 0xf5*/{NULL},
2125 /*OSD 0xf6*/{NULL},
2126 /*OSD 0xf7*/{NULL},
2127 /*OSD 0xf8*/{NULL},
2128 /*OSD 0xf9*/{NULL},
2129 /*OSD 0xfa*/{NULL},
2130 /*OSD 0xfb*/{NULL},
2131 /*OSD 0xfc*/{NULL},
2132 /*OSD 0xfd*/{NULL},
2133 /*OSD 0xfe*/{NULL},
2134 /*OSD 0xff*/{NULL}
2135 };
2136
2137
2138
2139
2140 void
2141 proto_register_scsi_osd(void)
2142 {
2143         static hf_register_info hf[] = {
2144         { &hf_scsi_osd_opcode,
2145           {"OSD Opcode", "scsi.osd.opcode", FT_UINT8, BASE_HEX,
2146            VALS (scsi_osd_vals), 0x0, "", HFILL}},
2147         { &hf_scsi_osd_control,
2148           {"Control", "scsi.osd.cdb.control", FT_UINT8, BASE_HEX,
2149            NULL, 0x0, "", HFILL}},
2150         { &hf_scsi_osd_add_cdblen,
2151           {"Additional CDB Length", "scsi.osd.addcdblen", FT_UINT8, BASE_DEC,
2152            NULL, 0x0, "", HFILL}},
2153         { &hf_scsi_osd_svcaction,
2154           {"Service Action", "scsi.osd.svcaction", FT_UINT16, BASE_HEX,
2155            VALS(scsi_osd_svcaction_vals), 0x0, "", HFILL}},
2156         { &hf_scsi_osd_option,
2157           {"Options Byte", "scsi.osd.option", FT_UINT8, BASE_HEX,
2158            NULL, 0x0, "", HFILL}},
2159         { &hf_scsi_osd_option_dpo,
2160           {"DPO", "scsi.osd.option.dpo", FT_BOOLEAN, 8,
2161            TFS(&option_dpo_tfs), 0x10, "", HFILL}},
2162         { &hf_scsi_osd_option_fua,
2163           {"FUA", "scsi.osd.option.fua", FT_BOOLEAN, 8,
2164            TFS(&option_fua_tfs), 0x08, "", HFILL}},
2165         { &hf_scsi_osd_getsetattrib,
2166           {"GET/SET CDBFMT", "scsi.osd.getset", FT_UINT8, BASE_HEX,
2167            VALS(scsi_osd_getsetattrib_vals), 0x30, "", HFILL}},
2168         { &hf_scsi_osd_timestamps_control,
2169           {"Timestamps Control", "scsi.osd.timestamps_control", FT_UINT8, BASE_HEX,
2170            VALS(scsi_osd_timestamps_control_vals), 0x0, "", HFILL}},
2171         { &hf_scsi_osd_formatted_capacity,
2172           {"Formatted Capacity", "scsi.osd.formatted_capacity", FT_UINT64, BASE_DEC,
2173            NULL, 0x0, "", HFILL}},
2174         { &hf_scsi_osd_get_attributes_page,
2175           {"Get Attributes Page", "scsi.osd.get_attributes_page", FT_UINT32, BASE_HEX,
2176            NULL, 0x0, "", HFILL}},
2177         { &hf_scsi_osd_get_attributes_list_length,
2178           {"Get Attributes List Length", "scsi.osd.get_attributes_list_length", FT_UINT32, BASE_HEX,
2179            NULL, 0x0, "", HFILL}},
2180         { &hf_scsi_osd_get_attributes_list_offset,
2181           {"Get Attributes List Offset", "scsi.osd.get_attributes_list_offset", FT_UINT32, BASE_HEX,
2182            NULL, 0x0, "", HFILL}},
2183         { &hf_scsi_osd_set_attributes_list_length,
2184           {"Set Attributes List Length", "scsi.osd.set_attributes_list_length", FT_UINT32, BASE_HEX,
2185            NULL, 0x0, "", HFILL}},
2186         { &hf_scsi_osd_set_attributes_list_offset,
2187           {"Set Attributes List Offset", "scsi.osd.set_attributes_list_offset", FT_UINT32, BASE_HEX,
2188            NULL, 0x0, "", HFILL}},
2189         { &hf_scsi_osd_get_attributes_allocation_length,
2190           {"Get Attributes Allocation Length", "scsi.osd.get_attributes_allocation_length", FT_UINT32, BASE_HEX,
2191            NULL, 0x0, "", HFILL}},
2192         { &hf_scsi_osd_retreived_attributes_offset,
2193           {"Retreived Attributes Offset", "scsi.osd.retreived_attributes_offset", FT_UINT32, BASE_HEX,
2194            NULL, 0x0, "", HFILL}},
2195         { &hf_scsi_osd_set_attributes_page,
2196           {"Set Attributes Page", "scsi.osd.set_attributes_page", FT_UINT32, BASE_HEX,
2197            NULL, 0x0, "", HFILL}},
2198         { &hf_scsi_osd_set_attribute_length,
2199           {"Set Attribute Length", "scsi.osd.set_attribute_length", FT_UINT32, BASE_HEX,
2200            NULL, 0x0, "", HFILL}},
2201         { &hf_scsi_osd_set_attribute_number,
2202           {"Set Attribute Number", "scsi.osd.set_attribute_number", FT_UINT32, BASE_HEX,
2203            NULL, 0x0, "", HFILL}},
2204         { &hf_scsi_osd_set_attributes_offset,
2205           {"Set Attributes Offset", "scsi.osd.set_attributes_offset", FT_UINT32, BASE_HEX,
2206            NULL, 0x0, "", HFILL}},
2207         { &hf_scsi_osd_capability_format,
2208           {"Capability Format", "scsi.osd.capability_format", FT_UINT8, BASE_HEX,
2209            VALS(scsi_osd_capability_format_vals), 0x0f, "", HFILL}},
2210         { &hf_scsi_osd_key_version,
2211           {"Key Version", "scsi.osd.key_version", FT_UINT8, BASE_HEX,
2212            NULL, 0xf0, "", HFILL}},
2213         { &hf_scsi_osd_icva,
2214           {"Integrity Check Value Algorithm", "scsi.osd.icva", FT_UINT8, BASE_HEX,
2215            NULL, 0x0f, "", HFILL}},
2216         { &hf_scsi_osd_security_method,
2217           {"Security Method", "scsi.osd.security_method", FT_UINT8, BASE_HEX,
2218            NULL, 0x0f, "", HFILL}},
2219         { &hf_scsi_osd_capability_expiration_time,
2220           {"Capability Expiration Time", "scsi.osd.capability_expiration_time", FT_BYTES, BASE_HEX,
2221            NULL, 0, "", HFILL}},
2222         { &hf_scsi_osd_audit,
2223           {"Audit", "scsi.osd.audit", FT_BYTES, BASE_HEX,
2224            NULL, 0, "", HFILL}},
2225         { &hf_scsi_osd_capability_discriminator,
2226           {"Capability Discriminator", "scsi.osd.capability_descriminator", FT_BYTES, BASE_HEX,
2227            NULL, 0, "", HFILL}},
2228         { &hf_scsi_osd_object_created_time,
2229           {"Object Created Time", "scsi.osd.object_created_time", FT_BYTES, BASE_HEX,
2230            NULL, 0, "", HFILL}},
2231         { &hf_scsi_osd_object_type,
2232           {"Object Type", "scsi.osd.object_type", FT_UINT8, BASE_HEX,
2233            VALS(scsi_osd_object_type_vals), 0, "", HFILL}},
2234         { &hf_scsi_osd_permissions,
2235           {"Permissions", "scsi.osd.permissions", FT_UINT16, BASE_HEX,
2236            NULL, 0, "", HFILL}},
2237         { &hf_scsi_osd_permissions_read,
2238           {"READ", "scsi.osd.permissions.read", FT_BOOLEAN, 16,
2239            TFS(&permissions_read_tfs), 0x8000, "", HFILL}},
2240         { &hf_scsi_osd_permissions_write,
2241           {"WRITE", "scsi.osd.permissions.write", FT_BOOLEAN, 16,
2242            TFS(&permissions_write_tfs), 0x4000, "", HFILL}},
2243         { &hf_scsi_osd_permissions_get_attr,
2244           {"GET_ATTR", "scsi.osd.permissions.get_attr", FT_BOOLEAN, 16,
2245            TFS(&permissions_get_attr_tfs), 0x2000, "", HFILL}},
2246         { &hf_scsi_osd_permissions_set_attr,
2247           {"SET_ATTR", "scsi.osd.permissions.set_attr", FT_BOOLEAN, 16,
2248            TFS(&permissions_set_attr_tfs), 0x1000, "", HFILL}},
2249         { &hf_scsi_osd_permissions_create,
2250           {"CREATE", "scsi.osd.permissions.create", FT_BOOLEAN, 16,
2251            TFS(&permissions_create_tfs), 0x0800, "", HFILL}},
2252         { &hf_scsi_osd_permissions_remove,
2253           {"REMOVE", "scsi.osd.permissions.remove", FT_BOOLEAN, 16,
2254            TFS(&permissions_remove_tfs), 0x0400, "", HFILL}},
2255         { &hf_scsi_osd_permissions_obj_mgmt,
2256           {"OBJ_MGMT", "scsi.osd.permissions.obj_mgmt", FT_BOOLEAN, 16,
2257            TFS(&permissions_obj_mgmt_tfs), 0x0200, "", HFILL}},
2258         { &hf_scsi_osd_permissions_append,
2259           {"APPEND", "scsi.osd.permissions.append", FT_BOOLEAN, 16,
2260            TFS(&permissions_append_tfs), 0x0100, "", HFILL}},
2261         { &hf_scsi_osd_permissions_dev_mgmt,
2262           {"DEV_MGMT", "scsi.osd.permissions.dev_mgmt", FT_BOOLEAN, 16,
2263            TFS(&permissions_dev_mgmt_tfs), 0x0080, "", HFILL}},
2264         { &hf_scsi_osd_permissions_global,
2265           {"GLOBAL", "scsi.osd.permissions.global", FT_BOOLEAN, 16,
2266            TFS(&permissions_global_tfs), 0x0040, "", HFILL}},
2267         { &hf_scsi_osd_permissions_pol_sec,
2268           {"POL/SEC", "scsi.osd.permissions.pol_sec", FT_BOOLEAN, 16,
2269            TFS(&permissions_pol_sec_tfs), 0x0020, "", HFILL}},
2270
2271         { &hf_scsi_osd_object_descriptor_type,
2272           {"Object Descriptor Type", "scsi.osd.object_descriptor_type", FT_UINT8, BASE_HEX,
2273            VALS(scsi_osd_object_descriptor_type_vals), 0xf0, "", HFILL}},
2274         { &hf_scsi_osd_object_descriptor,
2275           {"Object Descriptor", "scsi.osd.object_descriptor", FT_BYTES, BASE_HEX,
2276            NULL, 0, "", HFILL}},
2277         { &hf_scsi_osd_ricv,
2278           {"Request Integrity Check value", "scsi.osd.ricv", FT_BYTES, BASE_HEX,
2279            NULL, 0, "", HFILL}},
2280         { &hf_scsi_osd_request_nonce,
2281           {"Request Nonce", "scsi.osd.request_nonce", FT_BYTES, BASE_HEX,
2282            NULL, 0, "", HFILL}},
2283         { &hf_scsi_osd_diicvo,
2284           {"Data-In Integrity Check Value Offset", "scsi.osd.diicvo", FT_UINT32, BASE_DEC,
2285            NULL, 0, "", HFILL}},
2286         { &hf_scsi_osd_doicvo,
2287           {"Data-Out Integrity Check Value Offset", "scsi.osd.doicvo", FT_UINT32, BASE_DEC,
2288            NULL, 0, "", HFILL}},
2289         { &hf_scsi_osd_requested_partition_id,
2290           {"Requested Partition Id", "scsi.osd.requested_partition_id", FT_UINT64, BASE_HEX,
2291            NULL, 0, "", HFILL}},
2292         { &hf_scsi_osd_sortorder,
2293           {"Sort Order", "scsi.osd.sort_order", FT_UINT8, BASE_DEC,
2294            VALS(scsi_osd_sort_order_vals), 0x0f, "", HFILL}},
2295         { &hf_scsi_osd_partition_id,
2296           {"Partition Id", "scsi.osd.partition_id", FT_UINT64, BASE_HEX,
2297            NULL, 0, "", HFILL}},
2298         { &hf_scsi_osd_list_identifier,
2299           {"List Identifier", "scsi.osd.list_identifier", FT_UINT32, BASE_DEC,
2300            NULL, 0, "", HFILL}},
2301         { &hf_scsi_osd_allocation_length,
2302           {"Allocation Length", "scsi.osd.allocation_length", FT_UINT64, BASE_DEC,
2303            NULL, 0, "", HFILL}},
2304         { &hf_scsi_osd_length,
2305           {"Length", "scsi.osd.length", FT_UINT64, BASE_DEC,
2306            NULL, 0, "", HFILL}},
2307         { &hf_scsi_osd_starting_byte_address,
2308           {"Starting Byte Address", "scsi.osd.starting_byte_address", FT_UINT64, BASE_DEC,
2309            NULL, 0, "", HFILL}},
2310         { &hf_scsi_osd_initial_object_id,
2311           {"Initial Object Id", "scsi.osd.initial_object_id", FT_BYTES, BASE_HEX,
2312            NULL, 0, "", HFILL}},
2313         { &hf_scsi_osd_additional_length,
2314           {"Additional Length", "scsi.osd.additional_length", FT_UINT64, BASE_DEC,
2315            NULL, 0, "", HFILL}},
2316         { &hf_scsi_osd_continuation_object_id,
2317           {"Continuation Object Id", "scsi.osd.continuation_object_id", FT_BYTES, BASE_HEX,
2318            NULL, 0, "", HFILL}},
2319         { &hf_scsi_osd_user_object_id,
2320           {"User Object Id", "scsi.osd.user_object_id", FT_BYTES, BASE_HEX,
2321            NULL, 0, "", HFILL}},
2322         { &hf_scsi_osd_list_flags_lstchg,
2323           {"LSTCHG", "scsi.osd.list.lstchg", FT_BOOLEAN, 8,
2324            TFS(&list_lstchg_tfs), 0x02, "", HFILL}},
2325         { &hf_scsi_osd_list_flags_root,
2326           {"ROOT", "scsi.osd.list.root", FT_BOOLEAN, 8,
2327            TFS(&list_root_tfs), 0x01, "", HFILL}},
2328         { &hf_scsi_osd_requested_user_object_id,
2329           {"Requested User Object Id", "scsi.osd.requested_user_object_id", FT_BYTES, BASE_HEX,
2330            NULL, 0, "", HFILL}},
2331         { &hf_scsi_osd_number_of_user_objects,
2332           {"Number Of User Objects", "scsi.osd.number_of_user_objects", FT_UINT16, BASE_DEC,
2333            NULL, 0, "", HFILL}},
2334         { &hf_scsi_osd_key_to_set,
2335           {"Key to Set", "scsi.osd.key_to_set", FT_UINT8, BASE_DEC,
2336            VALS(key_to_set_vals), 0x03, "", HFILL}},
2337         { &hf_scsi_osd_set_key_version,
2338           {"Key Version", "scsi.osd.set_key_version", FT_UINT8, BASE_DEC,
2339            NULL, 0x0f, "", HFILL}},
2340         { &hf_scsi_osd_key_identifier,
2341           {"Key Identifier", "scsi.osd.key_identifier", FT_BYTES, BASE_HEX,
2342            NULL, 0, "", HFILL}},
2343         { &hf_scsi_osd_seed,
2344           {"Seed", "scsi.osd.seed", FT_BYTES, BASE_HEX,
2345            NULL, 0, "", HFILL}},
2346         { &hf_scsi_osd_collection_fcr,
2347           {"FCR", "scsi.osd.collection.fcr", FT_BOOLEAN, 8,
2348            TFS(&collection_fcr_tfs), 0x01, "", HFILL}},
2349         { &hf_scsi_osd_collection_object_id,
2350           {"Collection Object Id", "scsi.osd.collection_object_id", FT_BYTES, BASE_HEX,
2351            NULL, 0, "", HFILL}},
2352         { &hf_scsi_osd_requested_collection_object_id,
2353           {"Requested Collection Object Id", "scsi.osd.requested_collection_object_id", FT_BYTES, BASE_HEX,
2354            NULL, 0, "", HFILL}},
2355         { &hf_scsi_osd_partition_created_in,
2356           { "Created In", "scsi.osd.partition.created_in", FT_FRAMENUM, BASE_NONE,
2357           NULL, 0x0, "The frame this partition was created", HFILL }},
2358
2359         { &hf_scsi_osd_partition_removed_in,
2360           { "Removed In", "scsi.osd.partition.removed_in", FT_FRAMENUM, BASE_NONE,
2361           NULL, 0x0, "The frame this partition was removed", HFILL }},
2362
2363         { &hf_scsi_osd_flush_scope,
2364           {"Flush Scope", "scsi.osd.flush.scope", FT_UINT8, BASE_DEC,
2365            VALS(flush_scope_vals), 0x03, "", HFILL}},
2366
2367         { &hf_scsi_osd_flush_collection_scope,
2368           {"Flush Collection Scope", "scsi.osd.flush_collection.scope", FT_UINT8, BASE_DEC,
2369            VALS(flush_collection_scope_vals), 0x03, "", HFILL}},
2370         };
2371
2372         /* Setup protocol subtree array */
2373         static gint *ett[] = {
2374                 &ett_osd_option,
2375                 &ett_osd_partition,
2376                 &ett_osd_attribute_parameters,
2377                 &ett_osd_capability,
2378                 &ett_osd_permission_bitmask,
2379                 &ett_osd_security_parameters,
2380         };
2381
2382         /* Register the protocol name and description */
2383         proto_scsi_osd = proto_register_protocol("SCSI_OSD", "SCSI_OSD", "scsi_osd");
2384
2385         /* Required function calls to register the header fields and subtrees used */
2386         proto_register_field_array(proto_scsi_osd, hf, array_length(hf));
2387         proto_register_subtree_array(ett, array_length(ett));
2388 }
2389
2390 void
2391 proto_reg_handoff_scsi_osd(void)
2392 {
2393 }
2394