2 * Routines for FC Fabric Configuration 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 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <epan/packet.h>
29 #include <epan/to_str.h>
30 #include <epan/wmem/wmem.h>
31 #include <epan/conversation.h>
32 #include <epan/etypes.h>
33 #include "packet-fc.h"
34 #include "packet-fcct.h"
35 #include "packet-fcfcs.h"
37 void proto_register_fcfcs(void);
38 void proto_reg_handoff_fcfcs(void);
41 * See the FC-GS3 specification.
44 /* Initialize the protocol and registered fields */
45 static int proto_fcfcs = -1;
46 static int hf_fcs_opcode = -1;
47 static int hf_fcs_iename = -1;
48 static int hf_fcs_ietype = -1;
49 static int hf_fcs_iedomainid = -1;
50 static int hf_fcs_mgmtid = -1;
51 static int hf_fcs_fabricname = -1;
52 static int hf_fcs_mgmtaddr = -1;
53 static int hf_fcs_lname = -1;
54 static int hf_fcs_vendorname = -1;
55 static int hf_fcs_modelname = -1;
56 static int hf_fcs_portname = -1;
57 static int hf_fcs_portmodtype = -1;
58 static int hf_fcs_porttxtype = -1;
59 static int hf_fcs_porttype = -1;
60 static int hf_fcs_physportnum = -1;
61 static int hf_fcs_portflags = -1;
62 static int hf_fcs_portstate = -1;
63 static int hf_fcs_platformname = -1;
64 static int hf_fcs_platformnname = -1;
65 static int hf_fcs_platformtype = -1;
66 static int hf_fcs_platformaddr = -1;
67 static int hf_fcs_reason = -1;
68 static int hf_fcs_rjtdetail = -1;
69 static int hf_fcs_vendor = -1;
70 static int hf_fcs_numcap = -1;
71 static int hf_fcs_mgmt_subtype = -1;
72 static int hf_fcs_unsmask = -1;
73 static int hf_fcs_vnd_capmask = -1;
74 static int hf_fcs_fcsmask = -1;
75 static int hf_fcs_maxres_size = -1;
76 static int hf_fcs_releasecode = -1;
79 /* Initialize the subtree pointers */
80 static gint ett_fcfcs = -1;
82 typedef struct _fcfcs_conv_key {
86 typedef struct _fcfcs_conv_data {
90 static GHashTable *fcfcs_req_hash = NULL;
92 static dissector_handle_t data_handle;
98 fcfcs_equal(gconstpointer v, gconstpointer w)
100 const fcfcs_conv_key_t *v1 = (const fcfcs_conv_key_t *)v;
101 const fcfcs_conv_key_t *v2 = (const fcfcs_conv_key_t *)w;
103 return (v1->conv_idx == v2->conv_idx);
107 fcfcs_hash (gconstpointer v)
109 const fcfcs_conv_key_t *key = (const fcfcs_conv_key_t *)v;
118 * Protocol initialization
121 fcfcs_init_protocol(void)
124 g_hash_table_destroy (fcfcs_req_hash);
126 fcfcs_req_hash = g_hash_table_new(fcfcs_hash, fcfcs_equal);
129 /* Code to actually dissect the packets */
131 dissect_fcfcs_giel (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
133 int offset = 16; /* past the ct header */
136 if (!isreq && tree) {
137 numelem = tvb_get_ntohl (tvb, offset);
139 proto_tree_add_text (tree, tvb, offset, 4, "Number of IE entries: 0x%d",
142 for (i = 0; i < numelem; i++) {
143 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
144 tvb_fcwwn_to_str (tvb, offset));
145 proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+11, 1, ENC_BIG_ENDIAN);
152 dissect_fcfcs_giet (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
154 int offset = 16; /* past the fcct header */
158 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
159 tvb_fcwwn_to_str (tvb, offset));
162 proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+3, 1, ENC_BIG_ENDIAN);
168 dissect_fcfcs_gdid (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
170 int offset = 16; /* past the fcct header */
174 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
175 tvb_fcwwn_to_str (tvb, offset));
178 proto_tree_add_item (tree, hf_fcs_iedomainid, tvb, offset+1, 1, ENC_BIG_ENDIAN);
184 dissect_fcfcs_gmid (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
186 int offset = 16; /* past the fcct header */
190 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
191 tvb_fcwwn_to_str (tvb, offset));
194 proto_tree_add_string (tree, hf_fcs_mgmtid, tvb, offset+1, 3,
195 tvb_fc_to_str (tvb, offset+1));
201 dissect_fcfcs_gfn (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
203 int offset = 16; /* past the fcct header */
207 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
208 tvb_fcwwn_to_str (tvb, offset));
211 proto_tree_add_string (tree, hf_fcs_fabricname, tvb, offset, 8,
212 tvb_fcwwn_to_str (tvb, offset));
218 dissect_fcfcs_gieln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
220 int offset = 16; /* past the fcct header */
224 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
225 tvb_fcwwn_to_str (tvb, offset));
228 proto_tree_add_text (tree, tvb, offset, 1, "Name Length: %d",
229 tvb_get_guint8 (tvb, offset));
230 proto_tree_add_item (tree, hf_fcs_lname, tvb, offset+1,
231 tvb_get_guint8 (tvb, offset), ENC_ASCII|ENC_NA);
237 dissect_fcfcs_gmal (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
239 int offset = 16; /* past the fcct header */
244 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
245 tvb_fcwwn_to_str (tvb, offset));
248 numelem = tvb_get_ntohl (tvb, offset);
249 proto_tree_add_text (tree, tvb, offset, 4,
250 "Number of Mgmt. Addresses: 0x%d", numelem);
253 for (i = 0; i < numelem; i++) {
254 proto_tree_add_text (tree, tvb, offset, 1, "Name Length: %d",
255 tvb_get_guint8 (tvb, offset));
256 proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset+1,
257 tvb_get_guint8 (tvb, offset), ENC_ASCII|ENC_NA);
265 dissect_fcfcs_gieil (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
267 int offset = 16; /* past the fcct header */
268 int len, tot_len, prevlen;
272 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
273 tvb_fcwwn_to_str (tvb, offset));
276 tot_len = tvb_get_guint8 (tvb, offset+3);
277 proto_tree_add_text (tree, tvb, offset+3, 1, "List Length: %d",
281 len = tvb_strsize(tvb, offset+4);
282 proto_tree_add_item (tree, hf_fcs_vendorname, tvb, offset+4,
283 len, ENC_ASCII|ENC_NA);
286 len = tvb_strsize(tvb, offset+4+prevlen);
287 proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen,
288 len, ENC_ASCII|ENC_NA);
291 len = tvb_strsize(tvb, offset+4+prevlen);
292 proto_tree_add_item (tree, hf_fcs_releasecode, tvb,
293 offset+4+prevlen, len, ENC_ASCII|ENC_NA);
295 offset += (4+prevlen);
296 while (tot_len > prevlen) {
297 len = tvb_strsize(tvb, offset);
298 proto_tree_add_text (tree, tvb, offset, len,
299 "Vendor-specific Information: %s",
300 tvb_format_text(tvb, offset, len-1));
309 dissect_fcfcs_gpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
311 int offset = 16; /* past the fcct header */
316 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
317 tvb_fcwwn_to_str (tvb, offset));
320 numelem = tvb_get_ntohl (tvb, offset);
321 proto_tree_add_text (tree, tvb, offset, 4,
322 "Number of Port Entries: %d",
326 for (i = 0; i < numelem; i++) {
327 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
328 tvb_fcwwn_to_str (tvb, offset));
329 proto_tree_add_item (tree, hf_fcs_portmodtype, tvb, offset+9,
331 proto_tree_add_item (tree, hf_fcs_porttxtype, tvb, offset+10,
333 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11,
342 dissect_fcfcs_gpt (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
344 int offset = 16; /* past the fcct header */
348 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
349 tvb_fcwwn_to_str (tvb, offset));
352 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+3, 1, ENC_BIG_ENDIAN);
358 dissect_fcfcs_gppn (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
360 int offset = 16; /* past the fcct header */
364 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
365 tvb_fcwwn_to_str (tvb, offset));
368 proto_tree_add_item (tree, hf_fcs_physportnum, tvb, offset, 4, ENC_NA);
374 dissect_fcfcs_gapnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
376 int offset = 16; /* past the fcct header */
381 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
382 tvb_fcwwn_to_str (tvb, offset));
385 numelem = tvb_get_ntohl (tvb, offset);
386 proto_tree_add_text (tree, tvb, offset, 4,
387 "Number of Attached Port Entries: %d",
390 for (i = 0; i < numelem; i++) {
391 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
392 tvb_fcwwn_to_str (tvb, offset));
393 proto_tree_add_item (tree, hf_fcs_portflags, tvb, offset+10,
395 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11,
404 dissect_fcfcs_gps (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
406 int offset = 16; /* past the fcct header */
410 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
411 tvb_fcwwn_to_str (tvb, offset));
414 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+3, 1, ENC_BIG_ENDIAN);
415 proto_tree_add_item (tree, hf_fcs_portstate, tvb, offset+7, 1, ENC_BIG_ENDIAN);
421 dissect_fcfcs_gplnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
423 int offset = 16; /* past the fcct header */
428 len = tvb_get_guint8 (tvb, offset);
429 proto_tree_add_text (tree, tvb, offset, 1,
430 "Platform Name Length: %d", len);
431 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
435 numelem = tvb_get_ntohl (tvb, offset);
436 proto_tree_add_text (tree, tvb, offset, 4,
437 "Number of Platform Node Name Entries: %d",
440 for (i = 0; i < numelem; i++) {
441 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset,
442 8, tvb_fcwwn_to_str (tvb, offset));
450 dissect_fcfcs_gplt (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
452 int offset = 16; /* past the fcct header */
457 len = tvb_get_guint8 (tvb, offset);
458 proto_tree_add_text (tree, tvb, offset, 1,
459 "Platform Name Length: %d", len);
460 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
464 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+3,
471 dissect_fcfcs_gplml (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
473 int offset = 16; /* past the fcct header */
478 len = tvb_get_guint8 (tvb, offset);
479 proto_tree_add_text (tree, tvb, offset, 1,
480 "Platform Name Length: %d", len);
481 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
485 numelem = tvb_get_ntohl (tvb, offset);
486 proto_tree_add_text (tree, tvb, offset, 4,
487 "Number of Mgmt. Address Entries: %d",
490 for (i = 0; i < numelem; i++) {
491 len = tvb_get_guint8 (tvb, offset);
492 proto_tree_add_text (tree, tvb, offset, 1,
493 "Mgmt Address Length: %d",
495 proto_tree_add_item (tree, hf_fcs_platformaddr, tvb, offset+1,
496 len, ENC_ASCII|ENC_NA);
504 dissect_fcfcs_gnpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
506 int offset = 16; /* past the fcct header */
511 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset, 8,
512 tvb_fcwwn_to_str (tvb, offset));
515 len = tvb_get_guint8 (tvb, offset);
516 proto_tree_add_text (tree, tvb, offset, 1,
517 "Platform Name Length: %d", len);
518 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
525 dissect_fcfcs_gpnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
527 int offset = 16; /* past the fcct header */
532 numelem = tvb_get_ntohl (tvb, offset);
534 proto_tree_add_text (tree, tvb, offset, 4,
535 "Number of Platform Name Entries: %d",
538 for (i = 0; i < numelem; i++) {
539 len = tvb_get_guint8 (tvb, offset);
540 proto_tree_add_text (tree, tvb, offset, 1,
541 "Platform Name Length: %d",
543 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
552 dissect_fcfcs_rieln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
554 int offset = 16; /* past the fc_ct header */
559 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
560 tvb_fcwwn_to_str (tvb, offset));
561 len = tvb_get_guint8 (tvb, offset+8);
562 proto_tree_add_text (tree, tvb, offset+8, 1,
563 "Logical Name Length: %d", len);
564 proto_tree_add_item (tree, hf_fcs_lname, tvb, offset+9, len, ENC_ASCII|ENC_NA);
570 dissect_fcfcs_rpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
572 int offset = 16; /* past the fc_ct header */
577 len = tvb_get_guint8 (tvb, offset);
578 proto_tree_add_text (tree, tvb, offset, 1,
579 "Platform Name Length: %d", len);
580 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
582 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+256, 4,
584 numelem = tvb_get_ntohl (tvb, offset+260);
585 proto_tree_add_text (tree, tvb, offset+260, 4,
586 "Number of Mgmt. Addr Entries: %d", numelem);
588 for (i = 0; i < numelem; i++) {
589 len = tvb_get_guint8 (tvb, offset);
590 proto_tree_add_text (tree, tvb, offset, 1,
591 "Mgmt. Addr Length: %d", len);
592 proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset+1,
593 len, ENC_ASCII|ENC_NA);
597 numelem = tvb_get_ntohl (tvb, offset);
598 proto_tree_add_text (tree, tvb, offset, 4,
599 "Number of Platform Node Name Entries: %d",
602 for (i = 0; i < numelem; i++) {
603 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset,
604 8, tvb_fcwwn_to_str (tvb, offset));
612 dissect_fcfcs_rpln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
614 int offset = 16; /* past the fc_ct header */
619 len = tvb_get_guint8 (tvb, offset);
620 proto_tree_add_text (tree, tvb, offset, 1,
621 "Platform Name Length: %d", len);
622 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
624 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset+256,
625 8, tvb_fcwwn_to_str (tvb, offset+256));
631 dissect_fcfcs_rplt (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
633 int offset = 16; /* past the fc_ct header */
638 len = tvb_get_guint8 (tvb, offset);
639 proto_tree_add_text (tree, tvb, offset, 1,
640 "Platform Name Length: %d", len);
641 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
643 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+256,
650 dissect_fcfcs_rplm (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
652 int offset = 16; /* past the fc_ct header */
657 len = tvb_get_guint8 (tvb, offset);
658 proto_tree_add_text (tree, tvb, offset, 1,
659 "Platform Name Length: %d", len);
660 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
662 len = tvb_get_guint8 (tvb, offset+256);
663 proto_tree_add_text (tree, tvb, offset+256, 1,
664 "Platform Mgmt. Address Length: %d", len);
665 proto_tree_add_item (tree, hf_fcs_platformaddr, tvb, offset+257,
666 len, ENC_ASCII|ENC_NA);
672 dissect_fcfcs_dpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
674 int offset = 16; /* past the fc_ct header */
679 len = tvb_get_guint8 (tvb, offset);
680 proto_tree_add_text (tree, tvb, offset, 1,
681 "Platform Name Length: %d", len);
682 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
689 dissect_fcfcs_dpln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
691 int offset = 16; /* past the fc_ct header */
695 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset, 8,
696 tvb_fcwwn_to_str (tvb, offset));
702 dissect_fcfcs_dplml (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
704 int offset = 16; /* past the fc_ct header */
709 len = tvb_get_guint8 (tvb, offset);
710 proto_tree_add_text (tree, tvb, offset, 1,
711 "Platform Name Length: %d", len);
712 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
719 dissect_fcfcs_gcap (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
721 int offset = 16; /* past the fc_ct header */
727 numrec = tvb_get_ntohl (tvb, offset);
728 proto_tree_add_item (tree, hf_fcs_numcap, tvb, offset, 4, ENC_BIG_ENDIAN);
731 for (i = 0; i < numrec; i++) {
732 subtype = tvb_get_guint8 (tvb, offset);
733 proto_tree_add_uint (tree, hf_fcs_mgmt_subtype, tvb, offset,
736 proto_tree_add_item (tree, hf_fcs_vnd_capmask, tvb, offset+1,
738 if (subtype == FCCT_GSSUBTYPE_FCS) {
739 proto_tree_add_item (tree, hf_fcs_fcsmask, tvb, offset+4,
742 else if (subtype == FCCT_GSSUBTYPE_UNS) {
743 proto_tree_add_item (tree, hf_fcs_unsmask, tvb, offset+4,
753 dissect_fcfcs_rjt (tvbuff_t *tvb, proto_tree *tree)
758 proto_tree_add_item (tree, hf_fcs_reason, tvb, offset+13, 1, ENC_BIG_ENDIAN);
759 proto_tree_add_item (tree, hf_fcs_rjtdetail, tvb, offset+14, 1,
761 proto_tree_add_item (tree, hf_fcs_vendor, tvb, offset+15, 1, ENC_BIG_ENDIAN);
767 dissect_fcfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
770 /* Set up structures needed to add the protocol subtree and manage it */
773 proto_tree *fcfcs_tree = NULL;
774 fc_ct_preamble cthdr;
776 conversation_t *conversation;
777 fcfcs_conv_data_t *cdata;
778 fcfcs_conv_key_t ckey, *req_key;
783 /* Reject the packet if data is NULL */
786 fchdr = (fc_hdr *)data;
788 /* Make entries in Protocol column and Info column on summary display */
789 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FC-FCS");
792 ti = proto_tree_add_protocol_format (tree, proto_fcfcs, tvb, 0,
793 tvb_reported_length (tvb),
795 fcfcs_tree = proto_item_add_subtree (ti, ett_fcfcs);
798 tvb_memcpy (tvb, (guint8 *)&cthdr, offset, FCCT_PRMBL_SIZE);
799 cthdr.revision = tvb_get_guint8 (tvb, offset);
800 cthdr.in_id = tvb_get_ntoh24 (tvb, offset+1);
801 cthdr.opcode = g_ntohs (cthdr.opcode);
802 opcode = tvb_get_ntohs (tvb, offset+8);
803 cthdr.maxres_size = g_ntohs (cthdr.maxres_size);
805 if ((opcode != FCCT_MSG_ACC) && (opcode != FCCT_MSG_RJT)) {
806 conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
807 pinfo->ptype, fchdr->oxid,
808 fchdr->rxid, NO_PORT2);
810 conversation = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst,
811 pinfo->ptype, fchdr->oxid,
812 fchdr->rxid, NO_PORT2);
815 ckey.conv_idx = conversation->index;
817 cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash,
820 /* Since we never free the memory used by an exchange, this maybe a
821 * case of another request using the same exchange as a previous
824 cdata->opcode = opcode;
827 req_key = wmem_new(wmem_file_scope(), fcfcs_conv_key_t);
828 req_key->conv_idx = conversation->index;
830 cdata = wmem_new(wmem_file_scope(), fcfcs_conv_data_t);
831 cdata->opcode = opcode;
833 g_hash_table_insert (fcfcs_req_hash, req_key, cdata);
835 col_add_str (pinfo->cinfo, COL_INFO,
836 val_to_str (opcode, fc_fcs_opcode_abbrev_val, "0x%x"));
839 /* Opcode is ACC or RJT */
840 conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
841 pinfo->ptype, fchdr->oxid,
842 fchdr->rxid, NO_PORT2);
845 if (opcode == FCCT_MSG_ACC) {
846 col_add_str (pinfo->cinfo, COL_INFO,
847 val_to_str (opcode, fc_fcs_opcode_abbrev_val,
849 /* No record of what this accept is for. Can't decode */
850 proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb),
851 "No record of Exchg. Unable to decode MSG_ACC/RJT");
856 ckey.conv_idx = conversation->index;
858 cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash,
862 if (opcode == FCCT_MSG_ACC)
863 opcode = cdata->opcode;
865 failed_opcode = cdata->opcode;
868 if (opcode != FCCT_MSG_RJT) {
869 col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_ACC (%s)",
870 val_to_str (opcode, fc_fcs_opcode_abbrev_val,
874 col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_RJT (%s)",
875 val_to_str (failed_opcode,
876 fc_fcs_opcode_abbrev_val,
881 if ((cdata == NULL) && (opcode != FCCT_MSG_RJT)) {
882 /* No record of what this accept is for. Can't decode */
883 proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb),
884 "No record of Exchg. Unable to decode MSG_ACC/RJT");
893 proto_tree_add_item (fcfcs_tree, hf_fcs_opcode, tvb, offset+8, 2, ENC_BIG_ENDIAN);
894 proto_tree_add_item (fcfcs_tree, hf_fcs_maxres_size, tvb, offset+10,
900 dissect_fcfcs_rjt (tvb, fcfcs_tree);
903 dissect_fcfcs_giel (tvb, fcfcs_tree, isreq);
906 dissect_fcfcs_giet (tvb, fcfcs_tree, isreq);
909 dissect_fcfcs_gdid (tvb, fcfcs_tree, isreq);
912 dissect_fcfcs_gmid (tvb, fcfcs_tree, isreq);
915 dissect_fcfcs_gfn (tvb, fcfcs_tree, isreq);
918 dissect_fcfcs_gieln (tvb, fcfcs_tree, isreq);
921 dissect_fcfcs_gmal (tvb, fcfcs_tree, isreq);
924 dissect_fcfcs_gieil (tvb, fcfcs_tree, isreq);
927 dissect_fcfcs_gpl (tvb, fcfcs_tree, isreq);
930 dissect_fcfcs_gpt (tvb, fcfcs_tree, isreq);
933 dissect_fcfcs_gppn (tvb, fcfcs_tree, isreq);
936 dissect_fcfcs_gapnl (tvb, fcfcs_tree, isreq);
939 dissect_fcfcs_gps (tvb, fcfcs_tree, isreq);
942 dissect_fcfcs_gplnl (tvb, fcfcs_tree, isreq);
945 dissect_fcfcs_gplt (tvb, fcfcs_tree, isreq);
948 dissect_fcfcs_gplml (tvb, fcfcs_tree, isreq);
951 dissect_fcfcs_gnpl (tvb, fcfcs_tree, isreq);
954 dissect_fcfcs_gpnl (tvb, fcfcs_tree, isreq);
957 dissect_fcfcs_rieln (tvb, fcfcs_tree, isreq);
960 dissect_fcfcs_rpl (tvb, fcfcs_tree, isreq);
963 dissect_fcfcs_rpln (tvb, fcfcs_tree, isreq);
966 dissect_fcfcs_rplt (tvb, fcfcs_tree, isreq);
969 dissect_fcfcs_rplm (tvb, fcfcs_tree, isreq);
972 dissect_fcfcs_dpl (tvb, fcfcs_tree, isreq);
975 dissect_fcfcs_dpln (tvb, fcfcs_tree, isreq);
978 dissect_fcfcs_dplml (tvb, fcfcs_tree, isreq);
981 dissect_fcfcs_gcap (tvb, fcfcs_tree, isreq);
984 call_dissector (data_handle, tvb, pinfo, fcfcs_tree);
988 return tvb_length(tvb);
991 /* Register the protocol with Wireshark */
994 proto_register_fcfcs (void)
997 static hf_register_info hf[] = {
999 {"Opcode", "fcs.opcode", FT_UINT16, BASE_HEX,
1000 VALS (fc_fcs_opcode_val), 0x0, NULL, HFILL}},
1002 {"Interconnect Element Name", "fcs.ie.name", FT_STRING, BASE_NONE,
1003 NULL, 0x0, NULL, HFILL}},
1005 {"Interconnect Element Type", "fcs.ie.type", FT_UINT8, BASE_HEX,
1006 VALS (fc_fcs_ietype_val), 0x0, NULL, HFILL}},
1007 { &hf_fcs_iedomainid,
1008 {"Interconnect Element Domain ID", "fcs.ie.domainid", FT_UINT8,
1009 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1011 {"Interconnect Element Mgmt. ID", "fcs.ie.mgmtid", FT_STRING,
1012 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1013 { &hf_fcs_fabricname,
1014 {"Interconnect Element Fabric Name", "fcs.ie.fname", FT_STRING,
1015 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1017 {"Interconnect Element Mgmt. Address", "fcs.ie.mgmtaddr", FT_STRING,
1018 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1020 {"Interconnect Element Logical Name", "fcs.ie.logname", FT_STRING,
1021 BASE_NONE, NULL, 0x0, NULL, HFILL}},
1022 { &hf_fcs_vendorname,
1023 {"Vendor Name", "fcs.vendorname", FT_STRING, BASE_NONE, NULL, 0x0, NULL,
1025 { &hf_fcs_modelname,
1026 {"Model Name/Number", "fcs.modelname", FT_STRING, BASE_NONE, NULL,
1029 {"Port Name", "fcs.port.name", FT_STRING, BASE_NONE, NULL, 0x0, NULL,
1031 { &hf_fcs_portmodtype,
1032 {"Port Module Type", "fcs.port.moduletype", FT_UINT8, BASE_HEX,
1033 VALS (fc_fcs_port_modtype_val), 0x0, NULL, HFILL}},
1034 { &hf_fcs_porttxtype,
1035 {"Port TX Type", "fcs.port.txtype", FT_UINT8, BASE_HEX,
1036 VALS (fc_fcs_port_txtype_val), 0x0, NULL, HFILL}},
1038 {"Port Type", "fcs.port.type", FT_UINT8, BASE_HEX,
1039 VALS (fc_fcs_port_type_val), 0x0, NULL, HFILL}},
1040 { &hf_fcs_physportnum,
1041 {"Physical Port Number", "fcs.port.physportnum", FT_BYTES, BASE_NONE,
1042 NULL, 0x0, NULL, HFILL}},
1043 { &hf_fcs_portflags,
1044 {"Port Flags", "fcs.port.flags", FT_BOOLEAN, BASE_NONE,
1045 TFS (&fc_fcs_portflags_tfs), 0x0, NULL, HFILL}},
1046 { &hf_fcs_portstate,
1047 {"Port State", "fcs.port.state", FT_UINT8, BASE_HEX,
1048 VALS (fc_fcs_port_state_val), 0x0, NULL, HFILL}},
1049 { &hf_fcs_platformname,
1050 {"Platform Name", "fcs.platform.name", FT_BYTES, BASE_NONE, NULL, 0x0,
1052 { &hf_fcs_platformnname,
1053 {"Platform Node Name", "fcs.platform.nodename", FT_STRING, BASE_NONE,
1054 NULL, 0x0, NULL, HFILL}},
1055 { &hf_fcs_platformtype,
1056 {"Platform Type", "fcs.platform.type", FT_UINT8, BASE_HEX,
1057 VALS (fc_fcs_plat_type_val), 0x0, NULL, HFILL}},
1058 { &hf_fcs_platformaddr,
1059 {"Management Address", "fcs.platform.mgmtaddr", FT_STRING, BASE_NONE,
1060 NULL, 0x0, NULL, HFILL}},
1062 {"Reason Code", "fcs.reason", FT_UINT8, BASE_HEX,
1063 VALS (fc_ct_rjt_code_vals), 0x0, NULL, HFILL}},
1064 { &hf_fcs_rjtdetail,
1065 {"Reason Code Explanantion", "fcs.reasondet", FT_UINT8, BASE_HEX,
1066 VALS (fc_fcs_rjt_code_val), 0x0, NULL, HFILL}},
1068 {"Vendor Unique Reject Code", "fcs.err.vendor", FT_UINT8, BASE_HEX,
1069 NULL, 0x0, NULL, HFILL}},
1071 {"Number of Capabilities", "fcs.numcap", FT_UINT32, BASE_DEC, NULL,
1073 { &hf_fcs_mgmt_subtype,
1074 {"Management GS Subtype", "fcs.gssubtype", FT_UINT8, BASE_HEX, NULL,
1076 { &hf_fcs_vnd_capmask,
1077 {"Vendor Unique Capability Bitmask", "fcs.vbitmask", FT_UINT24,
1078 BASE_HEX, NULL, 0x0, NULL, HFILL}},
1080 {"Subtype Capability Bitmask", "fcs.fcsmask", FT_UINT32, BASE_HEX,
1081 VALS (fc_fcs_fcsmask_val), 0x0, NULL, HFILL}},
1083 {"Subtype Capability Bitmask", "fcs.unsmask", FT_UINT32, BASE_HEX,
1084 VALS (fc_fcs_unsmask_val), 0x0, NULL, HFILL}},
1085 { &hf_fcs_maxres_size,
1086 {"Maximum/Residual Size", "fcs.maxres_size", FT_UINT16, BASE_DEC,
1087 NULL, 0x0, NULL, HFILL}},
1088 { &hf_fcs_releasecode,
1089 {"Release Code", "fcs.releasecode", FT_STRING, BASE_NONE, NULL, 0x0,
1093 static gint *ett[] = {
1097 proto_fcfcs = proto_register_protocol("FC Fabric Configuration Server",
1100 proto_register_field_array(proto_fcfcs, hf, array_length(hf));
1101 proto_register_subtree_array(ett, array_length(ett));
1102 register_init_routine (&fcfcs_init_protocol);
1106 proto_reg_handoff_fcfcs (void)
1108 dissector_handle_t fcs_handle;
1110 fcs_handle = new_create_dissector_handle (dissect_fcfcs, proto_fcfcs);
1112 dissector_add_uint("fcct.server", FCCT_GSRVR_FCS, fcs_handle);
1114 data_handle = find_dissector ("data");