HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-scsi-osd.c
blob26cab1b1af27b88a299d1d729ef2781f2c8b2408
1 /* packet-scsi-osd.c
2 * Dissector for the SCSI OSD (object based storage) commandset
4 * Ronnie sahlberg 2006
5 * Joe Breher 2006
6 * Javier Godoy 2013 (OSD-2 dissector)
8 * $Id$
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 2002 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "config.h"
31 #include <glib.h>
32 #include <epan/packet.h>
33 #include <epan/wmem/wmem.h>
34 #include <epan/conversation.h>
35 #include <epan/tap.h>
36 #include <epan/expert.h>
37 #include "packet-scsi.h"
38 #include "packet-fc.h"
39 #include "packet-scsi-osd.h"
42 static int proto_scsi_osd = -1;
43 int hf_scsi_osd_opcode = -1;
44 static int hf_scsi_osd_add_cdblen = -1;
45 static int hf_scsi_osd_svcaction = -1;
46 static int hf_scsi_osd_option = -1;
47 static int hf_scsi_osd_option_dpo = -1;
48 static int hf_scsi_osd_option_fua = -1;
49 static int hf_scsi_osd_getsetattrib = -1;
50 static int hf_scsi_osd_timestamps_control = -1;
51 static int hf_scsi_osd_formatted_capacity = -1;
52 static int hf_scsi_osd_get_attributes_page = -1;
53 static int hf_scsi_osd_get_attributes_allocation_length = -1;
54 static int hf_scsi_osd_get_attributes_list_length = -1;
55 static int hf_scsi_osd_get_attributes_list_offset = -1;
56 static int hf_scsi_osd_retrieved_attributes_offset = -1;
57 static int hf_scsi_osd_set_attributes_page = -1;
58 static int hf_scsi_osd_set_attribute_length = -1;
59 static int hf_scsi_osd_set_attribute_number = -1;
60 static int hf_scsi_osd_set_attributes_offset = -1;
61 static int hf_scsi_osd_set_attributes_list_length = -1;
62 static int hf_scsi_osd_set_attributes_list_offset = -1;
63 static int hf_scsi_osd_capability_format = -1;
64 static int hf_scsi_osd_key_version = -1;
65 static int hf_scsi_osd_icva = -1;
66 static int hf_scsi_osd_security_method = -1;
67 static int hf_scsi_osd_capability_expiration_time = -1;
68 static int hf_scsi_osd_audit = -1;
69 static int hf_scsi_osd_capability_discriminator = -1;
70 static int hf_scsi_osd_object_created_time = -1;
71 static int hf_scsi_osd_object_type = -1;
72 static int hf_scsi_osd_permissions = -1;
73 static int hf_scsi_osd_permissions_read = -1;
74 static int hf_scsi_osd_permissions_write = -1;
75 static int hf_scsi_osd_permissions_get_attr = -1;
76 static int hf_scsi_osd_permissions_set_attr = -1;
77 static int hf_scsi_osd_permissions_create = -1;
78 static int hf_scsi_osd_permissions_remove = -1;
79 static int hf_scsi_osd_permissions_obj_mgmt = -1;
80 static int hf_scsi_osd_permissions_append = -1;
81 static int hf_scsi_osd_permissions_dev_mgmt = -1;
82 static int hf_scsi_osd_permissions_global = -1;
83 static int hf_scsi_osd_permissions_pol_sec = -1;
84 static int hf_scsi_osd_object_descriptor_type = -1;
85 static int hf_scsi_osd_object_descriptor = -1;
86 static int hf_scsi_osd_ricv = -1;
87 static int hf_scsi_osd_request_nonce = -1;
88 static int hf_scsi_osd_diicvo = -1;
89 static int hf_scsi_osd_doicvo = -1;
90 static int hf_scsi_osd_requested_partition_id = -1;
91 static int hf_scsi_osd_sortorder = -1;
92 static int hf_scsi_osd_partition_id = -1;
93 static int hf_scsi_osd_list_identifier = -1;
94 static int hf_scsi_osd_allocation_length = -1;
95 static int hf_scsi_osd_length = -1;
96 static int hf_scsi_osd_starting_byte_address = -1;
97 static int hf_scsi_osd_initial_object_id = -1;
98 static int hf_scsi_osd_additional_length = -1;
99 static int hf_scsi_osd_continuation_object_id = -1;
100 static int hf_scsi_osd_list_flags_lstchg = -1;
101 static int hf_scsi_osd_list_flags_root = -1;
102 static int hf_scsi_osd_list_collection_flags_coltn = -1;
103 static int hf_scsi_osd_user_object_id = -1;
104 static int hf_scsi_osd_requested_user_object_id = -1;
105 static int hf_scsi_osd_number_of_user_objects = -1;
106 static int hf_scsi_osd_key_to_set = -1;
107 static int hf_scsi_osd_set_key_version = -1;
108 static int hf_scsi_osd_key_identifier = -1;
109 static int hf_scsi_osd_seed = -1;
110 static int hf_scsi_osd_collection_fcr = -1;
111 static int hf_scsi_osd_collection_object_id = -1;
112 static int hf_scsi_osd_requested_collection_object_id = -1;
113 static int hf_scsi_osd_partition_created_in = -1;
114 static int hf_scsi_osd_partition_removed_in = -1;
115 static int hf_scsi_osd_flush_scope = -1;
116 static int hf_scsi_osd_flush_collection_scope = -1;
117 static int hf_scsi_osd_flush_partition_scope = -1;
118 static int hf_scsi_osd_flush_osd_scope = -1;
119 static int hf_scsi_osd_attributes_list_type = -1;
120 static int hf_scsi_osd_attributes_list_length = -1;
121 static int hf_scsi_osd_attributes_page = -1;
122 static int hf_scsi_osd_attribute_number = -1;
123 static int hf_scsi_osd_attribute_length = -1;
124 static int hf_scsi_osd_attrval_user_object_logical_length = -1;
125 static int hf_scsi_osd_attrval_object_type = -1;
126 static int hf_scsi_osd_attrval_partition_id = -1;
127 static int hf_scsi_osd_attrval_object_id = -1;
128 static int hf_scsi_osd2_query_type = -1;
129 static int hf_scsi_osd2_query_entry_length = -1;
130 static int hf_scsi_osd2_query_attributes_page = -1;
131 static int hf_scsi_osd2_query_attribute_number = -1;
132 static int hf_scsi_osd2_query_minimum_attribute_value_length = -1;
133 static int hf_scsi_osd2_query_maximum_attribute_value_length = -1;
135 /* Fields that are defined in OSD-2 are prefixed with hf_scsi_osd2_ */
136 static int hf_scsi_osd2_attributes_list_length = -1;
137 static int hf_scsi_osd2_set_attribute_value = -1;
138 static int hf_scsi_osd2_isolation = -1;
139 static int hf_scsi_osd2_immed_tr = -1;
140 static int hf_scsi_osd2_list_attr = -1;
141 static int hf_scsi_osd2_object_descriptor_format = -1;
142 static int hf_scsi_osd2_matches_collection_object_id = -1;
143 static int hf_scsi_osd2_source_collection_object_id = -1;
144 static int hf_scsi_osd2_cdb_continuation_length = -1;
145 static int hf_scsi_osd2_cdb_continuation_format = -1;
146 static int hf_scsi_osd2_continued_service_action = -1;
147 static int hf_scsi_osd2_cdb_continuation_descriptor_type = -1;
148 static int hf_scsi_osd2_cdb_continuation_descriptor_pad_length = -1;
149 static int hf_scsi_osd2_cdb_continuation_descriptor_length = -1;
150 static int hf_scsi_osd2_remove_scope = -1;
152 static gint ett_osd_option = -1;
153 static gint ett_osd_partition = -1;
154 static gint ett_osd_attribute_parameters = -1;
155 static gint ett_osd_capability = -1;
156 static gint ett_osd_permission_bitmask = -1;
157 static gint ett_osd_security_parameters = -1;
158 static gint ett_osd_get_attributes = -1;
159 static gint ett_osd_set_attributes = -1;
160 static gint ett_osd_multi_object = -1;
161 static gint ett_osd_attribute = -1;
162 static gint ett_osd2_query_criteria_entry = -1;
164 static expert_field ei_osd_attr_unknown = EI_INIT;
165 static expert_field ei_osd2_invalid_offset = EI_INIT;
166 static expert_field ei_osd2_invalid_object_descriptor_format = EI_INIT;
167 static expert_field ei_osd_unknown_attributes_list_type = EI_INIT;
168 static expert_field ei_osd2_cdb_continuation_format_unknown = EI_INIT;
169 static expert_field ei_osd2_continued_service_action_mismatch = EI_INIT;
170 static expert_field ei_osd2_cdb_continuation_descriptor_type_unknown = EI_INIT;
171 static expert_field ei_osd2_cdb_continuation_descriptor_length_invalid = EI_INIT;
172 static expert_field ei_osd2_cdb_continuation_length_invalid = EI_INIT;
173 static expert_field ei_osd_attr_length_invalid = EI_INIT;
174 static expert_field ei_osd2_query_values_equal= EI_INIT;
176 #define PAGE_NUMBER_OBJECT 0x00000000
177 #define PAGE_NUMBER_PARTITION 0x30000000
178 #define PAGE_NUMBER_COLLECTION 0x60000000
179 #define PAGE_NUMBER_ROOT 0x90000000
182 /* There will be one such structure create for each conversation ontop of which
183 * there is an OSD session
185 typedef struct _scsi_osd_conv_info_t {
186 wmem_tree_t *luns;
187 } scsi_osd_conv_info_t;
189 /* there will be one such structure created for each lun for each conversation
190 * that is handled by the OSD dissector
192 struct _scsi_osd_lun_info_t {
193 wmem_tree_t *partitions;
196 typedef void (*scsi_osd_dissector_t)(tvbuff_t *tvb, packet_info *pinfo,
197 proto_tree *tree, guint offset,
198 gboolean isreq, gboolean iscdb,
199 guint32 payload_len, scsi_task_data_t *cdata,
200 scsi_osd_conv_info_t *conv_info,
201 scsi_osd_lun_info_t *lun_info
204 /* One such structure is created per conversation/lun/partition to
205 * keep track of when partitions are created/used/destroyed
207 typedef struct _partition_info_t {
208 int created_in;
209 int removed_in;
210 } partition_info_t;
213 /* This is a set of extra data specific to OSD that we need to attach to every
214 * task.
216 typedef struct _scsi_osd_extra_data_t {
217 guint16 svcaction;
218 guint8 gsatype;
219 union {
220 struct { /* gsatype: attribute list */
221 guint32 get_list_length;
222 guint32 get_list_offset;
223 guint32 get_list_allocation_length;
224 guint32 retrieved_list_offset;
225 guint32 set_list_length;
226 guint32 set_list_offset;
227 } al;
228 } u;
229 guint32 continuation_length;
230 gboolean osd2;
231 } scsi_osd_extra_data_t;
233 static proto_item*
234 dissect_osd_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
236 /* user object id */
237 proto_item* item;
238 item=proto_tree_add_item(tree, hf_scsi_osd_user_object_id, tvb, offset, 8, ENC_NA);
239 return item;
243 /*dissects an attribute that is defined as a pair of hf_index,length*/
244 static void
245 generic_attribute_dissector(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
246 scsi_osd_lun_info_t *lun_info _U_, const attribute_page_numbers_t *att)
248 proto_tree_add_item(tree, *att->hf_index, tvb, 0, att->expected_length, ENC_BIG_ENDIAN);
251 static proto_item *
252 dissect_osd_partition_id(packet_info *pinfo, tvbuff_t *tvb, int offset,
253 proto_tree *tree, int hf_index,
254 scsi_osd_lun_info_t *lun_info, gboolean is_created,
255 gboolean is_removed);
257 static void
258 partition_id_attribute_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
259 scsi_osd_lun_info_t *lun_info, const attribute_page_numbers_t *att)
261 dissect_osd_partition_id(pinfo, tvb, 0, tree, *att->hf_index, lun_info, FALSE, FALSE);
264 static const attribute_page_numbers_t user_object_info_attributes[] = {
265 {0x82, "User object logical length", generic_attribute_dissector, &hf_scsi_osd_attrval_user_object_logical_length,8},
266 {0, NULL, NULL, NULL, 0}
269 static const attribute_page_numbers_t current_command_attributes[] = {
270 {0x02, "Object Type", generic_attribute_dissector, &hf_scsi_osd_attrval_object_type, 1},
271 {0x03, "Partition ID", partition_id_attribute_dissector, &hf_scsi_osd_attrval_partition_id,8},
272 {0x04, "Collection Object ID or User Object ID", generic_attribute_dissector, &hf_scsi_osd_attrval_object_id,8},
273 {0, NULL, NULL, NULL, 0}
276 typedef struct _attribute_pages_t {
277 guint32 page;
278 const attribute_page_numbers_t *attributes;
279 } attribute_pages_t;
281 static const attribute_pages_t attribute_pages[] = {
282 {PAGE_NUMBER_OBJECT+1, user_object_info_attributes},
283 {0xFFFFFFFE, current_command_attributes},
284 {0,NULL}
287 const value_string attributes_page_vals[] = {
288 {PAGE_NUMBER_OBJECT+0, "User Object Directory"},
289 {PAGE_NUMBER_OBJECT+1, "User Object Information"},
290 {PAGE_NUMBER_OBJECT+2, "User Object Quotas"},
291 {PAGE_NUMBER_OBJECT+3, "User Object Timestamps"},
292 {PAGE_NUMBER_OBJECT+4, "User Object Collections"},
293 {PAGE_NUMBER_OBJECT+5, "User Object Policy/Security"},
294 {PAGE_NUMBER_COLLECTION, "Collection Directory"},
295 {PAGE_NUMBER_COLLECTION+1, "Collection Information"},
296 {PAGE_NUMBER_COLLECTION+2, "Collection Quotas"},
297 {PAGE_NUMBER_COLLECTION+4, "Collection Command Tracking"},
298 {PAGE_NUMBER_COLLECTION+5, "Collection Policy/Security"},
299 {PAGE_NUMBER_PARTITION, "Partition Directory"},
300 {PAGE_NUMBER_PARTITION+1, "Partition Information"},
301 {PAGE_NUMBER_PARTITION+2, "Partition Quotas"},
302 {PAGE_NUMBER_PARTITION+3, "Partition Timestamps"},
303 {PAGE_NUMBER_PARTITION+5, "Partition Policy/Security"},
304 {PAGE_NUMBER_ROOT, "Root Directory"},
305 {PAGE_NUMBER_ROOT+1, "Root Information"},
306 {PAGE_NUMBER_ROOT+2, "Root Quotas"},
307 {PAGE_NUMBER_ROOT+3, "Root Timestamps"},
308 {PAGE_NUMBER_ROOT+5, "Root Policy/Security"},
309 {0xFFFFFFFE, "Current Command"},
310 {0xFFFFFFFF, "All attribute pages"},
311 {0, NULL}
315 static const value_string attributes_list_type_vals[] = {
316 {0x01, "Retrieve attributes for this OSD object"},
317 {0x09, "Retrieve/Set attributes for this OSD object"},
318 {0x0f, "Retrieve attributes for a CREATE command"},
319 {0,NULL}
322 static const value_string scsi_osd2_isolation_val[] = {
323 {0x00, "Default"},
324 {0x01, "None"},
325 {0x02, "Strict"},
326 {0x04, "Range"},
327 {0x05, "Functional"},
328 {0x07, "Vendor specific"},
329 {0,NULL}
332 static const value_string scsi_osd2_object_descriptor_format_val[] = {
333 {0x01, "Partition ID"},
334 {0x02, "Partition ID followed by attribute parameters"},
335 {0x11, "Collection ID"},
336 {0x12, "Collection ID followed by attribute parameters"},
337 {0x21, "User Object ID"},
338 {0x22, "User Object ID followed by attribute parameters"},
339 {0,NULL}
342 static const value_string scsi_osd2_remove_scope[] = {
343 {0x00, "Fail if there are collections or user objects in the partition"},
344 {0x01, "Remove collections and user objects in the partition"},
345 {0,NULL}
348 static const value_string scsi_osd2_cdb_continuation_format_val[] = {
349 {0x01, "OSD2"},
350 {0,NULL}
353 static const value_string scsi_osd2_cdb_continuation_descriptor_type_val[] = {
354 {0x0000, "No more continuation descriptors"},
355 {0x0001, "Scatter/gather list"},
356 {0x0002, "Query list"},
357 {0x0100, "User object"},
358 {0x0101, "Copy user object source"},
359 {0xFFEE, "Extension capabilities"},
360 {0,NULL}
363 static const value_string scsi_osd2_query_type_vals[] = {
364 {0x00, "Match any query criteria"},
365 {0x01, "Match all query criteria"},
366 {0,NULL}
369 /* OSD2/3 helper functions */
371 static void
372 dissect_osd2_isolation(tvbuff_t *tvb, int offset, proto_tree *tree)
374 /* isolation */
375 proto_tree_add_item(tree, hf_scsi_osd2_isolation, tvb, offset, 1, ENC_BIG_ENDIAN);
378 static void
379 dissect_osd2_list_attr(tvbuff_t *tvb, int offset, proto_tree *tree)
381 /* list_attr */
382 proto_tree_add_item(tree, hf_scsi_osd2_list_attr, tvb, offset, 1, ENC_BIG_ENDIAN);
386 /* used by dissect_osd_attributes_list, dissect_osd2_attribute_list_entry
387 and dissect_scsi_descriptor_snsinfo from packet-scsi.c*/
388 const attribute_page_numbers_t *
389 osd_lookup_attribute(guint32 page, guint32 number)
391 const attribute_pages_t *ap;
392 const attribute_page_numbers_t *apn;
394 /* find the proper attributes page */
395 apn=NULL;
396 for(ap=attribute_pages;ap->attributes;ap++){
397 if(ap->page==page){
398 apn=ap->attributes;
399 break;
402 if(!apn) return NULL;
404 /* find the specific attribute */
405 for(;apn->name;apn++){
406 if(apn->number==number){
407 break;
410 if(!apn->name) return NULL;
412 /* found it */
413 return apn;
416 /* OSD-1: 7.1.3.3, OSD2 7.1.4.3 list entry format */
417 static guint32
418 dissect_osd_attribute_list_entry(packet_info *pinfo, tvbuff_t *tvb,
419 proto_tree *tree, proto_item* item,
420 guint32 offset, scsi_osd_lun_info_t *lun_info,
421 gboolean osd2)
423 guint16 attribute_length;
424 guint32 page, number;
425 const attribute_page_numbers_t *apn;
427 /* attributes page */
428 page=tvb_get_ntohl(tvb, offset);
429 proto_tree_add_item(tree, hf_scsi_osd_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
430 offset+=4;
432 /* attribute number */
433 number=tvb_get_ntohl(tvb, offset);
434 proto_tree_add_item(tree, hf_scsi_osd_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
435 offset+=4;
437 if (osd2) {
438 /*6 reserved bytes*/
439 offset+=6;
442 /* attribute length */
443 attribute_length=tvb_get_ntohs(tvb, offset);
444 proto_tree_add_item(tree, hf_scsi_osd_attribute_length, tvb, offset, 2, ENC_BIG_ENDIAN);
445 offset+=2;
447 proto_item_append_text(item, " 0x%08x (%s)", page, val_to_str_const(page, attributes_page_vals,"Unknown"));
448 proto_item_append_text(item, " 0x%08x", number);
449 apn= osd_lookup_attribute(page,number);
451 if (!apn) {
452 expert_add_info(pinfo, item, &ei_osd_attr_unknown);
453 proto_item_append_text(item, " (Unknown)");
454 } else {
455 proto_item_append_text(item, " (%s)", apn->name);
457 /* attribute value*/
458 if (attribute_length) {
459 if (attribute_length != apn->expected_length) {
460 proto_tree_add_expert_format(tree, pinfo, &ei_osd_attr_length_invalid,
461 tvb, 0, attribute_length, "%s", apn->name);
462 } else {
463 tvbuff_t* next_tvb=tvb_new_subset(tvb, offset, attribute_length, attribute_length);
464 apn->dissector(next_tvb, pinfo, tree, lun_info, apn);
469 offset+=attribute_length;
470 if (osd2 && (attribute_length&7)) {
471 /* 8-bit padding */
472 offset += 8-(attribute_length&7);
475 return offset;
478 /* OSD1: 7.1.3.1
479 OSD2: 7.1.4.1*/
480 static void
481 dissect_osd_attributes_list(packet_info *pinfo, tvbuff_t *tvb, int offset,
482 proto_tree *tree, scsi_osd_lun_info_t *lun_info,
483 gboolean osd2)
485 guint8 type;
486 guint32 length;
487 guint32 page, number;
488 int start_offset=offset;
489 proto_item *item, *list_type_item;
490 const attribute_page_numbers_t *apn;
492 /* list type */
493 type=tvb_get_guint8(tvb, offset)&0x0f;
494 list_type_item=proto_tree_add_item(tree, hf_scsi_osd_attributes_list_type, tvb, offset, 1, ENC_BIG_ENDIAN);
495 offset++;
497 /* OSD-1: a reserved byte */
498 /* OSD-2: 3 reserved bytes */
499 offset+=(osd2?3:1);
501 /* OSD-1: length (16 bit)
502 OSD-2: length (32 bit) */
503 if (osd2) {
504 length=tvb_get_ntohl(tvb, offset);
505 proto_tree_add_item(tree, hf_scsi_osd2_attributes_list_length, tvb, offset, 4, ENC_BIG_ENDIAN);
506 offset+=4;
507 } else {
508 length=tvb_get_ntohs(tvb, offset);
509 proto_tree_add_item(tree, hf_scsi_osd_attributes_list_length, tvb, offset, 2, ENC_BIG_ENDIAN);
510 offset+=2;
513 /* if type is 1 length will be zero and we have to cycle over
514 * all remaining bytes. 7.1.3.1
516 if(!osd2&&type==1){
517 length=tvb_length_remaining(tvb, offset);
520 length+=(osd2?8:4);
522 while( (guint32)(offset-start_offset)<length ){
523 proto_item *ti;
524 proto_tree* tt;
525 guint32 attribute_entry_length;
527 switch(type){
528 case 0x01:
529 attribute_entry_length=8;
530 break;
531 case 0x0f:
532 attribute_entry_length=18+tvb_get_ntohs(tvb,offset+16);
533 break;
534 case 0x09:
535 if (osd2) {
536 attribute_entry_length=16+tvb_get_ntohs(tvb,offset+14);
537 } else {
538 attribute_entry_length=10+tvb_get_ntohs(tvb,offset+8);
540 break;
541 default:
542 expert_add_info(pinfo, list_type_item, &ei_osd_unknown_attributes_list_type);
543 return;
546 if ((guint32)(offset-start_offset)+attribute_entry_length>length) break;
547 ti = proto_tree_add_text(tree, tvb, offset, attribute_entry_length, "Attribute:");
548 tt = proto_item_add_subtree(ti, ett_osd_attribute);
550 switch(type){
551 case 0x01: /* retrieving attributes 7.1.3.2 */
552 /* attributes page */
553 page=tvb_get_ntohl(tvb, offset);
554 proto_tree_add_item(tt, hf_scsi_osd_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
555 offset+=4;
557 /* attribute number */
558 number=tvb_get_ntohl(tvb, offset);
559 item=proto_tree_add_item(tt, hf_scsi_osd_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
560 offset+=4;
562 proto_item_append_text(ti, " 0x%08x (%s)", page, val_to_str_const(page, attributes_page_vals,"Unknown"));
563 proto_item_append_text(ti, " 0x%08x", number);
565 /* find the proper attributes page */
566 apn=osd_lookup_attribute(page,number);
567 if (!apn) {
568 proto_item_append_text(ti, " (Unknown)");
569 proto_item_append_text(item, " (Unknown)");
570 } else {
571 proto_item_append_text(ti, " (%s)", apn->name);
572 proto_item_append_text(item, " (%s)", apn->name);
574 break;
575 case 0x0f: /* create attributes 7.1.3.4 */
576 /* user object id */
577 dissect_osd_user_object_id(tvb, offset, tt);
578 offset+=8;
579 /* fallthrough to the next case */
580 case 0x09: /* retrieved/set attributes OSD-1: 7.1.3.3 OSD-2: 7.1.4.3*/
581 offset=dissect_osd_attribute_list_entry(pinfo, tvb, tt, ti, offset, lun_info, osd2);
582 break;
588 /* OSD2 5.2.4 */
589 static void
590 dissect_osd_option(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
592 proto_tree *tree=NULL;
593 proto_item *it=NULL;
594 guint8 option;
596 option=tvb_get_guint8(tvb, offset);
598 if(parent_tree){
599 it=proto_tree_add_item(parent_tree, hf_scsi_osd_option, tvb, offset, 1, ENC_BIG_ENDIAN);
600 tree = proto_item_add_subtree(it, ett_osd_option);
603 proto_tree_add_item(tree, hf_scsi_osd_option_dpo, tvb, offset, 1, ENC_BIG_ENDIAN);
604 if(option&0x10){
605 proto_item_append_text(tree, " DPO");
608 proto_tree_add_item(tree, hf_scsi_osd_option_fua, tvb, offset, 1, ENC_BIG_ENDIAN);
609 if(option&0x08){
610 proto_item_append_text(tree, " FUA");
615 static const value_string scsi_osd_getsetattrib_vals[] = {
616 {1, "Set one attribute using CDB fields (OSD-2)"},
617 {2, "Get an attributes page and set an attribute value"},
618 {3, "Get and set attributes using a list"},
619 {0, NULL},
622 /* OSD2 5.2.2.1 */
623 static void
624 dissect_osd_getsetattrib(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
626 if(cdata && cdata->itlq && cdata->itlq->extra_data){
627 scsi_osd_extra_data_t *extra_data=(scsi_osd_extra_data_t *)cdata->itlq->extra_data;
628 extra_data->gsatype=(tvb_get_guint8(tvb, offset)>>4)&0x03;
630 proto_tree_add_item(tree, hf_scsi_osd_getsetattrib, tvb, offset, 1, ENC_BIG_ENDIAN);
633 static const value_string scsi_osd_timestamps_control_vals[] = {
634 {0x00, "Timestamps shall be updated"},
635 {0x7f, "Timestamps shall not be updated"},
636 {0, NULL},
639 /* OSD2 5.2.8 */
640 static void
641 dissect_osd_timestamps_control(tvbuff_t *tvb, int offset, proto_tree *tree)
643 proto_tree_add_item(tree, hf_scsi_osd_timestamps_control, tvb, offset, 1, ENC_BIG_ENDIAN);
647 static void
648 dissect_osd_formatted_capacity(tvbuff_t *tvb, int offset, proto_tree *tree)
650 proto_tree_add_item(tree, hf_scsi_osd_formatted_capacity, tvb, offset, 8, ENC_BIG_ENDIAN);
653 static void
654 dissect_osd_offset(packet_info *pinfo, tvbuff_t *tvb, int offset,
655 proto_tree *tree, int field, guint32 *raw_value_ptr,
656 gboolean osd2)
658 /* dissects an OSD offset value, add proto item and updates *raw_value_ptr */
659 guint32 value = *raw_value_ptr;
661 if (value!=0xFFFFFFFF) {
662 if (!osd2) {
663 /*OSD-1: the exponent is an unsigned value (4.12.5)*/
664 value = (value&0x0fffffff)<<((value>>28)&0x0f);
665 value<<=8;
666 } else {
667 /*OSD-2: the exponent is a signed value (4.15.5)*/
668 int exponent = (value>>28);
669 guint32 mantissa = (value&0x0FFFFFFF);
671 if (exponent&0x8) {
672 exponent=-(((~exponent)&7)+1);
673 if (exponent<=-6&&mantissa!=0xFFFFFFF) {
674 proto_item* item;
675 item = proto_tree_add_item(tree, field, tvb, offset, 4, value);
676 expert_add_info(pinfo, item, &ei_osd2_invalid_offset);
677 *raw_value_ptr=0xFFFFFFFF;
678 return;
681 value = mantissa<<(exponent+8);
684 proto_tree_add_uint(tree, field, tvb, offset, 4, value);
685 *raw_value_ptr=value;
688 static int
689 dissect_osd_attribute_parameters(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *parent_tree, scsi_task_data_t *cdata)
691 guint8 gsatype=0;
692 proto_item *item=NULL;
693 proto_tree *tree=NULL;
694 scsi_osd_extra_data_t *extra_data=NULL;
695 gboolean osd2;
697 if(parent_tree){
698 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
699 "Attribute Parameters");
700 tree = proto_item_add_subtree(item, ett_osd_attribute_parameters);
703 if(cdata && cdata->itlq && cdata->itlq->extra_data){
704 extra_data=(scsi_osd_extra_data_t *)cdata->itlq->extra_data;
705 gsatype=extra_data->gsatype;
706 osd2=extra_data->osd2;
707 } else {
708 return offset;
711 switch(gsatype){
712 case 1: /* OSD-2 5.2.6.2 Set one attribute using CDB fields*/
713 if (osd2) {
714 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
715 offset+=4;
716 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
717 offset+=4;
718 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, ENC_BIG_ENDIAN);
719 offset+=4;
720 proto_tree_add_item(tree, hf_scsi_osd2_set_attribute_value, tvb, offset, 18, ENC_NA);
721 offset+=18;
723 break;
724 case 2: /* 5.2.2.2 attribute page */
725 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
726 offset+=4;
727 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, ENC_BIG_ENDIAN);
728 offset+=4;
729 proto_tree_add_item(tree, hf_scsi_osd_retrieved_attributes_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
730 offset+=4;
731 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
732 offset+=4;
733 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
734 offset+=4;
735 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, ENC_BIG_ENDIAN);
736 offset+=4;
737 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
738 offset+=4;
739 break;
740 case 3: /* 5.2.2.3 attribute list */
741 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_list_length, tvb, offset, 4, ENC_BIG_ENDIAN);
742 extra_data->u.al.get_list_length=tvb_get_ntohl(tvb, offset);
743 offset+=4;
745 /* 4.12.5 */
746 extra_data->u.al.get_list_offset=tvb_get_ntohl(tvb, offset);
747 dissect_osd_offset(pinfo,tvb,offset,tree,hf_scsi_osd_get_attributes_list_offset,
748 &extra_data->u.al.get_list_offset,osd2);
749 if (extra_data->u.al.get_list_offset==0xFFFFFFFF) {
750 extra_data->u.al.get_list_length=0;
752 offset+=4;
754 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, ENC_BIG_ENDIAN);
755 extra_data->u.al.get_list_allocation_length=tvb_get_ntohl(tvb, offset);
756 offset+=4;
758 /* 4.12.5 */
759 extra_data->u.al.retrieved_list_offset=tvb_get_ntohl(tvb, offset);
760 dissect_osd_offset(pinfo,tvb,offset,tree,hf_scsi_osd_retrieved_attributes_offset,
761 &extra_data->u.al.retrieved_list_offset,osd2);
762 if (extra_data->u.al.retrieved_list_offset==0xFFFFFFFF) {
763 extra_data->u.al.get_list_allocation_length=0;
765 offset+=4;
767 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_list_length, tvb, offset, 4, ENC_BIG_ENDIAN);
768 extra_data->u.al.set_list_length=tvb_get_ntohl(tvb, offset);
769 offset+=4;
771 extra_data->u.al.set_list_offset=tvb_get_ntohl(tvb, offset);
772 dissect_osd_offset(pinfo,tvb,offset,tree,hf_scsi_osd_set_attributes_list_offset,
773 &extra_data->u.al.set_list_offset,osd2);
774 if (extra_data->u.al.set_list_offset==0xFFFFFFFF) {
775 extra_data->u.al.set_list_length=0;
777 offset+=4;
779 /* 4 reserved bytes */
780 offset+=4;
782 break;
784 return offset;
788 static void
789 dissect_osd_attribute_data_out(packet_info *pinfo, tvbuff_t *tvb, int offset _U_,
790 proto_tree *tree, scsi_task_data_t *cdata,
791 scsi_osd_lun_info_t *lun_info)
793 guint8 gsatype=0;
794 proto_tree *subtree;
795 proto_item *item;
796 scsi_osd_extra_data_t *extra_data=NULL;
798 if(cdata && cdata->itlq && cdata->itlq->extra_data){
799 extra_data=(scsi_osd_extra_data_t *)cdata->itlq->extra_data;
800 gsatype=extra_data->gsatype;
801 } else {
802 return;
805 switch(gsatype){
806 case 2: /* 5.2.2.2 attribute page */
807 /*qqq*/
808 break;
809 case 3: /* 5.2.2.3 attribute list */
810 if(extra_data->u.al.get_list_length){
811 item=proto_tree_add_text(tree, tvb, extra_data->u.al.get_list_offset, extra_data->u.al.get_list_length, "Get Attributes Segment");
812 subtree= proto_item_add_subtree(item, ett_osd_get_attributes);
813 dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.get_list_offset, subtree, lun_info, extra_data->osd2);
815 if(extra_data->u.al.set_list_length){
816 item=proto_tree_add_text(tree, tvb, extra_data->u.al.set_list_offset, extra_data->u.al.set_list_length, "Set Attributes Segment");
817 subtree= proto_item_add_subtree(item, ett_osd_set_attributes);
818 dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.set_list_offset, subtree, lun_info, extra_data->osd2);
820 break;
825 static void
826 dissect_osd_attribute_data_in(packet_info *pinfo, tvbuff_t *tvb, int offset _U_, proto_tree *tree, scsi_task_data_t *cdata, scsi_osd_lun_info_t *lun_info)
828 guint8 gsatype=0;
829 scsi_osd_extra_data_t *extra_data=NULL;
831 if(cdata && cdata->itlq && cdata->itlq->extra_data){
832 extra_data=(scsi_osd_extra_data_t *)cdata->itlq->extra_data;
833 gsatype=extra_data->gsatype;
834 } else {
835 return;
838 switch(gsatype){
839 case 2: /* 5.2.2.2 attribute page */
840 /*qqq*/
841 break;
842 case 3: /* 5.2.2.3 attribute list */
843 if(extra_data->u.al.get_list_allocation_length){
844 dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.retrieved_list_offset, tree, lun_info, extra_data->osd2);
846 break;
850 static void
851 dissect_osd2_cdb_continuation_length(packet_info *pinfo, tvbuff_t *tvb,
852 guint32 offset, proto_tree *tree,
853 scsi_task_data_t *cdata)
855 scsi_osd_extra_data_t *extra_data;
856 guint32 continuation_length;
857 proto_item* item;
859 continuation_length = tvb_get_ntohl(tvb,offset);
860 item=proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_length, tvb, offset, 4, ENC_BIG_ENDIAN);
861 if(cdata && cdata->itlq && cdata->itlq->extra_data){
862 extra_data=(scsi_osd_extra_data_t *)cdata->itlq->extra_data;
863 extra_data->continuation_length=continuation_length;
865 if (continuation_length>0&&continuation_length<40) {
866 expert_add_info(pinfo,item,&ei_osd2_cdb_continuation_length_invalid);
870 static void dissect_osd2_query_list_descriptor(packet_info *pinfo, tvbuff_t *tvb, guint32 offset, proto_tree *tree, guint32 length) {
871 guint32 end = offset+length;
873 /* query type */
874 proto_tree_add_item(tree, hf_scsi_osd2_query_type, tvb, offset, 1, ENC_BIG_ENDIAN);
875 offset++;
877 /* 3 reserved bytes */
878 offset+=3;
880 /*query criteria entry*/
881 while (offset<end) {
882 guint32 page, number;
883 guint32 min_value_length, max_value_length;
884 guint32 min_value_offset, max_value_offset;
885 const attribute_page_numbers_t *apn;
886 proto_item* item;
888 /* 2 reserved bytes */
889 offset+=2;
891 /* query entry length */
892 proto_tree_add_item(tree, hf_scsi_osd2_query_entry_length, tvb, offset, 2, ENC_BIG_ENDIAN);
893 offset+=2;
895 /* query attributes page */
896 page=tvb_get_ntohl(tvb, offset);
897 proto_tree_add_item(tree, hf_scsi_osd2_query_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
898 offset+=4;
900 /* query attributes number */
901 number=tvb_get_ntohl(tvb, offset);
902 item=proto_tree_add_item(tree, hf_scsi_osd2_query_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
903 offset+=4;
905 apn=osd_lookup_attribute(page,number);
907 if (!apn) {
908 expert_add_info(pinfo, item, &ei_osd_attr_unknown);
909 proto_item_append_text(item, " (Unknown)");
910 } else {
911 proto_item_append_text(item, " (%s)", apn->name);
914 /* query minimum attribute value length */
915 proto_tree_add_item(tree, hf_scsi_osd2_query_minimum_attribute_value_length, tvb, offset, 2, ENC_BIG_ENDIAN);
916 min_value_length=tvb_get_ntohs(tvb,offset);
917 offset+=2;
919 /* query minimum attribute value */
920 /* if(apn&&min_value_length) {
921 call_apn_dissector(tvb, pinfo, tree, lun_info, apn, offset, min_value_length);
922 } */
923 max_value_offset=offset;
924 offset+=min_value_length;
926 /* query maximum attribute value length */
927 item=proto_tree_add_item(tree, hf_scsi_osd2_query_maximum_attribute_value_length, tvb, offset, 2, ENC_BIG_ENDIAN);
928 max_value_length=tvb_get_ntohs(tvb,offset);
929 offset+=2;
931 /* xxx query maximum attribute value */
932 /* if(apn&&max_value_length) {
933 call_apn_dissector(tvb, pinfo, tree, lun_info, apn, offset, max_value_length);
934 } */
935 min_value_offset=offset;
936 offset+=max_value_length;
938 /* test if min and max values are equal */
939 if (max_value_length==min_value_length) {
940 unsigned int i;
941 for (i=0; i<max_value_length; i++) {
942 if (tvb_get_guint8(tvb,max_value_offset+i)!=tvb_get_guint8(tvb,min_value_offset+i)) return;
944 expert_add_info(pinfo,item,&ei_osd2_query_values_equal);
949 static void
950 dissect_osd2_cdb_continuation(packet_info *pinfo, tvbuff_t *tvb, guint32 offset,
951 proto_tree *tree, scsi_task_data_t *cdata)
953 scsi_osd_extra_data_t *extra_data=NULL;
954 proto_item* item;
955 guint8 format;
956 guint16 sa;
957 if(cdata && cdata->itlq && cdata->itlq->extra_data){
958 extra_data=(scsi_osd_extra_data_t *)cdata->itlq->extra_data;
960 if (!extra_data||extra_data->continuation_length<40) return;
962 /* cdb continuation format */
963 item=proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_format, tvb, offset, 1, ENC_BIG_ENDIAN);
964 format=tvb_get_guint8(tvb, offset);
965 if (format!=0x01) {
966 expert_add_info(pinfo, item, &ei_osd2_cdb_continuation_format_unknown);
967 return;
969 offset++;
971 /* 1 reserved byte */
972 offset++;
974 /* continued service action */
975 item=proto_tree_add_item(tree, hf_scsi_osd2_continued_service_action, tvb, offset, 2, ENC_BIG_ENDIAN);
976 sa = tvb_get_ntohs(tvb, offset);
977 if (sa!=extra_data->svcaction) {
978 expert_add_info(pinfo,item,&ei_osd2_continued_service_action_mismatch);
980 offset+=2;
982 /*4 reserved bytes and continuation integrity check value (32 bytes, not dissected)*/
983 offset+=36;
986 /* CDB continuation descriptors */
987 while (offset<extra_data->continuation_length) {
988 guint16 type;
989 guint32 length,padlen;
990 proto_item *item_type, *item_length;
992 /* descriptor type */
993 item_type= proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_descriptor_type, tvb, offset, 2, ENC_BIG_ENDIAN);
994 type=tvb_get_ntohs(tvb, offset);
995 offset+=2;
997 /* 1 reserved byte*/
998 offset++;
1000 /* descriptor pad length */
1001 proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_descriptor_pad_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1002 padlen=tvb_get_guint8(tvb, offset)&7;
1003 offset+=1;
1005 /* descriptor length */
1006 item_length = proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_descriptor_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1007 length=tvb_get_ntohl(tvb, offset);
1008 offset+=4;
1010 switch (type) {
1011 case 0x0000: break;
1012 case 0x0001: break;
1013 case 0x0002: dissect_osd2_query_list_descriptor(pinfo, tvb, offset, tree, length);
1014 case 0x0100: break;
1015 case 0x0101: break;
1016 case 0xFFEE: break;
1017 default: expert_add_info(pinfo,item_type,&ei_osd2_cdb_continuation_descriptor_type_unknown);
1020 if ((length+padlen)%8) {
1021 expert_add_info(pinfo,item_length,&ei_osd2_cdb_continuation_descriptor_length_invalid);
1022 return;
1024 offset+=length+padlen;
1030 static const value_string scsi_osd_capability_format_vals[] = {
1031 {0x00, "No Capability"},
1032 {0x01, "SCSI OSD Capabilities"},
1033 {0, NULL},
1035 static const value_string scsi_osd_object_type_vals[] = {
1036 {0x01, "ROOT"},
1037 {0x02, "PARTITION"},
1038 {0x40, "COLLECTION"},
1039 {0x80, "USER"},
1040 {0, NULL},
1042 static const value_string scsi_osd_object_descriptor_type_vals[] = {
1043 {0, "NONE: the object descriptor field shall be ignored"},
1044 {1, "U/C: a single collection or user object"},
1045 {2, "PAR: a single partition, including partition zero"},
1046 {0, NULL},
1050 /* OSD 4.9.2.2.1 */
1051 static void
1052 dissect_osd_permissions(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
1054 proto_tree *tree=NULL;
1055 proto_item *it=NULL;
1056 guint16 permissions;
1058 permissions=tvb_get_ntohs(tvb, offset);
1060 if(parent_tree){
1061 it=proto_tree_add_item(parent_tree, hf_scsi_osd_permissions, tvb, offset, 2, ENC_BIG_ENDIAN);
1062 tree = proto_item_add_subtree(it, ett_osd_permission_bitmask);
1065 proto_tree_add_item(tree, hf_scsi_osd_permissions_read, tvb, offset, 2, ENC_BIG_ENDIAN);
1066 if(permissions&0x8000){
1067 proto_item_append_text(tree, " READ");
1069 proto_tree_add_item(tree, hf_scsi_osd_permissions_write, tvb, offset, 2, ENC_BIG_ENDIAN);
1070 if(permissions&0x4000){
1071 proto_item_append_text(tree, " WRITE");
1073 proto_tree_add_item(tree, hf_scsi_osd_permissions_get_attr, tvb, offset, 2, ENC_BIG_ENDIAN);
1074 if(permissions&0x2000){
1075 proto_item_append_text(tree, " GET_ATTR");
1077 proto_tree_add_item(tree, hf_scsi_osd_permissions_set_attr, tvb, offset, 2, ENC_BIG_ENDIAN);
1078 if(permissions&0x1000){
1079 proto_item_append_text(tree, " SET_ATTR");
1081 proto_tree_add_item(tree, hf_scsi_osd_permissions_create, tvb, offset, 2, ENC_BIG_ENDIAN);
1082 if(permissions&0x0800){
1083 proto_item_append_text(tree, " CREATE");
1085 proto_tree_add_item(tree, hf_scsi_osd_permissions_remove, tvb, offset, 2, ENC_BIG_ENDIAN);
1086 if(permissions&0x0400){
1087 proto_item_append_text(tree, " REMOVE");
1089 proto_tree_add_item(tree, hf_scsi_osd_permissions_obj_mgmt, tvb, offset, 2, ENC_BIG_ENDIAN);
1090 if(permissions&0x0200){
1091 proto_item_append_text(tree, " OBJ_MGMT");
1093 proto_tree_add_item(tree, hf_scsi_osd_permissions_append, tvb, offset, 2, ENC_BIG_ENDIAN);
1094 if(permissions&0x0100){
1095 proto_item_append_text(tree, " APPEND");
1097 proto_tree_add_item(tree, hf_scsi_osd_permissions_dev_mgmt, tvb, offset, 2, ENC_BIG_ENDIAN);
1098 if(permissions&0x0080){
1099 proto_item_append_text(tree, " DEV_MGMT");
1101 proto_tree_add_item(tree, hf_scsi_osd_permissions_global, tvb, offset, 2, ENC_BIG_ENDIAN);
1102 if(permissions&0x0040){
1103 proto_item_append_text(tree, " GLOBAL");
1105 proto_tree_add_item(tree, hf_scsi_osd_permissions_pol_sec, tvb, offset, 2, ENC_BIG_ENDIAN);
1106 if(permissions&0x0020){
1107 proto_item_append_text(tree, " POL/SEC");
1111 /* OSD-1 4.9.2.2
1112 OSD-2 4.11.2.2 */
1113 static void
1114 dissect_osd_capability(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
1116 proto_item *item=NULL;
1117 proto_tree *tree=NULL;
1118 guint8 format;
1120 if(parent_tree){
1121 item = proto_tree_add_text(parent_tree, tvb, offset, 80,
1122 "Capability");
1123 tree = proto_item_add_subtree(item, ett_osd_capability);
1126 /* capability format */
1127 proto_tree_add_item(tree, hf_scsi_osd_capability_format, tvb, offset, 1, ENC_BIG_ENDIAN);
1128 format = tvb_get_guint8(tvb, offset)&0x0F;
1129 offset++;
1131 if (format!=1) return;
1133 /* key version and icva */
1134 proto_tree_add_item(tree, hf_scsi_osd_key_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1135 proto_tree_add_item(tree, hf_scsi_osd_icva, tvb, offset, 1, ENC_BIG_ENDIAN);
1136 offset++;
1138 /* security method */
1139 proto_tree_add_item(tree, hf_scsi_osd_security_method, tvb, offset, 1, ENC_BIG_ENDIAN);
1140 offset++;
1142 /* a reserved byte */
1143 offset++;
1145 /* capability expiration time */
1146 proto_tree_add_item(tree, hf_scsi_osd_capability_expiration_time, tvb, offset, 6, ENC_NA);
1147 offset+=6;
1149 /* audit */
1150 proto_tree_add_item(tree, hf_scsi_osd_audit, tvb, offset, 20, ENC_NA);
1151 offset+=20;
1153 /* capability discriminator */
1154 proto_tree_add_item(tree, hf_scsi_osd_capability_discriminator, tvb, offset, 12, ENC_NA);
1155 offset+=12;
1157 /* object created time */
1158 proto_tree_add_item(tree, hf_scsi_osd_object_created_time, tvb, offset, 6, ENC_NA);
1159 offset+=6;
1161 /* object type */
1162 proto_tree_add_item(tree, hf_scsi_osd_object_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1163 offset++;
1165 /* permission bitmask */
1166 dissect_osd_permissions(tvb, offset, tree);
1167 offset+=5;
1169 /* a reserved byte */
1170 offset++;
1172 /* object descriptor type */
1173 proto_tree_add_item(tree, hf_scsi_osd_object_descriptor_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1174 offset++;
1176 /* object descriptor */
1177 proto_tree_add_item(tree, hf_scsi_osd_object_descriptor, tvb, offset, 24, ENC_NA);
1178 /*offset+=24;*/
1180 return;
1185 /* 5.2.6 */
1186 static int
1187 dissect_osd_security_parameters(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
1189 proto_item *item=NULL;
1190 proto_tree *tree=NULL;
1192 if(parent_tree){
1193 item = proto_tree_add_text(parent_tree, tvb, offset, 40,
1194 "Security Parameters");
1195 tree = proto_item_add_subtree(item, ett_osd_security_parameters);
1198 /* request integrity check value */
1199 proto_tree_add_item(tree, hf_scsi_osd_ricv, tvb, offset, 20, ENC_NA);
1200 offset+=20;
1202 /* request nonce */
1203 proto_tree_add_item(tree, hf_scsi_osd_request_nonce, tvb, offset, 12, ENC_NA);
1204 offset+=12;
1206 /* data in integrity check value offset */
1207 proto_tree_add_item(tree, hf_scsi_osd_diicvo, tvb, offset, 4, ENC_BIG_ENDIAN);
1208 offset+=4;
1210 /* data out integrity check value offset */
1211 proto_tree_add_item(tree, hf_scsi_osd_doicvo, tvb, offset, 4, ENC_BIG_ENDIAN);
1212 offset+=4;
1214 return offset;
1217 static void
1218 dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1219 guint offset, gboolean isreq, gboolean iscdb,
1220 guint payload_len _U_, scsi_task_data_t *cdata _U_,
1221 scsi_osd_conv_info_t *conv_info _U_,
1222 scsi_osd_lun_info_t *lun_info _U_)
1224 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1225 if(isreq && iscdb){
1226 /* options byte */
1227 dissect_osd_option(tvb, offset, tree);
1228 offset++;
1230 /* getset attributes byte */
1231 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1232 offset++;
1234 /* timestamps control */
1235 dissect_osd_timestamps_control(tvb, offset, tree);
1236 offset++;
1238 /* 23 reserved bytes */
1239 offset+=23;
1241 /* formatted capacity */
1242 dissect_osd_formatted_capacity(tvb, offset, tree);
1243 offset+=8;
1245 /* 8 reserved bytes */
1246 offset+=8;
1248 /* attribute parameters */
1249 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1250 offset+=28;
1252 /* capability */
1253 dissect_osd_capability(tvb, offset, tree);
1254 offset+=80;
1256 /* security parameters */
1257 dissect_osd_security_parameters(tvb, offset, tree);
1258 offset+=40;
1261 /* dissecting the DATA OUT */
1262 if(isreq && !iscdb){
1263 /* attribute data out */
1264 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1266 /* no data out for format osd */
1269 /* dissecting the DATA IN */
1270 if(!isreq && !iscdb){
1271 /* attribute data in */
1272 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1274 /* no data in for format osd */
1280 static proto_item*
1281 dissect_osd_partition_id(packet_info *pinfo, tvbuff_t *tvb, int offset,
1282 proto_tree *tree, int hf_index,
1283 scsi_osd_lun_info_t *lun_info, gboolean is_created,
1284 gboolean is_removed)
1286 proto_item *item=NULL;
1287 guint32 partition_id[2];
1289 /* partition id */
1290 item=proto_tree_add_item(tree, hf_index, tvb, offset, 8, ENC_BIG_ENDIAN);
1291 partition_id[0]=tvb_get_ntohl(tvb, offset);
1292 partition_id[1]=tvb_get_ntohl(tvb, offset+4);
1293 if(!partition_id[0] && !partition_id[1]){
1294 proto_item_append_text(item, " (ROOT partition)");
1295 } else {
1296 partition_info_t *part_info;
1297 wmem_tree_key_t pikey[2];
1298 proto_tree *partition_tree=NULL;
1300 pikey[0].length=2;
1301 pikey[0].key=partition_id;
1302 pikey[1].length=0;
1303 part_info=(partition_info_t *)wmem_tree_lookup32_array(lun_info->partitions, &pikey[0]);
1304 if(!part_info){
1305 part_info=wmem_new(wmem_file_scope(), partition_info_t);
1306 part_info->created_in=0;
1307 part_info->removed_in=0;
1309 pikey[0].length=2;
1310 pikey[0].key=partition_id;
1311 pikey[1].length=0;
1312 wmem_tree_insert32_array(lun_info->partitions, &pikey[0], part_info);
1314 if(is_created){
1315 part_info->created_in=pinfo->fd->num;
1317 if(is_removed){
1318 part_info->removed_in=pinfo->fd->num;
1320 if(item){
1321 partition_tree=proto_item_add_subtree(item, ett_osd_partition);
1323 if(part_info->created_in){
1324 proto_item *tmp_item;
1325 tmp_item=proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_created_in, tvb, 0, 0, part_info->created_in);
1326 PROTO_ITEM_SET_GENERATED(tmp_item);
1328 if(part_info->removed_in){
1329 proto_item *tmp_item;
1330 tmp_item=proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_removed_in, tvb, 0, 0, part_info->removed_in);
1331 PROTO_ITEM_SET_GENERATED(tmp_item);
1335 return item;
1340 static void
1341 dissect_osd_create_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1342 guint offset, gboolean isreq, gboolean iscdb,
1343 guint payload_len _U_, scsi_task_data_t *cdata _U_,
1344 scsi_osd_conv_info_t *conv_info _U_,
1345 scsi_osd_lun_info_t *lun_info)
1347 gboolean osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
1348 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=osd2;
1350 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1351 if(isreq && iscdb){
1352 /* options byte */
1353 if (osd2) dissect_osd2_isolation(tvb,offset,tree);
1354 dissect_osd_option(tvb, offset, tree);
1355 offset++;
1357 /* getset attributes byte */
1358 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1359 offset++;
1361 /* timestamps control */
1362 dissect_osd_timestamps_control(tvb, offset, tree);
1363 offset++;
1365 /* 3 reserved bytes */
1366 offset+=3;
1368 /* requested partiton id */
1369 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_requested_partition_id, lun_info, TRUE, FALSE);
1370 offset+=8;
1372 /* 24 reserved bytes */
1373 offset+=24;
1375 if (osd2) {
1376 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
1377 } else {
1378 /* 4 reserved bytes */
1380 offset+=4;
1382 /* attribute parameters */
1383 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1384 offset+=28;
1386 /* capability */
1387 dissect_osd_capability(tvb, offset, tree);
1388 offset+=osd2?104:80;
1390 /* security parameters */
1391 dissect_osd_security_parameters(tvb, offset, tree);
1392 offset+=osd2?52:40;
1395 /* dissecting the DATA OUT */
1396 if(isreq && !iscdb){
1397 /* CDB continuation */
1398 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
1400 /* attribute data out */
1401 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1403 /* no data out for create partition */
1406 /* dissecting the DATA IN */
1407 if(!isreq && !iscdb){
1408 /* attribute data in */
1409 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1411 /* no data in for create partition */
1416 static const value_string scsi_osd_sort_order_vals[] = {
1417 {0x00, "Ascending numeric value"},
1418 {0, NULL},
1420 static int
1421 dissect_osd_sortorder(tvbuff_t *tvb, int offset, proto_tree *tree)
1423 /* sort order */
1424 proto_tree_add_item(tree, hf_scsi_osd_sortorder, tvb, offset, 1, ENC_BIG_ENDIAN);
1425 offset++;
1427 return offset;
1430 static int
1431 dissect_osd_list_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
1433 /* list identifier */
1434 proto_tree_add_item(tree, hf_scsi_osd_list_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
1435 offset+=4;
1437 return offset;
1440 static void
1441 dissect_osd_allocation_length(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
1443 /* allocation length */
1444 proto_tree_add_item(tree, hf_scsi_osd_allocation_length, tvb, offset, 8, ENC_BIG_ENDIAN);
1446 if (cdata) {
1447 guint64 alloc_len = tvb_get_ntoh64(tvb,offset);
1448 if (alloc_len>G_GINT64_CONSTANT(0xFFFFFFFF)) {
1449 alloc_len=G_GINT64_CONSTANT(0xFFFFFFFF);
1451 cdata->itlq->alloc_len=(guint32)alloc_len;
1455 static int
1456 dissect_osd_initial_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1458 /* initial object id */
1459 proto_tree_add_item(tree, hf_scsi_osd_initial_object_id, tvb, offset, 8, ENC_NA);
1460 offset+=8;
1462 return offset;
1465 static int
1466 dissect_osd_additional_length(tvbuff_t *tvb, int offset, proto_tree *tree)
1468 /* additional length */
1469 proto_tree_add_item(tree, hf_scsi_osd_additional_length, tvb, offset, 8, ENC_BIG_ENDIAN);
1470 offset+=8;
1472 return offset;
1476 static int
1477 dissect_osd_continuation_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1479 /* continuation object id */
1480 proto_tree_add_item(tree, hf_scsi_osd_continuation_object_id, tvb, offset, 8, ENC_NA);
1481 offset+=8;
1483 return offset;
1486 static const true_false_string list_lstchg_tfs = {
1487 "List has CHANGED since the first List command",
1488 "List has NOT changed since first command"
1490 static const true_false_string list_root_tfs = {
1491 "Objects are from root and are PARTITION IDs",
1492 "Objects are from the partition and are USER OBJECTs"
1494 static const true_false_string list_coltn_tfs = {
1495 "Objects are from the partition and are COLLECTION IDs",
1496 "Objects are from the collection and are USER OBJECTs"
1499 static proto_item*
1500 dissect_osd_collection_object_id(tvbuff_t *tvb, int offset, proto_tree *tree, const int hfindex)
1502 /* collection object id */
1503 proto_item* item;
1504 item = proto_tree_add_item(tree, hfindex, tvb, offset, 8, ENC_NA);
1505 return item;
1508 static void
1509 dissect_osd_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1510 guint offset, gboolean isreq, gboolean iscdb,
1511 guint payload_len _U_, scsi_task_data_t *cdata _U_,
1512 scsi_osd_conv_info_t *conv_info _U_,
1513 scsi_osd_lun_info_t *lun_info)
1515 guint svcaction = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction;
1516 gboolean list_collection = (svcaction==0x8817) || (svcaction==0x8897);
1517 gboolean osd2 = svcaction&0x80;
1518 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=osd2;
1520 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1522 if(isreq && iscdb){
1523 /*byte 10*/
1524 if (osd2) dissect_osd2_isolation(tvb,offset,tree);
1525 offset++;
1527 /* getset attributes byte / sort order */
1528 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1529 if (!list_collection) dissect_osd_sortorder(tvb, offset, tree);
1530 if (osd2) dissect_osd2_list_attr(tvb,offset,tree);
1531 offset++;
1533 /* timestamps control */
1534 dissect_osd_timestamps_control(tvb, offset, tree);
1535 offset++;
1537 /* 3 reserved bytes */
1538 offset+=3;
1540 /* partiton id */
1541 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1542 offset+=8;
1544 if (list_collection) {
1545 /* collection id */
1546 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
1547 } else {
1548 /* 8 reserved bytes */
1550 offset+=8;
1552 if (osd2) {
1553 /* allocation length */
1554 dissect_osd_allocation_length(tvb, offset, tree, cdata);
1555 offset+=8;
1557 /* initial object id */
1558 dissect_osd_initial_object_id(tvb, offset, tree);
1559 offset+=8;
1561 /* list identifier */
1562 dissect_osd_list_identifier(tvb, offset, tree);
1563 offset+=4;
1564 } else {
1565 /* list identifier */
1566 dissect_osd_list_identifier(tvb, offset, tree);
1567 offset+=4;
1569 /* allocation length */
1570 dissect_osd_allocation_length(tvb, offset, tree, cdata);
1571 offset+=8;
1573 /* initial object id */
1574 dissect_osd_initial_object_id(tvb, offset, tree);
1575 offset+=8;
1579 /* attribute parameters */
1580 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1581 offset+=28;
1583 /* capability */
1584 dissect_osd_capability(tvb, offset, tree);
1585 offset+=osd2?104:80;
1587 /* security parameters */
1588 dissect_osd_security_parameters(tvb, offset, tree);
1589 offset+=osd2?52:40;
1592 /* dissecting the DATA OUT */
1593 if(isreq && !iscdb){
1594 /* attribute data out */
1595 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1597 /* no data out for LIST or LIST COLLECTION */
1600 /* dissecting the DATA IN */
1601 if(!isreq && !iscdb){
1603 guint64 additional_length;
1604 guint64 allocation_length;
1605 guint64 remaining_length;
1606 gboolean is_root_or_coltn;
1607 guint8 format = 0;
1609 /* attribute data in */
1610 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1612 allocation_length=cdata->itlq->alloc_len;
1613 remaining_length=tvb_length_remaining(tvb, offset);
1614 if (remaining_length<allocation_length) allocation_length=remaining_length;
1615 if (allocation_length<24) return;
1617 /* dissection of the LIST or LIST COLLECTION DATA-IN */
1618 /* additional length */
1619 additional_length=tvb_get_ntoh64(tvb, offset);
1620 if (allocation_length<additional_length) additional_length=allocation_length;
1622 dissect_osd_additional_length(tvb, offset, tree);
1624 offset+=8;
1625 /* continuation object id */
1626 dissect_osd_continuation_object_id(tvb, offset, tree);
1627 offset+=8;
1628 /* list identifier */
1629 dissect_osd_list_identifier(tvb, offset, tree);
1630 offset+=4;
1631 /* 3 reserved bytes */
1632 offset+=3;
1634 /* OSD: LSTCHG and ROOT flags
1635 OSD2: LSTCHG and OBJECT DESCRIPTOR FORMAT*/
1636 proto_tree_add_item(tree, hf_scsi_osd_list_flags_lstchg, tvb, offset, 1, ENC_BIG_ENDIAN);
1637 if (osd2) {
1638 proto_item *item;
1639 item = proto_tree_add_item(tree, hf_scsi_osd2_object_descriptor_format, tvb, offset, 1, ENC_BIG_ENDIAN);
1640 format = tvb_get_guint8(tvb, offset)>>2;
1641 if (format==0x01||format==0x02) {
1642 is_root_or_coltn=TRUE;
1643 if (list_collection) format=0;
1644 } else if (format==0x11||format==0x12) {
1645 is_root_or_coltn=TRUE;
1646 if (!list_collection) format=0;
1647 } else if (format==0x21||format==0x22) {
1648 is_root_or_coltn=FALSE;
1649 } else format=0;
1650 if (!format) {
1651 expert_add_info(pinfo,item,&ei_osd2_invalid_object_descriptor_format);
1652 return;
1654 } else {
1655 if (list_collection) {
1656 proto_tree_add_item(tree, hf_scsi_osd_list_collection_flags_coltn, tvb, offset, 1, ENC_BIG_ENDIAN);
1657 } else {
1658 proto_tree_add_item(tree, hf_scsi_osd_list_flags_root, tvb, offset, 1, ENC_BIG_ENDIAN);
1660 is_root_or_coltn=tvb_get_guint8(tvb, offset)&0x01;
1663 offset++;
1665 while(additional_length > (offset-8)) {
1666 proto_item *ti;
1667 /* list of 8-byte IDs; the type of ID is given by is_root_or_coltn and list_collection*/
1668 if(is_root_or_coltn){
1669 if (list_collection){
1670 ti=dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
1671 } else {
1672 ti=dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1674 } else {
1675 ti=dissect_osd_user_object_id(tvb, offset, tree);
1677 offset+=8;
1679 /* for OSD-2 if format is 0x02, 0x12 or 0x22: sub-list of attributes*/
1680 if (osd2&&(format&0x02)) {
1681 guint32 attr_list_end;
1682 proto_tree *subtree;
1684 if (offset+8>additional_length) break;
1685 subtree = proto_item_add_subtree(ti, ett_osd_multi_object);
1687 /*object type*/
1688 proto_tree_add_item(subtree, hf_scsi_osd_object_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1689 offset++;
1690 /* 5 reserved bytes */
1691 offset+=5;
1692 /* attribute list length*/
1693 attr_list_end=offset+2+tvb_get_ntohs(tvb, offset);
1694 offset+=2;
1695 if (attr_list_end>additional_length+8) break;
1696 while (offset+16<attr_list_end) {
1697 guint32 attribute_length=tvb_get_ntohs(tvb, offset+14);
1698 proto_item *att_item = proto_tree_add_text(subtree, tvb, offset, 16+attribute_length, "Attribute:");
1699 proto_tree *att_tree = proto_item_add_subtree(att_item, ett_osd_attribute);
1700 offset=dissect_osd_attribute_list_entry(pinfo,tvb,att_tree,att_item,offset,lun_info,TRUE);
1702 offset=attr_list_end;
1710 static int
1711 dissect_osd_requested_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1713 /* request user object id */
1714 proto_tree_add_item(tree, hf_scsi_osd_requested_user_object_id, tvb, offset, 8, ENC_NA);
1715 offset+=8;
1717 return offset;
1720 static int
1721 dissect_osd_number_of_user_objects(tvbuff_t *tvb, int offset, proto_tree *tree)
1723 /* number_of_user_objects */
1724 proto_tree_add_item(tree, hf_scsi_osd_number_of_user_objects, tvb, offset, 2, ENC_BIG_ENDIAN);
1725 offset+=2;
1727 return offset;
1730 static void
1731 dissect_osd_create(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1732 guint offset, gboolean isreq, gboolean iscdb,
1733 guint payload_len _U_, scsi_task_data_t *cdata _U_,
1734 scsi_osd_conv_info_t *conv_info _U_,
1735 scsi_osd_lun_info_t *lun_info)
1737 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1738 if(isreq && iscdb){
1739 /* options byte */
1740 dissect_osd_option(tvb, offset, tree);
1741 offset++;
1743 /* getset attributes byte */
1744 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1745 offset++;
1747 /* timestamps control */
1748 dissect_osd_timestamps_control(tvb, offset, tree);
1749 offset++;
1751 /* 3 reserved bytes */
1752 offset+=3;
1754 /* partiton id */
1755 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1756 offset+=8;
1758 /* requested user_object id */
1759 dissect_osd_requested_user_object_id(tvb, offset, tree);
1760 offset+=8;
1762 /* 4 reserved bytes */
1763 offset+=4;
1765 /* number of user objects */
1766 dissect_osd_number_of_user_objects(tvb, offset, tree);
1767 offset+=2;
1769 /* 14 reserved bytes */
1770 offset+=14;
1772 /* attribute parameters */
1773 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1774 offset+=28;
1776 /* capability */
1777 dissect_osd_capability(tvb, offset, tree);
1778 offset+=80;
1780 /* security parameters */
1781 dissect_osd_security_parameters(tvb, offset, tree);
1782 offset+=40;
1785 /* dissecting the DATA OUT */
1786 if(isreq && !iscdb){
1787 /* attribute data out */
1788 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1790 /* no data out for create */
1793 /* dissecting the DATA IN */
1794 if(!isreq && !iscdb){
1795 /* attribute data in */
1796 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1798 /* no data in for create */
1804 static void
1805 dissect_osd_remove_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1806 guint offset, gboolean isreq, gboolean iscdb,
1807 guint payload_len _U_, scsi_task_data_t *cdata _U_,
1808 scsi_osd_conv_info_t *conv_info _U_,
1809 scsi_osd_lun_info_t *lun_info)
1811 gboolean osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
1812 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=osd2;
1814 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1815 if(isreq && iscdb){
1816 /* options byte */
1817 if (osd2) dissect_osd2_isolation(tvb,offset,tree);
1818 dissect_osd_option(tvb, offset, tree);
1819 offset++;
1821 /* getset attributes byte */
1822 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1823 if (osd2) proto_tree_add_item(tree, hf_scsi_osd2_remove_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
1824 offset++;
1826 /* timestamps control */
1827 dissect_osd_timestamps_control(tvb, offset, tree);
1828 offset++;
1830 /* 3 reserved bytes */
1831 offset+=3;
1833 /* partiton id */
1834 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, TRUE);
1835 offset+=8;
1837 /* 24 reserved bytes */
1838 offset+=24;
1840 if (osd2) {
1841 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
1842 } else {
1843 /* 4 reserved bytes */
1845 offset+=4;
1847 /* attribute parameters */
1848 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1849 offset+=28;
1851 /* capability */
1852 dissect_osd_capability(tvb, offset, tree);
1853 offset+=osd2?104:80;
1855 /* security parameters */
1856 dissect_osd_security_parameters(tvb, offset, tree);
1857 offset+=osd2?52:40;
1860 /* dissecting the DATA OUT */
1861 if(isreq && !iscdb){
1862 /* CDB continuation */
1863 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
1865 /* attribute data out */
1866 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1868 /* no data out for remove partition */
1871 /* dissecting the DATA IN */
1872 if(!isreq && !iscdb){
1873 /* attribute data in */
1874 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1876 /* no data in for remove partition */
1881 static const value_string key_to_set_vals[] = {
1882 {1, "Root"},
1883 {2, "Partition"},
1884 {3, "Working"},
1885 {0, NULL},
1887 static void
1888 dissect_osd_key_to_set(tvbuff_t *tvb, int offset, proto_tree *tree)
1890 proto_tree_add_item(tree, hf_scsi_osd_key_to_set, tvb, offset, 1, ENC_BIG_ENDIAN);
1893 static void
1894 dissect_osd_set_key_version(tvbuff_t *tvb, int offset, proto_tree *tree)
1896 proto_tree_add_item(tree, hf_scsi_osd_set_key_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1899 static void
1900 dissect_osd_key_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
1902 proto_tree_add_item(tree, hf_scsi_osd_key_identifier, tvb, offset, 7, ENC_NA);
1905 static void
1906 dissect_osd_seed(tvbuff_t *tvb, int offset, proto_tree *tree)
1908 proto_tree_add_item(tree, hf_scsi_osd_seed, tvb, offset, 20, ENC_NA);
1911 static void
1912 dissect_osd_set_key(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1913 guint offset, gboolean isreq, gboolean iscdb,
1914 guint payload_len _U_, scsi_task_data_t *cdata _U_,
1915 scsi_osd_conv_info_t *conv_info _U_,
1916 scsi_osd_lun_info_t *lun_info)
1918 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1919 if(isreq && iscdb){
1920 /* a reserved byte */
1921 offset++;
1923 /* getset attributes byte and key to set*/
1924 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1925 dissect_osd_key_to_set(tvb, offset, tree);
1926 offset++;
1928 /* timestamps control */
1929 dissect_osd_timestamps_control(tvb, offset, tree);
1930 offset++;
1932 /* 3 reserved bytes */
1933 offset+=3;
1935 /* partiton id */
1936 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
1937 offset+=8;
1939 /* key version */
1940 dissect_osd_set_key_version(tvb, offset, tree);
1941 offset++;
1943 /* key identifier */
1944 dissect_osd_key_identifier(tvb, offset, tree);
1945 offset+=7;
1947 /* seed */
1948 dissect_osd_seed(tvb, offset, tree);
1949 offset+=20;
1951 /* attribute parameters */
1952 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1953 offset+=28;
1955 /* capability */
1956 dissect_osd_capability(tvb, offset, tree);
1957 offset+=80;
1959 /* security parameters */
1960 dissect_osd_security_parameters(tvb, offset, tree);
1961 offset+=40;
1964 /* dissecting the DATA OUT */
1965 if(isreq && !iscdb){
1966 /* attribute data out */
1967 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1969 /* no data out for set key */
1972 /* dissecting the DATA IN */
1973 if(!isreq && !iscdb){
1974 /* attribute data in */
1975 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1977 /* no data in for set key */
1982 static void
1983 dissect_osd_remove(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1984 guint offset, gboolean isreq, gboolean iscdb,
1985 guint payload_len _U_, scsi_task_data_t *cdata _U_,
1986 scsi_osd_conv_info_t *conv_info _U_,
1987 scsi_osd_lun_info_t *lun_info)
1989 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1990 if(isreq && iscdb){
1991 /* options byte */
1992 dissect_osd_option(tvb, offset, tree);
1993 offset++;
1995 /* getset attributes byte */
1996 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1997 offset++;
1999 /* timestamps control */
2000 dissect_osd_timestamps_control(tvb, offset, tree);
2001 offset++;
2003 /* 3 reserved bytes */
2004 offset+=3;
2006 /* partiton id */
2007 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2008 offset+=8;
2010 /* user object id */
2011 dissect_osd_user_object_id(tvb, offset, tree);
2012 offset+=8;
2014 /* 20 reserved bytes */
2015 offset+=20;
2017 /* attribute parameters */
2018 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2019 offset+=28;
2021 /* capability */
2022 dissect_osd_capability(tvb, offset, tree);
2023 offset+=80;
2025 /* security parameters */
2026 dissect_osd_security_parameters(tvb, offset, tree);
2027 offset+=40;
2030 /* dissecting the DATA OUT */
2031 if(isreq && !iscdb){
2032 /* attribute data out */
2033 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2035 /* no data out for remove */
2038 /* dissecting the DATA IN */
2039 if(!isreq && !iscdb){
2040 /* attribute data in */
2041 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2043 /* no data in for remove */
2048 static void
2049 dissect_osd_collection_fcr(tvbuff_t *tvb, int offset, proto_tree *tree)
2051 proto_tree_add_item(tree, hf_scsi_osd_collection_fcr, tvb, offset, 1, ENC_BIG_ENDIAN);
2054 static void
2055 dissect_osd_remove_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2056 guint offset, gboolean isreq, gboolean iscdb,
2057 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2058 scsi_osd_conv_info_t *conv_info _U_,
2059 scsi_osd_lun_info_t *lun_info)
2061 gboolean osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
2062 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=osd2;
2064 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2065 if(isreq && iscdb){
2066 /* options byte */
2067 dissect_osd_option(tvb, offset, tree);
2068 offset++;
2070 /* getset attributes byte */
2071 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2072 dissect_osd_collection_fcr(tvb, offset, tree);
2073 offset++;
2075 /* timestamps control */
2076 dissect_osd_timestamps_control(tvb, offset, tree);
2077 offset++;
2079 /* 3 reserved bytes */
2080 offset+=3;
2082 /* partiton id */
2083 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2084 offset+=8;
2086 /* collection object id */
2087 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
2088 offset+=8;
2090 /* 16 reserved bytes */
2091 offset+=16;
2093 if (osd2) {
2094 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
2095 } else {
2096 /* 4 reserved bytes */
2098 offset+=4;
2100 /* attribute parameters */
2101 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2102 offset+=28;
2104 /* capability */
2105 dissect_osd_capability(tvb, offset, tree);
2106 offset+=osd2?104:80;
2108 /* security parameters */
2109 dissect_osd_security_parameters(tvb, offset, tree);
2110 offset+=osd2?52:40;
2113 /* dissecting the DATA OUT */
2114 if(isreq && !iscdb){
2115 /* CDB continuation */
2116 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
2118 /* attribute data out */
2119 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2121 /* no data out for remove collection */
2124 /* dissecting the DATA IN */
2125 if(!isreq && !iscdb){
2126 /* attribute data in */
2127 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2129 /* no data in for remove collection */
2135 static int
2136 dissect_osd_length(tvbuff_t *tvb, int offset, proto_tree *tree)
2138 /* length */
2139 proto_tree_add_item(tree, hf_scsi_osd_length, tvb, offset, 8, ENC_BIG_ENDIAN);
2140 offset+=8;
2142 return offset;
2145 static int
2146 dissect_osd_starting_byte_address(tvbuff_t *tvb, int offset, proto_tree *tree)
2148 /* starting_byte_address */
2149 proto_tree_add_item(tree, hf_scsi_osd_starting_byte_address, tvb, offset, 8, ENC_BIG_ENDIAN);
2150 offset+=8;
2152 return offset;
2156 static void
2157 dissect_osd_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2158 guint offset, gboolean isreq, gboolean iscdb,
2159 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2160 scsi_osd_conv_info_t *conv_info _U_,
2161 scsi_osd_lun_info_t *lun_info)
2163 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2164 if(isreq && iscdb){
2165 /* options byte */
2166 dissect_osd_option(tvb, offset, tree);
2167 offset++;
2169 /* getset attributes byte / sort order */
2170 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2171 offset++;
2173 /* timestamps control */
2174 dissect_osd_timestamps_control(tvb, offset, tree);
2175 offset++;
2177 /* 3 reserved bytes */
2178 offset+=3;
2180 /* partiton id */
2181 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2182 offset+=8;
2184 /* user object id */
2185 dissect_osd_user_object_id(tvb, offset, tree);
2186 offset+=8;
2188 /* 4 reserved bytes */
2189 offset+=4;
2191 /* length */
2192 dissect_osd_length(tvb, offset, tree);
2193 offset+=8;
2195 /* starting byte address */
2196 dissect_osd_starting_byte_address(tvb, offset, tree);
2197 offset+=8;
2199 /* attribute parameters */
2200 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2201 offset+=28;
2203 /* capability */
2204 dissect_osd_capability(tvb, offset, tree);
2205 offset+=80;
2207 /* security parameters */
2208 dissect_osd_security_parameters(tvb, offset, tree);
2209 offset+=40;
2212 /* dissecting the DATA OUT */
2213 if(isreq && !iscdb){
2214 /* attribute data out */
2215 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2217 /* xxx should dissect the data ? */
2220 /* dissecting the DATA IN */
2221 if(!isreq && !iscdb){
2222 /* attribute data in */
2223 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2225 /* no data in for WRITE */
2230 static void
2231 dissect_osd_create_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2232 guint offset, gboolean isreq, gboolean iscdb,
2233 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2234 scsi_osd_conv_info_t *conv_info _U_,
2235 scsi_osd_lun_info_t *lun_info)
2237 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2238 if(isreq && iscdb){
2239 /* options byte */
2240 dissect_osd_option(tvb, offset, tree);
2241 offset++;
2243 /* getset attributes byte */
2244 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2245 dissect_osd_collection_fcr(tvb, offset, tree);
2246 offset++;
2248 /* timestamps control */
2249 dissect_osd_timestamps_control(tvb, offset, tree);
2250 offset++;
2252 /* 3 reserved bytes */
2253 offset+=3;
2255 /* partiton id */
2256 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2257 offset+=8;
2259 /* requested collection object id */
2260 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_requested_collection_object_id);
2261 offset+=8;
2263 /* 20 reserved bytes */
2264 offset+=20;
2266 /* attribute parameters */
2267 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2268 offset+=28;
2270 /* capability */
2271 dissect_osd_capability(tvb, offset, tree);
2272 offset+=80;
2274 /* security parameters */
2275 dissect_osd_security_parameters(tvb, offset, tree);
2276 offset+=40;
2279 /* dissecting the DATA OUT */
2280 if(isreq && !iscdb){
2281 /* attribute data out */
2282 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2284 /* no data out for create collection */
2287 /* dissecting the DATA IN */
2288 if(!isreq && !iscdb){
2289 /* attribute data in */
2290 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2292 /* no data in for create collection */
2298 static const value_string flush_scope_vals[] = {
2299 {0, "User object data and attributes"},
2300 {1, "User object attributes only"},
2301 {0, NULL}
2304 static int
2305 dissect_osd_flush_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2307 /* flush scope */
2308 proto_tree_add_item(tree, hf_scsi_osd_flush_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2309 offset++;
2311 return offset;
2314 static void
2315 dissect_osd_flush(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2316 guint offset, gboolean isreq, gboolean iscdb,
2317 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2318 scsi_osd_conv_info_t *conv_info _U_,
2319 scsi_osd_lun_info_t *lun_info)
2321 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2322 if(isreq && iscdb){
2323 /* options byte */
2324 dissect_osd_flush_scope(tvb, offset, tree);
2325 offset++;
2327 /* getset attributes byte */
2328 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2329 offset++;
2331 /* timestamps control */
2332 dissect_osd_timestamps_control(tvb, offset, tree);
2333 offset++;
2335 /* 3 reserved bytes */
2336 offset+=3;
2338 /* partiton id */
2339 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2340 offset+=8;
2342 /* user object id */
2343 dissect_osd_user_object_id(tvb, offset, tree);
2344 offset+=8;
2346 /* 20 reserved bytes */
2347 offset+=20;
2349 /* attribute parameters */
2350 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2351 offset+=28;
2353 /* capability */
2354 dissect_osd_capability(tvb, offset, tree);
2355 offset+=80;
2357 /* security parameters */
2358 dissect_osd_security_parameters(tvb, offset, tree);
2359 offset+=40;
2362 /* dissecting the DATA OUT */
2363 if(isreq && !iscdb){
2364 /* attribute data out */
2365 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2367 /* no data out for flush */
2370 /* dissecting the DATA IN */
2371 if(!isreq && !iscdb){
2372 /* attribute data in */
2373 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2375 /* no data in for flush */
2381 static const value_string flush_collection_scope_vals[] = {
2382 {0, "List of user objects contained in the collection"},
2383 {1, "Collection attributes only"},
2384 {2, "List of user objects and collection attributes"},
2385 {0, NULL}
2388 static int
2389 dissect_osd_flush_collection_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2391 /* flush collection scope */
2392 proto_tree_add_item(tree, hf_scsi_osd_flush_collection_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2393 offset++;
2395 return offset;
2398 static void
2399 dissect_osd_flush_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2400 guint offset, gboolean isreq, gboolean iscdb,
2401 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2402 scsi_osd_conv_info_t *conv_info _U_,
2403 scsi_osd_lun_info_t *lun_info)
2405 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2406 if(isreq && iscdb){
2407 /* options byte */
2408 dissect_osd_flush_collection_scope(tvb, offset, tree);
2409 offset++;
2411 /* getset attributes byte */
2412 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2413 dissect_osd_collection_fcr(tvb, offset, tree);
2414 offset++;
2416 /* timestamps control */
2417 dissect_osd_timestamps_control(tvb, offset, tree);
2418 offset++;
2420 /* 3 reserved bytes */
2421 offset+=3;
2423 /* partiton id */
2424 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2425 offset+=8;
2427 /* collection object id */
2428 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
2429 offset+=8;
2431 /* 20 reserved bytes */
2432 offset+=20;
2434 /* attribute parameters */
2435 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2436 offset+=28;
2438 /* capability */
2439 dissect_osd_capability(tvb, offset, tree);
2440 offset+=80;
2442 /* security parameters */
2443 dissect_osd_security_parameters(tvb, offset, tree);
2444 offset+=40;
2447 /* dissecting the DATA OUT */
2448 if(isreq && !iscdb){
2449 /* attribute data out */
2450 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2452 /* no data out for flush collection */
2455 /* dissecting the DATA IN */
2456 if(!isreq && !iscdb){
2457 /* attribute data in */
2458 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2460 /* no data in for flush collection */
2466 static void
2467 dissect_osd_append(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2468 guint offset, gboolean isreq, gboolean iscdb,
2469 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2470 scsi_osd_conv_info_t *conv_info _U_,
2471 scsi_osd_lun_info_t *lun_info)
2473 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2474 if(isreq && iscdb){
2475 /* options byte */
2476 dissect_osd_option(tvb, offset, tree);
2477 offset++;
2479 /* getset attributes byte */
2480 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2481 offset++;
2483 /* timestamps control */
2484 dissect_osd_timestamps_control(tvb, offset, tree);
2485 offset++;
2487 /* 3 reserved bytes */
2488 offset+=3;
2490 /* partiton id */
2491 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2492 offset+=8;
2494 /* user object id */
2495 dissect_osd_user_object_id(tvb, offset, tree);
2496 offset+=8;
2498 /* 4 reserved bytes */
2499 offset+=4;
2501 /* length */
2502 dissect_osd_length(tvb, offset, tree);
2503 offset+=8;
2505 /* 8 reserved bytes */
2506 offset+=8;
2508 /* attribute parameters */
2509 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2510 offset+=28;
2512 /* capability */
2513 dissect_osd_capability(tvb, offset, tree);
2514 offset+=80;
2516 /* security parameters */
2517 dissect_osd_security_parameters(tvb, offset, tree);
2518 offset+=40;
2521 /* dissecting the DATA OUT */
2522 if(isreq && !iscdb){
2523 /* attribute data out */
2524 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2526 /* xxx should dissect the data ? */
2529 /* dissecting the DATA IN */
2530 if(!isreq && !iscdb){
2531 /* attribute data in */
2532 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2534 /* no data in for append */
2539 static void
2540 dissect_osd_create_and_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2541 guint offset, gboolean isreq, gboolean iscdb,
2542 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2543 scsi_osd_conv_info_t *conv_info _U_,
2544 scsi_osd_lun_info_t *lun_info)
2546 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2547 if(isreq && iscdb){
2548 /* options byte */
2549 dissect_osd_option(tvb, offset, tree);
2550 offset++;
2552 /* getset attributes byte */
2553 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2554 offset++;
2556 /* timestamps control */
2557 dissect_osd_timestamps_control(tvb, offset, tree);
2558 offset++;
2560 /* 3 reserved bytes */
2561 offset+=3;
2563 /* partiton id */
2564 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2565 offset+=8;
2567 /* requested user_object id */
2568 dissect_osd_requested_user_object_id(tvb, offset, tree);
2569 offset+=8;
2571 /* 4 reserved bytes */
2572 offset+=4;
2574 /* length */
2575 dissect_osd_length(tvb, offset, tree);
2576 offset+=8;
2578 /* starting byte address */
2579 dissect_osd_starting_byte_address(tvb, offset, tree);
2580 offset+=8;
2582 /* attribute parameters */
2583 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2584 offset+=28;
2586 /* capability */
2587 dissect_osd_capability(tvb, offset, tree);
2588 offset+=80;
2590 /* security parameters */
2591 dissect_osd_security_parameters(tvb, offset, tree);
2592 offset+=40;
2595 /* dissecting the DATA OUT */
2596 if(isreq && !iscdb){
2597 /* attribute data out */
2598 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2600 /* should we dissect the data? */
2603 /* dissecting the DATA IN */
2604 if(!isreq && !iscdb){
2605 /* attribute data in */
2606 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2608 /* no data in for create and write*/
2614 static const value_string flush_osd_scope_vals[] = {
2615 {0, "List of partitions contained in the OSD logical unit"},
2616 {1, "Root object attributes only"},
2617 {2, "Everything"},
2618 {0, NULL}
2621 static int
2622 dissect_osd_flush_osd_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2624 /* flush osd scope */
2625 proto_tree_add_item(tree, hf_scsi_osd_flush_osd_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2626 offset++;
2628 return offset;
2631 static void
2632 dissect_osd_flush_osd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2633 guint offset, gboolean isreq, gboolean iscdb,
2634 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2635 scsi_osd_conv_info_t *conv_info _U_,
2636 scsi_osd_lun_info_t *lun_info _U_)
2638 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2639 if(isreq && iscdb){
2640 /* options byte */
2641 dissect_osd_flush_osd_scope(tvb, offset, tree);
2642 offset++;
2644 /* getset attributes byte */
2645 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2646 offset++;
2648 /* timestamps control */
2649 dissect_osd_timestamps_control(tvb, offset, tree);
2650 offset++;
2652 /* 39 reserved bytes */
2653 offset+=39;
2655 /* attribute parameters */
2656 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2657 offset+=28;
2659 /* capability */
2660 dissect_osd_capability(tvb, offset, tree);
2661 offset+=80;
2663 /* security parameters */
2664 dissect_osd_security_parameters(tvb, offset, tree);
2665 offset+=40;
2668 /* dissecting the DATA OUT */
2669 if(isreq && !iscdb){
2670 /* attribute data out */
2671 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2673 /* no data out for flush osd */
2676 /* dissecting the DATA IN */
2677 if(!isreq && !iscdb){
2678 /* attribute data in */
2679 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2681 /* no data in for flush osd */
2687 static const value_string flush_partition_scope_vals[] = {
2688 {0, "List of user objects and collections in the partition"},
2689 {1, "Partition attributes only"},
2690 {2, "Everything"},
2691 {0, NULL}
2694 static int
2695 dissect_osd_flush_partition_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2697 /* flush partition scope */
2698 proto_tree_add_item(tree, hf_scsi_osd_flush_partition_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2699 offset++;
2701 return offset;
2705 static void
2706 dissect_osd_flush_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2707 guint offset, gboolean isreq, gboolean iscdb,
2708 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2709 scsi_osd_conv_info_t *conv_info _U_,
2710 scsi_osd_lun_info_t *lun_info)
2712 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2713 if(isreq && iscdb){
2714 /* options byte */
2715 dissect_osd_flush_partition_scope(tvb, offset, tree);
2716 offset++;
2718 /* getset attributes byte */
2719 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2720 offset++;
2722 /* timestamps control */
2723 dissect_osd_timestamps_control(tvb, offset, tree);
2724 offset++;
2726 /* 3 reserved bytes */
2727 offset+=3;
2729 /* partiton id */
2730 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2731 offset+=8;
2733 /* 28 reserved bytes */
2734 offset+=28;
2736 /* attribute parameters */
2737 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2738 offset+=28;
2740 /* capability */
2741 dissect_osd_capability(tvb, offset, tree);
2742 offset+=80;
2744 /* security parameters */
2745 dissect_osd_security_parameters(tvb, offset, tree);
2746 offset+=40;
2749 /* dissecting the DATA OUT */
2750 if(isreq && !iscdb){
2751 /* attribute data out */
2752 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2754 /* no data out for flush partition */
2757 /* dissecting the DATA IN */
2758 if(!isreq && !iscdb){
2759 /* attribute data in */
2760 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2762 /* no data in for flush partition */
2768 static void
2769 dissect_osd_get_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2770 guint offset, gboolean isreq, gboolean iscdb,
2771 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2772 scsi_osd_conv_info_t *conv_info _U_,
2773 scsi_osd_lun_info_t *lun_info)
2775 gboolean osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
2776 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=osd2;
2778 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2779 if(isreq && iscdb){
2780 /* options byte */
2781 dissect_osd_option(tvb, offset, tree);
2782 offset++;
2784 /* getset attributes byte */
2785 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2786 offset++;
2788 /* timestamps control */
2789 dissect_osd_timestamps_control(tvb, offset, tree);
2790 offset++;
2792 /* 3 reserved bytes */
2793 offset+=3;
2795 /* partiton id */
2796 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2797 offset+=8;
2799 /* user_object id */
2800 dissect_osd_user_object_id(tvb, offset, tree);
2801 offset+=8;
2803 /* 16 reserved bytes */
2804 offset+=16;
2806 if (osd2) {
2807 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
2808 } else {
2809 /* 4 reserved bytes */
2811 offset+=4;
2813 /* attribute parameters */
2814 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2815 offset+=28;
2817 /* capability */
2818 dissect_osd_capability(tvb, offset, tree);
2819 offset+=osd2?104:80;
2821 /* security parameters */
2822 dissect_osd_security_parameters(tvb, offset, tree);
2823 offset+=osd2?52:40;
2826 /* dissecting the DATA OUT */
2827 if(isreq && !iscdb){
2828 /* attribute data out */
2829 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2831 /* no data out for get attributes */
2834 /* dissecting the DATA IN */
2835 if(!isreq && !iscdb){
2836 /* attribute data in */
2837 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2839 /* no data in for get attributes */
2845 static void
2846 dissect_osd_read(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2847 guint offset, gboolean isreq, gboolean iscdb,
2848 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2849 scsi_osd_conv_info_t *conv_info _U_,
2850 scsi_osd_lun_info_t *lun_info)
2852 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2853 if(isreq && iscdb){
2854 /* options byte */
2855 dissect_osd_option(tvb, offset, tree);
2856 offset++;
2858 /* getset attributes byte / sort order */
2859 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2860 offset++;
2862 /* timestamps control */
2863 dissect_osd_timestamps_control(tvb, offset, tree);
2864 offset++;
2866 /* 3 reserved bytes */
2867 offset+=3;
2869 /* partiton id */
2870 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2871 offset+=8;
2873 /* user object id */
2874 dissect_osd_user_object_id(tvb, offset, tree);
2875 offset+=8;
2877 /* 4 reserved bytes */
2878 offset+=4;
2880 /* length */
2881 dissect_osd_length(tvb, offset, tree);
2882 offset+=8;
2884 /* starting byte address */
2885 dissect_osd_starting_byte_address(tvb, offset, tree);
2886 offset+=8;
2888 /* attribute parameters */
2889 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2890 offset+=28;
2892 /* capability */
2893 dissect_osd_capability(tvb, offset, tree);
2894 offset+=80;
2896 /* security parameters */
2897 dissect_osd_security_parameters(tvb, offset, tree);
2898 offset+=40;
2901 /* dissecting the DATA OUT */
2902 if(isreq && !iscdb){
2903 /* attribute data out */
2904 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2906 /* no data out for READ */
2909 /* dissecting the DATA IN */
2910 if(!isreq && !iscdb){
2911 /* attribute data in */
2912 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2914 /* xxx should dissect the data ? */
2920 static void
2921 dissect_osd_set_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2922 guint offset, gboolean isreq, gboolean iscdb,
2923 guint payload_len _U_, scsi_task_data_t *cdata _U_,
2924 scsi_osd_conv_info_t *conv_info _U_,
2925 scsi_osd_lun_info_t *lun_info)
2927 gboolean osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
2928 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=osd2;
2930 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2931 if(isreq && iscdb){
2932 /* options byte */
2933 dissect_osd_option(tvb, offset, tree);
2934 offset++;
2936 /* getset attributes byte */
2937 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2938 offset++;
2940 /* timestamps control */
2941 dissect_osd_timestamps_control(tvb, offset, tree);
2942 offset++;
2944 /* 3 reserved bytes */
2945 offset+=3;
2947 /* partiton id */
2948 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
2949 offset+=8;
2951 /* user_object id */
2952 dissect_osd_user_object_id(tvb, offset, tree);
2953 offset+=8;
2955 /* 16 reserved bytes */
2956 offset+=16;
2958 if (osd2) {
2959 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
2960 } else {
2961 /* 4 reserved bytes */
2963 offset+=4;
2965 /* attribute parameters */
2966 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2967 offset+=28;
2969 /* capability */
2970 dissect_osd_capability(tvb, offset, tree);
2971 offset+=osd2?104:80;
2973 /* security parameters */
2974 dissect_osd_security_parameters(tvb, offset, tree);
2975 offset+=osd2?52:40;
2978 /* dissecting the DATA OUT */
2979 if(isreq && !iscdb){
2980 /* attribute data out */
2981 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2983 /* no data out for set attributes */
2986 /* dissecting the DATA IN */
2987 if(!isreq && !iscdb){
2988 /* attribute data in */
2989 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2991 /* no data in for set attributes */
2997 static void
2998 dissect_osd2_create_user_tracking_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2999 guint offset, gboolean isreq, gboolean iscdb,
3000 guint payload_len _U_, scsi_task_data_t *cdata _U_,
3001 scsi_osd_conv_info_t *conv_info _U_,
3002 scsi_osd_lun_info_t *lun_info)
3004 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=TRUE;
3006 /* dissecting the CDB dissection starts at byte 10 of the CDB */
3007 if(isreq && iscdb){
3009 /* options byte */
3010 dissect_osd2_isolation(tvb,offset,tree);
3011 dissect_osd_option(tvb, offset, tree);
3012 offset++;
3014 /* getset attributes byte */
3015 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
3016 offset++;
3018 /* timestamps control */
3019 dissect_osd_timestamps_control(tvb, offset, tree);
3020 offset++;
3022 /* 3 reserved bytes */
3023 offset+=3;
3025 /* partition id */
3026 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
3027 offset+=8;
3029 /* user_object id */
3030 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_requested_collection_object_id);
3031 offset+=8;
3033 /* 8 reserved bytes */
3034 offset+=8;
3036 /* source collection id */
3037 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd2_source_collection_object_id);
3038 offset+=8;
3040 /*cdb continuation length*/
3041 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
3042 offset+=4;
3044 /* attribute parameters */
3045 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
3046 offset+=28;
3048 /* capability */
3049 dissect_osd_capability(tvb, offset, tree);
3050 offset+=104;
3052 /* security parameters */
3053 dissect_osd_security_parameters(tvb, offset, tree);
3054 offset+=52;
3057 /* dissecting the DATA OUT */
3058 if(isreq && !iscdb){
3059 /* CDB continuation */
3060 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
3062 /* attribute data out */
3063 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
3065 /* no data out for create user tracking collection */
3068 /* dissecting the DATA IN */
3069 if(!isreq && !iscdb){
3070 /* attribute data in */
3071 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
3073 /* no data in for create user tracking collection */
3078 static void
3079 dissect_osd2_query(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3080 guint offset, gboolean isreq, gboolean iscdb,
3081 guint payload_len _U_, scsi_task_data_t *cdata _U_,
3082 scsi_osd_conv_info_t *conv_info _U_,
3083 scsi_osd_lun_info_t *lun_info)
3085 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2=TRUE;
3087 /* dissecting the CDB dissection starts at byte 10 of the CDB */
3088 if(isreq && iscdb){
3090 /* isolation field */
3091 dissect_osd2_isolation(tvb,offset,tree);
3092 offset++;
3094 /* immed_tr, getset attributes*/
3095 proto_tree_add_item(tree, hf_scsi_osd2_immed_tr, tvb, offset, 1, ENC_BIG_ENDIAN);
3096 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
3097 offset++;
3099 /* timestamps control */
3100 dissect_osd_timestamps_control(tvb, offset, tree);
3101 offset++;
3103 /* 3 reserved bytes */
3104 offset+=3;
3106 /* partition id */
3107 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, FALSE, FALSE);
3108 offset+=8;
3110 /* collection_object id */
3111 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
3112 offset+=8;
3114 /* allocation_length */
3115 dissect_osd_allocation_length(tvb, offset, tree, cdata);
3116 offset+=8;
3118 /* matches collection id */
3119 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd2_matches_collection_object_id);
3120 offset+=8;
3122 /*cdb continuation length*/
3123 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
3124 offset+=4;
3126 /* attribute parameters */
3127 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
3128 offset+=28;
3130 /* capability */
3131 dissect_osd_capability(tvb, offset, tree);
3132 offset+=104;
3134 /* security parameters */
3135 dissect_osd_security_parameters(tvb, offset, tree);
3136 offset+=52;
3139 /* dissecting the DATA OUT */
3140 if(isreq && !iscdb){
3141 /* CDB continuation */
3142 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
3144 /* attribute data out */
3145 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
3147 /* no data out for query */
3150 /* dissecting the DATA IN */
3151 if(!isreq && !iscdb){
3152 guint64 additional_length;
3153 guint64 allocation_length;
3154 guint64 remaining_length;
3155 guint8 format;
3156 proto_item *item;
3158 /* attribute data in */
3159 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
3161 allocation_length=cdata->itlq->alloc_len;
3162 remaining_length=tvb_length_remaining(tvb, offset);
3163 if (remaining_length<allocation_length) allocation_length=remaining_length;
3164 if (allocation_length<12) return;
3166 /* dissection of the LIST or LIST COLLECTION DATA-IN */
3167 /* additional length */
3168 additional_length=tvb_get_ntoh64(tvb, offset);
3169 if ((guint32)(allocation_length-8)<additional_length) additional_length=(guint32)(allocation_length-8);
3171 dissect_osd_additional_length(tvb, offset, tree);
3172 offset+=8;
3174 /* 3 reserved bytes */
3175 offset+=3;
3176 item = proto_tree_add_item(tree, hf_scsi_osd2_object_descriptor_format, tvb, offset, 1, ENC_BIG_ENDIAN);
3177 format = tvb_get_guint8(tvb, offset)>>2;
3178 offset++;
3179 if (format!=0x21) {
3180 expert_add_info(pinfo,item,&ei_osd2_invalid_object_descriptor_format);
3181 return;
3184 while(additional_length > (offset-4)) {
3185 dissect_osd_user_object_id(tvb, offset, tree);
3186 offset+=8;
3192 /* OSD Service Actions */
3193 #define OSD_FORMAT_OSD 0x8801
3194 #define OSD_CREATE 0x8802
3195 #define OSD_LIST 0x8803
3196 #define OSD_READ 0x8805
3197 #define OSD_WRITE 0x8806
3198 #define OSD_APPEND 0x8807
3199 #define OSD_FLUSH 0x8808
3200 #define OSD_REMOVE 0x880a
3201 #define OSD_CREATE_PARTITION 0x880b
3202 #define OSD_REMOVE_PARTITION 0x880c
3203 #define OSD_GET_ATTRIBUTES 0x880e
3204 #define OSD_SET_ATTRIBUTES 0x880f
3205 #define OSD_CREATE_AND_WRITE 0x8812
3206 #define OSD_CREATE_COLLECTION 0x8815
3207 #define OSD_REMOVE_COLLECTION 0x8816
3208 #define OSD_LIST_COLLECTION 0x8817
3209 #define OSD_SET_KEY 0x8818
3210 #define OSD_FLUSH_COLLECTION 0x881a
3211 #define OSD_FLUSH_PARTITION 0x881b
3212 #define OSD_FLUSH_OSD 0x881c
3214 #define OSD_2_CREATE 0x8882
3215 #define OSD_2_LIST 0x8883
3216 #define OSD_2_READ 0x8885
3217 #define OSD_2_WRITE 0x8886
3218 #define OSD_2_APPEND 0x8887
3219 #define OSD_2_CLEAR 0x8889
3220 #define OSD_2_REMOVE 0x888a
3221 #define OSD_2_CREATE_PARTITION 0x888b
3222 #define OSD_2_REMOVE_PARTITION 0x888c
3223 #define OSD_2_GET_ATTRIBUTES 0x888e
3224 #define OSD_2_SET_ATTRIBUTES 0x888f
3225 #define OSD_2_CREATE_AND_WRITE 0x8892
3226 #define OSD_2_COPY_USER_OBJECTS 0x8893
3227 #define OSD_2_CREATE_USER_TRACKING_COLLECTION 0x8894
3228 #define OSD_2_REMOVE_COLLECTION 0x8896
3229 #define OSD_2_LIST_COLLECTION 0x8897
3230 #define OSD_2_QUERY 0x88a0
3231 #define OSD_2_REMOVE_MEMBER_OBJECTS 0x88a1
3232 #define OSD_2_GET_MEMBER_ATTRIBUTES 0x88a2
3233 #define OSD_2_SET_MEMBER_ATTRIBUTES 0x88a3
3235 static const value_string scsi_osd_svcaction_vals[] = {
3236 {OSD_FORMAT_OSD, "Format OSD"},
3237 {OSD_CREATE, "Create"},
3238 {OSD_LIST, "List"},
3239 {OSD_READ, "Read"},
3240 {OSD_WRITE, "Write"},
3241 {OSD_APPEND, "Append"},
3242 {OSD_FLUSH, "Flush"},
3243 {OSD_REMOVE, "Remove"},
3244 {OSD_CREATE_PARTITION, "Create Partition"},
3245 {OSD_REMOVE_PARTITION, "Remove Partition"},
3246 {OSD_GET_ATTRIBUTES, "Get Attributes"},
3247 {OSD_SET_ATTRIBUTES, "Set Attributes"},
3248 {OSD_CREATE_AND_WRITE, "Create And Write"},
3249 {OSD_CREATE_COLLECTION, "Create Collection"},
3250 {OSD_REMOVE_COLLECTION, "Remove Collection"},
3251 {OSD_LIST_COLLECTION, "List Collection"},
3252 {OSD_SET_KEY, "Set Key"},
3253 {OSD_FLUSH_COLLECTION, "Flush Collection"},
3254 {OSD_FLUSH_PARTITION, "Flush Partition"},
3255 {OSD_FLUSH_OSD, "Flush OSD"},
3256 {OSD_2_CREATE, "Create (OSD-2)"},
3257 {OSD_2_LIST, "List (OSD-2)"},
3258 {OSD_2_READ, "Read (OSD-2)"},
3259 {OSD_2_WRITE, "Write (OSD-2)"},
3260 {OSD_2_APPEND, "Append (OSD-2)"},
3261 {OSD_2_CLEAR, "Clear (OSD-2)"},
3262 {OSD_2_REMOVE, "Remove (OSD-2)"},
3263 {OSD_2_CREATE_PARTITION, "Create Partition (OSD-2)"},
3264 {OSD_2_REMOVE_PARTITION, "Remove Partition (OSD-2)"},
3265 {OSD_2_GET_ATTRIBUTES, "Get Attributes (OSD-2)"},
3266 {OSD_2_SET_ATTRIBUTES, "Set Attributes (OSD-2)"},
3267 {OSD_2_CREATE_AND_WRITE, "Create And Write (OSD-2)"},
3268 {OSD_2_REMOVE_COLLECTION, "Remove Collection (OSD-2)"},
3269 {OSD_2_LIST_COLLECTION, "List Collection (OSD-2)"},
3270 {OSD_2_COPY_USER_OBJECTS, "Copy User Objects (OSD-2)"},
3271 {OSD_2_CREATE_USER_TRACKING_COLLECTION, "Create User Tracking Collection (OSD-2)"},
3272 {OSD_2_REMOVE_COLLECTION, "Remove Collection (OSD-2)"},
3273 {OSD_2_LIST_COLLECTION, "List Collection (OSD-2)"},
3274 {OSD_2_QUERY, "Query (OSD-2)"},
3275 {OSD_2_REMOVE_MEMBER_OBJECTS, "Remove Member Objects (OSD-2)"},
3276 {OSD_2_GET_MEMBER_ATTRIBUTES, "Get Member Attributes (OSD-2)"},
3277 {OSD_2_SET_MEMBER_ATTRIBUTES, "Set Member Attributes (OSD-2)"},
3278 {0, NULL},
3281 /* OSD Service Action dissectors */
3282 typedef struct _scsi_osd_svcaction_t {
3283 guint16 svcaction;
3284 scsi_osd_dissector_t dissector;
3285 } scsi_osd_svcaction_t;
3287 static const scsi_osd_svcaction_t scsi_osd_svcaction[] = {
3288 {OSD_FORMAT_OSD, dissect_osd_format_osd},
3289 {OSD_CREATE, dissect_osd_create},
3290 {OSD_LIST, dissect_osd_list},
3291 {OSD_READ, dissect_osd_read},
3292 {OSD_WRITE, dissect_osd_write},
3293 {OSD_APPEND, dissect_osd_append},
3294 {OSD_FLUSH, dissect_osd_flush},
3295 {OSD_REMOVE, dissect_osd_remove},
3296 {OSD_CREATE_PARTITION, dissect_osd_create_partition},
3297 {OSD_REMOVE_PARTITION, dissect_osd_remove_partition},
3298 {OSD_GET_ATTRIBUTES, dissect_osd_get_attributes},
3299 {OSD_SET_ATTRIBUTES, dissect_osd_set_attributes},
3300 {OSD_CREATE_AND_WRITE, dissect_osd_create_and_write},
3301 {OSD_CREATE_COLLECTION, dissect_osd_create_collection},
3302 {OSD_REMOVE_COLLECTION, dissect_osd_remove_collection},
3303 {OSD_LIST_COLLECTION, dissect_osd_list},
3304 {OSD_SET_KEY, dissect_osd_set_key},
3305 {OSD_FLUSH_COLLECTION, dissect_osd_flush_collection},
3306 {OSD_FLUSH_PARTITION, dissect_osd_flush_partition},
3307 {OSD_FLUSH_OSD, dissect_osd_flush_osd},
3308 {OSD_2_LIST, dissect_osd_list},
3309 {OSD_2_CREATE_PARTITION, dissect_osd_create_partition},
3310 {OSD_2_CREATE_USER_TRACKING_COLLECTION, dissect_osd2_create_user_tracking_collection},
3311 {OSD_2_REMOVE_PARTITION, dissect_osd_remove_partition},
3312 {OSD_2_LIST_COLLECTION, dissect_osd_list},
3313 {OSD_2_CREATE_USER_TRACKING_COLLECTION, dissect_osd2_create_user_tracking_collection},
3314 {OSD_2_REMOVE_COLLECTION, dissect_osd_remove_collection},
3315 {OSD_2_GET_ATTRIBUTES, dissect_osd_get_attributes},
3316 {OSD_2_SET_ATTRIBUTES, dissect_osd_set_attributes},
3317 {OSD_2_QUERY, dissect_osd2_query},
3318 {0, NULL},
3321 static scsi_osd_dissector_t
3322 find_svcaction_dissector(guint16 svcaction)
3324 const scsi_osd_svcaction_t *sa=scsi_osd_svcaction;
3326 while(sa&&sa->dissector){
3327 if(sa->svcaction==svcaction){
3328 return sa->dissector;
3330 sa++;
3332 return NULL;
3337 static void
3338 dissect_osd_opcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3339 guint offset, gboolean isreq, gboolean iscdb,
3340 guint payload_len, scsi_task_data_t *cdata)
3342 guint16 svcaction=0;
3343 scsi_osd_dissector_t dissector;
3344 scsi_osd_conv_info_t *conv_info=NULL;
3345 scsi_osd_lun_info_t *lun_info=NULL;
3347 if(!tree) {
3348 return;
3351 /* We must have an itl an itlq and a conversation */
3352 if(!cdata || !cdata->itl || !cdata->itl->conversation || !cdata->itlq){
3353 return;
3355 /* make sure we have a conversation info for this */
3356 conv_info=(scsi_osd_conv_info_t *)conversation_get_proto_data(cdata->itl->conversation, proto_scsi_osd);
3357 if(!conv_info){
3358 conv_info=wmem_new(wmem_file_scope(), scsi_osd_conv_info_t);
3359 conv_info->luns=wmem_tree_new(wmem_file_scope());
3360 conversation_add_proto_data(cdata->itl->conversation, proto_scsi_osd, conv_info);
3362 /* make sure we have a lun_info structure for this */
3363 lun_info=(scsi_osd_lun_info_t *)wmem_tree_lookup32(conv_info->luns, cdata->itlq->lun);
3364 if(!lun_info){
3365 lun_info=wmem_new(wmem_file_scope(), scsi_osd_lun_info_t);
3366 lun_info->partitions=wmem_tree_new(wmem_file_scope());
3367 wmem_tree_insert32(conv_info->luns, cdata->itlq->lun, (void *)lun_info);
3370 /* dissecting the CDB */
3371 if (isreq && iscdb) {
3372 proto_tree_add_item (tree, hf_scsi_control, tvb, offset, 1, ENC_BIG_ENDIAN);
3373 offset++;
3375 /* 5 reserved bytes */
3376 offset+=5;
3378 proto_tree_add_item (tree, hf_scsi_osd_add_cdblen, tvb, offset, 1, ENC_BIG_ENDIAN);
3379 offset++;
3381 svcaction=tvb_get_ntohs(tvb, offset);
3382 if(cdata && cdata->itlq){
3383 /* We must store the service action for this itlq
3384 * so we can indentify what the data contains
3386 if((!pinfo->fd->flags.visited) || (!cdata->itlq->extra_data)){
3387 scsi_osd_extra_data_t *extra_data;
3389 extra_data=wmem_new(wmem_file_scope(), scsi_osd_extra_data_t);
3390 extra_data->svcaction=svcaction;
3391 extra_data->gsatype=0;
3392 extra_data->osd2=0;
3393 extra_data->continuation_length=0;
3394 cdata->itlq->extra_data=extra_data;
3397 proto_tree_add_item (tree, hf_scsi_osd_svcaction, tvb, offset, 2, ENC_BIG_ENDIAN);
3398 offset+=2;
3401 col_append_str(pinfo->cinfo, COL_INFO,
3402 val_to_str_const(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Service Action"));
3404 dissector=find_svcaction_dissector(svcaction);
3405 if(dissector){
3406 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
3408 return;
3411 /* If it was not a CDB, try to find the service action and pass it
3412 * off to the service action dissector
3414 if(cdata && cdata->itlq && cdata->itlq->extra_data){
3415 scsi_osd_extra_data_t *extra_data=(scsi_osd_extra_data_t *)cdata->itlq->extra_data;
3416 svcaction=extra_data->svcaction;
3418 col_append_str(pinfo->cinfo, COL_INFO,
3419 val_to_str_const(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Service Action"));
3420 if(svcaction){
3421 proto_item *it;
3422 it=proto_tree_add_uint_format_value(tree, hf_scsi_osd_svcaction, tvb, 0, 0, svcaction, "0x%04x", svcaction);
3423 PROTO_ITEM_SET_GENERATED(it);
3425 dissector=find_svcaction_dissector(svcaction);
3426 if(dissector){
3427 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
3433 /* OSD Commands */
3434 const value_string scsi_osd_vals[] = {
3435 {SCSI_SPC_INQUIRY, "Inquiry"},
3436 {SCSI_SPC_LOGSELECT, "Log Select"},
3437 {SCSI_SPC_LOGSENSE, "Log Sense"},
3438 {SCSI_SPC_MGMT_PROTOCOL_IN, "Mgmt Protocol In"},
3439 {SCSI_SPC_MODESELECT10, "Mode Select(10)"},
3440 {SCSI_SPC_MODESENSE10, "Mode Sense(10)"},
3441 {SCSI_SPC_PERSRESVIN, "Persistent Reserve In"},
3442 {SCSI_SPC_PERSRESVOUT, "Persistent Reserve Out"},
3443 {SCSI_SPC_REPORTLUNS, "Report LUNs"},
3444 {SCSI_OSD_OPCODE, "OSD Command" },
3445 {0, NULL},
3450 scsi_cdb_table_t scsi_osd_table[256] = {
3451 /*OSD 0x00*/{NULL},
3452 /*OSD 0x01*/{NULL},
3453 /*OSD 0x02*/{NULL},
3454 /*OSD 0x03*/{NULL},
3455 /*OSD 0x04*/{NULL},
3456 /*OSD 0x05*/{NULL},
3457 /*OSD 0x06*/{NULL},
3458 /*OSD 0x07*/{NULL},
3459 /*OSD 0x08*/{NULL},
3460 /*OSD 0x09*/{NULL},
3461 /*OSD 0x0a*/{NULL},
3462 /*OSD 0x0b*/{NULL},
3463 /*OSD 0x0c*/{NULL},
3464 /*OSD 0x0d*/{NULL},
3465 /*OSD 0x0e*/{NULL},
3466 /*OSD 0x0f*/{NULL},
3467 /*OSD 0x10*/{NULL},
3468 /*OSD 0x11*/{NULL},
3469 /*OSD 0x12*/{dissect_spc_inquiry},
3470 /*OSD 0x13*/{NULL},
3471 /*OSD 0x14*/{NULL},
3472 /*OSD 0x15*/{NULL},
3473 /*OSD 0x16*/{NULL},
3474 /*OSD 0x17*/{NULL},
3475 /*OSD 0x18*/{NULL},
3476 /*OSD 0x19*/{NULL},
3477 /*OSD 0x1a*/{NULL},
3478 /*OSD 0x1b*/{NULL},
3479 /*OSD 0x1c*/{NULL},
3480 /*OSD 0x1d*/{NULL},
3481 /*OSD 0x1e*/{NULL},
3482 /*OSD 0x1f*/{NULL},
3483 /*OSD 0x20*/{NULL},
3484 /*OSD 0x21*/{NULL},
3485 /*OSD 0x22*/{NULL},
3486 /*OSD 0x23*/{NULL},
3487 /*OSD 0x24*/{NULL},
3488 /*OSD 0x25*/{NULL},
3489 /*OSD 0x26*/{NULL},
3490 /*OSD 0x27*/{NULL},
3491 /*OSD 0x28*/{NULL},
3492 /*OSD 0x29*/{NULL},
3493 /*OSD 0x2a*/{NULL},
3494 /*OSD 0x2b*/{NULL},
3495 /*OSD 0x2c*/{NULL},
3496 /*OSD 0x2d*/{NULL},
3497 /*OSD 0x2e*/{NULL},
3498 /*OSD 0x2f*/{NULL},
3499 /*OSD 0x30*/{NULL},
3500 /*OSD 0x31*/{NULL},
3501 /*OSD 0x32*/{NULL},
3502 /*OSD 0x33*/{NULL},
3503 /*OSD 0x34*/{NULL},
3504 /*OSD 0x35*/{NULL},
3505 /*OSD 0x36*/{NULL},
3506 /*OSD 0x37*/{NULL},
3507 /*OSD 0x38*/{NULL},
3508 /*OSD 0x39*/{NULL},
3509 /*OSD 0x3a*/{NULL},
3510 /*OSD 0x3b*/{NULL},
3511 /*OSD 0x3c*/{NULL},
3512 /*OSD 0x3d*/{NULL},
3513 /*OSD 0x3e*/{NULL},
3514 /*OSD 0x3f*/{NULL},
3515 /*OSD 0x40*/{NULL},
3516 /*OSD 0x41*/{NULL},
3517 /*OSD 0x42*/{NULL},
3518 /*OSD 0x43*/{NULL},
3519 /*OSD 0x44*/{NULL},
3520 /*OSD 0x45*/{NULL},
3521 /*OSD 0x46*/{NULL},
3522 /*OSD 0x47*/{NULL},
3523 /*OSD 0x48*/{NULL},
3524 /*OSD 0x49*/{NULL},
3525 /*OSD 0x4a*/{NULL},
3526 /*OSD 0x4b*/{NULL},
3527 /*OSD 0x4c*/{dissect_spc_logselect},
3528 /*OSD 0x4d*/{dissect_spc_logsense},
3529 /*OSD 0x4e*/{NULL},
3530 /*OSD 0x4f*/{NULL},
3531 /*OSD 0x50*/{NULL},
3532 /*OSD 0x51*/{NULL},
3533 /*OSD 0x52*/{NULL},
3534 /*OSD 0x53*/{NULL},
3535 /*OSD 0x54*/{NULL},
3536 /*OSD 0x55*/{dissect_spc_modeselect10},
3537 /*OSD 0x56*/{NULL},
3538 /*OSD 0x57*/{NULL},
3539 /*OSD 0x58*/{NULL},
3540 /*OSD 0x59*/{NULL},
3541 /*OSD 0x5a*/{dissect_spc_modesense10},
3542 /*OSD 0x5b*/{NULL},
3543 /*OSD 0x5c*/{NULL},
3544 /*OSD 0x5d*/{NULL},
3545 /*OSD 0x5e*/{dissect_spc_persistentreservein},
3546 /*OSD 0x5f*/{dissect_spc_persistentreserveout},
3547 /*OSD 0x60*/{NULL},
3548 /*OSD 0x61*/{NULL},
3549 /*OSD 0x62*/{NULL},
3550 /*OSD 0x63*/{NULL},
3551 /*OSD 0x64*/{NULL},
3552 /*OSD 0x65*/{NULL},
3553 /*OSD 0x66*/{NULL},
3554 /*OSD 0x67*/{NULL},
3555 /*OSD 0x68*/{NULL},
3556 /*OSD 0x69*/{NULL},
3557 /*OSD 0x6a*/{NULL},
3558 /*OSD 0x6b*/{NULL},
3559 /*OSD 0x6c*/{NULL},
3560 /*OSD 0x6d*/{NULL},
3561 /*OSD 0x6e*/{NULL},
3562 /*OSD 0x6f*/{NULL},
3563 /*OSD 0x70*/{NULL},
3564 /*OSD 0x71*/{NULL},
3565 /*OSD 0x72*/{NULL},
3566 /*OSD 0x73*/{NULL},
3567 /*OSD 0x74*/{NULL},
3568 /*OSD 0x75*/{NULL},
3569 /*OSD 0x76*/{NULL},
3570 /*OSD 0x77*/{NULL},
3571 /*OSD 0x78*/{NULL},
3572 /*OSD 0x79*/{NULL},
3573 /*OSD 0x7a*/{NULL},
3574 /*OSD 0x7b*/{NULL},
3575 /*OSD 0x7c*/{NULL},
3576 /*OSD 0x7d*/{NULL},
3577 /*OSD 0x7e*/{NULL},
3578 /*OSD 0x7f*/{dissect_osd_opcode},
3579 /*OSD 0x80*/{NULL},
3580 /*OSD 0x81*/{NULL},
3581 /*OSD 0x82*/{NULL},
3582 /*OSD 0x83*/{NULL},
3583 /*OSD 0x84*/{NULL},
3584 /*OSD 0x85*/{NULL},
3585 /*OSD 0x86*/{NULL},
3586 /*OSD 0x87*/{NULL},
3587 /*OSD 0x88*/{NULL},
3588 /*OSD 0x89*/{NULL},
3589 /*OSD 0x8a*/{NULL},
3590 /*OSD 0x8b*/{NULL},
3591 /*OSD 0x8c*/{NULL},
3592 /*OSD 0x8d*/{NULL},
3593 /*OSD 0x8e*/{NULL},
3594 /*OSD 0x8f*/{NULL},
3595 /*OSD 0x90*/{NULL},
3596 /*OSD 0x91*/{NULL},
3597 /*OSD 0x92*/{NULL},
3598 /*OSD 0x93*/{NULL},
3599 /*OSD 0x94*/{NULL},
3600 /*OSD 0x95*/{NULL},
3601 /*OSD 0x96*/{NULL},
3602 /*OSD 0x97*/{NULL},
3603 /*OSD 0x98*/{NULL},
3604 /*OSD 0x99*/{NULL},
3605 /*OSD 0x9a*/{NULL},
3606 /*OSD 0x9b*/{NULL},
3607 /*OSD 0x9c*/{NULL},
3608 /*OSD 0x9d*/{NULL},
3609 /*OSD 0x9e*/{NULL},
3610 /*OSD 0x9f*/{NULL},
3611 /*OSD 0xa0*/{dissect_spc_reportluns},
3612 /*OSD 0xa1*/{NULL},
3613 /*OSD 0xa2*/{NULL},
3614 /*SPC 0xa3*/{dissect_spc_mgmt_protocol_in},
3615 /*OSD 0xa4*/{NULL},
3616 /*OSD 0xa5*/{NULL},
3617 /*OSD 0xa6*/{NULL},
3618 /*OSD 0xa7*/{NULL},
3619 /*OSD 0xa8*/{NULL},
3620 /*OSD 0xa9*/{NULL},
3621 /*OSD 0xaa*/{NULL},
3622 /*OSD 0xab*/{NULL},
3623 /*OSD 0xac*/{NULL},
3624 /*OSD 0xad*/{NULL},
3625 /*OSD 0xae*/{NULL},
3626 /*OSD 0xaf*/{NULL},
3627 /*OSD 0xb0*/{NULL},
3628 /*OSD 0xb1*/{NULL},
3629 /*OSD 0xb2*/{NULL},
3630 /*OSD 0xb3*/{NULL},
3631 /*OSD 0xb4*/{NULL},
3632 /*OSD 0xb5*/{NULL},
3633 /*OSD 0xb6*/{NULL},
3634 /*OSD 0xb7*/{NULL},
3635 /*OSD 0xb8*/{NULL},
3636 /*OSD 0xb9*/{NULL},
3637 /*OSD 0xba*/{NULL},
3638 /*OSD 0xbb*/{NULL},
3639 /*OSD 0xbc*/{NULL},
3640 /*OSD 0xbd*/{NULL},
3641 /*OSD 0xbe*/{NULL},
3642 /*OSD 0xbf*/{NULL},
3643 /*OSD 0xc0*/{NULL},
3644 /*OSD 0xc1*/{NULL},
3645 /*OSD 0xc2*/{NULL},
3646 /*OSD 0xc3*/{NULL},
3647 /*OSD 0xc4*/{NULL},
3648 /*OSD 0xc5*/{NULL},
3649 /*OSD 0xc6*/{NULL},
3650 /*OSD 0xc7*/{NULL},
3651 /*OSD 0xc8*/{NULL},
3652 /*OSD 0xc9*/{NULL},
3653 /*OSD 0xca*/{NULL},
3654 /*OSD 0xcb*/{NULL},
3655 /*OSD 0xcc*/{NULL},
3656 /*OSD 0xcd*/{NULL},
3657 /*OSD 0xce*/{NULL},
3658 /*OSD 0xcf*/{NULL},
3659 /*OSD 0xd0*/{NULL},
3660 /*OSD 0xd1*/{NULL},
3661 /*OSD 0xd2*/{NULL},
3662 /*OSD 0xd3*/{NULL},
3663 /*OSD 0xd4*/{NULL},
3664 /*OSD 0xd5*/{NULL},
3665 /*OSD 0xd6*/{NULL},
3666 /*OSD 0xd7*/{NULL},
3667 /*OSD 0xd8*/{NULL},
3668 /*OSD 0xd9*/{NULL},
3669 /*OSD 0xda*/{NULL},
3670 /*OSD 0xdb*/{NULL},
3671 /*OSD 0xdc*/{NULL},
3672 /*OSD 0xdd*/{NULL},
3673 /*OSD 0xde*/{NULL},
3674 /*OSD 0xdf*/{NULL},
3675 /*OSD 0xe0*/{NULL},
3676 /*OSD 0xe1*/{NULL},
3677 /*OSD 0xe2*/{NULL},
3678 /*OSD 0xe3*/{NULL},
3679 /*OSD 0xe4*/{NULL},
3680 /*OSD 0xe5*/{NULL},
3681 /*OSD 0xe6*/{NULL},
3682 /*OSD 0xe7*/{NULL},
3683 /*OSD 0xe8*/{NULL},
3684 /*OSD 0xe9*/{NULL},
3685 /*OSD 0xea*/{NULL},
3686 /*OSD 0xeb*/{NULL},
3687 /*OSD 0xec*/{NULL},
3688 /*OSD 0xed*/{NULL},
3689 /*OSD 0xee*/{NULL},
3690 /*OSD 0xef*/{NULL},
3691 /*OSD 0xf0*/{NULL},
3692 /*OSD 0xf1*/{NULL},
3693 /*OSD 0xf2*/{NULL},
3694 /*OSD 0xf3*/{NULL},
3695 /*OSD 0xf4*/{NULL},
3696 /*OSD 0xf5*/{NULL},
3697 /*OSD 0xf6*/{NULL},
3698 /*OSD 0xf7*/{NULL},
3699 /*OSD 0xf8*/{NULL},
3700 /*OSD 0xf9*/{NULL},
3701 /*OSD 0xfa*/{NULL},
3702 /*OSD 0xfb*/{NULL},
3703 /*OSD 0xfc*/{NULL},
3704 /*OSD 0xfd*/{NULL},
3705 /*OSD 0xfe*/{NULL},
3706 /*OSD 0xff*/{NULL}
3712 void
3713 proto_register_scsi_osd(void)
3715 expert_module_t* expert_scsi_osd;
3717 static hf_register_info hf[] = {
3718 { &hf_scsi_osd_opcode,
3719 {"OSD Opcode", "scsi_osd.opcode", FT_UINT8, BASE_HEX,
3720 VALS (scsi_osd_vals), 0x0, NULL, HFILL}},
3721 { &hf_scsi_osd_add_cdblen,
3722 {"Additional CDB Length", "scsi_osd.addcdblen", FT_UINT8, BASE_DEC,
3723 NULL, 0x0, NULL, HFILL}},
3724 { &hf_scsi_osd_svcaction,
3725 {"Service Action", "scsi_osd.svcaction", FT_UINT16, BASE_HEX,
3726 VALS(scsi_osd_svcaction_vals), 0x0, NULL, HFILL}},
3727 { &hf_scsi_osd_option,
3728 {"Options Byte", "scsi_osd.option", FT_UINT8, BASE_HEX,
3729 NULL, 0x0, NULL, HFILL}},
3730 { &hf_scsi_osd_option_dpo,
3731 {"DPO", "scsi_osd.option.dpo", FT_BOOLEAN, 8,
3732 TFS(&tfs_set_notset), 0x10, NULL, HFILL}},
3733 { &hf_scsi_osd_option_fua,
3734 {"FUA", "scsi_osd.option.fua", FT_BOOLEAN, 8,
3735 TFS(&tfs_set_notset), 0x08, NULL, HFILL}},
3736 { &hf_scsi_osd_getsetattrib,
3737 {"GET/SET CDBFMT", "scsi_osd.getset", FT_UINT8, BASE_HEX,
3738 VALS(scsi_osd_getsetattrib_vals), 0x30, NULL, HFILL}},
3739 { &hf_scsi_osd_timestamps_control,
3740 {"Timestamps Control", "scsi_osd.timestamps_control", FT_UINT8, BASE_HEX,
3741 VALS(scsi_osd_timestamps_control_vals), 0x0, NULL, HFILL}},
3742 { &hf_scsi_osd_formatted_capacity,
3743 {"Formatted Capacity", "scsi_osd.formatted_capacity", FT_UINT64, BASE_DEC,
3744 NULL, 0x0, NULL, HFILL}},
3745 { &hf_scsi_osd_get_attributes_page,
3746 {"Get Attributes Page", "scsi_osd.get_attributes_page", FT_UINT32, BASE_HEX,
3747 NULL, 0x0, NULL, HFILL}},
3748 { &hf_scsi_osd_get_attributes_list_length,
3749 {"Get Attributes List Length", "scsi_osd.get_attributes_list_length", FT_UINT32, BASE_HEX,
3750 NULL, 0x0, NULL, HFILL}},
3751 { &hf_scsi_osd_get_attributes_list_offset,
3752 {"Get Attributes List Offset", "scsi_osd.get_attributes_list_offset", FT_UINT32, BASE_HEX,
3753 NULL, 0x0, NULL, HFILL}},
3754 { &hf_scsi_osd_set_attributes_list_length,
3755 {"Set Attributes List Length", "scsi_osd.set_attributes_list_length", FT_UINT32, BASE_HEX,
3756 NULL, 0x0, NULL, HFILL}},
3757 { &hf_scsi_osd_set_attributes_list_offset,
3758 {"Set Attributes List Offset", "scsi_osd.set_attributes_list_offset", FT_UINT32, BASE_HEX,
3759 NULL, 0x0, NULL, HFILL}},
3760 { &hf_scsi_osd_get_attributes_allocation_length,
3761 {"Get Attributes Allocation Length", "scsi_osd.get_attributes_allocation_length", FT_UINT32, BASE_HEX,
3762 NULL, 0x0, NULL, HFILL}},
3763 { &hf_scsi_osd_retrieved_attributes_offset,
3764 {"Retrieved Attributes Offset", "scsi_osd.retrieved_attributes_offset", FT_UINT32, BASE_HEX,
3765 NULL, 0x0, NULL, HFILL}},
3766 { &hf_scsi_osd_set_attributes_page,
3767 {"Set Attributes Page", "scsi_osd.set_attributes_page", FT_UINT32, BASE_HEX,
3768 NULL, 0x0, NULL, HFILL}},
3769 { &hf_scsi_osd_set_attribute_length,
3770 {"Set Attribute Length", "scsi_osd.set_attribute_length", FT_UINT32, BASE_HEX,
3771 NULL, 0x0, NULL, HFILL}},
3772 { &hf_scsi_osd_set_attribute_number,
3773 {"Set Attribute Number", "scsi_osd.set_attribute_number", FT_UINT32, BASE_HEX,
3774 NULL, 0x0, NULL, HFILL}},
3775 { &hf_scsi_osd_set_attributes_offset,
3776 {"Set Attributes Offset", "scsi_osd.set_attributes_offset", FT_UINT32, BASE_HEX,
3777 NULL, 0x0, NULL, HFILL}},
3778 { &hf_scsi_osd_capability_format,
3779 {"Capability Format", "scsi_osd.capability_format", FT_UINT8, BASE_HEX,
3780 VALS(scsi_osd_capability_format_vals), 0x0f, NULL, HFILL}},
3781 { &hf_scsi_osd_key_version,
3782 {"Key Version", "scsi_osd.key_version", FT_UINT8, BASE_HEX,
3783 NULL, 0xf0, NULL, HFILL}},
3784 { &hf_scsi_osd_icva,
3785 {"Integrity Check Value Algorithm", "scsi_osd.icva", FT_UINT8, BASE_HEX,
3786 NULL, 0x0f, NULL, HFILL}},
3787 { &hf_scsi_osd_security_method,
3788 {"Security Method", "scsi_osd.security_method", FT_UINT8, BASE_HEX,
3789 NULL, 0x0f, NULL, HFILL}},
3790 { &hf_scsi_osd_capability_expiration_time,
3791 {"Capability Expiration Time", "scsi_osd.capability_expiration_time", FT_BYTES, BASE_NONE,
3792 NULL, 0, NULL, HFILL}},
3793 { &hf_scsi_osd_audit,
3794 {"Audit", "scsi_osd.audit", FT_BYTES, BASE_NONE,
3795 NULL, 0, NULL, HFILL}},
3796 { &hf_scsi_osd_capability_discriminator,
3797 {"Capability Discriminator", "scsi_osd.capability_descriminator", FT_BYTES, BASE_NONE,
3798 NULL, 0, NULL, HFILL}},
3799 { &hf_scsi_osd_object_created_time,
3800 {"Object Created Time", "scsi_osd.object_created_time", FT_BYTES, BASE_NONE,
3801 NULL, 0, NULL, HFILL}},
3802 { &hf_scsi_osd_object_type,
3803 {"Object Type", "scsi_osd.object_type", FT_UINT8, BASE_HEX,
3804 VALS(scsi_osd_object_type_vals), 0, NULL, HFILL}},
3805 { &hf_scsi_osd_permissions,
3806 {"Permissions", "scsi_osd.permissions", FT_UINT16, BASE_HEX,
3807 NULL, 0, NULL, HFILL}},
3808 { &hf_scsi_osd_permissions_read,
3809 {"READ", "scsi_osd.permissions.read", FT_BOOLEAN, 16,
3810 TFS(&tfs_set_notset), 0x8000, NULL, HFILL}},
3811 { &hf_scsi_osd_permissions_write,
3812 {"WRITE", "scsi_osd.permissions.write", FT_BOOLEAN, 16,
3813 TFS(&tfs_set_notset), 0x4000, NULL, HFILL}},
3814 { &hf_scsi_osd_permissions_get_attr,
3815 {"GET_ATTR", "scsi_osd.permissions.get_attr", FT_BOOLEAN, 16,
3816 TFS(&tfs_set_notset), 0x2000, NULL, HFILL}},
3817 { &hf_scsi_osd_permissions_set_attr,
3818 {"SET_ATTR", "scsi_osd.permissions.set_attr", FT_BOOLEAN, 16,
3819 TFS(&tfs_set_notset), 0x1000, NULL, HFILL}},
3820 { &hf_scsi_osd_permissions_create,
3821 {"CREATE", "scsi_osd.permissions.create", FT_BOOLEAN, 16,
3822 TFS(&tfs_set_notset), 0x0800, NULL, HFILL}},
3823 { &hf_scsi_osd_permissions_remove,
3824 {"REMOVE", "scsi_osd.permissions.remove", FT_BOOLEAN, 16,
3825 TFS(&tfs_set_notset), 0x0400, NULL, HFILL}},
3826 { &hf_scsi_osd_permissions_obj_mgmt,
3827 {"OBJ_MGMT", "scsi_osd.permissions.obj_mgmt", FT_BOOLEAN, 16,
3828 TFS(&tfs_set_notset), 0x0200, NULL, HFILL}},
3829 { &hf_scsi_osd_permissions_append,
3830 {"APPEND", "scsi_osd.permissions.append", FT_BOOLEAN, 16,
3831 TFS(&tfs_set_notset), 0x0100, NULL, HFILL}},
3832 { &hf_scsi_osd_permissions_dev_mgmt,
3833 {"DEV_MGMT", "scsi_osd.permissions.dev_mgmt", FT_BOOLEAN, 16,
3834 TFS(&tfs_set_notset), 0x0080, NULL, HFILL}},
3835 { &hf_scsi_osd_permissions_global,
3836 {"GLOBAL", "scsi_osd.permissions.global", FT_BOOLEAN, 16,
3837 TFS(&tfs_set_notset), 0x0040, NULL, HFILL}},
3838 { &hf_scsi_osd_permissions_pol_sec,
3839 {"POL/SEC", "scsi_osd.permissions.pol_sec", FT_BOOLEAN, 16,
3840 TFS(&tfs_set_notset), 0x0020, NULL, HFILL}},
3842 { &hf_scsi_osd_object_descriptor_type,
3843 {"Object Descriptor Type", "scsi_osd.object_descriptor_type", FT_UINT8, BASE_HEX,
3844 VALS(scsi_osd_object_descriptor_type_vals), 0xf0, NULL, HFILL}},
3845 { &hf_scsi_osd_object_descriptor,
3846 {"Object Descriptor", "scsi_osd.object_descriptor", FT_BYTES, BASE_NONE,
3847 NULL, 0, NULL, HFILL}},
3848 { &hf_scsi_osd_ricv,
3849 {"Request Integrity Check value", "scsi_osd.ricv", FT_BYTES, BASE_NONE,
3850 NULL, 0, NULL, HFILL}},
3851 { &hf_scsi_osd_request_nonce,
3852 {"Request Nonce", "scsi_osd.request_nonce", FT_BYTES, BASE_NONE,
3853 NULL, 0, NULL, HFILL}},
3854 { &hf_scsi_osd_diicvo,
3855 {"Data-In Integrity Check Value Offset", "scsi_osd.diicvo", FT_UINT32, BASE_DEC,
3856 NULL, 0, NULL, HFILL}},
3857 { &hf_scsi_osd_doicvo,
3858 {"Data-Out Integrity Check Value Offset", "scsi_osd.doicvo", FT_UINT32, BASE_DEC,
3859 NULL, 0, NULL, HFILL}},
3860 { &hf_scsi_osd_requested_partition_id,
3861 {"Requested Partition Id", "scsi_osd.requested_partition_id", FT_UINT64, BASE_HEX,
3862 NULL, 0, NULL, HFILL}},
3863 { &hf_scsi_osd_sortorder,
3864 {"Sort Order", "scsi_osd.sort_order", FT_UINT8, BASE_DEC,
3865 VALS(scsi_osd_sort_order_vals), 0x0f, NULL, HFILL}},
3866 { &hf_scsi_osd_partition_id,
3867 {"Partition Id", "scsi_osd.partition_id", FT_UINT64, BASE_HEX,
3868 NULL, 0, NULL, HFILL}},
3869 { &hf_scsi_osd_list_identifier,
3870 {"List Identifier", "scsi_osd.list_identifier", FT_UINT32, BASE_DEC,
3871 NULL, 0, NULL, HFILL}},
3872 { &hf_scsi_osd_allocation_length,
3873 {"Allocation Length", "scsi_osd.allocation_length", FT_UINT64, BASE_DEC,
3874 NULL, 0, NULL, HFILL}},
3875 { &hf_scsi_osd_length,
3876 {"Length", "scsi_osd.length", FT_UINT64, BASE_DEC,
3877 NULL, 0, NULL, HFILL}},
3878 { &hf_scsi_osd_starting_byte_address,
3879 {"Starting Byte Address", "scsi_osd.starting_byte_address", FT_UINT64, BASE_DEC,
3880 NULL, 0, NULL, HFILL}},
3881 { &hf_scsi_osd_initial_object_id,
3882 {"Initial Object Id", "scsi_osd.initial_object_id", FT_BYTES, BASE_NONE,
3883 NULL, 0, NULL, HFILL}},
3884 { &hf_scsi_osd_additional_length,
3885 {"Additional Length", "scsi_osd.additional_length", FT_UINT64, BASE_DEC,
3886 NULL, 0, NULL, HFILL}},
3887 { &hf_scsi_osd_continuation_object_id,
3888 {"Continuation Object Id", "scsi_osd.continuation_object_id", FT_BYTES, BASE_NONE,
3889 NULL, 0, NULL, HFILL}},
3890 { &hf_scsi_osd_user_object_id,
3891 {"User Object Id", "scsi_osd.user_object_id", FT_BYTES, BASE_NONE,
3892 NULL, 0, NULL, HFILL}},
3893 { &hf_scsi_osd_list_flags_lstchg,
3894 {"LSTCHG", "scsi_osd.list.lstchg", FT_BOOLEAN, 8,
3895 TFS(&list_lstchg_tfs), 0x02, NULL, HFILL}},
3896 { &hf_scsi_osd_list_flags_root,
3897 {"ROOT", "scsi_osd.list.root", FT_BOOLEAN, 8,
3898 TFS(&list_root_tfs), 0x01, NULL, HFILL}},
3899 { &hf_scsi_osd_list_collection_flags_coltn,
3900 {"COLTN", "scsi_osd.list_collection.coltn", FT_BOOLEAN, 8,
3901 TFS(&list_coltn_tfs), 0x01, NULL, HFILL}},
3902 { &hf_scsi_osd_requested_user_object_id,
3903 {"Requested User Object Id", "scsi_osd.requested_user_object_id", FT_BYTES, BASE_NONE,
3904 NULL, 0, NULL, HFILL}},
3905 { &hf_scsi_osd_number_of_user_objects,
3906 {"Number Of User Objects", "scsi_osd.number_of_user_objects", FT_UINT16, BASE_DEC,
3907 NULL, 0, NULL, HFILL}},
3908 { &hf_scsi_osd_key_to_set,
3909 {"Key to Set", "scsi_osd.key_to_set", FT_UINT8, BASE_DEC,
3910 VALS(key_to_set_vals), 0x03, NULL, HFILL}},
3911 { &hf_scsi_osd_set_key_version,
3912 {"Key Version", "scsi_osd.set_key_version", FT_UINT8, BASE_DEC,
3913 NULL, 0x0f, NULL, HFILL}},
3914 { &hf_scsi_osd_key_identifier,
3915 {"Key Identifier", "scsi_osd.key_identifier", FT_BYTES, BASE_NONE,
3916 NULL, 0, NULL, HFILL}},
3917 { &hf_scsi_osd_seed,
3918 {"Seed", "scsi_osd.seed", FT_BYTES, BASE_NONE,
3919 NULL, 0, NULL, HFILL}},
3920 { &hf_scsi_osd_collection_fcr,
3921 {"FCR", "scsi_osd.collection.fcr", FT_BOOLEAN, 8,
3922 TFS(&tfs_set_notset), 0x01, NULL, HFILL}},
3923 { &hf_scsi_osd_collection_object_id,
3924 {"Collection Object Id", "scsi_osd.collection_object_id", FT_BYTES, BASE_NONE,
3925 NULL, 0, NULL, HFILL}},
3926 { &hf_scsi_osd_requested_collection_object_id,
3927 {"Requested Collection Object Id", "scsi_osd.requested_collection_object_id", FT_BYTES, BASE_NONE,
3928 NULL, 0, NULL, HFILL}},
3929 { &hf_scsi_osd_partition_created_in,
3930 { "Created In", "scsi_osd.partition.created_in", FT_FRAMENUM, BASE_NONE,
3931 NULL, 0x0, "The frame this partition was created", HFILL }},
3933 { &hf_scsi_osd_partition_removed_in,
3934 { "Removed In", "scsi_osd.partition.removed_in", FT_FRAMENUM, BASE_NONE,
3935 NULL, 0x0, "The frame this partition was removed", HFILL }},
3937 { &hf_scsi_osd_flush_scope,
3938 {"Flush Scope", "scsi_osd.flush.scope", FT_UINT8, BASE_DEC,
3939 VALS(flush_scope_vals), 0x03, NULL, HFILL}},
3941 { &hf_scsi_osd_flush_collection_scope,
3942 {"Flush Collection Scope", "scsi_osd.flush_collection.scope", FT_UINT8, BASE_DEC,
3943 VALS(flush_collection_scope_vals), 0x03, NULL, HFILL}},
3945 { &hf_scsi_osd_flush_partition_scope,
3946 {"Flush Partition Scope", "scsi_osd.flush_partition.scope", FT_UINT8, BASE_DEC,
3947 VALS(flush_partition_scope_vals), 0x03, NULL, HFILL}},
3949 { &hf_scsi_osd_flush_osd_scope,
3950 {"Flush OSD Scope", "scsi_osd.flush_osd.scope", FT_UINT8, BASE_DEC,
3951 VALS(flush_osd_scope_vals), 0x03, NULL, HFILL}},
3952 { &hf_scsi_osd_attributes_list_type,
3953 {"Attributes List Type", "scsi_osd.attributes_list.type", FT_UINT8, BASE_HEX,
3954 VALS(attributes_list_type_vals), 0x0f, NULL, HFILL}},
3955 { &hf_scsi_osd_attributes_list_length,
3956 {"Attributes List Length", "scsi_osd.attributes_list.length", FT_UINT16, BASE_DEC,
3957 NULL, 0, NULL, HFILL}},
3958 { &hf_scsi_osd_attributes_page,
3959 {"Attributes Page", "scsi_osd.attributes.page", FT_UINT32, BASE_HEX,
3960 VALS(attributes_page_vals), 0, NULL, HFILL}},
3961 { &hf_scsi_osd_attribute_number,
3962 {"Attribute Number", "scsi_osd.attribute.number", FT_UINT32, BASE_HEX,
3963 NULL, 0, NULL, HFILL}},
3964 { &hf_scsi_osd_attribute_length,
3965 {"Attribute Length", "scsi_osd.attribute.length", FT_UINT16, BASE_DEC,
3966 NULL, 0, NULL, HFILL}},
3967 { &hf_scsi_osd2_attributes_list_length,
3968 {"Attributes List Length", "scsi_osd2.attributes_list.length", FT_UINT32, BASE_DEC,
3969 NULL, 0, NULL, HFILL}},
3970 { &hf_scsi_osd_attrval_user_object_logical_length,
3971 {"User Object Logical Length", "scsi_osd.user_object.logical_length", FT_UINT64, BASE_DEC,
3972 NULL, 0, NULL, HFILL}},
3973 { &hf_scsi_osd_attrval_object_type,
3974 {"Object Type", "scsi_osd.attr.object_type", FT_UINT8, BASE_HEX, VALS(scsi_osd_object_type_vals), 0, NULL, HFILL}},
3975 { &hf_scsi_osd_attrval_partition_id,
3976 {"Partition ID", "scsi_osd.attr.partition_id", FT_UINT64, BASE_HEX,
3977 NULL, 0, NULL, HFILL}},
3978 { &hf_scsi_osd_attrval_object_id,
3979 {"Object ID", "scsi_osd.attr.object_id", FT_UINT64, BASE_HEX,
3980 NULL, 0, NULL, HFILL}},
3981 { &hf_scsi_osd2_set_attribute_value,
3982 {"Set Attributes Value", "scsi_osd.set_attribute_value", FT_BYTES, BASE_NONE, 0, 0, NULL, HFILL}},
3983 { &hf_scsi_osd2_isolation,
3984 {"Isolation", "scsi_osd2.isolation", FT_UINT8, BASE_HEX, VALS(scsi_osd2_isolation_val), 0x0F, NULL, HFILL}},
3985 { &hf_scsi_osd2_list_attr,
3986 {"LIST ATTR flag", "scsi_osd2.list_attr", FT_BOOLEAN, 8, 0, 0x40, NULL, HFILL}},
3987 { &hf_scsi_osd2_object_descriptor_format,
3988 {"Object Descriptor Format", "scsi_osd2.object_descriptor_format", FT_UINT8, BASE_HEX, VALS(scsi_osd2_object_descriptor_format_val), 0xFC, NULL, HFILL}},
3989 { &hf_scsi_osd2_immed_tr,
3990 {"Immed TR", "scsi_osd2.immed_tr", FT_UINT8, BASE_DEC, 0, 0x80, NULL, HFILL}},
3991 { &hf_scsi_osd2_remove_scope,
3992 {"Remove scope","scsi_osd2.remove_scope", FT_UINT8, BASE_HEX, VALS(scsi_osd2_remove_scope), 0x07, NULL, HFILL}},
3993 { &hf_scsi_osd2_source_collection_object_id,
3994 {"Source Collection Object ID", "scsi_osd2.source_collection_object_id", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}},
3995 { &hf_scsi_osd2_matches_collection_object_id,
3996 {"Matches Collection Object ID", "scsi_osd2.matches_collection_object_id", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}},
3997 { &hf_scsi_osd2_cdb_continuation_length,
3998 {"CDB Continuation Length", "scsi_osd2.cdb_continuation.length", FT_UINT32, BASE_DEC, 0, 0, NULL, HFILL}},
3999 { &hf_scsi_osd2_cdb_continuation_format,
4000 {"CDB Continuation Format", "scsi_osd2.cdb_continuation.format", FT_UINT8, BASE_HEX, VALS(scsi_osd2_cdb_continuation_format_val), 0, NULL, HFILL}},
4001 { &hf_scsi_osd2_continued_service_action,
4002 {"Continued Service Action", "scsi_osd2.cdb_continuation.sa", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL}},
4003 { &hf_scsi_osd2_cdb_continuation_descriptor_type,
4004 {"Descriptor Type", "scsi_osd2.cdb_continuation.desc.type", FT_UINT16, BASE_HEX, VALS(scsi_osd2_cdb_continuation_descriptor_type_val), 0, NULL, HFILL}},
4005 { &hf_scsi_osd2_cdb_continuation_descriptor_pad_length,
4006 {"Descriptor Pad Length", "scsi_osd2.cdb_continuation.desc.padlen", FT_UINT8, BASE_DEC, NULL, 0x7, NULL, HFILL}},
4007 { &hf_scsi_osd2_cdb_continuation_descriptor_length,
4008 {"Descriptor Length", "scsi_osd2.cdb_continuation.desc.length", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
4009 { &hf_scsi_osd2_query_type,
4010 {"Query Type", "scsi_osd2.query.type", FT_UINT8, BASE_HEX, VALS(scsi_osd2_query_type_vals), 0x0f, NULL, HFILL}},
4011 { &hf_scsi_osd2_query_entry_length,
4012 {"Entry Length", "scsi_osd2.query.entry.length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
4013 { &hf_scsi_osd2_query_attributes_page,
4014 {"Attributes Page", "scsi_osd2.query.entry.page", FT_UINT32, BASE_HEX, VALS(attributes_page_vals), 0, NULL, HFILL}},
4015 { &hf_scsi_osd2_query_attribute_number,
4016 {"Attribute Number", "scsi_osd2.query.entry.number", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL}},
4017 { &hf_scsi_osd2_query_minimum_attribute_value_length,
4018 {"Minimum Attribute Value Length", "scsi_osd2.query.entry.min_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
4019 { &hf_scsi_osd2_query_maximum_attribute_value_length,
4020 {"Maximum Attribute Value Length", "scsi_osd2.query.entry.max_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
4023 /* Setup protocol subtree array */
4024 static gint *ett[] = {
4025 &ett_osd_option,
4026 &ett_osd_partition,
4027 &ett_osd_attribute_parameters,
4028 &ett_osd_capability,
4029 &ett_osd_permission_bitmask,
4030 &ett_osd_security_parameters,
4031 &ett_osd_get_attributes,
4032 &ett_osd_set_attributes,
4033 &ett_osd_multi_object,
4034 &ett_osd_attribute,
4035 &ett_osd2_query_criteria_entry,
4038 /* Setup expert info */
4039 static ei_register_info ei[] = {
4040 { &ei_osd_attr_unknown, { "scsi_osd.attr_unknown", PI_UNDECODED, PI_NOTE, "Unknown attribute, cannot decode attribute value", EXPFILL }},
4041 { &ei_osd2_invalid_offset, { "scsi_osd2.invalid_offset", PI_UNDECODED, PI_ERROR, "Invalid offset exponent", EXPFILL }},
4042 { &ei_osd2_invalid_object_descriptor_format, { "scsi_osd2.object_descriptor_format.invalid", PI_UNDECODED, PI_ERROR, "Invalid list format", EXPFILL }},
4043 { &ei_osd_unknown_attributes_list_type, {"scsi_osd.attributes_list.type.invalid", PI_UNDECODED, PI_ERROR, "Unknown attribute list type", EXPFILL }},
4044 { &ei_osd2_cdb_continuation_format_unknown, {"scsi_osd2.cdb_continuation.format.unknown", PI_UNDECODED, PI_ERROR, "Unknown CDB Continuation Format", EXPFILL }},
4045 { &ei_osd2_continued_service_action_mismatch, {"scsi_osd2.cdb_continuation.sa.mismatch", PI_PROTOCOL, PI_WARN, "CONTINUED SERVICE ACTION and SERVICE ACTION do not match", EXPFILL }},
4046 { &ei_osd2_cdb_continuation_descriptor_type_unknown, {"scsi_osd2.cdb_continuation.desc.type.unknown", PI_UNDECODED, PI_WARN, "Unknown descriptor type", EXPFILL }},
4047 { &ei_osd2_cdb_continuation_descriptor_length_invalid, {"scsi_osd2.cdb_continuation.desc.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid descriptor length (not a multiple of 8)", EXPFILL }},
4048 { &ei_osd2_cdb_continuation_length_invalid, {"scsi_osd2.cdb_continuation.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid CDB continuation length", EXPFILL }},
4049 { &ei_osd_attr_length_invalid, {"scsi_osd.attribute_length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Attribute Length", EXPFILL }},
4050 { &ei_osd2_query_values_equal,{"scsi_osd2.query.entry.equal",PI_PROTOCOL,PI_NOTE,"The minimum and maximum values are equal", EXPFILL }},
4053 /* Register the protocol name and description */
4054 proto_scsi_osd = proto_register_protocol("SCSI_OSD", "SCSI_OSD", "scsi_osd");
4056 /* Required function calls to register the header fields and subtrees used */
4057 proto_register_field_array(proto_scsi_osd, hf, array_length(hf));
4058 proto_register_subtree_array(ett, array_length(ett));
4060 /* Register expert info */
4061 expert_scsi_osd = expert_register_protocol(proto_scsi_osd);
4062 expert_register_field_array(expert_scsi_osd, ei, array_length(ei));
4065 void
4066 proto_reg_handoff_scsi_osd(void)
4070 * Editor modelines
4072 * Local Variables:
4073 * c-basic-offset: 4
4074 * tab-width: 8
4075 * indent-tabs-mode: nil
4076 * End:
4078 * ex: set shiftwidth=4 tabstop=8 expandtab:
4079 * :indentSize=4:tabSize=8:noTabs=true: