Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-scsi-osd.c
blobe2dff863d909aaf77f44453782850e18fac9e725
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 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 2002 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/conversation.h>
19 #include <epan/expert.h>
20 #include <epan/tfs.h>
21 #include <wsutil/array.h>
22 #include "packet-scsi.h"
23 #include "packet-scsi-osd.h"
25 void proto_register_scsi_osd(void);
27 static int proto_scsi_osd;
28 int hf_scsi_osd_opcode;
29 static int hf_scsi_osd_add_cdblen;
30 static int hf_scsi_osd_svcaction;
31 static int hf_scsi_osd_option;
32 static int hf_scsi_osd_option_dpo;
33 static int hf_scsi_osd_option_fua;
34 static int hf_scsi_osd_getsetattrib;
35 static int hf_scsi_osd_timestamps_control;
36 static int hf_scsi_osd_formatted_capacity;
37 static int hf_scsi_osd_get_attributes_page;
38 static int hf_scsi_osd_get_attributes_allocation_length;
39 static int hf_scsi_osd_get_attributes_list_length;
40 static int hf_scsi_osd_get_attributes_list_offset;
41 static int hf_scsi_osd_retrieved_attributes_offset;
42 static int hf_scsi_osd_set_attributes_page;
43 static int hf_scsi_osd_set_attribute_length;
44 static int hf_scsi_osd_set_attribute_number;
45 static int hf_scsi_osd_set_attributes_offset;
46 static int hf_scsi_osd_set_attributes_list_length;
47 static int hf_scsi_osd_set_attributes_list_offset;
48 static int hf_scsi_osd_capability_format;
49 static int hf_scsi_osd_key_version;
50 static int hf_scsi_osd_icva;
51 static int hf_scsi_osd_security_method;
52 static int hf_scsi_osd_capability_expiration_time;
53 static int hf_scsi_osd_audit;
54 static int hf_scsi_osd_capability_discriminator;
55 static int hf_scsi_osd_object_created_time;
56 static int hf_scsi_osd_object_type;
57 static int hf_scsi_osd_permissions;
58 static int hf_scsi_osd_permissions_read;
59 static int hf_scsi_osd_permissions_write;
60 static int hf_scsi_osd_permissions_get_attr;
61 static int hf_scsi_osd_permissions_set_attr;
62 static int hf_scsi_osd_permissions_create;
63 static int hf_scsi_osd_permissions_remove;
64 static int hf_scsi_osd_permissions_obj_mgmt;
65 static int hf_scsi_osd_permissions_append;
66 static int hf_scsi_osd_permissions_dev_mgmt;
67 static int hf_scsi_osd_permissions_global;
68 static int hf_scsi_osd_permissions_pol_sec;
69 static int hf_scsi_osd_object_descriptor_type;
70 static int hf_scsi_osd_object_descriptor;
71 static int hf_scsi_osd_ricv;
72 static int hf_scsi_osd_request_nonce;
73 static int hf_scsi_osd_diicvo;
74 static int hf_scsi_osd_doicvo;
75 static int hf_scsi_osd_requested_partition_id;
76 static int hf_scsi_osd_sortorder;
77 static int hf_scsi_osd_partition_id;
78 static int hf_scsi_osd_list_identifier;
79 static int hf_scsi_osd_allocation_length;
80 static int hf_scsi_osd_length;
81 static int hf_scsi_osd_starting_byte_address;
82 static int hf_scsi_osd_initial_object_id;
83 static int hf_scsi_osd_additional_length;
84 static int hf_scsi_osd_continuation_object_id;
85 static int hf_scsi_osd_list_flags_lstchg;
86 static int hf_scsi_osd_list_flags_root;
87 static int hf_scsi_osd_list_collection_flags_coltn;
88 static int hf_scsi_osd_user_object_id;
89 static int hf_scsi_osd_requested_user_object_id;
90 static int hf_scsi_osd_number_of_user_objects;
91 static int hf_scsi_osd_key_to_set;
92 static int hf_scsi_osd_set_key_version;
93 static int hf_scsi_osd_key_identifier;
94 static int hf_scsi_osd_seed;
95 static int hf_scsi_osd_collection_fcr;
96 static int hf_scsi_osd_collection_object_id;
97 static int hf_scsi_osd_requested_collection_object_id;
98 static int hf_scsi_osd_partition_created_in;
99 static int hf_scsi_osd_partition_removed_in;
100 static int hf_scsi_osd_flush_scope;
101 static int hf_scsi_osd_flush_collection_scope;
102 static int hf_scsi_osd_flush_partition_scope;
103 static int hf_scsi_osd_flush_osd_scope;
104 static int hf_scsi_osd_attributes_list_type;
105 static int hf_scsi_osd_attributes_list_length;
106 static int hf_scsi_osd_attributes_page;
107 static int hf_scsi_osd_attribute_number;
108 static int hf_scsi_osd_attribute_length;
109 static int hf_scsi_osd_attrval_user_object_logical_length;
110 static int hf_scsi_osd_attrval_object_type;
111 static int hf_scsi_osd_attrval_partition_id;
112 static int hf_scsi_osd_attrval_object_id;
113 static int hf_scsi_osd2_query_type;
114 static int hf_scsi_osd2_query_entry_length;
115 static int hf_scsi_osd2_query_attributes_page;
116 static int hf_scsi_osd2_query_attribute_number;
117 static int hf_scsi_osd2_query_minimum_attribute_value_length;
118 static int hf_scsi_osd2_query_maximum_attribute_value_length;
120 /* Fields that are defined in OSD-2 are prefixed with hf_scsi_osd2_ */
121 static int hf_scsi_osd2_attributes_list_length;
122 static int hf_scsi_osd2_set_attribute_value;
123 static int hf_scsi_osd2_isolation;
124 static int hf_scsi_osd2_immed_tr;
125 static int hf_scsi_osd2_list_attr;
126 static int hf_scsi_osd2_object_descriptor_format;
127 static int hf_scsi_osd2_matches_collection_object_id;
128 static int hf_scsi_osd2_source_collection_object_id;
129 static int hf_scsi_osd2_cdb_continuation_length;
130 static int hf_scsi_osd2_cdb_continuation_format;
131 static int hf_scsi_osd2_continued_service_action;
132 static int hf_scsi_osd2_cdb_continuation_descriptor_type;
133 static int hf_scsi_osd2_cdb_continuation_descriptor_pad_length;
134 static int hf_scsi_osd2_cdb_continuation_descriptor_length;
135 static int hf_scsi_osd2_remove_scope;
137 static int ett_osd_option;
138 static int ett_osd_partition;
139 static int ett_osd_attribute_parameters;
140 static int ett_osd_capability;
141 static int ett_osd_permission_bitmask;
142 static int ett_osd_security_parameters;
143 static int ett_osd_get_attributes;
144 static int ett_osd_set_attributes;
145 static int ett_osd_multi_object;
146 static int ett_osd_attribute;
147 static int ett_osd2_query_criteria_entry;
149 static expert_field ei_osd_attr_unknown;
150 static expert_field ei_osd2_invalid_offset;
151 static expert_field ei_osd2_invalid_object_descriptor_format;
152 static expert_field ei_osd_unknown_attributes_list_type;
153 static expert_field ei_osd2_cdb_continuation_format_unknown;
154 static expert_field ei_osd2_continued_service_action_mismatch;
155 static expert_field ei_osd2_cdb_continuation_descriptor_type_unknown;
156 static expert_field ei_osd2_cdb_continuation_descriptor_length_invalid;
157 static expert_field ei_osd2_cdb_continuation_length_invalid;
158 static expert_field ei_osd_attr_length_invalid;
159 static expert_field ei_osd2_query_values_equal;
161 #define PAGE_NUMBER_OBJECT 0x00000000
162 #define PAGE_NUMBER_PARTITION 0x30000000
163 #define PAGE_NUMBER_COLLECTION 0x60000000
164 #define PAGE_NUMBER_ROOT 0x90000000
167 /* There will be one such structure create for each conversation ontop of which
168 * there is an OSD session
170 typedef struct _scsi_osd_conv_info_t {
171 wmem_tree_t *luns;
172 } scsi_osd_conv_info_t;
174 /* there will be one such structure created for each lun for each conversation
175 * that is handled by the OSD dissector
177 struct _scsi_osd_lun_info_t {
178 wmem_tree_t *partitions;
181 typedef void (*scsi_osd_dissector_t)(tvbuff_t *tvb, packet_info *pinfo,
182 proto_tree *tree, unsigned offset,
183 bool isreq, bool iscdb,
184 uint32_t payload_len, scsi_task_data_t *cdata,
185 scsi_osd_conv_info_t *conv_info,
186 scsi_osd_lun_info_t *lun_info
189 /* One such structure is created per conversation/lun/partition to
190 * keep track of when partitions are created/used/destroyed
192 typedef struct _partition_info_t {
193 int created_in;
194 int removed_in;
195 } partition_info_t;
198 /* This is a set of extra data specific to OSD that we need to attach to every
199 * task.
201 typedef struct _scsi_osd_extra_data_t {
202 uint16_t svcaction;
203 uint8_t gsatype;
204 union {
205 struct { /* gsatype: attribute list */
206 uint32_t get_list_length;
207 uint32_t get_list_offset;
208 uint32_t get_list_allocation_length;
209 uint32_t retrieved_list_offset;
210 uint32_t set_list_length;
211 uint32_t set_list_offset;
212 } al;
213 } u;
214 uint32_t continuation_length;
215 bool osd2;
216 } scsi_osd_extra_data_t;
218 static proto_item*
219 dissect_osd_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
221 /* user object id */
222 proto_item *item;
223 item = proto_tree_add_item(tree, hf_scsi_osd_user_object_id, tvb, offset, 8, ENC_NA);
224 return item;
228 /*dissects an attribute that is defined as a pair of hf_index, length*/
229 static void
230 generic_attribute_dissector(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
231 scsi_osd_lun_info_t *lun_info _U_, const attribute_page_numbers_t *att)
233 proto_tree_add_item(tree, *att->hf_index, tvb, 0, att->expected_length, ENC_BIG_ENDIAN);
236 static proto_item *
237 dissect_osd_partition_id(packet_info *pinfo, tvbuff_t *tvb, int offset,
238 proto_tree *tree, int hf_index,
239 scsi_osd_lun_info_t *lun_info, bool is_created,
240 bool is_removed);
242 static void
243 partition_id_attribute_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
244 scsi_osd_lun_info_t *lun_info, const attribute_page_numbers_t *att)
246 dissect_osd_partition_id(pinfo, tvb, 0, tree, *att->hf_index, lun_info, false, false);
249 static const attribute_page_numbers_t user_object_info_attributes[] = {
250 {0x82, "User object logical length", generic_attribute_dissector, &hf_scsi_osd_attrval_user_object_logical_length, 8},
251 {0, NULL, NULL, NULL, 0}
254 static const attribute_page_numbers_t current_command_attributes[] = {
255 {0x02, "Object Type", generic_attribute_dissector, &hf_scsi_osd_attrval_object_type, 1},
256 {0x03, "Partition ID", partition_id_attribute_dissector, &hf_scsi_osd_attrval_partition_id, 8},
257 {0x04, "Collection Object ID or User Object ID", generic_attribute_dissector, &hf_scsi_osd_attrval_object_id, 8},
258 {0, NULL, NULL, NULL, 0}
261 typedef struct _attribute_pages_t {
262 uint32_t page;
263 const attribute_page_numbers_t *attributes;
264 } attribute_pages_t;
266 static const attribute_pages_t attribute_pages[] = {
267 {PAGE_NUMBER_OBJECT+1, user_object_info_attributes},
268 {0xFFFFFFFE, current_command_attributes},
269 {0, NULL}
272 static const value_string attributes_page_vals[] = {
273 {PAGE_NUMBER_OBJECT+0, "User Object Directory"},
274 {PAGE_NUMBER_OBJECT+1, "User Object Information"},
275 {PAGE_NUMBER_OBJECT+2, "User Object Quotas"},
276 {PAGE_NUMBER_OBJECT+3, "User Object Timestamps"},
277 {PAGE_NUMBER_OBJECT+4, "User Object Collections"},
278 {PAGE_NUMBER_OBJECT+5, "User Object Policy/Security"},
279 {PAGE_NUMBER_PARTITION, "Partition Directory"},
280 {PAGE_NUMBER_PARTITION+1, "Partition Information"},
281 {PAGE_NUMBER_PARTITION+2, "Partition Quotas"},
282 {PAGE_NUMBER_PARTITION+3, "Partition Timestamps"},
283 {PAGE_NUMBER_PARTITION+5, "Partition Policy/Security"},
284 {PAGE_NUMBER_COLLECTION, "Collection Directory"},
285 {PAGE_NUMBER_COLLECTION+1, "Collection Information"},
286 {PAGE_NUMBER_COLLECTION+2, "Collection Quotas"},
287 {PAGE_NUMBER_COLLECTION+4, "Collection Command Tracking"},
288 {PAGE_NUMBER_COLLECTION+5, "Collection Policy/Security"},
289 {PAGE_NUMBER_ROOT, "Root Directory"},
290 {PAGE_NUMBER_ROOT+1, "Root Information"},
291 {PAGE_NUMBER_ROOT+2, "Root Quotas"},
292 {PAGE_NUMBER_ROOT+3, "Root Timestamps"},
293 {PAGE_NUMBER_ROOT+5, "Root Policy/Security"},
294 {0xFFFFFFFE, "Current Command"},
295 {0xFFFFFFFF, "All attribute pages"},
296 {0, NULL}
298 value_string_ext attributes_page_vals_ext = VALUE_STRING_EXT_INIT(attributes_page_vals);
300 static const value_string attributes_list_type_vals[] = {
301 {0x01, "Retrieve attributes for this OSD object"},
302 {0x09, "Retrieve/Set attributes for this OSD object"},
303 {0x0f, "Retrieve attributes for a CREATE command"},
304 {0, NULL}
307 static const value_string scsi_osd2_isolation_val[] = {
308 {0x00, "Default"},
309 {0x01, "None"},
310 {0x02, "Strict"},
311 {0x04, "Range"},
312 {0x05, "Functional"},
313 {0x07, "Vendor specific"},
314 {0, NULL}
317 static const value_string scsi_osd2_object_descriptor_format_val[] = {
318 {0x01, "Partition ID"},
319 {0x02, "Partition ID followed by attribute parameters"},
320 {0x11, "Collection ID"},
321 {0x12, "Collection ID followed by attribute parameters"},
322 {0x21, "User Object ID"},
323 {0x22, "User Object ID followed by attribute parameters"},
324 {0, NULL}
327 static const value_string scsi_osd2_remove_scope[] = {
328 {0x00, "Fail if there are collections or user objects in the partition"},
329 {0x01, "Remove collections and user objects in the partition"},
330 {0, NULL}
333 static const value_string scsi_osd2_cdb_continuation_format_val[] = {
334 {0x01, "OSD2"},
335 {0, NULL}
338 static const value_string scsi_osd2_cdb_continuation_descriptor_type_val[] = {
339 {0x0000, "No more continuation descriptors"},
340 {0x0001, "Scatter/gather list"},
341 {0x0002, "Query list"},
342 {0x0100, "User object"},
343 {0x0101, "Copy user object source"},
344 {0xFFEE, "Extension capabilities"},
345 {0, NULL}
348 static const value_string scsi_osd2_query_type_vals[] = {
349 {0x00, "Match any query criteria"},
350 {0x01, "Match all query criteria"},
351 {0, NULL}
354 /* OSD2/3 helper functions */
356 static void
357 dissect_osd2_isolation(tvbuff_t *tvb, int offset, proto_tree *tree)
359 /* isolation */
360 proto_tree_add_item(tree, hf_scsi_osd2_isolation, tvb, offset, 1, ENC_BIG_ENDIAN);
363 static void
364 dissect_osd2_list_attr(tvbuff_t *tvb, int offset, proto_tree *tree)
366 /* list_attr */
367 proto_tree_add_item(tree, hf_scsi_osd2_list_attr, tvb, offset, 1, ENC_BIG_ENDIAN);
371 /* used by dissect_osd_attributes_list, dissect_osd2_attribute_list_entry
372 and dissect_scsi_descriptor_snsinfo from packet-scsi.c*/
373 const attribute_page_numbers_t *
374 osd_lookup_attribute(uint32_t page, uint32_t number)
376 const attribute_pages_t *ap;
377 const attribute_page_numbers_t *apn;
379 /* find the proper attributes page */
380 apn = NULL;
381 for (ap=attribute_pages;ap->attributes;ap++) {
382 if (ap->page == page) {
383 apn = ap->attributes;
384 break;
387 if (!apn) return NULL;
389 /* find the specific attribute */
390 for (;apn->name;apn++) {
391 if (apn->number == number) {
392 break;
395 if (!apn->name) return NULL;
397 /* found it */
398 return apn;
401 /* OSD-1: 7.1.3.3, OSD2 7.1.4.3 list entry format */
402 static uint32_t
403 dissect_osd_attribute_list_entry(packet_info *pinfo, tvbuff_t *tvb,
404 proto_tree *tree, proto_item *item,
405 uint32_t offset, scsi_osd_lun_info_t *lun_info,
406 bool osd2)
408 uint16_t attribute_length;
409 uint32_t page, number;
410 const attribute_page_numbers_t *apn;
412 /* attributes page */
413 page = tvb_get_ntohl(tvb, offset);
414 proto_tree_add_item(tree, hf_scsi_osd_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
415 offset += 4;
417 /* attribute number */
418 number = tvb_get_ntohl(tvb, offset);
419 proto_tree_add_item(tree, hf_scsi_osd_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
420 offset += 4;
422 if (osd2) {
423 /*6 reserved bytes*/
424 offset += 6;
427 /* attribute length */
428 attribute_length = tvb_get_ntohs(tvb, offset);
429 proto_tree_add_item(tree, hf_scsi_osd_attribute_length, tvb, offset, 2, ENC_BIG_ENDIAN);
430 offset += 2;
432 proto_item_append_text(item, " 0x%08x (%s)", page, val_to_str_ext_const(page, &attributes_page_vals_ext, "Unknown"));
433 proto_item_append_text(item, " 0x%08x", number);
434 apn= osd_lookup_attribute(page, number);
436 if (!apn) {
437 expert_add_info(pinfo, item, &ei_osd_attr_unknown);
438 proto_item_append_text(item, " (Unknown)");
439 } else {
440 proto_item_append_text(item, " (%s)", apn->name);
442 /* attribute value */
443 if (attribute_length) {
444 if (attribute_length != apn->expected_length) {
445 proto_tree_add_expert_format(tree, pinfo, &ei_osd_attr_length_invalid,
446 tvb, 0, attribute_length, "%s", apn->name);
447 } else {
448 tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset, attribute_length);
449 apn->dissector(next_tvb, pinfo, tree, lun_info, apn);
454 offset += attribute_length;
455 if (osd2 && (attribute_length&7)) {
456 /* 8-bit padding */
457 offset += 8-(attribute_length&7);
460 return offset;
463 /* OSD1: 7.1.3.1
464 OSD2: 7.1.4.1*/
465 static void
466 dissect_osd_attributes_list(packet_info *pinfo, tvbuff_t *tvb, int offset,
467 proto_tree *tree, scsi_osd_lun_info_t *lun_info,
468 bool osd2)
470 uint8_t type;
471 uint32_t length;
472 uint32_t page, number;
473 int start_offset = offset;
474 proto_item *item, *list_type_item;
475 const attribute_page_numbers_t *apn;
477 /* list type */
478 type = tvb_get_uint8(tvb, offset)&0x0f;
479 list_type_item = proto_tree_add_item(tree, hf_scsi_osd_attributes_list_type, tvb, offset, 1, ENC_BIG_ENDIAN);
480 offset += 1;
482 /* OSD-1: a reserved byte */
483 /* OSD-2: 3 reserved bytes */
484 offset += (osd2?3:1);
486 /* OSD-1: length (16 bit)
487 OSD-2: length (32 bit) */
488 if (osd2) {
489 length = tvb_get_ntohl(tvb, offset);
490 proto_tree_add_item(tree, hf_scsi_osd2_attributes_list_length, tvb, offset, 4, ENC_BIG_ENDIAN);
491 offset += 4;
492 } else {
493 length = tvb_get_ntohs(tvb, offset);
494 proto_tree_add_item(tree, hf_scsi_osd_attributes_list_length, tvb, offset, 2, ENC_BIG_ENDIAN);
495 offset += 2;
498 /* if type is 1 length will be zero and we have to cycle over
499 * all remaining bytes. 7.1.3.1
501 if (!osd2 && type == 1) {
502 length = tvb_reported_length_remaining(tvb, offset);
505 length += (osd2?8:4);
507 while ( (uint32_t)(offset-start_offset)<length ) {
508 proto_item *ti;
509 proto_tree *tt;
510 uint32_t attribute_entry_length;
512 switch (type) {
513 case 0x01:
514 attribute_entry_length = 8;
515 break;
516 case 0x0f:
517 attribute_entry_length = 18+tvb_get_ntohs(tvb, offset+16);
518 break;
519 case 0x09:
520 if (osd2) {
521 attribute_entry_length = 16+tvb_get_ntohs(tvb, offset+14);
522 } else {
523 attribute_entry_length = 10+tvb_get_ntohs(tvb, offset+8);
525 break;
526 default:
527 expert_add_info(pinfo, list_type_item, &ei_osd_unknown_attributes_list_type);
528 return;
531 if ((uint32_t)(offset-start_offset)+attribute_entry_length>length) break;
532 tt = proto_tree_add_subtree(tree, tvb, offset, attribute_entry_length, ett_osd_attribute, &ti, "Attribute:");
534 switch (type) {
535 case 0x01: /* retrieving attributes 7.1.3.2 */
536 /* attributes page */
537 page = tvb_get_ntohl(tvb, offset);
538 proto_tree_add_item(tt, hf_scsi_osd_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
539 offset += 4;
541 /* attribute number */
542 number = tvb_get_ntohl(tvb, offset);
543 item = proto_tree_add_item(tt, hf_scsi_osd_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
544 offset += 4;
546 proto_item_append_text(ti, " 0x%08x (%s)", page, val_to_str_ext_const(page, &attributes_page_vals_ext, "Unknown"));
547 proto_item_append_text(ti, " 0x%08x", number);
549 /* find the proper attributes page */
550 apn = osd_lookup_attribute(page, number);
551 if (!apn) {
552 proto_item_append_text(ti, " (Unknown)");
553 proto_item_append_text(item, " (Unknown)");
554 } else {
555 proto_item_append_text(ti, " (%s)", apn->name);
556 proto_item_append_text(item, " (%s)", apn->name);
558 break;
559 case 0x0f: /* create attributes 7.1.3.4 */
560 /* user object id */
561 dissect_osd_user_object_id(tvb, offset, tt);
562 offset += 8;
563 /* fallthrough */
564 case 0x09: /* retrieved/set attributes OSD-1: 7.1.3.3 OSD-2: 7.1.4.3*/
565 offset = dissect_osd_attribute_list_entry(pinfo, tvb, tt, ti, offset, lun_info, osd2);
566 break;
572 /* OSD2 5.2.4 */
573 static void
574 dissect_osd_option(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
576 proto_tree *tree;
577 proto_item *it;
578 uint8_t option;
580 option = tvb_get_uint8(tvb, offset);
582 it = proto_tree_add_item(parent_tree, hf_scsi_osd_option, tvb, offset, 1, ENC_BIG_ENDIAN);
583 tree = proto_item_add_subtree(it, ett_osd_option);
585 proto_tree_add_item(tree, hf_scsi_osd_option_dpo, tvb, offset, 1, ENC_BIG_ENDIAN);
586 if (option&0x10) {
587 proto_item_append_text(tree, " DPO");
590 proto_tree_add_item(tree, hf_scsi_osd_option_fua, tvb, offset, 1, ENC_BIG_ENDIAN);
591 if (option&0x08) {
592 proto_item_append_text(tree, " FUA");
597 static const value_string scsi_osd_getsetattrib_vals[] = {
598 {1, "Set one attribute using CDB fields (OSD-2)"},
599 {2, "Get an attributes page and set an attribute value"},
600 {3, "Get and set attributes using a list"},
601 {0, NULL},
604 /* OSD2 5.2.2.1 */
605 static void
606 dissect_osd_getsetattrib(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
608 if (cdata && cdata->itlq && cdata->itlq->extra_data) {
609 scsi_osd_extra_data_t *extra_data = (scsi_osd_extra_data_t *)cdata->itlq->extra_data;
610 extra_data->gsatype = (tvb_get_uint8(tvb, offset)>>4)&0x03;
612 proto_tree_add_item(tree, hf_scsi_osd_getsetattrib, tvb, offset, 1, ENC_BIG_ENDIAN);
615 static const value_string scsi_osd_timestamps_control_vals[] = {
616 {0x00, "Timestamps shall be updated"},
617 {0x7f, "Timestamps shall not be updated"},
618 {0, NULL},
621 /* OSD2 5.2.8 */
622 static void
623 dissect_osd_timestamps_control(tvbuff_t *tvb, int offset, proto_tree *tree)
625 proto_tree_add_item(tree, hf_scsi_osd_timestamps_control, tvb, offset, 1, ENC_BIG_ENDIAN);
629 static void
630 dissect_osd_formatted_capacity(tvbuff_t *tvb, int offset, proto_tree *tree)
632 proto_tree_add_item(tree, hf_scsi_osd_formatted_capacity, tvb, offset, 8, ENC_BIG_ENDIAN);
635 static void
636 dissect_osd_offset(packet_info *pinfo, tvbuff_t *tvb, int offset,
637 proto_tree *tree, int field, uint32_t *raw_value_ptr,
638 bool osd2)
640 /* dissects an OSD offset value, add proto item and updates *raw_value_ptr */
641 uint32_t value = *raw_value_ptr;
643 if (value != 0xFFFFFFFF) {
644 if (!osd2) {
645 /*OSD-1: the exponent is an unsigned value (4.12.5)*/
646 value = (value & 0x0fffffff) << ((value>>28) & 0x0f);
647 value <<= 8;
648 } else {
649 /*OSD-2: the exponent is a signed value (4.15.5)*/
650 int exponent = (value>>28);
651 uint32_t mantissa = (value&0x0FFFFFFF);
653 if (exponent&0x8) {
654 exponent = -(((~exponent)&7)+1);
655 if (exponent <=- 6 && mantissa != 0xFFFFFFF) {
656 proto_item *item;
657 item = proto_tree_add_uint(tree, field, tvb, offset, 4, value);
658 expert_add_info(pinfo, item, &ei_osd2_invalid_offset);
659 *raw_value_ptr = 0xFFFFFFFF;
660 return;
663 value = mantissa << (exponent+8);
666 proto_tree_add_uint(tree, field, tvb, offset, 4, value);
667 *raw_value_ptr = value;
670 static int
671 dissect_osd_attribute_parameters(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *parent_tree, scsi_task_data_t *cdata)
673 uint8_t gsatype = 0;
674 proto_tree *tree;
675 scsi_osd_extra_data_t *extra_data = NULL;
676 bool osd2;
678 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 28,
679 ett_osd_attribute_parameters, NULL, "Attribute Parameters");
681 if (cdata && cdata->itlq && cdata->itlq->extra_data) {
682 extra_data = (scsi_osd_extra_data_t *)cdata->itlq->extra_data;
683 gsatype = extra_data->gsatype;
684 osd2 = extra_data->osd2;
685 } else {
686 return offset;
689 switch (gsatype) {
690 case 1: /* OSD-2 5.2.6.2 Set one attribute using CDB fields*/
691 if (osd2) {
692 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
693 offset += 4;
694 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
695 offset += 4;
696 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, ENC_BIG_ENDIAN);
697 offset += 4;
698 proto_tree_add_item(tree, hf_scsi_osd2_set_attribute_value, tvb, offset, 18, ENC_NA);
699 offset += 18;
701 break;
702 case 2: /* 5.2.2.2 attribute page */
703 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
704 offset += 4;
705 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, ENC_BIG_ENDIAN);
706 offset += 4;
707 proto_tree_add_item(tree, hf_scsi_osd_retrieved_attributes_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
708 offset += 4;
709 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
710 offset += 4;
711 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
712 offset += 4;
713 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, ENC_BIG_ENDIAN);
714 offset += 4;
715 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
716 offset += 4;
717 break;
718 case 3: /* 5.2.2.3 attribute list */
719 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_list_length, tvb, offset, 4, ENC_BIG_ENDIAN);
720 extra_data->u.al.get_list_length = tvb_get_ntohl(tvb, offset);
721 offset += 4;
723 /* 4.12.5 */
724 extra_data->u.al.get_list_offset = tvb_get_ntohl(tvb, offset);
725 dissect_osd_offset(pinfo, tvb, offset, tree, hf_scsi_osd_get_attributes_list_offset,
726 &extra_data->u.al.get_list_offset, osd2);
727 if (extra_data->u.al.get_list_offset == 0xFFFFFFFF) {
728 extra_data->u.al.get_list_length = 0;
730 offset += 4;
732 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, ENC_BIG_ENDIAN);
733 extra_data->u.al.get_list_allocation_length = tvb_get_ntohl(tvb, offset);
734 offset += 4;
736 /* 4.12.5 */
737 extra_data->u.al.retrieved_list_offset = tvb_get_ntohl(tvb, offset);
738 dissect_osd_offset(pinfo, tvb, offset, tree, hf_scsi_osd_retrieved_attributes_offset,
739 &extra_data->u.al.retrieved_list_offset, osd2);
740 if (extra_data->u.al.retrieved_list_offset == 0xFFFFFFFF) {
741 extra_data->u.al.get_list_allocation_length = 0;
743 offset += 4;
745 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_list_length, tvb, offset, 4, ENC_BIG_ENDIAN);
746 extra_data->u.al.set_list_length = tvb_get_ntohl(tvb, offset);
747 offset += 4;
749 extra_data->u.al.set_list_offset = tvb_get_ntohl(tvb, offset);
750 dissect_osd_offset(pinfo, tvb, offset, tree, hf_scsi_osd_set_attributes_list_offset,
751 &extra_data->u.al.set_list_offset, osd2);
752 if (extra_data->u.al.set_list_offset == 0xFFFFFFFF) {
753 extra_data->u.al.set_list_length = 0;
755 offset += 4;
757 /* 4 reserved bytes */
758 offset += 4;
760 break;
762 return offset;
766 static void
767 dissect_osd_attribute_data_out(packet_info *pinfo, tvbuff_t *tvb, int offset _U_,
768 proto_tree *tree, scsi_task_data_t *cdata,
769 scsi_osd_lun_info_t *lun_info)
771 uint8_t gsatype = 0;
772 proto_tree *subtree;
773 scsi_osd_extra_data_t *extra_data = NULL;
775 if (cdata && cdata->itlq && cdata->itlq->extra_data) {
776 extra_data = (scsi_osd_extra_data_t *)cdata->itlq->extra_data;
777 gsatype = extra_data->gsatype;
778 } else {
779 return;
782 switch (gsatype) {
783 case 2: /* 5.2.2.2 attribute page */
784 /*qqq*/
785 break;
786 case 3: /* 5.2.2.3 attribute list */
787 if (extra_data->u.al.get_list_length) {
788 subtree = proto_tree_add_subtree(tree, tvb, extra_data->u.al.get_list_offset, extra_data->u.al.get_list_length,
789 ett_osd_get_attributes, NULL, "Get Attributes Segment");
790 dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.get_list_offset, subtree, lun_info, extra_data->osd2);
792 if (extra_data->u.al.set_list_length) {
793 subtree = proto_tree_add_subtree(tree, tvb, extra_data->u.al.set_list_offset, extra_data->u.al.set_list_length,
794 ett_osd_get_attributes, NULL, "Set Attributes Segment");
795 dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.set_list_offset, subtree, lun_info, extra_data->osd2);
797 break;
802 static void
803 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)
805 uint8_t gsatype = 0;
806 scsi_osd_extra_data_t *extra_data = NULL;
808 if (cdata && cdata->itlq && cdata->itlq->extra_data) {
809 extra_data = (scsi_osd_extra_data_t *)cdata->itlq->extra_data;
810 gsatype = extra_data->gsatype;
811 } else {
812 return;
815 switch (gsatype) {
816 case 2: /* 5.2.2.2 attribute page */
817 /*qqq*/
818 break;
819 case 3: /* 5.2.2.3 attribute list */
820 if (extra_data->u.al.get_list_allocation_length) {
821 dissect_osd_attributes_list(pinfo, tvb, extra_data->u.al.retrieved_list_offset, tree, lun_info, extra_data->osd2);
823 break;
827 static void
828 dissect_osd2_cdb_continuation_length(packet_info *pinfo, tvbuff_t *tvb,
829 uint32_t offset, proto_tree *tree,
830 scsi_task_data_t *cdata)
832 scsi_osd_extra_data_t *extra_data;
833 uint32_t continuation_length;
834 proto_item *item;
836 continuation_length = tvb_get_ntohl(tvb, offset);
837 item = proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_length, tvb, offset, 4, ENC_BIG_ENDIAN);
838 if (cdata && cdata->itlq && cdata->itlq->extra_data) {
839 extra_data = (scsi_osd_extra_data_t *)cdata->itlq->extra_data;
840 extra_data->continuation_length = continuation_length;
842 if (continuation_length>0 && continuation_length<40) {
843 expert_add_info(pinfo, item, &ei_osd2_cdb_continuation_length_invalid);
847 static void dissect_osd2_query_list_descriptor(packet_info *pinfo, tvbuff_t *tvb, uint32_t offset, proto_tree *tree, uint32_t length) {
848 uint32_t end = offset+length;
850 /* query type */
851 proto_tree_add_item(tree, hf_scsi_osd2_query_type, tvb, offset, 1, ENC_BIG_ENDIAN);
852 offset += 1;
854 /* 3 reserved bytes */
855 offset += 3;
857 /*query criteria entry*/
858 while (offset<end) {
859 uint32_t page, number;
860 uint32_t min_value_length, max_value_length;
861 uint32_t min_value_offset, max_value_offset;
862 proto_item *item;
863 const attribute_page_numbers_t *apn;
865 /* 2 reserved bytes */
866 offset += 2;
868 /* query entry length */
869 proto_tree_add_item(tree, hf_scsi_osd2_query_entry_length, tvb, offset, 2, ENC_BIG_ENDIAN);
870 offset += 2;
872 /* query attributes page */
873 page = tvb_get_ntohl(tvb, offset);
874 proto_tree_add_item(tree, hf_scsi_osd2_query_attributes_page, tvb, offset, 4, ENC_BIG_ENDIAN);
875 offset += 4;
877 /* query attributes number */
878 number = tvb_get_ntohl(tvb, offset);
879 item = proto_tree_add_item(tree, hf_scsi_osd2_query_attribute_number, tvb, offset, 4, ENC_BIG_ENDIAN);
880 offset += 4;
882 apn = osd_lookup_attribute(page, number);
884 if (!apn) {
885 expert_add_info(pinfo, item, &ei_osd_attr_unknown);
886 proto_item_append_text(item, " (Unknown)");
887 } else {
888 proto_item_append_text(item, " (%s)", apn->name);
891 /* query minimum attribute value length */
892 proto_tree_add_item(tree, hf_scsi_osd2_query_minimum_attribute_value_length, tvb, offset, 2, ENC_BIG_ENDIAN);
893 min_value_length = tvb_get_ntohs(tvb, offset);
894 offset += 2;
896 /* query minimum attribute value */
897 /* if (apn && min_value_length) {
898 call_apn_dissector(tvb, pinfo, tree, lun_info, apn, offset, min_value_length);
899 } */
900 max_value_offset = offset;
901 offset += min_value_length;
903 /* query maximum attribute value length */
904 item = proto_tree_add_item(tree, hf_scsi_osd2_query_maximum_attribute_value_length, tvb, offset, 2, ENC_BIG_ENDIAN);
905 max_value_length = tvb_get_ntohs(tvb, offset);
906 offset += 2;
908 /* xxx query maximum attribute value */
909 /* if (apn && max_value_length) {
910 call_apn_dissector(tvb, pinfo, tree, lun_info, apn, offset, max_value_length);
911 } */
912 min_value_offset = offset;
913 offset += max_value_length;
915 /* test if min and max values are equal */
916 if (max_value_length == min_value_length) {
917 unsigned int i;
918 for (i=0; i<max_value_length; i++) {
919 if (tvb_get_uint8(tvb, max_value_offset+i) != tvb_get_uint8(tvb, min_value_offset+i)) return;
921 expert_add_info(pinfo, item, &ei_osd2_query_values_equal);
926 static void
927 dissect_osd2_cdb_continuation(packet_info *pinfo, tvbuff_t *tvb, uint32_t offset,
928 proto_tree *tree, scsi_task_data_t *cdata)
930 scsi_osd_extra_data_t *extra_data = NULL;
931 proto_item *item;
932 uint8_t format;
933 uint16_t sa;
934 if (cdata && cdata->itlq && cdata->itlq->extra_data) {
935 extra_data = (scsi_osd_extra_data_t *)cdata->itlq->extra_data;
937 if (!extra_data || extra_data->continuation_length<40) return;
939 /* cdb continuation format */
940 item = proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_format, tvb, offset, 1, ENC_BIG_ENDIAN);
941 format = tvb_get_uint8(tvb, offset);
942 if (format != 0x01) {
943 expert_add_info(pinfo, item, &ei_osd2_cdb_continuation_format_unknown);
944 return;
946 offset += 1;
948 /* 1 reserved byte */
949 offset += 1;
951 /* continued service action */
952 item = proto_tree_add_item(tree, hf_scsi_osd2_continued_service_action, tvb, offset, 2, ENC_BIG_ENDIAN);
953 sa = tvb_get_ntohs(tvb, offset);
954 if (sa != extra_data->svcaction) {
955 expert_add_info(pinfo, item, &ei_osd2_continued_service_action_mismatch);
957 offset += 2;
959 /*4 reserved bytes and continuation integrity check value (32 bytes, not dissected)*/
960 offset += 36;
963 /* CDB continuation descriptors */
964 while (offset<extra_data->continuation_length) {
965 uint16_t type;
966 uint32_t length, padlen;
967 proto_item *item_type, *item_length;
969 /* descriptor type */
970 item_type= proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_descriptor_type, tvb, offset, 2, ENC_BIG_ENDIAN);
971 type = tvb_get_ntohs(tvb, offset);
972 offset += 2;
974 /* 1 reserved byte*/
975 offset += 1;
977 /* descriptor pad length */
978 proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_descriptor_pad_length, tvb, offset, 1, ENC_BIG_ENDIAN);
979 padlen = tvb_get_uint8(tvb, offset)&7;
980 offset += 1;
982 /* descriptor length */
983 item_length = proto_tree_add_item(tree, hf_scsi_osd2_cdb_continuation_descriptor_length, tvb, offset, 4, ENC_BIG_ENDIAN);
984 length = tvb_get_ntohl(tvb, offset);
985 offset += 4;
987 switch (type) {
988 case 0x0000: break;
989 case 0x0001: break;
990 case 0x0002: dissect_osd2_query_list_descriptor(pinfo, tvb, offset, tree, length);
991 case 0x0100: break;
992 case 0x0101: break;
993 case 0xFFEE: break;
994 default: expert_add_info(pinfo, item_type, &ei_osd2_cdb_continuation_descriptor_type_unknown);
997 if ((length+padlen)%8) {
998 expert_add_info(pinfo, item_length, &ei_osd2_cdb_continuation_descriptor_length_invalid);
999 return;
1001 /* check for overflow */
1002 if (offset + length + padlen > offset) {
1003 offset += length+padlen;
1010 static const value_string scsi_osd_capability_format_vals[] = {
1011 {0x00, "No Capability"},
1012 {0x01, "SCSI OSD Capabilities"},
1013 {0, NULL},
1015 static const value_string scsi_osd_object_type_vals[] = {
1016 {0x01, "ROOT"},
1017 {0x02, "PARTITION"},
1018 {0x40, "COLLECTION"},
1019 {0x80, "USER"},
1020 {0, NULL},
1022 static const value_string scsi_osd_object_descriptor_type_vals[] = {
1023 {0, "NONE: the object descriptor field shall be ignored"},
1024 {1, "U/C: a single collection or user object"},
1025 {2, "PAR: a single partition, including partition zero"},
1026 {0, NULL},
1030 /* OSD 4.9.2.2.1 */
1031 static void
1032 dissect_osd_permissions(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
1034 proto_tree *tree = NULL;
1035 proto_item *it = NULL;
1036 uint16_t permissions;
1038 permissions = tvb_get_ntohs(tvb, offset);
1040 if (parent_tree) {
1041 it = proto_tree_add_item(parent_tree, hf_scsi_osd_permissions, tvb, offset, 2, ENC_BIG_ENDIAN);
1042 tree = proto_item_add_subtree(it, ett_osd_permission_bitmask);
1045 proto_tree_add_item(tree, hf_scsi_osd_permissions_read, tvb, offset, 2, ENC_BIG_ENDIAN);
1046 if (permissions&0x8000) {
1047 proto_item_append_text(tree, " READ");
1049 proto_tree_add_item(tree, hf_scsi_osd_permissions_write, tvb, offset, 2, ENC_BIG_ENDIAN);
1050 if (permissions&0x4000) {
1051 proto_item_append_text(tree, " WRITE");
1053 proto_tree_add_item(tree, hf_scsi_osd_permissions_get_attr, tvb, offset, 2, ENC_BIG_ENDIAN);
1054 if (permissions&0x2000) {
1055 proto_item_append_text(tree, " GET_ATTR");
1057 proto_tree_add_item(tree, hf_scsi_osd_permissions_set_attr, tvb, offset, 2, ENC_BIG_ENDIAN);
1058 if (permissions&0x1000) {
1059 proto_item_append_text(tree, " SET_ATTR");
1061 proto_tree_add_item(tree, hf_scsi_osd_permissions_create, tvb, offset, 2, ENC_BIG_ENDIAN);
1062 if (permissions&0x0800) {
1063 proto_item_append_text(tree, " CREATE");
1065 proto_tree_add_item(tree, hf_scsi_osd_permissions_remove, tvb, offset, 2, ENC_BIG_ENDIAN);
1066 if (permissions&0x0400) {
1067 proto_item_append_text(tree, " REMOVE");
1069 proto_tree_add_item(tree, hf_scsi_osd_permissions_obj_mgmt, tvb, offset, 2, ENC_BIG_ENDIAN);
1070 if (permissions&0x0200) {
1071 proto_item_append_text(tree, " OBJ_MGMT");
1073 proto_tree_add_item(tree, hf_scsi_osd_permissions_append, tvb, offset, 2, ENC_BIG_ENDIAN);
1074 if (permissions&0x0100) {
1075 proto_item_append_text(tree, " APPEND");
1077 proto_tree_add_item(tree, hf_scsi_osd_permissions_dev_mgmt, tvb, offset, 2, ENC_BIG_ENDIAN);
1078 if (permissions&0x0080) {
1079 proto_item_append_text(tree, " DEV_MGMT");
1081 proto_tree_add_item(tree, hf_scsi_osd_permissions_global, tvb, offset, 2, ENC_BIG_ENDIAN);
1082 if (permissions&0x0040) {
1083 proto_item_append_text(tree, " GLOBAL");
1085 proto_tree_add_item(tree, hf_scsi_osd_permissions_pol_sec, tvb, offset, 2, ENC_BIG_ENDIAN);
1086 if (permissions&0x0020) {
1087 proto_item_append_text(tree, " POL/SEC");
1091 /* OSD-1 4.9.2.2
1092 OSD-2 4.11.2.2 */
1093 static void
1094 dissect_osd_capability(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
1096 proto_tree *tree;
1097 uint8_t format;
1099 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 80,
1100 ett_osd_capability, NULL, "Capability");
1102 /* capability format */
1103 proto_tree_add_item(tree, hf_scsi_osd_capability_format, tvb, offset, 1, ENC_BIG_ENDIAN);
1104 format = tvb_get_uint8(tvb, offset)&0x0F;
1105 offset += 1;
1107 if (format != 1) return;
1109 /* key version and icva */
1110 proto_tree_add_item(tree, hf_scsi_osd_key_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1111 proto_tree_add_item(tree, hf_scsi_osd_icva, tvb, offset, 1, ENC_BIG_ENDIAN);
1112 offset += 1;
1114 /* security method */
1115 proto_tree_add_item(tree, hf_scsi_osd_security_method, tvb, offset, 1, ENC_BIG_ENDIAN);
1116 offset += 1;
1118 /* a reserved byte */
1119 offset += 1;
1121 /* capability expiration time */
1122 proto_tree_add_item(tree, hf_scsi_osd_capability_expiration_time, tvb, offset, 6, ENC_NA);
1123 offset += 6;
1125 /* audit */
1126 proto_tree_add_item(tree, hf_scsi_osd_audit, tvb, offset, 20, ENC_NA);
1127 offset += 20;
1129 /* capability discriminator */
1130 proto_tree_add_item(tree, hf_scsi_osd_capability_discriminator, tvb, offset, 12, ENC_NA);
1131 offset += 12;
1133 /* object created time */
1134 proto_tree_add_item(tree, hf_scsi_osd_object_created_time, tvb, offset, 6, ENC_NA);
1135 offset += 6;
1137 /* object type */
1138 proto_tree_add_item(tree, hf_scsi_osd_object_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1139 offset += 1;
1141 /* permission bitmask */
1142 dissect_osd_permissions(tvb, offset, tree);
1143 offset += 5;
1145 /* a reserved byte */
1146 offset += 1;
1148 /* object descriptor type */
1149 proto_tree_add_item(tree, hf_scsi_osd_object_descriptor_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1150 offset += 1;
1152 /* object descriptor */
1153 proto_tree_add_item(tree, hf_scsi_osd_object_descriptor, tvb, offset, 24, ENC_NA);
1154 /*offset += 24;*/
1156 return;
1161 /* 5.2.6 */
1162 static int
1163 dissect_osd_security_parameters(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
1165 proto_tree *tree;
1167 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 40,
1168 ett_osd_security_parameters, NULL, "Security Parameters");
1170 /* request integrity check value */
1171 proto_tree_add_item(tree, hf_scsi_osd_ricv, tvb, offset, 20, ENC_NA);
1172 offset += 20;
1174 /* request nonce */
1175 proto_tree_add_item(tree, hf_scsi_osd_request_nonce, tvb, offset, 12, ENC_NA);
1176 offset += 12;
1178 /* data in integrity check value offset */
1179 proto_tree_add_item(tree, hf_scsi_osd_diicvo, tvb, offset, 4, ENC_BIG_ENDIAN);
1180 offset += 4;
1182 /* data out integrity check value offset */
1183 proto_tree_add_item(tree, hf_scsi_osd_doicvo, tvb, offset, 4, ENC_BIG_ENDIAN);
1184 offset += 4;
1186 return offset;
1189 static void
1190 dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1191 unsigned offset, bool isreq, bool iscdb,
1192 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
1193 scsi_osd_conv_info_t *conv_info _U_,
1194 scsi_osd_lun_info_t *lun_info _U_)
1196 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1197 if (isreq && iscdb) {
1198 /* options byte */
1199 dissect_osd_option(tvb, offset, tree);
1200 offset += 1;
1202 /* getset attributes byte */
1203 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1204 offset += 1;
1206 /* timestamps control */
1207 dissect_osd_timestamps_control(tvb, offset, tree);
1208 offset += 1;
1210 /* 23 reserved bytes */
1211 offset += 23;
1213 /* formatted capacity */
1214 dissect_osd_formatted_capacity(tvb, offset, tree);
1215 offset += 8;
1217 /* 8 reserved bytes */
1218 offset += 8;
1220 /* attribute parameters */
1221 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1222 offset += 28;
1224 /* capability */
1225 dissect_osd_capability(tvb, offset, tree);
1226 offset += 80;
1228 /* security parameters */
1229 dissect_osd_security_parameters(tvb, offset, tree);
1230 offset += 40;
1233 /* dissecting the DATA OUT */
1234 if (isreq && !iscdb) {
1235 /* attribute data out */
1236 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1238 /* no data out for format osd */
1241 /* dissecting the DATA IN */
1242 if (!isreq && !iscdb) {
1243 /* attribute data in */
1244 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1246 /* no data in for format osd */
1252 static proto_item*
1253 dissect_osd_partition_id(packet_info *pinfo, tvbuff_t *tvb, int offset,
1254 proto_tree *tree, int hf_index,
1255 scsi_osd_lun_info_t *lun_info, bool is_created,
1256 bool is_removed)
1258 proto_item *item = NULL;
1259 uint32_t partition_id[2];
1261 /* partition id */
1262 item = proto_tree_add_item(tree, hf_index, tvb, offset, 8, ENC_BIG_ENDIAN);
1263 partition_id[0] = tvb_get_ntohl(tvb, offset);
1264 partition_id[1] = tvb_get_ntohl(tvb, offset+4);
1265 if (!partition_id[0] && !partition_id[1]) {
1266 proto_item_append_text(item, " (ROOT partition)");
1267 } else {
1268 partition_info_t *part_info;
1269 wmem_tree_key_t pikey[2];
1270 proto_tree *partition_tree = NULL;
1272 pikey[0].length = 2;
1273 pikey[0].key = partition_id;
1274 pikey[1].length = 0;
1275 part_info = (partition_info_t *)wmem_tree_lookup32_array(lun_info->partitions, &pikey[0]);
1276 if (!part_info) {
1277 part_info = wmem_new(wmem_file_scope(), partition_info_t);
1278 part_info->created_in = 0;
1279 part_info->removed_in = 0;
1281 pikey[0].length = 2;
1282 pikey[0].key = partition_id;
1283 pikey[1].length = 0;
1284 wmem_tree_insert32_array(lun_info->partitions, &pikey[0], part_info);
1286 if (is_created) {
1287 part_info->created_in = pinfo->num;
1289 if (is_removed) {
1290 part_info->removed_in = pinfo->num;
1292 if (item) {
1293 partition_tree = proto_item_add_subtree(item, ett_osd_partition);
1295 if (part_info->created_in) {
1296 proto_item *tmp_item;
1297 tmp_item = proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_created_in, tvb, 0, 0, part_info->created_in);
1298 proto_item_set_generated(tmp_item);
1300 if (part_info->removed_in) {
1301 proto_item *tmp_item;
1302 tmp_item = proto_tree_add_uint(partition_tree, hf_scsi_osd_partition_removed_in, tvb, 0, 0, part_info->removed_in);
1303 proto_item_set_generated(tmp_item);
1307 return item;
1312 static void
1313 dissect_osd_create_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1314 unsigned offset, bool isreq, bool iscdb,
1315 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
1316 scsi_osd_conv_info_t *conv_info _U_,
1317 scsi_osd_lun_info_t *lun_info)
1319 bool osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
1320 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = osd2;
1322 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1323 if (isreq && iscdb) {
1324 /* options byte */
1325 if (osd2) dissect_osd2_isolation(tvb, offset, tree);
1326 dissect_osd_option(tvb, offset, tree);
1327 offset += 1;
1329 /* getset attributes byte */
1330 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1331 offset += 1;
1333 /* timestamps control */
1334 dissect_osd_timestamps_control(tvb, offset, tree);
1335 offset += 1;
1337 /* 3 reserved bytes */
1338 offset += 3;
1340 /* requested partition id */
1341 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_requested_partition_id, lun_info, true, false);
1342 offset += 8;
1344 /* 24 reserved bytes */
1345 offset += 24;
1347 if (osd2) {
1348 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
1349 } else {
1350 /* 4 reserved bytes */
1352 offset += 4;
1354 /* attribute parameters */
1355 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1356 offset += 28;
1358 /* capability */
1359 dissect_osd_capability(tvb, offset, tree);
1360 offset += osd2?104:80;
1362 /* security parameters */
1363 dissect_osd_security_parameters(tvb, offset, tree);
1364 offset += osd2?52:40;
1367 /* dissecting the DATA OUT */
1368 if (isreq && !iscdb) {
1369 /* CDB continuation */
1370 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
1372 /* attribute data out */
1373 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1375 /* no data out for create partition */
1378 /* dissecting the DATA IN */
1379 if (!isreq && !iscdb) {
1380 /* attribute data in */
1381 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1383 /* no data in for create partition */
1388 static const value_string scsi_osd_sort_order_vals[] = {
1389 {0x00, "Ascending numeric value"},
1390 {0, NULL},
1392 static int
1393 dissect_osd_sortorder(tvbuff_t *tvb, int offset, proto_tree *tree)
1395 /* sort order */
1396 proto_tree_add_item(tree, hf_scsi_osd_sortorder, tvb, offset, 1, ENC_BIG_ENDIAN);
1397 offset += 1;
1399 return offset;
1402 static int
1403 dissect_osd_list_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
1405 /* list identifier */
1406 proto_tree_add_item(tree, hf_scsi_osd_list_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
1407 offset += 4;
1409 return offset;
1412 static void
1413 dissect_osd_allocation_length(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
1415 /* allocation length */
1416 proto_tree_add_item(tree, hf_scsi_osd_allocation_length, tvb, offset, 8, ENC_BIG_ENDIAN);
1418 if (cdata) {
1419 uint64_t alloc_len = tvb_get_ntoh64(tvb, offset);
1420 if (alloc_len>INT64_C(0xFFFFFFFF)) {
1421 alloc_len = INT64_C(0xFFFFFFFF);
1423 cdata->itlq->alloc_len = (uint32_t)alloc_len;
1427 static int
1428 dissect_osd_initial_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1430 /* initial object id */
1431 proto_tree_add_item(tree, hf_scsi_osd_initial_object_id, tvb, offset, 8, ENC_NA);
1432 offset += 8;
1434 return offset;
1437 static int
1438 dissect_osd_additional_length(tvbuff_t *tvb, int offset, proto_tree *tree)
1440 /* additional length */
1441 proto_tree_add_item(tree, hf_scsi_osd_additional_length, tvb, offset, 8, ENC_BIG_ENDIAN);
1442 offset += 8;
1444 return offset;
1448 static int
1449 dissect_osd_continuation_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1451 /* continuation object id */
1452 proto_tree_add_item(tree, hf_scsi_osd_continuation_object_id, tvb, offset, 8, ENC_NA);
1453 offset += 8;
1455 return offset;
1458 static const true_false_string list_lstchg_tfs = {
1459 "List has CHANGED since the first List command",
1460 "List has NOT changed since first command"
1462 static const true_false_string list_root_tfs = {
1463 "Objects are from root and are PARTITION IDs",
1464 "Objects are from the partition and are USER OBJECTs"
1466 static const true_false_string list_coltn_tfs = {
1467 "Objects are from the partition and are COLLECTION IDs",
1468 "Objects are from the collection and are USER OBJECTs"
1471 static proto_item*
1472 dissect_osd_collection_object_id(tvbuff_t *tvb, int offset, proto_tree *tree, const int hfindex)
1474 /* collection object id */
1475 proto_item *item;
1476 item = proto_tree_add_item(tree, hfindex, tvb, offset, 8, ENC_NA);
1477 return item;
1480 static void
1481 dissect_osd_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1482 unsigned offset, bool isreq, bool iscdb,
1483 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
1484 scsi_osd_conv_info_t *conv_info _U_,
1485 scsi_osd_lun_info_t *lun_info)
1487 unsigned svcaction = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction;
1488 bool list_collection = (svcaction == 0x8817) || (svcaction == 0x8897);
1489 bool osd2 = svcaction&0x80;
1490 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = osd2;
1492 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1494 if (isreq && iscdb) {
1495 /*byte 10*/
1496 if (osd2) dissect_osd2_isolation(tvb, offset, tree);
1497 offset += 1;
1499 /* getset attributes byte / sort order */
1500 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1501 if (!list_collection) dissect_osd_sortorder(tvb, offset, tree);
1502 if (osd2) dissect_osd2_list_attr(tvb, offset, tree);
1503 offset += 1;
1505 /* timestamps control */
1506 dissect_osd_timestamps_control(tvb, offset, tree);
1507 offset += 1;
1509 /* 3 reserved bytes */
1510 offset += 3;
1512 /* partition id */
1513 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
1514 offset += 8;
1516 if (list_collection) {
1517 /* collection id */
1518 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
1519 } else {
1520 /* 8 reserved bytes */
1522 offset += 8;
1524 if (osd2) {
1525 /* allocation length */
1526 dissect_osd_allocation_length(tvb, offset, tree, cdata);
1527 offset += 8;
1529 /* initial object id */
1530 dissect_osd_initial_object_id(tvb, offset, tree);
1531 offset += 8;
1533 /* list identifier */
1534 dissect_osd_list_identifier(tvb, offset, tree);
1535 offset += 4;
1536 } else {
1537 /* list identifier */
1538 dissect_osd_list_identifier(tvb, offset, tree);
1539 offset += 4;
1541 /* allocation length */
1542 dissect_osd_allocation_length(tvb, offset, tree, cdata);
1543 offset += 8;
1545 /* initial object id */
1546 dissect_osd_initial_object_id(tvb, offset, tree);
1547 offset += 8;
1551 /* attribute parameters */
1552 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1553 offset += 28;
1555 /* capability */
1556 dissect_osd_capability(tvb, offset, tree);
1557 offset += osd2?104:80;
1559 /* security parameters */
1560 dissect_osd_security_parameters(tvb, offset, tree);
1561 offset += osd2?52:40;
1564 /* dissecting the DATA OUT */
1565 if (isreq && !iscdb) {
1566 /* attribute data out */
1567 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1569 /* no data out for LIST or LIST COLLECTION */
1572 /* dissecting the DATA IN */
1573 if (!isreq && !iscdb) {
1575 uint64_t additional_length;
1576 uint64_t allocation_length;
1577 uint64_t remaining_length;
1578 bool is_root_or_coltn;
1579 uint8_t format = 0;
1581 /* attribute data in */
1582 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1584 allocation_length = cdata->itlq->alloc_len;
1585 remaining_length = tvb_captured_length_remaining(tvb, offset);
1586 if (remaining_length<allocation_length) allocation_length = remaining_length;
1587 if (allocation_length<24) return;
1589 /* dissection of the LIST or LIST COLLECTION DATA-IN */
1590 /* additional length */
1591 additional_length = tvb_get_ntoh64(tvb, offset);
1592 if (allocation_length<additional_length) additional_length = allocation_length;
1594 dissect_osd_additional_length(tvb, offset, tree);
1596 offset += 8;
1597 /* continuation object id */
1598 dissect_osd_continuation_object_id(tvb, offset, tree);
1599 offset += 8;
1600 /* list identifier */
1601 dissect_osd_list_identifier(tvb, offset, tree);
1602 offset += 4;
1603 /* 3 reserved bytes */
1604 offset += 3;
1606 /* OSD: LSTCHG and ROOT flags
1607 OSD2: LSTCHG and OBJECT DESCRIPTOR FORMAT*/
1608 proto_tree_add_item(tree, hf_scsi_osd_list_flags_lstchg, tvb, offset, 1, ENC_BIG_ENDIAN);
1609 if (osd2) {
1610 proto_item *item;
1611 item = proto_tree_add_item(tree, hf_scsi_osd2_object_descriptor_format, tvb, offset, 1, ENC_BIG_ENDIAN);
1612 format = tvb_get_uint8(tvb, offset)>>2;
1613 if (format == 0x01 || format == 0x02) {
1614 is_root_or_coltn = true;
1615 if (list_collection) format = 0;
1616 } else if (format == 0x11 || format == 0x12) {
1617 is_root_or_coltn = true;
1618 if (!list_collection) format = 0;
1619 } else if (format == 0x21 || format == 0x22) {
1620 is_root_or_coltn = false;
1621 } else format = 0;
1622 if (!format) {
1623 expert_add_info(pinfo, item, &ei_osd2_invalid_object_descriptor_format);
1624 return;
1626 } else {
1627 if (list_collection) {
1628 proto_tree_add_item(tree, hf_scsi_osd_list_collection_flags_coltn, tvb, offset, 1, ENC_BIG_ENDIAN);
1629 } else {
1630 proto_tree_add_item(tree, hf_scsi_osd_list_flags_root, tvb, offset, 1, ENC_BIG_ENDIAN);
1632 is_root_or_coltn = tvb_get_uint8(tvb, offset)&0x01;
1635 offset += 1;
1637 while (additional_length > (offset-8)) {
1638 proto_item *ti;
1639 /* list of 8-byte IDs; the type of ID is given by is_root_or_coltn and list_collection*/
1640 if (is_root_or_coltn) {
1641 if (list_collection) {
1642 ti = dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
1643 } else {
1644 ti = dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
1646 } else {
1647 ti = dissect_osd_user_object_id(tvb, offset, tree);
1649 offset += 8;
1651 /* for OSD-2 if format is 0x02, 0x12 or 0x22: sub-list of attributes*/
1652 if (osd2 && (format&0x02)) {
1653 uint32_t attr_list_end;
1654 proto_tree *subtree;
1656 if (offset+8>additional_length) break;
1657 subtree = proto_item_add_subtree(ti, ett_osd_multi_object);
1659 /*object type*/
1660 proto_tree_add_item(subtree, hf_scsi_osd_object_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1661 offset += 1;
1662 /* 5 reserved bytes */
1663 offset += 5;
1664 /* attribute list length*/
1665 attr_list_end = offset+2+tvb_get_ntohs(tvb, offset);
1666 offset += 2;
1667 if (attr_list_end>additional_length+8) break;
1668 while (offset+16<attr_list_end) {
1669 uint32_t attribute_length = tvb_get_ntohs(tvb, offset+14);
1670 proto_item *att_item;
1671 proto_tree *att_tree = proto_tree_add_subtree(subtree, tvb, offset, 16+attribute_length, ett_osd_attribute, &att_item, "Attribute:");
1672 offset = dissect_osd_attribute_list_entry(pinfo, tvb, att_tree, att_item, offset, lun_info, true);
1674 offset = attr_list_end;
1682 static int
1683 dissect_osd_requested_user_object_id(tvbuff_t *tvb, int offset, proto_tree *tree)
1685 /* request user object id */
1686 proto_tree_add_item(tree, hf_scsi_osd_requested_user_object_id, tvb, offset, 8, ENC_NA);
1687 offset += 8;
1689 return offset;
1692 static int
1693 dissect_osd_number_of_user_objects(tvbuff_t *tvb, int offset, proto_tree *tree)
1695 /* number_of_user_objects */
1696 proto_tree_add_item(tree, hf_scsi_osd_number_of_user_objects, tvb, offset, 2, ENC_BIG_ENDIAN);
1697 offset += 2;
1699 return offset;
1702 static void
1703 dissect_osd_create(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1704 unsigned offset, bool isreq, bool iscdb,
1705 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
1706 scsi_osd_conv_info_t *conv_info _U_,
1707 scsi_osd_lun_info_t *lun_info)
1709 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1710 if (isreq && iscdb) {
1711 /* options byte */
1712 dissect_osd_option(tvb, offset, tree);
1713 offset += 1;
1715 /* getset attributes byte */
1716 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1717 offset += 1;
1719 /* timestamps control */
1720 dissect_osd_timestamps_control(tvb, offset, tree);
1721 offset += 1;
1723 /* 3 reserved bytes */
1724 offset += 3;
1726 /* partition id */
1727 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
1728 offset += 8;
1730 /* requested user_object id */
1731 dissect_osd_requested_user_object_id(tvb, offset, tree);
1732 offset += 8;
1734 /* 4 reserved bytes */
1735 offset += 4;
1737 /* number of user objects */
1738 dissect_osd_number_of_user_objects(tvb, offset, tree);
1739 offset += 2;
1741 /* 14 reserved bytes */
1742 offset += 14;
1744 /* attribute parameters */
1745 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1746 offset += 28;
1748 /* capability */
1749 dissect_osd_capability(tvb, offset, tree);
1750 offset += 80;
1752 /* security parameters */
1753 dissect_osd_security_parameters(tvb, offset, tree);
1754 offset += 40;
1757 /* dissecting the DATA OUT */
1758 if (isreq && !iscdb) {
1759 /* attribute data out */
1760 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1762 /* no data out for create */
1765 /* dissecting the DATA IN */
1766 if (!isreq && !iscdb) {
1767 /* attribute data in */
1768 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1770 /* no data in for create */
1776 static void
1777 dissect_osd_remove_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1778 unsigned offset, bool isreq, bool iscdb,
1779 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
1780 scsi_osd_conv_info_t *conv_info _U_,
1781 scsi_osd_lun_info_t *lun_info)
1783 bool osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
1784 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = osd2;
1786 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1787 if (isreq && iscdb) {
1788 /* options byte */
1789 if (osd2) dissect_osd2_isolation(tvb, offset, tree);
1790 dissect_osd_option(tvb, offset, tree);
1791 offset += 1;
1793 /* getset attributes byte */
1794 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1795 if (osd2) proto_tree_add_item(tree, hf_scsi_osd2_remove_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
1796 offset += 1;
1798 /* timestamps control */
1799 dissect_osd_timestamps_control(tvb, offset, tree);
1800 offset += 1;
1802 /* 3 reserved bytes */
1803 offset += 3;
1805 /* partition id */
1806 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, true);
1807 offset += 8;
1809 /* 24 reserved bytes */
1810 offset += 24;
1812 if (osd2) {
1813 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
1814 } else {
1815 /* 4 reserved bytes */
1817 offset += 4;
1819 /* attribute parameters */
1820 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1821 offset += 28;
1823 /* capability */
1824 dissect_osd_capability(tvb, offset, tree);
1825 offset += osd2?104:80;
1827 /* security parameters */
1828 dissect_osd_security_parameters(tvb, offset, tree);
1829 offset += osd2?52:40;
1832 /* dissecting the DATA OUT */
1833 if (isreq && !iscdb) {
1834 /* CDB continuation */
1835 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
1837 /* attribute data out */
1838 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1840 /* no data out for remove partition */
1843 /* dissecting the DATA IN */
1844 if (!isreq && !iscdb) {
1845 /* attribute data in */
1846 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1848 /* no data in for remove partition */
1853 static const value_string key_to_set_vals[] = {
1854 {1, "Root"},
1855 {2, "Partition"},
1856 {3, "Working"},
1857 {0, NULL},
1859 static void
1860 dissect_osd_key_to_set(tvbuff_t *tvb, int offset, proto_tree *tree)
1862 proto_tree_add_item(tree, hf_scsi_osd_key_to_set, tvb, offset, 1, ENC_BIG_ENDIAN);
1865 static void
1866 dissect_osd_set_key_version(tvbuff_t *tvb, int offset, proto_tree *tree)
1868 proto_tree_add_item(tree, hf_scsi_osd_set_key_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1871 static void
1872 dissect_osd_key_identifier(tvbuff_t *tvb, int offset, proto_tree *tree)
1874 proto_tree_add_item(tree, hf_scsi_osd_key_identifier, tvb, offset, 7, ENC_NA);
1877 static void
1878 dissect_osd_seed(tvbuff_t *tvb, int offset, proto_tree *tree)
1880 proto_tree_add_item(tree, hf_scsi_osd_seed, tvb, offset, 20, ENC_NA);
1883 static void
1884 dissect_osd_set_key(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1885 unsigned offset, bool isreq, bool iscdb,
1886 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
1887 scsi_osd_conv_info_t *conv_info _U_,
1888 scsi_osd_lun_info_t *lun_info)
1890 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1891 if (isreq && iscdb) {
1892 /* a reserved byte */
1893 offset += 1;
1895 /* getset attributes byte and key to set*/
1896 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1897 dissect_osd_key_to_set(tvb, offset, tree);
1898 offset += 1;
1900 /* timestamps control */
1901 dissect_osd_timestamps_control(tvb, offset, tree);
1902 offset += 1;
1904 /* 3 reserved bytes */
1905 offset += 3;
1907 /* partition id */
1908 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
1909 offset += 8;
1911 /* key version */
1912 dissect_osd_set_key_version(tvb, offset, tree);
1913 offset += 1;
1915 /* key identifier */
1916 dissect_osd_key_identifier(tvb, offset, tree);
1917 offset += 7;
1919 /* seed */
1920 dissect_osd_seed(tvb, offset, tree);
1921 offset += 20;
1923 /* attribute parameters */
1924 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1925 offset += 28;
1927 /* capability */
1928 dissect_osd_capability(tvb, offset, tree);
1929 offset += 80;
1931 /* security parameters */
1932 dissect_osd_security_parameters(tvb, offset, tree);
1933 offset += 40;
1936 /* dissecting the DATA OUT */
1937 if (isreq && !iscdb) {
1938 /* attribute data out */
1939 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
1941 /* no data out for set key */
1944 /* dissecting the DATA IN */
1945 if (!isreq && !iscdb) {
1946 /* attribute data in */
1947 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
1949 /* no data in for set key */
1954 static void
1955 dissect_osd_remove(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1956 unsigned offset, bool isreq, bool iscdb,
1957 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
1958 scsi_osd_conv_info_t *conv_info _U_,
1959 scsi_osd_lun_info_t *lun_info)
1961 /* dissecting the CDB dissection starts at byte 10 of the CDB */
1962 if (isreq && iscdb) {
1963 /* options byte */
1964 dissect_osd_option(tvb, offset, tree);
1965 offset += 1;
1967 /* getset attributes byte */
1968 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
1969 offset += 1;
1971 /* timestamps control */
1972 dissect_osd_timestamps_control(tvb, offset, tree);
1973 offset += 1;
1975 /* 3 reserved bytes */
1976 offset += 3;
1978 /* partition id */
1979 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
1980 offset += 8;
1982 /* user object id */
1983 dissect_osd_user_object_id(tvb, offset, tree);
1984 offset += 8;
1986 /* 20 reserved bytes */
1987 offset += 20;
1989 /* attribute parameters */
1990 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
1991 offset += 28;
1993 /* capability */
1994 dissect_osd_capability(tvb, offset, tree);
1995 offset += 80;
1997 /* security parameters */
1998 dissect_osd_security_parameters(tvb, offset, tree);
1999 offset += 40;
2002 /* dissecting the DATA OUT */
2003 if (isreq && !iscdb) {
2004 /* attribute data out */
2005 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2007 /* no data out for remove */
2010 /* dissecting the DATA IN */
2011 if (!isreq && !iscdb) {
2012 /* attribute data in */
2013 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2015 /* no data in for remove */
2020 static void
2021 dissect_osd_collection_fcr(tvbuff_t *tvb, int offset, proto_tree *tree)
2023 proto_tree_add_item(tree, hf_scsi_osd_collection_fcr, tvb, offset, 1, ENC_BIG_ENDIAN);
2026 static void
2027 dissect_osd_remove_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2028 unsigned offset, bool isreq, bool iscdb,
2029 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2030 scsi_osd_conv_info_t *conv_info _U_,
2031 scsi_osd_lun_info_t *lun_info)
2033 bool osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
2034 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = osd2;
2036 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2037 if (isreq && iscdb) {
2038 /* options byte */
2039 dissect_osd_option(tvb, offset, tree);
2040 offset += 1;
2042 /* getset attributes byte */
2043 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2044 dissect_osd_collection_fcr(tvb, offset, tree);
2045 offset += 1;
2047 /* timestamps control */
2048 dissect_osd_timestamps_control(tvb, offset, tree);
2049 offset += 1;
2051 /* 3 reserved bytes */
2052 offset += 3;
2054 /* partition id */
2055 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2056 offset += 8;
2058 /* collection object id */
2059 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
2060 offset += 8;
2062 /* 16 reserved bytes */
2063 offset += 16;
2065 if (osd2) {
2066 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
2067 } else {
2068 /* 4 reserved bytes */
2070 offset += 4;
2072 /* attribute parameters */
2073 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2074 offset += 28;
2076 /* capability */
2077 dissect_osd_capability(tvb, offset, tree);
2078 offset += osd2?104:80;
2080 /* security parameters */
2081 dissect_osd_security_parameters(tvb, offset, tree);
2082 offset += osd2?52:40;
2085 /* dissecting the DATA OUT */
2086 if (isreq && !iscdb) {
2087 /* CDB continuation */
2088 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
2090 /* attribute data out */
2091 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2093 /* no data out for remove collection */
2096 /* dissecting the DATA IN */
2097 if (!isreq && !iscdb) {
2098 /* attribute data in */
2099 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2101 /* no data in for remove collection */
2107 static int
2108 dissect_osd_length(tvbuff_t *tvb, int offset, proto_tree *tree)
2110 /* length */
2111 proto_tree_add_item(tree, hf_scsi_osd_length, tvb, offset, 8, ENC_BIG_ENDIAN);
2112 offset += 8;
2114 return offset;
2117 static int
2118 dissect_osd_starting_byte_address(tvbuff_t *tvb, int offset, proto_tree *tree)
2120 /* starting_byte_address */
2121 proto_tree_add_item(tree, hf_scsi_osd_starting_byte_address, tvb, offset, 8, ENC_BIG_ENDIAN);
2122 offset += 8;
2124 return offset;
2128 static void
2129 dissect_osd_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2130 unsigned offset, bool isreq, bool iscdb,
2131 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2132 scsi_osd_conv_info_t *conv_info _U_,
2133 scsi_osd_lun_info_t *lun_info)
2135 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2136 if (isreq && iscdb) {
2137 /* options byte */
2138 dissect_osd_option(tvb, offset, tree);
2139 offset += 1;
2141 /* getset attributes byte / sort order */
2142 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2143 offset += 1;
2145 /* timestamps control */
2146 dissect_osd_timestamps_control(tvb, offset, tree);
2147 offset += 1;
2149 /* 3 reserved bytes */
2150 offset += 3;
2152 /* partition id */
2153 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2154 offset += 8;
2156 /* user object id */
2157 dissect_osd_user_object_id(tvb, offset, tree);
2158 offset += 8;
2160 /* 4 reserved bytes */
2161 offset += 4;
2163 /* length */
2164 dissect_osd_length(tvb, offset, tree);
2165 offset += 8;
2167 /* starting byte address */
2168 dissect_osd_starting_byte_address(tvb, offset, tree);
2169 offset += 8;
2171 /* attribute parameters */
2172 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2173 offset += 28;
2175 /* capability */
2176 dissect_osd_capability(tvb, offset, tree);
2177 offset += 80;
2179 /* security parameters */
2180 dissect_osd_security_parameters(tvb, offset, tree);
2181 offset += 40;
2184 /* dissecting the DATA OUT */
2185 if (isreq && !iscdb) {
2186 /* attribute data out */
2187 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2189 /* xxx should dissect the data ? */
2192 /* dissecting the DATA IN */
2193 if (!isreq && !iscdb) {
2194 /* attribute data in */
2195 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2197 /* no data in for WRITE */
2202 static void
2203 dissect_osd_create_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2204 unsigned offset, bool isreq, bool iscdb,
2205 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2206 scsi_osd_conv_info_t *conv_info _U_,
2207 scsi_osd_lun_info_t *lun_info)
2209 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2210 if (isreq && iscdb) {
2211 /* options byte */
2212 dissect_osd_option(tvb, offset, tree);
2213 offset += 1;
2215 /* getset attributes byte */
2216 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2217 dissect_osd_collection_fcr(tvb, offset, tree);
2218 offset += 1;
2220 /* timestamps control */
2221 dissect_osd_timestamps_control(tvb, offset, tree);
2222 offset += 1;
2224 /* 3 reserved bytes */
2225 offset += 3;
2227 /* partition id */
2228 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2229 offset += 8;
2231 /* requested collection object id */
2232 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_requested_collection_object_id);
2233 offset += 8;
2235 /* 20 reserved bytes */
2236 offset += 20;
2238 /* attribute parameters */
2239 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2240 offset += 28;
2242 /* capability */
2243 dissect_osd_capability(tvb, offset, tree);
2244 offset += 80;
2246 /* security parameters */
2247 dissect_osd_security_parameters(tvb, offset, tree);
2248 offset += 40;
2251 /* dissecting the DATA OUT */
2252 if (isreq && !iscdb) {
2253 /* attribute data out */
2254 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2256 /* no data out for create collection */
2259 /* dissecting the DATA IN */
2260 if (!isreq && !iscdb) {
2261 /* attribute data in */
2262 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2264 /* no data in for create collection */
2270 static const value_string flush_scope_vals[] = {
2271 {0, "User object data and attributes"},
2272 {1, "User object attributes only"},
2273 {0, NULL}
2276 static int
2277 dissect_osd_flush_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2279 /* flush scope */
2280 proto_tree_add_item(tree, hf_scsi_osd_flush_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2281 offset += 1;
2283 return offset;
2286 static void
2287 dissect_osd_flush(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2288 unsigned offset, bool isreq, bool iscdb,
2289 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2290 scsi_osd_conv_info_t *conv_info _U_,
2291 scsi_osd_lun_info_t *lun_info)
2293 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2294 if (isreq && iscdb) {
2295 /* options byte */
2296 dissect_osd_flush_scope(tvb, offset, tree);
2297 offset += 1;
2299 /* getset attributes byte */
2300 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2301 offset += 1;
2303 /* timestamps control */
2304 dissect_osd_timestamps_control(tvb, offset, tree);
2305 offset += 1;
2307 /* 3 reserved bytes */
2308 offset += 3;
2310 /* partition id */
2311 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2312 offset += 8;
2314 /* user object id */
2315 dissect_osd_user_object_id(tvb, offset, tree);
2316 offset += 8;
2318 /* 20 reserved bytes */
2319 offset += 20;
2321 /* attribute parameters */
2322 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2323 offset += 28;
2325 /* capability */
2326 dissect_osd_capability(tvb, offset, tree);
2327 offset += 80;
2329 /* security parameters */
2330 dissect_osd_security_parameters(tvb, offset, tree);
2331 offset += 40;
2334 /* dissecting the DATA OUT */
2335 if (isreq && !iscdb) {
2336 /* attribute data out */
2337 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2339 /* no data out for flush */
2342 /* dissecting the DATA IN */
2343 if (!isreq && !iscdb) {
2344 /* attribute data in */
2345 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2347 /* no data in for flush */
2353 static const value_string flush_collection_scope_vals[] = {
2354 {0, "List of user objects contained in the collection"},
2355 {1, "Collection attributes only"},
2356 {2, "List of user objects and collection attributes"},
2357 {0, NULL}
2360 static int
2361 dissect_osd_flush_collection_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2363 /* flush collection scope */
2364 proto_tree_add_item(tree, hf_scsi_osd_flush_collection_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2365 offset += 1;
2367 return offset;
2370 static void
2371 dissect_osd_flush_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2372 unsigned offset, bool isreq, bool iscdb,
2373 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2374 scsi_osd_conv_info_t *conv_info _U_,
2375 scsi_osd_lun_info_t *lun_info)
2377 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2378 if (isreq && iscdb) {
2379 /* options byte */
2380 dissect_osd_flush_collection_scope(tvb, offset, tree);
2381 offset += 1;
2383 /* getset attributes byte */
2384 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2385 dissect_osd_collection_fcr(tvb, offset, tree);
2386 offset += 1;
2388 /* timestamps control */
2389 dissect_osd_timestamps_control(tvb, offset, tree);
2390 offset += 1;
2392 /* 3 reserved bytes */
2393 offset += 3;
2395 /* partition id */
2396 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2397 offset += 8;
2399 /* collection object id */
2400 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
2401 offset += 8;
2403 /* 20 reserved bytes */
2404 offset += 20;
2406 /* attribute parameters */
2407 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2408 offset += 28;
2410 /* capability */
2411 dissect_osd_capability(tvb, offset, tree);
2412 offset += 80;
2414 /* security parameters */
2415 dissect_osd_security_parameters(tvb, offset, tree);
2416 offset += 40;
2419 /* dissecting the DATA OUT */
2420 if (isreq && !iscdb) {
2421 /* attribute data out */
2422 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2424 /* no data out for flush collection */
2427 /* dissecting the DATA IN */
2428 if (!isreq && !iscdb) {
2429 /* attribute data in */
2430 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2432 /* no data in for flush collection */
2438 static void
2439 dissect_osd_append(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2440 unsigned offset, bool isreq, bool iscdb,
2441 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2442 scsi_osd_conv_info_t *conv_info _U_,
2443 scsi_osd_lun_info_t *lun_info)
2445 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2446 if (isreq && iscdb) {
2447 /* options byte */
2448 dissect_osd_option(tvb, offset, tree);
2449 offset += 1;
2451 /* getset attributes byte */
2452 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2453 offset += 1;
2455 /* timestamps control */
2456 dissect_osd_timestamps_control(tvb, offset, tree);
2457 offset += 1;
2459 /* 3 reserved bytes */
2460 offset += 3;
2462 /* partition id */
2463 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2464 offset += 8;
2466 /* user object id */
2467 dissect_osd_user_object_id(tvb, offset, tree);
2468 offset += 8;
2470 /* 4 reserved bytes */
2471 offset += 4;
2473 /* length */
2474 dissect_osd_length(tvb, offset, tree);
2475 offset += 8;
2477 /* 8 reserved bytes */
2478 offset += 8;
2480 /* attribute parameters */
2481 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2482 offset += 28;
2484 /* capability */
2485 dissect_osd_capability(tvb, offset, tree);
2486 offset += 80;
2488 /* security parameters */
2489 dissect_osd_security_parameters(tvb, offset, tree);
2490 offset += 40;
2493 /* dissecting the DATA OUT */
2494 if (isreq && !iscdb) {
2495 /* attribute data out */
2496 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2498 /* xxx should dissect the data ? */
2501 /* dissecting the DATA IN */
2502 if (!isreq && !iscdb) {
2503 /* attribute data in */
2504 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2506 /* no data in for append */
2511 static void
2512 dissect_osd_create_and_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2513 unsigned offset, bool isreq, bool iscdb,
2514 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2515 scsi_osd_conv_info_t *conv_info _U_,
2516 scsi_osd_lun_info_t *lun_info)
2518 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2519 if (isreq && iscdb) {
2520 /* options byte */
2521 dissect_osd_option(tvb, offset, tree);
2522 offset += 1;
2524 /* getset attributes byte */
2525 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2526 offset += 1;
2528 /* timestamps control */
2529 dissect_osd_timestamps_control(tvb, offset, tree);
2530 offset += 1;
2532 /* 3 reserved bytes */
2533 offset += 3;
2535 /* partition id */
2536 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2537 offset += 8;
2539 /* requested user_object id */
2540 dissect_osd_requested_user_object_id(tvb, offset, tree);
2541 offset += 8;
2543 /* 4 reserved bytes */
2544 offset += 4;
2546 /* length */
2547 dissect_osd_length(tvb, offset, tree);
2548 offset += 8;
2550 /* starting byte address */
2551 dissect_osd_starting_byte_address(tvb, offset, tree);
2552 offset += 8;
2554 /* attribute parameters */
2555 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2556 offset += 28;
2558 /* capability */
2559 dissect_osd_capability(tvb, offset, tree);
2560 offset += 80;
2562 /* security parameters */
2563 dissect_osd_security_parameters(tvb, offset, tree);
2564 offset += 40;
2567 /* dissecting the DATA OUT */
2568 if (isreq && !iscdb) {
2569 /* attribute data out */
2570 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2572 /* should we dissect the data? */
2575 /* dissecting the DATA IN */
2576 if (!isreq && !iscdb) {
2577 /* attribute data in */
2578 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2580 /* no data in for create and write*/
2586 static const value_string flush_osd_scope_vals[] = {
2587 {0, "List of partitions contained in the OSD logical unit"},
2588 {1, "Root object attributes only"},
2589 {2, "Everything"},
2590 {0, NULL}
2593 static int
2594 dissect_osd_flush_osd_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2596 /* flush osd scope */
2597 proto_tree_add_item(tree, hf_scsi_osd_flush_osd_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2598 offset += 1;
2600 return offset;
2603 static void
2604 dissect_osd_flush_osd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2605 unsigned offset, bool isreq, bool iscdb,
2606 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2607 scsi_osd_conv_info_t *conv_info _U_,
2608 scsi_osd_lun_info_t *lun_info _U_)
2610 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2611 if (isreq && iscdb) {
2612 /* options byte */
2613 dissect_osd_flush_osd_scope(tvb, offset, tree);
2614 offset += 1;
2616 /* getset attributes byte */
2617 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2618 offset += 1;
2620 /* timestamps control */
2621 dissect_osd_timestamps_control(tvb, offset, tree);
2622 offset += 1;
2624 /* 39 reserved bytes */
2625 offset += 39;
2627 /* attribute parameters */
2628 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2629 offset += 28;
2631 /* capability */
2632 dissect_osd_capability(tvb, offset, tree);
2633 offset += 80;
2635 /* security parameters */
2636 dissect_osd_security_parameters(tvb, offset, tree);
2637 offset += 40;
2640 /* dissecting the DATA OUT */
2641 if (isreq && !iscdb) {
2642 /* attribute data out */
2643 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2645 /* no data out for flush osd */
2648 /* dissecting the DATA IN */
2649 if (!isreq && !iscdb) {
2650 /* attribute data in */
2651 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2653 /* no data in for flush osd */
2659 static const value_string flush_partition_scope_vals[] = {
2660 {0, "List of user objects and collections in the partition"},
2661 {1, "Partition attributes only"},
2662 {2, "Everything"},
2663 {0, NULL}
2666 static int
2667 dissect_osd_flush_partition_scope(tvbuff_t *tvb, int offset, proto_tree *tree)
2669 /* flush partition scope */
2670 proto_tree_add_item(tree, hf_scsi_osd_flush_partition_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
2671 offset += 1;
2673 return offset;
2677 static void
2678 dissect_osd_flush_partition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2679 unsigned offset, bool isreq, bool iscdb,
2680 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2681 scsi_osd_conv_info_t *conv_info _U_,
2682 scsi_osd_lun_info_t *lun_info)
2684 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2685 if (isreq && iscdb) {
2686 /* options byte */
2687 dissect_osd_flush_partition_scope(tvb, offset, tree);
2688 offset += 1;
2690 /* getset attributes byte */
2691 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2692 offset += 1;
2694 /* timestamps control */
2695 dissect_osd_timestamps_control(tvb, offset, tree);
2696 offset += 1;
2698 /* 3 reserved bytes */
2699 offset += 3;
2701 /* partition id */
2702 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2703 offset += 8;
2705 /* 28 reserved bytes */
2706 offset += 28;
2708 /* attribute parameters */
2709 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2710 offset += 28;
2712 /* capability */
2713 dissect_osd_capability(tvb, offset, tree);
2714 offset += 80;
2716 /* security parameters */
2717 dissect_osd_security_parameters(tvb, offset, tree);
2718 offset += 40;
2721 /* dissecting the DATA OUT */
2722 if (isreq && !iscdb) {
2723 /* attribute data out */
2724 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2726 /* no data out for flush partition */
2729 /* dissecting the DATA IN */
2730 if (!isreq && !iscdb) {
2731 /* attribute data in */
2732 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2734 /* no data in for flush partition */
2740 static void
2741 dissect_osd_get_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2742 unsigned offset, bool isreq, bool iscdb,
2743 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2744 scsi_osd_conv_info_t *conv_info _U_,
2745 scsi_osd_lun_info_t *lun_info)
2747 bool osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
2748 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = osd2;
2750 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2751 if (isreq && iscdb) {
2752 /* options byte */
2753 dissect_osd_option(tvb, offset, tree);
2754 offset += 1;
2756 /* getset attributes byte */
2757 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2758 offset += 1;
2760 /* timestamps control */
2761 dissect_osd_timestamps_control(tvb, offset, tree);
2762 offset += 1;
2764 /* 3 reserved bytes */
2765 offset += 3;
2767 /* partition id */
2768 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2769 offset += 8;
2771 /* user_object id */
2772 dissect_osd_user_object_id(tvb, offset, tree);
2773 offset += 8;
2775 /* 16 reserved bytes */
2776 offset += 16;
2778 if (osd2) {
2779 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
2780 } else {
2781 /* 4 reserved bytes */
2783 offset += 4;
2785 /* attribute parameters */
2786 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2787 offset += 28;
2789 /* capability */
2790 dissect_osd_capability(tvb, offset, tree);
2791 offset += osd2?104:80;
2793 /* security parameters */
2794 dissect_osd_security_parameters(tvb, offset, tree);
2795 offset += osd2?52:40;
2798 /* dissecting the DATA OUT */
2799 if (isreq && !iscdb) {
2800 /* attribute data out */
2801 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2803 /* no data out for get attributes */
2806 /* dissecting the DATA IN */
2807 if (!isreq && !iscdb) {
2808 /* attribute data in */
2809 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2811 /* no data in for get attributes */
2817 static void
2818 dissect_osd_read(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2819 unsigned offset, bool isreq, bool iscdb,
2820 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2821 scsi_osd_conv_info_t *conv_info _U_,
2822 scsi_osd_lun_info_t *lun_info)
2824 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2825 if (isreq && iscdb) {
2826 /* options byte */
2827 dissect_osd_option(tvb, offset, tree);
2828 offset += 1;
2830 /* getset attributes byte / sort order */
2831 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2832 offset += 1;
2834 /* timestamps control */
2835 dissect_osd_timestamps_control(tvb, offset, tree);
2836 offset += 1;
2838 /* 3 reserved bytes */
2839 offset += 3;
2841 /* partition id */
2842 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2843 offset += 8;
2845 /* user object id */
2846 dissect_osd_user_object_id(tvb, offset, tree);
2847 offset += 8;
2849 /* 4 reserved bytes */
2850 offset += 4;
2852 /* length */
2853 dissect_osd_length(tvb, offset, tree);
2854 offset += 8;
2856 /* starting byte address */
2857 dissect_osd_starting_byte_address(tvb, offset, tree);
2858 offset += 8;
2860 /* attribute parameters */
2861 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2862 offset += 28;
2864 /* capability */
2865 dissect_osd_capability(tvb, offset, tree);
2866 offset += 80;
2868 /* security parameters */
2869 dissect_osd_security_parameters(tvb, offset, tree);
2870 offset += 40;
2873 /* dissecting the DATA OUT */
2874 if (isreq && !iscdb) {
2875 /* attribute data out */
2876 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2878 /* no data out for READ */
2881 /* dissecting the DATA IN */
2882 if (!isreq && !iscdb) {
2883 /* attribute data in */
2884 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2886 /* xxx should dissect the data ? */
2892 static void
2893 dissect_osd_set_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2894 unsigned offset, bool isreq, bool iscdb,
2895 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2896 scsi_osd_conv_info_t *conv_info _U_,
2897 scsi_osd_lun_info_t *lun_info)
2899 bool osd2 = ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->svcaction&0x80;
2900 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = osd2;
2902 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2903 if (isreq && iscdb) {
2904 /* options byte */
2905 dissect_osd_option(tvb, offset, tree);
2906 offset += 1;
2908 /* getset attributes byte */
2909 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2910 offset += 1;
2912 /* timestamps control */
2913 dissect_osd_timestamps_control(tvb, offset, tree);
2914 offset += 1;
2916 /* 3 reserved bytes */
2917 offset += 3;
2919 /* partition id */
2920 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2921 offset += 8;
2923 /* user_object id */
2924 dissect_osd_user_object_id(tvb, offset, tree);
2925 offset += 8;
2927 /* 16 reserved bytes */
2928 offset += 16;
2930 if (osd2) {
2931 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
2932 } else {
2933 /* 4 reserved bytes */
2935 offset += 4;
2937 /* attribute parameters */
2938 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
2939 offset += 28;
2941 /* capability */
2942 dissect_osd_capability(tvb, offset, tree);
2943 offset += osd2?104:80;
2945 /* security parameters */
2946 dissect_osd_security_parameters(tvb, offset, tree);
2947 offset += osd2?52:40;
2950 /* dissecting the DATA OUT */
2951 if (isreq && !iscdb) {
2952 /* attribute data out */
2953 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
2955 /* no data out for set attributes */
2958 /* dissecting the DATA IN */
2959 if (!isreq && !iscdb) {
2960 /* attribute data in */
2961 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
2963 /* no data in for set attributes */
2969 static void
2970 dissect_osd2_create_user_tracking_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2971 unsigned offset, bool isreq, bool iscdb,
2972 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
2973 scsi_osd_conv_info_t *conv_info _U_,
2974 scsi_osd_lun_info_t *lun_info)
2976 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = true;
2978 /* dissecting the CDB dissection starts at byte 10 of the CDB */
2979 if (isreq && iscdb) {
2981 /* options byte */
2982 dissect_osd2_isolation(tvb, offset, tree);
2983 dissect_osd_option(tvb, offset, tree);
2984 offset += 1;
2986 /* getset attributes byte */
2987 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
2988 offset += 1;
2990 /* timestamps control */
2991 dissect_osd_timestamps_control(tvb, offset, tree);
2992 offset += 1;
2994 /* 3 reserved bytes */
2995 offset += 3;
2997 /* partition id */
2998 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
2999 offset += 8;
3001 /* user_object id */
3002 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_requested_collection_object_id);
3003 offset += 8;
3005 /* 8 reserved bytes */
3006 offset += 8;
3008 /* source collection id */
3009 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd2_source_collection_object_id);
3010 offset += 8;
3012 /*cdb continuation length*/
3013 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
3014 offset += 4;
3016 /* attribute parameters */
3017 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
3018 offset += 28;
3020 /* capability */
3021 dissect_osd_capability(tvb, offset, tree);
3022 offset += 104;
3024 /* security parameters */
3025 dissect_osd_security_parameters(tvb, offset, tree);
3026 offset += 52;
3029 /* dissecting the DATA OUT */
3030 if (isreq && !iscdb) {
3031 /* CDB continuation */
3032 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
3034 /* attribute data out */
3035 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
3037 /* no data out for create user tracking collection */
3040 /* dissecting the DATA IN */
3041 if (!isreq && !iscdb) {
3042 /* attribute data in */
3043 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
3045 /* no data in for create user tracking collection */
3050 static void
3051 dissect_osd2_query(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3052 unsigned offset, bool isreq, bool iscdb,
3053 unsigned payload_len _U_, scsi_task_data_t *cdata _U_,
3054 scsi_osd_conv_info_t *conv_info _U_,
3055 scsi_osd_lun_info_t *lun_info)
3057 ((scsi_osd_extra_data_t *)cdata->itlq->extra_data)->osd2 = true;
3059 /* dissecting the CDB dissection starts at byte 10 of the CDB */
3060 if (isreq && iscdb) {
3062 /* isolation field */
3063 dissect_osd2_isolation(tvb, offset, tree);
3064 offset += 1;
3066 /* immed_tr, getset attributes*/
3067 proto_tree_add_item(tree, hf_scsi_osd2_immed_tr, tvb, offset, 1, ENC_BIG_ENDIAN);
3068 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
3069 offset += 1;
3071 /* timestamps control */
3072 dissect_osd_timestamps_control(tvb, offset, tree);
3073 offset += 1;
3075 /* 3 reserved bytes */
3076 offset += 3;
3078 /* partition id */
3079 dissect_osd_partition_id(pinfo, tvb, offset, tree, hf_scsi_osd_partition_id, lun_info, false, false);
3080 offset += 8;
3082 /* collection_object id */
3083 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd_collection_object_id);
3084 offset += 8;
3086 /* allocation_length */
3087 dissect_osd_allocation_length(tvb, offset, tree, cdata);
3088 offset += 8;
3090 /* matches collection id */
3091 dissect_osd_collection_object_id(tvb, offset, tree, hf_scsi_osd2_matches_collection_object_id);
3092 offset += 8;
3094 /*cdb continuation length*/
3095 dissect_osd2_cdb_continuation_length(pinfo, tvb, offset, tree, cdata);
3096 offset += 4;
3098 /* attribute parameters */
3099 dissect_osd_attribute_parameters(pinfo, tvb, offset, tree, cdata);
3100 offset += 28;
3102 /* capability */
3103 dissect_osd_capability(tvb, offset, tree);
3104 offset += 104;
3106 /* security parameters */
3107 dissect_osd_security_parameters(tvb, offset, tree);
3108 offset += 52;
3111 /* dissecting the DATA OUT */
3112 if (isreq && !iscdb) {
3113 /* CDB continuation */
3114 dissect_osd2_cdb_continuation(pinfo, tvb, offset, tree, cdata);
3116 /* attribute data out */
3117 dissect_osd_attribute_data_out(pinfo, tvb, offset, tree, cdata, lun_info);
3119 /* no data out for query */
3122 /* dissecting the DATA IN */
3123 if (!isreq && !iscdb) {
3124 uint64_t additional_length;
3125 uint64_t allocation_length;
3126 uint64_t remaining_length;
3127 uint8_t format;
3128 proto_item *item;
3130 /* attribute data in */
3131 dissect_osd_attribute_data_in(pinfo, tvb, offset, tree, cdata, lun_info);
3133 allocation_length = cdata->itlq->alloc_len;
3134 remaining_length = tvb_captured_length_remaining(tvb, offset);
3135 if (remaining_length<allocation_length) allocation_length = remaining_length;
3136 if (allocation_length<12) return;
3138 /* dissection of the LIST or LIST COLLECTION DATA-IN */
3139 /* additional length */
3140 additional_length = tvb_get_ntoh64(tvb, offset);
3141 if ((uint32_t)(allocation_length-8)<additional_length) additional_length = (uint32_t)(allocation_length-8);
3143 dissect_osd_additional_length(tvb, offset, tree);
3144 offset += 8;
3146 /* 3 reserved bytes */
3147 offset += 3;
3148 item = proto_tree_add_item(tree, hf_scsi_osd2_object_descriptor_format, tvb, offset, 1, ENC_BIG_ENDIAN);
3149 format = tvb_get_uint8(tvb, offset)>>2;
3150 offset += 1;
3151 if (format != 0x21) {
3152 expert_add_info(pinfo, item, &ei_osd2_invalid_object_descriptor_format);
3153 return;
3156 while (additional_length > (offset-4)) {
3157 dissect_osd_user_object_id(tvb, offset, tree);
3158 offset += 8;
3164 /* OSD Service Actions */
3165 #define OSD_FORMAT_OSD 0x8801
3166 #define OSD_CREATE 0x8802
3167 #define OSD_LIST 0x8803
3168 #define OSD_READ 0x8805
3169 #define OSD_WRITE 0x8806
3170 #define OSD_APPEND 0x8807
3171 #define OSD_FLUSH 0x8808
3172 #define OSD_REMOVE 0x880a
3173 #define OSD_CREATE_PARTITION 0x880b
3174 #define OSD_REMOVE_PARTITION 0x880c
3175 #define OSD_GET_ATTRIBUTES 0x880e
3176 #define OSD_SET_ATTRIBUTES 0x880f
3177 #define OSD_CREATE_AND_WRITE 0x8812
3178 #define OSD_CREATE_COLLECTION 0x8815
3179 #define OSD_REMOVE_COLLECTION 0x8816
3180 #define OSD_LIST_COLLECTION 0x8817
3181 #define OSD_SET_KEY 0x8818
3182 #define OSD_FLUSH_COLLECTION 0x881a
3183 #define OSD_FLUSH_PARTITION 0x881b
3184 #define OSD_FLUSH_OSD 0x881c
3186 #define OSD_2_CREATE 0x8882
3187 #define OSD_2_LIST 0x8883
3188 #define OSD_2_READ 0x8885
3189 #define OSD_2_WRITE 0x8886
3190 #define OSD_2_APPEND 0x8887
3191 #define OSD_2_CLEAR 0x8889
3192 #define OSD_2_REMOVE 0x888a
3193 #define OSD_2_CREATE_PARTITION 0x888b
3194 #define OSD_2_REMOVE_PARTITION 0x888c
3195 #define OSD_2_GET_ATTRIBUTES 0x888e
3196 #define OSD_2_SET_ATTRIBUTES 0x888f
3197 #define OSD_2_CREATE_AND_WRITE 0x8892
3198 #define OSD_2_COPY_USER_OBJECTS 0x8893
3199 #define OSD_2_CREATE_USER_TRACKING_COLLECTION 0x8894
3200 #define OSD_2_REMOVE_COLLECTION 0x8896
3201 #define OSD_2_LIST_COLLECTION 0x8897
3202 #define OSD_2_QUERY 0x88a0
3203 #define OSD_2_REMOVE_MEMBER_OBJECTS 0x88a1
3204 #define OSD_2_GET_MEMBER_ATTRIBUTES 0x88a2
3205 #define OSD_2_SET_MEMBER_ATTRIBUTES 0x88a3
3207 static const value_string scsi_osd_svcaction_vals[] = {
3208 {OSD_FORMAT_OSD, "Format OSD"},
3209 {OSD_CREATE, "Create"},
3210 {OSD_LIST, "List"},
3211 {OSD_READ, "Read"},
3212 {OSD_WRITE, "Write"},
3213 {OSD_APPEND, "Append"},
3214 {OSD_FLUSH, "Flush"},
3215 {OSD_REMOVE, "Remove"},
3216 {OSD_CREATE_PARTITION, "Create Partition"},
3217 {OSD_REMOVE_PARTITION, "Remove Partition"},
3218 {OSD_GET_ATTRIBUTES, "Get Attributes"},
3219 {OSD_SET_ATTRIBUTES, "Set Attributes"},
3220 {OSD_CREATE_AND_WRITE, "Create And Write"},
3221 {OSD_CREATE_COLLECTION, "Create Collection"},
3222 {OSD_REMOVE_COLLECTION, "Remove Collection"},
3223 {OSD_LIST_COLLECTION, "List Collection"},
3224 {OSD_SET_KEY, "Set Key"},
3225 {OSD_FLUSH_COLLECTION, "Flush Collection"},
3226 {OSD_FLUSH_PARTITION, "Flush Partition"},
3227 {OSD_FLUSH_OSD, "Flush OSD"},
3229 {OSD_2_CREATE, "Create (OSD-2)"},
3230 {OSD_2_LIST, "List (OSD-2)"},
3231 {OSD_2_READ, "Read (OSD-2)"},
3232 {OSD_2_WRITE, "Write (OSD-2)"},
3233 {OSD_2_APPEND, "Append (OSD-2)"},
3234 {OSD_2_CLEAR, "Clear (OSD-2)"},
3235 {OSD_2_REMOVE, "Remove (OSD-2)"},
3236 {OSD_2_CREATE_PARTITION, "Create Partition (OSD-2)"},
3237 {OSD_2_REMOVE_PARTITION, "Remove Partition (OSD-2)"},
3238 {OSD_2_GET_ATTRIBUTES, "Get Attributes (OSD-2)"},
3239 {OSD_2_SET_ATTRIBUTES, "Set Attributes (OSD-2)"},
3240 {OSD_2_CREATE_AND_WRITE, "Create And Write (OSD-2)"},
3241 {OSD_2_COPY_USER_OBJECTS, "Copy User Objects (OSD-2)"},
3242 {OSD_2_CREATE_USER_TRACKING_COLLECTION, "Create User Tracking Collection (OSD-2)"},
3243 {OSD_2_REMOVE_COLLECTION, "Remove Collection (OSD-2)"},
3244 {OSD_2_LIST_COLLECTION, "List Collection (OSD-2)"},
3245 {OSD_2_QUERY, "Query (OSD-2)"},
3246 {OSD_2_REMOVE_MEMBER_OBJECTS, "Remove Member Objects (OSD-2)"},
3247 {OSD_2_GET_MEMBER_ATTRIBUTES, "Get Member Attributes (OSD-2)"},
3248 {OSD_2_SET_MEMBER_ATTRIBUTES, "Set Member Attributes (OSD-2)"},
3249 {0, NULL},
3251 static value_string_ext scsi_osd_svcaction_vals_ext = VALUE_STRING_EXT_INIT(scsi_osd_svcaction_vals);
3253 /* OSD Service Action dissectors */
3254 typedef struct _scsi_osd_svcaction_t {
3255 uint16_t svcaction;
3256 scsi_osd_dissector_t dissector;
3257 } scsi_osd_svcaction_t;
3259 static const scsi_osd_svcaction_t scsi_osd_svcaction[] = {
3260 {OSD_FORMAT_OSD, dissect_osd_format_osd},
3261 {OSD_CREATE, dissect_osd_create},
3262 {OSD_LIST, dissect_osd_list},
3263 {OSD_READ, dissect_osd_read},
3264 {OSD_WRITE, dissect_osd_write},
3265 {OSD_APPEND, dissect_osd_append},
3266 {OSD_FLUSH, dissect_osd_flush},
3267 {OSD_REMOVE, dissect_osd_remove},
3268 {OSD_CREATE_PARTITION, dissect_osd_create_partition},
3269 {OSD_REMOVE_PARTITION, dissect_osd_remove_partition},
3270 {OSD_GET_ATTRIBUTES, dissect_osd_get_attributes},
3271 {OSD_SET_ATTRIBUTES, dissect_osd_set_attributes},
3272 {OSD_CREATE_AND_WRITE, dissect_osd_create_and_write},
3273 {OSD_CREATE_COLLECTION, dissect_osd_create_collection},
3274 {OSD_REMOVE_COLLECTION, dissect_osd_remove_collection},
3275 {OSD_LIST_COLLECTION, dissect_osd_list},
3276 {OSD_SET_KEY, dissect_osd_set_key},
3277 {OSD_FLUSH_COLLECTION, dissect_osd_flush_collection},
3278 {OSD_FLUSH_PARTITION, dissect_osd_flush_partition},
3279 {OSD_FLUSH_OSD, dissect_osd_flush_osd},
3280 {OSD_2_LIST, dissect_osd_list},
3281 {OSD_2_CREATE_PARTITION, dissect_osd_create_partition},
3282 {OSD_2_CREATE_USER_TRACKING_COLLECTION, dissect_osd2_create_user_tracking_collection},
3283 {OSD_2_REMOVE_PARTITION, dissect_osd_remove_partition},
3284 {OSD_2_LIST_COLLECTION, dissect_osd_list},
3285 {OSD_2_CREATE_USER_TRACKING_COLLECTION, dissect_osd2_create_user_tracking_collection},
3286 {OSD_2_REMOVE_COLLECTION, dissect_osd_remove_collection},
3287 {OSD_2_GET_ATTRIBUTES, dissect_osd_get_attributes},
3288 {OSD_2_SET_ATTRIBUTES, dissect_osd_set_attributes},
3289 {OSD_2_QUERY, dissect_osd2_query},
3290 {0, NULL},
3293 static scsi_osd_dissector_t
3294 find_svcaction_dissector(uint16_t svcaction)
3296 const scsi_osd_svcaction_t *sa = scsi_osd_svcaction;
3298 while (sa && sa->dissector) {
3299 if (sa->svcaction == svcaction) {
3300 return sa->dissector;
3302 sa++;
3304 return NULL;
3309 static void
3310 dissect_osd_opcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3311 unsigned offset, bool isreq, bool iscdb,
3312 unsigned payload_len, scsi_task_data_t *cdata)
3314 uint16_t svcaction = 0;
3315 scsi_osd_dissector_t dissector;
3316 scsi_osd_conv_info_t *conv_info;
3317 scsi_osd_lun_info_t *lun_info;
3319 if (!tree) {
3320 return;
3323 /* We must have an itl an itlq and a conversation */
3324 if (!cdata || !cdata->itl || !cdata->itl->conversation || !cdata->itlq) {
3325 return;
3327 /* make sure we have a conversation info for this */
3328 conv_info = (scsi_osd_conv_info_t *)conversation_get_proto_data(cdata->itl->conversation, proto_scsi_osd);
3329 if (!conv_info) {
3330 conv_info = wmem_new(wmem_file_scope(), scsi_osd_conv_info_t);
3331 conv_info->luns = wmem_tree_new(wmem_file_scope());
3332 conversation_add_proto_data(cdata->itl->conversation, proto_scsi_osd, conv_info);
3334 /* make sure we have a lun_info structure for this */
3335 lun_info = (scsi_osd_lun_info_t *)wmem_tree_lookup32(conv_info->luns, cdata->itlq->lun);
3336 if (!lun_info) {
3337 lun_info = wmem_new(wmem_file_scope(), scsi_osd_lun_info_t);
3338 lun_info->partitions = wmem_tree_new(wmem_file_scope());
3339 wmem_tree_insert32(conv_info->luns, cdata->itlq->lun, (void *)lun_info);
3342 /* dissecting the CDB */
3343 if (isreq && iscdb) {
3344 proto_tree_add_item (tree, hf_scsi_control, tvb, offset, 1, ENC_BIG_ENDIAN);
3345 offset += 1;
3347 /* 5 reserved bytes */
3348 offset += 5;
3350 proto_tree_add_item (tree, hf_scsi_osd_add_cdblen, tvb, offset, 1, ENC_BIG_ENDIAN);
3351 offset += 1;
3353 svcaction = tvb_get_ntohs(tvb, offset);
3354 if (cdata && cdata->itlq) {
3355 /* We must store the service action for this itlq
3356 * so we can identify what the data contains
3358 if ((!pinfo->fd->visited) || (!cdata->itlq->extra_data)) {
3359 scsi_osd_extra_data_t *extra_data;
3361 extra_data = wmem_new0(wmem_file_scope(), scsi_osd_extra_data_t);
3362 extra_data->svcaction = svcaction;
3363 cdata->itlq->extra_data = extra_data;
3366 proto_tree_add_item (tree, hf_scsi_osd_svcaction, tvb, offset, 2, ENC_BIG_ENDIAN);
3367 offset += 2;
3370 col_append_str(pinfo->cinfo, COL_INFO,
3371 val_to_str_ext_const(svcaction, &scsi_osd_svcaction_vals_ext, "Unknown OSD Service Action"));
3373 dissector = find_svcaction_dissector(svcaction);
3374 if (dissector) {
3375 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
3377 return;
3380 /* If it was not a CDB, try to find the service action and pass it
3381 * off to the service action dissector
3383 if (cdata && cdata->itlq && cdata->itlq->extra_data) {
3384 scsi_osd_extra_data_t *extra_data = (scsi_osd_extra_data_t *)cdata->itlq->extra_data;
3385 svcaction = extra_data->svcaction;
3387 col_append_str(pinfo->cinfo, COL_INFO,
3388 val_to_str_ext_const(svcaction, &scsi_osd_svcaction_vals_ext, "Unknown OSD Service Action"));
3389 if (svcaction) {
3390 proto_item *it;
3391 it = proto_tree_add_uint_format_value(tree, hf_scsi_osd_svcaction, tvb, 0, 0, svcaction, "0x%04x", svcaction);
3392 proto_item_set_generated(it);
3394 dissector = find_svcaction_dissector(svcaction);
3395 if (dissector) {
3396 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata, conv_info, lun_info);
3402 /* OSD Commands */
3403 static const value_string scsi_osd_vals[] = {
3404 /* 0x12 */ {SCSI_SPC_INQUIRY, "Inquiry"},
3405 /* 0x4C */ {SCSI_SPC_LOGSELECT, "Log Select"},
3406 /* 0x4D */ {SCSI_SPC_LOGSENSE, "Log Sense"},
3407 /* 0x55 */ {SCSI_SPC_MODESELECT10, "Mode Select(10)"},
3408 /* 0x5A */ {SCSI_SPC_MODESENSE10, "Mode Sense(10)"},
3409 /* 0x5E */ {SCSI_SPC_PERSRESVIN, "Persistent Reserve In"},
3410 /* 0x5F */ {SCSI_SPC_PERSRESVOUT, "Persistent Reserve Out"},
3411 /* 0x7f */ {SCSI_OSD_OPCODE, "OSD Command" },
3412 /* 0xA0 */ {SCSI_SPC_REPORTLUNS, "Report LUNs"},
3413 /* 0xA3 */ {SCSI_SPC_MGMT_PROTOCOL_IN, "Mgmt Protocol In"},
3414 {0, NULL},
3416 value_string_ext scsi_osd_vals_ext = VALUE_STRING_EXT_INIT(scsi_osd_vals);
3418 const scsi_cdb_table_t scsi_osd_table[256] = {
3419 /*OSD 0x00*/{NULL},
3420 /*OSD 0x01*/{NULL},
3421 /*OSD 0x02*/{NULL},
3422 /*OSD 0x03*/{NULL},
3423 /*OSD 0x04*/{NULL},
3424 /*OSD 0x05*/{NULL},
3425 /*OSD 0x06*/{NULL},
3426 /*OSD 0x07*/{NULL},
3427 /*OSD 0x08*/{NULL},
3428 /*OSD 0x09*/{NULL},
3429 /*OSD 0x0a*/{NULL},
3430 /*OSD 0x0b*/{NULL},
3431 /*OSD 0x0c*/{NULL},
3432 /*OSD 0x0d*/{NULL},
3433 /*OSD 0x0e*/{NULL},
3434 /*OSD 0x0f*/{NULL},
3435 /*OSD 0x10*/{NULL},
3436 /*OSD 0x11*/{NULL},
3437 /*OSD 0x12*/{dissect_spc_inquiry},
3438 /*OSD 0x13*/{NULL},
3439 /*OSD 0x14*/{NULL},
3440 /*OSD 0x15*/{NULL},
3441 /*OSD 0x16*/{NULL},
3442 /*OSD 0x17*/{NULL},
3443 /*OSD 0x18*/{NULL},
3444 /*OSD 0x19*/{NULL},
3445 /*OSD 0x1a*/{NULL},
3446 /*OSD 0x1b*/{NULL},
3447 /*OSD 0x1c*/{NULL},
3448 /*OSD 0x1d*/{NULL},
3449 /*OSD 0x1e*/{NULL},
3450 /*OSD 0x1f*/{NULL},
3451 /*OSD 0x20*/{NULL},
3452 /*OSD 0x21*/{NULL},
3453 /*OSD 0x22*/{NULL},
3454 /*OSD 0x23*/{NULL},
3455 /*OSD 0x24*/{NULL},
3456 /*OSD 0x25*/{NULL},
3457 /*OSD 0x26*/{NULL},
3458 /*OSD 0x27*/{NULL},
3459 /*OSD 0x28*/{NULL},
3460 /*OSD 0x29*/{NULL},
3461 /*OSD 0x2a*/{NULL},
3462 /*OSD 0x2b*/{NULL},
3463 /*OSD 0x2c*/{NULL},
3464 /*OSD 0x2d*/{NULL},
3465 /*OSD 0x2e*/{NULL},
3466 /*OSD 0x2f*/{NULL},
3467 /*OSD 0x30*/{NULL},
3468 /*OSD 0x31*/{NULL},
3469 /*OSD 0x32*/{NULL},
3470 /*OSD 0x33*/{NULL},
3471 /*OSD 0x34*/{NULL},
3472 /*OSD 0x35*/{NULL},
3473 /*OSD 0x36*/{NULL},
3474 /*OSD 0x37*/{NULL},
3475 /*OSD 0x38*/{NULL},
3476 /*OSD 0x39*/{NULL},
3477 /*OSD 0x3a*/{NULL},
3478 /*OSD 0x3b*/{NULL},
3479 /*OSD 0x3c*/{NULL},
3480 /*OSD 0x3d*/{NULL},
3481 /*OSD 0x3e*/{NULL},
3482 /*OSD 0x3f*/{NULL},
3483 /*OSD 0x40*/{NULL},
3484 /*OSD 0x41*/{NULL},
3485 /*OSD 0x42*/{NULL},
3486 /*OSD 0x43*/{NULL},
3487 /*OSD 0x44*/{NULL},
3488 /*OSD 0x45*/{NULL},
3489 /*OSD 0x46*/{NULL},
3490 /*OSD 0x47*/{NULL},
3491 /*OSD 0x48*/{NULL},
3492 /*OSD 0x49*/{NULL},
3493 /*OSD 0x4a*/{NULL},
3494 /*OSD 0x4b*/{NULL},
3495 /*OSD 0x4c*/{dissect_spc_logselect},
3496 /*OSD 0x4d*/{dissect_spc_logsense},
3497 /*OSD 0x4e*/{NULL},
3498 /*OSD 0x4f*/{NULL},
3499 /*OSD 0x50*/{NULL},
3500 /*OSD 0x51*/{NULL},
3501 /*OSD 0x52*/{NULL},
3502 /*OSD 0x53*/{NULL},
3503 /*OSD 0x54*/{NULL},
3504 /*OSD 0x55*/{dissect_spc_modeselect10},
3505 /*OSD 0x56*/{NULL},
3506 /*OSD 0x57*/{NULL},
3507 /*OSD 0x58*/{NULL},
3508 /*OSD 0x59*/{NULL},
3509 /*OSD 0x5a*/{dissect_spc_modesense10},
3510 /*OSD 0x5b*/{NULL},
3511 /*OSD 0x5c*/{NULL},
3512 /*OSD 0x5d*/{NULL},
3513 /*OSD 0x5e*/{dissect_spc_persistentreservein},
3514 /*OSD 0x5f*/{dissect_spc_persistentreserveout},
3515 /*OSD 0x60*/{NULL},
3516 /*OSD 0x61*/{NULL},
3517 /*OSD 0x62*/{NULL},
3518 /*OSD 0x63*/{NULL},
3519 /*OSD 0x64*/{NULL},
3520 /*OSD 0x65*/{NULL},
3521 /*OSD 0x66*/{NULL},
3522 /*OSD 0x67*/{NULL},
3523 /*OSD 0x68*/{NULL},
3524 /*OSD 0x69*/{NULL},
3525 /*OSD 0x6a*/{NULL},
3526 /*OSD 0x6b*/{NULL},
3527 /*OSD 0x6c*/{NULL},
3528 /*OSD 0x6d*/{NULL},
3529 /*OSD 0x6e*/{NULL},
3530 /*OSD 0x6f*/{NULL},
3531 /*OSD 0x70*/{NULL},
3532 /*OSD 0x71*/{NULL},
3533 /*OSD 0x72*/{NULL},
3534 /*OSD 0x73*/{NULL},
3535 /*OSD 0x74*/{NULL},
3536 /*OSD 0x75*/{NULL},
3537 /*OSD 0x76*/{NULL},
3538 /*OSD 0x77*/{NULL},
3539 /*OSD 0x78*/{NULL},
3540 /*OSD 0x79*/{NULL},
3541 /*OSD 0x7a*/{NULL},
3542 /*OSD 0x7b*/{NULL},
3543 /*OSD 0x7c*/{NULL},
3544 /*OSD 0x7d*/{NULL},
3545 /*OSD 0x7e*/{NULL},
3546 /*OSD 0x7f*/{dissect_osd_opcode},
3547 /*OSD 0x80*/{NULL},
3548 /*OSD 0x81*/{NULL},
3549 /*OSD 0x82*/{NULL},
3550 /*OSD 0x83*/{NULL},
3551 /*OSD 0x84*/{NULL},
3552 /*OSD 0x85*/{NULL},
3553 /*OSD 0x86*/{NULL},
3554 /*OSD 0x87*/{NULL},
3555 /*OSD 0x88*/{NULL},
3556 /*OSD 0x89*/{NULL},
3557 /*OSD 0x8a*/{NULL},
3558 /*OSD 0x8b*/{NULL},
3559 /*OSD 0x8c*/{NULL},
3560 /*OSD 0x8d*/{NULL},
3561 /*OSD 0x8e*/{NULL},
3562 /*OSD 0x8f*/{NULL},
3563 /*OSD 0x90*/{NULL},
3564 /*OSD 0x91*/{NULL},
3565 /*OSD 0x92*/{NULL},
3566 /*OSD 0x93*/{NULL},
3567 /*OSD 0x94*/{NULL},
3568 /*OSD 0x95*/{NULL},
3569 /*OSD 0x96*/{NULL},
3570 /*OSD 0x97*/{NULL},
3571 /*OSD 0x98*/{NULL},
3572 /*OSD 0x99*/{NULL},
3573 /*OSD 0x9a*/{NULL},
3574 /*OSD 0x9b*/{NULL},
3575 /*OSD 0x9c*/{NULL},
3576 /*OSD 0x9d*/{NULL},
3577 /*OSD 0x9e*/{NULL},
3578 /*OSD 0x9f*/{NULL},
3579 /*OSD 0xa0*/{dissect_spc_reportluns},
3580 /*OSD 0xa1*/{NULL},
3581 /*OSD 0xa2*/{NULL},
3582 /*SPC 0xa3*/{dissect_spc_mgmt_protocol_in},
3583 /*OSD 0xa4*/{NULL},
3584 /*OSD 0xa5*/{NULL},
3585 /*OSD 0xa6*/{NULL},
3586 /*OSD 0xa7*/{NULL},
3587 /*OSD 0xa8*/{NULL},
3588 /*OSD 0xa9*/{NULL},
3589 /*OSD 0xaa*/{NULL},
3590 /*OSD 0xab*/{NULL},
3591 /*OSD 0xac*/{NULL},
3592 /*OSD 0xad*/{NULL},
3593 /*OSD 0xae*/{NULL},
3594 /*OSD 0xaf*/{NULL},
3595 /*OSD 0xb0*/{NULL},
3596 /*OSD 0xb1*/{NULL},
3597 /*OSD 0xb2*/{NULL},
3598 /*OSD 0xb3*/{NULL},
3599 /*OSD 0xb4*/{NULL},
3600 /*OSD 0xb5*/{NULL},
3601 /*OSD 0xb6*/{NULL},
3602 /*OSD 0xb7*/{NULL},
3603 /*OSD 0xb8*/{NULL},
3604 /*OSD 0xb9*/{NULL},
3605 /*OSD 0xba*/{NULL},
3606 /*OSD 0xbb*/{NULL},
3607 /*OSD 0xbc*/{NULL},
3608 /*OSD 0xbd*/{NULL},
3609 /*OSD 0xbe*/{NULL},
3610 /*OSD 0xbf*/{NULL},
3611 /*OSD 0xc0*/{NULL},
3612 /*OSD 0xc1*/{NULL},
3613 /*OSD 0xc2*/{NULL},
3614 /*OSD 0xc3*/{NULL},
3615 /*OSD 0xc4*/{NULL},
3616 /*OSD 0xc5*/{NULL},
3617 /*OSD 0xc6*/{NULL},
3618 /*OSD 0xc7*/{NULL},
3619 /*OSD 0xc8*/{NULL},
3620 /*OSD 0xc9*/{NULL},
3621 /*OSD 0xca*/{NULL},
3622 /*OSD 0xcb*/{NULL},
3623 /*OSD 0xcc*/{NULL},
3624 /*OSD 0xcd*/{NULL},
3625 /*OSD 0xce*/{NULL},
3626 /*OSD 0xcf*/{NULL},
3627 /*OSD 0xd0*/{NULL},
3628 /*OSD 0xd1*/{NULL},
3629 /*OSD 0xd2*/{NULL},
3630 /*OSD 0xd3*/{NULL},
3631 /*OSD 0xd4*/{NULL},
3632 /*OSD 0xd5*/{NULL},
3633 /*OSD 0xd6*/{NULL},
3634 /*OSD 0xd7*/{NULL},
3635 /*OSD 0xd8*/{NULL},
3636 /*OSD 0xd9*/{NULL},
3637 /*OSD 0xda*/{NULL},
3638 /*OSD 0xdb*/{NULL},
3639 /*OSD 0xdc*/{NULL},
3640 /*OSD 0xdd*/{NULL},
3641 /*OSD 0xde*/{NULL},
3642 /*OSD 0xdf*/{NULL},
3643 /*OSD 0xe0*/{NULL},
3644 /*OSD 0xe1*/{NULL},
3645 /*OSD 0xe2*/{NULL},
3646 /*OSD 0xe3*/{NULL},
3647 /*OSD 0xe4*/{NULL},
3648 /*OSD 0xe5*/{NULL},
3649 /*OSD 0xe6*/{NULL},
3650 /*OSD 0xe7*/{NULL},
3651 /*OSD 0xe8*/{NULL},
3652 /*OSD 0xe9*/{NULL},
3653 /*OSD 0xea*/{NULL},
3654 /*OSD 0xeb*/{NULL},
3655 /*OSD 0xec*/{NULL},
3656 /*OSD 0xed*/{NULL},
3657 /*OSD 0xee*/{NULL},
3658 /*OSD 0xef*/{NULL},
3659 /*OSD 0xf0*/{NULL},
3660 /*OSD 0xf1*/{NULL},
3661 /*OSD 0xf2*/{NULL},
3662 /*OSD 0xf3*/{NULL},
3663 /*OSD 0xf4*/{NULL},
3664 /*OSD 0xf5*/{NULL},
3665 /*OSD 0xf6*/{NULL},
3666 /*OSD 0xf7*/{NULL},
3667 /*OSD 0xf8*/{NULL},
3668 /*OSD 0xf9*/{NULL},
3669 /*OSD 0xfa*/{NULL},
3670 /*OSD 0xfb*/{NULL},
3671 /*OSD 0xfc*/{NULL},
3672 /*OSD 0xfd*/{NULL},
3673 /*OSD 0xfe*/{NULL},
3674 /*OSD 0xff*/{NULL}
3680 void
3681 proto_register_scsi_osd(void)
3683 expert_module_t *expert_scsi_osd;
3685 static hf_register_info hf[] = {
3686 { &hf_scsi_osd_opcode,
3687 {"OSD Opcode", "scsi_osd.opcode", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
3688 &scsi_osd_vals_ext, 0x0, NULL, HFILL}},
3689 { &hf_scsi_osd_add_cdblen,
3690 {"Additional CDB Length", "scsi_osd.addcdblen", FT_UINT8, BASE_DEC,
3691 NULL, 0x0, NULL, HFILL}},
3692 { &hf_scsi_osd_svcaction,
3693 {"Service Action", "scsi_osd.svcaction", FT_UINT16, BASE_HEX | BASE_EXT_STRING,
3694 &scsi_osd_svcaction_vals_ext, 0x0, NULL, HFILL}},
3695 { &hf_scsi_osd_option,
3696 {"Options Byte", "scsi_osd.option", FT_UINT8, BASE_HEX,
3697 NULL, 0x0, NULL, HFILL}},
3698 { &hf_scsi_osd_option_dpo,
3699 {"DPO", "scsi_osd.option.dpo", FT_BOOLEAN, 8,
3700 TFS(&tfs_set_notset), 0x10, NULL, HFILL}},
3701 { &hf_scsi_osd_option_fua,
3702 {"FUA", "scsi_osd.option.fua", FT_BOOLEAN, 8,
3703 TFS(&tfs_set_notset), 0x08, NULL, HFILL}},
3704 { &hf_scsi_osd_getsetattrib,
3705 {"GET/SET CDBFMT", "scsi_osd.getset", FT_UINT8, BASE_HEX,
3706 VALS(scsi_osd_getsetattrib_vals), 0x30, NULL, HFILL}},
3707 { &hf_scsi_osd_timestamps_control,
3708 {"Timestamps Control", "scsi_osd.timestamps_control", FT_UINT8, BASE_HEX,
3709 VALS(scsi_osd_timestamps_control_vals), 0x0, NULL, HFILL}},
3710 { &hf_scsi_osd_formatted_capacity,
3711 {"Formatted Capacity", "scsi_osd.formatted_capacity", FT_UINT64, BASE_DEC,
3712 NULL, 0x0, NULL, HFILL}},
3713 { &hf_scsi_osd_get_attributes_page,
3714 {"Get Attributes Page", "scsi_osd.get_attributes_page", FT_UINT32, BASE_HEX,
3715 NULL, 0x0, NULL, HFILL}},
3716 { &hf_scsi_osd_get_attributes_list_length,
3717 {"Get Attributes List Length", "scsi_osd.get_attributes_list_length", FT_UINT32, BASE_DEC_HEX,
3718 NULL, 0x0, NULL, HFILL}},
3719 { &hf_scsi_osd_get_attributes_list_offset,
3720 {"Get Attributes List Offset", "scsi_osd.get_attributes_list_offset", FT_UINT32, BASE_HEX,
3721 NULL, 0x0, NULL, HFILL}},
3722 { &hf_scsi_osd_set_attributes_list_length,
3723 {"Set Attributes List Length", "scsi_osd.set_attributes_list_length", FT_UINT32, BASE_DEC_HEX,
3724 NULL, 0x0, NULL, HFILL}},
3725 { &hf_scsi_osd_set_attributes_list_offset,
3726 {"Set Attributes List Offset", "scsi_osd.set_attributes_list_offset", FT_UINT32, BASE_HEX,
3727 NULL, 0x0, NULL, HFILL}},
3728 { &hf_scsi_osd_get_attributes_allocation_length,
3729 {"Get Attributes Allocation Length", "scsi_osd.get_attributes_allocation_length", FT_UINT32, BASE_DEC_HEX,
3730 NULL, 0x0, NULL, HFILL}},
3731 { &hf_scsi_osd_retrieved_attributes_offset,
3732 {"Retrieved Attributes Offset", "scsi_osd.retrieved_attributes_offset", FT_UINT32, BASE_HEX,
3733 NULL, 0x0, NULL, HFILL}},
3734 { &hf_scsi_osd_set_attributes_page,
3735 {"Set Attributes Page", "scsi_osd.set_attributes_page", FT_UINT32, BASE_HEX,
3736 NULL, 0x0, NULL, HFILL}},
3737 { &hf_scsi_osd_set_attribute_length,
3738 {"Set Attribute Length", "scsi_osd.set_attribute_length", FT_UINT32, BASE_DEC_HEX,
3739 NULL, 0x0, NULL, HFILL}},
3740 { &hf_scsi_osd_set_attribute_number,
3741 {"Set Attribute Number", "scsi_osd.set_attribute_number", FT_UINT32, BASE_HEX,
3742 NULL, 0x0, NULL, HFILL}},
3743 { &hf_scsi_osd_set_attributes_offset,
3744 {"Set Attributes Offset", "scsi_osd.set_attributes_offset", FT_UINT32, BASE_HEX,
3745 NULL, 0x0, NULL, HFILL}},
3746 { &hf_scsi_osd_capability_format,
3747 {"Capability Format", "scsi_osd.capability_format", FT_UINT8, BASE_HEX,
3748 VALS(scsi_osd_capability_format_vals), 0x0f, NULL, HFILL}},
3749 { &hf_scsi_osd_key_version,
3750 {"Key Version", "scsi_osd.key_version", FT_UINT8, BASE_HEX,
3751 NULL, 0xf0, NULL, HFILL}},
3752 { &hf_scsi_osd_icva,
3753 {"Integrity Check Value Algorithm", "scsi_osd.icva", FT_UINT8, BASE_HEX,
3754 NULL, 0x0f, NULL, HFILL}},
3755 { &hf_scsi_osd_security_method,
3756 {"Security Method", "scsi_osd.security_method", FT_UINT8, BASE_HEX,
3757 NULL, 0x0f, NULL, HFILL}},
3758 { &hf_scsi_osd_capability_expiration_time,
3759 {"Capability Expiration Time", "scsi_osd.capability_expiration_time", FT_BYTES, BASE_NONE,
3760 NULL, 0, NULL, HFILL}},
3761 { &hf_scsi_osd_audit,
3762 {"Audit", "scsi_osd.audit", FT_BYTES, BASE_NONE,
3763 NULL, 0, NULL, HFILL}},
3764 { &hf_scsi_osd_capability_discriminator,
3765 {"Capability Discriminator", "scsi_osd.capability_discriminator", FT_BYTES, BASE_NONE,
3766 NULL, 0, NULL, HFILL}},
3767 { &hf_scsi_osd_object_created_time,
3768 {"Object Created Time", "scsi_osd.object_created_time", FT_BYTES, BASE_NONE,
3769 NULL, 0, NULL, HFILL}},
3770 { &hf_scsi_osd_object_type,
3771 {"Object Type", "scsi_osd.object_type", FT_UINT8, BASE_HEX,
3772 VALS(scsi_osd_object_type_vals), 0, NULL, HFILL}},
3773 { &hf_scsi_osd_permissions,
3774 {"Permissions", "scsi_osd.permissions", FT_UINT16, BASE_HEX,
3775 NULL, 0, NULL, HFILL}},
3776 { &hf_scsi_osd_permissions_read,
3777 {"READ", "scsi_osd.permissions.read", FT_BOOLEAN, 16,
3778 TFS(&tfs_set_notset), 0x8000, NULL, HFILL}},
3779 { &hf_scsi_osd_permissions_write,
3780 {"WRITE", "scsi_osd.permissions.write", FT_BOOLEAN, 16,
3781 TFS(&tfs_set_notset), 0x4000, NULL, HFILL}},
3782 { &hf_scsi_osd_permissions_get_attr,
3783 {"GET_ATTR", "scsi_osd.permissions.get_attr", FT_BOOLEAN, 16,
3784 TFS(&tfs_set_notset), 0x2000, NULL, HFILL}},
3785 { &hf_scsi_osd_permissions_set_attr,
3786 {"SET_ATTR", "scsi_osd.permissions.set_attr", FT_BOOLEAN, 16,
3787 TFS(&tfs_set_notset), 0x1000, NULL, HFILL}},
3788 { &hf_scsi_osd_permissions_create,
3789 {"CREATE", "scsi_osd.permissions.create", FT_BOOLEAN, 16,
3790 TFS(&tfs_set_notset), 0x0800, NULL, HFILL}},
3791 { &hf_scsi_osd_permissions_remove,
3792 {"REMOVE", "scsi_osd.permissions.remove", FT_BOOLEAN, 16,
3793 TFS(&tfs_set_notset), 0x0400, NULL, HFILL}},
3794 { &hf_scsi_osd_permissions_obj_mgmt,
3795 {"OBJ_MGMT", "scsi_osd.permissions.obj_mgmt", FT_BOOLEAN, 16,
3796 TFS(&tfs_set_notset), 0x0200, NULL, HFILL}},
3797 { &hf_scsi_osd_permissions_append,
3798 {"APPEND", "scsi_osd.permissions.append", FT_BOOLEAN, 16,
3799 TFS(&tfs_set_notset), 0x0100, NULL, HFILL}},
3800 { &hf_scsi_osd_permissions_dev_mgmt,
3801 {"DEV_MGMT", "scsi_osd.permissions.dev_mgmt", FT_BOOLEAN, 16,
3802 TFS(&tfs_set_notset), 0x0080, NULL, HFILL}},
3803 { &hf_scsi_osd_permissions_global,
3804 {"GLOBAL", "scsi_osd.permissions.global", FT_BOOLEAN, 16,
3805 TFS(&tfs_set_notset), 0x0040, NULL, HFILL}},
3806 { &hf_scsi_osd_permissions_pol_sec,
3807 {"POL/SEC", "scsi_osd.permissions.pol_sec", FT_BOOLEAN, 16,
3808 TFS(&tfs_set_notset), 0x0020, NULL, HFILL}},
3810 { &hf_scsi_osd_object_descriptor_type,
3811 {"Object Descriptor Type", "scsi_osd.object_descriptor_type", FT_UINT8, BASE_HEX,
3812 VALS(scsi_osd_object_descriptor_type_vals), 0xf0, NULL, HFILL}},
3813 { &hf_scsi_osd_object_descriptor,
3814 {"Object Descriptor", "scsi_osd.object_descriptor", FT_BYTES, BASE_NONE,
3815 NULL, 0, NULL, HFILL}},
3816 { &hf_scsi_osd_ricv,
3817 {"Request Integrity Check value", "scsi_osd.ricv", FT_BYTES, BASE_NONE,
3818 NULL, 0, NULL, HFILL}},
3819 { &hf_scsi_osd_request_nonce,
3820 {"Request Nonce", "scsi_osd.request_nonce", FT_BYTES, BASE_NONE,
3821 NULL, 0, NULL, HFILL}},
3822 { &hf_scsi_osd_diicvo,
3823 {"Data-In Integrity Check Value Offset", "scsi_osd.diicvo", FT_UINT32, BASE_DEC,
3824 NULL, 0, NULL, HFILL}},
3825 { &hf_scsi_osd_doicvo,
3826 {"Data-Out Integrity Check Value Offset", "scsi_osd.doicvo", FT_UINT32, BASE_DEC,
3827 NULL, 0, NULL, HFILL}},
3828 { &hf_scsi_osd_requested_partition_id,
3829 {"Requested Partition Id", "scsi_osd.requested_partition_id", FT_UINT64, BASE_HEX,
3830 NULL, 0, NULL, HFILL}},
3831 { &hf_scsi_osd_sortorder,
3832 {"Sort Order", "scsi_osd.sort_order", FT_UINT8, BASE_DEC,
3833 VALS(scsi_osd_sort_order_vals), 0x0f, NULL, HFILL}},
3834 { &hf_scsi_osd_partition_id,
3835 {"Partition Id", "scsi_osd.partition_id", FT_UINT64, BASE_HEX,
3836 NULL, 0, NULL, HFILL}},
3837 { &hf_scsi_osd_list_identifier,
3838 {"List Identifier", "scsi_osd.list_identifier", FT_UINT32, BASE_DEC,
3839 NULL, 0, NULL, HFILL}},
3840 { &hf_scsi_osd_allocation_length,
3841 {"Allocation Length", "scsi_osd.allocation_length", FT_UINT64, BASE_DEC,
3842 NULL, 0, NULL, HFILL}},
3843 { &hf_scsi_osd_length,
3844 {"Length", "scsi_osd.length", FT_UINT64, BASE_DEC,
3845 NULL, 0, NULL, HFILL}},
3846 { &hf_scsi_osd_starting_byte_address,
3847 {"Starting Byte Address", "scsi_osd.starting_byte_address", FT_UINT64, BASE_DEC,
3848 NULL, 0, NULL, HFILL}},
3849 { &hf_scsi_osd_initial_object_id,
3850 {"Initial Object Id", "scsi_osd.initial_object_id", FT_BYTES, BASE_NONE,
3851 NULL, 0, NULL, HFILL}},
3852 { &hf_scsi_osd_additional_length,
3853 {"Additional Length", "scsi_osd.additional_length", FT_UINT64, BASE_DEC,
3854 NULL, 0, NULL, HFILL}},
3855 { &hf_scsi_osd_continuation_object_id,
3856 {"Continuation Object Id", "scsi_osd.continuation_object_id", FT_BYTES, BASE_NONE,
3857 NULL, 0, NULL, HFILL}},
3858 { &hf_scsi_osd_user_object_id,
3859 {"User Object Id", "scsi_osd.user_object_id", FT_BYTES, BASE_NONE,
3860 NULL, 0, NULL, HFILL}},
3861 { &hf_scsi_osd_list_flags_lstchg,
3862 {"LSTCHG", "scsi_osd.list.lstchg", FT_BOOLEAN, 8,
3863 TFS(&list_lstchg_tfs), 0x02, NULL, HFILL}},
3864 { &hf_scsi_osd_list_flags_root,
3865 {"ROOT", "scsi_osd.list.root", FT_BOOLEAN, 8,
3866 TFS(&list_root_tfs), 0x01, NULL, HFILL}},
3867 { &hf_scsi_osd_list_collection_flags_coltn,
3868 {"COLTN", "scsi_osd.list_collection.coltn", FT_BOOLEAN, 8,
3869 TFS(&list_coltn_tfs), 0x01, NULL, HFILL}},
3870 { &hf_scsi_osd_requested_user_object_id,
3871 {"Requested User Object Id", "scsi_osd.requested_user_object_id", FT_BYTES, BASE_NONE,
3872 NULL, 0, NULL, HFILL}},
3873 { &hf_scsi_osd_number_of_user_objects,
3874 {"Number Of User Objects", "scsi_osd.number_of_user_objects", FT_UINT16, BASE_DEC,
3875 NULL, 0, NULL, HFILL}},
3876 { &hf_scsi_osd_key_to_set,
3877 {"Key to Set", "scsi_osd.key_to_set", FT_UINT8, BASE_DEC,
3878 VALS(key_to_set_vals), 0x03, NULL, HFILL}},
3879 { &hf_scsi_osd_set_key_version,
3880 {"Key Version", "scsi_osd.set_key_version", FT_UINT8, BASE_DEC,
3881 NULL, 0x0f, NULL, HFILL}},
3882 { &hf_scsi_osd_key_identifier,
3883 {"Key Identifier", "scsi_osd.key_identifier", FT_BYTES, BASE_NONE,
3884 NULL, 0, NULL, HFILL}},
3885 { &hf_scsi_osd_seed,
3886 {"Seed", "scsi_osd.seed", FT_BYTES, BASE_NONE,
3887 NULL, 0, NULL, HFILL}},
3888 { &hf_scsi_osd_collection_fcr,
3889 {"FCR", "scsi_osd.collection.fcr", FT_BOOLEAN, 8,
3890 TFS(&tfs_set_notset), 0x01, NULL, HFILL}},
3891 { &hf_scsi_osd_collection_object_id,
3892 {"Collection Object Id", "scsi_osd.collection_object_id", FT_BYTES, BASE_NONE,
3893 NULL, 0, NULL, HFILL}},
3894 { &hf_scsi_osd_requested_collection_object_id,
3895 {"Requested Collection Object Id", "scsi_osd.requested_collection_object_id", FT_BYTES, BASE_NONE,
3896 NULL, 0, NULL, HFILL}},
3897 { &hf_scsi_osd_partition_created_in,
3898 { "Created In", "scsi_osd.partition.created_in", FT_FRAMENUM, BASE_NONE,
3899 NULL, 0x0, "The frame this partition was created", HFILL }},
3901 { &hf_scsi_osd_partition_removed_in,
3902 { "Removed In", "scsi_osd.partition.removed_in", FT_FRAMENUM, BASE_NONE,
3903 NULL, 0x0, "The frame this partition was removed", HFILL }},
3905 { &hf_scsi_osd_flush_scope,
3906 {"Flush Scope", "scsi_osd.flush.scope", FT_UINT8, BASE_DEC,
3907 VALS(flush_scope_vals), 0x03, NULL, HFILL}},
3909 { &hf_scsi_osd_flush_collection_scope,
3910 {"Flush Collection Scope", "scsi_osd.flush_collection.scope", FT_UINT8, BASE_DEC,
3911 VALS(flush_collection_scope_vals), 0x03, NULL, HFILL}},
3913 { &hf_scsi_osd_flush_partition_scope,
3914 {"Flush Partition Scope", "scsi_osd.flush_partition.scope", FT_UINT8, BASE_DEC,
3915 VALS(flush_partition_scope_vals), 0x03, NULL, HFILL}},
3917 { &hf_scsi_osd_flush_osd_scope,
3918 {"Flush OSD Scope", "scsi_osd.flush_osd.scope", FT_UINT8, BASE_DEC,
3919 VALS(flush_osd_scope_vals), 0x03, NULL, HFILL}},
3920 { &hf_scsi_osd_attributes_list_type,
3921 {"Attributes List Type", "scsi_osd.attributes_list.type", FT_UINT8, BASE_HEX,
3922 VALS(attributes_list_type_vals), 0x0f, NULL, HFILL}},
3923 { &hf_scsi_osd_attributes_list_length,
3924 {"Attributes List Length", "scsi_osd.attributes_list.length", FT_UINT16, BASE_DEC,
3925 NULL, 0, NULL, HFILL}},
3926 { &hf_scsi_osd_attributes_page,
3927 {"Attributes Page", "scsi_osd.attributes.page", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
3928 &attributes_page_vals_ext, 0, NULL, HFILL}},
3929 { &hf_scsi_osd_attribute_number,
3930 {"Attribute Number", "scsi_osd.attribute.number", FT_UINT32, BASE_HEX,
3931 NULL, 0, NULL, HFILL}},
3932 { &hf_scsi_osd_attribute_length,
3933 {"Attribute Length", "scsi_osd.attribute.length", FT_UINT16, BASE_DEC,
3934 NULL, 0, NULL, HFILL}},
3935 { &hf_scsi_osd2_attributes_list_length,
3936 {"Attributes List Length", "scsi_osd2.attributes_list.length", FT_UINT32, BASE_DEC,
3937 NULL, 0, NULL, HFILL}},
3938 { &hf_scsi_osd_attrval_user_object_logical_length,
3939 {"User Object Logical Length", "scsi_osd.user_object.logical_length", FT_UINT64, BASE_DEC,
3940 NULL, 0, NULL, HFILL}},
3941 { &hf_scsi_osd_attrval_object_type,
3942 {"Object Type", "scsi_osd.attr.object_type", FT_UINT8, BASE_HEX, VALS(scsi_osd_object_type_vals), 0, NULL, HFILL}},
3943 { &hf_scsi_osd_attrval_partition_id,
3944 {"Partition ID", "scsi_osd.attr.partition_id", FT_UINT64, BASE_HEX,
3945 NULL, 0, NULL, HFILL}},
3946 { &hf_scsi_osd_attrval_object_id,
3947 {"Object ID", "scsi_osd.attr.object_id", FT_UINT64, BASE_HEX,
3948 NULL, 0, NULL, HFILL}},
3949 { &hf_scsi_osd2_set_attribute_value,
3950 {"Set Attributes Value", "scsi_osd.set_attribute_value", FT_BYTES, BASE_NONE, 0, 0, NULL, HFILL}},
3951 { &hf_scsi_osd2_isolation,
3952 {"Isolation", "scsi_osd2.isolation", FT_UINT8, BASE_HEX, VALS(scsi_osd2_isolation_val), 0x0F, NULL, HFILL}},
3953 { &hf_scsi_osd2_list_attr,
3954 {"LIST ATTR flag", "scsi_osd2.list_attr", FT_BOOLEAN, 8, 0, 0x40, NULL, HFILL}},
3955 { &hf_scsi_osd2_object_descriptor_format,
3956 {"Object Descriptor Format", "scsi_osd2.object_descriptor_format", FT_UINT8, BASE_HEX, VALS(scsi_osd2_object_descriptor_format_val), 0xFC, NULL, HFILL}},
3957 { &hf_scsi_osd2_immed_tr,
3958 {"Immed TR", "scsi_osd2.immed_tr", FT_UINT8, BASE_DEC, 0, 0x80, NULL, HFILL}},
3959 { &hf_scsi_osd2_remove_scope,
3960 {"Remove scope", "scsi_osd2.remove_scope", FT_UINT8, BASE_HEX, VALS(scsi_osd2_remove_scope), 0x07, NULL, HFILL}},
3961 { &hf_scsi_osd2_source_collection_object_id,
3962 {"Source Collection Object ID", "scsi_osd2.source_collection_object_id", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}},
3963 { &hf_scsi_osd2_matches_collection_object_id,
3964 {"Matches Collection Object ID", "scsi_osd2.matches_collection_object_id", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}},
3965 { &hf_scsi_osd2_cdb_continuation_length,
3966 {"CDB Continuation Length", "scsi_osd2.cdb_continuation.length", FT_UINT32, BASE_DEC, 0, 0, NULL, HFILL}},
3967 { &hf_scsi_osd2_cdb_continuation_format,
3968 {"CDB Continuation Format", "scsi_osd2.cdb_continuation.format", FT_UINT8, BASE_HEX, VALS(scsi_osd2_cdb_continuation_format_val), 0, NULL, HFILL}},
3969 { &hf_scsi_osd2_continued_service_action,
3970 {"Continued Service Action", "scsi_osd2.cdb_continuation.sa", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL}},
3971 { &hf_scsi_osd2_cdb_continuation_descriptor_type,
3972 {"Descriptor Type", "scsi_osd2.cdb_continuation.desc.type", FT_UINT16, BASE_HEX, VALS(scsi_osd2_cdb_continuation_descriptor_type_val), 0, NULL, HFILL}},
3973 { &hf_scsi_osd2_cdb_continuation_descriptor_pad_length,
3974 {"Descriptor Pad Length", "scsi_osd2.cdb_continuation.desc.padlen", FT_UINT8, BASE_DEC, NULL, 0x7, NULL, HFILL}},
3975 { &hf_scsi_osd2_cdb_continuation_descriptor_length,
3976 {"Descriptor Length", "scsi_osd2.cdb_continuation.desc.length", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
3977 { &hf_scsi_osd2_query_type,
3978 {"Query Type", "scsi_osd2.query.type", FT_UINT8, BASE_HEX, VALS(scsi_osd2_query_type_vals), 0x0f, NULL, HFILL}},
3979 { &hf_scsi_osd2_query_entry_length,
3980 {"Entry Length", "scsi_osd2.query.entry.length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
3981 { &hf_scsi_osd2_query_attributes_page,
3982 {"Attributes Page", "scsi_osd2.query.entry.page", FT_UINT32, BASE_HEX | BASE_EXT_STRING, &attributes_page_vals_ext, 0, NULL, HFILL}},
3983 { &hf_scsi_osd2_query_attribute_number,
3984 {"Attribute Number", "scsi_osd2.query.entry.number", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL}},
3985 { &hf_scsi_osd2_query_minimum_attribute_value_length,
3986 {"Minimum Attribute Value Length", "scsi_osd2.query.entry.min_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
3987 { &hf_scsi_osd2_query_maximum_attribute_value_length,
3988 {"Maximum Attribute Value Length", "scsi_osd2.query.entry.max_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
3991 /* Setup protocol subtree array */
3992 static int *ett[] = {
3993 &ett_osd_option,
3994 &ett_osd_partition,
3995 &ett_osd_attribute_parameters,
3996 &ett_osd_capability,
3997 &ett_osd_permission_bitmask,
3998 &ett_osd_security_parameters,
3999 &ett_osd_get_attributes,
4000 &ett_osd_set_attributes,
4001 &ett_osd_multi_object,
4002 &ett_osd_attribute,
4003 &ett_osd2_query_criteria_entry,
4006 /* Setup expert info */
4007 static ei_register_info ei[] = {
4008 { &ei_osd_attr_unknown, { "scsi_osd.attr_unknown", PI_UNDECODED, PI_NOTE, "Unknown attribute, cannot decode attribute value", EXPFILL }},
4009 { &ei_osd2_invalid_offset, { "scsi_osd2.invalid_offset", PI_UNDECODED, PI_ERROR, "Invalid offset exponent", EXPFILL }},
4010 { &ei_osd2_invalid_object_descriptor_format, { "scsi_osd2.object_descriptor_format.invalid", PI_UNDECODED, PI_ERROR, "Invalid list format", EXPFILL }},
4011 { &ei_osd_unknown_attributes_list_type, { "scsi_osd.attributes_list.type.invalid", PI_UNDECODED, PI_ERROR, "Unknown attribute list type", EXPFILL }},
4012 { &ei_osd2_cdb_continuation_format_unknown, { "scsi_osd2.cdb_continuation.format.unknown", PI_UNDECODED, PI_ERROR, "Unknown CDB Continuation Format", EXPFILL }},
4013 { &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 }},
4014 { &ei_osd2_cdb_continuation_descriptor_type_unknown, { "scsi_osd2.cdb_continuation.desc.type.unknown", PI_UNDECODED, PI_WARN, "Unknown descriptor type", EXPFILL }},
4015 { &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 }},
4016 { &ei_osd2_cdb_continuation_length_invalid, { "scsi_osd2.cdb_continuation.length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid CDB continuation length", EXPFILL }},
4017 { &ei_osd_attr_length_invalid, { "scsi_osd.attribute_length.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Attribute Length", EXPFILL }},
4018 { &ei_osd2_query_values_equal, { "scsi_osd2.query.entry.equal", PI_PROTOCOL, PI_NOTE, "The minimum and maximum values are equal", EXPFILL }},
4021 /* Register the protocol name and description */
4022 proto_scsi_osd = proto_register_protocol("SCSI_OSD", "SCSI_OSD", "scsi_osd");
4024 /* Required function calls to register the header fields and subtrees used */
4025 proto_register_field_array(proto_scsi_osd, hf, array_length(hf));
4026 proto_register_subtree_array(ett, array_length(ett));
4028 /* Register expert info */
4029 expert_scsi_osd = expert_register_protocol(proto_scsi_osd);
4030 expert_register_field_array(expert_scsi_osd, ei, array_length(ei));
4034 * Editor modelines
4036 * Local Variables:
4037 * c-basic-offset: 4
4038 * tab-width: 8
4039 * indent-tabs-mode: nil
4040 * End:
4042 * ex: set shiftwidth=4 tabstop=8 expandtab:
4043 * :indentSize=4:tabSize=8:noTabs=true: