Update a URL.
[obnox/wireshark/wip.git] / packet-fcsp.c
1 /* packet-fc-sp.c
2  * Routines for Fibre Channel Security Protocol (FC-SP)
3  * This decoder is for FC-SP version 1.1
4  * Copyright 2003, Dinesh G Dutt <ddutt@cisco.com>
5  *
6  * $Id: packet-fcsp.c,v 1.2 2003/11/07 08:47:53 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from WHATEVER_FILE_YOU_USED (where "WHATEVER_FILE_YOU_USED"
13  * is a dissector file; if you just copied this from README.developer,
14  * don't bother with the "Copied from" - you don't even need to put
15  * in a "Copied from" if you copied an existing dissector, especially
16  * if the bulk of the code in the new dissector is your code)
17  * 
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  * 
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  * 
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
43 #endif
44
45 #ifdef HAVE_NETINET_IN_H
46 # include <netinet/in.h>
47 #endif
48
49 #include <glib.h>
50
51 #ifdef NEED_SNPRINTF_H
52 # include "snprintf.h"
53 #endif
54
55 #include "prefs.h"
56 #include <epan/packet.h>
57 #include <epan/conversation.h>
58 #include "etypes.h"
59 #include "packet-fc.h"
60 #include "packet-fcsp.h"
61
62 /* Initialize the protocol and registered fields */
63 static int proto_fcsp              = -1;
64 static int hf_auth_proto_ver       = -1;
65 static int hf_auth_msg_code        = -1;
66 static int hf_auth_flags           = -1;
67 static int hf_auth_len             = -1;
68 static int hf_auth_tid             = -1;
69 static int hf_auth_initiator_wwn   = -1;
70 static int hf_auth_initiator_name  = -1;
71 static int hf_auth_usable_proto    = -1;
72 static int hf_auth_rjt_code        = -1;
73 static int hf_auth_rjt_codedet     = -1;
74 static int hf_auth_responder_wwn   = -1;
75 static int hf_auth_responder_name  = -1;
76 static int hf_auth_dhchap_groupid  = -1;
77 static int hf_auth_dhchap_hashid   = -1;
78 static int hf_auth_dhchap_chal_len = -1;
79 static int hf_auth_dhchap_val_len  = -1;
80 static int hf_auth_dhchap_rsp_len  = -1;
81 static int hf_auth_initiator_name_type = -1;
82 static int hf_auth_initiator_name_len = -1;
83 static int hf_auth_responder_name_len = -1;
84 static int hf_auth_responder_name_type = -1;
85 static int hf_auth_proto_type = -1;
86 static int hf_auth_proto_param_len = -1;
87 static int hf_auth_dhchap_param_tag = -1;
88 static int hf_auth_dhchap_param_len = -1;
89 static int hf_auth_dhchap_hash_type = -1;
90 static int hf_auth_dhchap_group_type = -1;
91 static int hf_auth_dhchap_dhvalue = -1;
92 static int hf_auth_dhchap_chal_value = -1;
93 static int hf_auth_dhchap_rsp_value = -1;
94
95 /* Initialize the subtree pointers */
96 static gint ett_fcsp = -1;
97
98 static dissector_handle_t data_handle;
99
100 static const value_string fcauth_msgcode_vals[] = {
101     {FC_AUTH_MSG_AUTH_REJECT, "AUTH_Reject"},
102     {FC_AUTH_MSG_AUTH_NEGOTIATE, "AUTH_Negotiate"},
103     {FC_AUTH_MSG_AUTH_DONE, "AUTH_Done"},
104     {FC_AUTH_DHCHAP_CHALLENGE, "DHCHAP_Challenge"},
105     {FC_AUTH_DHCHAP_REPLY, "DHCHAP_Reply"},
106     {FC_AUTH_DHCHAP_SUCCESS, "DHCHAP_Success"},
107     {FC_AUTH_FCAP_REQUEST, "FCAP_Request"},
108     {FC_AUTH_FCAP_ACKNOWLEDGE, "FCAP_Acknowledge"},
109     {FC_AUTH_FCAP_CONFIRM, "FCAP_Confirm"},
110     {FC_AUTH_FCPAP_INIT, "FCPAP_Init"},
111     {FC_AUTH_FCPAP_ACCEPT, "FCPAP_Accept"},
112     {FC_AUTH_FCPAP_COMPLETE, "FCPAP_Complete"},
113     {0, NULL},
114 };
115
116 static const value_string fcauth_rjtcode_vals[] = {
117     {0x01, "Authentication Failure"},
118     {0x02, "Logical Error"},
119     {0, NULL},
120 };
121
122 static const value_string fcauth_rjtcode_detail_vals[] = {
123     {0x01, "Authentication Mechanism Not Usable"},
124     {0x02, "DH Group Not Usable"},
125     {0x03, "Hash Algorithm Not Usable"},
126     {0x04, "Authentication Protocol Instance Already Started"},
127     {0x05, "Authentication Failed "},
128     {0x06, "Incorrect Payload "},
129     {0x07, "Incorrect Authentication Protocol Message"},
130     {0x08, "Protocol Reset"},
131     {0, NULL},
132 };
133
134 static const value_string fcauth_dhchap_param_vals[] = {
135     {FC_AUTH_DHCHAP_PARAM_HASHLIST, "HashList"},
136     {FC_AUTH_DHCHAP_PARAM_DHgIDLIST, "DHgIDList"},
137     {0, NULL},
138 };
139
140 static const value_string fcauth_dhchap_hash_algo_vals[] = {
141     {FC_AUTH_DHCHAP_HASH_MD5, "MD5"},
142     {FC_AUTH_DHCHAP_HASH_SHA1, "SHA-1"},
143     {0, NULL},
144 };
145
146 static const value_string fcauth_name_type_vals[] = {
147     {FC_AUTH_NAME_TYPE_WWN, "WWN"},
148     {0, NULL},
149 };
150
151 static const value_string fcauth_proto_type_vals[] = {
152     {FC_AUTH_PROTO_TYPE_DHCHAP, "DHCHAP"},
153     {FC_AUTH_PROTO_TYPE_FCAP, "FCAP"},
154     {0, NULL},
155 };
156
157 static const value_string fcauth_dhchap_dhgid_vals[] = {
158     {0, "DH NULL"},
159     {1, "DH Group 1024"},
160     {2, "DH Group 1280"},
161     {3, "DH Group 1536"},
162     {4, "DH Group 2048"},
163     {0, NULL},
164 };
165
166 /* this format is required because a script is used to build the C function
167    that calls all the protocol registration.
168 */
169
170 void dissect_fcsp_dhchap_auth_param (tvbuff_t *tvb, proto_tree *tree,
171                                      int offset, gint32 total_len)
172 {
173     guint16 auth_param_tag;
174     guint16 param_len = 0, i;
175     
176     if (tree) {
177         auth_param_tag = tvb_get_ntohs (tvb, offset);
178         total_len -= 4;
179         
180         while (total_len > 0) {
181             proto_tree_add_item (tree, hf_auth_dhchap_param_tag, tvb, offset,
182                                  2, 0);
183             proto_tree_add_item (tree, hf_auth_dhchap_param_len, tvb, offset+2,
184                                  2, 0);
185
186             auth_param_tag = tvb_get_ntohs (tvb, offset);
187             param_len = tvb_get_ntohs (tvb, offset+2)*4;
188
189             switch (auth_param_tag) {
190             case FC_AUTH_DHCHAP_PARAM_HASHLIST:
191                 offset += 4;
192                 total_len -= 4;
193                 for (i = 0; i < param_len; i += 4) {
194                     proto_tree_add_item (tree, hf_auth_dhchap_hash_type, tvb,
195                                          offset, 4, 0);
196                     offset += 4;
197                 }
198                 break;
199             case FC_AUTH_DHCHAP_PARAM_DHgIDLIST:
200                 offset += 4;
201                 total_len -= 4;
202                 for (i = 0; i < param_len; i += 4) {
203                     proto_tree_add_item (tree, hf_auth_dhchap_group_type, tvb,
204                                          offset, 4, 0);
205                     offset += 4;
206                 }
207                 break;
208             default:
209                 break;
210             }
211
212             total_len -= param_len;
213         }
214     }
215 }
216
217 void dissect_fcsp_dhchap_challenge (tvbuff_t *tvb, proto_tree *tree)
218 {
219     int offset = 12;
220     guint16 name_type;
221     guint16 param_len, name_len;
222     
223     if (tree) {
224         proto_tree_add_item (tree, hf_auth_responder_name_type, tvb, offset,
225                              2, 0);
226         name_type = tvb_get_ntohs (tvb, offset);
227
228         proto_tree_add_item (tree, hf_auth_responder_name_len, tvb, offset+2,
229                              2, 0);
230
231         name_len = tvb_get_ntohs (tvb, offset+2);
232         
233         if (name_type == FC_AUTH_NAME_TYPE_WWN) {
234             proto_tree_add_string (tree, hf_auth_responder_wwn, tvb, offset+4,
235                                    8,
236                                    fcwwn_to_str (tvb_get_ptr (tvb, offset+4,
237                                                               8)));
238         }
239         else {
240             proto_tree_add_bytes (tree, hf_auth_responder_name, tvb, offset+4,
241                                   name_len, tvb_get_ptr (tvb, offset+4, name_len));
242         }
243         offset += (4+name_len);
244         
245         proto_tree_add_item (tree, hf_auth_dhchap_hash_type, tvb, offset,
246                              4, 0);
247         proto_tree_add_item (tree, hf_auth_dhchap_group_type, tvb, offset+4,
248                              4, 0);
249         proto_tree_add_item (tree, hf_auth_dhchap_chal_len, tvb, offset+8,
250                              4, 0);
251         param_len = tvb_get_ntohl (tvb, offset+8);
252         
253         proto_tree_add_bytes (tree, hf_auth_dhchap_chal_value, tvb, offset+12,
254                               param_len,
255                               tvb_get_ptr (tvb, offset+12, param_len));
256         offset += (param_len + 12);
257
258         proto_tree_add_item (tree, hf_auth_dhchap_val_len, tvb, offset, 4, 0);
259         param_len = tvb_get_ntohl (tvb, offset);
260         
261         proto_tree_add_bytes (tree, hf_auth_dhchap_dhvalue, tvb, offset+4,
262                               param_len,
263                               tvb_get_ptr (tvb, offset+4, param_len));
264     }
265 }
266
267
268 void dissect_fcsp_dhchap_reply (tvbuff_t *tvb, proto_tree *tree)
269 {
270     int offset = 12;
271     guint32 param_len;
272     
273     if (tree) {
274         proto_tree_add_item (tree, hf_auth_dhchap_rsp_len, tvb, offset, 4, 0);
275         param_len = tvb_get_ntohl (tvb, offset);
276
277         proto_tree_add_bytes (tree, hf_auth_dhchap_rsp_value, tvb, offset+4,
278                               param_len,
279                               tvb_get_ptr (tvb, offset+4, param_len));
280         offset += (param_len + 4);
281
282         proto_tree_add_item (tree, hf_auth_dhchap_val_len, tvb, offset, 4, 0);
283         param_len = tvb_get_ntohl (tvb, offset);
284
285         proto_tree_add_bytes (tree, hf_auth_dhchap_dhvalue, tvb, offset+4,
286                               param_len,
287                               tvb_get_ptr (tvb, offset+4, param_len));
288         offset += (param_len + 4);
289
290         proto_tree_add_item (tree, hf_auth_dhchap_chal_len, tvb, offset, 4, 0);
291         param_len = tvb_get_ntohl (tvb, offset);
292
293         proto_tree_add_bytes (tree, hf_auth_dhchap_chal_value, tvb, offset+4,
294                               param_len,
295                               tvb_get_ptr (tvb, offset+4, param_len));
296     }
297 }
298
299 void dissect_fcsp_dhchap_success (tvbuff_t *tvb, proto_tree *tree)
300 {
301     int offset = 12;
302     guint32 param_len;
303     
304     if (tree) {
305         proto_tree_add_item (tree, hf_auth_dhchap_rsp_len, tvb, offset, 4, 0);
306         param_len = tvb_get_ntohl (tvb, offset);
307
308         proto_tree_add_bytes (tree, hf_auth_dhchap_rsp_value, tvb, offset+4,
309                               param_len,
310                               tvb_get_ptr (tvb, offset+4, param_len));
311     }
312 }
313
314
315 void dissect_fcsp_auth_negotiate (tvbuff_t *tvb, proto_tree *tree)
316 {
317     int offset = 12;
318     guint16 name_type, name_len, proto_type, param_len;
319     guint32 num_protos, i;
320
321     if (tree) {
322         proto_tree_add_item (tree, hf_auth_initiator_name_type, tvb, offset,
323                              2, 0);
324         name_type = tvb_get_ntohs (tvb, offset);
325
326         proto_tree_add_item (tree, hf_auth_initiator_name_len, tvb, offset+2,
327                              2, 0);
328         name_len = tvb_get_ntohs (tvb, offset+2);
329
330         if (name_type == FC_AUTH_NAME_TYPE_WWN) {
331             proto_tree_add_string (tree, hf_auth_initiator_wwn, tvb, offset+4, 8,
332                                    fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8)));
333         }
334         else {
335             proto_tree_add_bytes (tree, hf_auth_initiator_name, tvb, offset+4,
336                                   name_len, tvb_get_ptr (tvb, offset+4,
337                                                          name_len));
338         }
339
340         offset += (4+name_len);
341
342         proto_tree_add_item (tree, hf_auth_usable_proto, tvb, offset, 4, 0);
343         num_protos = tvb_get_ntohl (tvb, offset);
344         offset += 4;
345         
346         for (i = 0; i < num_protos; i++) {
347             proto_tree_add_item (tree, hf_auth_proto_param_len, tvb, offset, 4, 0);
348             param_len = tvb_get_ntohl (tvb, offset);
349             offset += 4;
350             
351             if (tvb_bytes_exist (tvb, offset, param_len)) {
352                 proto_type = tvb_get_ntohl (tvb, offset);
353
354                 proto_tree_add_item (tree, hf_auth_proto_type, tvb, offset, 4, 0);
355                 switch (proto_type) {
356                 case FC_AUTH_PROTO_TYPE_DHCHAP:
357                     dissect_fcsp_dhchap_auth_param (tvb, tree, offset+4, param_len);
358                     break;
359                 case FC_AUTH_PROTO_TYPE_FCAP:
360                     break;
361                 default:
362                     break;
363                 }
364             }
365             offset += param_len;
366         }
367     }
368 }
369
370 void dissect_fcsp_auth_done (tvbuff_t *tvb _U_, proto_tree *tree _U_)
371 {
372 }
373
374 void dissect_fcsp_auth_rjt (tvbuff_t *tvb, proto_tree *tree)
375 {
376     int offset = 12;
377     
378     if (tree) {
379         proto_tree_add_item (tree, hf_auth_rjt_code, tvb, offset, 1, 0);
380         proto_tree_add_item (tree, hf_auth_rjt_codedet, tvb, offset+1, 1, 0);
381     }
382 }
383
384 void dissect_fcsp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
385 {
386     proto_item *ti = NULL;
387     guint8 opcode;
388     int offset = 0;
389     proto_tree *fcsp_tree = NULL;
390
391     /* Make entry in the Info column on summary display */
392     opcode = tvb_get_guint8 (tvb, 2);
393
394     if (check_col (pinfo->cinfo, COL_INFO)) {
395         col_set_str (pinfo->cinfo, COL_INFO,
396                      val_to_str (opcode, fcauth_msgcode_vals, "0x%x"));
397     }
398     
399     if (tree) {
400         ti = proto_tree_add_protocol_format (tree, proto_fcsp, tvb, 0,
401                                              tvb_length (tvb), "FC-SP");
402         fcsp_tree = proto_item_add_subtree (ti, ett_fcsp);
403
404         proto_tree_add_item (fcsp_tree, hf_auth_flags, tvb, offset+1, 1, 0);
405         proto_tree_add_item (fcsp_tree, hf_auth_msg_code, tvb, offset+2, 1, 0);
406         proto_tree_add_item (fcsp_tree, hf_auth_proto_ver, tvb, offset+3, 1,
407                              0);
408         proto_tree_add_item (fcsp_tree, hf_auth_len, tvb, offset+4, 4, 0);
409         proto_tree_add_item (fcsp_tree, hf_auth_tid, tvb, offset+8, 4, 0);
410
411         switch (opcode) {
412         case FC_AUTH_MSG_AUTH_REJECT:
413             dissect_fcsp_auth_rjt (tvb, tree);
414             break;
415         case FC_AUTH_MSG_AUTH_NEGOTIATE:
416             dissect_fcsp_auth_negotiate (tvb, tree);
417             break;
418         case FC_AUTH_MSG_AUTH_DONE:
419             dissect_fcsp_auth_done (tvb, tree);
420             break;
421         case FC_AUTH_DHCHAP_CHALLENGE:
422             dissect_fcsp_dhchap_challenge (tvb, tree);
423             break;
424         case FC_AUTH_DHCHAP_REPLY:
425             dissect_fcsp_dhchap_reply (tvb, tree);
426             break;
427         case FC_AUTH_DHCHAP_SUCCESS:
428             dissect_fcsp_dhchap_success (tvb, tree);
429             break;
430         case FC_AUTH_FCAP_REQUEST:
431         case FC_AUTH_FCAP_ACKNOWLEDGE:
432         case FC_AUTH_FCAP_CONFIRM:
433         case FC_AUTH_FCPAP_INIT:
434         case FC_AUTH_FCPAP_ACCEPT:
435         case FC_AUTH_FCPAP_COMPLETE:
436             proto_tree_add_text (fcsp_tree, tvb, offset+12, tvb_length (tvb),
437                                  "FCAP Decoding Not Supported");
438             break;
439         default:
440             break;
441         }
442     }
443 }
444
445 void
446 proto_register_fcsp (void)
447 {                 
448     /* Setup list of header fields  See Section 1.6.1 for details*/
449     static hf_register_info hf[] = {
450         { &hf_auth_proto_ver,
451           {"Protocol Version", "fcsp.version", FT_UINT8, BASE_HEX, NULL,
452            0x0, "", HFILL}},
453         { &hf_auth_msg_code,
454           {"Message Code", "fcsp.opcode", FT_UINT8, BASE_HEX,
455            VALS (fcauth_msgcode_vals), 0x0, "", HFILL}},
456         { &hf_auth_flags,
457           {"Flags", "fcsp.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
458            HFILL}},
459         { &hf_auth_len,
460           {"Packet Length", "fcsp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
461            "", HFILL}},
462         { &hf_auth_tid,
463           {"Transaction Identifier", "fcsp.tid", FT_UINT32, BASE_HEX, NULL,
464            0x0, "", HFILL}},
465         { &hf_auth_initiator_wwn,
466           {"Initiator Name (WWN)", "fcsp.initwwn", FT_STRING, BASE_HEX, NULL,
467            0x0, "", HFILL}},
468         { &hf_auth_initiator_name,
469           {"Initiator Name (Unknown Type)", "fcsp.initname", FT_BYTES,
470            BASE_HEX, NULL, 0x0, "", HFILL}},
471         { &hf_auth_initiator_name_type,
472           {"Initiator Name Type", "fcsp.initnametype", FT_UINT16, BASE_HEX,
473            VALS (fcauth_name_type_vals), 0x0, "", HFILL}},
474         { &hf_auth_initiator_name_len,
475           {"Initiator Name Length", "fcsp.initnamelen", FT_UINT16, BASE_DEC,
476            NULL, 0x0, "", HFILL}},
477         { &hf_auth_usable_proto,
478           {"Number of Usable Protocols", "fcsp.usableproto", FT_UINT32,
479            BASE_DEC, NULL, 0x0, "", HFILL}},
480         { &hf_auth_rjt_code,
481           {"Reason Code", "fcsp.rjtcode", FT_UINT8, BASE_DEC,
482            VALS (fcauth_rjtcode_vals), 0x0, "", HFILL}},
483         { &hf_auth_rjt_codedet,
484           {"Reason Code Explanation", "fcsp.rjtcodet", FT_UINT8, BASE_DEC,
485            VALS (fcauth_rjtcode_detail_vals), 0x0, "", HFILL}},
486         { &hf_auth_responder_wwn,
487           {"Responder Name (WWN)", "fcsp.rspwwn", FT_STRING, BASE_HEX, NULL,
488            0x0, "", HFILL}},
489         { &hf_auth_responder_name,
490           {"Responder Name (Unknown Type)", "fcsp.rspname", FT_BYTES, BASE_HEX,
491            NULL, 0x0, "", HFILL}},
492         { &hf_auth_responder_name_type,
493           {"Responder Name Type", "fcsp.rspnametype", FT_UINT16, BASE_HEX,
494            VALS (fcauth_name_type_vals), 0x0, "", HFILL}},
495         { &hf_auth_responder_name_len,
496           {"Responder Name Type", "fcsp.rspnamelen", FT_UINT16, BASE_DEC,
497            NULL, 0x0, "", HFILL}},
498         { &hf_auth_dhchap_hashid,
499           {"Hash Identifier", "fcsp.dhchap.hashid", FT_UINT32, BASE_HEX, NULL, 0x0,
500            "", HFILL}},
501         { &hf_auth_dhchap_groupid,
502           {"DH Group Identifier", "fcsp.dhchap.groupid", FT_UINT32, BASE_HEX, NULL,
503            0x0, "", HFILL}},
504         { &hf_auth_dhchap_chal_len,
505           {"Challenge Value Length", "fcsp.dhchap.challen", FT_UINT32, BASE_DEC,
506            NULL, 0x0, "", HFILL}},
507         { &hf_auth_dhchap_val_len,
508           {"DH Value Length", "fcsp.dhchap.vallen", FT_UINT32, BASE_DEC, NULL,
509            0x0, "", HFILL}},
510         { &hf_auth_dhchap_rsp_len,
511           {"Response Value Length", "fcsp.dhchap.rsplen", FT_UINT32, BASE_DEC,
512            NULL, 0x0, "", HFILL}},
513         { &hf_auth_proto_type,
514           {"Authentication Protocol Type", "fcsp.proto", FT_UINT32, BASE_DEC,
515            VALS (fcauth_proto_type_vals), 0x0, "", HFILL}},
516         { &hf_auth_proto_param_len,
517           {"Protocol Parameters Length", "fcsp.protoparamlen", FT_UINT32,
518            BASE_DEC, NULL, 0x0, "", HFILL}},
519         { &hf_auth_dhchap_param_tag,
520           {"Parameter Tag", "fcsp.dhchap.paramtype", FT_UINT16, BASE_HEX,
521            VALS (fcauth_dhchap_param_vals), 0x0, "", HFILL}},
522         { &hf_auth_dhchap_param_len,
523           {"Parameter Length", "fcsp.dhchap.paramlen", FT_UINT16, BASE_DEC,
524            NULL, 0x0, "", HFILL}},
525         { &hf_auth_dhchap_hash_type,
526           {"Hash Algorithm", "fcsp.dhchap.hashtype", FT_UINT32, BASE_DEC,
527            VALS (fcauth_dhchap_hash_algo_vals), 0x0, "", HFILL}},
528         { &hf_auth_dhchap_group_type,
529           {"DH Group", "fcsp.dhchap.dhgid", FT_UINT32, BASE_DEC,
530            VALS (fcauth_dhchap_dhgid_vals), 0x0, "", HFILL}},
531         { &hf_auth_dhchap_chal_value,
532           {"Challenge Value", "fcsp.dhchap.chalval", FT_BYTES, BASE_HEX,
533            NULL, 0x0, "", HFILL}},
534         { &hf_auth_dhchap_dhvalue,
535           {"DH Value", "fcsp.dhchap.dhvalue", FT_BYTES, BASE_HEX, NULL, 0x0,
536            "", HFILL}},
537         { &hf_auth_dhchap_rsp_value,
538           {"Response Value", "fcsp.dhchap.rspval", FT_BYTES, BASE_HEX, NULL,
539            0x0, "", HFILL}},
540           
541     };
542
543
544     /* Setup protocol subtree array */
545     static gint *ett[] = {
546         &ett_fcsp,
547     };
548
549     /* Register the protocol name and description */
550     proto_fcsp = proto_register_protocol ("Fibre Channel Security Protocol",
551                                            "FC-SP", "fcsp");
552
553     register_dissector("fcsp", dissect_fcsp, proto_fcsp);
554     /* Required function calls to register the header fields and subtrees used */
555     proto_register_field_array(proto_fcsp, hf, array_length(hf));
556     proto_register_subtree_array(ett, array_length(ett));
557
558     data_handle = find_dissector("data");
559 }
560
561 /* If this dissector uses sub-dissector registration add a registration routine.
562    This format is required because a script is used to find these routines and
563    create the code that calls these routines.
564 */
565 void
566 proto_reg_handoff_fcsp (void)
567 {
568     dissector_handle_t fcsp_handle;
569
570     fcsp_handle = create_dissector_handle (dissect_fcsp, proto_fcsp);
571
572     data_handle = find_dissector ("data");
573 }
574