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