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