Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-fcfzs.c
blob2ce368ee858a6df024ad20cb5bfd8119131ce048
1 /* packet-fcfzs.c
2 * Routines for FC Fabric Zone Server
3 * Copyright 2001, Dinesh G Dutt <ddutt@andiamo.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * Fibre Channel Generic Services (FC-GS) specification.
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/tfs.h>
20 #include <epan/expert.h>
21 #include "packet-fc.h"
22 #include "packet-fcct.h"
23 #include "packet-fcfzs.h"
25 void proto_register_fcfzs(void);
26 void proto_reg_handoff_fcfzs(void);
28 static dissector_handle_t fzs_handle;
30 /* Initialize the protocol and registered fields */
31 static int proto_fcfzs;
32 static int hf_fcfzs_opcode;
33 static int hf_fcfzs_gzc_vendor;
34 static int hf_fcfzs_gest_vendor;
35 static int hf_fcfzs_numzoneattrs;
36 static int hf_fcfzs_zonesetnmlen;
37 static int hf_fcfzs_zonesetname;
38 static int hf_fcfzs_numzones;
39 static int hf_fcfzs_numzonesetattrs;
40 static int hf_fcfzs_zonenmlen;
41 static int hf_fcfzs_zonename;
42 static int hf_fcfzs_nummbrs;
43 static int hf_fcfzs_nummbrentries;
44 static int hf_fcfzs_mbrid_fcwwn;
45 static int hf_fcfzs_mbrid_fc;
46 static int hf_fcfzs_mbrid_uint;
47 /* static int hf_fcfzs_mbridlen; */
48 static int hf_fcfzs_mbrtype;
49 static int hf_fcfzs_reason;
50 static int hf_fcfzs_rjtdetail;
51 static int hf_fcfzs_rjtvendor;
52 static int hf_fcfzs_maxres_size;
53 static int hf_fcfzs_mbrid_lun;
54 static int hf_fcfzs_gzc_flags;
55 static int hf_fcfzs_gzc_flags_hard_zones;
56 static int hf_fcfzs_gzc_flags_soft_zones;
57 static int hf_fcfzs_gzc_flags_zoneset_db;
58 static int hf_fcfzs_zone_state;
59 static int hf_fcfzs_soft_zone_set_enforced;
60 static int hf_fcfzs_hard_zone_set_enforced;
62 /* Initialize the subtree pointers */
63 static int ett_fcfzs;
64 static int ett_fcfzs_gzc_flags;
65 static int ett_fcfzs_zone_state;
67 static expert_field ei_fcfzs_no_exchange;
68 static expert_field ei_fcfzs_mbrid;
70 typedef struct _fcfzs_conv_key {
71 uint32_t conv_idx;
72 } fcfzs_conv_key_t;
74 typedef struct _fcfzs_conv_data {
75 uint32_t opcode;
76 } fcfzs_conv_data_t;
78 static wmem_map_t *fcfzs_req_hash;
81 * Hash Functions
83 static int
84 fcfzs_equal(const void *v, const void *w)
86 const fcfzs_conv_key_t *v1 = (const fcfzs_conv_key_t *)v;
87 const fcfzs_conv_key_t *v2 = (const fcfzs_conv_key_t *)w;
89 return (v1->conv_idx == v2->conv_idx);
92 static unsigned
93 fcfzs_hash(const void *v)
95 const fcfzs_conv_key_t *key = (const fcfzs_conv_key_t *)v;
96 unsigned val;
98 val = key->conv_idx;
100 return val;
103 /* Code to actually dissect the packets */
104 static void
105 dissect_fcfzs_zoneset(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset)
107 int numzones, nummbrs, i, j, len;
108 proto_item* ti;
110 /* The zoneset structure has the following format */
111 /* zoneset name (len[not including pad], name, pad),
112 * number of zones,
113 * for each zone,
114 * Zone name (len[not including pad], name, pad), num zone mbrs
115 * for each zone mbr,
116 * zone mbr id type, zone mbr id (len, name, pad)
119 /* Zoneset Name */
120 len = tvb_get_uint8(tvb, offset);
121 proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
122 1, ENC_BIG_ENDIAN);
123 offset += 4;
124 proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset,
125 len, ENC_ASCII);
126 offset += len;
127 /* Fill Bytes */
128 if (len % 4)
129 offset += 4 - (len % 4);
132 /* Number of zones */
133 numzones = tvb_get_ntohl(tvb, offset);
134 proto_tree_add_item(tree, hf_fcfzs_numzones, tvb, offset, 4, ENC_BIG_ENDIAN);
135 offset += 4;
137 /* For each zone... */
138 for (i = 0; i < numzones; i++) {
139 len = tvb_get_uint8(tvb, offset);
140 proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset,
141 1, ENC_BIG_ENDIAN);
142 offset += 4;
143 proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset,
144 len, ENC_ASCII);
145 offset += len;
146 /* Fill Bytes */
147 if (len % 4)
148 offset += 4 - (len % 4);
150 nummbrs = tvb_get_ntohl(tvb, offset);
151 proto_tree_add_item(tree, hf_fcfzs_nummbrentries, tvb, offset,
152 4, ENC_BIG_ENDIAN);
154 offset += 4;
155 for (j = 0; j < nummbrs; j++) {
156 ti = proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN);
158 switch (tvb_get_uint8(tvb, offset)) {
159 case FC_FZS_ZONEMBR_PWWN:
160 case FC_FZS_ZONEMBR_NWWN:
161 proto_tree_add_item(tree, hf_fcfzs_mbrid_fcwwn, tvb,
162 offset+4, 8, ENC_NA);
163 break;
164 case FC_FZS_ZONEMBR_DP:
165 proto_tree_add_item(tree, hf_fcfzs_mbrid_uint,
166 tvb, offset+4, 3, ENC_BIG_ENDIAN);
167 break;
168 case FC_FZS_ZONEMBR_FCID:
169 proto_tree_add_item(tree, hf_fcfzs_mbrid_fc, tvb,
170 offset+4, 3, ENC_NA);
171 break;
172 case FC_FZS_ZONEMBR_PWWN_LUN:
173 proto_tree_add_item(tree, hf_fcfzs_mbrid_fcwwn, tvb,
174 offset+4, 8, ENC_NA);
175 proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
176 offset+8, 8, ENC_NA);
177 break;
178 case FC_FZS_ZONEMBR_DP_LUN:
179 proto_tree_add_item(tree, hf_fcfzs_mbrid_uint,
180 tvb, offset+4, 3, ENC_BIG_ENDIAN);
181 proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
182 offset+4, 8, ENC_NA);
183 break;
184 case FC_FZS_ZONEMBR_FCID_LUN:
185 proto_tree_add_item(tree, hf_fcfzs_mbrid_fc, tvb,
186 offset+4, 3, ENC_NA);
187 proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
188 offset+4, 8, ENC_NA);
189 break;
190 default:
191 expert_add_info(pinfo, ti, &ei_fcfzs_mbrid);
193 offset += 12;
199 static void
200 dissect_fcfzs_gzc(tvbuff_t *tvb, int offset, proto_tree *parent_tree, bool isreq)
202 static int * const flags[] = {
203 &hf_fcfzs_gzc_flags_hard_zones,
204 &hf_fcfzs_gzc_flags_soft_zones,
205 &hf_fcfzs_gzc_flags_zoneset_db,
206 NULL
209 if (!isreq) {
210 proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_fcfzs_gzc_flags,
211 ett_fcfzs_gzc_flags, flags, ENC_NA, BMT_NO_FALSE|BMT_NO_TFS);
213 proto_tree_add_item(parent_tree, hf_fcfzs_gzc_vendor, tvb, offset+4, 4, ENC_BIG_ENDIAN);
217 static void
218 dissect_fcfzs_gest(tvbuff_t *tvb, proto_tree *parent_tree, bool isreq)
220 int offset = 16; /* past the fc_ct header */
221 static int * const flags[] = {
222 &hf_fcfzs_soft_zone_set_enforced,
223 &hf_fcfzs_hard_zone_set_enforced,
224 NULL
227 if (!isreq) {
228 proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_fcfzs_zone_state,
229 ett_fcfzs_zone_state, flags, ENC_NA, BMT_NO_FALSE|BMT_NO_TFS);
231 proto_tree_add_item(parent_tree, hf_fcfzs_gest_vendor, tvb, offset+4, 4, ENC_BIG_ENDIAN);
235 static void
236 dissect_fcfzs_gzsn(tvbuff_t *tvb, proto_tree *tree, bool isreq)
238 int numrec, i, len;
239 int offset = 16; /* past the fc_ct header */
241 if (tree) {
242 if (!isreq) {
243 numrec = tvb_get_ntohl(tvb, offset);
245 proto_tree_add_item(tree, hf_fcfzs_numzonesetattrs, tvb, offset,
246 4, ENC_BIG_ENDIAN);
248 offset += 4;
249 for (i = 0; i < numrec; i++) {
250 len = tvb_get_uint8(tvb, offset);
251 proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
252 1, ENC_BIG_ENDIAN);
253 proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+1,
254 len, ENC_ASCII);
255 offset += len + 1 + (len % 4);
256 proto_tree_add_item(tree, hf_fcfzs_numzones, tvb, offset,
257 4, ENC_BIG_ENDIAN);
258 offset += 4;
264 static void
265 dissect_fcfzs_gzd(tvbuff_t *tvb, proto_tree *tree, bool isreq)
267 int numrec, i, len;
268 int offset = 16; /* past the fc_ct header */
270 if (tree) {
271 if (isreq) {
272 len = tvb_get_uint8(tvb, offset);
273 proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
274 1, ENC_BIG_ENDIAN);
275 proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+1,
276 len, ENC_ASCII);
278 else {
279 numrec = tvb_get_ntohl(tvb, offset);
281 proto_tree_add_item(tree, hf_fcfzs_numzoneattrs, tvb, offset,
282 4, ENC_BIG_ENDIAN);
284 offset += 4;
285 for (i = 0; i < numrec; i++) {
286 len = tvb_get_uint8(tvb, offset);
287 proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset,
288 1, ENC_BIG_ENDIAN);
289 proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+1,
290 len, ENC_ASCII);
291 offset += len + 1 + (len % 4);
292 proto_tree_add_item(tree, hf_fcfzs_nummbrs, tvb, offset,
293 4, ENC_BIG_ENDIAN);
294 offset += 4;
300 static void
301 dissect_fcfzs_gzm(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, bool isreq)
303 int numrec, i, len;
304 int offset = 16; /* past the fc_ct header */
305 proto_item* ti;
307 if (isreq) {
308 len = tvb_get_uint8(tvb, offset);
309 proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset,
310 1, ENC_BIG_ENDIAN);
311 proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+1,
312 len, ENC_ASCII);
314 else {
315 numrec = tvb_get_ntohl(tvb, offset);
317 proto_tree_add_item(tree, hf_fcfzs_nummbrentries, tvb, offset,
318 4, ENC_BIG_ENDIAN);
319 offset += 4;
320 for (i = 0; i < numrec; i++) {
321 ti = proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN);
322 switch (tvb_get_uint8(tvb, offset)) {
323 case FC_FZS_ZONEMBR_PWWN:
324 case FC_FZS_ZONEMBR_NWWN:
325 proto_tree_add_item(tree, hf_fcfzs_mbrid_fcwwn, tvb,
326 offset+4, 8, ENC_NA);
327 break;
328 case FC_FZS_ZONEMBR_DP:
329 proto_tree_add_item(tree, hf_fcfzs_mbrid_uint,
330 tvb, offset+4, 3, ENC_BIG_ENDIAN);
331 break;
332 case FC_FZS_ZONEMBR_FCID:
333 proto_tree_add_item(tree, hf_fcfzs_mbrid_fc, tvb,
334 offset+4, 3, ENC_NA);
335 break;
336 default:
337 expert_add_info(pinfo, ti, &ei_fcfzs_mbrid);
339 offset += 12;
344 static void
345 dissect_fcfzs_gazs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, bool isreq)
347 int offset = 16; /* past the fc_ct header */
349 if (!isreq) {
350 dissect_fcfzs_zoneset(tvb, pinfo, tree, offset);
354 static void
355 dissect_fcfzs_gzs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, bool isreq)
357 int offset = 16; /* past the fc_ct header */
358 int len;
360 if (isreq) {
361 len = tvb_get_uint8(tvb, offset);
362 proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
363 1, ENC_BIG_ENDIAN);
364 proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+4,
365 len, ENC_ASCII);
367 else {
368 dissect_fcfzs_zoneset(tvb, pinfo, tree, offset);
372 static void
373 dissect_fcfzs_adzs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, bool isreq)
375 int offset = 16; /* past the fc_ct header */
377 if (isreq) {
378 dissect_fcfzs_zoneset(tvb, pinfo, tree, offset);
382 static void
383 dissect_fcfzs_azsd(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, bool isreq)
385 int offset = 16; /* past the fc_ct header */
387 if (isreq) {
388 dissect_fcfzs_zoneset(tvb, pinfo, tree, offset);
392 static void
393 dissect_fcfzs_arzs(tvbuff_t *tvb, proto_tree *tree, bool isreq)
395 int offset = 16; /* past the fc_ct header */
396 int len;
398 if (tree) {
399 if (isreq) {
400 len = tvb_get_uint8(tvb, offset);
401 proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
402 1, ENC_BIG_ENDIAN);
403 proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+4,
404 len, ENC_ASCII);
409 static void
410 dissect_fcfzs_dzs(tvbuff_t *tvb _U_, proto_tree *tree _U_, bool isreq _U_)
412 /* Both req & successful response contain just the FC_CT header */
413 return;
416 static void
417 dissect_fcfzs_arzm(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, bool isreq)
419 int numrec, i, len, plen;
420 int offset = 16; /* past the fc_ct header */
421 proto_item* ti;
423 if (isreq) {
424 len = tvb_get_uint8(tvb, offset);
425 proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset,
426 1, ENC_BIG_ENDIAN);
427 proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+1,
428 len, ENC_ASCII);
430 len += (len % 4);
431 plen = tvb_reported_length(tvb) - offset - len;
433 numrec = plen/12; /* each mbr rec is 12 bytes long */
435 offset += len;
436 for (i = 0; i < numrec; i++) {
437 ti = proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN);
438 switch (tvb_get_uint8(tvb, offset)) {
439 case FC_FZS_ZONEMBR_PWWN:
440 case FC_FZS_ZONEMBR_NWWN:
441 proto_tree_add_item(tree, hf_fcfzs_mbrid_fcwwn, tvb,
442 offset+4, 8, ENC_NA);
443 break;
444 case FC_FZS_ZONEMBR_DP:
445 proto_tree_add_item(tree, hf_fcfzs_mbrid_uint,
446 tvb, offset+4, 3, ENC_BIG_ENDIAN);
447 break;
448 case FC_FZS_ZONEMBR_FCID:
449 proto_tree_add_item(tree, hf_fcfzs_mbrid_fc, tvb,
450 offset+4, 3, ENC_NA);
451 break;
452 default:
453 expert_add_info(pinfo, ti, &ei_fcfzs_mbrid);
455 offset += 12;
460 static void
461 dissect_fcfzs_arzd(tvbuff_t *tvb, proto_tree *tree, bool isreq)
463 int offset = 16; /* past the fc_ct header */
464 int len;
466 if (tree) {
467 if (isreq) {
468 len = tvb_get_uint8(tvb, offset);
469 proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
470 1, ENC_BIG_ENDIAN);
471 proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+4,
472 len, ENC_ASCII);
473 len += (len % 4);
474 offset += len;
476 len = tvb_get_uint8(tvb, offset);
477 proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset, 1, ENC_BIG_ENDIAN);
478 proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+4,
479 len, ENC_ASCII);
484 static void
485 dissect_fcfzs_rjt(tvbuff_t *tvb, proto_tree *tree)
487 int offset = 0;
489 if (tree) {
490 proto_tree_add_item(tree, hf_fcfzs_reason, tvb, offset+13, 1, ENC_BIG_ENDIAN);
491 proto_tree_add_item(tree, hf_fcfzs_rjtdetail, tvb, offset+14, 1, ENC_BIG_ENDIAN);
492 proto_tree_add_item(tree, hf_fcfzs_rjtvendor, tvb, offset+15, 1, ENC_BIG_ENDIAN);
496 static int
497 dissect_fcfzs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
500 /* Set up structures needed to add the protocol subtree and manage it */
501 proto_item *ti;
502 proto_tree *fcfzs_tree = NULL;
503 int offset = 0;
504 fc_ct_preamble cthdr;
505 int opcode;
506 int failed_opcode = 0;
507 conversation_t *conversation;
508 fcfzs_conv_data_t *cdata;
509 fcfzs_conv_key_t ckey, *req_key;
510 bool isreq = true;
511 fc_hdr *fchdr;
513 /* Reject the packet if data is NULL */
514 if (data == NULL)
515 return 0;
516 fchdr = (fc_hdr *)data;
518 /* Make entries in Protocol column and Info column on summary display */
519 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Zone Server");
522 tvb_memcpy(tvb, (uint8_t *)&cthdr, offset, FCCT_PRMBL_SIZE);
523 cthdr.revision = tvb_get_uint8(tvb, offset+1);
524 cthdr.in_id = tvb_get_ntoh24(tvb, offset);
525 cthdr.opcode = g_ntohs(cthdr.opcode);
526 opcode = cthdr.opcode;
527 cthdr.maxres_size = g_ntohs(cthdr.maxres_size);
529 if (tree) {
530 ti = proto_tree_add_protocol_format(tree, proto_fcfzs, tvb, 0,
531 tvb_captured_length(tvb),
532 "Zone Server");
533 fcfzs_tree = proto_item_add_subtree(ti, ett_fcfzs);
534 proto_tree_add_item(fcfzs_tree, hf_fcfzs_opcode, tvb, offset+8, 2, ENC_BIG_ENDIAN);
535 proto_tree_add_item(fcfzs_tree, hf_fcfzs_maxres_size, tvb, offset+10,
536 2, ENC_BIG_ENDIAN);
539 if ((opcode != FCCT_MSG_ACC) && (opcode != FCCT_MSG_RJT)) {
540 conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
541 conversation_pt_to_conversation_type(pinfo->ptype), fchdr->oxid,
542 fchdr->rxid, NO_PORT_B);
543 if (!conversation) {
544 conversation = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst,
545 conversation_pt_to_conversation_type(pinfo->ptype), fchdr->oxid,
546 fchdr->rxid, NO_PORT2);
549 ckey.conv_idx = conversation->conv_index;
551 cdata = (fcfzs_conv_data_t *)wmem_map_lookup(fcfzs_req_hash,
552 &ckey);
553 if (cdata) {
554 /* Since we never free the memory used by an exchange, this maybe a
555 * case of another request using the same exchange as a previous
556 * req.
558 cdata->opcode = opcode;
560 else {
561 req_key = wmem_new(wmem_file_scope(), fcfzs_conv_key_t);
562 req_key->conv_idx = conversation->conv_index;
564 cdata = wmem_new(wmem_file_scope(), fcfzs_conv_data_t);
565 cdata->opcode = opcode;
567 wmem_map_insert(fcfzs_req_hash, req_key, cdata);
570 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, fc_fzs_opcode_val,
571 "0x%x"));
573 else {
574 /* Opcode is ACC or RJT */
575 conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
576 conversation_pt_to_conversation_type(pinfo->ptype), fchdr->oxid,
577 fchdr->rxid, NO_PORT_B);
578 isreq = false;
579 if (!conversation) {
580 if (opcode == FCCT_MSG_ACC) {
581 col_add_str(pinfo->cinfo, COL_INFO,
582 val_to_str(opcode, fc_fzs_opcode_val,
583 "0x%x"));
584 /* No record of what this accept is for. Can't decode */
585 proto_tree_add_expert_format(fcfzs_tree, pinfo, &ei_fcfzs_no_exchange, tvb, 0, -1,
586 "No record of Exchg. Unable to decode MSG_ACC");
587 return 0;
590 else {
591 ckey.conv_idx = conversation->conv_index;
593 cdata = (fcfzs_conv_data_t *)wmem_map_lookup(fcfzs_req_hash, &ckey);
595 if (cdata != NULL) {
596 if (opcode == FCCT_MSG_ACC)
597 opcode = cdata->opcode;
598 else
599 failed_opcode = cdata->opcode;
602 if (opcode != FCCT_MSG_RJT) {
603 col_add_fstr(pinfo->cinfo, COL_INFO, "MSG_ACC (%s)",
604 val_to_str(opcode,
605 fc_fzs_opcode_val, "0x%x"));
607 else {
608 col_add_fstr(pinfo->cinfo, COL_INFO, "MSG_RJT (%s)",
609 val_to_str(failed_opcode,
610 fc_fzs_opcode_val, "0x%x"));
613 if ((cdata == NULL) && (opcode != FCCT_MSG_RJT)) {
614 /* No record of what this accept is for. Can't decode */
615 proto_tree_add_expert_format(fcfzs_tree, pinfo, &ei_fcfzs_no_exchange, tvb, 0, -1,
616 "No record of Exchg. Unable to decode MSG_ACC/RJT");
617 return 0;
622 switch (opcode) {
623 case FCCT_MSG_RJT:
624 dissect_fcfzs_rjt(tvb, fcfzs_tree);
625 break;
626 case FC_FZS_GZC:
627 dissect_fcfzs_gzc(tvb, 16, fcfzs_tree, isreq);
628 break;
629 case FC_FZS_GEST:
630 dissect_fcfzs_gest(tvb, fcfzs_tree, isreq);
631 break;
632 case FC_FZS_GZSN:
633 dissect_fcfzs_gzsn(tvb, fcfzs_tree, isreq);
634 break;
635 case FC_FZS_GZD:
636 dissect_fcfzs_gzd(tvb, fcfzs_tree, isreq);
637 break;
638 case FC_FZS_GZM:
639 dissect_fcfzs_gzm(tvb, pinfo, fcfzs_tree, isreq);
640 break;
641 case FC_FZS_GAZS:
642 dissect_fcfzs_gazs(tvb, pinfo, fcfzs_tree, isreq);
643 break;
644 case FC_FZS_GZS:
645 dissect_fcfzs_gzs(tvb, pinfo, fcfzs_tree, isreq);
646 break;
647 case FC_FZS_ADZS:
648 dissect_fcfzs_adzs(tvb, pinfo, fcfzs_tree, isreq);
649 break;
650 case FC_FZS_AZSD:
651 dissect_fcfzs_azsd(tvb, pinfo, fcfzs_tree, isreq);
652 break;
653 case FC_FZS_AZS:
654 dissect_fcfzs_arzs(tvb, fcfzs_tree, isreq);
655 break;
656 case FC_FZS_DZS:
657 dissect_fcfzs_dzs(tvb, fcfzs_tree, isreq);
658 break;
659 case FC_FZS_AZM:
660 dissect_fcfzs_arzm(tvb, pinfo, fcfzs_tree, isreq);
661 break;
662 case FC_FZS_AZD:
663 dissect_fcfzs_arzd(tvb, fcfzs_tree, isreq);
664 break;
665 case FC_FZS_RZM:
666 dissect_fcfzs_arzm(tvb, pinfo, fcfzs_tree, isreq);
667 break;
668 case FC_FZS_RZD:
669 dissect_fcfzs_arzd(tvb, fcfzs_tree, isreq);
670 break;
671 case FC_FZS_RZS:
672 dissect_fcfzs_arzs(tvb, fcfzs_tree, isreq);
673 break;
674 default:
675 call_data_dissector(tvb, pinfo, tree);
676 break;
679 return tvb_captured_length(tvb);
682 /* Register the protocol with Wireshark */
684 void
685 proto_register_fcfzs(void)
688 static hf_register_info hf[] = {
689 { &hf_fcfzs_opcode,
690 {"Opcode", "fcfzs.opcode",
691 FT_UINT16, BASE_HEX, VALS(fc_fzs_opcode_val), 0x0,
692 NULL, HFILL}},
694 { &hf_fcfzs_gzc_vendor,
695 {"Vendor Specific Flags", "fcfzs.gzc.vendor",
696 FT_UINT32, BASE_HEX, NULL, 0x0,
697 NULL, HFILL}},
699 { &hf_fcfzs_gest_vendor,
700 {"Vendor Specific State", "fcfzs.gest.vendor",
701 FT_UINT32, BASE_HEX, NULL, 0x0,
702 NULL, HFILL}},
704 { &hf_fcfzs_numzoneattrs,
705 {"Number of Zone Attribute Entries", "fcfzs.zone.numattrs",
706 FT_UINT32, BASE_DEC, NULL, 0x0,
707 NULL, HFILL}},
709 { &hf_fcfzs_zonesetnmlen,
710 {"Zone Set Name Length", "fcfzs.zoneset.namelen",
711 FT_UINT8, BASE_DEC, NULL, 0x0,
712 NULL, HFILL}},
714 { &hf_fcfzs_zonesetname,
715 {"Zone Set Name", "fcfzs.zoneset.name",
716 FT_STRING, BASE_NONE, NULL, 0x0,
717 NULL, HFILL}},
719 { &hf_fcfzs_numzones,
720 {"Number of Zones", "fcfzs.zoneset.numzones",
721 FT_UINT32, BASE_DEC, NULL, 0x0,
722 NULL, HFILL}},
724 { &hf_fcfzs_numzonesetattrs,
725 {"Number of Zone Set Attribute Entries", "fcfzs.zoneset.numattrs",
726 FT_UINT32, BASE_DEC, NULL, 0x0,
727 NULL, HFILL}},
729 { &hf_fcfzs_zonenmlen,
730 {"Zone Name Length", "fcfzs.zone.namelen",
731 FT_UINT8, BASE_DEC, NULL, 0x0,
732 NULL, HFILL}},
734 { &hf_fcfzs_zonename,
735 {"Zone Name", "fcfzs.zone.name",
736 FT_STRING, BASE_NONE, NULL, 0x0,
737 NULL, HFILL}},
739 { &hf_fcfzs_nummbrs,
740 {"Number of Zone Members", "fcfzs.zone.nummbrs",
741 FT_UINT32, BASE_DEC, NULL, 0x0,
742 NULL, HFILL}},
744 { &hf_fcfzs_nummbrentries,
745 {"Number of Zone Member Attribute Entries", "fcfzs.zonembr.numattrs",
746 FT_UINT32, BASE_DEC, NULL, 0x0,
747 NULL, HFILL}},
749 { &hf_fcfzs_mbrtype,
750 {"Zone Member Identifier Type", "fcfzs.zonembr.idtype",
751 FT_UINT8, BASE_HEX, VALS(fc_fzs_zonembr_type_val), 0x0,
752 NULL, HFILL}},
754 #if 0
755 { &hf_fcfzs_mbridlen,
756 {"Zone Member Identifier Length", "fcfzs.zonembr.idlen",
757 FT_UINT8, BASE_DEC, NULL, 0x0,
758 NULL, HFILL}},
759 #endif
761 { &hf_fcfzs_mbrid_fcwwn,
762 {"Zone Member Identifier", "fcfzs.zone.mbrid.fcwwn",
763 FT_FCWWN, BASE_NONE, NULL, 0x0,
764 NULL, HFILL}},
766 { &hf_fcfzs_mbrid_fc,
767 {"Zone Member Identifier", "fcfzs.zone.mbrid.fc",
768 FT_BYTES, SEP_DOT, NULL, 0x0,
769 NULL, HFILL}},
771 { &hf_fcfzs_mbrid_uint,
772 {"Zone Member Identifier", "fcfzs.zone.mbrid.uint",
773 FT_UINT24, BASE_HEX, NULL, 0x0,
774 NULL, HFILL}},
776 { &hf_fcfzs_reason,
777 {"Reason Code", "fcfzs.reason",
778 FT_UINT8, BASE_HEX, VALS(fc_ct_rjt_code_vals), 0x0,
779 NULL, HFILL}},
781 { &hf_fcfzs_rjtdetail,
782 {"Reason Code Explanation", "fcfzs.rjtdetail",
783 FT_UINT8, BASE_HEX, VALS(fc_fzs_rjt_code_val), 0x0,
784 NULL, HFILL}},
786 { &hf_fcfzs_rjtvendor,
787 {"Vendor Specific Reason", "fcfzs.rjtvendor",
788 FT_UINT8, BASE_HEX, NULL, 0x0,
789 NULL, HFILL}},
791 { &hf_fcfzs_maxres_size,
792 {"Maximum/Residual Size", "fcfzs.maxres_size",
793 FT_UINT16, BASE_DEC, NULL, 0x0,
794 NULL, HFILL}},
796 { &hf_fcfzs_mbrid_lun,
797 {"LUN", "fcfzs.zone.lun",
798 FT_BYTES, BASE_NONE, NULL, 0x0,
799 NULL, HFILL}},
801 { &hf_fcfzs_gzc_flags,
802 {"Capabilities", "fcfzs.gzc.flags",
803 FT_UINT8, BASE_HEX, NULL, 0x0,
804 NULL, HFILL}},
806 { &hf_fcfzs_gzc_flags_hard_zones,
807 {"Hard Zones", "fcfzs.gzc.flags.hard_zones",
808 FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x80,
809 NULL, HFILL}},
811 { &hf_fcfzs_gzc_flags_soft_zones,
812 {"Soft Zones", "fcfzs.gzc.flags.soft_zones",
813 FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x40,
814 NULL, HFILL}},
816 { &hf_fcfzs_gzc_flags_zoneset_db,
817 {"ZoneSet Database", "fcfzs.gzc.flags.zoneset_db",
818 FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x01,
819 NULL, HFILL}},
821 { &hf_fcfzs_zone_state,
822 {"Zone State", "fcfzs.zone.state",
823 FT_UINT8, BASE_HEX, NULL, 0x0,
824 NULL, HFILL}},
826 { &hf_fcfzs_soft_zone_set_enforced,
827 {"Soft Zone Set", "fcfzs.soft_zone_set.enforced",
828 FT_BOOLEAN, 8, TFS(&tfs_enforced_not_enforced), 0x80,
829 NULL, HFILL}},
831 { &hf_fcfzs_hard_zone_set_enforced,
832 {"Hard Zone Set", "fcfzs.hard_zone_set.enforced",
833 FT_BOOLEAN, 8, TFS(&tfs_enforced_not_enforced), 0x40,
834 NULL, HFILL}},
838 static int *ett[] = {
839 &ett_fcfzs,
840 &ett_fcfzs_gzc_flags,
841 &ett_fcfzs_zone_state,
844 static ei_register_info ei[] = {
845 { &ei_fcfzs_no_exchange, { "fcfzs.no_exchange", PI_UNDECODED, PI_WARN, "No record of Exchg. Unable to decode", EXPFILL }},
846 { &ei_fcfzs_mbrid, { "fcfzs.mbrid.unknown_type", PI_PROTOCOL, PI_WARN, "Unknown member type format", EXPFILL }},
849 expert_module_t* expert_fcfzs;
851 proto_fcfzs = proto_register_protocol("Fibre Channel Fabric Zone Server", "FC FZS", "fcfzs");
853 proto_register_field_array(proto_fcfzs, hf, array_length(hf));
854 proto_register_subtree_array(ett, array_length(ett));
855 expert_fcfzs = expert_register_protocol(proto_fcfzs);
856 expert_register_field_array(expert_fcfzs, ei, array_length(ei));
858 fcfzs_req_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), fcfzs_hash, fcfzs_equal);
860 fzs_handle = register_dissector("fcfzs", dissect_fcfzs, proto_fcfzs);
863 void
864 proto_reg_handoff_fcfzs(void)
866 dissector_add_uint("fcct.server", FCCT_GSRVR_FZS, fzs_handle);
870 * Editor modelines - https://www.wireshark.org/tools/modelines.html
872 * Local variables:
873 * c-basic-offset: 4
874 * tab-width: 8
875 * indent-tabs-mode: nil
876 * End:
878 * vi: set shiftwidth=4 tabstop=8 expandtab:
879 * :indentSize=4:tabSize=8:noTabs=true: