Deleting unneccessary #includes from dissectors.
[metze/wireshark/wip.git] / epan / dissectors / packet-fcswils.c
1 /* packet-fcswils.c
2  * Routines for FC Inter-switch link services
3  * Copyright 2001, Dinesh G Dutt <ddutt@cisco.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 #include "config.h"
25
26 #include <epan/packet.h>
27 #include <epan/expert.h>
28 #include <epan/to_str.h>
29 #include "packet-fc.h"
30 #include "packet-fcswils.h"
31 #include "packet-fcct.h"
32
33 void proto_register_fcswils(void);
34 void proto_reg_handoff_fcswils(void);
35
36 /*
37  * See the FC-SW specifications.
38  */
39
40 #define FC_SWILS_RPLY               0x0
41 #define FC_SWILS_REQ                0x1
42 #define FC_SWILS_RSCN_DEVENTRY_SIZE 20
43
44 /* Zone name has the structure:
45  * name_len (1 byte), rsvd (3 bytes), name (m bytes), fill (n bytes)
46  * name_len excludes the 4 initial bytes before the name
47  */
48 #define ZONENAME_LEN(x, y)  (tvb_get_guint8(x, y)+4)
49
50 /* Initialize the protocol and registered fields */
51 static int proto_fcswils                  = -1;
52 static int hf_swils_opcode                = -1;
53 static int hf_swils_elp_rev               = -1;
54 static int hf_swils_elp_flags             = -1;
55 static int hf_swils_elp_r_a_tov           = -1;
56 static int hf_swils_elp_e_d_tov           = -1;
57 static int hf_swils_elp_req_epn           = -1;
58 static int hf_swils_elp_req_esn           = -1;
59 static int hf_swils_elp_clsf_svcp         = -1;
60 static int hf_swils_elp_clsf_rcvsz        = -1;
61 static int hf_swils_elp_clsf_conseq       = -1;
62 static int hf_swils_elp_clsf_e2e          = -1;
63 static int hf_swils_elp_clsf_openseq      = -1;
64 static int hf_swils_elp_cls1_svcp         = -1;
65 static int hf_swils_elp_cls1_rcvsz        = -1;
66 static int hf_swils_elp_cls2_svcp         = -1;
67 static int hf_swils_elp_cls2_rcvsz        = -1;
68 static int hf_swils_elp_cls3_svcp         = -1;
69 static int hf_swils_elp_cls3_rcvsz        = -1;
70 static int hf_swils_elp_isl_fc_mode       = -1;
71 static int hf_swils_elp_fcplen            = -1;
72 static int hf_swils_elp_b2bcredit         = -1;
73 static int hf_swils_elp_compat1           = -1;
74 static int hf_swils_elp_compat2           = -1;
75 static int hf_swils_elp_compat3           = -1;
76 static int hf_swils_elp_compat4           = -1;
77 static int hf_swils_efp_rec_type          = -1;
78 static int hf_swils_efp_dom_id            = -1;
79 static int hf_swils_efp_switch_name       = -1;
80 static int hf_swils_efp_mcast_grpno       = -1;
81 /* static int hf_swils_efp_alias_token       = -1; */
82 static int hf_swils_efp_record_len        = -1;
83 static int hf_swils_efp_payload_len       = -1;
84 static int hf_swils_efp_pswitch_pri       = -1;
85 static int hf_swils_efp_pswitch_name      = -1;
86 static int hf_swils_dia_switch_name       = -1;
87 static int hf_swils_rdi_payload_len       = -1;
88 static int hf_swils_rdi_req_sname         = -1;
89 /* static int hf_swils_fspfh_cmd             = -1; */
90 static int hf_swils_fspfh_rev             = -1;
91 static int hf_swils_fspfh_ar_num          = -1;
92 static int hf_swils_fspfh_auth_type       = -1;
93 static int hf_swils_fspfh_dom_id          = -1;
94 static int hf_swils_fspfh_auth            = -1;
95 static int hf_swils_hlo_options           = -1;
96 static int hf_swils_hlo_hloint            = -1;
97 static int hf_swils_hlo_deadint           = -1;
98 static int hf_swils_hlo_rcv_domid         = -1;
99 static int hf_swils_hlo_orig_pidx         = -1;
100 static int hf_swils_ldrec_linkid          = -1;
101 static int hf_swils_ldrec_out_pidx        = -1;
102 static int hf_swils_ldrec_nbr_pidx        = -1;
103 static int hf_swils_ldrec_link_type       = -1;
104 static int hf_swils_ldrec_link_cost       = -1;
105 static int hf_swils_lsrh_lsr_type         = -1;
106 static int hf_swils_lsrh_lsid             = -1;
107 static int hf_swils_lsrh_adv_domid        = -1;
108 static int hf_swils_lsrh_ls_incid         = -1;
109 static int hf_swils_esc_pdesc_vendorid    = -1;
110 static int hf_swils_esc_swvendorid        = -1;
111 static int hf_swils_esc_protocolid        = -1;
112 static int hf_swils_rscn_evtype           = -1;
113 static int hf_swils_rscn_addrfmt          = -1;
114 static int hf_swils_rscn_detectfn         = -1;
115 static int hf_swils_rscn_affectedport     = -1;
116 static int hf_swils_rscn_portstate        = -1;
117 static int hf_swils_rscn_portid           = -1;
118 static int hf_swils_rscn_pwwn             = -1;
119 static int hf_swils_rscn_nwwn             = -1;
120 static int hf_swils_zone_activezonenm     = -1;
121 static int hf_swils_zone_objname          = -1;
122 static int hf_swils_zone_objtype          = -1;
123 static int hf_swils_zone_mbrtype          = -1;
124 static int hf_swils_zone_protocol         = -1;
125 static int hf_swils_zone_mbrid            = -1;
126 static int hf_swils_zone_status           = -1;
127 static int hf_swils_zone_reason           = -1;
128 static int hf_swils_aca_domainid          = -1;
129 static int hf_swils_sfc_opcode            = -1;
130 static int hf_swils_sfc_zonenm            = -1;
131 static int hf_swils_rjt                   = -1;
132 static int hf_swils_rjtdet                = -1;
133 static int hf_swils_rjtvendor             = -1;
134 static int hf_swils_zone_mbrid_lun        = -1;
135 static int hf_swils_ess_rev               = -1;
136 static int hf_swils_ess_len               = -1;
137 static int hf_swils_ess_numobj            = -1;
138 static int hf_swils_interconnect_list_len = -1;
139 static int hf_swils_ess_vendorname        = -1;
140 static int hf_swils_ess_modelname         = -1;
141 static int hf_swils_ess_relcode           = -1;
142 static int hf_swils_ess_vendorspecific    = -1;
143 static int hf_swils_ess_cap_type          = -1;
144 static int hf_swils_ess_cap_subtype       = -1;
145 static int hf_swils_ess_cap_numentries    = -1;
146 static int hf_swils_ess_cap_svc           = -1;
147 static int hf_swils_ess_dns_obj0h         = -1;
148 static int hf_swils_ess_dns_obj1h         = -1;
149 static int hf_swils_ess_dns_obj2h         = -1;
150 static int hf_swils_ess_dns_obj3h         = -1;
151 static int hf_swils_ess_dns_zlacc         = -1;
152 static int hf_swils_ess_dns_vendor        = -1;
153 static int hf_swils_ess_fctlr_rscn        = -1;
154 static int hf_swils_ess_fctlr_vendor      = -1;
155 static int hf_swils_ess_fcs_basic         = -1;
156 static int hf_swils_ess_fcs_platform      = -1;
157 static int hf_swils_ess_fcs_topology      = -1;
158 static int hf_swils_ess_fcs_enhanced      = -1;
159 static int hf_swils_ess_fzs_enh_supp      = -1;
160 static int hf_swils_ess_fzs_enh_ena       = -1;
161 static int hf_swils_ess_fzs_mr            = -1;
162 static int hf_swils_ess_fzs_zsdb_supp     = -1;
163 static int hf_swils_ess_fzs_zsdb_ena      = -1;
164 static int hf_swils_ess_fzs_adc_supp      = -1;
165 static int hf_swils_ess_fzs_hardzone      = -1;
166 static int hf_swils_mrra_rev              = -1;
167 static int hf_swils_mrra_size             = -1;
168 static int hf_swils_mrra_vendorid         = -1;
169 static int hf_swils_mrra_reply            = -1;
170 static int hf_swils_mrra_reply_size       = -1;
171 static int hf_swils_mrra_waittime         = -1;
172 static int hf_swils_ess_cap_t10           = -1;
173 static int hf_swils_ess_cap_vendorobj     = -1;
174 static int hf_swils_ess_fzs_defzone       = -1;
175 static int hf_swils_ess_cap_len           = -1;
176 static int hf_swils_mrra_vendorinfo       = -1;
177
178 /* Generated from convert_proto_tree_add_text.pl */
179 static int hf_swils_lsrh_lsr_age = -1;
180 static int hf_swils_zone_full_zone_set_length = -1;
181 static int hf_swils_zone_num_zoning_objects = -1;
182 static int hf_swils_lsrec_number_of_links = -1;
183 static int hf_swils_sfc_zoneset_length = -1;
184 static int hf_swils_zone_vendor_unique = -1;
185 static int hf_swils_zone_num_members = -1;
186 static int hf_swils_zone_active_zoneset_length = -1;
187 static int hf_swils_lsack_num_of_lsr_headers = -1;
188 static int hf_swils_lsrh_lsr_length = -1;
189 static int hf_swils_esc_payload_length = -1;
190 static int hf_swils_lsupdate_num_of_lsrs = -1;
191 static int hf_swils_zone_mbr_identifier_length = -1;
192 static int hf_swils_zone_mbrflags = -1;
193 static int hf_swils_lsrh_options = -1;
194 static int hf_swils_domain_id_list_length = -1;
195 static int hf_swils_lsack_flags = -1;
196 static int hf_swils_rscn_num_entries = -1;
197 static int hf_swils_requested_domain_id = -1;
198 static int hf_swils_lsrh_checksum = -1;
199 static int hf_swils_granted_domain_id = -1;
200 static int hf_swils_lsupdate_flags = -1;
201
202
203 static expert_field ei_swils_efp_record_len = EI_INIT;
204 static expert_field ei_swils_no_exchange = EI_INIT;
205
206 /* Initialize the subtree pointers */
207 static gint ett_fcswils             = -1;
208 static gint ett_fcswils_swacc       = -1;
209 static gint ett_fcswils_swrjt       = -1;
210 static gint ett_fcswils_elp         = -1;
211 static gint ett_fcswils_efp         = -1;
212 static gint ett_fcswils_efplist     = -1;
213 static gint ett_fcswils_dia         = -1;
214 static gint ett_fcswils_rdi         = -1;
215 static gint ett_fcswils_fspfhdr     = -1;
216 static gint ett_fcswils_hlo         = -1;
217 static gint ett_fcswils_lsrec       = -1;
218 static gint ett_fcswils_lsrechdr    = -1;
219 static gint ett_fcswils_ldrec       = -1;
220 static gint ett_fcswils_lsu         = -1;
221 static gint ett_fcswils_lsa         = -1;
222 static gint ett_fcswils_bf          = -1;
223 static gint ett_fcswils_rcf         = -1;
224 static gint ett_fcswils_rscn        = -1;
225 static gint ett_fcswils_rscn_dev    = -1;
226 static gint ett_fcswils_drlir       = -1;
227 static gint ett_fcswils_mr          = -1;
228 static gint ett_fcswils_zoneobjlist = -1;
229 static gint ett_fcswils_zoneobj     = -1;
230 static gint ett_fcswils_zonembr     = -1;
231 static gint ett_fcswils_aca         = -1;
232 static gint ett_fcswils_rca         = -1;
233 static gint ett_fcswils_sfc         = -1;
234 static gint ett_fcswils_ufc         = -1;
235 static gint ett_fcswils_esc         = -1;
236 static gint ett_fcswils_esc_pdesc   = -1;
237 static gint ett_fcswils_ieinfo      = -1;
238 static gint ett_fcswils_capinfo     = -1;
239
240 static const value_string fc_swils_opcode_key_val[] = {
241     {FC_SWILS_SWRJT   , "SW_RJT"},
242     {FC_SWILS_SWACC   , "SW_ACC"},
243     {FC_SWILS_ELP     , "ELP"},
244     {FC_SWILS_EFP     , "EFP"},
245     {FC_SWILS_DIA     , "DIA"},
246     {FC_SWILS_RDI     , "RDI"},
247     {FC_SWILS_HLO     , "HLO"},
248     {FC_SWILS_LSU     , "LSU"},
249     {FC_SWILS_LSA     , "LSA"},
250     {FC_SWILS_BF      , "BF"},
251     {FC_SWILS_RCF     , "RCF"},
252     {FC_SWILS_RSCN    , "SW_RSCN"},
253     {FC_SWILS_DRLIR   , "DRLIR"},
254     {FC_SWILS_DSCN    , "DSCN"},
255     {FC_SWILS_LOOPD   , "LOOPD"},
256     {FC_SWILS_MR      , "MR"},
257     {FC_SWILS_ACA     , "ACA"},
258     {FC_SWILS_RCA     , "RCA"},
259     {FC_SWILS_SFC     , "SFC"},
260     {FC_SWILS_UFC     , "UFC"},
261     {FC_SWILS_ESC     , "ESC"},
262     {FC_SWILS_ESS     , "ESS"},
263     {FC_SWILS_MRRA    , "MRRA"},
264     {FC_SWILS_AUTH_ILS, "AUTH_ILS"},
265     {0, NULL},
266 };
267
268 static const value_string fc_swils_rjt_val [] = {
269     {FC_SWILS_RJT_INVCODE   , "Invalid Cmd Code"},
270     {FC_SWILS_RJT_INVVER    , "Invalid Revision"},
271     {FC_SWILS_RJT_LOGERR    , "Logical Error"},
272     {FC_SWILS_RJT_INVSIZE   , "Invalid Size"},
273     {FC_SWILS_RJT_LOGBSY    , "Logical Busy"},
274     {FC_SWILS_RJT_PROTERR   , "Protocol Error"},
275     {FC_SWILS_RJT_GENFAIL   , "Unable to Perform"},
276     {FC_SWILS_RJT_CMDNOTSUPP, "Unsupported Cmd"},
277     {FC_SWILS_RJT_VENDUNIQ  , "Vendor Unique Err"},
278     {0, NULL},
279 };
280
281 static const value_string fc_swils_deterr_val [] = {
282     {FC_SWILS_RJT_NODET     , "No Additional Details"},
283     {FC_SWILS_RJT_CLSF_ERR  , "Class F Svc Param Err"},
284     {FC_SWILS_RJT_CLSN_ERR  , "Class N Svc Param Err"},
285     {FC_SWILS_RJT_INVFC_CODE, "Unknown Flow Ctrl Code"},
286     {FC_SWILS_RJT_INVFC_PARM, "Invalid Flow Ctrl Parm"},
287     {FC_SWILS_RJT_INV_PNAME , "Invalid Port Name"},
288     {FC_SWILS_RJT_INV_SNAME , "Invalid Switch Name"},
289     {FC_SWILS_RJT_TOV_MSMTCH, "R_A_/E_D_TOV Mismatch"},
290     {FC_SWILS_RJT_INV_DIDLST, "Invalid Domain ID List"},
291     {FC_SWILS_RJT_CMD_INPROG, "Cmd Already in Progress"},
292     {FC_SWILS_RJT_OORSRC    , "Insufficient Resources"},
293     {FC_SWILS_RJT_NO_DID    , "Domain ID Unavailable"},
294     {FC_SWILS_RJT_INV_DID   , "Invalid Domain ID"},
295     {FC_SWILS_RJT_NO_REQ    , "Request Not Supported"},
296     {FC_SWILS_RJT_NOLNK_PARM, "Link Parm Not Estd."},
297     {FC_SWILS_RJT_NO_REQDID , "Group of Domain IDs Unavail"},
298     {FC_SWILS_RJT_EP_ISOL   , "E_Port Isolated"},
299     {0, NULL}
300 };
301
302 static const value_string fcswils_elp_fc_val[] = {
303     {FC_SWILS_ELP_FC_VENDOR, "Vendor Unique"},
304     {FC_SWILS_ELP_FC_RRDY  , "R_RDY Flow Ctrl"},
305     {0, NULL},
306 };
307
308 static const value_string fcswils_rectype_val[] = {
309     {FC_SWILS_LRECTYPE_DOMAIN, "Domain ID Record"},
310     {FC_SWILS_LRECTYPE_MCAST , "Multicast ID Record"},
311     {0, NULL},
312 };
313
314 static const value_string fc_swils_link_type_val[] = {
315     {0x01, "P2P Link"},
316     {0xF0, "Vendor Specific"},
317     {0xF1, "Vendor Specific"},
318     {0xF2, "Vendor Specific"},
319     {0xF3, "Vendor Specific"},
320     {0xF4, "Vendor Specific"},
321     {0xF5, "Vendor Specific"},
322     {0xF6, "Vendor Specific"},
323     {0xF7, "Vendor Specific"},
324     {0xF8, "Vendor Specific"},
325     {0xF9, "Vendor Specific"},
326     {0xFA, "Vendor Specific"},
327     {0xFB, "Vendor Specific"},
328     {0xFC, "Vendor Specific"},
329     {0xFD, "Vendor Specific"},
330     {0xFE, "Vendor Specific"},
331     {0xFF, "Vendor Specific"},
332     {0, NULL},
333 };
334
335 static const value_string fc_swils_fspf_linkrec_val[] = {
336     {FC_SWILS_LSR_SLR, "Switch Link Record"},
337     {FC_SWILS_LSR_ARS, "AR Summary Record"},
338     {0, NULL},
339 };
340
341 static const value_string fc_swils_fspf_lsrflags_val[] = {
342     {0x0, "LSR is for a Topology Update"},
343     {0x1, "LSR is for Initial DB Sync | Not the last seq in DB sync"},
344     {0x2, "Last Seq in DB Sync. LSU has no LSRs"},
345     {0x3, "LSR is for Initial DB Sync | Last Seq in DB Sync"},
346     {0, NULL},
347 };
348
349 static const value_string fc_swils_rscn_portstate_val[] = {
350     {0, "No Additional Info"},
351     {1, "Port is online"},
352     {2, "Port is offline"},
353     {0, NULL},
354 };
355
356 static const value_string fc_swils_rscn_addrfmt_val[] = {
357     {0, "Port Addr Format"},
358     {1, "Area Addr Format"},
359     {2, "Domain Addr Format"},
360     {3, "Fabric Addr Format"},
361     {0, NULL},
362 };
363
364 static const value_string fc_swils_rscn_detectfn_val[] = {
365     {1, "Fabric Detected"},
366     {2, "N_Port Detected"},
367     {0, NULL},
368 };
369
370 static const value_string fc_swils_esc_protocol_val[] = {
371     {0, "Reserved"},
372     {1, "FSPF-Backbone Protocol"},
373     {2, "FSPF Protocol"},
374     {0, NULL},
375 };
376
377 static const value_string fc_swils_zoneobj_type_val[] = {
378     {0, "Reserved"},
379     {FC_SWILS_ZONEOBJ_ZONESET  , "Zone Set"},
380     {FC_SWILS_ZONEOBJ_ZONE     , "Zone"},
381     {FC_SWILS_ZONEOBJ_ZONEALIAS, "Zone Alias"},
382     {0, NULL},
383 };
384
385 const value_string fc_swils_zonembr_type_val[] = {
386     {0                        , "Reserved"},
387     {FC_SWILS_ZONEMBR_WWN     , "WWN"},
388     {FC_SWILS_ZONEMBR_DP      , "Domain/Physical Port (0x00ddpppp)"},
389     {FC_SWILS_ZONEMBR_FCID    , "FC Address"},
390     {FC_SWILS_ZONEMBR_ALIAS   , "Zone Alias"},
391     {FC_SWILS_ZONEMBR_WWN_LUN , "WWN+LUN"},
392     {FC_SWILS_ZONEMBR_DP_LUN  , "Domain/Physical Port+LUN"},
393     {FC_SWILS_ZONEMBR_FCID_LUN, "FCID+LUN"},
394     {0, NULL},
395 };
396
397 static const value_string fc_swils_mr_rsp_val[] = {
398     {0, "Successful"},
399     {1, "Fabric Busy"},
400     {2, "Failed"},
401     {0, NULL},
402 };
403
404 static const value_string fc_swils_mr_reason_val[] = {
405     {0x0, "No Reason"},
406     {0x1, "Invalid Data Length"},
407     {0x2, "Unsupported Command"},
408     {0x3, "Reserved"},
409     {0x4, "Not Authorized"},
410     {0x5, "Invalid Request"},
411     {0x6, "Fabric Changing"},
412     {0x7, "Update Not Staged"},
413     {0x8, "Invalid Zone Set Format"},
414     {0x9, "Invalid Data"},
415     {0xA, "Cannot Merge"},
416     {0, NULL},
417 };
418
419 static const value_string fc_swils_sfc_op_val[] = {
420     {0, "Reserved"},
421     {1, "Reserved"},
422     {2, "Reserved"},
423     {3, "Activate Zone Set"},
424     {4, "Deactivate Zone Set"},
425     {0, NULL},
426 };
427
428 typedef struct _zonename {
429     guint32  namelen:8,
430         rsvd:24;
431     gchar   *name;
432     gchar   *pad;
433 } zonename_t;
434
435 typedef struct _fcswils_conv_key {
436     guint32 conv_idx;
437 } fcswils_conv_key_t;
438
439 typedef struct _fcswils_conv_data {
440     guint32 opcode;
441 } fcswils_conv_data_t;
442
443 static GHashTable *fcswils_req_hash = NULL;
444
445 /* list of commands for each commandset */
446 typedef void (*fcswils_dissector_t)(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint8 isreq);
447
448 typedef struct _fcswils_func_table_t {
449     fcswils_dissector_t func;
450 } fcswils_func_table_t;
451
452 static dissector_handle_t data_handle, fcsp_handle;
453
454 static gint get_zoneobj_len(tvbuff_t *tvb, gint offset);
455
456 /*
457  * Hash Functions
458  */
459 static gint
460 fcswils_equal(gconstpointer v, gconstpointer w)
461 {
462     const fcswils_conv_key_t *v1 = (const fcswils_conv_key_t *)v;
463     const fcswils_conv_key_t *v2 = (const fcswils_conv_key_t *)w;
464
465     return (v1->conv_idx == v2->conv_idx);
466 }
467
468 static guint
469 fcswils_hash(gconstpointer v)
470 {
471     const fcswils_conv_key_t *key = (const fcswils_conv_key_t *)v;
472     guint val;
473
474     val = key->conv_idx;
475
476     return val;
477 }
478
479 /*
480  * Protocol initialization
481  */
482 static void
483 fcswils_init_protocol(void)
484 {
485     if (fcswils_req_hash)
486         g_hash_table_destroy(fcswils_req_hash);
487
488     fcswils_req_hash = g_hash_table_new(fcswils_hash, fcswils_equal);
489
490 }
491
492 static guint8 *
493 zonenm_to_str(tvbuff_t *tvb, gint offset)
494 {
495     int len = tvb_get_guint8(tvb, offset);
496     return tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, len, ENC_ASCII);
497 }
498
499 /* Offset points to the start of the zone object */
500 static gint
501 get_zoneobj_len(tvbuff_t *tvb, gint offset)
502 {
503     gint   numrec, numrec1;
504     guint8 objtype;
505     gint   i, j, len;
506
507     /* zone object structure is:
508      * type (1 byte), protocol (1 byte), rsvd (2 bytes), obj name (x bytes),
509      * num of zone mbrs (4 bytes ), list of zone members (each member if of
510      * variable length).
511      *
512      * zone member structure is:
513      * type (1 byte), rsvd (1 byte), flags (1 byte), id_len (1 byte),
514      * id (id_len bytes)
515      */
516     objtype = tvb_get_guint8(tvb, offset);
517     len = 4 + ZONENAME_LEN(tvb, offset+4); /* length upto num_of_mbrs field */
518     numrec = tvb_get_ntohl(tvb, offset+len); /* gets us num of zone mbrs */
519
520     len += 4;                   /* + num_mbrs */
521     for (i = 0; i < numrec; i++) {
522         if (objtype == FC_SWILS_ZONEOBJ_ZONESET) {
523             len += 4 + ZONENAME_LEN(tvb, offset+4+len); /* length upto num_of_mbrs field */
524             numrec1 = tvb_get_ntohl(tvb, offset+len);
525
526             len += 4;
527             for (j = 0; j < numrec1; j++) {
528                 len += 4 + tvb_get_guint8(tvb, offset+3+len);
529             }
530         }
531         else {
532             len += 4 + tvb_get_guint8(tvb, offset+3+len);
533         }
534     }
535
536     return len;
537 }
538
539 #define MAX_INTERCONNECT_ELEMENT_INFO_LEN  252
540 static int
541 dissect_swils_interconnect_element_info(tvbuff_t *tvb, proto_tree *tree, int offset)
542 {
543
544     int len, max_len = MAX_INTERCONNECT_ELEMENT_INFO_LEN;
545
546     if (tree) {
547         proto_tree_add_item(tree, hf_swils_interconnect_list_len, tvb, offset+3, 1, ENC_BIG_ENDIAN);
548         len = tvb_strsize(tvb, offset+4);
549         proto_tree_add_item(tree, hf_swils_ess_vendorname, tvb, offset+4, len, ENC_ASCII|ENC_NA);
550         offset += (4 + len);
551         max_len -= len;
552         len = tvb_strsize(tvb, offset);
553         proto_tree_add_item(tree, hf_swils_ess_modelname, tvb, offset, len, ENC_ASCII|ENC_NA);
554         offset += len;
555         max_len -= len;
556         len = tvb_strsize(tvb, offset);
557         proto_tree_add_item(tree, hf_swils_ess_relcode, tvb, offset, len, ENC_ASCII|ENC_NA);
558         offset += len;
559         max_len -= len;
560         while (max_len > 0) {
561             /* Vendor specific field is a set of one or more null-terminated
562              * strings
563              */
564             len = tvb_strsize(tvb, offset);
565             proto_tree_add_item(tree, hf_swils_ess_vendorspecific, tvb, offset, len, ENC_ASCII|ENC_NA);
566             offset += len;
567             max_len -= len;
568         }
569     }
570
571     return TRUE;
572 }
573
574 static void
575 dissect_swils_ess_capability(tvbuff_t *tvb, proto_tree *tree, int offset,
576                              guint8 srvr_type)
577 {
578     if (tree) {
579         switch (srvr_type) {
580         case FCCT_GSRVR_DNS:
581             proto_tree_add_item(tree, hf_swils_ess_dns_zlacc, tvb, offset+3,
582                                 1, ENC_BIG_ENDIAN);
583             proto_tree_add_item(tree, hf_swils_ess_dns_obj3h, tvb, offset+3,
584                                 1, ENC_BIG_ENDIAN);
585             proto_tree_add_item(tree, hf_swils_ess_dns_obj2h, tvb, offset+3,
586                                 1, ENC_BIG_ENDIAN);
587             proto_tree_add_item(tree, hf_swils_ess_dns_obj1h, tvb, offset+3,
588                                 1, ENC_BIG_ENDIAN);
589             proto_tree_add_item(tree, hf_swils_ess_dns_obj0h, tvb, offset+3,
590                                 1, ENC_BIG_ENDIAN);
591             proto_tree_add_item(tree, hf_swils_ess_dns_vendor, tvb,
592                                 offset+4, 4, ENC_BIG_ENDIAN);
593             break;
594         case FCCT_GSRVR_FCTLR:
595             proto_tree_add_item(tree, hf_swils_ess_fctlr_rscn, tvb,
596                                 offset+3, 1, ENC_BIG_ENDIAN);
597             proto_tree_add_item(tree, hf_swils_ess_fctlr_vendor, tvb,
598                                 offset+4, 4, ENC_BIG_ENDIAN);
599             break;
600         case FCCT_GSRVR_FCS:
601             proto_tree_add_item(tree, hf_swils_ess_fcs_basic, tvb,
602                                 offset+3, 1, ENC_BIG_ENDIAN);
603             proto_tree_add_item(tree, hf_swils_ess_fcs_platform, tvb,
604                                 offset+3, 1, ENC_BIG_ENDIAN);
605             proto_tree_add_item(tree, hf_swils_ess_fcs_topology, tvb,
606                                 offset+3, 1, ENC_BIG_ENDIAN);
607             proto_tree_add_item(tree, hf_swils_ess_fcs_enhanced, tvb,
608                                 offset+3, 1, ENC_BIG_ENDIAN);
609             break;
610         case FCCT_GSRVR_FZS:
611             proto_tree_add_item(tree, hf_swils_ess_fzs_enh_supp, tvb,
612                                 offset+3, 1, ENC_BIG_ENDIAN);
613             proto_tree_add_item(tree, hf_swils_ess_fzs_enh_ena, tvb,
614                                 offset+3, 1, ENC_BIG_ENDIAN);
615             proto_tree_add_item(tree, hf_swils_ess_fzs_mr, tvb, offset+3,
616                                 1, ENC_BIG_ENDIAN);
617             proto_tree_add_item(tree, hf_swils_ess_fzs_defzone, tvb,
618                                 offset+3, 1, ENC_BIG_ENDIAN);
619             proto_tree_add_item(tree, hf_swils_ess_fzs_zsdb_supp, tvb,
620                                 offset+3, 1, ENC_BIG_ENDIAN);
621             proto_tree_add_item(tree, hf_swils_ess_fzs_zsdb_ena, tvb,
622                                 offset+3, 1, ENC_BIG_ENDIAN);
623             proto_tree_add_item(tree, hf_swils_ess_fzs_adc_supp, tvb,
624                                 offset+3, 1, ENC_BIG_ENDIAN);
625             proto_tree_add_item(tree, hf_swils_ess_fzs_hardzone, tvb,
626                                 offset+3, 1, ENC_BIG_ENDIAN);
627             break;
628         default:
629             break;
630         }
631     }
632
633     return;
634 }
635
636 static int
637 dissect_swils_ess_capability_obj(tvbuff_t *tvb, proto_tree *tree, int offset)
638 {
639     int         i = 0, num_entries = 0, len = 0, total_len = 0;
640     guint8      type, subtype, srvr_type;
641     proto_tree *capinfo_tree = NULL;
642
643     if (tree) {
644         /*
645          * Structure of capability object is: WK type (2B), WK subtype(2),
646          * rsvd (1), num_cap_entries (1), entry_1 (8) ... entry_n (8)
647          */
648         /* Compute length first to create subtree of cap object */
649         type = tvb_get_guint8(tvb, offset);
650         if (type != FCCT_GSTYPE_VENDOR) {
651             num_entries = tvb_get_guint8(tvb, offset+3);
652             total_len = 4 + (num_entries*8);
653             capinfo_tree = proto_tree_add_subtree_format(tree, tvb, offset,
654                                      total_len, ett_fcswils_capinfo, NULL, "Capability Object (%s)",
655                                      val_to_str(type, fc_ct_gstype_vals,
656                                                 "Unknown (0x%x)"));
657         } else {
658             i = tvb_get_guint8(tvb, offset+3);
659             i += 12;
660
661             capinfo_tree = proto_tree_add_subtree_format(tree, tvb, offset,
662                                      i, ett_fcswils_capinfo, NULL, "Capability Object (Vendor-specific 0x%x)",
663                                      type);
664         }
665
666         proto_tree_add_item(capinfo_tree, hf_swils_ess_cap_type, tvb, offset, 1, ENC_BIG_ENDIAN);
667         proto_tree_add_item(capinfo_tree, hf_swils_ess_cap_subtype, tvb, offset+1,
668                             1, ENC_BIG_ENDIAN);
669         subtype = tvb_get_guint8(tvb, offset+1);
670
671         if (type != FCCT_GSTYPE_VENDOR) {
672             srvr_type = get_gs_server(type, subtype);
673             proto_tree_add_uint(capinfo_tree, hf_swils_ess_cap_svc, tvb, offset, 2,
674                                 srvr_type);
675             proto_tree_add_item(capinfo_tree, hf_swils_ess_cap_numentries, tvb,
676                                 offset+3, 1, ENC_BIG_ENDIAN);
677             offset += 4;
678             len += 4;
679
680             while ((num_entries > 0) && tvb_bytes_exist(tvb, offset, 8)) {
681                 dissect_swils_ess_capability(tvb, capinfo_tree, offset, srvr_type);
682                 num_entries--;
683                 offset += 8;
684                 len += 8;
685             }
686         } else {
687             /* Those damn T11 guys defined another format for
688              * Vendor-specific objects.
689              */
690             proto_tree_add_item(capinfo_tree, hf_swils_ess_cap_len, tvb, offset+3,
691                                 1, ENC_BIG_ENDIAN);
692             proto_tree_add_item(capinfo_tree, hf_swils_ess_cap_t10, tvb, offset+4,
693                                 8, ENC_ASCII|ENC_NA);
694             i -= 8;          /* reduce length by t10 object size */
695             offset += 12;
696             len += 12;
697
698             while ((i > 0) && tvb_bytes_exist(tvb, offset, 8)) {
699                 proto_tree_add_item(capinfo_tree, hf_swils_ess_cap_vendorobj,
700                                     tvb, offset, 8, ENC_NA);
701                 i -= 8;
702                 offset += 8;
703                 len += 12;
704             }
705         }
706     }
707     return len;
708 }
709
710 static void
711 dissect_swils_nullpayload(tvbuff_t *tvb _U_, packet_info* pinfo _U_, proto_tree *tree _U_,
712                           guint8 isreq _U_)
713 {
714     /* Common dissector for those ILSs without a payload */
715     return;
716 }
717
718 static void
719 dissect_swils_elp(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *elp_tree, guint8 isreq _U_)
720 {
721
722     /* Set up structures needed to add the protocol subtree and manage it */
723     int          offset = 0;
724     const gchar *flags;
725     fcswils_elp  elp;
726
727     /* Response i.e. SW_ACC for an ELP has the same format as the request */
728     /* We skip the initial 4 bytes as we don't care about the opcode */
729     tvb_memcpy(tvb, (guint8 *)&elp, 4, FC_SWILS_ELP_SIZE);
730
731     elp.r_a_tov = g_ntohl(elp.r_a_tov);
732     elp.e_d_tov = g_ntohl(elp.e_d_tov);
733     elp.isl_flwctrl_mode = g_ntohs(elp.isl_flwctrl_mode);
734     elp.flw_ctrl_parmlen = g_ntohs(elp.flw_ctrl_parmlen);
735
736     if (elp_tree) {
737         offset += 4;
738         proto_tree_add_item(elp_tree, hf_swils_elp_rev, tvb, offset++, 1, ENC_BIG_ENDIAN);
739         proto_tree_add_item(elp_tree, hf_swils_elp_flags, tvb, offset, 2, ENC_NA);
740         offset += 3;
741         proto_tree_add_uint_format_value(elp_tree, hf_swils_elp_r_a_tov, tvb, offset, 4,
742                                    elp.r_a_tov, "%d msecs", elp.r_a_tov);
743         offset += 4;
744         proto_tree_add_uint_format_value(elp_tree, hf_swils_elp_e_d_tov, tvb, offset, 4,
745                                    elp.e_d_tov, "%d msecs", elp.e_d_tov);
746         offset += 4;
747         proto_tree_add_string(elp_tree, hf_swils_elp_req_epn, tvb, offset, 8,
748                               fcwwn_to_str(elp.req_epname));
749         offset += 8;
750         proto_tree_add_string(elp_tree, hf_swils_elp_req_esn, tvb, offset, 8,
751                               fcwwn_to_str(elp.req_sname));
752         offset += 8;
753
754         if (elp.clsf_svcparm[0] & 0x80) {
755             if (elp.clsf_svcparm[4] & 0x20) {
756                 flags="Class F Valid | X_ID Interlock";
757             } else {
758                 flags="Class F Valid | No X_ID Interlk";
759             }
760         } else {
761             flags="Class F Invld";
762         }
763         proto_tree_add_bytes_format_value(elp_tree, hf_swils_elp_clsf_svcp, tvb, offset, 6,
764                                     &elp.clsf_svcparm[0], "(%s)", flags);
765         offset += 6;
766
767         proto_tree_add_item(elp_tree, hf_swils_elp_clsf_rcvsz, tvb, offset, 2, ENC_BIG_ENDIAN);
768         offset += 2;
769         proto_tree_add_item(elp_tree, hf_swils_elp_clsf_conseq, tvb, offset, 2, ENC_BIG_ENDIAN);
770         offset += 2;
771         proto_tree_add_item(elp_tree, hf_swils_elp_clsf_e2e, tvb, offset, 2, ENC_BIG_ENDIAN);
772         offset += 2;
773         proto_tree_add_item(elp_tree, hf_swils_elp_clsf_openseq, tvb, offset, 2, ENC_BIG_ENDIAN);
774         offset += 4;
775
776         if (elp.cls1_svcparm[0] & 0x80) {
777 #define MAX_FLAGS_LEN 40
778             char *flagsbuf;
779             gint stroff, returned_length;
780
781             flagsbuf=(char *)wmem_alloc(wmem_packet_scope(), MAX_FLAGS_LEN);
782             stroff = 0;
783
784             returned_length = g_snprintf(flagsbuf+stroff, MAX_FLAGS_LEN-stroff,
785                                          "Class 1 Valid");
786             stroff += MIN(returned_length, MAX_FLAGS_LEN-stroff);
787             if (elp.cls1_svcparm[0] & 0x40) {
788                 returned_length = g_snprintf(flagsbuf+stroff, MAX_FLAGS_LEN-stroff, " | IMX");
789                 stroff += MIN(returned_length, MAX_FLAGS_LEN-stroff);
790             }
791             if (elp.cls1_svcparm[0] & 0x20) {
792                 returned_length = g_snprintf(flagsbuf+stroff, MAX_FLAGS_LEN-stroff, " | IPS");
793                 stroff += MIN(returned_length, MAX_FLAGS_LEN-stroff);
794             }
795             if (elp.cls1_svcparm[0] & 0x10) {
796                 /*returned_length =*/ g_snprintf(flagsbuf+stroff, MAX_FLAGS_LEN-stroff, " | LKS");
797             }
798             flags=flagsbuf;
799         }
800         else {
801             flags="Class 1 Invalid";
802         }
803
804         proto_tree_add_bytes_format_value(elp_tree, hf_swils_elp_cls1_svcp, tvb, offset, 2,
805                                     NULL, "(%s)", flags);
806         offset += 2;
807         if (elp.cls1_svcparm[0] & 0x80) {
808             proto_tree_add_item(elp_tree, hf_swils_elp_cls1_rcvsz, tvb, offset, 2, ENC_BIG_ENDIAN);
809         }
810         offset += 2;
811
812         if (elp.cls2_svcparm[0] & 0x80) {
813             if (elp.cls2_svcparm[0] & 0x08) {
814                 flags="Class 2 Valid | Seq Delivery";
815             }
816             else {
817                 flags="Class 2 Valid | No Seq Delivery";
818             }
819         }
820         else {
821             flags="Class 2 Invld";
822         }
823
824         proto_tree_add_bytes_format_value(elp_tree, hf_swils_elp_cls2_svcp, tvb, offset, 2,
825                                     &elp.cls2_svcparm[0],
826                                     "(%s)", flags);
827         offset += 2;
828
829         if (elp.cls2_svcparm[0] & 0x80) {
830             proto_tree_add_item(elp_tree, hf_swils_elp_cls2_rcvsz, tvb, offset, 2, ENC_BIG_ENDIAN);
831         }
832         offset += 2;
833
834         if (elp.cls3_svcparm[0] & 0x80) {
835             if (elp.cls3_svcparm[0] & 0x08) {
836                 flags="Class 3 Valid | Seq Delivery";
837             }
838             else {
839                 flags="Class 3 Valid | No Seq Delivery";
840             }
841         }
842         else {
843             flags="Class 3 Invld";
844         }
845         proto_tree_add_bytes_format_value(elp_tree, hf_swils_elp_cls3_svcp, tvb, offset, 2,
846                                     &elp.cls3_svcparm[0],
847                                     "(%s)", flags);
848         offset += 2;
849
850         if (elp.cls3_svcparm[0] & 0x80) {
851             proto_tree_add_item(elp_tree, hf_swils_elp_cls3_rcvsz, tvb, offset, 2, ENC_BIG_ENDIAN);
852         }
853         offset += 22;
854
855         proto_tree_add_string(elp_tree, hf_swils_elp_isl_fc_mode, tvb, offset, 2,
856                               val_to_str_const(elp.isl_flwctrl_mode, fcswils_elp_fc_val, "Vendor Unique"));
857         offset += 2;
858         proto_tree_add_item(elp_tree, hf_swils_elp_fcplen, tvb, offset, 2, ENC_BIG_ENDIAN);
859         offset += 2;
860         proto_tree_add_item(elp_tree, hf_swils_elp_b2bcredit, tvb, offset, 4, ENC_BIG_ENDIAN);
861         offset += 4;
862         proto_tree_add_item(elp_tree, hf_swils_elp_compat1, tvb, offset, 4, ENC_BIG_ENDIAN);
863         offset += 4;
864         proto_tree_add_item(elp_tree, hf_swils_elp_compat2, tvb, offset, 4, ENC_BIG_ENDIAN);
865         offset += 4;
866         proto_tree_add_item(elp_tree, hf_swils_elp_compat3, tvb, offset, 4, ENC_BIG_ENDIAN);
867         offset += 4;
868         proto_tree_add_item(elp_tree, hf_swils_elp_compat4, tvb, offset, 4, ENC_BIG_ENDIAN);
869     }
870
871 }
872
873 static void
874 dissect_swils_efp(tvbuff_t *tvb, packet_info* pinfo, proto_tree *efp_tree, guint8 isreq _U_)
875 {
876
877 /* Set up structures needed to add the protocol subtree and manage it */
878     proto_tree  *lrec_tree;
879     proto_item  *rec_item;
880     int          num_listrec = 0;
881     int          offset      = 0;
882     fcswils_efp  efp;
883     guint8       rec_type;
884
885     offset += 1;
886     efp.reclen = tvb_get_guint8(tvb, offset);
887     rec_item = proto_tree_add_uint(efp_tree, hf_swils_efp_record_len, tvb, offset, 1, efp.reclen);
888     offset += 1;
889     efp.payload_len = tvb_get_ntohs(tvb, offset);
890     if (efp.payload_len < FC_SWILS_EFP_SIZE) {
891         proto_tree_add_uint_format_value(efp_tree, hf_swils_efp_payload_len,
892                                        tvb, offset, 2, efp.payload_len,
893                                        "%u (bogus, must be >= %u)",
894                                        efp.payload_len, FC_SWILS_EFP_SIZE);
895         return;
896     }
897     proto_tree_add_item(efp_tree, hf_swils_efp_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN);
898     offset += 5;       /* skip 3 reserved bytes, too */
899     proto_tree_add_item(efp_tree, hf_swils_efp_pswitch_pri, tvb,
900                             offset, 1, ENC_BIG_ENDIAN);
901     offset += 1;
902     tvb_memcpy(tvb, efp.pswitch_name, offset, 8);
903     proto_tree_add_string(efp_tree, hf_swils_efp_pswitch_name, tvb, offset,
904                               8, fcwwn_to_str(efp.pswitch_name));
905     offset += 8;
906
907     if (efp.reclen == 0) {
908         expert_add_info(pinfo, rec_item, &ei_swils_efp_record_len);
909         return;
910     }
911     /* Add List Records now */
912     if (efp_tree) {
913         num_listrec = (efp.payload_len - FC_SWILS_EFP_SIZE)/efp.reclen;
914         while (num_listrec-- > 0) {
915             rec_type = tvb_get_guint8(tvb, offset);
916             lrec_tree = proto_tree_add_subtree(efp_tree, tvb, offset, -1,
917                                         ett_fcswils_efplist, NULL,
918                                         val_to_str(rec_type,
919                                                    fcswils_rectype_val,
920                                                    "Unknown record type (0x%02x)"));
921             proto_tree_add_uint(lrec_tree, hf_swils_efp_rec_type, tvb, offset, 1,
922                                 rec_type);
923             switch (rec_type) {
924
925             case FC_SWILS_LRECTYPE_DOMAIN:
926                 proto_tree_add_item(lrec_tree, hf_swils_efp_dom_id, tvb, offset+1, 1, ENC_BIG_ENDIAN);
927                 proto_tree_add_string(lrec_tree, hf_swils_efp_switch_name, tvb, offset+8, 8,
928                                       tvb_fcwwn_to_str(tvb, offset+8));
929                 break;
930
931             case FC_SWILS_LRECTYPE_MCAST:
932                 proto_tree_add_item(lrec_tree, hf_swils_efp_mcast_grpno, tvb, offset+1, 1, ENC_BIG_ENDIAN);
933                 break;
934             }
935             offset += efp.reclen;
936         }
937     }
938 }
939
940 static void
941 dissect_swils_dia(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *dia_tree, guint8 isreq _U_)
942 {
943     /* Set up structures needed to add the protocol subtree and manage it */
944     int offset = 0;
945
946     if (dia_tree) {
947         proto_tree_add_string(dia_tree, hf_swils_dia_switch_name, tvb, offset+4,
948                               8, tvb_fcwwn_to_str(tvb, offset+4));
949     }
950 }
951
952 static void
953 dissect_swils_rdi(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *rdi_tree, guint8 isreq)
954 {
955     /* Set up structures needed to add the protocol subtree and manage it */
956     int offset = 0;
957     int i, plen, numrec;
958
959     if (rdi_tree) {
960         plen = tvb_get_ntohs(tvb, offset+2);
961
962         proto_tree_add_item(rdi_tree, hf_swils_rdi_payload_len, tvb, offset+2, 2, ENC_BIG_ENDIAN);
963         proto_tree_add_string(rdi_tree, hf_swils_rdi_req_sname, tvb, offset+4,
964                               8, tvb_fcwwn_to_str(tvb, offset+4));
965
966         /* 12 is the length of the initial header and 4 is the size of each
967          * domain request record.
968          */
969         numrec = (plen - 12)/4;
970         offset = 12;
971         for (i = 0; i < numrec; i++) {
972             if (isreq) {
973                 proto_tree_add_item(rdi_tree, hf_swils_requested_domain_id, tvb, offset+3, 1, ENC_BIG_ENDIAN);
974             }
975             else {
976                 proto_tree_add_item(rdi_tree, hf_swils_granted_domain_id, tvb, offset+3, 1, ENC_BIG_ENDIAN);
977             }
978             offset += 4;
979         }
980     }
981 }
982
983 static void
984 dissect_swils_fspf_hdr(tvbuff_t *tvb, proto_tree *tree, int offset)
985 {
986     proto_tree *fspfh_tree;
987
988     if (tree) {
989         /* 20 is the size of FSPF header */
990         fspfh_tree = proto_tree_add_subtree(tree, tvb, offset, 20, ett_fcswils_fspfhdr, NULL, "FSPF Header");
991
992         proto_tree_add_item(fspfh_tree, hf_swils_fspfh_rev, tvb, offset+4,
993                             1, ENC_BIG_ENDIAN);
994         proto_tree_add_item(fspfh_tree, hf_swils_fspfh_ar_num, tvb,
995                             offset+5, 1, ENC_BIG_ENDIAN);
996         proto_tree_add_item(fspfh_tree, hf_swils_fspfh_auth_type, tvb,
997                             offset+6, 1, ENC_BIG_ENDIAN);
998         proto_tree_add_item(fspfh_tree, hf_swils_fspfh_dom_id, tvb, offset+11,
999                             1, ENC_BIG_ENDIAN);
1000         proto_tree_add_item(fspfh_tree, hf_swils_fspfh_auth, tvb, offset+12,
1001                             8, ENC_NA);
1002     }
1003 }
1004
1005 static void
1006 dissect_swils_fspf_lsrechdr(tvbuff_t *tvb, proto_tree *tree, int offset)
1007 {
1008     proto_tree_add_item(tree, hf_swils_lsrh_lsr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1009     proto_tree_add_uint_format_value(tree, hf_swils_lsrh_lsr_age, tvb, offset+2, 2,
1010                         tvb_get_ntohs(tvb, offset+2), "%d secs", tvb_get_ntohs(tvb, offset+2));
1011     proto_tree_add_item(tree, hf_swils_lsrh_options, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1012     proto_tree_add_item(tree, hf_swils_lsrh_lsid, tvb, offset+11, 1, ENC_BIG_ENDIAN);
1013     proto_tree_add_item(tree, hf_swils_lsrh_adv_domid, tvb, offset+15, 1, ENC_BIG_ENDIAN);
1014     proto_tree_add_item(tree, hf_swils_lsrh_ls_incid, tvb, offset+16, 4, ENC_BIG_ENDIAN);
1015     proto_tree_add_item(tree, hf_swils_lsrh_checksum, tvb, offset+20, 2, ENC_BIG_ENDIAN);
1016     proto_tree_add_item(tree, hf_swils_lsrh_lsr_length, tvb, offset+22, 2, ENC_BIG_ENDIAN);
1017 }
1018
1019 static void
1020 dissect_swils_fspf_ldrec(tvbuff_t *tvb, proto_tree *tree, int offset)
1021 {
1022     proto_tree_add_string(tree, hf_swils_ldrec_linkid, tvb, offset, 4,
1023                           tvb_fc_to_str(tvb, offset+1));
1024     proto_tree_add_item(tree, hf_swils_ldrec_out_pidx, tvb, offset+5, 3, ENC_BIG_ENDIAN);
1025     proto_tree_add_item(tree, hf_swils_ldrec_nbr_pidx, tvb, offset+9, 3, ENC_BIG_ENDIAN);
1026     proto_tree_add_item(tree, hf_swils_ldrec_link_type, tvb, offset+12, 1, ENC_BIG_ENDIAN);
1027     proto_tree_add_item(tree, hf_swils_ldrec_link_cost, tvb, offset+14, 2, ENC_BIG_ENDIAN);
1028 }
1029
1030 static void
1031 dissect_swils_fspf_lsrec(tvbuff_t *tvb, proto_tree *tree, int offset,
1032                          int num_lsrec)
1033 {
1034     int         i, j, num_ldrec;
1035     proto_tree *lsrec_tree, *ldrec_tree, *lsrechdr_tree;
1036
1037     if (tree) {
1038         for (j = 0; j < num_lsrec; j++) {
1039             num_ldrec = tvb_get_ntohs(tvb, offset+26);
1040             lsrec_tree = proto_tree_add_subtree_format(tree, tvb, offset, (28+num_ldrec*16),
1041                                         ett_fcswils_lsrec, NULL, "Link State Record %d (Domain %d)", j,
1042                                         tvb_get_guint8(tvb, offset+15));
1043
1044             lsrechdr_tree = proto_tree_add_subtree(lsrec_tree, tvb, offset, 24,
1045                                         ett_fcswils_lsrechdr, NULL, "Link State Record Header");
1046
1047             dissect_swils_fspf_lsrechdr(tvb, lsrechdr_tree, offset);
1048             proto_tree_add_item(tree, hf_swils_lsrec_number_of_links, tvb, offset+26, 2, ENC_BIG_ENDIAN);
1049             offset += 28;
1050
1051             for (i = 0; i < num_ldrec; i++) {
1052                 ldrec_tree = proto_tree_add_subtree_format(lsrec_tree, tvb, offset, 16,
1053                                              ett_fcswils_ldrec, NULL, "Link Descriptor %d "
1054                                              "(Neighbor domain %d)", i,
1055                                              tvb_get_guint8(tvb, offset+3));
1056                 dissect_swils_fspf_ldrec(tvb, ldrec_tree, offset);
1057                 offset += 16;
1058             }
1059         }
1060     }
1061 }
1062
1063 static void
1064 dissect_swils_hello(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *hlo_tree, guint8 isreq _U_)
1065 {
1066     /* Set up structures needed to add the protocol subtree and manage it */
1067     int offset = 0;
1068
1069     if (hlo_tree) {
1070         dissect_swils_fspf_hdr(tvb, hlo_tree, offset);
1071
1072         proto_tree_add_item(hlo_tree, hf_swils_hlo_options, tvb, offset+20, 4, ENC_NA);
1073         proto_tree_add_item(hlo_tree, hf_swils_hlo_hloint, tvb, offset+24, 4, ENC_BIG_ENDIAN);
1074         proto_tree_add_item(hlo_tree, hf_swils_hlo_deadint, tvb, offset+28, 4, ENC_BIG_ENDIAN);
1075         proto_tree_add_item(hlo_tree, hf_swils_hlo_rcv_domid, tvb, offset+35, 1, ENC_BIG_ENDIAN);
1076         proto_tree_add_item(hlo_tree, hf_swils_hlo_orig_pidx, tvb, offset+37, 3, ENC_BIG_ENDIAN);
1077     }
1078 }
1079
1080 static void
1081 dissect_swils_lsupdate(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *lsu_tree, guint8 isreq _U_)
1082 {
1083     /* Set up structures needed to add the protocol subtree and manage it */
1084     int offset = 0;
1085     int num_lsrec;
1086
1087     if (lsu_tree) {
1088         dissect_swils_fspf_hdr(tvb, lsu_tree, offset);
1089
1090         proto_tree_add_item(lsu_tree, hf_swils_lsupdate_flags, tvb, offset+23, 1, ENC_BIG_ENDIAN);
1091         num_lsrec = tvb_get_ntohl(tvb, offset+24);
1092
1093         proto_tree_add_item(lsu_tree, hf_swils_lsupdate_num_of_lsrs, tvb, offset+24, 4, ENC_BIG_ENDIAN);
1094
1095         offset = 28;
1096         dissect_swils_fspf_lsrec(tvb, lsu_tree, offset, num_lsrec);
1097     }
1098 }
1099
1100 static void
1101 dissect_swils_lsack(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *lsa_tree, guint8 isreq _U_)
1102 {
1103     /* Set up structures needed to add the protocol subtree and manage it */
1104     int         offset = 0;
1105     int         num_lsrechdr, i;
1106     proto_tree *lsrechdr_tree;
1107
1108     if (lsa_tree) {
1109         dissect_swils_fspf_hdr(tvb, lsa_tree, offset);
1110
1111         proto_tree_add_item(lsa_tree, hf_swils_lsack_flags, tvb, offset+23, 1, ENC_BIG_ENDIAN);
1112         num_lsrechdr = tvb_get_ntohl(tvb, offset+24);
1113
1114         proto_tree_add_item(lsa_tree, hf_swils_lsack_num_of_lsr_headers, tvb, offset+24, 4, ENC_BIG_ENDIAN);
1115
1116         offset = 28;
1117
1118         for (i = 0; i < num_lsrechdr; i++) {
1119             lsrechdr_tree = proto_tree_add_subtree_format(lsa_tree, tvb, offset, 24,
1120                                         ett_fcswils_lsrechdr, NULL, "Link State Record Header (Domain %d)",
1121                                         tvb_get_guint8(tvb, offset+15));
1122             dissect_swils_fspf_lsrechdr(tvb, lsrechdr_tree, offset);
1123             offset += 24;
1124         }
1125     }
1126 }
1127
1128 static void
1129 dissect_swils_rscn(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *rscn_tree, guint8 isreq)
1130 {
1131     /* Set up structures needed to add the protocol subtree and manage it */
1132     int         offset = 0;
1133     proto_tree *dev_tree;
1134     int         numrec, i;
1135
1136     if (rscn_tree) {
1137         if (!isreq)
1138             return;
1139
1140         proto_tree_add_item(rscn_tree, hf_swils_rscn_evtype, tvb, offset+4,
1141                             1, ENC_BIG_ENDIAN);
1142         proto_tree_add_item(rscn_tree, hf_swils_rscn_addrfmt, tvb, offset+4,
1143                             1, ENC_BIG_ENDIAN);
1144         proto_tree_add_string(rscn_tree, hf_swils_rscn_affectedport, tvb,
1145                               offset+5, 3, tvb_fc_to_str(tvb, offset+5));
1146         proto_tree_add_item(rscn_tree, hf_swils_rscn_detectfn, tvb,
1147                             offset+8, 4, ENC_BIG_ENDIAN);
1148         numrec = tvb_get_ntohl(tvb, offset+12);
1149
1150         if (!tvb_bytes_exist(tvb, offset+16, FC_SWILS_RSCN_DEVENTRY_SIZE*numrec)) {
1151             /* Some older devices do not include device entry information. */
1152             return;
1153         }
1154
1155         proto_tree_add_item(rscn_tree, hf_swils_rscn_num_entries, tvb, offset+12, 4, ENC_BIG_ENDIAN);
1156
1157         offset = 16;
1158         for (i = 0; i < numrec; i++) {
1159             dev_tree = proto_tree_add_subtree_format(rscn_tree, tvb, offset, 20,
1160                                         ett_fcswils_rscn_dev, NULL, "Device Entry %d", i);
1161
1162             proto_tree_add_item(dev_tree, hf_swils_rscn_portstate, tvb, offset, 1, ENC_BIG_ENDIAN);
1163             proto_tree_add_string(dev_tree, hf_swils_rscn_portid, tvb, offset+1, 3,
1164                                   tvb_fc_to_str(tvb, offset+1));
1165             proto_tree_add_string(dev_tree, hf_swils_rscn_pwwn, tvb, offset+4, 8,
1166                                   tvb_fcwwn_to_str(tvb, offset+4));
1167             proto_tree_add_string(dev_tree, hf_swils_rscn_nwwn, tvb, offset+12, 8,
1168                                   tvb_fcwwn_to_str(tvb, offset+12));
1169             offset += 20;
1170         }
1171     }
1172 }
1173
1174 /*
1175  * Merge Request contains zoning objects organized in the following format:
1176  *
1177  * Zone Set Object
1178  *      |
1179  *      +---------------- Zone Object
1180  *      |                      |
1181  *      +--                    +---------------- Zone Member
1182  *      |                      |                     |
1183  *      +--                    +----                 +-----
1184  *
1185  * So the decoding of the zone merge request is based on this structure
1186  */
1187
1188 static void
1189 dissect_swils_zone_mbr(tvbuff_t *tvb, proto_tree *zmbr_tree, int offset)
1190 {
1191     guint8  mbrtype;
1192     int     idlen;
1193     char    dpbuf[2+8+1];
1194     char   *str;
1195
1196     mbrtype = tvb_get_guint8(tvb, offset);
1197     proto_tree_add_uint(zmbr_tree, hf_swils_zone_mbrtype, tvb,
1198                         offset, 1, mbrtype);
1199     proto_tree_add_item(zmbr_tree, hf_swils_zone_mbrflags, tvb, offset+2, 1, ENC_BIG_ENDIAN);
1200     idlen = tvb_get_guint8(tvb, offset+3);
1201     proto_tree_add_item(zmbr_tree, hf_swils_zone_mbr_identifier_length, tvb, offset+3, 1, ENC_BIG_ENDIAN);
1202     switch (mbrtype) {
1203     case FC_SWILS_ZONEMBR_WWN:
1204         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1205                               offset+4, 8,
1206                               tvb_fcwwn_to_str(tvb, offset+4));
1207         break;
1208     case FC_SWILS_ZONEMBR_DP:
1209         g_snprintf(dpbuf, sizeof(dpbuf), "0x%08x", tvb_get_ntohl(tvb, offset+4));
1210         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1211                               offset+4, 4, dpbuf);
1212         break;
1213     case FC_SWILS_ZONEMBR_FCID:
1214         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1215                               offset+4, 4,
1216                               tvb_fc_to_str(tvb, offset+5));
1217         break;
1218     case FC_SWILS_ZONEMBR_ALIAS:
1219         str = zonenm_to_str(tvb, offset+4);
1220         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1221                               offset+4, idlen, str);
1222         break;
1223     case FC_SWILS_ZONEMBR_WWN_LUN:
1224         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1225                               offset+4, 8,
1226                               tvb_fcwwn_to_str(tvb, offset+4));
1227         proto_tree_add_item(zmbr_tree, hf_swils_zone_mbrid_lun, tvb,
1228                             offset+12, 8, ENC_NA);
1229         break;
1230     case FC_SWILS_ZONEMBR_DP_LUN:
1231         g_snprintf(dpbuf, sizeof(dpbuf), "0x%08x", tvb_get_ntohl(tvb, offset+4));
1232         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1233                               offset+4, 4, dpbuf);
1234         proto_tree_add_item(zmbr_tree, hf_swils_zone_mbrid_lun, tvb,
1235                             offset+8, 8, ENC_NA);
1236         break;
1237     case FC_SWILS_ZONEMBR_FCID_LUN:
1238         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1239                               offset+4, 4,
1240                               tvb_fc_to_str(tvb, offset+5));
1241         proto_tree_add_item(zmbr_tree, hf_swils_zone_mbrid_lun, tvb,
1242                             offset+8, 8, ENC_NA);
1243         break;
1244     default:
1245         proto_tree_add_string(zmbr_tree, hf_swils_zone_mbrid, tvb,
1246                               offset+4, idlen,
1247                               "Unknown member type format");
1248
1249     }
1250 }
1251
1252 static void
1253 dissect_swils_zone_obj(tvbuff_t *tvb, proto_tree *zobj_tree, int offset)
1254 {
1255     proto_tree *zmbr_tree;
1256     int         mbrlen, numrec, i, objtype;
1257     char       *str;
1258
1259     objtype = tvb_get_guint8(tvb, offset);
1260
1261     proto_tree_add_item(zobj_tree, hf_swils_zone_objtype, tvb, offset,
1262                         1, ENC_BIG_ENDIAN);
1263     proto_tree_add_item(zobj_tree, hf_swils_zone_protocol, tvb,
1264                         offset+1, 1, ENC_BIG_ENDIAN);
1265     str = zonenm_to_str(tvb, offset+4);
1266     proto_tree_add_string(zobj_tree, hf_swils_zone_objname, tvb,
1267                           offset+4, ZONENAME_LEN(tvb, offset+4), str);
1268
1269     numrec = tvb_get_ntohl(tvb, offset+4+ZONENAME_LEN(tvb, offset+4));
1270     proto_tree_add_item(zobj_tree, hf_swils_zone_num_members, tvb, offset+4+ZONENAME_LEN(tvb,offset+4), 4, ENC_BIG_ENDIAN);
1271
1272     offset += 8 + ZONENAME_LEN(tvb, offset+4);
1273     for (i = 0; i < numrec; i++) {
1274         if (objtype == FC_SWILS_ZONEOBJ_ZONESET) {
1275             dissect_swils_zone_obj(tvb, zobj_tree, offset);
1276             offset += get_zoneobj_len(tvb, offset);
1277         }
1278         else {
1279             mbrlen = 4 + tvb_get_guint8(tvb, offset+3);
1280             zmbr_tree = proto_tree_add_subtree_format(zobj_tree, tvb, offset, mbrlen,
1281                                         ett_fcswils_zonembr, NULL, "Zone Member %d", i);
1282             dissect_swils_zone_mbr(tvb, zmbr_tree, offset);
1283             offset += mbrlen;
1284         }
1285     }
1286 }
1287
1288 static void
1289 dissect_swils_mergereq(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *mr_tree, guint8 isreq)
1290 {
1291     /* Set up structures needed to add the protocol subtree and manage it */
1292     int         offset = 0;
1293     proto_tree *zobjlist_tree, *zobj_tree;
1294     int         numrec, i, zonesetlen, objlistlen, objlen;
1295     char       *str;
1296
1297     if (mr_tree) {
1298         if (isreq) {
1299             /* zonesetlen is the size of the zoneset including the zone name */
1300             zonesetlen = tvb_get_ntohs(tvb, offset+2);
1301             proto_tree_add_item(mr_tree, hf_swils_zone_active_zoneset_length, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1302
1303             if (zonesetlen) {
1304                 str = zonenm_to_str(tvb, offset+4);
1305                 proto_tree_add_string(mr_tree, hf_swils_zone_activezonenm, tvb,
1306                                       offset+4, ZONENAME_LEN(tvb, offset+4),
1307                                       str);
1308
1309                 /* objlistlen gives the size of the active zoneset object list */
1310                 objlistlen = zonesetlen - ZONENAME_LEN(tvb, offset+4);
1311                 /* Offset = start of the active zoneset zoning object list */
1312                 offset = offset + (4 + ZONENAME_LEN(tvb, offset+4));
1313                 numrec = tvb_get_ntohl(tvb, offset);
1314
1315                 zobjlist_tree = proto_tree_add_subtree(mr_tree, tvb, offset, objlistlen,
1316                                             ett_fcswils_zoneobjlist, NULL, "Active Zone Set");
1317
1318                 proto_tree_add_item(zobjlist_tree, hf_swils_zone_num_zoning_objects, tvb, offset, 4, ENC_BIG_ENDIAN);
1319
1320                 offset += 4;
1321                 for (i = 0; i < numrec; i++) {
1322                     objlen = get_zoneobj_len(tvb, offset);
1323                     zobj_tree = proto_tree_add_subtree_format(zobjlist_tree, tvb, offset+4, objlen,
1324                                                 ett_fcswils_zoneobj, NULL, "Zone Object %d", i);
1325                     dissect_swils_zone_obj(tvb, zobj_tree, offset);
1326                     offset += objlen;
1327                 }
1328             }
1329             else {
1330                 offset += 4;
1331             }
1332
1333             zonesetlen = tvb_get_ntohl(tvb, offset);
1334             proto_tree_add_item(mr_tree, hf_swils_zone_full_zone_set_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1335
1336             if (zonesetlen) {
1337                 objlistlen = zonesetlen;
1338                 /* Offset = start of the active zoneset zoning object list */
1339                 offset += 4;
1340                 numrec = tvb_get_ntohl(tvb, offset);
1341
1342                 zobjlist_tree = proto_tree_add_subtree(mr_tree, tvb, offset, objlistlen,
1343                                             ett_fcswils_zoneobjlist, NULL, "Full Zone Set");
1344
1345                 proto_tree_add_item(zobjlist_tree, hf_swils_zone_num_zoning_objects, tvb, offset, 4, ENC_BIG_ENDIAN);
1346                 offset += 4;
1347                 for (i = 0; i < numrec; i++) {
1348                     objlen = get_zoneobj_len(tvb, offset);
1349                     zobj_tree = proto_tree_add_subtree_format(zobjlist_tree, tvb, offset,
1350                                                 objlen, ett_fcswils_zoneobj, NULL, "Zone Object %d", i);
1351                     dissect_swils_zone_obj(tvb, zobj_tree, offset);
1352                     offset += objlen;
1353                 }
1354             }
1355         }
1356         else {
1357             proto_tree_add_item(mr_tree, hf_swils_zone_status, tvb,
1358                                 offset+5, 1, ENC_BIG_ENDIAN);
1359             proto_tree_add_item(mr_tree, hf_swils_zone_reason, tvb,
1360                                 offset+6, 1, ENC_BIG_ENDIAN);
1361             proto_tree_add_item(mr_tree, hf_swils_zone_vendor_unique, tvb, offset+7, 1, ENC_BIG_ENDIAN);
1362         }
1363     }
1364 }
1365
1366 static void
1367 dissect_swils_aca(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *aca_tree, guint8 isreq)
1368 {
1369     /* Set up structures needed to add the protocol subtree and manage it */
1370     int offset = 0;
1371     int numrec, plen, i;
1372
1373     if (aca_tree) {
1374         if (isreq) {
1375             plen = tvb_get_ntohs(tvb, offset+2);
1376             proto_tree_add_item(aca_tree, hf_swils_domain_id_list_length, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1377             numrec = plen/4;
1378             offset = 4;
1379
1380             for (i = 0; i < numrec; i++) {
1381                 proto_tree_add_uint_format(aca_tree, hf_swils_aca_domainid,
1382                                            tvb, offset+3, 1,
1383                                            tvb_get_guint8(tvb, offset+3),
1384                                            "Domain ID %d: %d", i,
1385                                            tvb_get_guint8(tvb, offset+3));
1386                 offset += 4;
1387             }
1388         }
1389         else {
1390             proto_tree_add_item(aca_tree, hf_swils_zone_status, tvb,
1391                                 offset+5, 1, ENC_BIG_ENDIAN);
1392             proto_tree_add_item(aca_tree, hf_swils_zone_reason, tvb,
1393                                 offset+6, 1, ENC_BIG_ENDIAN);
1394             proto_tree_add_item(aca_tree, hf_swils_zone_vendor_unique, tvb, offset+7, 1, ENC_BIG_ENDIAN);
1395         }
1396     }
1397 }
1398
1399 static void
1400 dissect_swils_rca(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *rca_tree, guint8 isreq)
1401 {
1402     /* Set up structures needed to add the protocol subtree and manage it */
1403     int offset = 0;
1404
1405     if (rca_tree) {
1406         if (!isreq) {
1407             proto_tree_add_item(rca_tree, hf_swils_zone_status, tvb,
1408                                 offset+5, 1, ENC_BIG_ENDIAN);
1409             proto_tree_add_item(rca_tree, hf_swils_zone_reason, tvb,
1410                                 offset+6, 1, ENC_BIG_ENDIAN);
1411             proto_tree_add_item(rca_tree, hf_swils_zone_vendor_unique, tvb, offset+7, 1, ENC_BIG_ENDIAN);
1412         }
1413     }
1414 }
1415
1416 static void
1417 dissect_swils_sfc(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *sfc_tree, guint8 isreq)
1418 {
1419     /* Set up structures needed to add the protocol subtree and manage it */
1420     int         offset = 0;
1421     proto_tree *zobjlist_tree, *zobj_tree;
1422     int         numrec, i, zonesetlen, objlistlen, objlen;
1423     char       *str;
1424
1425     if (sfc_tree) {
1426         if (isreq) {
1427             proto_tree_add_item(sfc_tree, hf_swils_sfc_opcode, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1428
1429             zonesetlen = tvb_get_ntohs(tvb, offset+2);
1430             proto_tree_add_item(sfc_tree, hf_swils_sfc_zoneset_length, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1431
1432             if (zonesetlen) {
1433                 str = zonenm_to_str(tvb, offset+4);
1434                 proto_tree_add_string(sfc_tree, hf_swils_sfc_zonenm, tvb,
1435                                       offset+4, ZONENAME_LEN(tvb, offset+4),
1436                                       str);
1437
1438                 /* objlistlen gives the size of the active zoneset object list */
1439                 objlistlen = zonesetlen - ZONENAME_LEN(tvb, offset+4);
1440                 /* Offset = start of the active zoneset zoning object list */
1441                 offset = offset + (4 + ZONENAME_LEN(tvb, offset+4));
1442                 numrec = tvb_get_ntohl(tvb, offset);
1443
1444                 zobjlist_tree = proto_tree_add_subtree(sfc_tree, tvb, offset, objlistlen,
1445                                             ett_fcswils_zoneobjlist, NULL, "Zone Set");
1446
1447                 proto_tree_add_item(zobjlist_tree, hf_swils_zone_num_zoning_objects, tvb, offset, 4, ENC_BIG_ENDIAN);
1448
1449                 offset += 4;
1450                 for (i = 0; i < numrec; i++) {
1451                     objlen = get_zoneobj_len(tvb, offset);
1452                     zobj_tree = proto_tree_add_subtree_format(zobjlist_tree, tvb, offset, objlen,
1453                                                 ett_fcswils_zoneobj, NULL, "Zone Object %d", i);
1454                     dissect_swils_zone_obj(tvb, zobj_tree, offset);
1455                     offset += objlen;
1456                 }
1457             }
1458             else {
1459                 offset += 4;
1460             }
1461
1462             zonesetlen = tvb_get_ntohl(tvb, offset);
1463             proto_tree_add_item(sfc_tree, hf_swils_zone_full_zone_set_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1464
1465             if (zonesetlen) {
1466                 objlistlen = zonesetlen;
1467                 /* Offset = start of the active zoneset zoning object list */
1468                 offset += 4;
1469                 numrec = tvb_get_ntohl(tvb, offset);
1470
1471                 zobjlist_tree = proto_tree_add_subtree(sfc_tree, tvb, offset, objlistlen,
1472                                             ett_fcswils_zoneobjlist, NULL, "Full Zone Set");
1473
1474                 proto_tree_add_item(zobjlist_tree, hf_swils_zone_num_zoning_objects, tvb, offset, 4, ENC_BIG_ENDIAN);
1475                 offset += 4;
1476                 for (i = 0; i < numrec; i++) {
1477                     objlen = get_zoneobj_len(tvb, offset);
1478                     zobj_tree = proto_tree_add_subtree_format(zobjlist_tree, tvb, offset, objlen,
1479                                                 ett_fcswils_zoneobj, NULL, "Zone Object %d", i);
1480                     dissect_swils_zone_obj(tvb, zobj_tree, offset);
1481                     offset += objlen;
1482                 }
1483             }
1484         }
1485         else {
1486             proto_tree_add_item(sfc_tree, hf_swils_zone_status, tvb,
1487                                 offset+5, 1, ENC_BIG_ENDIAN);
1488             proto_tree_add_item(sfc_tree, hf_swils_zone_reason, tvb,
1489                                 offset+6, 1, ENC_BIG_ENDIAN);
1490             proto_tree_add_item(sfc_tree, hf_swils_zone_vendor_unique, tvb, offset+7, 1, ENC_BIG_ENDIAN);
1491         }
1492     }
1493 }
1494
1495 static void
1496 dissect_swils_ufc(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *ufc_tree, guint8 isreq)
1497 {
1498     /* Set up structures needed to add the protocol subtree and manage it */
1499     int offset = 0;
1500
1501     if (ufc_tree) {
1502         if (!isreq) {
1503             proto_tree_add_item(ufc_tree, hf_swils_zone_status, tvb,
1504                                 offset+5, 1, ENC_BIG_ENDIAN);
1505             proto_tree_add_item(ufc_tree, hf_swils_zone_reason, tvb,
1506                                 offset+6, 1, ENC_BIG_ENDIAN);
1507             proto_tree_add_item(ufc_tree, hf_swils_zone_vendor_unique, tvb, offset+7, 1, ENC_BIG_ENDIAN);
1508         }
1509     }
1510 }
1511
1512 static void
1513 dissect_swils_esc(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *esc_tree, guint8 isreq)
1514 {
1515     /* Set up structures needed to add the protocol subtree and manage it */
1516     int         offset = 0;
1517     int         i, numrec, plen;
1518     proto_tree *pdesc_tree;
1519
1520     if (esc_tree) {
1521         if (isreq) {
1522             plen = tvb_get_ntohs(tvb, offset+2);
1523             proto_tree_add_item(esc_tree, hf_swils_esc_payload_length, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1524             proto_tree_add_item(esc_tree, hf_swils_esc_swvendorid, tvb,
1525                                 offset+4, 8, ENC_ASCII|ENC_NA);
1526             numrec = (plen - 12)/12;
1527             offset = 12;
1528
1529             for (i = 0; i < numrec; i++) {
1530                 pdesc_tree = proto_tree_add_subtree_format(esc_tree, tvb, offset, 12,
1531                                             ett_fcswils_esc_pdesc, NULL, "Protocol Descriptor %d", i);
1532                 proto_tree_add_item(pdesc_tree, hf_swils_esc_pdesc_vendorid, tvb,
1533                                     offset, 8, ENC_ASCII|ENC_NA);
1534                 proto_tree_add_item(pdesc_tree, hf_swils_esc_protocolid,
1535                                     tvb, offset+10, 2, ENC_BIG_ENDIAN);
1536                 offset += 12;
1537             }
1538         }
1539         else {
1540             proto_tree_add_item(esc_tree, hf_swils_esc_swvendorid, tvb,
1541                                 offset+4, 8, ENC_ASCII|ENC_NA);
1542             pdesc_tree = proto_tree_add_subtree(esc_tree, tvb, offset+12, 12,
1543                                         ett_fcswils_esc_pdesc, NULL, "Accepted Protocol Descriptor");
1544
1545             proto_tree_add_item(pdesc_tree, hf_swils_esc_pdesc_vendorid, tvb,
1546                                 offset+12, 8, ENC_ASCII|ENC_NA);
1547             proto_tree_add_item(pdesc_tree, hf_swils_esc_protocolid,
1548                                 tvb, offset+22, 2, ENC_BIG_ENDIAN);
1549         }
1550     }
1551 }
1552
1553 static void
1554 dissect_swils_drlir(tvbuff_t *tvb _U_, packet_info* pinfo _U_, proto_tree *drlir_tree _U_,
1555                     guint8 isreq _U_)
1556 {
1557     /* Set up structures needed to add the protocol subtree and manage it */
1558     return;
1559 }
1560
1561 static void
1562 dissect_swils_swrjt(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *swrjt_tree, guint8 isreq _U_)
1563 {
1564     /* Set up structures needed to add the protocol subtree and manage it */
1565     int offset = 0;
1566
1567     if (swrjt_tree) {
1568         proto_tree_add_item(swrjt_tree, hf_swils_rjt, tvb, offset+5, 1, ENC_BIG_ENDIAN);
1569         proto_tree_add_item(swrjt_tree, hf_swils_rjtdet, tvb, offset+6, 1, ENC_BIG_ENDIAN);
1570         proto_tree_add_item(swrjt_tree, hf_swils_rjtvendor, tvb, offset+7,
1571                             1, ENC_BIG_ENDIAN);
1572     }
1573 }
1574
1575 static void
1576 dissect_swils_ess(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *ess_tree, guint8 isreq _U_)
1577 {
1578     int         offset      = 0;
1579     gint16      numcapobj   = 0;
1580     gint        len         = 0;
1581     gint        capobjlen   = 0;
1582     proto_tree *ieinfo_tree;
1583
1584     if (!ess_tree) {
1585         return;
1586     }
1587
1588     proto_tree_add_item(ess_tree, hf_swils_ess_rev, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1589     proto_tree_add_item(ess_tree, hf_swils_ess_len, tvb, offset+8, 4, ENC_BIG_ENDIAN);
1590     len = tvb_get_ntohl(tvb, offset+8);
1591
1592     ieinfo_tree = proto_tree_add_subtree(ess_tree, tvb, offset+12,
1593                              MAX_INTERCONNECT_ELEMENT_INFO_LEN+4,
1594                              ett_fcswils_ieinfo, NULL, "Interconnect Element Info");
1595     dissect_swils_interconnect_element_info(tvb, ieinfo_tree, offset+12);
1596     len -= 256;                /* the interconnect obj above is 256 bytes */
1597     offset += 268;
1598
1599     proto_tree_add_item(ess_tree, hf_swils_ess_numobj, tvb, offset, 2, ENC_BIG_ENDIAN);
1600     numcapobj = tvb_get_ntohs(tvb, offset);
1601
1602     len -= 4;                  /* 2B numcapobj + 2B rsvd */
1603     offset += 4;
1604
1605     while ((len > 0) && (numcapobj > 0)) {
1606         capobjlen = dissect_swils_ess_capability_obj(tvb, ess_tree, offset);
1607         numcapobj--;
1608         len -= capobjlen;
1609         offset += capobjlen;
1610     }
1611 }
1612
1613 static void
1614 dissect_swils_mrra(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *tree, guint8 isreq)
1615 {
1616
1617     int offset = 0;
1618
1619     if (!tree) {
1620         return;
1621     }
1622
1623     if (isreq) {
1624         proto_tree_add_item(tree, hf_swils_mrra_rev, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1625         proto_tree_add_item(tree, hf_swils_mrra_size, tvb, offset+8, 4, ENC_BIG_ENDIAN);
1626         proto_tree_add_item(tree, hf_swils_mrra_vendorid, tvb, offset+12, 8, ENC_ASCII|ENC_NA);
1627         proto_tree_add_item(tree, hf_swils_mrra_vendorinfo, tvb, offset+20,
1628                             8, ENC_NA);
1629     } else {
1630         proto_tree_add_item(tree, hf_swils_mrra_vendorid, tvb, offset+4,
1631                             8, ENC_ASCII|ENC_NA);
1632         proto_tree_add_item(tree, hf_swils_mrra_reply, tvb, offset+12,
1633                             4, ENC_BIG_ENDIAN);
1634         proto_tree_add_item(tree, hf_swils_mrra_reply_size, tvb, offset+16,
1635                             4, ENC_BIG_ENDIAN);
1636         proto_tree_add_item(tree, hf_swils_mrra_waittime, tvb, offset+20,
1637                             4, ENC_BIG_ENDIAN);
1638     }
1639
1640
1641 }
1642
1643 static fcswils_func_table_t fcswils_func_table[FC_SWILS_MAXCODE] = {
1644     /* 0x00 */ {NULL},
1645     /* 0x01 */ {dissect_swils_swrjt},
1646     /* 0x02 */ {NULL},
1647     /* 0x03 */ {NULL},
1648     /* 0x04 */ {NULL},
1649     /* 0x05 */ {NULL},
1650     /* 0x06 */ {NULL},
1651     /* 0x07 */ {NULL},
1652     /* 0x08 */ {NULL},
1653     /* 0x09 */ {NULL},
1654     /* 0x0a */ {NULL},
1655     /* 0x0b */ {NULL},
1656     /* 0x0c */ {NULL},
1657     /* 0x0d */ {NULL},
1658     /* 0x0e */ {NULL},
1659     /* 0x0f */ {NULL},
1660     /* 0x10 */ {dissect_swils_elp},
1661     /* 0x11 */ {dissect_swils_efp},
1662     /* 0x12 */ {dissect_swils_dia},
1663     /* 0x13 */ {dissect_swils_rdi},
1664     /* 0x14 */ {dissect_swils_hello},
1665     /* 0x15 */ {dissect_swils_lsupdate},
1666     /* 0x16 */ {dissect_swils_lsack},
1667     /* 0x17 */ {dissect_swils_nullpayload},
1668     /* 0x18 */ {dissect_swils_nullpayload},
1669     /* 0x19 */ {NULL},
1670     /* 0x1a */ {NULL},
1671     /* 0x1b */ {dissect_swils_rscn},
1672     /* 0x1c */ {NULL},
1673     /* 0x1d */ {NULL},
1674     /* 0x1e */ {dissect_swils_drlir},
1675     /* 0x1f */ {NULL},
1676     /* 0x20 */ {NULL /*dissect_swils_dscn*/},
1677     /* 0x21 */ {NULL /*dissect_swils_loopd*/},
1678     /* 0x22 */ {dissect_swils_mergereq},
1679     /* 0x23 */ {dissect_swils_aca},
1680     /* 0x24 */ {dissect_swils_rca},
1681     /* 0x25 */ {dissect_swils_sfc},
1682     /* 0x26 */ {dissect_swils_ufc},
1683     /* 0x27 */ {NULL},
1684     /* 0x28 */ {NULL},
1685     /* 0x29 */ {NULL},
1686     /* 0x2a */ {NULL},
1687     /* 0x2b */ {NULL},
1688     /* 0x2c */ {NULL},
1689     /* 0x2d */ {NULL},
1690     /* 0x2e */ {NULL},
1691     /* 0x2f */ {NULL},
1692     /* 0x30 */ {dissect_swils_esc},
1693     /* 0x31 */ {dissect_swils_ess},
1694     /* 0x32 */ {NULL},
1695     /* 0x33 */ {NULL},
1696     /* 0x34 */ {dissect_swils_mrra}
1697 };
1698
1699 /* Code to actually dissect the packets */
1700 static int
1701 dissect_fcswils(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1702 {
1703     proto_item          *ti            = NULL;
1704     guint8               opcode;
1705     guint8               failed_opcode = 0;
1706     int                  offset        = 0;
1707     conversation_t      *conversation;
1708     fcswils_conv_data_t *cdata;
1709     fcswils_conv_key_t   ckey, *req_key;
1710     proto_tree          *swils_tree    = NULL;
1711     guint8               isreq         = FC_SWILS_REQ;
1712     tvbuff_t            *next_tvb;
1713     fc_hdr *fchdr;
1714
1715     /* Reject the packet if data is NULL */
1716     if (data == NULL)
1717         return 0;
1718     fchdr = (fc_hdr *)data;
1719
1720     /* Make entries in Protocol column and Info column on summary display */
1721     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SW_ILS");
1722
1723     /* decoding of this is done by each individual opcode handler */
1724     opcode = tvb_get_guint8(tvb, 0);
1725
1726     ti = proto_tree_add_protocol_format(tree, proto_fcswils, tvb, 0, -1, "SW_ILS");
1727     swils_tree = proto_item_add_subtree(ti, ett_fcswils);
1728
1729     /* Register conversation if this is not a response */
1730     if ((opcode != FC_SWILS_SWACC) && (opcode != FC_SWILS_SWRJT)) {
1731         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1732                                          pinfo->ptype, fchdr->oxid,
1733                                          fchdr->rxid, NO_PORT2);
1734         if (!conversation) {
1735             conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1736                                             pinfo->ptype, fchdr->oxid,
1737                                             fchdr->rxid, NO_PORT2);
1738         }
1739
1740         ckey.conv_idx = conversation->index;
1741
1742         cdata = (fcswils_conv_data_t *)g_hash_table_lookup(fcswils_req_hash,
1743                                                            &ckey);
1744         if (cdata) {
1745             /* Since we never free the memory used by an exchange, this maybe a
1746              * case of another request using the same exchange as a previous
1747              * req.
1748              */
1749             cdata->opcode = opcode;
1750         }
1751         else {
1752             req_key = wmem_new(wmem_file_scope(), fcswils_conv_key_t);
1753             req_key->conv_idx = conversation->index;
1754
1755             cdata = wmem_new(wmem_file_scope(), fcswils_conv_data_t);
1756             cdata->opcode = opcode;
1757
1758             g_hash_table_insert(fcswils_req_hash, req_key, cdata);
1759         }
1760     }
1761     else {
1762         /* Opcode is ACC or RJT */
1763         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1764                                          pinfo->ptype, fchdr->oxid,
1765                                          fchdr->rxid, NO_PORT2);
1766         isreq = FC_SWILS_RPLY;
1767         if (!conversation) {
1768             if (tree && (opcode == FC_SWILS_SWACC)) {
1769                 /* No record of what this accept is for. Can't decode */
1770                 proto_tree_add_expert_format(swils_tree, pinfo, &ei_swils_no_exchange, tvb, 0, -1, "No record of Exchg. Unable to decode SW_ACC");
1771                 return 0;
1772             }
1773         }
1774         else {
1775             ckey.conv_idx = conversation->index;
1776
1777             cdata = (fcswils_conv_data_t *)g_hash_table_lookup(fcswils_req_hash, &ckey);
1778
1779             if (cdata != NULL) {
1780                 if (opcode == FC_SWILS_SWACC)
1781                     opcode = cdata->opcode;
1782                 else
1783                     failed_opcode = cdata->opcode;
1784             }
1785
1786             if (tree) {
1787                 if ((cdata == NULL) && (opcode != FC_SWILS_SWRJT)) {
1788                     /* No record of what this accept is for. Can't decode */
1789                     proto_tree_add_expert_format(swils_tree, pinfo, &ei_swils_no_exchange, tvb, 0, -1, "No record of SW_ILS Req. Unable to decode SW_ACC");
1790                     return 0;
1791                 }
1792             }
1793         }
1794     }
1795
1796     if (isreq == FC_SWILS_REQ) {
1797         col_add_str(pinfo->cinfo, COL_INFO,
1798                     val_to_str(opcode, fc_swils_opcode_key_val, "0x%x"));
1799     }
1800     else if (opcode == FC_SWILS_SWRJT) {
1801         col_add_fstr(pinfo->cinfo, COL_INFO, "SW_RJT (%s)",
1802                         val_to_str(failed_opcode, fc_swils_opcode_key_val, "0x%x"));
1803     }
1804     else {
1805         col_add_fstr(pinfo->cinfo, COL_INFO, "SW_ACC (%s)",
1806                         val_to_str(opcode, fc_swils_opcode_key_val, "0x%x"));
1807     }
1808
1809     proto_tree_add_item(swils_tree, hf_swils_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
1810
1811     if ((opcode < FC_SWILS_MAXCODE) && fcswils_func_table[opcode].func) {
1812         fcswils_func_table[opcode].func(tvb, pinfo, swils_tree, isreq);
1813     } else if (opcode == FC_SWILS_AUTH_ILS) {
1814         /* This is treated differently */
1815         if (isreq && fcsp_handle)
1816             call_dissector(fcsp_handle, tvb, pinfo, swils_tree);
1817     } else {
1818         /* data dissector */
1819         next_tvb = tvb_new_subset_remaining(tvb, offset+4);
1820         call_dissector(data_handle, next_tvb, pinfo, tree);
1821     }
1822
1823     return tvb_length(tvb);
1824 }
1825
1826 /* Register the protocol with Wireshark */
1827
1828 void
1829 proto_register_fcswils(void)
1830 {
1831     static hf_register_info hf[] = {
1832         { &hf_swils_opcode,
1833           {"Cmd Code", "swils.opcode",
1834            FT_UINT8, BASE_HEX, VALS(fc_swils_opcode_key_val), 0x0,
1835            NULL, HFILL}},
1836
1837         { &hf_swils_elp_rev,
1838           {"Revision", "swils.elp.rev",
1839            FT_UINT8, BASE_DEC, NULL, 0x0,
1840            NULL, HFILL}},
1841
1842         { &hf_swils_elp_flags,
1843           {"Flag", "swils.elp.flag",
1844            FT_BYTES, BASE_NONE, NULL, 0x0,
1845            NULL, HFILL}},
1846
1847         { &hf_swils_elp_r_a_tov,
1848           {"R_A_TOV", "swils.elp.ratov",
1849            FT_UINT32, BASE_DEC, NULL, 0x0,
1850            NULL, HFILL}},
1851
1852         { &hf_swils_elp_e_d_tov,
1853           {"E_D_TOV", "swils.elp.edtov",
1854            FT_UINT32, BASE_DEC, NULL, 0x0,
1855            NULL, HFILL}},
1856
1857         { &hf_swils_elp_req_epn,
1858           {"Req Eport Name", "swils.elp.reqepn",
1859            FT_STRING, BASE_NONE, NULL, 0x0,
1860            NULL, HFILL}},
1861
1862         { &hf_swils_elp_req_esn,
1863           {"Req Switch Name", "swils.elp.reqesn",
1864            FT_STRING, BASE_NONE, NULL, 0x0,
1865            NULL, HFILL}},
1866
1867         { &hf_swils_elp_clsf_svcp,
1868           {"Class F Svc Parameters", "swils.elp.clsfp",
1869            FT_BYTES, BASE_NONE, NULL, 0x0,
1870            NULL, HFILL}},
1871
1872         { &hf_swils_elp_clsf_rcvsz,
1873           {"Max Class F Frame Size", "swils.elp.clsfrsz",
1874            FT_UINT16, BASE_DEC, NULL, 0x0,
1875            NULL, HFILL}},
1876
1877         { &hf_swils_elp_clsf_conseq,
1878           {"Class F Max Concurrent Seq", "swils.elp.clsfcs",
1879            FT_UINT16, BASE_DEC, NULL, 0x0,
1880            NULL, HFILL}},
1881
1882         { &hf_swils_elp_clsf_e2e,
1883           {"Class F E2E Credit", "swils.elp.cfe2e",
1884            FT_UINT16, BASE_DEC, NULL, 0x0,
1885            NULL, HFILL}},
1886
1887         { &hf_swils_elp_clsf_openseq,
1888           {"Class F Max Open Seq", "swils.elp.oseq",
1889            FT_UINT16, BASE_DEC, NULL, 0x0,
1890            NULL, HFILL}},
1891
1892         { &hf_swils_elp_cls1_svcp,
1893           {"Class 1 Svc Parameters", "swils.elp.cls1p",
1894            FT_BYTES, BASE_NONE, NULL, 0x0,
1895            NULL, HFILL}},
1896
1897         { &hf_swils_elp_cls1_rcvsz,
1898           {"Class 1 Frame Size", "swils.elp.cls1rsz",
1899            FT_UINT16, BASE_DEC, NULL, 0x0,
1900            NULL, HFILL}},
1901
1902         { &hf_swils_elp_cls2_svcp,
1903           {"Class 2 Svc Parameters", "swils.elp.cls2p",
1904            FT_BYTES, BASE_NONE, NULL, 0x0,
1905            NULL, HFILL}},
1906
1907         { &hf_swils_elp_cls2_rcvsz,
1908           {"Class 2 Frame Size", "swils.elp.cls2rsz",
1909            FT_UINT16, BASE_DEC, NULL, 0x0,
1910            NULL, HFILL}},
1911
1912         { &hf_swils_elp_cls3_svcp,
1913           {"Class 3 Svc Parameters", "swils.elp.cls3p",
1914            FT_BYTES, BASE_NONE, NULL, 0x0,
1915            NULL, HFILL}},
1916
1917         { &hf_swils_elp_cls3_rcvsz,
1918           {"Class 3 Frame Size", "swils.elp.cls3rsz",
1919            FT_UINT16, BASE_DEC, NULL, 0x0,
1920            NULL, HFILL}},
1921
1922         { &hf_swils_elp_isl_fc_mode,
1923           {"ISL Flow Ctrl Mode", "swils.elp.fcmode",
1924            FT_STRING, BASE_NONE, NULL, 0x0,
1925            NULL, HFILL}},
1926
1927         { &hf_swils_elp_fcplen,
1928           {"Flow Ctrl Param Len", "swils.elp.fcplen",
1929            FT_UINT16, BASE_DEC, NULL, 0x0,
1930            NULL, HFILL}},
1931
1932         { &hf_swils_elp_b2bcredit,
1933           {"B2B Credit", "swils.elp.b2b",
1934            FT_UINT32, BASE_DEC, NULL, 0x0,
1935            NULL, HFILL}},
1936
1937         { &hf_swils_elp_compat1,
1938           {"Compatibility Param 1", "swils.elp.compat1",
1939            FT_UINT32, BASE_DEC, NULL, 0x0,
1940            NULL, HFILL}},
1941
1942         { &hf_swils_elp_compat2,
1943           {"Compatibility Param 2", "swils.elp.compat2",
1944            FT_UINT32, BASE_DEC, NULL, 0x0,
1945            NULL, HFILL}},
1946
1947         { &hf_swils_elp_compat3,
1948           {"Compatibility Param 3", "swils.elp.compat3",
1949            FT_UINT32, BASE_DEC, NULL, 0x0,
1950            NULL, HFILL}},
1951
1952         { &hf_swils_elp_compat4,
1953           {"Compatibility Param 4", "swils.elp.compat4",
1954            FT_UINT32, BASE_DEC, NULL, 0x0,
1955            NULL, HFILL}},
1956
1957         { &hf_swils_efp_rec_type,
1958           {"Record Type", "swils.efp.rectype",
1959            FT_UINT8, BASE_HEX, VALS(fcswils_rectype_val), 0x0,
1960            NULL, HFILL}},
1961
1962         { &hf_swils_efp_dom_id,
1963           {"Domain ID", "swils.efp.domid",
1964            FT_UINT8, BASE_HEX, NULL, 0x0,
1965            NULL, HFILL}},
1966
1967         { &hf_swils_efp_switch_name,
1968           {"Switch Name", "swils.efp.sname",
1969            FT_STRING, BASE_NONE, NULL, 0x0,
1970            NULL, HFILL}},
1971
1972         { &hf_swils_efp_mcast_grpno,
1973           {"Mcast Grp#", "swils.efp.mcastno",
1974            FT_UINT8, BASE_HEX, NULL, 0x0,
1975            NULL, HFILL}},
1976
1977 #if 0
1978         { &hf_swils_efp_alias_token,
1979           {"Alias Token", "swils.efp.aliastok",
1980            FT_BYTES, BASE_NONE, NULL, 0x0,
1981            NULL, HFILL}},
1982 #endif
1983
1984         { &hf_swils_efp_record_len,
1985           {"Record Len", "swils.efp.recordlen",
1986            FT_UINT8, BASE_DEC, NULL, 0x0,
1987            NULL, HFILL}},
1988
1989         { &hf_swils_efp_payload_len,
1990           {"Payload Len", "swils.efp.payloadlen",
1991            FT_UINT16, BASE_DEC, NULL, 0x0,
1992            NULL, HFILL}},
1993
1994         { &hf_swils_efp_pswitch_pri,
1995           {"Principal Switch Priority", "swils.efp.psprio",
1996            FT_UINT8, BASE_DEC, NULL, 0x0,
1997            NULL, HFILL}},
1998
1999         { &hf_swils_efp_pswitch_name,
2000           {"Principal Switch Name", "swils.efp.psname",
2001            FT_STRING, BASE_NONE, NULL, 0x0,
2002            NULL, HFILL}},
2003
2004         { &hf_swils_dia_switch_name,
2005           {"Switch Name", "swils.dia.sname",
2006            FT_STRING, BASE_NONE, NULL, 0x0,
2007            NULL, HFILL}},
2008
2009         { &hf_swils_rdi_payload_len,
2010           {"Payload Len", "swils.rdi.len",
2011            FT_UINT16, BASE_DEC, NULL, 0x0,
2012            NULL, HFILL}},
2013
2014         { &hf_swils_rdi_req_sname,
2015           {"Req Switch Name", "swils.rdi.reqsn",
2016            FT_STRING, BASE_NONE, NULL, 0x0,
2017            NULL, HFILL}},
2018
2019 #if 0
2020         { &hf_swils_fspfh_cmd,
2021           {"Command:", "swils.fspf.cmd",
2022            FT_UINT8, BASE_HEX, NULL, 0x0,
2023            NULL, HFILL}},
2024 #endif
2025
2026         { &hf_swils_fspfh_rev,
2027           {"Version", "swils.fspf.ver",
2028            FT_UINT8, BASE_HEX, NULL, 0x0,
2029            NULL, HFILL}},
2030
2031         { &hf_swils_fspfh_ar_num,
2032           {"AR Number", "swils.fspf.arnum",
2033            FT_UINT8, BASE_HEX, NULL, 0x0,
2034            NULL, HFILL}},
2035
2036         { &hf_swils_fspfh_auth_type,
2037           {"Authentication Type", "swils.fspf.authtype",
2038            FT_UINT8, BASE_HEX, NULL, 0x0,
2039            NULL, HFILL}},
2040
2041         { &hf_swils_fspfh_dom_id,
2042           {"Originating Domain ID", "swils.fspf.origdomid",
2043            FT_UINT8, BASE_DEC, NULL, 0x0,
2044            NULL, HFILL}},
2045
2046         { &hf_swils_fspfh_auth,
2047           {"Authentication", "swils.fspf.auth",
2048            FT_BYTES, BASE_NONE, NULL, 0x0,
2049            NULL, HFILL}},
2050
2051         { &hf_swils_hlo_options,
2052           {"Options", "swils.hlo.options",
2053            FT_BYTES, BASE_NONE, NULL, 0x0,
2054            NULL, HFILL}},
2055
2056         { &hf_swils_hlo_hloint,
2057           {"Hello Interval (secs)", "swils.hlo.hloint",
2058            FT_UINT32, BASE_DEC, NULL, 0x0,
2059            NULL, HFILL}},
2060
2061         { &hf_swils_hlo_deadint,
2062           {"Dead Interval (secs)", "swils.hlo.deadint",
2063            FT_UINT32, BASE_DEC, NULL, 0x0,
2064            NULL, HFILL}},
2065
2066         { &hf_swils_hlo_rcv_domid,
2067           {"Recipient Domain ID", "swils.hlo.rcvdomid",
2068            FT_UINT8, BASE_DEC, NULL, 0x0,
2069            NULL, HFILL}},
2070
2071         { &hf_swils_hlo_orig_pidx,
2072           {"Originating Port Idx", "swils.hlo.origpidx",
2073            FT_UINT24, BASE_HEX, NULL, 0x0,
2074            NULL, HFILL}},
2075
2076         { &hf_swils_lsrh_lsr_type,
2077           {"LSR Type", "swils.lsr.type",
2078            FT_UINT8, BASE_HEX, VALS(fc_swils_fspf_linkrec_val), 0x0,
2079            NULL, HFILL}},
2080
2081         { &hf_swils_lsrh_lsid,
2082           {"Link State Id", "swils.ls.id",
2083            FT_UINT8, BASE_DEC, NULL, 0x0,
2084            NULL, HFILL}},
2085
2086         { &hf_swils_lsrh_adv_domid,
2087           {"Advertising Domain Id", "swils.lsr.advdomid",
2088            FT_UINT8, BASE_DEC, NULL, 0x0,
2089            NULL, HFILL}},
2090
2091         { &hf_swils_lsrh_ls_incid,
2092           {"LS Incarnation Number", "swils.lsr.incid",
2093            FT_UINT32, BASE_DEC, NULL, 0x0,
2094            NULL, HFILL}},
2095
2096         { &hf_swils_ldrec_linkid,
2097           {"Link ID", "swils.ldr.linkid",
2098            FT_STRING, BASE_NONE, NULL, 0x0,
2099            NULL, HFILL}},
2100
2101         { &hf_swils_ldrec_out_pidx,
2102           {"Output Port Idx", "swils.ldr.out_portidx",
2103            FT_UINT24, BASE_HEX, NULL, 0x0,
2104            NULL, HFILL}},
2105
2106         { &hf_swils_ldrec_nbr_pidx,
2107           {"Neighbor Port Idx", "swils.ldr.nbr_portidx",
2108            FT_UINT24, BASE_HEX, NULL, 0x0,
2109            NULL, HFILL}},
2110
2111         { &hf_swils_ldrec_link_type,
2112           {"Link Type", "swils.ldr.linktype",
2113            FT_UINT8, BASE_HEX, VALS(fc_swils_link_type_val), 0x0,
2114            NULL, HFILL}},
2115
2116         { &hf_swils_ldrec_link_cost,
2117           {"Link Cost", "swils.ldr.linkcost",
2118            FT_UINT16, BASE_DEC, NULL, 0x0,
2119            NULL, HFILL}},
2120
2121         { &hf_swils_rscn_evtype,
2122           {"Event Type", "swils.rscn.evtype",
2123            FT_UINT8, BASE_DEC, VALS(fc_swils_rscn_portstate_val), 0xF0,
2124            NULL, HFILL}},
2125
2126         { &hf_swils_rscn_addrfmt,
2127           {"Address Format", "swils.rscn.addrfmt",
2128            FT_UINT8, BASE_DEC, VALS(fc_swils_rscn_addrfmt_val), 0x0F,
2129            NULL, HFILL}},
2130
2131         { &hf_swils_rscn_affectedport,
2132           {"Affected Port ID", "swils.rscn.affectedport",
2133            FT_STRING, BASE_NONE, NULL, 0x0,
2134            NULL, HFILL}},
2135
2136         { &hf_swils_rscn_detectfn,
2137           {"Detection Function", "swils.rscn.detectfn",
2138            FT_UINT32, BASE_HEX, VALS(fc_swils_rscn_detectfn_val), 0x0,
2139            NULL, HFILL}},
2140
2141         { &hf_swils_rscn_portstate,
2142           {"Port State", "swils.rscn.portstate",
2143            FT_UINT8, BASE_HEX, NULL, 0x0,
2144            NULL, HFILL}},
2145
2146         { &hf_swils_rscn_portid,
2147           {"Port Id", "swils.rscn.portid",
2148            FT_STRING, BASE_NONE, NULL, 0x0,
2149            NULL, HFILL}},
2150
2151         { &hf_swils_rscn_pwwn,
2152           {"Port WWN", "swils.rscn.pwwn",
2153            FT_STRING, BASE_NONE, NULL, 0x0,
2154            NULL, HFILL}},
2155
2156         { &hf_swils_rscn_nwwn,
2157           {"Node WWN", "swils.rscn.nwwn",
2158            FT_STRING, BASE_NONE, NULL, 0x0,
2159            NULL, HFILL}},
2160
2161         { &hf_swils_esc_swvendorid,
2162           {"Switch Vendor ID", "swils.esc.swvendor",
2163            FT_STRING, BASE_NONE, NULL, 0x0,
2164            NULL, HFILL}},
2165
2166         { &hf_swils_esc_pdesc_vendorid,
2167           {"Vendor ID", "swils.esc.vendorid",
2168            FT_STRING, BASE_NONE, NULL, 0x0,
2169            NULL, HFILL}},
2170
2171         { &hf_swils_esc_protocolid,
2172           {"Protocol ID", "swils.esc.protocol",
2173            FT_UINT16, BASE_HEX, VALS(fc_swils_esc_protocol_val), 0x0,
2174            NULL, HFILL}},
2175
2176         { &hf_swils_zone_activezonenm,
2177           {"Active Zoneset Name", "swils.mr.activezonesetname",
2178            FT_STRING, BASE_NONE, NULL, 0x0,
2179            NULL, HFILL}},
2180
2181         { &hf_swils_zone_objname,
2182           {"Zone Object Name", "swils.zone.zoneobjname",
2183            FT_STRING, BASE_NONE, NULL, 0x0,
2184            NULL, HFILL}},
2185
2186         { &hf_swils_zone_objtype,
2187           {"Zone Object Type", "swils.zone.zoneobjtype",
2188            FT_UINT8, BASE_HEX, VALS(fc_swils_zoneobj_type_val), 0x0,
2189            NULL, HFILL}},
2190
2191         { &hf_swils_zone_mbrtype,
2192           {"Zone Member Type", "swils.zone.mbrtype",
2193            FT_UINT8, BASE_HEX, VALS(fc_swils_zonembr_type_val), 0x0,
2194            NULL, HFILL}},
2195
2196         { &hf_swils_zone_protocol,
2197           {"Zone Protocol", "swils.zone.protocol",
2198            FT_UINT8, BASE_HEX, NULL, 0x0,
2199            NULL, HFILL}},
2200
2201         { &hf_swils_zone_mbrid,
2202           {"Member Identifier", "swils.zone.mbrid",
2203            FT_STRING, BASE_NONE, NULL, 0x0,
2204            NULL, HFILL}},
2205
2206         { &hf_swils_zone_status,
2207           {"Zone Command Status", "swils.zone.status",
2208            FT_UINT8, BASE_HEX, VALS(fc_swils_mr_rsp_val), 0x0,
2209            "Applies to MR, ACA, RCA, SFC, UFC", HFILL}},
2210
2211         { &hf_swils_zone_reason,
2212           {"Zone Command Reason Code", "swils.zone.reason",
2213            FT_UINT8, BASE_HEX, VALS(fc_swils_mr_reason_val), 0x0,
2214            "Applies to MR, ACA, RCA, SFC, UFC", HFILL}},
2215
2216         { &hf_swils_aca_domainid,
2217           {"Known Domain ID", "swils.aca.domainid",
2218            FT_UINT8, BASE_HEX, NULL, 0x0,
2219            NULL, HFILL}},
2220
2221         { &hf_swils_sfc_opcode,
2222           {"Operation Request", "swils.sfc.opcode",
2223            FT_UINT8, BASE_HEX, VALS(fc_swils_sfc_op_val), 0x0,
2224            NULL, HFILL}},
2225
2226         { &hf_swils_sfc_zonenm,
2227           {"Zone Set Name", "swils.sfc.zonename",
2228            FT_STRING, BASE_NONE, NULL, 0x0,
2229            NULL, HFILL}},
2230
2231         { &hf_swils_rjt,
2232           {"Reason Code", "swils.rjt.reason",
2233            FT_UINT8, BASE_HEX, VALS(fc_swils_rjt_val), 0x0,
2234            NULL, HFILL}},
2235
2236         { &hf_swils_rjtdet,
2237           {"Reason Code Explanantion", "swils.rjt.reasonexpl",
2238            FT_UINT8, BASE_HEX, VALS(fc_swils_deterr_val), 0x0,
2239            NULL, HFILL}},
2240
2241         { &hf_swils_rjtvendor,
2242           {"Vendor Unique Error Code", "swils.rjt.vendor",
2243            FT_UINT8, BASE_HEX, NULL, 0x0,
2244            NULL, HFILL}},
2245
2246         { &hf_swils_zone_mbrid_lun,
2247           {"LUN", "swils.zone.lun",
2248            FT_BYTES, BASE_NONE, NULL, 0x0,
2249            NULL, HFILL}},
2250
2251         { &hf_swils_ess_rev,
2252           {"Revision", "swils.ess.revision",
2253            FT_UINT32, BASE_DEC, NULL, 0x0,
2254            NULL, HFILL}},
2255
2256         { &hf_swils_ess_len,
2257           {"Payload Length", "swils.ess.leb",
2258            FT_UINT32, BASE_DEC, NULL, 0x0,
2259            NULL, HFILL}},
2260
2261         { &hf_swils_ess_numobj,
2262           {"Number of Capability Objects", "swils.ess.numobj",
2263            FT_UINT16, BASE_DEC, NULL, 0x0,
2264            NULL, HFILL}},
2265
2266         { &hf_swils_interconnect_list_len,
2267           {"List Length", "swils.ess.listlen",
2268            FT_UINT8, BASE_DEC, NULL, 0x0,
2269            NULL, HFILL}},
2270
2271         { &hf_swils_ess_vendorname,
2272           {"Vendor Name", "swils.ess.vendorname",
2273            FT_STRING, BASE_NONE, NULL, 0x0,
2274            NULL, HFILL}},
2275
2276         { &hf_swils_ess_modelname,
2277           {"Model Name", "swils.ess.modelname",
2278            FT_STRING, BASE_NONE, NULL, 0x0,
2279            NULL, HFILL}},
2280
2281         { &hf_swils_ess_relcode,
2282           {"Release Code", "swils.ess.relcode",
2283            FT_STRING, BASE_NONE, NULL, 0x0,
2284            NULL, HFILL}},
2285
2286         { &hf_swils_ess_vendorspecific,
2287           {"Vendor Specific", "swils.ess.vendorspecific",
2288            FT_STRING, BASE_NONE, NULL, 0x0,
2289            NULL, HFILL}},
2290
2291         { &hf_swils_ess_cap_type,
2292           {"Type", "swils.ess.capability.type",
2293            FT_UINT8, BASE_DEC, VALS(fc_ct_gstype_vals), 0x0,
2294            NULL, HFILL}},
2295
2296         { &hf_swils_ess_cap_subtype,
2297           {"Subtype", "swils.ess.capability.subtype",
2298            FT_UINT8, BASE_DEC, NULL, 0x0,
2299            NULL, HFILL}},
2300
2301         { &hf_swils_ess_cap_numentries,
2302           {"Number of Entries", "swils.ess.capability.numentries",
2303            FT_UINT8, BASE_DEC, NULL, 0x0,
2304            NULL, HFILL}},
2305
2306         { &hf_swils_ess_cap_svc,
2307           {"Service Name", "swils.ess.capability.service",
2308            FT_UINT8, BASE_DEC, VALS(fc_ct_gsserver_vals), 0x0,
2309            NULL, HFILL}},
2310
2311         { &hf_swils_ess_dns_obj0h,
2312           {"Name Server Entry Object 00h Support", "swils.ess.capability.dns.obj0h",
2313            FT_BOOLEAN, 8, NULL, 0x1,
2314            NULL, HFILL}},
2315
2316         { &hf_swils_ess_dns_obj1h,
2317           {"Name Server Entry Object 01h Support", "swils.ess.capability.dns.obj1h",
2318            FT_BOOLEAN, 8, NULL, 0x2,
2319            NULL, HFILL}},
2320
2321         { &hf_swils_ess_dns_obj2h,
2322           {"Name Server Entry Object 02h Support", "swils.ess.capability.dns.obj2h",
2323            FT_BOOLEAN, 8, NULL, 0x4,
2324            NULL, HFILL}},
2325
2326         { &hf_swils_ess_dns_obj3h,
2327           {"Name Server Entry Object 03h Support", "swils.ess.capability.dns.obj3h",
2328            FT_BOOLEAN, 8, NULL, 0x8,
2329            NULL, HFILL}},
2330
2331         { &hf_swils_ess_dns_zlacc,
2332           {"GE_PT Zero Length Accepted", "swils.ess.capability.dns.zlacc",
2333            FT_BOOLEAN, 8, NULL, 0x10,
2334            NULL, HFILL}},
2335
2336         { &hf_swils_ess_dns_vendor,
2337           {"Vendor Specific Flags", "swils.ess.capability.dns.vendor",
2338            FT_UINT32, BASE_HEX, NULL, 0x0,
2339            NULL, HFILL}},
2340
2341         { &hf_swils_ess_fctlr_rscn,
2342           {"SW_RSCN Supported", "swils.ess.capability.fctlr.rscn",
2343            FT_BOOLEAN, 8, NULL, 0x1,
2344            NULL, HFILL}},
2345
2346         { &hf_swils_ess_fctlr_vendor,
2347           {"Vendor Specific Flags", "swils.ess.capability.fctlr.vendor",
2348            FT_UINT32, BASE_HEX, NULL, 0x0,
2349            NULL, HFILL}},
2350
2351         { &hf_swils_ess_fcs_basic,
2352           {"Basic Configuration Services", "swils.ess.capability.fcs.basic",
2353            FT_BOOLEAN, 8, NULL, 0x1,
2354            NULL, HFILL}},
2355
2356         { &hf_swils_ess_fcs_platform,
2357           {"Platform Configuration Services", "swils.ess.capability.fcs.platform",
2358            FT_BOOLEAN, 8, NULL, 0x2,
2359            NULL, HFILL}},
2360
2361         { &hf_swils_ess_fcs_topology,
2362           {"Topology Discovery Services", "swils.ess.capability.fcs.topology",
2363            FT_BOOLEAN, 8, NULL, 0x4,
2364            NULL, HFILL}},
2365
2366         { &hf_swils_ess_fcs_enhanced,
2367           {"Enhanced Configuration Services", "swils.ess.capability.fcs.enhanced",
2368            FT_BOOLEAN, 8, NULL, 0x8,
2369            NULL, HFILL}},
2370
2371         { &hf_swils_ess_fzs_enh_supp,
2372           {"Enhanced Zoning Supported", "swils.ess.capability.fzs.ezonesupp",
2373            FT_BOOLEAN, 8, NULL, 0x1,
2374            NULL, HFILL}},
2375
2376         { &hf_swils_ess_fzs_enh_ena,
2377           {"Enhanced Zoning Enabled", "swils.ess.capability.fzs.ezoneena",
2378            FT_BOOLEAN, 8, NULL, 0x2,
2379            NULL, HFILL}},
2380
2381         { &hf_swils_ess_fzs_mr,
2382           {"Merge Control Setting", "swils.ess.capability.fzs.mr",
2383            FT_BOOLEAN, 8, NULL, 0x4,
2384            NULL, HFILL}},
2385
2386         { &hf_swils_ess_fzs_defzone,
2387           {"Default Zone Setting", "swils.ess.capability.fzs.defzone",
2388            FT_BOOLEAN, 8, NULL, 0x8,
2389            NULL, HFILL}},
2390
2391         { &hf_swils_ess_fzs_zsdb_supp,
2392           {"Zoneset Database Supported", "swils.ess.capability.fzs.zsdbsupp",
2393            FT_BOOLEAN, 8, NULL, 0x10,
2394            NULL, HFILL}},
2395
2396         { &hf_swils_ess_fzs_zsdb_ena,
2397           {"Zoneset Database Enabled", "swils.ess.capability.fzs.zsdbena",
2398            FT_BOOLEAN, 8, NULL, 0x20,
2399            NULL, HFILL}},
2400
2401         { &hf_swils_ess_fzs_adc_supp,
2402           {"Active Direct Command Supported", "swils.ess.capability.fzs.adcsupp",
2403            FT_BOOLEAN, 8, NULL, 0x40,
2404            NULL, HFILL}},
2405
2406         { &hf_swils_ess_fzs_hardzone,
2407           {"Hard Zoning Supported", "swils.ess.capability.fzs.hardzone",
2408            FT_BOOLEAN, 8, NULL, 0x80,
2409            NULL, HFILL}},
2410
2411         { &hf_swils_ess_cap_len,
2412           {"Length", "swils.ess.capability.length",
2413            FT_UINT8, BASE_DEC, NULL, 0x0,
2414            NULL, HFILL}},
2415
2416         { &hf_swils_ess_cap_t10,
2417           {"T10 Vendor ID", "swils.ess.capability.t10id",
2418            FT_STRING, BASE_NONE, NULL, 0x0,
2419            NULL, HFILL}},
2420
2421         { &hf_swils_ess_cap_vendorobj,
2422           {"Vendor-Specific Info", "swils.ess.capability.vendorobj",
2423            FT_BYTES, BASE_NONE, NULL, 0x0,
2424            NULL, HFILL}},
2425
2426         { &hf_swils_mrra_rev,
2427           {"Revision", "swils.mrra.revision",
2428            FT_UINT32, BASE_DEC, NULL, 0x0,
2429            NULL, HFILL}},
2430
2431         { &hf_swils_mrra_size,
2432           {"Merge Request Size", "swils.mrra.size",
2433            FT_UINT32, BASE_DEC, NULL, 0x0,
2434            NULL, HFILL}},
2435
2436         { &hf_swils_mrra_vendorid,
2437           {"Vendor ID", "swils.mrra.vendorid",
2438            FT_STRING, BASE_NONE, NULL, 0x0,
2439            NULL, HFILL}},
2440
2441         { &hf_swils_mrra_vendorinfo,
2442           {"Vendor-Specific Info", "swils.mrra.vendorinfo",
2443            FT_BYTES, BASE_NONE, NULL, 0x0,
2444            NULL, HFILL}},
2445
2446         { &hf_swils_mrra_reply,
2447           {"MRRA Response", "swils.mrra.reply",
2448            FT_UINT32, BASE_DEC, NULL, 0x0,
2449            NULL, HFILL}},
2450
2451         { &hf_swils_mrra_reply_size,
2452           {"Maximum Resources Available", "swils.mrra.replysize",
2453            FT_UINT32, BASE_DEC, NULL, 0x0,
2454            NULL, HFILL}},
2455
2456         { &hf_swils_mrra_waittime,
2457           {"Waiting Period (secs)", "swils.mrra.waittime",
2458            FT_UINT32, BASE_DEC, NULL, 0x0,
2459            NULL, HFILL}},
2460
2461       /* Generated from convert_proto_tree_add_text.pl */
2462       { &hf_swils_requested_domain_id, { "Requested Domain ID", "swils.requested_domain_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2463       { &hf_swils_granted_domain_id, { "Granted Domain ID", "swils.granted_domain_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2464       { &hf_swils_lsrh_lsr_age, { "LSR Age", "swils.lsr.age", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2465       { &hf_swils_lsrh_options, { "Options", "swils.lsr.options", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2466       { &hf_swils_lsrh_checksum, { "Checksum", "swils.lsr.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2467       { &hf_swils_lsrh_lsr_length, { "LSR Length", "swils.lsr.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2468       { &hf_swils_lsrec_number_of_links, { "Number of Links", "swils.lsr.number_of_links", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2469       { &hf_swils_lsupdate_flags, { "Flags", "swils.lsupdate.flags", FT_UINT8, BASE_HEX, VALS(fc_swils_fspf_lsrflags_val), 0x0, NULL, HFILL }},
2470       { &hf_swils_lsupdate_num_of_lsrs, { "Num of LSRs", "swils.lsupdate.num_of_lsrs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2471       { &hf_swils_lsack_flags, { "Flags", "swils.lsack.flags", FT_UINT8, BASE_HEX, VALS(fc_swils_fspf_lsrflags_val), 0x0, NULL, HFILL }},
2472       { &hf_swils_lsack_num_of_lsr_headers, { "Num of LSR Headers", "swils.lsack.num_of_lsr_headers", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2473       { &hf_swils_rscn_num_entries, { "Num Entries", "swils.rscn.num_entries", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2474       { &hf_swils_zone_mbrflags, { "Flags", "swils.zone.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2475       { &hf_swils_zone_mbr_identifier_length, { "Identifier Length", "swils.zone.identifier_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2476       { &hf_swils_zone_num_members, { "4", "swils.zone.num_members", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2477       { &hf_swils_zone_active_zoneset_length, { "Active ZoneSet Length", "swils.zone.active_zoneset_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2478       { &hf_swils_zone_num_zoning_objects, { "Number of zoning objects", "swils.zone.num_zoning_objects", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2479       { &hf_swils_zone_full_zone_set_length, { "Full Zone Set Length", "swils.zone.full_zone_set_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2480       { &hf_swils_zone_vendor_unique, { "Vendor Unique", "swils.zone.vendor_unique", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2481       { &hf_swils_domain_id_list_length, { "Domain ID List Length", "swils.aca.domain_id_list_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2482       { &hf_swils_sfc_zoneset_length, { "ZoneSet Length", "swils.sfc.zoneset_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2483       { &hf_swils_esc_payload_length, { "Payload Length", "swils.esc.payload_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2484     };
2485
2486     static gint *ett[] = {
2487         &ett_fcswils,
2488         &ett_fcswils_swacc,
2489         &ett_fcswils_swrjt,
2490         &ett_fcswils_elp,
2491         &ett_fcswils_efp,
2492         &ett_fcswils_efplist,
2493         &ett_fcswils_dia,
2494         &ett_fcswils_rdi,
2495         &ett_fcswils_fspfhdr,
2496         &ett_fcswils_hlo,
2497         &ett_fcswils_lsrec,
2498         &ett_fcswils_lsrechdr,
2499         &ett_fcswils_ldrec,
2500         &ett_fcswils_lsu,
2501         &ett_fcswils_lsa,
2502         &ett_fcswils_bf,
2503         &ett_fcswils_rcf,
2504         &ett_fcswils_rscn,
2505         &ett_fcswils_rscn_dev,
2506         &ett_fcswils_drlir,
2507         &ett_fcswils_mr,
2508         &ett_fcswils_zoneobjlist,
2509         &ett_fcswils_zoneobj,
2510         &ett_fcswils_zonembr,
2511         &ett_fcswils_aca,
2512         &ett_fcswils_rca,
2513         &ett_fcswils_sfc,
2514         &ett_fcswils_ufc,
2515         &ett_fcswils_esc,
2516         &ett_fcswils_esc_pdesc,
2517         &ett_fcswils_ieinfo,
2518         &ett_fcswils_capinfo
2519     };
2520
2521     static ei_register_info ei[] = {
2522         { &ei_swils_efp_record_len, { "swils.efp.recordlen.zero", PI_UNDECODED, PI_NOTE, "Record length is zero", EXPFILL }},
2523         { &ei_swils_no_exchange, { "swils.no_exchange", PI_UNDECODED, PI_WARN, "No record of Exchg. Unable to decode", EXPFILL }},
2524     };
2525
2526     expert_module_t* expert_fcswils;
2527
2528     proto_fcswils = proto_register_protocol("Fibre Channel SW_ILS", "FC-SWILS", "swils");
2529
2530     proto_register_field_array(proto_fcswils, hf, array_length(hf));
2531     proto_register_subtree_array(ett, array_length(ett));
2532     expert_fcswils = expert_register_protocol(proto_fcswils);
2533     expert_register_field_array(expert_fcswils, ei, array_length(ei));
2534     register_init_routine(&fcswils_init_protocol);
2535 }
2536
2537 void
2538 proto_reg_handoff_fcswils(void)
2539 {
2540     dissector_handle_t swils_handle;
2541
2542     swils_handle = new_create_dissector_handle(dissect_fcswils, proto_fcswils);
2543     dissector_add_uint("fc.ftype", FC_FTYPE_SWILS, swils_handle);
2544
2545     data_handle = find_dissector("data");
2546     fcsp_handle = find_dissector("fcsp");
2547 }
2548
2549 /*
2550  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2551  *
2552  * Local variables:
2553  * c-basic-offset: 4
2554  * tab-width: 8
2555  * indent-tabs-mode: nil
2556  * End:
2557  *
2558  * vi: set shiftwidth=4 tabstop=8 expandtab:
2559  * :indentSize=4:tabSize=8:noTabs=true:
2560  */