2 * Routines for FC Fabric Zone Server
3 * Copyright 2001, Dinesh G Dutt <ddutt@andiamo.com>
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.
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-fcct.h"
38 #include "packet-fcfzs.h"
40 /* Initialize the protocol and registered fields */
41 static int proto_fcfzs
= -1;
42 static int hf_fcfzs_opcode
= -1;
43 static int hf_fcfzs_gzc_vendor
= -1;
44 static int hf_fcfzs_gest_vendor
= -1;
45 static int hf_fcfzs_numzoneattrs
= -1;
46 static int hf_fcfzs_zonesetnmlen
= -1;
47 static int hf_fcfzs_zonesetname
= -1;
48 static int hf_fcfzs_numzones
= -1;
49 static int hf_fcfzs_numzonesetattrs
= -1;
50 static int hf_fcfzs_zonenmlen
= -1;
51 static int hf_fcfzs_zonename
= -1;
52 static int hf_fcfzs_nummbrs
= -1;
53 static int hf_fcfzs_nummbrentries
= -1;
54 static int hf_fcfzs_mbrid
= -1;
55 /* static int hf_fcfzs_mbridlen = -1; */
56 static int hf_fcfzs_mbrtype
= -1;
57 static int hf_fcfzs_reason
= -1;
58 static int hf_fcfzs_rjtdetail
= -1;
59 static int hf_fcfzs_rjtvendor
= -1;
60 static int hf_fcfzs_maxres_size
= -1;
61 static int hf_fcfzs_mbrid_lun
= -1;
62 static int hf_fcfzs_gzc_flags
= -1;
63 static int hf_fcfzs_gzc_flags_hard_zones
= -1;
64 static int hf_fcfzs_gzc_flags_soft_zones
= -1;
65 static int hf_fcfzs_gzc_flags_zoneset_db
= -1;
66 static int hf_fcfzs_zone_state
= -1;
67 static int hf_fcfzs_soft_zone_set_enforced
= -1;
68 static int hf_fcfzs_hard_zone_set_enforced
= -1;
70 /* Initialize the subtree pointers */
71 static gint ett_fcfzs
= -1;
72 static gint ett_fcfzs_gzc_flags
= -1;
73 static gint ett_fcfzs_zone_state
= -1;
75 typedef struct _fcfzs_conv_key
{
79 typedef struct _fcfzs_conv_data
{
83 static GHashTable
*fcfzs_req_hash
= NULL
;
85 static dissector_handle_t data_handle
;
91 fcfzs_equal(gconstpointer v
, gconstpointer w
)
93 const fcfzs_conv_key_t
*v1
= (const fcfzs_conv_key_t
*)v
;
94 const fcfzs_conv_key_t
*v2
= (const fcfzs_conv_key_t
*)w
;
96 return (v1
->conv_idx
== v2
->conv_idx
);
100 fcfzs_hash(gconstpointer v
)
102 const fcfzs_conv_key_t
*key
= (const fcfzs_conv_key_t
*)v
;
111 * Protocol initialization
114 fcfzs_init_protocol(void)
117 g_hash_table_destroy(fcfzs_req_hash
);
119 fcfzs_req_hash
= g_hash_table_new(fcfzs_hash
, fcfzs_equal
);
122 /* Code to actually dissect the packets */
124 dissect_fcfzs_zoneset(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
126 int numzones
, nummbrs
, i
, j
, len
;
128 /* The zoneset structure has the following format */
129 /* zoneset name (len[not including pad], name, pad),
132 * Zone name (len[not including pad], name, pad), num zone mbrs
134 * zone mbr id type, zone mbr id (len, name, pad)
139 len
= tvb_get_guint8(tvb
, offset
);
140 proto_tree_add_item(tree
, hf_fcfzs_zonesetnmlen
, tvb
, offset
,
142 proto_tree_add_item(tree
, hf_fcfzs_zonesetname
, tvb
, offset
+4,
143 len
, ENC_ASCII
|ENC_NA
);
144 offset
+= 4 + len
+ (4-(len
% 4));
147 /* Number of zones */
148 numzones
= tvb_get_ntohl(tvb
, offset
);
149 proto_tree_add_item(tree
, hf_fcfzs_numzones
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
152 /* For each zone... */
153 for (i
= 0; i
< numzones
; i
++) {
154 len
= tvb_get_guint8(tvb
, offset
);
155 proto_tree_add_item(tree
, hf_fcfzs_zonenmlen
, tvb
, offset
,
157 proto_tree_add_item(tree
, hf_fcfzs_zonename
, tvb
, offset
+4,
158 len
, ENC_ASCII
|ENC_NA
);
159 offset
+= 4 + len
+ (4-(len
% 4));
161 nummbrs
= tvb_get_ntohl(tvb
, offset
);
162 proto_tree_add_item(tree
, hf_fcfzs_nummbrentries
, tvb
, offset
,
166 for (j
= 0; j
< nummbrs
; j
++) {
167 proto_tree_add_item(tree
, hf_fcfzs_mbrtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
169 switch (tvb_get_guint8(tvb
, offset
)) {
170 case FC_FZS_ZONEMBR_PWWN
:
171 case FC_FZS_ZONEMBR_NWWN
:
172 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
174 tvb_fcwwn_to_str(tvb
, offset
+4));
176 case FC_FZS_ZONEMBR_DP
:
177 proto_tree_add_string_format(tree
,
179 tvb
, offset
+4, 3, " ",
184 case FC_FZS_ZONEMBR_FCID
:
185 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
187 tvb_fc_to_str(tvb
, offset
+4));
189 case FC_FZS_ZONEMBR_PWWN_LUN
:
190 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
192 tvb_fcwwn_to_str(tvb
, offset
+4));
193 proto_tree_add_item(tree
, hf_fcfzs_mbrid_lun
, tvb
,
194 offset
+8, 8, ENC_NA
);
196 case FC_FZS_ZONEMBR_DP_LUN
:
197 proto_tree_add_string_format(tree
,
199 tvb
, offset
+4, 3, " ",
203 proto_tree_add_item(tree
, hf_fcfzs_mbrid_lun
, tvb
,
204 offset
+4, 8, ENC_NA
);
206 case FC_FZS_ZONEMBR_FCID_LUN
:
207 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
209 tvb_fc_to_str(tvb
, offset
+4));
210 proto_tree_add_item(tree
, hf_fcfzs_mbrid_lun
, tvb
,
211 offset
+4, 8, ENC_NA
);
214 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
216 "Unknown member type format");
226 dissect_fcfzs_gzc(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, gboolean isreq
)
230 proto_item
*item
= NULL
;
231 proto_tree
*tree
= NULL
;
233 flags
= tvb_get_guint8(tvb
, offset
);
235 item
= proto_tree_add_uint(parent_tree
, hf_fcfzs_gzc_flags
, tvb
, offset
, 1, flags
);
236 tree
= proto_item_add_subtree(item
, ett_fcfzs_gzc_flags
);
239 proto_tree_add_boolean(tree
, hf_fcfzs_gzc_flags_hard_zones
, tvb
, offset
, 1, flags
);
241 proto_item_append_text(item
, " Hard Zones");
243 flags
&= (~( 0x80 ));
245 proto_tree_add_boolean(tree
, hf_fcfzs_gzc_flags_soft_zones
, tvb
, offset
, 1, flags
);
247 proto_item_append_text(item
, " Soft Zones");
249 flags
&= (~( 0x40 ));
251 proto_tree_add_boolean(tree
, hf_fcfzs_gzc_flags_zoneset_db
, tvb
, offset
, 1, flags
);
253 proto_item_append_text(item
, " ZoneSet Database Available");
255 /*flags &= (~( 0x01 ));*/
257 proto_tree_add_item(tree
, hf_fcfzs_gzc_vendor
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
262 dissect_fcfzs_gest(tvbuff_t
*tvb
, proto_tree
*parent_tree
, gboolean isreq
)
264 int offset
= 16; /* past the fc_ct header */
268 proto_item
*item
= NULL
;
269 proto_tree
*tree
= NULL
;
271 flags
= tvb_get_guint8(tvb
, offset
);
273 item
= proto_tree_add_uint(parent_tree
, hf_fcfzs_zone_state
, tvb
, offset
, 1, flags
);
274 tree
= proto_item_add_subtree(item
, ett_fcfzs_zone_state
);
277 proto_tree_add_boolean(tree
, hf_fcfzs_soft_zone_set_enforced
, tvb
, offset
, 1, flags
);
279 proto_item_append_text(item
, " Soft Zone Set Enforced");
281 flags
&= (~( 0x80 ));
283 proto_tree_add_boolean(tree
, hf_fcfzs_hard_zone_set_enforced
, tvb
, offset
, 1, flags
);
285 proto_item_append_text(item
, " Hard Zone Set Enforced");
287 /*flags &= (~( 0x40 ));*/
290 proto_tree_add_item(parent_tree
, hf_fcfzs_gest_vendor
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
295 dissect_fcfzs_gzsn(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
298 int offset
= 16; /* past the fc_ct header */
302 numrec
= tvb_get_ntohl(tvb
, offset
);
304 proto_tree_add_item(tree
, hf_fcfzs_numzonesetattrs
, tvb
, offset
,
308 for (i
= 0; i
< numrec
; i
++) {
309 len
= tvb_get_guint8(tvb
, offset
);
310 proto_tree_add_item(tree
, hf_fcfzs_zonesetnmlen
, tvb
, offset
,
312 proto_tree_add_item(tree
, hf_fcfzs_zonesetname
, tvb
, offset
+1,
313 len
, ENC_ASCII
|ENC_NA
);
314 offset
+= len
+ 1 + (len
% 4);
315 proto_tree_add_item(tree
, hf_fcfzs_numzones
, tvb
, offset
,
324 dissect_fcfzs_gzd(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
327 int offset
= 16; /* past the fc_ct header */
331 len
= tvb_get_guint8(tvb
, offset
);
332 proto_tree_add_item(tree
, hf_fcfzs_zonesetnmlen
, tvb
, offset
,
334 proto_tree_add_item(tree
, hf_fcfzs_zonesetname
, tvb
, offset
+1,
335 len
, ENC_ASCII
|ENC_NA
);
338 numrec
= tvb_get_ntohl(tvb
, offset
);
340 proto_tree_add_item(tree
, hf_fcfzs_numzoneattrs
, tvb
, offset
,
344 for (i
= 0; i
< numrec
; i
++) {
345 len
= tvb_get_guint8(tvb
, offset
);
346 proto_tree_add_item(tree
, hf_fcfzs_zonenmlen
, tvb
, offset
,
348 proto_tree_add_item(tree
, hf_fcfzs_zonename
, tvb
, offset
+1,
349 len
, ENC_ASCII
|ENC_NA
);
350 offset
+= len
+ 1 + (len
% 4);
351 proto_tree_add_item(tree
, hf_fcfzs_nummbrs
, tvb
, offset
,
360 dissect_fcfzs_gzm(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
363 int offset
= 16; /* past the fc_ct header */
367 len
= tvb_get_guint8(tvb
, offset
);
368 proto_tree_add_item(tree
, hf_fcfzs_zonenmlen
, tvb
, offset
,
370 proto_tree_add_item(tree
, hf_fcfzs_zonename
, tvb
, offset
+1,
371 len
, ENC_ASCII
|ENC_NA
);
374 numrec
= tvb_get_ntohl(tvb
, offset
);
376 proto_tree_add_item(tree
, hf_fcfzs_nummbrentries
, tvb
, offset
,
379 for (i
= 0; i
< numrec
; i
++) {
380 proto_tree_add_item(tree
, hf_fcfzs_mbrtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
381 switch (tvb_get_guint8(tvb
, offset
)) {
382 case FC_FZS_ZONEMBR_PWWN
:
383 case FC_FZS_ZONEMBR_NWWN
:
384 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
386 tvb_fcwwn_to_str(tvb
, offset
+4));
388 case FC_FZS_ZONEMBR_DP
:
389 proto_tree_add_string_format(tree
,
391 tvb
, offset
+4, 3, " ",
396 case FC_FZS_ZONEMBR_FCID
:
397 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
399 tvb_fc_to_str(tvb
, offset
+4));
402 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
404 "Unknown member type format");
413 dissect_fcfzs_gazs(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
415 int offset
= 16; /* past the fc_ct header */
419 dissect_fcfzs_zoneset(tvb
, tree
, offset
);
425 dissect_fcfzs_gzs(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
427 int offset
= 16; /* past the fc_ct header */
432 len
= tvb_get_guint8(tvb
, offset
);
433 proto_tree_add_item(tree
, hf_fcfzs_zonesetnmlen
, tvb
, offset
,
435 proto_tree_add_item(tree
, hf_fcfzs_zonesetname
, tvb
, offset
+4,
436 len
, ENC_ASCII
|ENC_NA
);
439 dissect_fcfzs_zoneset(tvb
, tree
, offset
);
445 dissect_fcfzs_adzs(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
447 int offset
= 16; /* past the fc_ct header */
451 dissect_fcfzs_zoneset(tvb
, tree
, offset
);
457 dissect_fcfzs_azsd(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
459 int offset
= 16; /* past the fc_ct header */
463 dissect_fcfzs_zoneset(tvb
, tree
, offset
);
469 dissect_fcfzs_arzs(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
471 int offset
= 16; /* past the fc_ct header */
476 len
= tvb_get_guint8(tvb
, offset
);
477 proto_tree_add_item(tree
, hf_fcfzs_zonesetnmlen
, tvb
, offset
,
479 proto_tree_add_item(tree
, hf_fcfzs_zonesetname
, tvb
, offset
+4,
480 len
, ENC_ASCII
|ENC_NA
);
486 dissect_fcfzs_dzs(tvbuff_t
*tvb _U_
, proto_tree
*tree _U_
, gboolean isreq _U_
)
488 /* Both req & successful response contain just the FC_CT header */
493 dissect_fcfzs_arzm(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
495 int numrec
, i
, len
, plen
;
496 int offset
= 16; /* past the fc_ct header */
500 len
= tvb_get_guint8(tvb
, offset
);
501 proto_tree_add_item(tree
, hf_fcfzs_zonenmlen
, tvb
, offset
,
503 proto_tree_add_item(tree
, hf_fcfzs_zonename
, tvb
, offset
+1,
504 len
, ENC_ASCII
|ENC_NA
);
507 plen
= tvb_length(tvb
) - offset
- len
;
509 numrec
= plen
/12; /* each mbr rec is 12 bytes long */
512 for (i
= 0; i
< numrec
; i
++) {
513 proto_tree_add_item(tree
, hf_fcfzs_mbrtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
514 switch (tvb_get_guint8(tvb
, offset
)) {
515 case FC_FZS_ZONEMBR_PWWN
:
516 case FC_FZS_ZONEMBR_NWWN
:
517 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
519 tvb_fcwwn_to_str(tvb
, offset
+4));
521 case FC_FZS_ZONEMBR_DP
:
522 proto_tree_add_string_format(tree
,
524 tvb
, offset
+4, 3, " ",
529 case FC_FZS_ZONEMBR_FCID
:
530 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
532 tvb_fc_to_str(tvb
, offset
+4));
535 proto_tree_add_string(tree
, hf_fcfzs_mbrid
, tvb
,
537 "Unknown member type format");
546 dissect_fcfzs_arzd(tvbuff_t
*tvb
, proto_tree
*tree
, gboolean isreq
)
548 int offset
= 16; /* past the fc_ct header */
553 len
= tvb_get_guint8(tvb
, offset
);
554 proto_tree_add_item(tree
, hf_fcfzs_zonesetnmlen
, tvb
, offset
,
556 proto_tree_add_item(tree
, hf_fcfzs_zonesetname
, tvb
, offset
+4,
557 len
, ENC_ASCII
|ENC_NA
);
561 len
= tvb_get_guint8(tvb
, offset
);
562 proto_tree_add_item(tree
, hf_fcfzs_zonenmlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
563 proto_tree_add_item(tree
, hf_fcfzs_zonename
, tvb
, offset
+4,
564 len
, ENC_ASCII
|ENC_NA
);
570 dissect_fcfzs_rjt(tvbuff_t
*tvb
, proto_tree
*tree
)
575 proto_tree_add_item(tree
, hf_fcfzs_reason
, tvb
, offset
+13, 1, ENC_BIG_ENDIAN
);
576 proto_tree_add_item(tree
, hf_fcfzs_rjtdetail
, tvb
, offset
+14, 1, ENC_BIG_ENDIAN
);
577 proto_tree_add_item(tree
, hf_fcfzs_rjtvendor
, tvb
, offset
+15, 1, ENC_BIG_ENDIAN
);
582 dissect_fcfzs(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
585 /* Set up structures needed to add the protocol subtree and manage it */
587 proto_tree
*fcfzs_tree
= NULL
;
589 fc_ct_preamble cthdr
;
591 int failed_opcode
= 0;
592 conversation_t
*conversation
;
593 fcfzs_conv_data_t
*cdata
;
594 fcfzs_conv_key_t ckey
, *req_key
;
595 gboolean isreq
= TRUE
;
597 /* Make entries in Protocol column and Info column on summary display */
598 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Zone Server");
601 tvb_memcpy(tvb
, (guint8
*)&cthdr
, offset
, FCCT_PRMBL_SIZE
);
602 cthdr
.revision
= tvb_get_guint8(tvb
, offset
+1);
603 cthdr
.in_id
= tvb_get_ntoh24(tvb
, offset
);
604 cthdr
.opcode
= g_ntohs(cthdr
.opcode
);
605 opcode
= cthdr
.opcode
;
606 cthdr
.maxres_size
= g_ntohs(cthdr
.maxres_size
);
609 ti
= proto_tree_add_protocol_format(tree
, proto_fcfzs
, tvb
, 0,
612 fcfzs_tree
= proto_item_add_subtree(ti
, ett_fcfzs
);
613 proto_tree_add_item(fcfzs_tree
, hf_fcfzs_opcode
, tvb
, offset
+8, 2, ENC_BIG_ENDIAN
);
614 proto_tree_add_item(fcfzs_tree
, hf_fcfzs_maxres_size
, tvb
, offset
+10,
618 if ((opcode
!= FCCT_MSG_ACC
) && (opcode
!= FCCT_MSG_RJT
)) {
619 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
620 pinfo
->ptype
, pinfo
->oxid
,
621 pinfo
->rxid
, NO_PORT2
);
623 conversation
= conversation_new(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
624 pinfo
->ptype
, pinfo
->oxid
,
625 pinfo
->rxid
, NO_PORT2
);
628 ckey
.conv_idx
= conversation
->index
;
630 cdata
= (fcfzs_conv_data_t
*)g_hash_table_lookup(fcfzs_req_hash
,
633 /* Since we never free the memory used by an exchange, this maybe a
634 * case of another request using the same exchange as a previous
637 cdata
->opcode
= opcode
;
640 req_key
= wmem_new(wmem_file_scope(), fcfzs_conv_key_t
);
641 req_key
->conv_idx
= conversation
->index
;
643 cdata
= wmem_new(wmem_file_scope(), fcfzs_conv_data_t
);
644 cdata
->opcode
= opcode
;
646 g_hash_table_insert(fcfzs_req_hash
, req_key
, cdata
);
649 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(opcode
, fc_fzs_opcode_val
,
653 /* Opcode is ACC or RJT */
654 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
655 pinfo
->ptype
, pinfo
->oxid
,
656 pinfo
->rxid
, NO_PORT2
);
659 if (opcode
== FCCT_MSG_ACC
) {
660 col_add_str(pinfo
->cinfo
, COL_INFO
,
661 val_to_str(opcode
, fc_fzs_opcode_val
,
663 /* No record of what this accept is for. Can't decode */
664 proto_tree_add_text(fcfzs_tree
, tvb
, 0, tvb_length(tvb
),
665 "No record of Exchg. Unable to decode MSG_ACC");
670 ckey
.conv_idx
= conversation
->index
;
672 cdata
= (fcfzs_conv_data_t
*)g_hash_table_lookup(fcfzs_req_hash
, &ckey
);
675 if (opcode
== FCCT_MSG_ACC
)
676 opcode
= cdata
->opcode
;
678 failed_opcode
= cdata
->opcode
;
681 if (opcode
!= FCCT_MSG_RJT
) {
682 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MSG_ACC (%s)",
684 fc_fzs_opcode_val
, "0x%x"));
687 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MSG_RJT (%s)",
688 val_to_str(failed_opcode
,
689 fc_fzs_opcode_val
, "0x%x"));
692 if ((cdata
== NULL
) && (opcode
!= FCCT_MSG_RJT
)) {
693 /* No record of what this accept is for. Can't decode */
694 proto_tree_add_text(fcfzs_tree
, tvb
, 0, tvb_length(tvb
),
695 "No record of Exchg. Unable to decode MSG_ACC/RJT");
703 dissect_fcfzs_rjt(tvb
, fcfzs_tree
);
706 dissect_fcfzs_gzc(tvb
, 16, fcfzs_tree
, isreq
);
709 dissect_fcfzs_gest(tvb
, fcfzs_tree
, isreq
);
712 dissect_fcfzs_gzsn(tvb
, fcfzs_tree
, isreq
);
715 dissect_fcfzs_gzd(tvb
, fcfzs_tree
, isreq
);
718 dissect_fcfzs_gzm(tvb
, fcfzs_tree
, isreq
);
721 dissect_fcfzs_gazs(tvb
, fcfzs_tree
, isreq
);
724 dissect_fcfzs_gzs(tvb
, fcfzs_tree
, isreq
);
727 dissect_fcfzs_adzs(tvb
, fcfzs_tree
, isreq
);
730 dissect_fcfzs_azsd(tvb
, fcfzs_tree
, isreq
);
733 dissect_fcfzs_arzs(tvb
, fcfzs_tree
, isreq
);
736 dissect_fcfzs_dzs(tvb
, fcfzs_tree
, isreq
);
739 dissect_fcfzs_arzm(tvb
, fcfzs_tree
, isreq
);
742 dissect_fcfzs_arzd(tvb
, fcfzs_tree
, isreq
);
745 dissect_fcfzs_arzm(tvb
, fcfzs_tree
, isreq
);
748 dissect_fcfzs_arzd(tvb
, fcfzs_tree
, isreq
);
751 dissect_fcfzs_arzs(tvb
, fcfzs_tree
, isreq
);
754 call_dissector(data_handle
, tvb
, pinfo
, tree
);
759 /* Register the protocol with Wireshark */
762 proto_register_fcfzs(void)
765 static hf_register_info hf
[] = {
767 {"Opcode", "fcfzs.opcode",
768 FT_UINT16
, BASE_HEX
, VALS(fc_fzs_opcode_val
), 0x0,
771 { &hf_fcfzs_gzc_vendor
,
772 {"Vendor Specific Flags", "fcfzs.gzc.vendor",
773 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
776 { &hf_fcfzs_gest_vendor
,
777 {"Vendor Specific State", "fcfzs.gest.vendor",
778 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
781 { &hf_fcfzs_numzoneattrs
,
782 {"Number of Zone Attribute Entries", "fcfzs.zone.numattrs",
783 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
786 { &hf_fcfzs_zonesetnmlen
,
787 {"Zone Set Name Length", "fcfzs.zoneset.namelen",
788 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
791 { &hf_fcfzs_zonesetname
,
792 {"Zone Set Name", "fcfzs.zoneset.name",
793 FT_STRING
, BASE_NONE
, NULL
, 0x0,
796 { &hf_fcfzs_numzones
,
797 {"Number of Zones", "fcfzs.zoneset.numzones",
798 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
801 { &hf_fcfzs_numzonesetattrs
,
802 {"Number of Zone Set Attribute Entries", "fcfzs.zoneset.numattrs",
803 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
806 { &hf_fcfzs_zonenmlen
,
807 {"Zone Name Length", "fcfzs.zone.namelen",
808 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
811 { &hf_fcfzs_zonename
,
812 {"Zone Name", "fcfzs.zone.name",
813 FT_STRING
, BASE_NONE
, NULL
, 0x0,
817 {"Number of Zone Members", "fcfzs.zone.nummbrs",
818 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
821 { &hf_fcfzs_nummbrentries
,
822 {"Number of Zone Member Attribute Entries", "fcfzs.zonembr.numattrs",
823 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
827 {"Zone Member Identifier Type", "fcfzs.zonembr.idtype",
828 FT_UINT8
, BASE_HEX
, VALS(fc_fzs_zonembr_type_val
), 0x0,
832 { &hf_fcfzs_mbridlen
,
833 {"Zone Member Identifier Length", "fcfzs.zonembr.idlen",
834 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
839 {"Zone Member Identifier", "fcfzs.zone.mbrid",
840 FT_STRING
, BASE_NONE
, NULL
, 0x0,
844 {"Reason Code", "fcfzs.reason",
845 FT_UINT8
, BASE_HEX
, VALS(fc_ct_rjt_code_vals
), 0x0,
848 { &hf_fcfzs_rjtdetail
,
849 {"Reason Code Explanation", "fcfzs.rjtdetail",
850 FT_UINT8
, BASE_HEX
, VALS(fc_fzs_rjt_code_val
), 0x0,
853 { &hf_fcfzs_rjtvendor
,
854 {"Vendor Specific Reason", "fcfzs.rjtvendor",
855 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
858 { &hf_fcfzs_maxres_size
,
859 {"Maximum/Residual Size", "fcfzs.maxres_size",
860 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
863 { &hf_fcfzs_mbrid_lun
,
864 {"LUN", "fcfzs.zone.lun",
865 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
868 { &hf_fcfzs_gzc_flags
,
869 {"Capabilities", "fcfzs.gzc.flags",
870 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
873 { &hf_fcfzs_gzc_flags_hard_zones
,
874 {"Hard Zones", "fcfzs.gzc.flags.hard_zones",
875 FT_BOOLEAN
, 8, TFS(&tfs_supported_not_supported
), 0x80,
878 { &hf_fcfzs_gzc_flags_soft_zones
,
879 {"Soft Zones", "fcfzs.gzc.flags.soft_zones",
880 FT_BOOLEAN
, 8, TFS(&tfs_supported_not_supported
), 0x40,
883 { &hf_fcfzs_gzc_flags_zoneset_db
,
884 {"ZoneSet Database", "fcfzs.gzc.flags.zoneset_db",
885 FT_BOOLEAN
, 8, TFS(&tfs_available_not_available
), 0x01,
888 { &hf_fcfzs_zone_state
,
889 {"Zone State", "fcfzs.zone.state",
890 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
893 { &hf_fcfzs_soft_zone_set_enforced
,
894 {"Soft Zone Set", "fcfzs.soft_zone_set.enforced",
895 FT_BOOLEAN
, 8, TFS(&tfs_enforced_not_enforced
), 0x80,
898 { &hf_fcfzs_hard_zone_set_enforced
,
899 {"Hard Zone Set", "fcfzs.hard_zone_set.enforced",
900 FT_BOOLEAN
, 8, TFS(&tfs_enforced_not_enforced
), 0x40,
905 static gint
*ett
[] = {
907 &ett_fcfzs_gzc_flags
,
908 &ett_fcfzs_zone_state
,
911 proto_fcfzs
= proto_register_protocol("Fibre Channel Fabric Zone Server", "FC FZS", "fcfzs");
913 proto_register_field_array(proto_fcfzs
, hf
, array_length(hf
));
914 proto_register_subtree_array(ett
, array_length(ett
));
915 register_init_routine(&fcfzs_init_protocol
);
920 proto_reg_handoff_fcfzs(void)
922 dissector_handle_t fzs_handle
;
924 fzs_handle
= create_dissector_handle(dissect_fcfzs
, proto_fcfzs
);
925 dissector_add_uint("fcct.server", FCCT_GSRVR_FZS
, fzs_handle
);
927 data_handle
= find_dissector("data");