71fae1e06f0600ca426f3bf12198977cdc4033f0
[obnox/wireshark/wip.git] / epan / dissectors / packet-scsi-osd.c
1 /* packet-scsi-osd.c
2  * Ronnie sahlberg 2006
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 2002 Gerald Combs
9  *
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.
14  *
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.
19  *
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.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <glib.h>
30 #include <string.h>
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>
36 #include <epan/tap.h>
37 #include "packet-fc.h"
38 #include "packet-scsi.h"
39 #include "packet-scsi-osd.h"
40
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
52
53 static gint ett_osd_option              = -1;
54
55
56
57 static const true_false_string option_dpo_tfs = {
58         "DPO is SET",
59         "Dpo is NOT set"
60 };
61 static const true_false_string option_fua_tfs = {
62         "FUA is SET",
63         "Fua is NOT set"
64 };
65
66 /* OSD2 5.2.4 */
67 static void
68 dissect_osd_option(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
69 {
70         proto_tree *tree=NULL;
71         proto_item *it=NULL;
72         guint8 option;
73
74         option=tvb_get_guint8(tvb, offset);
75
76         if(parent_tree){
77                 it=proto_tree_add_item(parent_tree, hf_scsi_osd_option, tvb, offset, 1, 0);
78                 tree = proto_item_add_subtree(it, ett_osd_option);
79         }
80
81         proto_tree_add_item(tree, hf_scsi_osd_option_dpo, tvb, offset, 1, 0);
82         if(option&0x10){
83                 proto_item_append_text(tree, " DPO");
84         }
85
86         proto_tree_add_item(tree, hf_scsi_osd_option_fua, tvb, offset, 1, 0);
87         if(option&0x08){
88                 proto_item_append_text(tree, " FUA");
89         }
90 }
91
92
93 static const value_string scsi_osd_getsetattrib_vals[] = {
94     {2,         "Get an attributes page and set an attribute value"},
95     {3,         "Get and set attributes using a list"},
96     {0, NULL},
97 };
98 /* OSD2 5.2.2.1 */
99 static void
100 dissect_osd_getsetattrib(tvbuff_t *tvb, int offset, proto_tree *tree)
101 {
102         proto_tree_add_item(tree, hf_scsi_osd_getsetattrib, tvb, offset, 1, 0);
103 }
104
105
106 static const value_string scsi_osd_timestamps_control_vals[] = {
107     {0x00,      "Timestamps shall be updated"},
108     {0x7f,      "Timestamps shall not be updated"},
109     {0, NULL},
110 };
111 /* OSD2 5.2.8 */
112 static void
113 dissect_osd_timestamps_control(tvbuff_t *tvb, int offset, proto_tree *tree)
114 {
115         proto_tree_add_item(tree, hf_scsi_osd_timestamps_control, tvb, offset, 1, 0);
116 }
117
118
119
120
121
122
123
124
125 static void
126 dissect_osd_format_osd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
127                         guint offset, gboolean isreq, gboolean iscdb,
128                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
129 {
130         /* dissecting the CDB   dissection starts at byte 10 of the CDB */
131         if(isreq && iscdb){
132                 /* options byte */
133                 dissect_osd_option(tvb, offset, tree);
134                 offset++;
135
136                 /* getset attributes byte */
137                 dissect_osd_getsetattrib(tvb, offset, tree);
138                 offset++;
139
140                 /* timestamps control */
141                 dissect_osd_timestamps_control(tvb, offset, tree);
142                 offset++;
143
144                 /* 23 reserved bytes */
145                 offset+=23;
146
147 /*qqq*/
148         }
149
150         /* dissecting the DATA OUT */
151         if(isreq && !iscdb){
152                 /* no data out for format osd */
153         }
154
155         /* dissecting the DATA IN */
156         if(!isreq && !iscdb){
157                 /* no data in for format osd */
158         }
159         
160 }
161
162
163 /* OSD Service Actions */
164 #define OSD_FORMAT_OSD          0x8801
165 static const value_string scsi_osd_svcaction_vals[] = {
166     {OSD_FORMAT_OSD,            "Format OSD"},
167     {0, NULL},
168 };
169
170 /* OSD Service Action dissectors */
171 typedef struct _scsi_osd_svcaction_t {
172         guint16 svcaction;
173         scsi_dissector_t dissector;
174 } scsi_osd_svcaction_t;
175 static const scsi_osd_svcaction_t scsi_osd_svcaction[] = {
176     {OSD_FORMAT_OSD,            dissect_osd_format_osd},
177     {0, NULL},
178 };
179
180 static scsi_dissector_t
181 find_svcaction_dissector(guint16 svcaction)
182 {
183         scsi_osd_svcaction_t *sa=scsi_osd_svcaction;
184
185         while(sa&&sa->dissector){
186                 if(sa->svcaction==svcaction){
187                         return sa->dissector;
188                 }
189                 sa++;
190         }
191         return NULL;
192 }
193
194
195
196 static void
197 dissect_osd_opcode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
198                         guint offset, gboolean isreq, gboolean iscdb,
199                         guint payload_len, scsi_task_data_t *cdata)
200 {
201         guint16 svcaction=0;
202         scsi_dissector_t dissector;
203
204         if(!tree) {
205                 return;
206         }
207
208         /* dissecting the CDB */
209         if (isreq && iscdb) {
210                 proto_tree_add_item (tree, hf_scsi_osd_control, tvb, offset, 1, 0);
211                 offset++;
212
213                 /* 5 reserved bytes */
214                 offset+=5;
215
216                 proto_tree_add_item (tree, hf_scsi_osd_add_cdblen, tvb, offset, 1, 0);
217                 offset++;
218
219                 svcaction=tvb_get_ntohs(tvb, offset);
220                 if(cdata && cdata->itlq){
221                         /* We must store the service action for this itlq
222                          * so we can indentify what the data contains
223                          */
224                         cdata->itlq->svcaction=svcaction;
225                 }
226                 proto_tree_add_item (tree, hf_scsi_osd_svcaction, tvb, offset, 2, 0);
227                 offset+=2;
228
229
230                 if(check_col(pinfo->cinfo, COL_INFO)){
231                         col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
232                                 val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
233                 }
234                 dissector=find_svcaction_dissector(svcaction);
235                 if(dissector){
236                         (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata);
237                 }
238                 return;
239         }
240
241         /* If it was not a CDB, try to find the service action and pass it
242          * off to the service action dissector
243          */
244         if(cdata && cdata->itlq){
245                 svcaction=cdata->itlq->svcaction;
246         }
247         if(check_col(pinfo->cinfo, COL_INFO)){
248                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
249                         val_to_str(svcaction, scsi_osd_svcaction_vals, "Unknown OSD Serviceaction"));
250         }
251         if(svcaction){
252                 proto_item *it;
253                 it=proto_tree_add_uint_format(tree, hf_scsi_osd_svcaction, tvb, 0, 0, svcaction, "Service Action: 0x%04x", svcaction);
254                 PROTO_ITEM_SET_GENERATED(it);
255         }
256         dissector=find_svcaction_dissector(svcaction);
257         if(dissector){
258                 (*dissector)(tvb, pinfo, tree, offset, isreq, iscdb, payload_len, cdata);
259         }
260
261 }
262
263
264 /* OSD Commands */
265 const value_string scsi_osd_vals[] = {
266     {SCSI_SPC2_INQUIRY                  , "Inquiry"},
267     {SCSI_SPC2_LOGSELECT                , "Log Select"},
268     {SCSI_SPC2_LOGSENSE                 , "Log Sense"},
269     {SCSI_SPC2_MODESELECT10             , "Mode Select(10)"},
270     {SCSI_SPC2_MODESENSE10              , "Mode Sense(10)"},
271     {SCSI_SPC2_PERSRESVIN               , "Persistent Reserve In"},
272     {SCSI_SPC2_PERSRESVOUT              , "Persistent Reserve Out"},
273     {SCSI_SPC2_REPORTLUNS               , "Report LUNs"},
274     {SCSI_OSD_OPCODE                    , "OSD Command" },
275     {0, NULL},
276 };
277
278
279
280 scsi_cdb_table_t scsi_osd_table[256] = {
281 /*OSD 0x00*/{NULL},
282 /*OSD 0x01*/{NULL},
283 /*OSD 0x02*/{NULL},
284 /*OSD 0x03*/{NULL},
285 /*OSD 0x04*/{NULL},
286 /*OSD 0x05*/{NULL},
287 /*OSD 0x06*/{NULL},
288 /*OSD 0x07*/{NULL},
289 /*OSD 0x08*/{NULL},
290 /*OSD 0x09*/{NULL},
291 /*OSD 0x0a*/{NULL},
292 /*OSD 0x0b*/{NULL},
293 /*OSD 0x0c*/{NULL},
294 /*OSD 0x0d*/{NULL},
295 /*OSD 0x0e*/{NULL},
296 /*OSD 0x0f*/{NULL},
297 /*OSD 0x10*/{NULL},
298 /*OSD 0x11*/{NULL},
299 /*OSD 0x12*/{dissect_spc3_inquiry},
300 /*OSD 0x13*/{NULL},
301 /*OSD 0x14*/{NULL},
302 /*OSD 0x15*/{NULL},
303 /*OSD 0x16*/{NULL},
304 /*OSD 0x17*/{NULL},
305 /*OSD 0x18*/{NULL},
306 /*OSD 0x19*/{NULL},
307 /*OSD 0x1a*/{NULL},
308 /*OSD 0x1b*/{NULL},
309 /*OSD 0x1c*/{NULL},
310 /*OSD 0x1d*/{NULL},
311 /*OSD 0x1e*/{NULL},
312 /*OSD 0x1f*/{NULL},
313 /*OSD 0x20*/{NULL},
314 /*OSD 0x21*/{NULL},
315 /*OSD 0x22*/{NULL},
316 /*OSD 0x23*/{NULL},
317 /*OSD 0x24*/{NULL},
318 /*OSD 0x25*/{NULL},
319 /*OSD 0x26*/{NULL},
320 /*OSD 0x27*/{NULL},
321 /*OSD 0x28*/{NULL},
322 /*OSD 0x29*/{NULL},
323 /*OSD 0x2a*/{NULL},
324 /*OSD 0x2b*/{NULL},
325 /*OSD 0x2c*/{NULL},
326 /*OSD 0x2d*/{NULL},
327 /*OSD 0x2e*/{NULL},
328 /*OSD 0x2f*/{NULL},
329 /*OSD 0x30*/{NULL},
330 /*OSD 0x31*/{NULL},
331 /*OSD 0x32*/{NULL},
332 /*OSD 0x33*/{NULL},
333 /*OSD 0x34*/{NULL},
334 /*OSD 0x35*/{NULL},
335 /*OSD 0x36*/{NULL},
336 /*OSD 0x37*/{NULL},
337 /*OSD 0x38*/{NULL},
338 /*OSD 0x39*/{NULL},
339 /*OSD 0x3a*/{NULL},
340 /*OSD 0x3b*/{NULL},
341 /*OSD 0x3c*/{NULL},
342 /*OSD 0x3d*/{NULL},
343 /*OSD 0x3e*/{NULL},
344 /*OSD 0x3f*/{NULL},
345 /*OSD 0x40*/{NULL},
346 /*OSD 0x41*/{NULL},
347 /*OSD 0x42*/{NULL},
348 /*OSD 0x43*/{NULL},
349 /*OSD 0x44*/{NULL},
350 /*OSD 0x45*/{NULL},
351 /*OSD 0x46*/{NULL},
352 /*OSD 0x47*/{NULL},
353 /*OSD 0x48*/{NULL},
354 /*OSD 0x49*/{NULL},
355 /*OSD 0x4a*/{NULL},
356 /*OSD 0x4b*/{NULL},
357 /*OSD 0x4c*/{dissect_spc3_logselect},
358 /*OSD 0x4d*/{dissect_spc3_logsense},
359 /*OSD 0x4e*/{NULL},
360 /*OSD 0x4f*/{NULL},
361 /*OSD 0x50*/{NULL},
362 /*OSD 0x51*/{NULL},
363 /*OSD 0x52*/{NULL},
364 /*OSD 0x53*/{NULL},
365 /*OSD 0x54*/{NULL},
366 /*OSD 0x55*/{dissect_spc3_modeselect10},
367 /*OSD 0x56*/{NULL},
368 /*OSD 0x57*/{NULL},
369 /*OSD 0x58*/{NULL},
370 /*OSD 0x59*/{NULL},
371 /*OSD 0x5a*/{dissect_spc3_modesense10},
372 /*OSD 0x5b*/{NULL},
373 /*OSD 0x5c*/{NULL},
374 /*OSD 0x5d*/{NULL},
375 /*OSD 0x5e*/{dissect_spc3_persistentreservein},
376 /*OSD 0x5f*/{dissect_spc3_persistentreserveout},
377 /*OSD 0x60*/{NULL},
378 /*OSD 0x61*/{NULL},
379 /*OSD 0x62*/{NULL},
380 /*OSD 0x63*/{NULL},
381 /*OSD 0x64*/{NULL},
382 /*OSD 0x65*/{NULL},
383 /*OSD 0x66*/{NULL},
384 /*OSD 0x67*/{NULL},
385 /*OSD 0x68*/{NULL},
386 /*OSD 0x69*/{NULL},
387 /*OSD 0x6a*/{NULL},
388 /*OSD 0x6b*/{NULL},
389 /*OSD 0x6c*/{NULL},
390 /*OSD 0x6d*/{NULL},
391 /*OSD 0x6e*/{NULL},
392 /*OSD 0x6f*/{NULL},
393 /*OSD 0x70*/{NULL},
394 /*OSD 0x71*/{NULL},
395 /*OSD 0x72*/{NULL},
396 /*OSD 0x73*/{NULL},
397 /*OSD 0x74*/{NULL},
398 /*OSD 0x75*/{NULL},
399 /*OSD 0x76*/{NULL},
400 /*OSD 0x77*/{NULL},
401 /*OSD 0x78*/{NULL},
402 /*OSD 0x79*/{NULL},
403 /*OSD 0x7a*/{NULL},
404 /*OSD 0x7b*/{NULL},
405 /*OSD 0x7c*/{NULL},
406 /*OSD 0x7d*/{NULL},
407 /*OSD 0x7e*/{NULL},
408 /*OSD 0x7f*/{dissect_osd_opcode},
409 /*OSD 0x80*/{NULL},
410 /*OSD 0x81*/{NULL},
411 /*OSD 0x82*/{NULL},
412 /*OSD 0x83*/{NULL},
413 /*OSD 0x84*/{NULL},
414 /*OSD 0x85*/{NULL},
415 /*OSD 0x86*/{NULL},
416 /*OSD 0x87*/{NULL},
417 /*OSD 0x88*/{NULL},
418 /*OSD 0x89*/{NULL},
419 /*OSD 0x8a*/{NULL},
420 /*OSD 0x8b*/{NULL},
421 /*OSD 0x8c*/{NULL},
422 /*OSD 0x8d*/{NULL},
423 /*OSD 0x8e*/{NULL},
424 /*OSD 0x8f*/{NULL},
425 /*OSD 0x90*/{NULL},
426 /*OSD 0x91*/{NULL},
427 /*OSD 0x92*/{NULL},
428 /*OSD 0x93*/{NULL},
429 /*OSD 0x94*/{NULL},
430 /*OSD 0x95*/{NULL},
431 /*OSD 0x96*/{NULL},
432 /*OSD 0x97*/{NULL},
433 /*OSD 0x98*/{NULL},
434 /*OSD 0x99*/{NULL},
435 /*OSD 0x9a*/{NULL},
436 /*OSD 0x9b*/{NULL},
437 /*OSD 0x9c*/{NULL},
438 /*OSD 0x9d*/{NULL},
439 /*OSD 0x9e*/{NULL},
440 /*OSD 0x9f*/{NULL},
441 /*OSD 0xa0*/{dissect_spc3_reportluns},
442 /*OSD 0xa1*/{NULL},
443 /*OSD 0xa2*/{NULL},
444 /*OSD 0xa3*/{NULL},
445 /*OSD 0xa4*/{NULL},
446 /*OSD 0xa5*/{NULL},
447 /*OSD 0xa6*/{NULL},
448 /*OSD 0xa7*/{NULL},
449 /*OSD 0xa8*/{NULL},
450 /*OSD 0xa9*/{NULL},
451 /*OSD 0xaa*/{NULL},
452 /*OSD 0xab*/{NULL},
453 /*OSD 0xac*/{NULL},
454 /*OSD 0xad*/{NULL},
455 /*OSD 0xae*/{NULL},
456 /*OSD 0xaf*/{NULL},
457 /*OSD 0xb0*/{NULL},
458 /*OSD 0xb1*/{NULL},
459 /*OSD 0xb2*/{NULL},
460 /*OSD 0xb3*/{NULL},
461 /*OSD 0xb4*/{NULL},
462 /*OSD 0xb5*/{NULL},
463 /*OSD 0xb6*/{NULL},
464 /*OSD 0xb7*/{NULL},
465 /*OSD 0xb8*/{NULL},
466 /*OSD 0xb9*/{NULL},
467 /*OSD 0xba*/{NULL},
468 /*OSD 0xbb*/{NULL},
469 /*OSD 0xbc*/{NULL},
470 /*OSD 0xbd*/{NULL},
471 /*OSD 0xbe*/{NULL},
472 /*OSD 0xbf*/{NULL},
473 /*OSD 0xc0*/{NULL},
474 /*OSD 0xc1*/{NULL},
475 /*OSD 0xc2*/{NULL},
476 /*OSD 0xc3*/{NULL},
477 /*OSD 0xc4*/{NULL},
478 /*OSD 0xc5*/{NULL},
479 /*OSD 0xc6*/{NULL},
480 /*OSD 0xc7*/{NULL},
481 /*OSD 0xc8*/{NULL},
482 /*OSD 0xc9*/{NULL},
483 /*OSD 0xca*/{NULL},
484 /*OSD 0xcb*/{NULL},
485 /*OSD 0xcc*/{NULL},
486 /*OSD 0xcd*/{NULL},
487 /*OSD 0xce*/{NULL},
488 /*OSD 0xcf*/{NULL},
489 /*OSD 0xd0*/{NULL},
490 /*OSD 0xd1*/{NULL},
491 /*OSD 0xd2*/{NULL},
492 /*OSD 0xd3*/{NULL},
493 /*OSD 0xd4*/{NULL},
494 /*OSD 0xd5*/{NULL},
495 /*OSD 0xd6*/{NULL},
496 /*OSD 0xd7*/{NULL},
497 /*OSD 0xd8*/{NULL},
498 /*OSD 0xd9*/{NULL},
499 /*OSD 0xda*/{NULL},
500 /*OSD 0xdb*/{NULL},
501 /*OSD 0xdc*/{NULL},
502 /*OSD 0xdd*/{NULL},
503 /*OSD 0xde*/{NULL},
504 /*OSD 0xdf*/{NULL},
505 /*OSD 0xe0*/{NULL},
506 /*OSD 0xe1*/{NULL},
507 /*OSD 0xe2*/{NULL},
508 /*OSD 0xe3*/{NULL},
509 /*OSD 0xe4*/{NULL},
510 /*OSD 0xe5*/{NULL},
511 /*OSD 0xe6*/{NULL},
512 /*OSD 0xe7*/{NULL},
513 /*OSD 0xe8*/{NULL},
514 /*OSD 0xe9*/{NULL},
515 /*OSD 0xea*/{NULL},
516 /*OSD 0xeb*/{NULL},
517 /*OSD 0xec*/{NULL},
518 /*OSD 0xed*/{NULL},
519 /*OSD 0xee*/{NULL},
520 /*OSD 0xef*/{NULL},
521 /*OSD 0xf0*/{NULL},
522 /*OSD 0xf1*/{NULL},
523 /*OSD 0xf2*/{NULL},
524 /*OSD 0xf3*/{NULL},
525 /*OSD 0xf4*/{NULL},
526 /*OSD 0xf5*/{NULL},
527 /*OSD 0xf6*/{NULL},
528 /*OSD 0xf7*/{NULL},
529 /*OSD 0xf8*/{NULL},
530 /*OSD 0xf9*/{NULL},
531 /*OSD 0xfa*/{NULL},
532 /*OSD 0xfb*/{NULL},
533 /*OSD 0xfc*/{NULL},
534 /*OSD 0xfd*/{NULL},
535 /*OSD 0xfe*/{NULL},
536 /*OSD 0xff*/{NULL}
537 };
538
539
540
541
542 void
543 proto_register_scsi_osd(void)
544 {
545         static hf_register_info hf[] = {
546         { &hf_scsi_osd_opcode,
547           {"OSD Opcode", "scsi.osd.opcode", FT_UINT8, BASE_HEX,
548            VALS (scsi_osd_vals), 0x0, "", HFILL}},
549         { &hf_scsi_osd_control,
550           {"Control", "scsi.osd.cdb.control", FT_UINT8, BASE_HEX,
551            NULL, 0x0, "", HFILL}},
552         { &hf_scsi_osd_add_cdblen,
553           {"Additional CDB Length", "scsi.osd.addcdblen", FT_UINT8, BASE_DEC,
554            NULL, 0x0, "", HFILL}},
555         { &hf_scsi_osd_svcaction,
556           {"Service Action", "scsi.osd.svcaction", FT_UINT16, BASE_HEX,
557            VALS(scsi_osd_svcaction_vals), 0x0, "", HFILL}},
558         { &hf_scsi_osd_option,
559           {"Option", "scsi.osd.option", FT_UINT8, BASE_HEX,
560            NULL, 0x0, "", HFILL}},
561         { &hf_scsi_osd_option_dpo,
562           {"DPO", "scsi.osd.option.dpo", FT_BOOLEAN, 8,
563            TFS(&option_dpo_tfs), 0x10, "", HFILL}},
564         { &hf_scsi_osd_option_fua,
565           {"FUA", "scsi.osd.option.fua", FT_BOOLEAN, 8,
566            TFS(&option_fua_tfs), 0x08, "", HFILL}},
567         { &hf_scsi_osd_getsetattrib,
568           {"GET/SET CDBFMT", "scsi.osd.getset", FT_UINT8, BASE_HEX,
569            VALS(scsi_osd_getsetattrib_vals), 0x30, "", HFILL}},
570         { &hf_scsi_osd_timestamps_control,
571           {"Timestamps Control", "scsi.osd.timestamps_control", FT_UINT8, BASE_HEX,
572            VALS(scsi_osd_timestamps_control_vals), 0x0, "", HFILL}},
573         };
574
575         /* Setup protocol subtree array */
576         static gint *ett[] = {
577                 &ett_osd_option,
578         };
579
580         /* Register the protocol name and description */
581         proto_scsi_osd = proto_register_protocol("SCSI_OSD", "SCSI_OSD", "scsi_osd");
582
583         /* Required function calls to register the header fields and subtrees used */
584         proto_register_field_array(proto_scsi_osd, hf, array_length(hf));
585         proto_register_subtree_array(ett, array_length(ett));
586 }
587
588 void
589 proto_reg_handoff_scsi_osd(void)
590 {
591 }