Replace tabs in files with editor modeline "expandtab"
[metze/wireshark/wip.git] / epan / dissectors / packet-fcdns.c
1 /* packet-fc-dns.c
2  * Routines for FC distributed Name Server (dNS)
3  * Copyright 2001, Dinesh G Dutt <ddutt@andiamo.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #define NEW_PROTO_TREE_API
25
26 #include "config.h"
27
28 #include <epan/packet.h>
29 #include <epan/expert.h>
30 #include <epan/to_str.h>
31 #include "packet-fc.h"
32 #include "packet-fcct.h"
33 #include "packet-fcdns.h"
34 #include "packet-fcswils.h"
35
36 void proto_register_fcdns(void);
37 void proto_reg_handoff_fcdns(void);
38
39 /*
40  * See FC-GS-2.
41  */
42
43 static dissector_handle_t dns_handle;
44
45 /* protocol and registered fields */
46
47 static header_field_info *hfi_fcdns = NULL;
48
49 #define FCDNS_HFI_INIT HFI_INIT(proto_fcdns)
50
51 #if 0
52 static header_field_info hfi_fcdns_gssubtype FCDNS_HFI_INIT =
53           {"GS_Subtype", "fcdns.gssubtype", FT_UINT8, BASE_HEX,
54            VALS(fc_dns_subtype_val), 0x0, NULL, HFILL};
55 #endif
56
57 static header_field_info hfi_fcdns_opcode FCDNS_HFI_INIT =
58          {"Opcode", "fcdns.opcode", FT_UINT16, BASE_HEX, VALS (fc_dns_opcode_val),
59           0x0, NULL, HFILL};
60
61 static header_field_info hfi_fcdns_reason FCDNS_HFI_INIT =
62           {"Reason Code", "fcdns.rply.reason", FT_UINT8, BASE_HEX,
63            VALS (fc_ct_rjt_code_vals), 0x0, NULL, HFILL};
64
65 static header_field_info hfi_fcdns_vendor FCDNS_HFI_INIT =
66           {"Vendor Unique Reject Code", "fcdns.rply.vendor", FT_UINT8,
67            BASE_HEX, NULL, 0x0, NULL, HFILL};
68
69 static header_field_info hfi_fcdns_req_portid FCDNS_HFI_INIT =
70           {"Port Identifier", "fcdns.req.portid", FT_BYTES, SEP_DOT, NULL, 0x0,
71            NULL, HFILL};
72
73 static header_field_info hfi_fcdns_rply_pname FCDNS_HFI_INIT =
74           {"Port Name", "fcdns.rply.pname", FT_FCWWN, BASE_NONE, NULL, 0x0, NULL,
75            HFILL};
76
77 static header_field_info hfi_fcdns_rply_nname FCDNS_HFI_INIT =
78           {"Node Name", "fcdns.rply.nname", FT_FCWWN, BASE_NONE, NULL, 0x0, NULL,
79            HFILL};
80
81 static header_field_info hfi_fcdns_rply_gft FCDNS_HFI_INIT =
82           {"FC-4 Types Supported", "fcdns.rply.fc4type", FT_NONE, BASE_NONE,
83            NULL, 0x0, NULL, HFILL};
84
85 static header_field_info hfi_fcdns_rply_snamelen FCDNS_HFI_INIT =
86           {"Symbolic Node Name Length", "fcdns.rply.snamelen", FT_UINT8, BASE_DEC,
87            NULL, 0x0, NULL, HFILL};
88
89 static header_field_info hfi_fcdns_rply_sname FCDNS_HFI_INIT =
90           {"Symbolic Node Name", "fcdns.rply.sname", FT_STRING, BASE_NONE, NULL,
91            0x0, NULL, HFILL};
92
93 static header_field_info hfi_fcdns_rply_ptype FCDNS_HFI_INIT =
94           {"Port Type", "fcdns.rply.porttype", FT_UINT8, BASE_HEX,
95            VALS (fc_dns_port_type_val), 0x0, NULL, HFILL};
96
97 static header_field_info hfi_fcdns_rply_fpname FCDNS_HFI_INIT =
98           {"Fabric Port Name", "fcdns.rply.fpname", FT_FCWWN, BASE_NONE, NULL,
99            0x0, NULL, HFILL};
100
101 static header_field_info hfi_fcdns_fc4type FCDNS_HFI_INIT =
102           {"FC-4 Types", "fcdns.req.fc4type", FT_NONE, BASE_NONE,
103            NULL, 0x0, NULL, HFILL};
104
105 static header_field_info hfi_fcdns_rply_fc4type FCDNS_HFI_INIT =
106           {"FC-4 Descriptor Type", "fcdns.rply.fc4type", FT_UINT8, BASE_HEX,
107            VALS (fc_fc4_val), 0x0, NULL, HFILL};
108
109 static header_field_info hfi_fcdns_rply_fc4desc FCDNS_HFI_INIT =
110           {"FC-4 Descriptor", "fcdns.rply.fc4desc", FT_BYTES, BASE_NONE, NULL,
111            0x0, NULL, HFILL};
112
113 static header_field_info hfi_fcdns_req_pname FCDNS_HFI_INIT =
114           {"Port Name", "fcdns.req.portname", FT_FCWWN, BASE_NONE, NULL, 0x0,
115            NULL, HFILL};
116
117 static header_field_info hfi_fcdns_rply_portid FCDNS_HFI_INIT =
118           {"Port Identifier", "fcdns.rply.portid", FT_BYTES, SEP_DOT, NULL,
119            0x0, NULL, HFILL};
120
121 static header_field_info hfi_fcdns_req_nname FCDNS_HFI_INIT =
122           {"Node Name", "fcdns.req.nname", FT_FCWWN, BASE_NONE, NULL, 0x0,
123            NULL, HFILL};
124
125 static header_field_info hfi_fcdns_req_domainscope FCDNS_HFI_INIT =
126           {"Domain ID Scope", "fcdns.req.domainid", FT_UINT8, BASE_HEX, NULL,
127            0x0, NULL, HFILL};
128
129 static header_field_info hfi_fcdns_req_areascope FCDNS_HFI_INIT =
130           {"Area ID Scope", "fcdns.req.areaid", FT_UINT8, BASE_HEX, NULL,
131            0x0, NULL, HFILL};
132
133 static header_field_info hfi_fcdns_req_ptype FCDNS_HFI_INIT =
134           {"Port Type", "fcdns.req.porttype", FT_UINT8, BASE_HEX,
135            VALS (fc_dns_port_type_val), 0x0, NULL, HFILL};
136
137 static header_field_info hfi_fcdns_req_cos FCDNS_HFI_INIT =
138           {"Requested Class of Service", "fcdns.req.class", FT_UINT32, BASE_HEX,
139            NULL, 0x0, NULL, HFILL};
140
141 static header_field_info hfi_fcdns_req_fc4types FCDNS_HFI_INIT =
142           {"FC-4 Types Supported", "fcdns.req.fc4types", FT_NONE, BASE_NONE,
143            NULL, 0x0, NULL, HFILL};
144
145 static header_field_info hfi_fcdns_req_snamelen FCDNS_HFI_INIT =
146           {"Symbolic Name Length", "fcdns.req.snamelen", FT_UINT8, BASE_DEC,
147            NULL, 0x0, NULL, HFILL};
148
149 static header_field_info hfi_fcdns_req_sname FCDNS_HFI_INIT =
150           {"Symbolic Port Name", "fcdns.req.sname", FT_STRING, BASE_NONE, NULL,
151            0x0, NULL, HFILL};
152
153 static header_field_info hfi_fcdns_rply_spnamelen FCDNS_HFI_INIT =
154           {"Symbolic Port Name Length", "fcdns.rply.spnamelen", FT_UINT8,
155            BASE_DEC, NULL, 0x0, NULL, HFILL};
156
157 static header_field_info hfi_fcdns_rply_spname FCDNS_HFI_INIT =
158          {"Symbolic Port Name", "fcdns.rply.spname", FT_STRING, BASE_NONE, NULL,
159           0x0, NULL, HFILL};
160
161 static header_field_info hfi_fcdns_req_spnamelen FCDNS_HFI_INIT =
162           {"Symbolic Port Name Length", "fcdns.req.spnamelen", FT_UINT8,
163            BASE_DEC, NULL, 0x0, NULL, HFILL};
164
165 static header_field_info hfi_fcdns_req_spname FCDNS_HFI_INIT =
166           {"Symbolic Port Name", "fcdns.req.spname", FT_STRING, BASE_NONE, NULL,
167            0x0, NULL, HFILL};
168
169 static header_field_info hfi_fcdns_rply_ipa FCDNS_HFI_INIT =
170           {"Initial Process Associator", "fcdns.rply.ipa", FT_BYTES, BASE_NONE,
171            NULL, 0x0, NULL, HFILL};
172
173 static header_field_info hfi_fcdns_rply_ipnode FCDNS_HFI_INIT =
174           {"Node IP Address", "fcdns.rply.ipnode", FT_IPv6, BASE_NONE, NULL,
175            0x0, NULL, HFILL};
176
177 static header_field_info hfi_fcdns_rply_ipport FCDNS_HFI_INIT =
178           {"Port IP Address", "fcdns.rply.ipport", FT_IPv6, BASE_NONE, NULL,
179            0x0, NULL, HFILL};
180
181 static header_field_info hfi_fcdns_rply_fc4desclen FCDNS_HFI_INIT =
182           {"FC-4 Descriptor Length", "fcdns.rply.fc4desclen", FT_UINT8,
183            BASE_DEC, NULL, 0x0, NULL, HFILL};
184
185 static header_field_info hfi_fcdns_rply_hrdaddr FCDNS_HFI_INIT =
186           {"Hard Address", "fcdns.rply.hrdaddr", FT_BYTES, SEP_DOT, NULL,
187            0x0, NULL, HFILL};
188
189 static header_field_info hfi_fcdns_req_fdesclen FCDNS_HFI_INIT =
190           {"FC-4 Descriptor Length", "fcdns.req.fc4desclen", FT_UINT8, BASE_DEC,
191            NULL, 0x0, NULL, HFILL};
192
193 static header_field_info hfi_fcdns_req_fdesc FCDNS_HFI_INIT =
194           {"FC-4 Descriptor", "fcdns.req.fc4desc", FT_STRING, BASE_NONE, NULL,
195            0x0, NULL, HFILL};
196
197 static header_field_info hfi_fcdns_req_ip FCDNS_HFI_INIT =
198           {"IP Address", "fcdns.req.ip", FT_IPv6, BASE_NONE, NULL, 0x0,
199            NULL, HFILL};
200
201 static header_field_info hfi_fcdns_rjtdetail FCDNS_HFI_INIT =
202           {"Reason Code Explanantion", "fcdns.rply.reasondet", FT_UINT8,
203            BASE_HEX, VALS (fc_dns_rjt_det_code_val), 0x0, NULL, HFILL};
204
205 static header_field_info hfi_fcdns_zone_mbrtype FCDNS_HFI_INIT =
206           {"Zone Member Type", "fcdns.zone.mbrtype", FT_UINT8, BASE_HEX,
207            VALS (fc_swils_zonembr_type_val), 0x0, NULL, HFILL};
208
209 static header_field_info hfi_fcdns_zone_mbrid FCDNS_HFI_INIT =
210           {"Member Identifier", "fcdns.zone.mbrid", FT_STRING, BASE_NONE, NULL,
211            0x0, NULL, HFILL};
212
213 static header_field_info hfi_fcdns_zone_mbrid_wwn FCDNS_HFI_INIT =
214           {"Member Identifier", "fcdns.zone.mbrid.wwn", FT_FCWWN, BASE_NONE, NULL,
215            0x0, NULL, HFILL};
216
217 static header_field_info hfi_fcdns_zone_mbrid_uint FCDNS_HFI_INIT =
218           {"Member Identifier", "fcdns.zone.mbrid.uint", FT_UINT32, BASE_HEX, NULL,
219            0x0, NULL, HFILL};
220
221 static header_field_info hfi_fcdns_zone_mbrid_fc FCDNS_HFI_INIT =
222           {"Member Identifier", "fcdns.zone.mbrid.fc", FT_BYTES, SEP_DOT, NULL,
223            0x0, NULL, HFILL};
224
225 static header_field_info hfi_fcdns_id_length FCDNS_HFI_INIT =
226           {"Identifier Length", "fcdns.id_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL,
227            HFILL};
228
229 static header_field_info hfi_fcdns_zone_flags FCDNS_HFI_INIT =
230           {"Flags", "fcdns.zone_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL,
231            HFILL};
232
233 static header_field_info hfi_fcdns_zonelen FCDNS_HFI_INIT =
234           {"Name Length", "fcdns.zone_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL,
235            HFILL};
236
237 static header_field_info hfi_fcdns_zonenm FCDNS_HFI_INIT =
238           {"Zone Name", "fcdns.zonename", FT_STRING, BASE_NONE, NULL, 0x0, NULL,
239            HFILL};
240
241 static header_field_info hfi_fcdns_portip FCDNS_HFI_INIT =
242           {"Port IP Address", "fcdns.portip", FT_IPv4, BASE_NONE, NULL, 0x0,
243            NULL, HFILL};
244
245 static header_field_info hfi_fcdns_num_entries FCDNS_HFI_INIT =
246           {"Number of Entries", "fcdns.num_entries", FT_UINT32, BASE_HEX,
247            NULL, 0x0, NULL, HFILL};
248
249 static header_field_info hfi_fcdns_sw2_objfmt FCDNS_HFI_INIT =
250           {"Name Entry Object Format", "fcdns.entry.objfmt", FT_UINT8, BASE_HEX,
251            NULL, 0x0, NULL, HFILL};
252
253 static header_field_info hfi_fcdns_num_fc4desc FCDNS_HFI_INIT =
254           {"Number of FC4 Descriptors Registered", "fcdns.entry.numfc4desc",
255            FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL};
256
257 static header_field_info hfi_fcdns_rply_ownerid FCDNS_HFI_INIT =
258           {"Owner Id", "fcdns.rply.ownerid", FT_STRING, BASE_NONE, NULL, 0x0, NULL,
259            HFILL};
260
261 static header_field_info hfi_fcdns_maxres_size FCDNS_HFI_INIT =
262           {"Maximum/Residual Size", "fcdns.maxres_size", FT_UINT16, BASE_DEC,
263            NULL, 0x0, NULL, HFILL};
264
265 static header_field_info hfi_fcdns_reply_cos FCDNS_HFI_INIT =
266           {"Class of Service Supported", "fcdns.reply.cos", FT_UINT32, BASE_HEX,
267            NULL, 0x0, NULL, HFILL};
268
269 static header_field_info hfi_fcdns_cos_f FCDNS_HFI_INIT =
270           {"F", "fcdns.cos.f", FT_BOOLEAN, 32,
271            TFS(&tfs_set_notset), 0x01, NULL, HFILL};
272
273 static header_field_info hfi_fcdns_cos_1 FCDNS_HFI_INIT =
274           {"1", "fcdns.cos.1", FT_BOOLEAN, 32,
275            TFS(&tfs_set_notset), 0x02, NULL, HFILL};
276
277 static header_field_info hfi_fcdns_cos_2 FCDNS_HFI_INIT =
278           {"2", "fcdns.cos.2", FT_BOOLEAN, 32,
279            TFS(&tfs_set_notset), 0x04, NULL, HFILL};
280
281 static header_field_info hfi_fcdns_cos_3 FCDNS_HFI_INIT =
282           {"3", "fcdns.cos.3", FT_BOOLEAN, 32,
283            TFS(&tfs_set_notset), 0x08, NULL, HFILL};
284
285 static header_field_info hfi_fcdns_cos_4 FCDNS_HFI_INIT =
286           {"4", "fcdns.cos.4", FT_BOOLEAN, 32,
287            TFS(&tfs_set_notset), 0x10, NULL, HFILL};
288
289 static header_field_info hfi_fcdns_cos_6 FCDNS_HFI_INIT =
290           {"6", "fcdns.cos.6", FT_BOOLEAN, 32,
291            TFS(&tfs_set_notset), 0x40, NULL, HFILL};
292
293 static header_field_info hfi_fcdns_fc4type_llcsnap FCDNS_HFI_INIT =
294           {"LLC/SNAP", "fcdns.fc4types.llc_snap", FT_BOOLEAN, 32,
295            TFS(&tfs_set_notset), 0x0010, NULL, HFILL};
296
297 static header_field_info hfi_fcdns_fc4type_ip FCDNS_HFI_INIT =
298           {"IP", "fcdns.fc4types.ip", FT_BOOLEAN, 32,
299            TFS(&tfs_set_notset), 0x0020, NULL, HFILL};
300
301 static header_field_info hfi_fcdns_fc4type_fcp FCDNS_HFI_INIT =
302           {"FCP", "fcdns.fc4types.fcp", FT_BOOLEAN, 32,
303            TFS(&tfs_set_notset), 0x0100, NULL, HFILL};
304
305 static header_field_info hfi_fcdns_fc4type_swils FCDNS_HFI_INIT =
306           {"SW_ILS", "fcdns.fc4types.swils", FT_BOOLEAN, 32,
307            TFS(&tfs_set_notset), 0x0010, NULL, HFILL};
308
309 static header_field_info hfi_fcdns_fc4type_snmp FCDNS_HFI_INIT =
310           {"SNMP", "fcdns.fc4types.snmp", FT_BOOLEAN, 32,
311            TFS(&tfs_set_notset), 0x0004, NULL, HFILL};
312
313 static header_field_info hfi_fcdns_fc4type_gs3 FCDNS_HFI_INIT =
314           {"GS3", "fcdns.fc4types.gs3", FT_BOOLEAN, 32,
315            TFS(&tfs_set_notset), 0x0001, NULL, HFILL};
316
317 static header_field_info hfi_fcdns_fc4type_vi FCDNS_HFI_INIT =
318           {"VI", "fcdns.fc4types.vi", FT_BOOLEAN, 32,
319            TFS(&tfs_set_notset), 0x0001, NULL, HFILL};
320
321 static header_field_info hfi_fcdns_fc4features FCDNS_HFI_INIT =
322           {"FC-4 Feature Bits", "fcdns.fc4features", FT_UINT8,
323            BASE_HEX, NULL, 0x0, NULL, HFILL};
324
325 static header_field_info hfi_fcdns_fc4features_i FCDNS_HFI_INIT =
326           {"I", "fcdns.fc4features.i", FT_BOOLEAN, 8,
327            TFS(&tfs_set_notset), 0x02, NULL, HFILL};
328
329 static header_field_info hfi_fcdns_fc4features_t FCDNS_HFI_INIT =
330           {"T", "fcdns.fc4features.t", FT_BOOLEAN, 8,
331            TFS(&tfs_set_notset), 0x01, NULL, HFILL};
332
333 static header_field_info hfi_fcdns_req_fc4type FCDNS_HFI_INIT =
334           {"FC-4 Type", "fcdns.req.fc4type", FT_UINT8, BASE_HEX,
335            VALS (fc_fc4_val), 0x0, NULL, HFILL};
336
337
338 /* Initialize the subtree pointers */
339 static gint ett_fcdns = -1;
340 static gint ett_cos_flags = -1;
341 static gint ett_fc4flags = -1;
342 static gint ett_fc4features = -1;
343
344 static expert_field ei_fcdns_no_record_of_exchange = EI_INIT;
345 static expert_field ei_fcdns_zone_mbrid = EI_INIT;
346
347 typedef struct _fcdns_conv_key {
348     guint32 conv_idx;
349 } fcdns_conv_key_t;
350
351 typedef struct _fcdns_conv_data {
352     guint32 opcode;
353 } fcdns_conv_data_t;
354
355 static GHashTable *fcdns_req_hash = NULL;
356
357 /*
358  * Hash Functions
359  */
360 static gint
361 fcdns_equal(gconstpointer v, gconstpointer w)
362 {
363   const fcdns_conv_key_t *v1 = (const fcdns_conv_key_t *)v;
364   const fcdns_conv_key_t *v2 = (const fcdns_conv_key_t *)w;
365
366   return (v1->conv_idx == v2->conv_idx);
367 }
368
369 static guint
370 fcdns_hash (gconstpointer v)
371 {
372     const fcdns_conv_key_t *key = (const fcdns_conv_key_t *)v;
373     guint val;
374
375     val = key->conv_idx;
376
377     return val;
378 }
379
380 /*
381  * Protocol initialization
382  */
383 static void
384 fcdns_init_protocol(void)
385 {
386     if (fcdns_req_hash)
387         g_hash_table_destroy(fcdns_req_hash);
388
389     fcdns_req_hash = g_hash_table_new(fcdns_hash, fcdns_equal);
390 }
391
392
393 static void
394 dissect_cos_flags (proto_tree *parent_tree, tvbuff_t *tvb, int offset, const header_field_info *hfinfo)
395 {
396     static const int * flags[] = {
397         &hfi_fcdns_cos_f.id,
398         &hfi_fcdns_cos_1.id,
399         &hfi_fcdns_cos_2.id,
400         &hfi_fcdns_cos_3.id,
401         &hfi_fcdns_cos_4.id,
402         &hfi_fcdns_cos_6.id,
403         NULL
404     };
405
406     proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hfinfo->id,
407                                 ett_cos_flags, flags, ENC_BIG_ENDIAN, BMT_NO_FALSE|BMT_NO_TFS);
408 }
409
410
411
412 /* The feature routines just decode FCP's FC-4 features field
413  * based on the flahs in offset and the type in offset+1
414  */
415 static void
416 dissect_fc4features_and_type (proto_tree *parent_tree, tvbuff_t *tvb, int offset)
417 {
418     guint8 type;
419     static const int * flags[] = {
420         &hfi_fcdns_fc4features_i.id,
421         &hfi_fcdns_fc4features_t.id,
422         NULL
423     };
424
425     type = tvb_get_guint8(tvb, offset+1);
426
427     if(type==FC_TYPE_SCSI){
428         proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hfi_fcdns_fc4features.id,
429                                 ett_fc4features, flags, ENC_NA, BMT_NO_FALSE|BMT_NO_TFS);
430     } else {
431         proto_tree_add_item(parent_tree, &hfi_fcdns_fc4features, tvb, offset, 1, ENC_NA);
432     }
433
434     proto_tree_add_item (parent_tree, &hfi_fcdns_req_fc4type, tvb, offset+1, 1, ENC_BIG_ENDIAN);
435 }
436
437 /* The feature routines just decode FCP's FC-4 features field
438  */
439 static void
440 dissect_fc4features (proto_tree *parent_tree, tvbuff_t *tvb, int offset)
441 {
442     static const int * flags[] = {
443         &hfi_fcdns_fc4features_i.id,
444         &hfi_fcdns_fc4features_t.id,
445         NULL
446     };
447
448     proto_tree_add_bitmask(parent_tree, tvb, offset, hfi_fcdns_fc4features_i.id,
449                            ett_fc4features, flags, ENC_NA);
450 }
451
452
453
454 /* Decodes LLC/SNAP, IP, FCP, VI, GS, SW_ILS types only */
455 static void
456 dissect_fc4type (proto_tree *parent_tree, tvbuff_t *tvb, int offset, header_field_info *hfinfo)
457 {
458     proto_item *item;
459     proto_tree *tree;
460     guint32 flags;
461
462     item=proto_tree_add_item(parent_tree, hfinfo, tvb, offset,
463                                 32, ENC_NA);
464     tree=proto_item_add_subtree(item, ett_fc4flags);
465
466     flags = tvb_get_ntohl (tvb, offset);
467
468     proto_tree_add_boolean(tree, &hfi_fcdns_fc4type_fcp, tvb, offset, 4, flags);
469     if (flags&0x0100){
470         proto_item_append_text(item, "  FCP");
471     }
472     flags&=(~( 0x0100 ));
473
474     proto_tree_add_boolean(tree, &hfi_fcdns_fc4type_ip, tvb, offset, 4, flags);
475     if (flags&0x0020){
476         proto_item_append_text(item, "  IP");
477     }
478     flags&=(~( 0x0020 ));
479
480     proto_tree_add_boolean(tree, &hfi_fcdns_fc4type_llcsnap, tvb, offset, 4, flags);
481     if (flags&0x0010){
482         proto_item_append_text(item, "  LLC/SNAP");
483     }
484     /*flags&=(~( 0x0010 ));*/
485
486
487     flags = tvb_get_ntohl (tvb, offset+4);
488
489     proto_tree_add_boolean(tree, &hfi_fcdns_fc4type_swils, tvb, offset+4, 4, flags);
490     if (flags&0x0010){
491         proto_item_append_text(item, "  SW_ILS");
492     }
493     flags&=(~( 0x0010 ));
494
495     proto_tree_add_boolean(tree, &hfi_fcdns_fc4type_snmp, tvb, offset+4, 4, flags);
496     if (flags&0x0004){
497         proto_item_append_text(item, "  SNMP");
498     }
499     flags&=(~( 0x0004 ));
500
501     proto_tree_add_boolean(tree, &hfi_fcdns_fc4type_gs3, tvb, offset+4, 4, flags);
502     if (flags&0x0001){
503         proto_item_append_text(item, "  GS3");
504     }
505     /*flags&=(~( 0x0001 ));*/
506
507
508     flags = tvb_get_ntohl (tvb, offset+8);
509
510     proto_tree_add_boolean(tree, &hfi_fcdns_fc4type_vi, tvb, offset+8, 4, flags);
511     if (flags&0x0001){
512         proto_item_append_text(item, "  VI");
513     }
514     /*flags&=(~( 0x0001 ));*/
515 }
516
517 /* Code to actually dissect the packets */
518
519 /* A bunch of get routines have a similar req packet format. The first few
520  * routines deal with this decoding. All assume that tree is valid */
521 static void
522 dissect_fcdns_req_portid (tvbuff_t *tvb, proto_tree *tree, int offset)
523 {
524     proto_tree_add_item (tree, &hfi_fcdns_req_portid, tvb, offset, 3, ENC_NA);
525 }
526
527 static void
528 dissect_fcdns_ganxt (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
529 {
530     int offset = 16;            /* past the fc_ct header */
531     guint8 len;
532
533     if (req_tree) {
534         if (isreq) {
535             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
536         }
537         else {
538             proto_tree_add_item (req_tree, &hfi_fcdns_rply_ptype, tvb, offset,
539                                  1, ENC_BIG_ENDIAN);
540             proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid, tvb,
541                                    offset+1, 3, ENC_NA);
542             proto_tree_add_item (req_tree, &hfi_fcdns_rply_pname, tvb,
543                                    offset+4, 8, ENC_NA);
544             len = tvb_get_guint8 (tvb, offset+12);
545             proto_tree_add_item (req_tree, &hfi_fcdns_rply_spnamelen, tvb,
546                                  offset+12, 1, ENC_BIG_ENDIAN);
547             if (!tvb_offset_exists (tvb, 29+len))
548                 return;
549
550             if (len) {
551                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_spname, tvb,
552                                      offset+13, len, ENC_ASCII|ENC_NA);
553             }
554
555             if (tvb_offset_exists (tvb, 292)) {
556                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_nname, tvb,
557                                        offset+268, 8, ENC_NA);
558             }
559             if (tvb_offset_exists (tvb, 548)) {
560                 len = tvb_get_guint8 (tvb, offset+276);
561                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_snamelen, tvb,
562                                      offset+276, 1, ENC_BIG_ENDIAN);
563                 if (len) {
564                     proto_tree_add_item (req_tree, &hfi_fcdns_rply_sname, tvb,
565                                          offset+277, len, ENC_ASCII|ENC_NA);
566                 }
567             }
568             if (tvb_offset_exists (tvb, 556)) {
569                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_ipa, tvb,
570                                      offset+532, 8, ENC_NA);
571             }
572             if (tvb_offset_exists (tvb, 572)) {
573                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_ipnode, tvb,
574                                      offset+540, 16, ENC_NA);
575             }
576             if (tvb_offset_exists (tvb, 576)) {
577                 dissect_cos_flags(req_tree, tvb, offset+556, &hfi_fcdns_reply_cos);
578             }
579             if (tvb_offset_exists (tvb, 608)) {
580                 dissect_fc4type(req_tree, tvb, offset+560, &hfi_fcdns_rply_gft);
581             }
582             if (tvb_offset_exists (tvb, 624)) {
583                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_ipport, tvb,
584                                      offset+592, 16, ENC_NA);
585             }
586             if (tvb_offset_exists (tvb, 632)) {
587                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_fpname, tvb,
588                                        offset+608, 8, ENC_NA);
589             }
590             if (tvb_offset_exists (tvb, 635)) {
591                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_hrdaddr, tvb,
592                                        offset+617, 3, ENC_NA);
593             }
594         }
595     }
596 }
597
598 static void
599 dissect_fcdns_gpnid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
600 {
601     int offset = 16;            /* past the fc_ct header */
602
603     if (req_tree) {
604         if (isreq) {
605             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
606         }
607         else {
608             proto_tree_add_item (req_tree, &hfi_fcdns_rply_pname, tvb, offset,
609                                    8, ENC_NA);
610         }
611     }
612 }
613
614 static void
615 dissect_fcdns_gnnid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
616 {
617     int offset = 16;            /* past the fc_ct header */
618
619     if (req_tree) {
620         if (isreq) {
621             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
622         }
623         else {
624             proto_tree_add_item (req_tree, &hfi_fcdns_rply_nname, tvb,
625                                    offset, 8, ENC_NA);
626         }
627     }
628 }
629
630 static void
631 dissect_fcdns_gcsid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
632 {
633     int offset = 16;            /* past the fc_ct header */
634
635     if (req_tree) {
636         if (isreq) {
637             dissect_fcdns_req_portid (tvb, req_tree, offset);
638         }
639         else {
640             dissect_cos_flags(req_tree, tvb, offset, &hfi_fcdns_reply_cos);
641         }
642     }
643 }
644
645 static void
646 dissect_fcdns_gftid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
647 {
648     int offset = 16;            /* past the fc_ct header */
649
650     if (req_tree) {
651         if (isreq) {
652             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
653         }
654         else {
655             dissect_fc4type(req_tree, tvb, offset, &hfi_fcdns_rply_gft);
656         }
657     }
658 }
659
660 static void
661 dissect_fcdns_gspnid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
662 {
663     int offset = 16;            /* past the fc_ct header */
664     guint8 len;
665
666     if (req_tree) {
667         if (isreq) {
668             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
669         }
670         else {
671             len = tvb_get_guint8 (tvb, offset);
672             proto_tree_add_item (req_tree, &hfi_fcdns_rply_spnamelen,
673                                  tvb, offset, 1, ENC_BIG_ENDIAN);
674             proto_tree_add_item (req_tree, &hfi_fcdns_rply_spname, tvb,
675                                  offset+1, len, ENC_ASCII|ENC_NA);
676         }
677     }
678 }
679
680 static void
681 dissect_fcdns_gptid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
682 {
683     int offset = 16;            /* past the fc_ct header */
684
685     if (req_tree) {
686         if (isreq) {
687             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
688         }
689         else {
690             proto_tree_add_item (req_tree, &hfi_fcdns_rply_ptype, tvb,
691                                  offset, 1, ENC_BIG_ENDIAN);
692         }
693     }
694 }
695
696 static void
697 dissect_fcdns_gfpnid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
698 {
699     int offset = 16;            /* past the fc_ct header */
700
701     if (req_tree) {
702         if (isreq) {
703             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
704         }
705         else {
706             proto_tree_add_item (req_tree, &hfi_fcdns_rply_fpname, tvb,
707                                    offset, 8, ENC_NA);
708         }
709     }
710
711 }
712
713 static void
714 dissect_fcdns_gfdid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
715 {
716     int offset = 16;            /* past the fc_ct header */
717     int tot_len, desclen;
718
719     if (req_tree) {
720         if (isreq) {
721             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
722             dissect_fc4type(req_tree, tvb, offset+4, &hfi_fcdns_fc4type);
723         }
724         else {
725             tot_len = tvb_reported_length_remaining (tvb, offset); /* excluding CT header */
726             while (tot_len > 0) {
727                 /* The count of the descriptors is not returned and so we have
728                  * to track the display by the length field */
729                 desclen = tvb_get_guint8 (tvb, offset);
730                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_fc4desc, tvb,
731                                      offset, desclen, ENC_NA);
732                 tot_len -= 255; /* descriptors are aligned to 255 bytes */
733                 offset += 256;
734             }
735         }
736     }
737 }
738
739 static void
740 dissect_fcdns_gffid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
741 {
742     int offset = 16;            /* past the fc_ct header */
743
744     if (req_tree) {
745         if (isreq) {
746             dissect_fcdns_req_portid (tvb, req_tree, offset+1);
747         }
748         else {
749             dissect_fc4features(req_tree, tvb, offset);
750         }
751     }
752 }
753
754 static void
755 dissect_fcdns_gidpn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
756 {
757     int offset = 16;            /* past the fc_ct header */
758
759     if (req_tree) {
760         if (isreq) {
761             proto_tree_add_item (req_tree, &hfi_fcdns_req_pname, tvb,
762                                    offset, 8, ENC_NA);
763         }
764         else {
765             proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid, tvb,
766                                    offset+1, 3, ENC_NA);
767         }
768     }
769 }
770
771 static void
772 dissect_fcdns_gipppn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
773 {
774     int offset = 16;            /* past the fc_ct header */
775
776     if (req_tree) {
777         if (isreq) {
778             proto_tree_add_item (req_tree, &hfi_fcdns_req_pname, tvb,
779                                    offset, 8, ENC_NA);
780         }
781         else {
782             proto_tree_add_item (req_tree, &hfi_fcdns_rply_ipport, tvb, offset,
783                                  16, ENC_NA);
784         }
785     }
786 }
787
788 static void
789 dissect_fcdns_gidnn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
790 {
791     int offset = 16;            /* past the fc_ct header */
792     guint8 islast;
793
794     if (req_tree) {
795         if (isreq) {
796             proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb,
797                                    offset, 8, ENC_NA);
798         }
799         else {
800             do {
801                 islast = tvb_get_guint8 (tvb, offset);
802                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
803                                        tvb, offset+1, 3, ENC_NA);
804                 offset += 4;
805             } while (!(islast & 0x80));
806         }
807     }
808 }
809
810 static void
811 dissect_fcdns_gipnn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
812 {
813     int offset = 16;            /* past the fc_ct header */
814
815     if (req_tree) {
816         if (isreq) {
817             proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb,
818                                    offset, 8, ENC_NA);
819         }
820         else {
821             proto_tree_add_item (req_tree, &hfi_fcdns_rply_ipnode, tvb, offset,
822                                  16, ENC_NA);
823         }
824     }
825 }
826
827 static void
828 dissect_fcdns_gpnnn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
829 {
830     int offset = 16;            /* past the fc_ct header */
831     guint8 islast;
832
833     if (req_tree) {
834         if (isreq) {
835             proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb,
836                                    offset, 8, ENC_NA);
837         }
838         else {
839             do {
840                 islast = tvb_get_guint8 (tvb, offset);
841                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
842                                        tvb, offset+1, 3, ENC_NA);
843                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_pname,
844                                        tvb, offset+8, 8, ENC_NA);
845                 offset += 16;
846             } while (!(islast & 0x80));
847         }
848     }
849 }
850
851 static void
852 dissect_fcdns_gsnnnn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
853 {
854     int offset = 16;            /* past the fc_ct header */
855     guint8 len;
856
857     if (req_tree) {
858         if (isreq) {
859             proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb,
860                                    offset, 8, ENC_NA);
861         }
862         else {
863             len = tvb_get_guint8 (tvb, offset);
864             proto_tree_add_item (req_tree, &hfi_fcdns_rply_snamelen, tvb,
865                                  offset, 1, ENC_BIG_ENDIAN);
866             proto_tree_add_item (req_tree, &hfi_fcdns_rply_sname, tvb,
867                                  offset+1, len, ENC_ASCII|ENC_NA);
868         }
869     }
870 }
871
872 static void
873 dissect_fcdns_gidft (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
874 {
875     int offset = 16;            /* past the fc_ct header */
876     guint8 islast;
877
878     if (req_tree) {
879         if (isreq) {
880             proto_tree_add_item (req_tree, &hfi_fcdns_req_domainscope,
881                                  tvb, offset+1, 1, ENC_BIG_ENDIAN);
882             proto_tree_add_item (req_tree, &hfi_fcdns_req_areascope,
883                                  tvb, offset+2, 1, ENC_BIG_ENDIAN);
884             proto_tree_add_item (req_tree, &hfi_fcdns_req_fc4type,
885                                  tvb, offset+3, 1, ENC_BIG_ENDIAN);
886         }
887         else {
888             do {
889                 islast = tvb_get_guint8 (tvb, offset);
890                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
891                                        tvb, offset+1, 3, ENC_NA);
892                 offset += 4;
893             } while (!(islast & 0x80));
894         }
895     }
896 }
897
898 static void
899 dissect_fcdns_gpnft (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
900 {
901     int offset = 16;            /* past the fc_ct header */
902     guint8 islast;
903
904     if (req_tree) {
905         if (isreq) {
906             proto_tree_add_item (req_tree, &hfi_fcdns_req_domainscope,
907                                  tvb, offset+1, 1, ENC_BIG_ENDIAN);
908             proto_tree_add_item (req_tree, &hfi_fcdns_req_areascope,
909                                  tvb, offset+2, 1, ENC_BIG_ENDIAN);
910             proto_tree_add_item (req_tree, &hfi_fcdns_req_fc4type,
911                                  tvb, offset+3, 1, ENC_BIG_ENDIAN);
912         }
913         else {
914             do {
915                 islast = tvb_get_guint8 (tvb, offset);
916                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
917                                        tvb, offset+1, 3, ENC_NA);
918                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_pname,
919                                        tvb, offset+4, 8, ENC_NA);
920                 offset += 16;
921             } while (!(islast & 0x80));
922         }
923     }
924 }
925
926 static void
927 dissect_fcdns_gnnft (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
928 {
929     int offset = 16;            /* past the fc_ct header */
930     guint8 islast;
931
932     if (req_tree) {
933         if (isreq) {
934             proto_tree_add_item (req_tree, &hfi_fcdns_req_domainscope,
935                                  tvb, offset+1, 1, ENC_BIG_ENDIAN);
936             proto_tree_add_item (req_tree, &hfi_fcdns_req_areascope,
937                                  tvb, offset+2, 1, ENC_BIG_ENDIAN);
938             proto_tree_add_item (req_tree, &hfi_fcdns_req_fc4type,
939                                  tvb, offset+3, 1, ENC_BIG_ENDIAN);
940         }
941         else {
942             do {
943                 islast = tvb_get_guint8 (tvb, offset);
944                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
945                                        tvb, offset+1, 3, ENC_NA);
946                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_nname,
947                                        tvb, offset+4, 8, ENC_NA);
948                 offset += 16;
949             } while (!(islast & 0x80));
950         }
951     }
952 }
953
954 static void
955 dissect_fcdns_gidpt (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
956 {
957     int offset = 16;            /* past the fc_ct header */
958     guint8 islast = 0;
959
960     if (req_tree) {
961         if (isreq) {
962             proto_tree_add_item (req_tree, &hfi_fcdns_req_ptype,
963                                  tvb, offset, 1, ENC_BIG_ENDIAN);
964             proto_tree_add_item (req_tree, &hfi_fcdns_req_domainscope,
965                                  tvb, offset+1, 1, ENC_BIG_ENDIAN);
966             proto_tree_add_item (req_tree, &hfi_fcdns_req_areascope,
967                                  tvb, offset+2, 1, ENC_BIG_ENDIAN);
968         }
969         else {
970             do {
971                 islast = tvb_get_guint8 (tvb, offset);
972                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
973                                        tvb, offset+1, 3, ENC_NA);
974                 offset += 4;
975             } while (!(islast & 0x80));
976         }
977     }
978 }
979
980 static void
981 dissect_fcdns_gidipp (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
982 {
983     int offset = 16;            /* past the fc_ct header */
984     guint8 islast;
985
986     if (req_tree) {
987         if (isreq) {
988             proto_tree_add_item (req_tree, &hfi_fcdns_req_ip, tvb, offset,
989                                  16, ENC_NA);
990         }
991         else {
992             do {
993                 islast = tvb_get_guint8 (tvb, offset);
994                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
995                                        tvb, offset+1, 3, ENC_NA);
996                 offset += 4;
997             } while (!(islast & 0x80));
998         }
999     }
1000 }
1001
1002 static void
1003 dissect_fcdns_gidff (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1004 {
1005     int offset = 16;            /* past the fc_ct header */
1006     guint8 islast;
1007
1008     if (req_tree) {
1009         if (isreq) {
1010             proto_tree_add_item (req_tree, &hfi_fcdns_req_domainscope, tvb,
1011                                  offset+1, 1, ENC_BIG_ENDIAN);
1012             proto_tree_add_item (req_tree, &hfi_fcdns_req_areascope, tvb,
1013                                  offset+2, 1, ENC_BIG_ENDIAN);
1014             dissect_fc4features_and_type(req_tree, tvb, offset+6);
1015         }
1016         else {
1017             do {
1018                 islast = tvb_get_guint8 (tvb, offset);
1019                 proto_tree_add_item (req_tree, &hfi_fcdns_rply_portid,
1020                                        tvb, offset+1, 3, ENC_NA);
1021                 offset += 4;
1022             } while (!(islast & 0x80));
1023         }
1024     }
1025 }
1026
1027 static void
1028 dissect_fcdns_rpnid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1029 {
1030     int offset = 16;            /* past the fc_ct header */
1031
1032     if (req_tree) {
1033         if (isreq) {
1034             proto_tree_add_item (req_tree, &hfi_fcdns_req_portid,
1035                                    tvb, offset+1, 3, ENC_NA);
1036             proto_tree_add_item (req_tree, &hfi_fcdns_req_pname, tvb,
1037                                    offset+4, 8, ENC_NA);
1038         }
1039     }
1040 }
1041
1042 static void
1043 dissect_fcdns_rnnid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1044 {
1045     int offset = 16;            /* past the fc_ct header */
1046
1047     if (req_tree) {
1048         if (isreq) {
1049             proto_tree_add_item (req_tree, &hfi_fcdns_req_portid,
1050                                    tvb, offset+1, 3, ENC_NA);
1051             proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb,
1052                                    offset+4, 8, ENC_NA);
1053         }
1054     }
1055 }
1056
1057 static void
1058 dissect_fcdns_rcsid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1059 {
1060     int offset = 16;            /* past the fc_ct header */
1061
1062     if (req_tree && isreq) {
1063         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb,
1064                                offset+1, 3, ENC_NA);
1065         dissect_cos_flags(req_tree, tvb, offset+4, &hfi_fcdns_req_cos);
1066     }
1067 }
1068
1069 static void
1070 dissect_fcdns_rptid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1071 {
1072     int offset = 16;            /* past the fc_ct header */
1073
1074     if (isreq) {
1075         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb,
1076                                offset+1, 3, ENC_NA);
1077         proto_tree_add_item (req_tree, &hfi_fcdns_req_ptype, tvb,
1078                              offset+4, 1, ENC_BIG_ENDIAN);
1079     }
1080 }
1081
1082 static void
1083 dissect_fcdns_rftid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1084 {
1085     int offset = 16;            /* past the fc_ct header */
1086
1087     if (isreq) {
1088         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb,
1089                                offset+1, 3, ENC_NA);
1090         dissect_fc4type(req_tree, tvb, offset+4, &hfi_fcdns_req_fc4types);
1091     }
1092 }
1093
1094 static void
1095 dissect_fcdns_rspnid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1096 {
1097     int offset = 16;            /* past the fc_ct header */
1098     guint8 len;
1099
1100     if (req_tree && isreq) {
1101         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb,
1102                                offset+1, 3, ENC_NA);
1103         proto_tree_add_item (req_tree, &hfi_fcdns_req_spnamelen, tvb,
1104                              offset+4, 1, ENC_BIG_ENDIAN);
1105         len = tvb_get_guint8 (tvb, offset+4);
1106
1107         proto_tree_add_item (req_tree, &hfi_fcdns_req_spname, tvb, offset+5,
1108                              len, ENC_ASCII|ENC_NA);
1109     }
1110 }
1111
1112 static void
1113 dissect_fcdns_rippid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1114 {
1115     int offset = 16;            /* past the fc_ct header */
1116
1117     if (isreq) {
1118         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb,
1119                                offset+1, 3, ENC_NA);
1120         proto_tree_add_item (req_tree, &hfi_fcdns_req_ip, tvb,
1121                              offset+4, 16, ENC_NA);
1122     }
1123 }
1124
1125 static void
1126 dissect_fcdns_rfdid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1127 {
1128     int offset = 16;            /* past the fc_ct header */
1129     int len;
1130
1131     if (isreq) {
1132         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb,
1133                                offset+1, 3, ENC_NA);
1134         dissect_fc4type(req_tree, tvb, offset+4, &hfi_fcdns_req_fc4types);
1135
1136         offset += 36;
1137         len = tvb_reported_length_remaining (tvb, offset);
1138
1139         while (len > 0) {
1140             proto_tree_add_item (req_tree, &hfi_fcdns_req_fdesclen, tvb, offset,
1141                                  1, ENC_BIG_ENDIAN);
1142             proto_tree_add_item (req_tree, &hfi_fcdns_req_fdesc, tvb, offset+1,
1143                                  len, ENC_ASCII|ENC_NA);
1144             offset += 256;
1145             len -= 256;
1146         }
1147     }
1148 }
1149
1150 static void
1151 dissect_fcdns_rffid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1152 {
1153     int offset = 16;            /* past the fc_ct header */
1154
1155     if (isreq) {
1156         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb, offset+1, 3, ENC_NA);
1157         dissect_fc4features_and_type(req_tree, tvb, offset+6);
1158     }
1159 }
1160
1161 static void
1162 dissect_fcdns_ripnn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1163 {
1164     int offset = 16;            /* past the fc_ct header */
1165
1166     if (isreq) {
1167         proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb, offset, 8, ENC_NA);
1168         proto_tree_add_item (req_tree, &hfi_fcdns_req_ip, tvb, offset+8, 16, ENC_NA);
1169     }
1170 }
1171
1172 static void
1173 dissect_fcdns_rsnnnn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1174 {
1175     int offset = 16;            /* past the fc_ct header */
1176     guint8 len;
1177
1178     if (isreq) {
1179         proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb, offset, 8, ENC_NA);
1180         len = tvb_get_guint8 (tvb, offset+8);
1181
1182         proto_tree_add_item (req_tree, &hfi_fcdns_req_snamelen, tvb, offset+8,
1183                              1, ENC_BIG_ENDIAN);
1184         proto_tree_add_item (req_tree, &hfi_fcdns_req_sname, tvb, offset+9,
1185                              len, ENC_ASCII|ENC_NA);
1186     }
1187 }
1188
1189 static void
1190 dissect_fcdns_daid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1191 {
1192     int offset = 16;            /* past the fc_ct header */
1193
1194     if (isreq) {
1195         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb, offset+1, 3, ENC_NA);
1196     }
1197 }
1198
1199 static guint8 *
1200 zonenm_to_str (tvbuff_t *tvb, gint offset)
1201 {
1202     int len = tvb_get_guint8 (tvb, offset);
1203     return tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, len, ENC_ASCII);
1204 }
1205
1206 static void
1207 dissect_fcdns_zone_mbr (tvbuff_t *tvb, packet_info* pinfo, proto_tree *zmbr_tree, int offset)
1208 {
1209     guint8 mbrtype;
1210     int idlen;
1211     proto_item* ti;
1212
1213     mbrtype = tvb_get_guint8 (tvb, offset);
1214     ti = proto_tree_add_uint (zmbr_tree, &hfi_fcdns_zone_mbrtype, tvb,
1215                          offset, 1, mbrtype);
1216     proto_tree_add_item(zmbr_tree, &hfi_fcdns_zone_flags, tvb, offset+2, 1, ENC_NA);
1217     idlen = tvb_get_guint8 (tvb, offset+3);
1218     proto_tree_add_item(zmbr_tree, &hfi_fcdns_id_length, tvb, offset+3, 1, ENC_NA);
1219     switch (mbrtype) {
1220     case FC_SWILS_ZONEMBR_WWN:
1221         proto_tree_add_item (zmbr_tree, &hfi_fcdns_zone_mbrid_wwn, tvb,
1222                                offset+4, 8, ENC_NA);
1223         break;
1224     case FC_SWILS_ZONEMBR_DP:
1225         proto_tree_add_item (zmbr_tree, &hfi_fcdns_zone_mbrid_uint, tvb,
1226                                offset+4, 4, ENC_BIG_ENDIAN);
1227         break;
1228     case FC_SWILS_ZONEMBR_FCID:
1229         proto_tree_add_item (zmbr_tree, &hfi_fcdns_zone_mbrid_fc, tvb,
1230                                offset+4, 3, ENC_NA);
1231         break;
1232     case FC_SWILS_ZONEMBR_ALIAS:
1233         proto_tree_add_string (zmbr_tree, &hfi_fcdns_zone_mbrid, tvb,
1234                                offset+4, idlen, zonenm_to_str (tvb, offset+4));
1235         break;
1236     default:
1237         expert_add_info(pinfo, ti, &ei_fcdns_zone_mbrid);
1238
1239     }
1240 }
1241
1242 static void
1243 dissect_fcdns_swils_entries (tvbuff_t *tvb, proto_tree *tree, int offset)
1244 {
1245     int numrec, i, len;
1246     guint8 objfmt;
1247
1248     if (tree) {
1249         numrec = tvb_get_ntohl (tvb, offset);
1250         proto_tree_add_uint(tree, &hfi_fcdns_num_entries, tvb, offset, 4, numrec);
1251         offset += 4;
1252
1253         for (i = 0; i < numrec; i++) {
1254             objfmt = tvb_get_guint8 (tvb, offset);
1255
1256             proto_tree_add_item (tree, &hfi_fcdns_sw2_objfmt, tvb, offset, 1, ENC_BIG_ENDIAN);
1257             proto_tree_add_item (tree, &hfi_fcdns_rply_ownerid, tvb, offset+1, 3, ENC_NA);
1258             proto_tree_add_item (tree, &hfi_fcdns_rply_ptype, tvb, offset+4,
1259                                  1, ENC_BIG_ENDIAN);
1260             proto_tree_add_item (tree, &hfi_fcdns_rply_portid, tvb, offset+5, 3, ENC_NA);
1261             proto_tree_add_item (tree, &hfi_fcdns_rply_pname, tvb, offset+8, 8, ENC_NA);
1262             offset += 16;
1263             if (!(objfmt & 0x1)) {
1264                 len = tvb_get_guint8 (tvb, offset);
1265                 proto_tree_add_item (tree, &hfi_fcdns_rply_spnamelen, tvb,
1266                                      offset, 1, ENC_BIG_ENDIAN);
1267                 proto_tree_add_item (tree, &hfi_fcdns_rply_spname, tvb,
1268                                      offset+1, len, ENC_ASCII|ENC_NA);
1269                 offset += 256;
1270             }
1271             proto_tree_add_item (tree, &hfi_fcdns_rply_nname, tvb, offset, 8, ENC_NA);
1272             offset += 8;
1273             if (!(objfmt & 0x1)) {
1274                 len = tvb_get_guint8 (tvb, offset);
1275                 proto_tree_add_item (tree, &hfi_fcdns_rply_snamelen, tvb,
1276                                      offset, 1, ENC_BIG_ENDIAN);
1277                 proto_tree_add_item (tree, &hfi_fcdns_rply_sname, tvb,
1278                                      offset+1, len, ENC_ASCII|ENC_NA);
1279                 offset += 256;
1280             }
1281             proto_tree_add_item (tree, &hfi_fcdns_rply_ipa, tvb, offset, 8, ENC_NA);
1282             proto_tree_add_item (tree, &hfi_fcdns_rply_ipnode, tvb, offset+8, 16,
1283                                  ENC_NA);
1284             dissect_cos_flags(tree, tvb, offset+24, &hfi_fcdns_reply_cos);
1285             dissect_fc4type(tree, tvb, offset+28, &hfi_fcdns_rply_gft);
1286             proto_tree_add_item (tree, &hfi_fcdns_rply_ipport, tvb, offset+60,
1287                                  16, ENC_NA);
1288             proto_tree_add_item (tree, &hfi_fcdns_rply_fpname, tvb, offset+76,
1289                                    8, ENC_NA);
1290             proto_tree_add_item (tree, &hfi_fcdns_rply_hrdaddr, tvb, offset+85,
1291                                    3, ENC_NA);
1292             offset += 88;
1293             if (objfmt & 0x2) {
1294                 dissect_fc4features(tree, tvb, offset);
1295                 if (tvb_get_guint8 (tvb, offset+129)) {
1296                     proto_tree_add_item (tree, &hfi_fcdns_rply_fc4type, tvb,
1297                                          offset+128, 1, ENC_BIG_ENDIAN);
1298                     proto_tree_add_item (tree, &hfi_fcdns_num_fc4desc, tvb,
1299                                          offset+129, 1, ENC_BIG_ENDIAN);
1300                     len = tvb_get_guint8 (tvb, offset+132);
1301                     proto_tree_add_item (tree, &hfi_fcdns_rply_fc4desclen, tvb,
1302                                          offset+132, 1, ENC_BIG_ENDIAN);
1303                     proto_tree_add_item (tree, &hfi_fcdns_rply_fc4desc, tvb,
1304                                          offset+133, len, ENC_NA);
1305                 }
1306                 else {
1307                     proto_tree_add_item (tree, &hfi_fcdns_num_fc4desc, tvb,
1308                                          offset+129, 1, ENC_BIG_ENDIAN);
1309                 }
1310                 offset += 388;  /* FC4 desc is 260 bytes, maybe padded */
1311             }
1312         }
1313     }
1314 }
1315
1316 static void
1317 dissect_fcdns_geid (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1318 {
1319     int offset = 16;            /* past the fc_ct header */
1320
1321     if (isreq) {
1322         proto_tree_add_item (req_tree, &hfi_fcdns_req_portid, tvb, offset+1, 3, ENC_NA);
1323     }
1324     else {
1325         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1326     }
1327 }
1328
1329 static void
1330 dissect_fcdns_gepn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1331 {
1332     int offset = 16;            /* past the fc_ct header */
1333     if (isreq) {
1334         proto_tree_add_item(req_tree, &hfi_fcdns_req_pname, tvb, offset, 8, ENC_NA);
1335     }
1336     else {
1337         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1338     }
1339 }
1340
1341 static void
1342 dissect_fcdns_genn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1343 {
1344     int offset = 16;            /* past the fc_ct header */
1345
1346     if (isreq) {
1347         proto_tree_add_item (req_tree, &hfi_fcdns_req_nname, tvb, offset, 8, ENC_NA);
1348     }
1349     else {
1350         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1351     }
1352 }
1353
1354 static void
1355 dissect_fcdns_geip (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1356 {
1357     int offset = 16;            /* past the fc_ct header */
1358
1359     if (isreq) {
1360         if (req_tree) {
1361             proto_tree_add_item (req_tree, &hfi_fcdns_req_ip, tvb, offset, 16, ENC_NA);
1362         }
1363     }
1364     else {
1365         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1366     }
1367 }
1368
1369 static void
1370 dissect_fcdns_geft (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1371 {
1372     int offset = 16;            /* past the fc_ct header */
1373
1374     if (isreq) {
1375         if (req_tree) {
1376             dissect_fc4type(req_tree, tvb, offset, &hfi_fcdns_fc4type);
1377         }
1378     }
1379     else {
1380         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1381     }
1382 }
1383
1384 static void
1385 dissect_fcdns_gept (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1386 {
1387     int offset = 16;            /* past the fc_ct header */
1388
1389     if (isreq) {
1390         if (req_tree) {
1391             proto_tree_add_item (req_tree, &hfi_fcdns_req_ptype, tvb, offset+3,
1392                                  1, ENC_BIG_ENDIAN);
1393         }
1394     }
1395     else {
1396         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1397     }
1398 }
1399
1400 static void
1401 dissect_fcdns_gezm (tvbuff_t *tvb, packet_info* pinfo, proto_tree *req_tree, gboolean isreq)
1402 {
1403     int offset = 16;            /* past the fc_ct header */
1404
1405     if (isreq) {
1406         dissect_fcdns_zone_mbr (tvb, pinfo, req_tree, offset);
1407     }
1408     else {
1409         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1410     }
1411 }
1412
1413 static void
1414 dissect_fcdns_gezn (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1415 {
1416     int offset = 16;            /* past the fc_ct header */
1417     int str_len;
1418
1419     if (isreq) {
1420         if (req_tree) {
1421             str_len = tvb_get_guint8 (tvb, offset);
1422             proto_tree_add_uint(req_tree, &hfi_fcdns_zonelen, tvb, offset, 1, str_len);
1423             proto_tree_add_item (req_tree, &hfi_fcdns_zonenm, tvb, offset+3,
1424                                  str_len, ENC_ASCII|ENC_NA);
1425         }
1426     }
1427     else {
1428         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1429     }
1430 }
1431
1432 static void
1433 dissect_fcdns_geipp (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1434 {
1435     int offset = 16;            /* past the fc_ct header */
1436
1437     if (isreq) {
1438         if (req_tree) {
1439             proto_tree_add_item (req_tree, &hfi_fcdns_portip, tvb, offset, 4, ENC_BIG_ENDIAN);
1440         }
1441     }
1442     else {
1443         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1444     }
1445 }
1446
1447 static void
1448 dissect_fcdns_geff (tvbuff_t *tvb, proto_tree *req_tree, gboolean isreq)
1449 {
1450     int offset = 16;            /* past the fc_ct header */
1451
1452     if (isreq) {
1453         if (req_tree) {
1454             dissect_fc4features(req_tree, tvb, offset);
1455         }
1456     }
1457     else {
1458         dissect_fcdns_swils_entries (tvb, req_tree, offset);
1459     }
1460 }
1461
1462 static void
1463 dissect_fcdns_rjt (tvbuff_t *tvb, proto_tree *req_tree)
1464 {
1465     int offset = 0;
1466
1467     if (req_tree) {
1468         proto_tree_add_item (req_tree, &hfi_fcdns_reason, tvb, offset+13, 1, ENC_BIG_ENDIAN);
1469         proto_tree_add_item (req_tree, &hfi_fcdns_rjtdetail, tvb, offset+14, 1,
1470                              ENC_BIG_ENDIAN);
1471         proto_tree_add_item (req_tree, &hfi_fcdns_vendor, tvb, offset+15, 1, ENC_BIG_ENDIAN);
1472     }
1473 }
1474
1475 static int
1476 dissect_fcdns (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1477 {
1478     /* Set up structures needed to add the protocol subtree and manage it */
1479     proto_item *ti = NULL;
1480     proto_tree *fcdns_tree = NULL;
1481     int offset = 0;
1482     int opcode,
1483         failed_opcode = 0;
1484     int isreq = 1;
1485     fc_ct_preamble cthdr;
1486     conversation_t *conversation;
1487     fcdns_conv_data_t *cdata;
1488     fcdns_conv_key_t ckey, *req_key;
1489     fc_hdr *fchdr;
1490
1491     /* Reject the packet if data is NULL */
1492     if (data == NULL)
1493         return 0;
1494     fchdr = (fc_hdr *)data;
1495
1496     tvb_memcpy (tvb, (guint8 *)&cthdr, offset, FCCT_PRMBL_SIZE);
1497     cthdr.revision = tvb_get_guint8 (tvb, offset);
1498     cthdr.in_id = tvb_get_ntoh24 (tvb, offset+1);
1499     cthdr.opcode = g_ntohs (cthdr.opcode);
1500     opcode = cthdr.opcode;
1501     cthdr.maxres_size = g_ntohs (cthdr.maxres_size);
1502
1503     /* Determine the type of server the request/response is for */
1504     if (cthdr.gstype == FCCT_GSTYPE_DIRSVC)
1505         col_set_str (pinfo->cinfo, COL_PROTOCOL, "dNS");
1506     else
1507         col_set_str (pinfo->cinfo, COL_PROTOCOL, "Unzoned NS");
1508
1509     if (tree) {
1510         if (cthdr.gstype == FCCT_GSTYPE_DIRSVC) {
1511             ti = proto_tree_add_protocol_format (tree, hfi_fcdns->id, tvb, 0,
1512                                                  -1,
1513                                                  "dNS");
1514             fcdns_tree = proto_item_add_subtree (ti, ett_fcdns);
1515         }
1516         else {
1517             ti = proto_tree_add_protocol_format (tree, hfi_fcdns->id, tvb, 0,
1518                                                  -1,
1519                                                  "Unzoned NS");
1520             fcdns_tree = proto_item_add_subtree (ti, ett_fcdns);
1521         }
1522     }
1523
1524     if ((opcode != FCCT_MSG_ACC) && (opcode != FCCT_MSG_RJT)) {
1525         conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
1526                                           pinfo->ptype, fchdr->oxid,
1527                                           fchdr->rxid, NO_PORT2);
1528         if (!conversation) {
1529             conversation = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst,
1530                                              pinfo->ptype, fchdr->oxid,
1531                                              fchdr->rxid, NO_PORT2);
1532         }
1533
1534         ckey.conv_idx = conversation->index;
1535
1536         cdata = (fcdns_conv_data_t *)g_hash_table_lookup (fcdns_req_hash,
1537                                                             &ckey);
1538         if (cdata) {
1539             /* Since we never free the memory used by an exchange, this maybe a
1540              * case of another request using the same exchange as a previous
1541              * req.
1542              */
1543             cdata->opcode = opcode;
1544         }
1545         else {
1546             req_key = wmem_new(wmem_file_scope(), fcdns_conv_key_t);
1547             req_key->conv_idx = conversation->index;
1548
1549             cdata = wmem_new(wmem_file_scope(), fcdns_conv_data_t);
1550             cdata->opcode = opcode;
1551
1552             g_hash_table_insert (fcdns_req_hash, req_key, cdata);
1553         }
1554         col_add_str (pinfo->cinfo, COL_INFO, val_to_str (opcode, fc_dns_opcode_val,
1555                                                           "0x%x"));
1556     }
1557     else {
1558         /* Opcode is ACC or RJT */
1559         conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
1560                                           pinfo->ptype, fchdr->oxid,
1561                                           fchdr->rxid, NO_PORT2);
1562         isreq = 0;
1563         if (!conversation) {
1564             if (opcode == FCCT_MSG_ACC) {
1565                 col_add_str (pinfo->cinfo, COL_INFO,
1566                                  val_to_str (opcode, fc_dns_opcode_val,
1567                                              "0x%x"));
1568                 /* No record of what this accept is for. Can't decode */
1569                 proto_tree_add_expert(fcdns_tree, pinfo, &ei_fcdns_no_record_of_exchange, tvb, 0, -1);
1570                 return 0;
1571             }
1572         }
1573         else {
1574             ckey.conv_idx = conversation->index;
1575
1576             cdata = (fcdns_conv_data_t *)g_hash_table_lookup (fcdns_req_hash, &ckey);
1577
1578             if (cdata != NULL) {
1579                 if (opcode == FCCT_MSG_ACC) {
1580                     opcode = cdata->opcode;
1581                 }
1582                 else
1583                     failed_opcode = cdata->opcode;
1584             }
1585
1586             if (opcode != FCCT_MSG_RJT) {
1587                 col_add_fstr (pinfo->cinfo, COL_INFO, "ACC (%s)",
1588                                 val_to_str (opcode, fc_dns_opcode_val,
1589                                             "0x%x"));
1590             }
1591             else {
1592                 col_add_fstr (pinfo->cinfo, COL_INFO, "RJT (%s)",
1593                                 val_to_str (failed_opcode,
1594                                             fc_dns_opcode_val,
1595                                             "0x%x"));
1596             }
1597
1598             if (tree) {
1599                 if ((cdata == NULL) && (opcode != FCCT_MSG_RJT)) {
1600                     /* No record of what this accept is for. Can't decode */
1601                     proto_tree_add_expert(fcdns_tree, pinfo, &ei_fcdns_no_record_of_exchange, tvb, 0, -1);
1602                     return 0;
1603                 }
1604             }
1605         }
1606     }
1607
1608      if (tree) {
1609         proto_tree_add_item (fcdns_tree, &hfi_fcdns_opcode, tvb, offset+8, 2, ENC_BIG_ENDIAN);
1610         proto_tree_add_item (fcdns_tree, &hfi_fcdns_maxres_size, tvb, offset+10,
1611                              2, ENC_BIG_ENDIAN);
1612     }
1613
1614     switch (opcode) {
1615     case FCCT_MSG_RJT:
1616         dissect_fcdns_rjt (tvb, fcdns_tree);
1617         break;
1618     case FCDNS_GA_NXT:
1619         dissect_fcdns_ganxt (tvb, fcdns_tree, isreq);
1620         break;
1621     case FCDNS_GPN_ID:
1622         dissect_fcdns_gpnid (tvb, fcdns_tree, isreq);
1623         break;
1624     case FCDNS_GNN_ID:
1625         dissect_fcdns_gnnid (tvb, fcdns_tree, isreq);
1626         break;
1627     case FCDNS_GCS_ID:
1628         dissect_fcdns_gcsid (tvb, fcdns_tree, isreq);
1629         break;
1630     case FCDNS_GFT_ID:
1631         dissect_fcdns_gftid (tvb, fcdns_tree, isreq);
1632         break;
1633     case FCDNS_GSPN_ID:
1634         dissect_fcdns_gspnid (tvb, fcdns_tree, isreq);
1635         break;
1636     case FCDNS_GPT_ID:
1637         dissect_fcdns_gptid (tvb, fcdns_tree, isreq);
1638         break;
1639     case FCDNS_GFPN_ID:
1640         dissect_fcdns_gfpnid (tvb, fcdns_tree, isreq);
1641         break;
1642     case FCDNS_GFD_ID:
1643         dissect_fcdns_gfdid (tvb, fcdns_tree, isreq);
1644         break;
1645     case FCDNS_GFF_ID:
1646         dissect_fcdns_gffid (tvb, fcdns_tree, isreq);
1647         break;
1648     case FCDNS_GID_PN:
1649         dissect_fcdns_gidpn (tvb, fcdns_tree, isreq);
1650         break;
1651     case FCDNS_GIPP_PN:
1652         dissect_fcdns_gipppn (tvb, fcdns_tree, isreq);
1653         break;
1654     case FCDNS_GID_NN:
1655         dissect_fcdns_gidnn (tvb, fcdns_tree, isreq);
1656         break;
1657     case FCDNS_GPN_NN:
1658         dissect_fcdns_gpnnn (tvb, fcdns_tree, isreq);
1659         break;
1660     case FCDNS_GIP_NN:
1661         dissect_fcdns_gipnn (tvb, fcdns_tree, isreq);
1662         break;
1663     case FCDNS_GSNN_NN:
1664         dissect_fcdns_gsnnnn (tvb, fcdns_tree, isreq);
1665         break;
1666     case FCDNS_GID_FT:
1667         dissect_fcdns_gidft (tvb, fcdns_tree, isreq);
1668         break;
1669     case FCDNS_GPN_FT:
1670         dissect_fcdns_gpnft (tvb, fcdns_tree, isreq);
1671         break;
1672     case FCDNS_GNN_FT:
1673         dissect_fcdns_gnnft (tvb, fcdns_tree, isreq);
1674         break;
1675     case FCDNS_GID_PT:
1676         dissect_fcdns_gidpt (tvb, fcdns_tree, isreq);
1677         break;
1678     case FCDNS_GID_IPP:
1679         dissect_fcdns_gidipp (tvb, fcdns_tree, isreq);
1680         break;
1681     case FCDNS_GID_FF:
1682         dissect_fcdns_gidff (tvb, fcdns_tree, isreq);
1683         break;
1684     case FCDNS_RPN_ID:
1685         dissect_fcdns_rpnid (tvb, fcdns_tree, isreq);
1686         break;
1687     case FCDNS_RNN_ID:
1688         dissect_fcdns_rnnid (tvb, fcdns_tree, isreq);
1689         break;
1690     case FCDNS_RCS_ID:
1691         dissect_fcdns_rcsid (tvb, fcdns_tree, isreq);
1692         break;
1693     case FCDNS_RPT_ID:
1694         dissect_fcdns_rptid (tvb, fcdns_tree, isreq);
1695         break;
1696     case FCDNS_RFT_ID:
1697         dissect_fcdns_rftid (tvb, fcdns_tree, isreq);
1698         break;
1699     case FCDNS_RSPN_ID:
1700         dissect_fcdns_rspnid (tvb, fcdns_tree, isreq);
1701         break;
1702     case FCDNS_RIPP_ID:
1703         dissect_fcdns_rippid (tvb, fcdns_tree, isreq);
1704         break;
1705     case FCDNS_RFD_ID:
1706         dissect_fcdns_rfdid (tvb, fcdns_tree, isreq);
1707         break;
1708     case FCDNS_RFF_ID:
1709         dissect_fcdns_rffid (tvb, fcdns_tree, isreq);
1710         break;
1711     case FCDNS_RIP_NN:
1712         dissect_fcdns_ripnn (tvb, fcdns_tree, isreq);
1713         break;
1714     case FCDNS_RSNN_NN:
1715         dissect_fcdns_rsnnnn (tvb, fcdns_tree, isreq);
1716         break;
1717     case FCDNS_DA_ID:
1718         dissect_fcdns_daid (tvb, fcdns_tree, isreq);
1719         break;
1720     case FCDNS_GE_ID:
1721         dissect_fcdns_geid (tvb, fcdns_tree, isreq);
1722         break;
1723     case FCDNS_GE_PN:
1724         dissect_fcdns_gepn (tvb, fcdns_tree, isreq);
1725         break;
1726     case FCDNS_GE_NN:
1727         dissect_fcdns_genn (tvb, fcdns_tree, isreq);
1728         break;
1729     case FCDNS_GE_IP:
1730         dissect_fcdns_geip (tvb, fcdns_tree, isreq);
1731         break;
1732     case FCDNS_GE_FT:
1733         dissect_fcdns_geft (tvb, fcdns_tree, isreq);
1734         break;
1735     case FCDNS_GE_PT:
1736         dissect_fcdns_gept (tvb, fcdns_tree, isreq);
1737         break;
1738     case FCDNS_GE_ZM:
1739         dissect_fcdns_gezm (tvb, pinfo, fcdns_tree, isreq);
1740         break;
1741     case FCDNS_GE_ZN:
1742         dissect_fcdns_gezn (tvb, fcdns_tree, isreq);
1743         break;
1744     case FCDNS_GE_IPP:
1745         dissect_fcdns_geipp (tvb, fcdns_tree, isreq);
1746         break;
1747     case FCDNS_GE_FF:
1748         dissect_fcdns_geff (tvb, fcdns_tree, isreq);
1749         break;
1750     default:
1751         break;
1752     }
1753
1754     return tvb_length(tvb);
1755 }
1756
1757 /* Register the protocol with Wireshark */
1758
1759 void
1760 proto_register_fcdns (void)
1761 {
1762 #ifndef HAVE_HFI_SECTION_INIT
1763     static header_field_info *hfi[] = {
1764         /* &hfi_fcdns_gssubtype */
1765         &hfi_fcdns_opcode,
1766         &hfi_fcdns_req_portid,
1767         &hfi_fcdns_rply_pname,
1768         &hfi_fcdns_rply_nname,
1769         &hfi_fcdns_rply_snamelen,
1770         &hfi_fcdns_rply_sname,
1771         &hfi_fcdns_rply_ptype,
1772         &hfi_fcdns_rply_fpname,
1773         &hfi_fcdns_req_pname,
1774         &hfi_fcdns_rply_portid,
1775         &hfi_fcdns_req_nname,
1776         &hfi_fcdns_req_domainscope,
1777         &hfi_fcdns_req_areascope,
1778         &hfi_fcdns_req_fc4type,
1779         &hfi_fcdns_req_ptype,
1780         &hfi_fcdns_req_ip,
1781         &hfi_fcdns_rply_fc4type,
1782         &hfi_fcdns_req_snamelen,
1783         &hfi_fcdns_req_sname,
1784         &hfi_fcdns_rply_spnamelen,
1785         &hfi_fcdns_rply_spname,
1786         &hfi_fcdns_rply_ipa,
1787         &hfi_fcdns_rply_ipnode,
1788         &hfi_fcdns_rply_ipport,
1789         &hfi_fcdns_rply_fc4desclen,
1790         &hfi_fcdns_rply_fc4desc,
1791         &hfi_fcdns_rply_hrdaddr,
1792         &hfi_fcdns_req_fdesclen,
1793         &hfi_fcdns_req_fdesc,
1794         &hfi_fcdns_req_spnamelen,
1795         &hfi_fcdns_req_spname,
1796         &hfi_fcdns_reason,
1797         &hfi_fcdns_rjtdetail,
1798         &hfi_fcdns_vendor,
1799         &hfi_fcdns_zone_mbrtype,
1800         &hfi_fcdns_zone_mbrid,
1801         &hfi_fcdns_zone_mbrid_wwn,
1802         &hfi_fcdns_zone_mbrid_uint,
1803         &hfi_fcdns_zone_mbrid_fc,
1804         &hfi_fcdns_zonenm,
1805         &hfi_fcdns_portip,
1806         &hfi_fcdns_sw2_objfmt,
1807         &hfi_fcdns_num_fc4desc,
1808         &hfi_fcdns_rply_ownerid,
1809         &hfi_fcdns_maxres_size,
1810         &hfi_fcdns_reply_cos,
1811         &hfi_fcdns_req_cos,
1812         &hfi_fcdns_cos_f,
1813         &hfi_fcdns_cos_1,
1814         &hfi_fcdns_cos_2,
1815         &hfi_fcdns_cos_3,
1816         &hfi_fcdns_cos_4,
1817         &hfi_fcdns_cos_6,
1818         &hfi_fcdns_fc4type_llcsnap,
1819         &hfi_fcdns_fc4type_ip,
1820         &hfi_fcdns_fc4type_fcp,
1821         &hfi_fcdns_fc4type_swils,
1822         &hfi_fcdns_fc4type_snmp,
1823         &hfi_fcdns_fc4type_gs3,
1824         &hfi_fcdns_fc4type_vi,
1825         &hfi_fcdns_rply_gft,
1826         &hfi_fcdns_req_fc4types,
1827         &hfi_fcdns_fc4type,
1828         &hfi_fcdns_fc4features,
1829         &hfi_fcdns_fc4features_i,
1830         &hfi_fcdns_fc4features_t,
1831     };
1832 #endif
1833
1834     static gint *ett[] = {
1835         &ett_fcdns,
1836         &ett_cos_flags,
1837         &ett_fc4flags,
1838         &ett_fc4features,
1839     };
1840
1841     static ei_register_info ei[] = {
1842         { &ei_fcdns_no_record_of_exchange, { "fcdns.no_record_of_exchange", PI_UNDECODED, PI_WARN, "No record of Exchg. Unable to decode MSG_ACC/RJT", EXPFILL }},
1843         { &ei_fcdns_zone_mbrid, { "fcdns.zone.mbrid.unknown_type", PI_PROTOCOL, PI_WARN, "Unknown member type format", EXPFILL }},
1844     };
1845
1846     expert_module_t* expert_fcdns;
1847     int proto_fcdns;
1848
1849     proto_fcdns = proto_register_protocol("Fibre Channel Name Server", "FC-dNS", "fcdns");
1850     hfi_fcdns = proto_registrar_get_nth(proto_fcdns);
1851
1852     proto_register_fields(proto_fcdns, hfi, array_length(hfi));
1853     proto_register_subtree_array(ett, array_length(ett));
1854     expert_fcdns = expert_register_protocol(proto_fcdns);
1855     expert_register_field_array(expert_fcdns, ei, array_length(ei));
1856     register_init_routine (&fcdns_init_protocol);
1857
1858     dns_handle = new_create_dissector_handle (dissect_fcdns, proto_fcdns);
1859 }
1860
1861 void
1862 proto_reg_handoff_fcdns (void)
1863 {
1864     dissector_add_uint("fcct.server", FCCT_GSRVR_DNS, dns_handle);
1865     dissector_add_uint("fcct.server", FCCT_GSRVR_UNS, dns_handle);
1866 }
1867
1868 /*
1869  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1870  *
1871  * Local variables:
1872  * c-basic-offset: 4
1873  * tab-width: 8
1874  * indent-tabs-mode: nil
1875  * End:
1876  *
1877  * vi: set shiftwidth=4 tabstop=8 expandtab:
1878  * :indentSize=4:tabSize=8:noTabs=true:
1879  */