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