6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 2002 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/strutil.h>
32 #include <epan/packet.h>
33 #include <epan/prefs.h>
34 #include <epan/emem.h>
35 #include <epan/conversation.h>
37 #include "packet-fc.h"
38 #include "packet-scsi.h"
39 #include "packet-scsi-osd.h"
41 static int proto_scsi_osd = -1;
42 int hf_scsi_osd_opcode = -1;
43 static int hf_scsi_osd_control = -1;
44 static int hf_scsi_osd_add_cdblen = -1;
45 static int hf_scsi_osd_svcaction = -1;
46 static int hf_scsi_osd_option = -1;
47 static int hf_scsi_osd_option_dpo = -1;
48 static int hf_scsi_osd_option_fua = -1;
49 static int hf_scsi_osd_getsetattrib = -1;
50 static int hf_scsi_osd_timestamps_control = -1;
51 static int hf_scsi_osd_formatted_capacity = -1;
52 static int hf_scsi_osd_get_attributes_page = -1;
53 static int hf_scsi_osd_get_attributes_allocation_length = -1;
54 static int hf_scsi_osd_retreived_attributes_offset = -1;
55 static int hf_scsi_osd_set_attributes_page = -1;
56 static int hf_scsi_osd_set_attribute_length = -1;
57 static int hf_scsi_osd_set_attribute_number = -1;
58 static int hf_scsi_osd_set_attributes_offset = -1;
59 static int hf_scsi_osd_capability_format = -1;
60 static int hf_scsi_osd_key_version = -1;
61 static int hf_scsi_osd_icva = -1;
62 static int hf_scsi_osd_security_method = -1;
63 static int hf_scsi_osd_capability_expiration_time= -1;
64 static int hf_scsi_osd_audit= -1;
65 static int hf_scsi_osd_capability_discriminator = -1;
66 static int hf_scsi_osd_object_created_time= -1;
67 static int hf_scsi_osd_object_type = -1;
68 static int hf_scsi_osd_permission_bitmask= -1;
69 static int hf_scsi_osd_object_descriptor_type = -1;
70 static int hf_scsi_osd_object_descriptor= -1;
71 static int hf_scsi_osd_ricv = -1;
72 static int hf_scsi_osd_request_nonce = -1;
73 static int hf_scsi_osd_diicvo = -1;
74 static int hf_scsi_osd_doicvo = -1;
75 static int hf_scsi_osd_requested_partition_id = -1;
78 static gint ett_osd_option = -1;
81 typedef struct _scsi_osd_extra_data_t {
84 } scsi_osd_extra_data_t;
86 static const true_false_string option_dpo_tfs = {
90 static const true_false_string option_fua_tfs = {
97 dissect_osd_option(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
99 proto_tree *tree=NULL;
103 option=tvb_get_guint8(tvb, offset);
106 it=proto_tree_add_item(parent_tree, hf_scsi_osd_option, tvb, offset, 1, 0);
107 tree = proto_item_add_subtree(it, ett_osd_option);
110 proto_tree_add_item(tree, hf_scsi_osd_option_dpo, tvb, offset, 1, 0);
112 proto_item_append_text(tree, " DPO");
115 proto_tree_add_item(tree, hf_scsi_osd_option_fua, tvb, offset, 1, 0);
117 proto_item_append_text(tree, " FUA");
122 static const value_string scsi_osd_getsetattrib_vals[] = {
123 {2, "Get an attributes page and set an attribute value"},
124 {3, "Get and set attributes using a list"},
129 dissect_osd_getsetattrib(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
131 if(cdata && cdata->itlq && cdata->itlq->extra_data){
132 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
133 extra_data->gsatype=(tvb_get_guint8(tvb, offset)>>4)&0x03;
135 proto_tree_add_item(tree, hf_scsi_osd_getsetattrib, tvb, offset, 1, 0);
139 static const value_string scsi_osd_timestamps_control_vals[] = {
140 {0x00, "Timestamps shall be updated"},
141 {0x7f, "Timestamps shall not be updated"},
146 dissect_osd_timestamps_control(tvbuff_t *tvb, int offset, proto_tree *tree)
148 proto_tree_add_item(tree, hf_scsi_osd_timestamps_control, tvb, offset, 1, 0);
153 dissect_osd_formatted_capacity(tvbuff_t *tvb, int offset, proto_tree *tree)
155 proto_tree_add_item(tree, hf_scsi_osd_formatted_capacity, tvb, offset, 8, 0);
159 /* do we need to store these in the itlq structure ?*/
161 dissect_osd_attribute_parameters(tvbuff_t *tvb, int offset, proto_tree *tree, scsi_task_data_t *cdata)
165 if(cdata && cdata->itlq && cdata->itlq->extra_data){
166 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
167 gsatype=extra_data->gsatype;
173 case 2: /* 5.2.2.2 attribute page */
174 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_page, tvb, offset, 4, 0);
176 proto_tree_add_item(tree, hf_scsi_osd_get_attributes_allocation_length, tvb, offset, 4, 0);
178 proto_tree_add_item(tree, hf_scsi_osd_retreived_attributes_offset, tvb, offset, 4, 0);
180 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_page, tvb, offset, 4, 0);
182 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_length, tvb, offset, 4, 0);
184 proto_tree_add_item(tree, hf_scsi_osd_set_attribute_number, tvb, offset, 4, 0);
186 proto_tree_add_item(tree, hf_scsi_osd_set_attributes_offset, tvb, offset, 4, 0);
189 case 3: /* 5.2.2.3 attribute list */
196 static const value_string scsi_osd_capability_format_vals[] = {
197 {0x00, "No Capability"},
198 {0x01, "SCSI OSD2 Capabilities"},
201 static const value_string scsi_osd_object_type_vals[] = {
204 {0x40, "COLLECTION"},
208 static const value_string scsi_osd_object_descriptor_type_vals[] = {
209 {0, "NONE: the object descriptor field shall be ignored"},
210 {1, "U/C: a single collection or user object"},
211 {2, "PAR: a single partition, including partition zero"},
217 dissect_osd_capability(tvbuff_t *tvb, int offset, proto_tree *tree)
219 /* capability format */
220 proto_tree_add_item(tree, hf_scsi_osd_capability_format, tvb, offset, 1, 0);
223 /* key version and icva */
224 proto_tree_add_item(tree, hf_scsi_osd_key_version, tvb, offset, 1, 0);
225 proto_tree_add_item(tree, hf_scsi_osd_icva, tvb, offset, 1, 0);
228 /* security method */
229 proto_tree_add_item(tree, hf_scsi_osd_security_method, tvb, offset, 1, 0);
232 /* a reserved byte */
235 /* capability expiration time */
236 proto_tree_add_item(tree, hf_scsi_osd_capability_expiration_time, tvb, offset, 6, 0);
240 proto_tree_add_item(tree, hf_scsi_osd_audit, tvb, offset, 20, 0);
243 /* capability discriminator */
244 proto_tree_add_item(tree, hf_scsi_osd_capability_discriminator, tvb, offset, 12, 0);
247 /* object created time */
248 proto_tree_add_item(tree, hf_scsi_osd_object_created_time, tvb, offset, 6, 0);
252 proto_tree_add_item(tree, hf_scsi_osd_object_type, tvb, offset, 1, 0);
255 /* permission bitmask */
256 /*qqq should be broken out into a helper and have the individual bits dissected */
257 proto_tree_add_item(tree, hf_scsi_osd_permission_bitmask, tvb, offset, 5, 0);
260 /* a reserved byte */
263 /* object descriptor type */
264 proto_tree_add_item(tree, hf_scsi_osd_object_descriptor_type, tvb, offset, 1, 0);
267 /* object descriptor */
268 proto_tree_add_item(tree, hf_scsi_osd_object_descriptor, tvb, offset, 24, 0);
276 dissect_osd_security_parameters(tvbuff_t *tvb, int offset, proto_tree *tree)
278 /* request integrity check value */
279 proto_tree_add_item(tree, hf_scsi_osd_ricv, tvb, offset, 20, 0);
283 proto_tree_add_item(tree, hf_scsi_osd_request_nonce, tvb, offset, 12, 0);
286 /* data in integrity check value offset */
287 proto_tree_add_item(tree, hf_scsi_osd_diicvo, tvb, offset, 4, 0);
290 /* data out integrity check value offset */
291 proto_tree_add_item(tree, hf_scsi_osd_doicvo, tvb, offset, 4, 0);
296 dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
297 guint offset, gboolean isreq, gboolean iscdb,
298 guint payload_len _U_, scsi_task_data_t *cdata _U_)
300 /* dissecting the CDB dissection starts at byte 10 of the CDB */
303 dissect_osd_option(tvb, offset, tree);
306 /* getset attributes byte */
307 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
310 /* timestamps control */
311 dissect_osd_timestamps_control(tvb, offset, tree);
314 /* 23 reserved bytes */
317 /* formatted capacity */
318 dissect_osd_formatted_capacity(tvb, offset, tree);
321 /* 8 reserved bytes */
324 /* attribute parameters */
325 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
329 dissect_osd_capability(tvb, offset, tree);
332 /* security parameters */
333 dissect_osd_security_parameters(tvb, offset, tree);
337 /* dissecting the DATA OUT */
339 /* no data out for format osd */
342 /* dissecting the DATA IN */
343 if(!isreq && !iscdb){
344 /* no data in for format osd */
351 dissect_osd_requested_partition_id(tvbuff_t *tvb, int offset, proto_tree *tree)
353 /* request partition id */
354 proto_tree_add_item(tree, hf_scsi_osd_requested_partition_id, tvb, offset, 8, 0);
359 dissect_osd_create_partition(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
360 guint offset, gboolean isreq, gboolean iscdb,
361 guint payload_len _U_, scsi_task_data_t *cdata _U_)
363 /* dissecting the CDB dissection starts at byte 10 of the CDB */
366 dissect_osd_option(tvb, offset, tree);
369 /* getset attributes byte */
370 dissect_osd_getsetattrib(tvb, offset, tree, cdata);
373 /* timestamps control */
374 dissect_osd_timestamps_control(tvb, offset, tree);
377 /* 3 reserved bytes */
380 /* requested partiton id */
381 dissect_osd_requested_partition_id(tvb, offset, tree);
384 /* 28 reserved bytes */
387 /* attribute parameters */
388 dissect_osd_attribute_parameters(tvb, offset, tree, cdata);
392 dissect_osd_capability(tvb, offset, tree);
395 /* security parameters */
396 dissect_osd_security_parameters(tvb, offset, tree);
400 /* dissecting the DATA OUT */
402 /* no data out for create partition */
405 /* dissecting the DATA IN */
406 if(!isreq && !iscdb){
407 /* no data in for create partition */
413 /* OSD Service Actions */
414 #define OSD_FORMAT_OSD 0x8801
415 #define OSD_CREATE_PARTITION 0x880b
416 static const value_string scsi_osd_svcaction_vals[] = {
417 {OSD_FORMAT_OSD, "Format OSD"},
418 {OSD_CREATE_PARTITION, "Create Partition"},
422 /* OSD Service Action dissectors */
423 typedef struct _scsi_osd_svcaction_t {
425 scsi_dissector_t dissector;
426 } scsi_osd_svcaction_t;
427 static const scsi_osd_svcaction_t scsi_osd_svcaction[] = {
428 {OSD_FORMAT_OSD, dissect_osd_format_osd},
429 {OSD_CREATE_PARTITION, dissect_osd_create_partition},
433 static scsi_dissector_t
434 find_svcaction_dissector(guint16 svcaction)
436 const scsi_osd_svcaction_t *sa=scsi_osd_svcaction;
438 while(sa&&sa->dissector){
439 if(sa->svcaction==svcaction){
440 return sa->dissector;
450 dissect_osd_opcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
451 guint offset, gboolean isreq, gboolean iscdb,
452 guint payload_len, scsi_task_data_t *cdata)
455 scsi_dissector_t dissector;
461 /* dissecting the CDB */
462 if (isreq && iscdb) {
463 proto_tree_add_item (tree, hf_scsi_osd_control, tvb, offset, 1, 0);
466 /* 5 reserved bytes */
469 proto_tree_add_item (tree, hf_scsi_osd_add_cdblen, tvb, offset, 1, 0);
472 svcaction=tvb_get_ntohs(tvb, offset);
473 if(cdata && cdata->itlq){
474 /* We must store the service action for this itlq
475 * so we can indentify what the data contains
477 if((!pinfo->fd->flags.visited) && (!cdata->itlq->extra_data)){
478 scsi_osd_extra_data_t *extra_data;
480 extra_data=se_alloc(sizeof(scsi_osd_extra_data_t));
481 extra_data->svcaction=svcaction;
482 extra_data->gsatype=0;
483 cdata->itlq->extra_data=extra_data;
486 proto_tree_add_item (tree, hf_scsi_osd_svcaction, tvb, offset, 2, 0);
490 if(check_col(pinfo->cinfo, COL_INFO)){
491 col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
492 val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
494 dissector=find_svcaction_dissector(svcaction);
496 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata);
501 /* If it was not a CDB, try to find the service action and pass it
502 * off to the service action dissector
504 if(cdata && cdata->itlq && cdata->itlq->extra_data){
505 scsi_osd_extra_data_t *extra_data=cdata->itlq->extra_data;
506 svcaction=extra_data->svcaction;
508 if(check_col(pinfo->cinfo, COL_INFO)){
509 col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
510 val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
514 it=proto_tree_add_uint_format(tree, hf_scsi_osd_svcaction, tvb, 0, 0, svcaction, "Service Action: 0x%04x", svcaction);
515 PROTO_ITEM_SET_GENERATED(it);
517 dissector=find_svcaction_dissector(svcaction);
519 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata);
526 const value_string scsi_osd_vals[] = {
527 {SCSI_SPC2_INQUIRY , "Inquiry"},
528 {SCSI_SPC2_LOGSELECT , "Log Select"},
529 {SCSI_SPC2_LOGSENSE , "Log Sense"},
530 {SCSI_SPC2_MODESELECT10 , "Mode Select(10)"},
531 {SCSI_SPC2_MODESENSE10 , "Mode Sense(10)"},
532 {SCSI_SPC2_PERSRESVIN , "Persistent Reserve In"},
533 {SCSI_SPC2_PERSRESVOUT , "Persistent Reserve Out"},
534 {SCSI_SPC2_REPORTLUNS , "Report LUNs"},
535 {SCSI_OSD_OPCODE , "OSD Command" },
541 scsi_cdb_table_t scsi_osd_table[256] = {
560 /*OSD 0x12*/{dissect_spc3_inquiry},
618 /*OSD 0x4c*/{dissect_spc3_logselect},
619 /*OSD 0x4d*/{dissect_spc3_logsense},
627 /*OSD 0x55*/{dissect_spc3_modeselect10},
632 /*OSD 0x5a*/{dissect_spc3_modesense10},
636 /*OSD 0x5e*/{dissect_spc3_persistentreservein},
637 /*OSD 0x5f*/{dissect_spc3_persistentreserveout},
669 /*OSD 0x7f*/{dissect_osd_opcode},
702 /*OSD 0xa0*/{dissect_spc3_reportluns},
804 proto_register_scsi_osd(void)
806 static hf_register_info hf[] = {
807 { &hf_scsi_osd_opcode,
808 {"OSD Opcode", "scsi.osd.opcode", FT_UINT8, BASE_HEX,
809 VALS (scsi_osd_vals), 0x0, "", HFILL}},
810 { &hf_scsi_osd_control,
811 {"Control", "scsi.osd.cdb.control", FT_UINT8, BASE_HEX,
812 NULL, 0x0, "", HFILL}},
813 { &hf_scsi_osd_add_cdblen,
814 {"Additional CDB Length", "scsi.osd.addcdblen", FT_UINT8, BASE_DEC,
815 NULL, 0x0, "", HFILL}},
816 { &hf_scsi_osd_svcaction,
817 {"Service Action", "scsi.osd.svcaction", FT_UINT16, BASE_HEX,
818 VALS(scsi_osd_svcaction_vals), 0x0, "", HFILL}},
819 { &hf_scsi_osd_option,
820 {"Option", "scsi.osd.option", FT_UINT8, BASE_HEX,
821 NULL, 0x0, "", HFILL}},
822 { &hf_scsi_osd_option_dpo,
823 {"DPO", "scsi.osd.option.dpo", FT_BOOLEAN, 8,
824 TFS(&option_dpo_tfs), 0x10, "", HFILL}},
825 { &hf_scsi_osd_option_fua,
826 {"FUA", "scsi.osd.option.fua", FT_BOOLEAN, 8,
827 TFS(&option_fua_tfs), 0x08, "", HFILL}},
828 { &hf_scsi_osd_getsetattrib,
829 {"GET/SET CDBFMT", "scsi.osd.getset", FT_UINT8, BASE_HEX,
830 VALS(scsi_osd_getsetattrib_vals), 0x30, "", HFILL}},
831 { &hf_scsi_osd_timestamps_control,
832 {"Timestamps Control", "scsi.osd.timestamps_control", FT_UINT8, BASE_HEX,
833 VALS(scsi_osd_timestamps_control_vals), 0x0, "", HFILL}},
834 { &hf_scsi_osd_formatted_capacity,
835 {"Formatted Capacity", "scsi.osd.formatted_capacity", FT_UINT64, BASE_DEC,
836 NULL, 0x0, "", HFILL}},
837 { &hf_scsi_osd_get_attributes_page,
838 {"Get Attributes Page", "scsi.osd.get_attributes_page", FT_UINT32, BASE_HEX,
839 NULL, 0x0, "", HFILL}},
840 { &hf_scsi_osd_get_attributes_allocation_length,
841 {"Get Attributes Allocation Length", "scsi.osd.get_attributes_allocation_length", FT_UINT32, BASE_HEX,
842 NULL, 0x0, "", HFILL}},
843 { &hf_scsi_osd_retreived_attributes_offset,
844 {"Retreived Attributes Offset", "scsi.osd.retreived_attributes_offset", FT_UINT32, BASE_HEX,
845 NULL, 0x0, "", HFILL}},
846 { &hf_scsi_osd_set_attributes_page,
847 {"Set Attributes Page", "scsi.osd.set_attributes_page", FT_UINT32, BASE_HEX,
848 NULL, 0x0, "", HFILL}},
849 { &hf_scsi_osd_set_attribute_length,
850 {"Set Attribute Length", "scsi.osd.set_attribute_length", FT_UINT32, BASE_HEX,
851 NULL, 0x0, "", HFILL}},
852 { &hf_scsi_osd_set_attribute_number,
853 {"Set Attribute Number", "scsi.osd.set_attribute_number", FT_UINT32, BASE_HEX,
854 NULL, 0x0, "", HFILL}},
855 { &hf_scsi_osd_set_attributes_offset,
856 {"Set Attributes Offset", "scsi.osd.set_attributes_offset", FT_UINT32, BASE_HEX,
857 NULL, 0x0, "", HFILL}},
858 { &hf_scsi_osd_capability_format,
859 {"Capability Format", "scsi.osd.capability_format", FT_UINT8, BASE_HEX,
860 VALS(scsi_osd_capability_format_vals), 0x0f, "", HFILL}},
861 { &hf_scsi_osd_key_version,
862 {"Key Version", "scsi.osd.key_version", FT_UINT8, BASE_HEX,
863 NULL, 0xf0, "", HFILL}},
865 {"Integrity Check Value Algorithm", "scsi.osd.icva", FT_UINT8, BASE_HEX,
866 NULL, 0x0f, "", HFILL}},
867 { &hf_scsi_osd_security_method,
868 {"Security Method", "scsi.osd.security_method", FT_UINT8, BASE_HEX,
869 NULL, 0x0f, "", HFILL}},
870 { &hf_scsi_osd_capability_expiration_time,
871 {"Capability Expiration Time", "scsi.osd.capability_expiration_time", FT_BYTES, BASE_HEX,
872 NULL, 0, "", HFILL}},
873 { &hf_scsi_osd_audit,
874 {"Audit", "scsi.osd.audit", FT_BYTES, BASE_HEX,
875 NULL, 0, "", HFILL}},
876 { &hf_scsi_osd_capability_discriminator,
877 {"Capability Discriminator", "scsi.osd.capability_descriminator", FT_BYTES, BASE_HEX,
878 NULL, 0, "", HFILL}},
879 { &hf_scsi_osd_object_created_time,
880 {"Object Created Time", "scsi.osd.object_created_time", FT_BYTES, BASE_HEX,
881 NULL, 0, "", HFILL}},
882 { &hf_scsi_osd_object_type,
883 {"Object Type", "scsi.osd.object_type", FT_UINT8, BASE_HEX,
884 VALS(scsi_osd_object_type_vals), 0, "", HFILL}},
885 { &hf_scsi_osd_permission_bitmask,
886 {"Permission Bitmask", "scsi.osd.permission_bitmask", FT_BYTES, BASE_HEX,
887 NULL, 0, "", HFILL}},
888 { &hf_scsi_osd_object_descriptor_type,
889 {"Object Descriptor Type", "scsi.osd.object_descriptor_type", FT_UINT8, BASE_HEX,
890 VALS(scsi_osd_object_descriptor_type_vals), 0xf0, "", HFILL}},
891 { &hf_scsi_osd_object_descriptor,
892 {"Object Descriptor", "scsi.osd.object_descriptor", FT_BYTES, BASE_HEX,
893 NULL, 0, "", HFILL}},
895 {"Request Integrity Check value", "scsi.osd.ricv", FT_BYTES, BASE_HEX,
896 NULL, 0, "", HFILL}},
897 { &hf_scsi_osd_request_nonce,
898 {"Request Nonce", "scsi.osd.request_nonce", FT_BYTES, BASE_HEX,
899 NULL, 0, "", HFILL}},
900 { &hf_scsi_osd_diicvo,
901 {"Data-In Integrity Check Value Offset", "scsi.osd.diicvo", FT_UINT32, BASE_DEC,
902 NULL, 0, "", HFILL}},
903 { &hf_scsi_osd_doicvo,
904 {"Data-Out Integrity Check Value Offset", "scsi.osd.doicvo", FT_UINT32, BASE_DEC,
905 NULL, 0, "", HFILL}},
906 { &hf_scsi_osd_requested_partition_id,
907 {"Requested Partition Id", "scsi.osd.requested_partition_id", FT_BYTES, BASE_HEX,
908 NULL, 0, "", HFILL}},
911 /* Setup protocol subtree array */
912 static gint *ett[] = {
916 /* Register the protocol name and description */
917 proto_scsi_osd = proto_register_protocol("SCSI_OSD", "SCSI_OSD", "scsi_osd");
919 /* Required function calls to register the header fields and subtrees used */
920 proto_register_field_array(proto_scsi_osd, hf, array_length(hf));
921 proto_register_subtree_array(ett, array_length(ett));
925 proto_reg_handoff_scsi_osd(void)