2 * Routines for FC Inter-switch link services
3 * Copyright 2001, Dinesh G Dutt <ddutt@cisco.com>
5 * $Id: packet-fcswils.c,v 1.3 2003/03/05 07:41:23 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * Copied from WHATEVER_FILE_YOU_USED (where "WHATEVER_FILE_YOU_USED"
12 * is a dissector file; if you just copied this from README.developer,
13 * don't bother with the "Copied from" - you don't even need to put
14 * in a "Copied from" if you copied an existing dissector, especially
15 * if the bulk of the code in the new dissector is your code)
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40 #ifdef HAVE_SYS_TYPES_H
41 # include <sys/types.h>
44 #ifdef HAVE_NETINET_IN_H
45 # include <netinet/in.h>
50 #ifdef NEED_SNPRINTF_H
51 # include "snprintf.h"
54 #include <epan/packet.h>
55 #include <epan/conversation.h>
57 #include "packet-fc.h"
58 #include "packet-fcswils.h"
60 #define FC_SWILS_RPLY 0x0
61 #define FC_SWILS_REQ 0x1
62 #define FC_SWILS_RSCN_DEVENTRY_SIZE 20
64 /* Zone name has the structure:
65 * name_len (1 byte), rsvd (3 bytes), name (m bytes), fill (n bytes)
66 * name_len excludes the 4 initial bytes before the name
68 #define ZONENAME_LEN(x, y) (tvb_get_guint8(x, y)+4)
70 /* Initialize the protocol and registered fields */
71 static int proto_fcswils = -1;
72 static int hf_swils_opcode = -1;
73 static int hf_swils_elp_rev = -1;
74 static int hf_swils_elp_flags = -1;
75 static int hf_swils_elp_r_a_tov = -1;
76 static int hf_swils_elp_e_d_tov = -1;
77 static int hf_swils_elp_req_epn = -1;
78 static int hf_swils_elp_req_esn = -1;
79 static int hf_swils_elp_clsf_svcp = -1;
80 static int hf_swils_elp_clsf_rcvsz = -1;
81 static int hf_swils_elp_clsf_conseq = -1;
82 static int hf_swils_elp_clsf_e2e = -1;
83 static int hf_swils_elp_clsf_openseq = -1;
84 static int hf_swils_elp_cls1_svcp = -1;
85 static int hf_swils_elp_cls1_rcvsz = -1;
86 static int hf_swils_elp_cls2_svcp = -1;
87 static int hf_swils_elp_cls2_rcvsz = -1;
88 static int hf_swils_elp_cls3_svcp = -1;
89 static int hf_swils_elp_cls3_rcvsz = -1;
90 static int hf_swils_elp_isl_fc_mode = -1;
91 static int hf_swils_elp_fcplen = -1;
92 static int hf_swils_elp_b2bcredit = -1;
93 static int hf_swils_elp_compat1 = -1;
94 static int hf_swils_elp_compat2 = -1;
95 static int hf_swils_elp_compat3 = -1;
96 static int hf_swils_elp_compat4 = -1;
97 static int hf_swils_efp_rec_type = -1;
98 static int hf_swils_efp_dom_id = -1;
99 static int hf_swils_efp_switch_name = -1;
100 static int hf_swils_efp_mcast_grpno = -1;
101 static int hf_swils_efp_alias_token = -1;
102 static int hf_swils_efp_payload_len = -1;
103 static int hf_swils_efp_pswitch_pri = -1;
104 static int hf_swils_efp_pswitch_name = -1;
105 static int hf_swils_dia_switch_name = -1;
106 static int hf_swils_rdi_payload_len = -1;
107 static int hf_swils_rdi_req_sname = -1;
108 static int hf_swils_fspfh_cmd = -1;
109 static int hf_swils_fspfh_rev = -1;
110 static int hf_swils_fspfh_ar_num = -1;
111 static int hf_swils_fspfh_auth_type = -1;
112 static int hf_swils_fspfh_dom_id = -1;
113 static int hf_swils_fspfh_auth = -1;
114 static int hf_swils_hlo_options = -1;
115 static int hf_swils_hlo_hloint = -1;
116 static int hf_swils_hlo_deadint = -1;
117 static int hf_swils_hlo_rcv_domid = -1;
118 static int hf_swils_hlo_orig_pidx = -1;
119 static int hf_swils_ldrec_linkid = -1;
120 static int hf_swils_ldrec_out_pidx = -1;
121 static int hf_swils_ldrec_nbr_pidx = -1;
122 static int hf_swils_ldrec_link_type = -1;
123 static int hf_swils_ldrec_link_cost = -1;
124 static int hf_swils_lsrh_lsr_type = -1;
125 static int hf_swils_lsrh_lsid = -1;
126 static int hf_swils_lsrh_adv_domid = -1;
127 static int hf_swils_lsrh_ls_incid = -1;
128 static int hf_swils_esc_pdesc_vendorid = -1;
129 static int hf_swils_esc_swvendorid = -1;
130 static int hf_swils_esc_protocolid = -1;
131 static int hf_swils_rscn_evtype = -1;
132 static int hf_swils_rscn_addrfmt = -1;
133 static int hf_swils_rscn_detectfn = -1;
134 static int hf_swils_rscn_affectedport = -1;
135 static int hf_swils_rscn_portstate = -1;
136 static int hf_swils_rscn_portid = -1;
137 static int hf_swils_rscn_pwwn = -1;
138 static int hf_swils_rscn_nwwn = -1;
139 static int hf_swils_zone_activezonenm = -1;
140 static int hf_swils_zone_objname = -1;
141 static int hf_swils_zone_objtype = -1;
142 static int hf_swils_zone_mbrtype = -1;
143 static int hf_swils_zone_protocol = -1;
144 static int hf_swils_zone_mbrid = -1;
145 static int hf_swils_zone_status = -1;
146 static int hf_swils_zone_reason = -1;
147 static int hf_swils_aca_domainid = -1;
148 static int hf_swils_sfc_opcode = -1;
149 static int hf_swils_sfc_zonenm = -1;
150 static int hf_swils_rjt = -1;
151 static int hf_swils_rjtdet = -1;
152 static int hf_swils_rjtvendor = -1;
153 static int hf_swils_zone_mbrid_lun = -1;
155 /* Initialize the subtree pointers */
156 static gint ett_fcswils = -1;
157 static gint ett_fcswils_swacc = -1;
158 static gint ett_fcswils_swrjt = -1;
159 static gint ett_fcswils_elp = -1;
160 static gint ett_fcswils_efp = -1;
161 static gint ett_fcswils_efplist = -1;
162 static gint ett_fcswils_dia = -1;
163 static gint ett_fcswils_rdi = -1;
164 static gint ett_fcswils_fspfhdr = -1;
165 static gint ett_fcswils_hlo = -1;
166 static gint ett_fcswils_lsrec = -1;
167 static gint ett_fcswils_lsrechdr = -1;
168 static gint ett_fcswils_ldrec = -1;
169 static gint ett_fcswils_lsu = -1;
170 static gint ett_fcswils_lsa = -1;
171 static gint ett_fcswils_bf = -1;
172 static gint ett_fcswils_rcf = -1;
173 static gint ett_fcswils_rscn = -1;
174 static gint ett_fcswils_rscn_dev = -1;
175 static gint ett_fcswils_drlir = -1;
176 static gint ett_fcswils_mr = -1;
177 static gint ett_fcswils_zoneobjlist = -1;
178 static gint ett_fcswils_zoneobj = -1;
179 static gint ett_fcswils_zonembr = -1;
180 static gint ett_fcswils_aca = -1;
181 static gint ett_fcswils_rca = -1;
182 static gint ett_fcswils_sfc = -1;
183 static gint ett_fcswils_ufc = -1;
184 static gint ett_fcswils_esc = -1;
185 static gint ett_fcswils_esc_pdesc = -1;
187 typedef struct _zonename {
194 typedef struct _fcswils_conv_key {
196 } fcswils_conv_key_t;
198 typedef struct _fcswils_conv_data {
200 } fcswils_conv_data_t;
202 GHashTable *fcswils_req_hash = NULL;
203 GMemChunk *fcswils_req_keys = NULL;
204 GMemChunk *fcswils_req_vals = NULL;
205 guint32 fcswils_init_count = 25;
207 static dissector_handle_t data_handle;
209 static gint get_zoneobj_len (tvbuff_t *tvb, gint offset);
215 fcswils_equal(gconstpointer v, gconstpointer w)
217 fcswils_conv_key_t *v1 = (fcswils_conv_key_t *)v;
218 fcswils_conv_key_t *v2 = (fcswils_conv_key_t *)w;
220 return (v1->conv_idx == v2->conv_idx);
224 fcswils_hash (gconstpointer v)
226 fcswils_conv_key_t *key = (fcswils_conv_key_t *)v;
235 * Protocol initialization
238 fcswils_init_protocol(void)
240 if (fcswils_req_keys)
241 g_mem_chunk_destroy (fcswils_req_keys);
242 if (fcswils_req_vals)
243 g_mem_chunk_destroy (fcswils_req_vals);
244 if (fcswils_req_hash)
245 g_hash_table_destroy (fcswils_req_hash);
247 fcswils_req_hash = g_hash_table_new(fcswils_hash, fcswils_equal);
248 fcswils_req_keys = g_mem_chunk_new("fcswils_req_keys",
249 sizeof(fcswils_conv_key_t),
250 fcswils_init_count * sizeof(fcswils_conv_key_t),
252 fcswils_req_vals = g_mem_chunk_new("fcswils_req_vals",
253 sizeof(fcswils_conv_data_t),
254 fcswils_init_count * sizeof(fcswils_conv_data_t),
259 zonenm_to_str (tvbuff_t *tvb, gint offset)
261 int len = tvb_get_guint8 (tvb, offset);
262 return ((gchar *)tvb_get_ptr (tvb, offset+4, len));
265 /* Offset points to the start of the zone object */
267 get_zoneobj_len (tvbuff_t *tvb, gint offset)
269 gint numrec, numrec1;
273 /* zone object structure is:
274 * type (1 byte), protocol (1 byte), rsvd (2 bytes), obj name (x bytes),
275 * num of zone mbrs (4 bytes ), list of zone members (each member if of
278 * zone member structure is:
279 * type (1 byte), rsvd (1 byte), flags (1 byte), id_len (1 byte),
282 objtype = tvb_get_guint8 (tvb, offset);
283 len = 4 + ZONENAME_LEN (tvb, offset+4); /* length upto num_of_mbrs field */
284 numrec = tvb_get_ntohl (tvb, offset+len); /* gets us num of zone mbrs */
286 len += 4; /* + num_mbrs */
287 for (i = 0; i < numrec; i++) {
288 if (objtype == FC_SWILS_ZONEOBJ_ZONESET) {
289 len += 4 + ZONENAME_LEN (tvb, offset+4+len); /* length upto num_of_mbrs field */
290 numrec1 = tvb_get_ntohl (tvb, offset+len);
293 for (j = 0; j < numrec1; j++) {
294 len += 4 + tvb_get_guint8 (tvb, offset+3+len);
297 else if (objtype == FC_SWILS_ZONEOBJ_ZONE) {
298 len += 4 + tvb_get_guint8 (tvb, offset+3+len);
306 dissect_swils_elp (tvbuff_t *tvb, proto_tree *elp_tree, guint8 isreq _U_)
309 /* Set up structures needed to add the protocol subtree and manage it */
315 /* Response i.e. SW_ACC for an ELP has the same format as the request */
316 /* We skip the initial 4 bytes as we don't care about the opcode */
317 tvb_memcpy (tvb, (guint8 *)&elp, 4, FC_SWILS_ELP_SIZE);
319 elp.r_a_tov = ntohl (elp.r_a_tov);
320 elp.e_d_tov = ntohl (elp.e_d_tov);
321 elp.isl_flwctrl_mode = ntohs (elp.isl_flwctrl_mode);
322 elp.flw_ctrl_parmlen = ntohs (elp.flw_ctrl_parmlen);
326 proto_tree_add_item (elp_tree, hf_swils_elp_rev, tvb, offset++, 1, 0);
327 proto_tree_add_item (elp_tree, hf_swils_elp_flags, tvb, offset, 2, 0);
329 proto_tree_add_uint_format (elp_tree, hf_swils_elp_r_a_tov, tvb, offset, 4,
330 elp.r_a_tov, "R_A_TOV: %d msecs", elp.r_a_tov);
332 proto_tree_add_uint_format (elp_tree, hf_swils_elp_e_d_tov, tvb, offset, 4,
333 elp.e_d_tov, "E_D_TOV: %d msecs", elp.e_d_tov);
335 proto_tree_add_string (elp_tree, hf_swils_elp_req_epn, tvb, offset, 8,
336 fcwwn_to_str (elp.req_epname));
338 proto_tree_add_string (elp_tree, hf_swils_elp_req_esn, tvb, offset, 8,
339 fcwwn_to_str (elp.req_sname));
343 if (elp.clsf_svcparm[0] & 0x80) {
344 strcpy (flags, "Class F Valid");
346 if (elp.clsf_svcparm[4] & 0x20) {
347 strcpy (&flags[13], " | X_ID Interlock");
350 strcpy (&flags[13], " | No X_ID Interlk");
354 strcpy (flags, "Class F Invld");
356 proto_tree_add_bytes_format (elp_tree, hf_swils_elp_clsf_svcp, tvb, offset, 6,
357 &elp.clsf_svcparm[0], "Class F Svc Parameters: (%s)", flags);
360 proto_tree_add_item (elp_tree, hf_swils_elp_clsf_rcvsz, tvb, offset, 2, 0);
362 proto_tree_add_item (elp_tree, hf_swils_elp_clsf_conseq, tvb, offset, 2, 0);
364 proto_tree_add_item (elp_tree, hf_swils_elp_clsf_e2e, tvb, offset, 2, 0);
366 proto_tree_add_item (elp_tree, hf_swils_elp_clsf_openseq, tvb, offset, 2, 0);
371 if (elp.cls1_svcparm[0] & 0x80) {
372 strcpy (&flags[stroff], "Class 1 Valid");
374 if (elp.cls1_svcparm[0] & 0x40) {
375 strcpy (&flags[stroff], " | IMX");
378 if (elp.cls1_svcparm[0] & 0x20) {
379 strcpy (&flags[stroff], " | XPS");
382 if (elp.cls1_svcparm[0] & 0x10) {
383 strcpy (&flags[stroff], " | LKS");
387 strcpy (&flags[0], "Class 1 Invalid");
390 proto_tree_add_bytes_format (elp_tree, hf_swils_elp_cls1_svcp, tvb, offset, 2,
391 tvb_get_ptr (tvb, offset, 2),
392 "Class 1 Svc Parameters: (%s)", flags);
394 if (elp.cls1_svcparm[0] & 0x80) {
395 proto_tree_add_item (elp_tree, hf_swils_elp_cls1_rcvsz, tvb, offset, 2, 0);
400 if (elp.cls2_svcparm[0] & 0x80) {
401 strcpy (flags, "Class 2 Valid");
403 if (elp.cls2_svcparm[0] & 0x08) {
404 strcpy (&flags[13], " | Seq Delivery");
407 strcpy (&flags[13], " | No Seq Delivery");
411 strcpy (flags, "Class 2 Invld");
414 proto_tree_add_bytes_format (elp_tree, hf_swils_elp_cls2_svcp, tvb, offset, 2,
415 &elp.cls2_svcparm[0],
416 "Class 2 Svc Parameters: (%s)", flags);
419 if (elp.cls2_svcparm[0] & 0x80) {
420 proto_tree_add_item (elp_tree, hf_swils_elp_cls2_rcvsz, tvb, offset, 2, 0);
425 if (elp.cls3_svcparm[0] & 0x80) {
426 strcpy (flags, "Class 3 Valid");
428 if (elp.cls3_svcparm[0] & 0x08) {
429 strcpy (&flags[13], " | Seq Delivery");
432 strcpy (&flags[13], " | No Seq Delivery");
436 strcpy (flags, "Class 3 Invld");
438 proto_tree_add_bytes_format (elp_tree, hf_swils_elp_cls3_svcp, tvb, offset, 2,
439 &elp.cls3_svcparm[0],
440 "Class 3 Svc Parameters: (%s)", flags);
443 if (elp.cls3_svcparm[0] & 0x80) {
444 proto_tree_add_item (elp_tree, hf_swils_elp_cls3_rcvsz, tvb, offset, 2, 0);
448 proto_tree_add_string (elp_tree, hf_swils_elp_isl_fc_mode, tvb, offset, 2,
449 val_to_str (elp.isl_flwctrl_mode, fcswils_elp_fc_val, "Vendor Unique"));
451 proto_tree_add_item (elp_tree, hf_swils_elp_fcplen, tvb, offset, 2, 0);
453 proto_tree_add_item (elp_tree, hf_swils_elp_b2bcredit, tvb, offset, 4, 0);
455 proto_tree_add_item (elp_tree, hf_swils_elp_compat1, tvb, offset, 4, 0);
457 proto_tree_add_item (elp_tree, hf_swils_elp_compat2, tvb, offset, 4, 0);
459 proto_tree_add_item (elp_tree, hf_swils_elp_compat3, tvb, offset, 4, 0);
461 proto_tree_add_item (elp_tree, hf_swils_elp_compat4, tvb, offset, 4, 0);
467 dissect_swils_efp (tvbuff_t *tvb, proto_tree *efp_tree, guint8 isreq _U_)
470 /* Set up structures needed to add the protocol subtree and manage it */
472 proto_tree *lrec_tree;
476 fcswils_efp_listrec *lrec;
478 tvb_memcpy (tvb, (guint8 *)&efp, offset, FC_SWILS_EFP_SIZE);
479 efp.payload_len = ntohs (efp.payload_len);
480 efp.listrec = (fcswils_efp_listrec *)tvb_get_ptr (tvb, FC_SWILS_EFP_SIZE,
481 efp.payload_len - FC_SWILS_EFP_SIZE);
485 proto_tree_add_item (efp_tree, hf_swils_efp_payload_len, tvb, offset, 2, 0);
487 proto_tree_add_item (efp_tree, hf_swils_efp_pswitch_pri, tvb,
489 proto_tree_add_string (efp_tree, hf_swils_efp_pswitch_name, tvb, offset,
490 8, fcwwn_to_str (efp.pswitch_name));
493 /* Add List Records now */
495 num_listrec = (efp.payload_len - FC_SWILS_EFP_SIZE)/efp.reclen;
501 while (num_listrec--) {
502 lrec = (fcswils_efp_listrec *)tvb_get_ptr (tvb, offset, efp.reclen);
504 if (lrec->didrec.rec_type == FC_SWILS_LRECTYPE_DOMAIN) {
505 subti = proto_tree_add_text (efp_tree, tvb, offset,
506 (efp.payload_len - FC_SWILS_EFP_SIZE),
508 lrec_tree = proto_item_add_subtree (subti, ett_fcswils_efplist);
509 proto_tree_add_item (lrec_tree, hf_swils_efp_dom_id, tvb, offset+1, 1, 0);
510 proto_tree_add_string (lrec_tree, hf_swils_efp_switch_name, tvb, offset+8, 8,
511 fcwwn_to_str (lrec->didrec.sname));
513 else if (lrec->didrec.rec_type == FC_SWILS_LRECTYPE_MCAST) {
514 subti = proto_tree_add_text (efp_tree, tvb, offset,
515 (efp.payload_len - FC_SWILS_EFP_SIZE),
516 "Multicast ID Record");
517 lrec_tree = proto_item_add_subtree (subti, ett_fcswils_efplist);
518 proto_tree_add_item (lrec_tree, hf_swils_efp_mcast_grpno, tvb, offset+1, 1, 0);
520 offset += efp.reclen;
527 dissect_swils_dia (tvbuff_t *tvb, proto_tree *dia_tree, guint8 isreq _U_)
529 /* Set up structures needed to add the protocol subtree and manage it */
533 proto_tree_add_string (dia_tree, hf_swils_dia_switch_name, tvb, offset+4,
534 8, fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8)));
539 dissect_swils_rdi (tvbuff_t *tvb, proto_tree *rdi_tree, guint8 isreq)
541 /* Set up structures needed to add the protocol subtree and manage it */
546 plen = tvb_get_ntohs (tvb, offset+2);
548 proto_tree_add_item (rdi_tree, hf_swils_rdi_payload_len, tvb, offset+2, 2, 0);
549 proto_tree_add_string (rdi_tree, hf_swils_rdi_req_sname, tvb, offset+4,
550 8, fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8)));
552 /* 12 is the length of the initial header and 4 is the size of each
553 * domain request record.
555 numrec = (plen - 12)/4;
557 for (i = 0; i < numrec; i++) {
559 proto_tree_add_text (rdi_tree, tvb, offset+3, 1,
560 "Requested Domain ID: %d",
561 tvb_get_guint8 (tvb, offset+3));
564 proto_tree_add_text (rdi_tree, tvb, offset+3, 1,
565 "Granted Domain ID: %d",
566 tvb_get_guint8 (tvb, offset+3));
574 dissect_swils_fspf_hdr (tvbuff_t *tvb, proto_tree *tree, int offset)
577 proto_tree *fspfh_tree;
580 /* 20 is the size of FSPF header */
581 subti = proto_tree_add_text (tree, tvb, offset, 20, "FSPF Header");
582 fspfh_tree = proto_item_add_subtree (subti, ett_fcswils_fspfhdr);
584 proto_tree_add_item (fspfh_tree, hf_swils_fspfh_rev, tvb, offset+4,
586 proto_tree_add_item (fspfh_tree, hf_swils_fspfh_ar_num, tvb,
588 proto_tree_add_item (fspfh_tree, hf_swils_fspfh_auth_type, tvb,
590 proto_tree_add_item (fspfh_tree, hf_swils_fspfh_dom_id, tvb, offset+11,
592 proto_tree_add_item (fspfh_tree, hf_swils_fspfh_auth, tvb, offset+12,
598 dissect_swils_fspf_lsrechdr (tvbuff_t *tvb, proto_tree *tree, int offset)
600 proto_tree_add_item (tree, hf_swils_lsrh_lsr_type, tvb, offset, 1, 0);
601 proto_tree_add_text (tree, tvb, offset+2, 2, "LSR Age: %d secs",
602 tvb_get_ntohs (tvb, offset+2));
603 proto_tree_add_text (tree, tvb, offset+4, 4, "Options : 0x%x",
604 tvb_get_ntohl (tvb, offset+4));
605 proto_tree_add_item (tree, hf_swils_lsrh_lsid, tvb, offset+11, 1, 0);
606 proto_tree_add_item (tree, hf_swils_lsrh_adv_domid, tvb, offset+15, 1, 0);
607 proto_tree_add_item (tree, hf_swils_lsrh_ls_incid, tvb, offset+16, 4, 0);
608 proto_tree_add_text (tree, tvb, offset+20, 2, "Checksum: 0x%x",
609 tvb_get_ntohs (tvb, offset+20));
610 proto_tree_add_text (tree, tvb, offset+22, 2, "LSR Length: %d",
611 tvb_get_ntohs (tvb, offset+22));
615 dissect_swils_fspf_ldrec (tvbuff_t *tvb, proto_tree *tree, int offset)
617 proto_tree_add_string (tree, hf_swils_ldrec_linkid, tvb, offset, 4,
618 fc_to_str (tvb_get_ptr (tvb, offset+1, 3)));
619 proto_tree_add_item (tree, hf_swils_ldrec_out_pidx, tvb, offset+5, 3, 0);
620 proto_tree_add_item (tree, hf_swils_ldrec_nbr_pidx, tvb, offset+9, 3, 0);
621 proto_tree_add_item (tree, hf_swils_ldrec_link_type, tvb, offset+12, 1, 0);
622 proto_tree_add_item (tree, hf_swils_ldrec_link_cost, tvb, offset+14, 2, 0);
626 dissect_swils_fspf_lsrec (tvbuff_t *tvb, proto_tree *tree, int offset,
630 proto_item *subti1, *subti;
631 proto_tree *lsrec_tree, *ldrec_tree, *lsrechdr_tree;
634 for (j = 0; j < num_lsrec; j++) {
635 num_ldrec = tvb_get_ntohs (tvb, offset+26);
636 subti = proto_tree_add_text (tree, tvb, offset, (28+num_ldrec*16),
637 "Link State Record %d (Domain %d)", j,
638 tvb_get_guint8 (tvb, offset+15));
639 lsrec_tree = proto_item_add_subtree (subti, ett_fcswils_lsrec);
641 subti = proto_tree_add_text (lsrec_tree, tvb, offset, 24,
642 "Link State Record Header");
643 lsrechdr_tree = proto_item_add_subtree (subti,
644 ett_fcswils_lsrechdr);
646 dissect_swils_fspf_lsrechdr (tvb, lsrechdr_tree, offset);
647 proto_tree_add_text (tree, tvb, offset+26, 2, "Number of Links: %d",
651 for (i = 0; i < num_ldrec; i++) {
652 subti1 = proto_tree_add_text (lsrec_tree, tvb, offset, 16,
653 "Link Descriptor %d "
654 "(Neighbor domain %d)", i,
655 tvb_get_guint8 (tvb, offset+3));
656 ldrec_tree = proto_item_add_subtree (subti1, ett_fcswils_ldrec);
657 dissect_swils_fspf_ldrec (tvb, ldrec_tree, offset);
665 dissect_swils_hello (tvbuff_t *tvb, proto_tree *hlo_tree, guint8 isreq _U_)
667 /* Set up structures needed to add the protocol subtree and manage it */
671 dissect_swils_fspf_hdr (tvb, hlo_tree, offset);
673 proto_tree_add_item (hlo_tree, hf_swils_hlo_options, tvb, offset+20, 4, 0);
674 proto_tree_add_item (hlo_tree, hf_swils_hlo_hloint, tvb, offset+24, 4, 0);
675 proto_tree_add_item (hlo_tree, hf_swils_hlo_deadint, tvb, offset+28, 4, 0);
676 proto_tree_add_item (hlo_tree, hf_swils_hlo_rcv_domid, tvb, offset+35, 1, 0);
677 proto_tree_add_item (hlo_tree, hf_swils_hlo_orig_pidx, tvb, offset+37, 3, 0);
682 dissect_swils_lsupdate (tvbuff_t *tvb, proto_tree *lsu_tree, guint8 isreq _U_)
684 /* Set up structures needed to add the protocol subtree and manage it */
689 dissect_swils_fspf_hdr (tvb, lsu_tree, offset);
691 proto_tree_add_text (lsu_tree, tvb, offset+23, 1, "Flags : %s",
692 val_to_str (tvb_get_guint8 (tvb, offset+23),
693 fc_swils_fspf_lsrflags_val, "0x%x"));
694 num_lsrec = tvb_get_ntohl (tvb, offset+24);
696 proto_tree_add_text (lsu_tree, tvb, offset+24, 4, "Num of LSRs: %d",
700 dissect_swils_fspf_lsrec (tvb, lsu_tree, offset, num_lsrec);
705 dissect_swils_lsack (tvbuff_t *tvb, proto_tree *lsa_tree, guint8 isreq _U_)
707 /* Set up structures needed to add the protocol subtree and manage it */
711 proto_tree *lsrechdr_tree;
714 dissect_swils_fspf_hdr (tvb, lsa_tree, offset);
716 proto_tree_add_text (lsa_tree, tvb, offset+23, 1, "Flags : %s",
717 val_to_str (tvb_get_guint8 (tvb, offset+23),
718 fc_swils_fspf_lsrflags_val, "0x%x"));
719 num_lsrechdr = tvb_get_ntohl (tvb, offset+24);
721 proto_tree_add_text (lsa_tree, tvb, offset+24, 4, "Num of LSR Headers: %d",
726 for (i = 0; i < num_lsrechdr; i++) {
727 subti = proto_tree_add_text (lsa_tree, tvb, offset, 24,
728 "Link State Record Header (Domain %d)",
729 tvb_get_guint8 (tvb, offset+15));
730 lsrechdr_tree = proto_item_add_subtree (subti,
731 ett_fcswils_lsrechdr);
732 dissect_swils_fspf_lsrechdr (tvb, lsrechdr_tree, offset);
739 dissect_swils_rscn (tvbuff_t *tvb, proto_tree *rscn_tree, guint8 isreq)
741 /* Set up structures needed to add the protocol subtree and manage it */
743 proto_tree *dev_tree;
752 evtype = tvb_get_guint8 (tvb, offset+4);
753 addrfmt = evtype & 0x0F;
754 evtype = evtype >> 4;
756 proto_tree_add_item (rscn_tree, hf_swils_rscn_evtype, tvb, offset+4,
758 proto_tree_add_item (rscn_tree, hf_swils_rscn_addrfmt, tvb, offset+4,
760 proto_tree_add_string (rscn_tree, hf_swils_rscn_affectedport, tvb,
761 offset+5, 3, fc_to_str (tvb_get_ptr (tvb,
763 proto_tree_add_item (rscn_tree, hf_swils_rscn_detectfn, tvb,
765 numrec = tvb_get_ntohl (tvb, offset+12);
767 if (!tvb_bytes_exist (tvb, offset+16, FC_SWILS_RSCN_DEVENTRY_SIZE*numrec)) {
768 /* Some older devices do not include device entry information. */
772 proto_tree_add_text (rscn_tree, tvb, offset+12, 4, "Num Entries: %d",
776 for (i = 0; i < numrec; i++) {
777 subti = proto_tree_add_text (rscn_tree, tvb, offset, 20,
778 "Device Entry %d", i);
779 dev_tree = proto_item_add_subtree (rscn_tree, ett_fcswils_rscn_dev);
781 proto_tree_add_item (dev_tree, hf_swils_rscn_portstate, tvb, offset, 1, 0);
782 proto_tree_add_string (dev_tree, hf_swils_rscn_portid, tvb, offset+1, 3,
783 fc_to_str (tvb_get_ptr (tvb, offset+1, 3)));
784 proto_tree_add_string (dev_tree, hf_swils_rscn_pwwn, tvb, offset+4, 8,
785 fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8)));
786 proto_tree_add_string (dev_tree, hf_swils_rscn_nwwn, tvb, offset+4, 8,
787 fcwwn_to_str (tvb_get_ptr (tvb, offset+4, 8)));
794 * Merge Request contains zoning objects organized in the following format:
798 * +---------------- Zone Object
800 * +-- +---------------- Zone Member
804 * So the decoding of the zone merge request is based on this structure
808 dissect_swils_zone_mbr (tvbuff_t *tvb, proto_tree *zmbr_tree, int offset)
810 int mbrlen = 4 + tvb_get_guint8 (tvb, offset+3);
812 proto_tree_add_item (zmbr_tree, hf_swils_zone_mbrtype, tvb,
814 proto_tree_add_text (zmbr_tree, tvb, offset+2, 1, "Flags: 0x%x",
815 tvb_get_guint8 (tvb, offset+2));
816 proto_tree_add_text (zmbr_tree, tvb, offset+3, 1,
817 "Identifier Length: %d",
818 tvb_get_guint8 (tvb, offset+3));
819 switch (tvb_get_guint8 (tvb, offset)) {
820 case FC_SWILS_ZONEMBR_WWN:
821 proto_tree_add_string (zmbr_tree, hf_swils_zone_mbrid, tvb,
823 fcwwn_to_str (tvb_get_ptr (tvb,
827 case FC_SWILS_ZONEMBR_DP:
828 proto_tree_add_string_format (zmbr_tree,
830 tvb, offset+4, 4, " ",
835 case FC_SWILS_ZONEMBR_FCID:
836 proto_tree_add_string (zmbr_tree, hf_swils_zone_mbrid, tvb,
838 fc_to_str (tvb_get_ptr (tvb,
842 case FC_SWILS_ZONEMBR_ALIAS:
843 proto_tree_add_string (zmbr_tree, hf_swils_zone_mbrid, tvb,
845 tvb_get_guint8 (tvb, offset+3),
846 zonenm_to_str (tvb, offset+4));
848 case FC_SWILS_ZONEMBR_WWN_LUN:
849 proto_tree_add_string (zmbr_tree, hf_swils_zone_mbrid, tvb,
851 fcwwn_to_str (tvb_get_ptr (tvb,
854 proto_tree_add_item (zmbr_tree, hf_swils_zone_mbrid_lun, tvb,
857 case FC_SWILS_ZONEMBR_DP_LUN:
858 proto_tree_add_string_format (zmbr_tree,
860 tvb, offset+4, 4, " ",
864 proto_tree_add_item (zmbr_tree, hf_swils_zone_mbrid_lun, tvb,
867 case FC_SWILS_ZONEMBR_FCID_LUN:
868 proto_tree_add_string (zmbr_tree, hf_swils_zone_mbrid, tvb,
870 fc_to_str (tvb_get_ptr (tvb,
873 proto_tree_add_item (zmbr_tree, hf_swils_zone_mbrid_lun, tvb,
877 proto_tree_add_string (zmbr_tree, hf_swils_zone_mbrid, tvb,
879 "Unknown member type format");
885 dissect_swils_zone_obj (tvbuff_t *tvb, proto_tree *zobj_tree, int offset)
887 proto_tree *zmbr_tree;
888 int mbrlen, numrec, i, objtype;
891 objtype = tvb_get_guint8 (tvb, offset);
893 proto_tree_add_item (zobj_tree, hf_swils_zone_objtype, tvb, offset,
895 proto_tree_add_item (zobj_tree, hf_swils_zone_protocol, tvb,
897 proto_tree_add_string (zobj_tree, hf_swils_zone_objname, tvb,
898 offset+4, ZONENAME_LEN (tvb, offset+4),
899 zonenm_to_str (tvb, offset+4));
901 numrec = tvb_get_ntohl (tvb, offset+4+ZONENAME_LEN (tvb, offset+4));
902 proto_tree_add_text (zobj_tree, tvb,
903 offset+4+ZONENAME_LEN (tvb, offset+4), 4,
904 "Number of Zone Members: %d", numrec);
906 offset += 8 + ZONENAME_LEN (tvb, offset+4);
907 for (i = 0; i < numrec; i++) {
908 if (objtype == FC_SWILS_ZONEOBJ_ZONESET) {
909 dissect_swils_zone_obj (tvb, zobj_tree, offset);
910 offset += get_zoneobj_len (tvb, offset);
913 mbrlen = 4 + tvb_get_guint8 (tvb, offset+3);
914 subti = proto_tree_add_text (zobj_tree, tvb, offset, mbrlen,
915 "Zone Member %d", i);
916 zmbr_tree = proto_item_add_subtree (zobj_tree,
917 ett_fcswils_zonembr);
918 dissect_swils_zone_mbr (tvb, zmbr_tree, offset);
925 dissect_swils_mergereq (tvbuff_t *tvb, proto_tree *mr_tree, guint8 isreq)
927 /* Set up structures needed to add the protocol subtree and manage it */
929 proto_tree *zobjlist_tree, *zobj_tree;
930 int numrec, i, zonesetlen, objlistlen, objlen;
935 /* zonesetlen is the size of the zoneset including the zone name */
936 zonesetlen = tvb_get_ntohs (tvb, offset+2);
937 proto_tree_add_text (mr_tree, tvb, offset+2, 2,
938 "Active ZoneSet Length: %d", zonesetlen);
941 proto_tree_add_string (mr_tree, hf_swils_zone_activezonenm, tvb,
942 offset+4, ZONENAME_LEN (tvb, offset+4),
943 zonenm_to_str (tvb, offset+4));
945 /* objlistlen gives the size of the active zoneset object list */
946 objlistlen = zonesetlen - ZONENAME_LEN (tvb, offset+4);
947 /* Offset = start of the active zoneset zoning object list */
948 offset = offset + (4 + ZONENAME_LEN (tvb, offset+4));
949 numrec = tvb_get_ntohl (tvb, offset);
951 subti = proto_tree_add_text (mr_tree, tvb, offset, objlistlen,
953 zobjlist_tree = proto_item_add_subtree (subti,
954 ett_fcswils_zoneobjlist);
956 proto_tree_add_text (zobjlist_tree, tvb, offset, 4,
957 "Number of zoning objects: %d", numrec);
960 for (i = 0; i < numrec; i++) {
961 objlen = get_zoneobj_len (tvb, offset);
962 subti = proto_tree_add_text (zobjlist_tree, tvb, offset+4,
963 objlen, "Zone Object %d", i);
964 zobj_tree = proto_item_add_subtree (subti, ett_fcswils_zoneobj);
965 dissect_swils_zone_obj (tvb, zobj_tree, offset);
973 zonesetlen = tvb_get_ntohl (tvb, offset);
974 proto_tree_add_text (mr_tree, tvb, offset, 4,
975 "Full Zone Set Length: %d", zonesetlen);
978 objlistlen = zonesetlen;
979 /* Offset = start of the active zoneset zoning object list */
981 numrec = tvb_get_ntohl (tvb, offset);
983 subti = proto_tree_add_text (mr_tree, tvb, offset, objlistlen,
986 zobjlist_tree = proto_item_add_subtree (subti,
987 ett_fcswils_zoneobjlist);
988 proto_tree_add_text (zobjlist_tree, tvb, offset, 4,
989 "Number of zoning objects: %d", numrec);
991 for (i = 0; i < numrec; i++) {
992 objlen = get_zoneobj_len (tvb, offset);
993 subti = proto_tree_add_text (zobjlist_tree, tvb, offset,
994 objlen, "Zone Object %d", i);
995 zobj_tree = proto_item_add_subtree (subti, ett_fcswils_zoneobj);
996 dissect_swils_zone_obj (tvb, zobj_tree, offset);
1002 proto_tree_add_item (mr_tree, hf_swils_zone_status, tvb,
1004 proto_tree_add_item (mr_tree, hf_swils_zone_reason, tvb,
1006 proto_tree_add_text (mr_tree, tvb, offset+7, 1,
1007 "Vendor Unique: 0x%x",
1008 tvb_get_guint8 (tvb, offset+7));
1014 dissect_swils_aca (tvbuff_t *tvb, proto_tree *aca_tree, guint8 isreq)
1016 /* Set up structures needed to add the protocol subtree and manage it */
1018 int numrec, plen, i;
1022 plen = tvb_get_ntohs (tvb, offset+2);
1023 proto_tree_add_text (aca_tree, tvb, offset+2, 2,
1024 "Domain ID List Length: %d", plen);
1028 for (i = 0; i < numrec; i++) {
1029 proto_tree_add_uint_format (aca_tree, hf_swils_aca_domainid,
1031 tvb_get_guint8 (tvb, offset+3),
1032 "Domain ID %d: %d", i,
1033 tvb_get_guint8 (tvb, offset+3));
1038 proto_tree_add_item (aca_tree, hf_swils_zone_status, tvb,
1040 proto_tree_add_item (aca_tree, hf_swils_zone_reason, tvb,
1042 proto_tree_add_text (aca_tree, tvb, offset+7, 1,
1043 "Vendor Unique: 0x%x",
1044 tvb_get_guint8 (tvb, offset+7));
1050 dissect_swils_rca (tvbuff_t *tvb, proto_tree *rca_tree, guint8 isreq)
1052 /* Set up structures needed to add the protocol subtree and manage it */
1057 proto_tree_add_item (rca_tree, hf_swils_zone_status, tvb,
1059 proto_tree_add_item (rca_tree, hf_swils_zone_reason, tvb,
1061 proto_tree_add_text (rca_tree, tvb, offset+7, 1,
1062 "Vendor Unique: 0x%x",
1063 tvb_get_guint8 (tvb, offset+7));
1069 dissect_swils_sfc (tvbuff_t *tvb, proto_tree *sfc_tree, guint8 isreq)
1071 /* Set up structures needed to add the protocol subtree and manage it */
1073 proto_tree *zobjlist_tree, *zobj_tree;
1074 int numrec, i, zonesetlen, objlistlen, objlen;
1079 proto_tree_add_item (sfc_tree, hf_swils_sfc_opcode, tvb, offset+1, 1, 0);
1081 zonesetlen = tvb_get_ntohs (tvb, offset+2);
1082 proto_tree_add_text (sfc_tree, tvb, offset+2, 2,
1083 "ZoneSet Length: %d", zonesetlen);
1086 proto_tree_add_string (sfc_tree, hf_swils_sfc_zonenm, tvb,
1087 offset+4, ZONENAME_LEN (tvb, offset+4),
1088 zonenm_to_str (tvb, offset+4));
1090 /* objlistlen gives the size of the active zoneset object list */
1091 objlistlen = zonesetlen - ZONENAME_LEN (tvb, offset+4);
1092 /* Offset = start of the active zoneset zoning object list */
1093 offset = offset + (4 + ZONENAME_LEN (tvb, offset+4));
1094 numrec = tvb_get_ntohl (tvb, offset);
1096 subti = proto_tree_add_text (sfc_tree, tvb, offset, objlistlen,
1098 zobjlist_tree = proto_item_add_subtree (subti,
1099 ett_fcswils_zoneobjlist);
1101 proto_tree_add_text (zobjlist_tree, tvb, offset, 4,
1102 "Number of zoning objects: %d", numrec);
1105 for (i = 0; i < numrec; i++) {
1106 objlen = get_zoneobj_len (tvb, offset);
1107 subti = proto_tree_add_text (zobjlist_tree, tvb, offset,
1108 objlen, "Zone Object %d", i);
1109 zobj_tree = proto_item_add_subtree (subti, ett_fcswils_zoneobj);
1110 dissect_swils_zone_obj (tvb, zobj_tree, offset);
1118 zonesetlen = tvb_get_ntohl (tvb, offset);
1119 proto_tree_add_text (sfc_tree, tvb, offset, 4,
1120 "Full Zone Set Length: %d", zonesetlen);
1123 objlistlen = zonesetlen;
1124 /* Offset = start of the active zoneset zoning object list */
1126 numrec = tvb_get_ntohl (tvb, offset);
1128 subti = proto_tree_add_text (sfc_tree, tvb, offset, objlistlen,
1131 zobjlist_tree = proto_item_add_subtree (subti,
1132 ett_fcswils_zoneobjlist);
1133 proto_tree_add_text (zobjlist_tree, tvb, offset, 4,
1134 "Number of zoning objects: %d", numrec);
1136 for (i = 0; i < numrec; i++) {
1137 objlen = get_zoneobj_len (tvb, offset);
1138 subti = proto_tree_add_text (zobjlist_tree, tvb, offset,
1139 objlen, "Zone Object %d", i);
1140 zobj_tree = proto_item_add_subtree (subti, ett_fcswils_zoneobj);
1141 dissect_swils_zone_obj (tvb, zobj_tree, offset);
1147 proto_tree_add_item (sfc_tree, hf_swils_zone_status, tvb,
1149 proto_tree_add_item (sfc_tree, hf_swils_zone_reason, tvb,
1151 proto_tree_add_text (sfc_tree, tvb, offset+7, 1,
1152 "Vendor Unique: 0x%x",
1153 tvb_get_guint8 (tvb, offset+7));
1159 dissect_swils_ufc (tvbuff_t *tvb, proto_tree *ufc_tree, guint8 isreq)
1161 /* Set up structures needed to add the protocol subtree and manage it */
1166 proto_tree_add_item (ufc_tree, hf_swils_zone_status, tvb,
1168 proto_tree_add_item (ufc_tree, hf_swils_zone_reason, tvb,
1170 proto_tree_add_text (ufc_tree, tvb, offset+7, 1,
1171 "Vendor Unique: 0x%x",
1172 tvb_get_guint8 (tvb, offset+7));
1178 dissect_swils_esc (tvbuff_t *tvb, proto_tree *esc_tree, guint8 isreq)
1180 /* Set up structures needed to add the protocol subtree and manage it */
1182 int i, numrec, plen;
1183 proto_tree *pdesc_tree;
1188 plen = tvb_get_ntohs (tvb, offset+2);
1189 proto_tree_add_text (esc_tree, tvb, offset+2, 2,
1190 "Payload Length: %d", plen);
1191 proto_tree_add_item (esc_tree, hf_swils_esc_swvendorid, tvb,
1193 numrec = (plen - 12)/12;
1196 for (i = 0; i < numrec; i++) {
1197 subti = proto_tree_add_text (esc_tree, tvb, offset, 12,
1198 "Protocol Descriptor %d", i);
1199 pdesc_tree = proto_item_add_subtree (subti,
1200 ett_fcswils_esc_pdesc);
1201 proto_tree_add_item (pdesc_tree, hf_swils_esc_pdesc_vendorid, tvb,
1203 proto_tree_add_item (pdesc_tree, hf_swils_esc_protocolid,
1204 tvb, offset+10, 2, 0);
1209 proto_tree_add_item (esc_tree, hf_swils_esc_swvendorid, tvb,
1211 subti = proto_tree_add_text (esc_tree, tvb, offset+12, 12,
1212 "Accepted Protocol Descriptor");
1213 pdesc_tree = proto_item_add_subtree (subti, ett_fcswils_esc_pdesc);
1215 proto_tree_add_item (pdesc_tree, hf_swils_esc_pdesc_vendorid, tvb,
1217 proto_tree_add_item (pdesc_tree, hf_swils_esc_protocolid,
1218 tvb, offset+22, 2, 0);
1224 dissect_swils_drlir (tvbuff_t *tvb _U_, proto_tree *drlir_tree _U_,
1227 /* Set up structures needed to add the protocol subtree and manage it */
1232 dissect_swils_swrjt (tvbuff_t *tvb, proto_tree *swrjt_tree)
1234 /* Set up structures needed to add the protocol subtree and manage it */
1238 proto_tree_add_item (swrjt_tree, hf_swils_rjt, tvb, offset+5, 1, 0);
1239 proto_tree_add_item (swrjt_tree, hf_swils_rjtdet, tvb, offset+6, 1, 0);
1240 proto_tree_add_item (swrjt_tree, hf_swils_rjtvendor, tvb, offset+7,
1245 /* Code to actually dissect the packets */
1247 dissect_fcswils (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1249 proto_item *ti = NULL;
1253 conversation_t *conversation;
1254 fcswils_conv_data_t *cdata;
1255 fcswils_conv_key_t ckey, *req_key;
1256 proto_tree *swils_tree = NULL;
1257 guint8 isreq = FC_SWILS_REQ;
1260 /* Make entries in Protocol column and Info column on summary display */
1261 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1262 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SW_ILS");
1264 /* decoding of this is done by each individual opcode handler */
1265 opcode = tvb_get_guint8 (tvb, 0);
1268 ti = proto_tree_add_protocol_format (tree, proto_fcswils, tvb, 0,
1269 tvb_length (tvb), "SW_ILS");
1270 swils_tree = proto_item_add_subtree (ti, ett_fcswils);
1273 /* Register conversation if this is not a response */
1274 if ((opcode != FC_SWILS_SWACC) && (opcode != FC_SWILS_SWRJT)) {
1275 conversation = find_conversation (&pinfo->src, &pinfo->dst,
1276 pinfo->ptype, pinfo->oxid,
1277 pinfo->rxid, NO_PORT2);
1278 if (!conversation) {
1279 conversation = conversation_new (&pinfo->src, &pinfo->dst,
1280 pinfo->ptype, pinfo->oxid,
1281 pinfo->rxid, NO_PORT2);
1284 ckey.conv_idx = conversation->index;
1286 cdata = (fcswils_conv_data_t *)g_hash_table_lookup (fcswils_req_hash,
1289 /* Since we never free the memory used by an exchange, this maybe a
1290 * case of another request using the same exchange as a previous
1293 cdata->opcode = opcode;
1296 req_key = g_mem_chunk_alloc (fcswils_req_keys);
1297 req_key->conv_idx = conversation->index;
1299 cdata = g_mem_chunk_alloc (fcswils_req_vals);
1300 cdata->opcode = opcode;
1302 g_hash_table_insert (fcswils_req_hash, req_key, cdata);
1306 /* Opcode is ACC or RJT */
1307 conversation = find_conversation (&pinfo->src, &pinfo->dst,
1308 pinfo->ptype, pinfo->oxid,
1309 pinfo->rxid, NO_PORT2);
1310 isreq = FC_SWILS_RPLY;
1311 if (!conversation) {
1312 if (tree && (opcode == FC_SWILS_SWACC)) {
1313 /* No record of what this accept is for. Can't decode */
1314 proto_tree_add_text (swils_tree, tvb, 0, tvb_length (tvb),
1315 "No record of Exchg. Unable to decode SW_ACC");
1320 ckey.conv_idx = conversation->index;
1322 cdata = (fcswils_conv_data_t *)g_hash_table_lookup (fcswils_req_hash, &ckey);
1324 if (cdata != NULL) {
1325 if (opcode == FC_SWILS_SWACC)
1326 opcode = cdata->opcode;
1328 failed_opcode = cdata->opcode;
1332 if ((cdata == NULL) && (opcode != FC_SWILS_SWRJT)) {
1333 /* No record of what this accept is for. Can't decode */
1334 proto_tree_add_text (swils_tree, tvb, 0, tvb_length (tvb),
1335 "No record of SW_ILS Req. Unable to decode SW_ACC");
1342 if (check_col (pinfo->cinfo, COL_INFO)) {
1343 if (isreq == FC_SWILS_REQ) {
1344 col_add_str (pinfo->cinfo, COL_INFO,
1345 val_to_str (opcode, fc_swils_opcode_key_val, "0x%x"));
1347 else if (opcode == FC_SWILS_SWRJT) {
1348 col_add_fstr (pinfo->cinfo, COL_INFO, "SW_RJT (%s)",
1349 val_to_str (failed_opcode, fc_swils_opcode_key_val, "0x%x"));
1352 col_add_fstr (pinfo->cinfo, COL_INFO, "SW_ACC (%s)",
1353 val_to_str (opcode, fc_swils_opcode_key_val, "0x%x"));
1358 proto_tree_add_item (swils_tree, hf_swils_opcode, tvb, offset, 1, 0);
1362 case FC_SWILS_SWRJT:
1363 dissect_swils_swrjt (tvb, swils_tree);
1366 dissect_swils_elp (tvb, swils_tree, isreq);
1369 dissect_swils_efp (tvb, swils_tree, isreq);
1372 dissect_swils_dia (tvb, swils_tree, isreq);
1375 dissect_swils_rdi (tvb, swils_tree, isreq);
1378 dissect_swils_hello (tvb, swils_tree, isreq);
1381 dissect_swils_lsupdate (tvb, swils_tree, isreq);
1384 dissect_swils_lsack (tvb, swils_tree, isreq);
1388 /* Nothing to be displayed for these two commands */
1391 dissect_swils_rscn (tvb, swils_tree, isreq);
1393 case FC_SWILS_DRLIR:
1394 dissect_swils_drlir (tvb, swils_tree, isreq);
1397 dissect_swils_mergereq (tvb, swils_tree, isreq);
1400 dissect_swils_aca (tvb, swils_tree, isreq);
1403 dissect_swils_rca (tvb, swils_tree, isreq);
1406 dissect_swils_sfc (tvb, swils_tree, isreq);
1409 dissect_swils_ufc (tvb, swils_tree, isreq);
1412 dissect_swils_esc (tvb, swils_tree, isreq);
1415 next_tvb = tvb_new_subset (tvb, offset+4, -1, -1);
1416 call_dissector (data_handle, next_tvb, pinfo, tree);
1421 /* Register the protocol with Ethereal */
1423 /* this format is require because a script is used to build the C function
1424 that calls all the protocol registration.
1428 proto_register_fcswils (void)
1430 /* Setup list of header fields See Section 1.6.1 for details*/
1431 static hf_register_info hf[] = {
1433 {"Cmd Code", "swils.opcode", FT_UINT8, BASE_HEX,
1434 VALS (fc_swils_opcode_key_val), 0x0, "", HFILL}},
1435 { &hf_swils_elp_rev,
1436 {"Revision", "swils.elp.rev", FT_UINT8, BASE_DEC, NULL,
1438 { &hf_swils_elp_flags,
1439 {"Flag", "swils.elp.flag", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL}},
1440 { &hf_swils_elp_r_a_tov,
1441 {"R_A_TOV", "swils.elp.ratov", FT_UINT32, BASE_DEC, NULL,
1443 { &hf_swils_elp_e_d_tov,
1444 {"E_D_TOV", "swils.elp.edtov", FT_UINT32, BASE_DEC, NULL, 0x0, "",
1446 { &hf_swils_elp_req_epn,
1447 {"Req Eport Name", "swils.elp.reqepn", FT_STRING, BASE_HEX, NULL, 0x0,
1449 { &hf_swils_elp_req_esn,
1450 {"Req Switch Name", "swils.elp.reqesn", FT_STRING, BASE_HEX, NULL, 0x0,
1452 { &hf_swils_elp_clsf_svcp,
1453 {"Class F Svc Param", "swils.elp.clsfp", FT_BYTES, BASE_NONE, NULL, 0x0,
1455 { &hf_swils_elp_clsf_rcvsz,
1456 {"Max Class F Frame Size", "swils.elp.clsfrsz", FT_UINT16, BASE_DEC,
1457 NULL, 0x0, "", HFILL}},
1458 { &hf_swils_elp_clsf_conseq,
1459 {"Class F Max Concurrent Seq", "swils.elp.clsfcs", FT_UINT16, BASE_DEC,
1460 NULL, 0x0, "", HFILL}},
1461 { &hf_swils_elp_clsf_e2e,
1462 {"Class F E2E Credit", "swils.elp.cfe2e", FT_UINT16, BASE_DEC, NULL,
1464 { &hf_swils_elp_clsf_openseq,
1465 {"Class F Max Open Seq", "swils.elp.oseq", FT_UINT16, BASE_DEC, NULL,
1467 { &hf_swils_elp_cls1_svcp,
1468 {"Class 1 Svc Param", "swils.elp.cls1p", FT_BYTES, BASE_NONE, NULL, 0x0,
1470 { &hf_swils_elp_cls1_rcvsz,
1471 {"Class 1 Frame Size", "swils.elp.cls1rsz", FT_UINT16, BASE_DEC, NULL,
1473 { &hf_swils_elp_cls2_svcp,
1474 {"Class 2 Svc Param", "swils.elp.cls2p", FT_BYTES, BASE_HEX, NULL, 0x0,
1476 { &hf_swils_elp_cls2_rcvsz,
1477 {"Class 2 Frame Size", "swils.elp.cls1rsz", FT_UINT16, BASE_DEC, NULL,
1479 { &hf_swils_elp_cls3_svcp,
1480 {"Class 3 Svc Param", "swils.elp.cls3p", FT_BYTES, BASE_HEX, NULL, 0x0,
1482 { &hf_swils_elp_cls3_rcvsz,
1483 {"Class 3 Frame Size", "swils.elp.cls1rsz", FT_UINT16, BASE_DEC, NULL,
1485 { &hf_swils_elp_isl_fc_mode,
1486 {"ISL Flow Ctrl Mode", "swils.elp.fcmode", FT_STRING, BASE_HEX, NULL,
1488 { &hf_swils_elp_fcplen,
1489 {"Flow Ctrl Param Len", "swils.elp.fcplen", FT_UINT16, BASE_DEC, NULL,
1491 { &hf_swils_elp_b2bcredit,
1492 {"B2B Credit", "swils.elp.b2b", FT_UINT32, BASE_DEC, NULL, 0x0, "",
1494 { &hf_swils_elp_compat1,
1495 {"Compatability Param 1", "swils.elp.compat1", FT_UINT32, BASE_DEC, NULL,
1497 { &hf_swils_elp_compat2,
1498 {"Compatability Param 2", "swils.elp.compat2", FT_UINT32, BASE_DEC, NULL,
1500 { &hf_swils_elp_compat3,
1501 {"Compatability Param 3", "swils.elp.compat3", FT_UINT32, BASE_DEC, NULL,
1503 { &hf_swils_elp_compat4,
1504 {"Compatability Param 4", "swils.elp.compat4", FT_UINT32, BASE_DEC, NULL,
1506 { &hf_swils_efp_rec_type,
1507 {"Record Type", "swils.efp.rectype", FT_UINT8, BASE_HEX,
1508 VALS (fcswils_rectype_val), 0x0, "", HFILL}},
1509 { &hf_swils_efp_dom_id,
1510 {"Domain ID", "swils.efp.domid", FT_UINT8, BASE_HEX, NULL, 0x0,
1512 { &hf_swils_efp_switch_name,
1513 {"Switch Name", "swils.efp.sname", FT_STRING, BASE_HEX, NULL, 0x0,
1515 { &hf_swils_efp_mcast_grpno,
1516 {"Mcast Grp#", "swils.efp.mcastno", FT_UINT8, BASE_HEX, NULL, 0x0,
1518 { &hf_swils_efp_alias_token,
1519 {"Alias Token", "swils.efp.aliastok", FT_BYTES, BASE_HEX, NULL, 0x0,
1521 { &hf_swils_efp_payload_len,
1522 {"Payload Len", "swils.efp.payloadlen", FT_UINT16, BASE_DEC, NULL, 0x0,
1524 { &hf_swils_efp_pswitch_pri,
1525 {"Principal Switch Priority", "swils.efp.psprio", FT_UINT8, BASE_DEC,
1526 NULL, 0x0, "", HFILL}},
1527 { &hf_swils_efp_pswitch_name,
1528 {"Principal Switch Name", "swils.efp.psname", FT_STRING, BASE_HEX, NULL,
1530 { &hf_swils_dia_switch_name,
1531 {"Switch Name", "swils.dia.sname", FT_STRING, BASE_HEX, NULL, 0x0,
1533 { &hf_swils_rdi_payload_len,
1534 {"Payload Len", "swils.rdi.len", FT_UINT16, BASE_DEC, NULL, 0x0, "",
1536 { &hf_swils_rdi_req_sname,
1537 {"Req Switch Name", "swils.rdi.reqsn", FT_STRING, BASE_HEX, NULL, 0x0,
1539 { &hf_swils_fspfh_cmd,
1540 {"Command: ", "swils.fspf.cmd", FT_UINT8, BASE_HEX, NULL, 0x0,
1542 { &hf_swils_fspfh_rev,
1543 {"Version", "swils.fspf.ver", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
1544 { &hf_swils_fspfh_ar_num,
1545 {"AR Number", "swils.fspf.arnum", FT_UINT8, BASE_HEX, NULL, 0x0, "",
1547 { &hf_swils_fspfh_auth_type,
1548 {"Authentication Type", "swils.fspf.authtype", FT_UINT8, BASE_HEX, NULL,
1550 { &hf_swils_fspfh_dom_id,
1551 {"Originating Domain ID", "swils.fspf.origdomid", FT_UINT8, BASE_DEC,
1552 NULL, 0x0, "", HFILL}},
1553 { &hf_swils_fspfh_auth,
1554 {"Authentication", "swils.fspf.auth", FT_BYTES, BASE_HEX, NULL, 0x0,
1556 { &hf_swils_hlo_options,
1557 {"Options", "swils.hlo.options", FT_BYTES, BASE_HEX, NULL, 0x0,
1559 { &hf_swils_hlo_hloint,
1560 {"Hello Interval (secs)", "swils.hlo.hloint", FT_UINT32, BASE_DEC,
1561 NULL, 0x0, "", HFILL}},
1562 { &hf_swils_hlo_deadint,
1563 {"Dead Interval (secs)", "swils.hlo.deadint", FT_UINT32, BASE_DEC,
1564 NULL, 0x0, "", HFILL}},
1565 { &hf_swils_hlo_rcv_domid,
1566 {"Recipient Domain ID", "swils.hlo.rcvdomid", FT_UINT8, BASE_DEC,
1567 NULL, 0x0, "", HFILL}},
1568 { &hf_swils_hlo_orig_pidx,
1569 {"Originating Port Idx", "swils.hlo.origpidx", FT_UINT24, BASE_HEX,
1570 NULL, 0x0, "", HFILL}},
1571 { &hf_swils_lsrh_lsr_type,
1572 {"LSR Type", "swils.lsr.type", FT_UINT8, BASE_HEX,
1573 VALS (fc_swils_fspf_linkrec_val), 0x0, "", HFILL}},
1574 { &hf_swils_lsrh_lsid,
1575 {"Link State Id", "swils.ls.id", FT_UINT8, BASE_DEC, NULL, 0x0,
1577 { &hf_swils_lsrh_adv_domid,
1578 {"Advertising Domain Id", "swils.lsr.advdomid", FT_UINT8, BASE_DEC,
1579 NULL, 0x0, "", HFILL}},
1580 { &hf_swils_lsrh_ls_incid,
1581 {"LS Incarnation Number", "swils.lsr.incid", FT_UINT32, BASE_DEC,
1582 NULL, 0x0, "", HFILL}},
1583 { &hf_swils_ldrec_linkid,
1584 {"Link ID", "swils.ldr.linkid", FT_STRING, BASE_HEX, NULL, 0x0,
1586 { &hf_swils_ldrec_out_pidx,
1587 {"Output Port Idx", "swils.ldr.out_portidx", FT_UINT24, BASE_HEX, NULL,
1589 { &hf_swils_ldrec_nbr_pidx,
1590 {"Neighbor Port Idx", "swils.ldr.nbr_portidx", FT_UINT24, BASE_HEX,
1591 NULL, 0x0, "", HFILL}},
1592 { &hf_swils_ldrec_link_type,
1593 {"Link Type", "swils.ldr.linktype", FT_UINT8, BASE_HEX,
1594 VALS (fc_swils_link_type_val), 0x0, "", HFILL}},
1595 { &hf_swils_ldrec_link_cost,
1596 {"Link Cost", "swils.ldr.linkcost", FT_UINT16, BASE_DEC, NULL, 0x0,
1598 { &hf_swils_rscn_evtype,
1599 {"Event Type", "swils.rscn.evtype", FT_UINT8, BASE_DEC,
1600 VALS (fc_swils_rscn_portstate_val), 0xF0, "", HFILL}},
1601 { &hf_swils_rscn_addrfmt,
1602 {"Address Format", "swils.rscn.addrfmt", FT_UINT8, BASE_DEC,
1603 VALS (fc_swils_rscn_addrfmt_val), 0x0F, "", HFILL}},
1604 { &hf_swils_rscn_affectedport,
1605 {"Affected Port ID", "swils.rscn.affectedport", FT_STRING, BASE_HEX,
1606 NULL, 0x0, "", HFILL}},
1607 { &hf_swils_rscn_detectfn,
1608 {"Detection Function", "swils.rscn.detectfn", FT_UINT32, BASE_HEX,
1609 VALS (fc_swils_rscn_detectfn_val), 0x0, "", HFILL}},
1610 { &hf_swils_rscn_portstate,
1611 {"Port State", "swils.rscn.portstate", FT_UINT8, BASE_HEX, NULL, 0x0,
1613 { &hf_swils_rscn_portid,
1614 {"Port Id", "swils.rscn.portid", FT_STRING, BASE_HEX, NULL, 0x0, "",
1616 { &hf_swils_rscn_pwwn,
1617 {"Port WWN", "swils.rscn.pwwn", FT_STRING, BASE_HEX, NULL, 0x0, "",
1619 { &hf_swils_rscn_nwwn,
1620 {"Node WWN", "swils.rscn.nwwn", FT_STRING, BASE_HEX, NULL, 0x0, "",
1622 { &hf_swils_esc_swvendorid,
1623 {"Switch Vendor ID", "swils.esc.swvendor", FT_STRING, BASE_HEX, NULL,
1625 { &hf_swils_esc_pdesc_vendorid,
1626 {"Vendor ID", "swils.esc.vendorid", FT_STRING, BASE_HEX, NULL, 0x0,
1628 { &hf_swils_esc_protocolid,
1629 {"Protocol ID", "swils.esc.protocol", FT_UINT16, BASE_HEX,
1630 VALS (fc_swils_esc_protocol_val), 0x0, "", HFILL}},
1631 { &hf_swils_zone_activezonenm,
1632 {"Active Zoneset Name", "swils.mr.activezonesetname", FT_STRING,
1633 BASE_HEX, NULL, 0x0, "", HFILL}},
1634 { &hf_swils_zone_objname,
1635 {"Zone Object Name", "swils.zone.zoneobjname", FT_STRING, BASE_HEX,
1636 NULL, 0x0, "", HFILL}},
1637 { &hf_swils_zone_objtype,
1638 {"Zone Object Type", "swils.zone.zoneobjtype", FT_UINT8, BASE_HEX,
1639 VALS (fc_swils_zoneobj_type_val), 0x0, "", HFILL}},
1640 { &hf_swils_zone_mbrtype,
1641 {"Zone Member Type", "swils.zone.mbrtype", FT_UINT8, BASE_HEX,
1642 VALS (fc_swils_zonembr_type_val), 0x0, "", HFILL}},
1643 { &hf_swils_zone_protocol,
1644 {"Zone Protocol", "swils.zone.protocol", FT_UINT8, BASE_HEX, NULL,
1646 { &hf_swils_zone_mbrid,
1647 {"Member Identifier", "swils.zone.mbrid", FT_STRING, BASE_HEX, NULL,
1649 { &hf_swils_zone_status,
1650 {"Zone Command Status", "swils.zone.status", FT_UINT8, BASE_HEX,
1651 VALS (fc_swils_mr_rsp_val), 0x0, "Applies to MR, ACA, RCA, SFC, UFC",
1653 { &hf_swils_zone_reason,
1654 {"Zone Command Reason Code", "swils.zone.reason", FT_UINT8, BASE_HEX,
1655 VALS (fc_swils_mr_reason_val), 0x0, "Applies to MR, ACA, RCA, SFC, UFC",
1657 { &hf_swils_aca_domainid,
1658 {"Known Domain ID", "swils.aca.domainid", FT_UINT8, BASE_HEX, NULL,
1660 { &hf_swils_sfc_opcode,
1661 {"Operation Request", "swils.sfc.opcode", FT_UINT8, BASE_HEX,
1662 VALS (fc_swils_sfc_op_val), 0x0, "", HFILL}},
1663 { &hf_swils_sfc_zonenm,
1664 {"Zone Set Name", "swils.sfc.zonename", FT_STRING, BASE_HEX, NULL,
1667 {"Reason Code", "swils.rjt.reason", FT_UINT8, BASE_HEX,
1668 VALS (fc_swils_rjt_val), 0x0, "", HFILL}},
1670 {"Reason Code Explanantion", "swils.rjt.reasonexpl", FT_UINT8,
1671 BASE_HEX, VALS (fc_swils_deterr_val), 0x0, "", HFILL}},
1672 { &hf_swils_rjtvendor,
1673 {"Vendor Unique Error Code", "swils.rjt.vendor", FT_UINT8, BASE_HEX,
1674 NULL, 0x0, "", HFILL}},
1675 { &hf_swils_zone_mbrid_lun,
1676 {"LUN", "swils.zone.lun", FT_BYTES, BASE_HEX, NULL, 0x0, "",
1680 /* Setup protocol subtree array */
1681 static gint *ett[] = {
1687 &ett_fcswils_efplist,
1690 &ett_fcswils_fspfhdr,
1693 &ett_fcswils_lsrechdr,
1700 &ett_fcswils_rscn_dev,
1703 &ett_fcswils_zoneobjlist,
1704 &ett_fcswils_zoneobj,
1705 &ett_fcswils_zonembr,
1711 &ett_fcswils_esc_pdesc,
1714 /* Register the protocol name and description */
1715 proto_fcswils = proto_register_protocol("Fibre Channel SW_ILS", "FC-SWILS", "swils");
1717 /* Required function calls to register the header fields and subtrees used */
1718 proto_register_field_array(proto_fcswils, hf, array_length(hf));
1719 proto_register_subtree_array(ett, array_length(ett));
1720 register_init_routine(&fcswils_init_protocol);
1723 /* If this dissector uses sub-dissector registration add a registration routine.
1724 This format is required because a script is used to find these routines and
1725 create the code that calls these routines.
1728 proto_reg_handoff_fcswils (void)
1730 dissector_handle_t swils_handle;
1732 swils_handle = create_dissector_handle (dissect_fcswils, proto_fcswils);
1733 dissector_add("fc.ftype", FC_FTYPE_SWILS, swils_handle);
1735 data_handle = find_dissector ("data");