2 * Routines for FC Fabric Configuration Server
3 * Copyright 2001, Dinesh G Dutt <ddutt@andiamo.com>
5 * $Id: packet-fcfcs.c,v 1.1 2003/01/14 01:17:44 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-fcct.h"
59 #include "packet-fcfcs.h"
61 /* Initialize the protocol and registered fields */
62 static int proto_fcfcs = -1;
63 static int hf_fcs_opcode = -1;
64 static int hf_fcs_iename = -1;
65 static int hf_fcs_ietype = -1;
66 static int hf_fcs_iedomainid = -1;
67 static int hf_fcs_mgmtid = -1;
68 static int hf_fcs_fabricname = -1;
69 static int hf_fcs_mgmtaddr = -1;
70 static int hf_fcs_lname = -1;
71 static int hf_fcs_vendorname = -1;
72 static int hf_fcs_modelname = -1;
73 static int hf_fcs_portname = -1;
74 static int hf_fcs_portmodtype = -1;
75 static int hf_fcs_porttxtype = -1;
76 static int hf_fcs_porttype = -1;
77 static int hf_fcs_physportnum = -1;
78 static int hf_fcs_portflags = -1;
79 static int hf_fcs_portstate = -1;
80 static int hf_fcs_platformname = -1;
81 static int hf_fcs_platformnname = -1;
82 static int hf_fcs_platformtype = -1;
83 static int hf_fcs_platformaddr = -1;
84 static int hf_fcs_reason = -1;
85 static int hf_fcs_rjtdetail = -1;
86 static int hf_fcs_vendor = -1;
87 static int hf_fcs_numcap = -1;
88 static int hf_fcs_mgmt_subtype = -1;
89 static int hf_fcs_unsmask = -1;
90 static int hf_fcs_vnd_capmask = -1;
91 static int hf_fcs_fcsmask = -1;
92 static int hf_fcs_maxres_size = -1;
93 static int hf_fcs_releasecode = -1;
96 /* Initialize the subtree pointers */
97 static gint ett_fcfcs = -1;
99 typedef struct _fcfcs_conv_key {
103 typedef struct _fcfcs_conv_data {
107 GHashTable *fcfcs_req_hash = NULL;
108 GMemChunk *fcfcs_req_keys = NULL;
109 GMemChunk *fcfcs_req_vals = NULL;
110 guint32 fcfcs_init_count = 25;
112 static dissector_handle_t data_handle;
118 fcfcs_equal(gconstpointer v, gconstpointer w)
120 fcfcs_conv_key_t *v1 = (fcfcs_conv_key_t *)v;
121 fcfcs_conv_key_t *v2 = (fcfcs_conv_key_t *)w;
123 return (v1->conv_idx == v2->conv_idx);
127 fcfcs_hash (gconstpointer v)
129 fcfcs_conv_key_t *key = (fcfcs_conv_key_t *)v;
138 * Protocol initialization
141 fcfcs_init_protocol(void)
144 g_mem_chunk_destroy (fcfcs_req_keys);
146 g_mem_chunk_destroy (fcfcs_req_vals);
148 g_hash_table_destroy (fcfcs_req_hash);
150 fcfcs_req_hash = g_hash_table_new(fcfcs_hash, fcfcs_equal);
151 fcfcs_req_keys = g_mem_chunk_new ("fcfcs_req_keys",
152 sizeof(fcfcs_conv_key_t),
154 sizeof(fcfcs_conv_key_t),
156 fcfcs_req_vals = g_mem_chunk_new ("fcfcs_req_vals",
157 sizeof(fcfcs_conv_data_t),
159 sizeof(fcfcs_conv_data_t),
163 /* Code to actually dissect the packets */
165 dissect_fcfcs_giel (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
167 int offset = 16; /* past the ct header */
170 if (!isreq && tree) {
171 numelem = tvb_get_ntohl (tvb, offset);
173 proto_tree_add_text (tree, tvb, offset, 4, "Number of IE entries: 0x%d",
176 for (i = 0; i < numelem; i++) {
177 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
178 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
179 proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+11, 1, 0);
186 dissect_fcfcs_giet (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
188 int offset = 16; /* past the fcct header */
192 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
193 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
196 proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+3, 1, 0);
202 dissect_fcfcs_gdid (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
204 int offset = 16; /* past the fcct header */
208 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
209 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
212 proto_tree_add_item (tree, hf_fcs_iedomainid, tvb, offset+1, 1, 0);
218 dissect_fcfcs_gmid (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 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
228 proto_tree_add_string (tree, hf_fcs_mgmtid, tvb, offset+1, 3,
229 fc_to_str (tvb_get_ptr (tvb, offset+1, 3)));
235 dissect_fcfcs_gfn (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
237 int offset = 16; /* past the fcct header */
241 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
242 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
245 proto_tree_add_string (tree, hf_fcs_fabricname, tvb, offset, 8,
246 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
252 dissect_fcfcs_gieln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
254 int offset = 16; /* past the fcct header */
258 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
259 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
262 proto_tree_add_text (tree, tvb, offset, 1, "Name Length: %d",
263 tvb_get_guint8 (tvb, offset));
264 proto_tree_add_item (tree, hf_fcs_lname, tvb, offset+1,
265 tvb_get_guint8 (tvb, offset), 0);
271 dissect_fcfcs_gmal (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
273 int offset = 16; /* past the fcct header */
278 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
279 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
282 numelem = tvb_get_ntohl (tvb, offset);
283 proto_tree_add_text (tree, tvb, offset, 4,
284 "Number of Mgmt. Addresses: 0x%d", numelem);
287 for (i = 0; i < numelem; i++) {
288 proto_tree_add_text (tree, tvb, offset, 1, "Name Length: %d",
289 tvb_get_guint8 (tvb, offset));
290 proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset+1,
291 tvb_get_guint8 (tvb, offset), 0);
299 dissect_fcfcs_gieil (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
301 int offset = 16; /* past the fcct header */
303 int len, tot_len, prevlen;
307 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
308 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
311 tot_len = tvb_get_guint8 (tvb, offset+3);
312 proto_tree_add_text (tree, tvb, offset+3, 1, "List Length: %d",
316 str = (gchar *)tvb_get_ptr (tvb, offset+4, tot_len);
319 proto_tree_add_item (tree, hf_fcs_vendorname, tvb, offset+4,
324 str = (gchar *)tvb_get_ptr (tvb, offset+4+prevlen, tot_len-prevlen);
328 proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen,
333 str = (gchar *)tvb_get_ptr (tvb, offset+4+prevlen, tot_len-prevlen);
337 proto_tree_add_item (tree, hf_fcs_releasecode, tvb,
338 offset+4+prevlen, len, 0);
342 offset += (4+prevlen);
343 while (tot_len > prevlen) {
344 str = (gchar *)tvb_get_ptr (tvb, offset, tot_len-prevlen);
347 proto_tree_add_text (tree, tvb, offset, len,
348 "Vendor-specific Information: %s",
359 dissect_fcfcs_gpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
361 int offset = 16; /* past the fcct header */
366 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
367 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
370 numelem = tvb_get_ntohl (tvb, offset);
371 proto_tree_add_text (tree, tvb, offset, 4,
372 "Number of Port Entries: %d",
376 for (i = 0; i < numelem; i++) {
377 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
378 fcwwn_to_str (tvb_get_ptr (tvb, offset,
380 proto_tree_add_item (tree, hf_fcs_portmodtype, tvb, offset+9,
382 proto_tree_add_item (tree, hf_fcs_porttxtype, tvb, offset+10,
384 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11,
393 dissect_fcfcs_gpt (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
395 int offset = 16; /* past the fcct header */
399 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
400 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
403 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+3, 1, 0);
409 dissect_fcfcs_gppn (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
411 int offset = 16; /* past the fcct header */
415 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
416 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
419 proto_tree_add_item (tree, hf_fcs_physportnum, tvb, offset, 4, 0);
425 dissect_fcfcs_gapnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
427 int offset = 16; /* past the fcct header */
432 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
433 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
436 numelem = tvb_get_ntohl (tvb, offset);
437 proto_tree_add_text (tree, tvb, offset, 4,
438 "Number of Attached Port Entries: %d",
441 for (i = 0; i < numelem; i++) {
442 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
443 fcwwn_to_str (tvb_get_ptr (tvb, offset,
445 proto_tree_add_item (tree, hf_fcs_portflags, tvb, offset+10,
447 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+11,
456 dissect_fcfcs_gps (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
458 int offset = 16; /* past the fcct header */
462 proto_tree_add_string (tree, hf_fcs_portname, tvb, offset, 8,
463 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
466 proto_tree_add_item (tree, hf_fcs_porttype, tvb, offset+3, 1, 0);
467 proto_tree_add_item (tree, hf_fcs_portstate, tvb, offset+7, 1, 0);
473 dissect_fcfcs_gplnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
475 int offset = 16; /* past the fcct header */
480 len = tvb_get_guint8 (tvb, offset);
481 proto_tree_add_text (tree, tvb, offset, 1,
482 "Platform Name Length: %d", len);
483 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
487 numelem = tvb_get_ntohl (tvb, offset);
488 proto_tree_add_text (tree, tvb, offset, 4,
489 "Number of Platform Node Name Entries: %d",
492 for (i = 0; i < numelem; i++) {
493 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset,
495 fcwwn_to_str (tvb_get_ptr (tvb, offset,
504 dissect_fcfcs_gplt (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
506 int offset = 16; /* past the fcct header */
511 len = tvb_get_guint8 (tvb, offset);
512 proto_tree_add_text (tree, tvb, offset, 1,
513 "Platform Name Length: %d", len);
514 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
518 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+3,
525 dissect_fcfcs_gplml (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
527 int offset = 16; /* past the fcct header */
532 len = tvb_get_guint8 (tvb, offset);
533 proto_tree_add_text (tree, tvb, offset, 1,
534 "Platform Name Length: %d", len);
535 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
539 numelem = tvb_get_ntohl (tvb, offset);
540 proto_tree_add_text (tree, tvb, offset, 4,
541 "Number of Mgmt. Address Entries: %d",
544 for (i = 0; i < numelem; i++) {
545 len = tvb_get_guint8 (tvb, offset);
546 proto_tree_add_text (tree, tvb, offset, 1,
547 "Mgmt Address Length: %d",
549 proto_tree_add_item (tree, hf_fcs_platformaddr, tvb, offset+1,
558 dissect_fcfcs_gnpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
560 int offset = 16; /* past the fcct header */
565 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset, 8,
566 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
569 len = tvb_get_guint8 (tvb, offset);
570 proto_tree_add_text (tree, tvb, offset, 1,
571 "Platform Name Length: %d", len);
572 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
579 dissect_fcfcs_gpnl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
581 int offset = 16; /* past the fcct header */
586 numelem = tvb_get_ntohl (tvb, offset);
588 proto_tree_add_text (tree, tvb, offset, 4,
589 "Number of Platform Name Entries: %d",
592 for (i = 0; i < numelem; i++) {
593 len = tvb_get_guint8 (tvb, offset);
594 proto_tree_add_text (tree, tvb, offset, 1,
595 "Platform Name Length: %d",
597 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
606 dissect_fcfcs_rieln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
608 int offset = 16; /* past the fc_ct header */
613 proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
614 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
615 len = tvb_get_guint8 (tvb, offset+8);
616 proto_tree_add_text (tree, tvb, offset+8, 1,
617 "Logical Name Length: %d", len);
618 proto_tree_add_item (tree, hf_fcs_lname, tvb, offset+9, len, 0);
624 dissect_fcfcs_rpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
626 int offset = 16; /* past the fc_ct header */
631 len = tvb_get_guint8 (tvb, offset);
632 proto_tree_add_text (tree, tvb, offset, 1,
633 "Platform Name Length: %d", len);
634 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
636 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+259, 1,
638 numelem = tvb_get_ntohl (tvb, offset+260);
639 proto_tree_add_text (tree, tvb, offset+260, 4,
640 "Number of Mgmt. Addr Entries: %d", numelem);
642 for (i = 0; i < numelem; i++) {
643 len = tvb_get_guint8 (tvb, offset);
644 proto_tree_add_text (tree, tvb, offset, 1,
645 "Mgmt. Addr Length: %d", len);
646 proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset+1,
651 numelem = tvb_get_ntohl (tvb, offset);
652 proto_tree_add_text (tree, tvb, offset, 4,
653 "Number of Platform Node Name Entries: %d",
656 for (i = 0; i < numelem; i++) {
657 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset,
659 fcwwn_to_str (tvb_get_ptr (tvb, offset,
668 dissect_fcfcs_rpln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
670 int offset = 16; /* past the fc_ct header */
675 len = tvb_get_guint8 (tvb, offset);
676 proto_tree_add_text (tree, tvb, offset, 1,
677 "Platform Name Length: %d", len);
678 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
680 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset+256,
682 fcwwn_to_str (tvb_get_ptr (tvb, offset+256,
689 dissect_fcfcs_rplt (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
691 int offset = 16; /* past the fc_ct header */
696 len = tvb_get_guint8 (tvb, offset);
697 proto_tree_add_text (tree, tvb, offset, 1,
698 "Platform Name Length: %d", len);
699 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
701 proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+259,
708 dissect_fcfcs_rplm (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
710 int offset = 16; /* past the fc_ct header */
715 len = tvb_get_guint8 (tvb, offset);
716 proto_tree_add_text (tree, tvb, offset, 1,
717 "Platform Name Length: %d", len);
718 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
720 len = tvb_get_guint8 (tvb, offset+256);
721 proto_tree_add_text (tree, tvb, offset+256, 1,
722 "Platform Mgmt. Address Length: %d", len);
723 proto_tree_add_item (tree, hf_fcs_platformaddr, tvb, offset+257,
730 dissect_fcfcs_dpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
732 int offset = 16; /* past the fc_ct header */
737 len = tvb_get_guint8 (tvb, offset);
738 proto_tree_add_text (tree, tvb, offset, 1,
739 "Platform Name Length: %d", len);
740 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
747 dissect_fcfcs_dpln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
749 int offset = 16; /* past the fc_ct header */
753 proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset, 8,
754 fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
760 dissect_fcfcs_dplml (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
762 int offset = 16; /* past the fc_ct header */
767 len = tvb_get_guint8 (tvb, offset);
768 proto_tree_add_text (tree, tvb, offset, 1,
769 "Platform Name Length: %d", len);
770 proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
777 dissect_fcfcs_gcap (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
779 int offset = 16; /* past the fc_ct header */
785 numrec = tvb_get_ntohl (tvb, offset);
786 proto_tree_add_item (tree, hf_fcs_numcap, tvb, offset, 4, 0);
789 for (i = 0; i < numrec; i++) {
790 proto_tree_add_item (tree, hf_fcs_mgmt_subtype, tvb, offset,
792 subtype = tvb_get_guint8 (tvb, offset);
794 proto_tree_add_item (tree, hf_fcs_vnd_capmask, tvb, offset+1,
796 if (subtype == FCCT_GSSUBTYPE_FCS) {
797 proto_tree_add_item (tree, hf_fcs_fcsmask, tvb, offset+4,
800 else if (subtype == FCCT_GSSUBTYPE_UNS) {
801 proto_tree_add_item (tree, hf_fcs_unsmask, tvb, offset+4,
810 dissect_fcfcs_rjt (tvbuff_t *tvb, proto_tree *tree)
815 proto_tree_add_item (tree, hf_fcs_reason, tvb, offset+13, 1, 0);
816 proto_tree_add_item (tree, hf_fcs_rjtdetail, tvb, offset+14, 1,
818 proto_tree_add_item (tree, hf_fcs_vendor, tvb, offset+15, 1, 0);
824 dissect_fcfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
827 /* Set up structures needed to add the protocol subtree and manage it */
830 proto_tree *fcfcs_tree = NULL;
831 fc_ct_preamble cthdr;
833 conversation_t *conversation;
834 fcfcs_conv_data_t *cdata;
835 fcfcs_conv_key_t ckey, *req_key;
839 /* Make entries in Protocol column and Info column on summary display */
840 if (check_col(pinfo->cinfo, COL_PROTOCOL))
841 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FC-FCS");
844 ti = proto_tree_add_protocol_format (tree, proto_fcfcs, tvb, 0,
845 tvb_reported_length (tvb),
847 fcfcs_tree = proto_item_add_subtree (ti, ett_fcfcs);
850 tvb_memcpy (tvb, (guint8 *)&cthdr, offset, FCCT_PRMBL_SIZE);
851 cthdr.revision = tvb_get_guint8 (tvb, offset);
852 cthdr.in_id = tvb_get_ntoh24 (tvb, offset+1);
853 cthdr.opcode = ntohs (cthdr.opcode);
854 opcode = tvb_get_ntohs (tvb, offset+8);
855 cthdr.maxres_size = ntohs (cthdr.maxres_size);
857 if ((opcode != FCCT_MSG_ACC) && (opcode != FCCT_MSG_RJT)) {
858 conversation = find_conversation (&pinfo->src, &pinfo->dst,
859 pinfo->ptype, pinfo->oxid,
860 pinfo->rxid, NO_PORT2);
862 conversation = conversation_new (&pinfo->src, &pinfo->dst,
863 pinfo->ptype, pinfo->oxid,
864 pinfo->rxid, NO_PORT2);
867 ckey.conv_idx = conversation->index;
869 cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash,
872 /* Since we never free the memory used by an exchange, this maybe a
873 * case of another request using the same exchange as a previous
876 cdata->opcode = opcode;
879 req_key = g_mem_chunk_alloc (fcfcs_req_keys);
880 req_key->conv_idx = conversation->index;
882 cdata = g_mem_chunk_alloc (fcfcs_req_vals);
883 cdata->opcode = opcode;
885 g_hash_table_insert (fcfcs_req_hash, req_key, cdata);
887 if (check_col (pinfo->cinfo, COL_INFO)) {
888 col_set_str (pinfo->cinfo, COL_INFO,
889 val_to_str (opcode, fc_fcs_opcode_abbrev_val, "0x%x"));
893 /* Opcode is ACC or RJT */
894 conversation = find_conversation (&pinfo->src, &pinfo->dst,
895 pinfo->ptype, pinfo->oxid,
896 pinfo->rxid, NO_PORT2);
899 if (tree && (opcode == FCCT_MSG_ACC)) {
900 if (check_col (pinfo->cinfo, COL_INFO)) {
901 col_set_str (pinfo->cinfo, COL_INFO,
902 val_to_str (opcode, fc_fcs_opcode_abbrev_val,
905 /* No record of what this accept is for. Can't decode */
906 proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb),
907 "No record of Exchg. Unable to decode MSG_ACC/RJT");
912 ckey.conv_idx = conversation->index;
914 cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash,
918 if (opcode == FCCT_MSG_ACC)
919 opcode = cdata->opcode;
921 failed_opcode = cdata->opcode;
924 if (check_col (pinfo->cinfo, COL_INFO)) {
925 if (opcode != FCCT_MSG_RJT) {
926 col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_ACC (%s)",
927 val_to_str (opcode, fc_fcs_opcode_abbrev_val,
931 col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_RJT (%s)",
932 val_to_str (failed_opcode,
933 fc_fcs_opcode_abbrev_val,
939 if ((cdata == NULL) && (opcode != FCCT_MSG_RJT)) {
940 /* No record of what this accept is for. Can't decode */
941 proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb),
942 "No record of Exchg. Unable to decode MSG_ACC/RJT");
951 proto_tree_add_item (fcfcs_tree, hf_fcs_opcode, tvb, offset+8, 2, 0);
952 proto_tree_add_item (fcfcs_tree, hf_fcs_maxres_size, tvb, offset+10,
958 dissect_fcfcs_rjt (tvb, fcfcs_tree);
961 dissect_fcfcs_giel (tvb, fcfcs_tree, isreq);
964 dissect_fcfcs_giet (tvb, fcfcs_tree, isreq);
967 dissect_fcfcs_gdid (tvb, fcfcs_tree, isreq);
970 dissect_fcfcs_gmid (tvb, fcfcs_tree, isreq);
973 dissect_fcfcs_gfn (tvb, fcfcs_tree, isreq);
976 dissect_fcfcs_gieln (tvb, fcfcs_tree, isreq);
979 dissect_fcfcs_gmal (tvb, fcfcs_tree, isreq);
982 dissect_fcfcs_gieil (tvb, fcfcs_tree, isreq);
985 dissect_fcfcs_gpl (tvb, fcfcs_tree, isreq);
988 dissect_fcfcs_gpt (tvb, fcfcs_tree, isreq);
991 dissect_fcfcs_gppn (tvb, fcfcs_tree, isreq);
994 dissect_fcfcs_gapnl (tvb, fcfcs_tree, isreq);
997 dissect_fcfcs_gps (tvb, fcfcs_tree, isreq);
1000 dissect_fcfcs_gplnl (tvb, fcfcs_tree, isreq);
1003 dissect_fcfcs_gplt (tvb, fcfcs_tree, isreq);
1006 dissect_fcfcs_gplml (tvb, fcfcs_tree, isreq);
1009 dissect_fcfcs_gnpl (tvb, fcfcs_tree, isreq);
1012 dissect_fcfcs_gpnl (tvb, fcfcs_tree, isreq);
1015 dissect_fcfcs_rieln (tvb, fcfcs_tree, isreq);
1018 dissect_fcfcs_rpl (tvb, fcfcs_tree, isreq);
1021 dissect_fcfcs_rpln (tvb, fcfcs_tree, isreq);
1024 dissect_fcfcs_rplt (tvb, fcfcs_tree, isreq);
1027 dissect_fcfcs_rplm (tvb, fcfcs_tree, isreq);
1030 dissect_fcfcs_dpl (tvb, fcfcs_tree, isreq);
1033 dissect_fcfcs_dpln (tvb, fcfcs_tree, isreq);
1036 dissect_fcfcs_dplml (tvb, fcfcs_tree, isreq);
1039 dissect_fcfcs_gcap (tvb, fcfcs_tree, isreq);
1042 call_dissector (data_handle, tvb, pinfo, fcfcs_tree);
1047 /* Register the protocol with Ethereal */
1049 /* this format is require because a script is used to build the C function
1050 that calls all the protocol registration.
1054 proto_register_fcfcs (void)
1057 /* Setup list of header fields See Section 1.6.1 for details*/
1058 static hf_register_info hf[] = {
1060 {"Opcode", "fcs.opcode", FT_UINT16, BASE_HEX,
1061 VALS (fc_fcs_opcode_val), 0x0, "", HFILL}},
1063 {"Interconnect Element Name", "fcs.ie.name", FT_STRING, BASE_HEX,
1064 NULL, 0x0, "", HFILL}},
1066 {"Interconnect Element Type", "fcs.ie.type", FT_UINT8, BASE_HEX,
1067 VALS (fc_fcs_ietype_val), 0x0, "", HFILL}},
1068 { &hf_fcs_iedomainid,
1069 {"Interconnect Element Domain ID", "fcs.ie.domainid", FT_UINT8,
1070 BASE_HEX, NULL, 0x0, "", HFILL}},
1072 {"Interconnect Element Mgmt. ID", "fcs.ie.mgmtid", FT_STRING,
1073 BASE_HEX, NULL, 0x0, "", HFILL}},
1074 { &hf_fcs_fabricname,
1075 {"Interconnect Element Fabric Name", "fcs.ie.fname", FT_STRING,
1076 BASE_HEX, NULL, 0x0, "", HFILL}},
1078 {"Interconnect Element Mgmt. Address", "fcs.ie.mgmtaddr", FT_STRING,
1079 BASE_HEX, NULL, 0x0, "", HFILL}},
1081 {"Interconnect Element Logical Name", "fcs.ie.logname", FT_STRING,
1082 BASE_HEX, NULL, 0x0, "", HFILL}},
1083 { &hf_fcs_vendorname,
1084 {"Vendor Name", "fcs.vendorname", FT_STRING, BASE_HEX, NULL, 0x0, "",
1086 { &hf_fcs_modelname,
1087 {"Model Name/Number", "fcs.modelname", FT_STRING, BASE_HEX, NULL,
1090 {"Port Name", "fcs.port.name", FT_STRING, BASE_HEX, NULL, 0x0, "",
1092 { &hf_fcs_portmodtype,
1093 {"Port Module Type", "fcs.port.moduletype", FT_UINT8, BASE_HEX,
1094 VALS (fc_fcs_port_modtype_val), 0x0, "", HFILL}},
1095 { &hf_fcs_porttxtype,
1096 {"Port TX Type", "fcs.port.txtype", FT_UINT8, BASE_HEX,
1097 VALS (fc_fcs_port_txtype_val), 0x0, "", HFILL}},
1099 {"Port Type", "fcs.port.type", FT_UINT8, BASE_HEX,
1100 VALS (fc_fcs_port_type_val), 0x0, "", HFILL}},
1101 { &hf_fcs_physportnum,
1102 {"Physical Port Number", "fcs.port.physportnum", FT_BYTES, BASE_HEX,
1103 NULL, 0x0, "", HFILL}},
1104 { &hf_fcs_portflags,
1105 {"Port Flags", "fcs.port.flags", FT_BOOLEAN, BASE_NONE,
1106 TFS (&fc_fcs_portflags_tfs), 0x0, "", HFILL}},
1107 { &hf_fcs_portstate,
1108 {"Port State", "fcs.port.state", FT_UINT8, BASE_HEX,
1109 VALS (fc_fcs_port_state_val), 0x0, "", HFILL}},
1110 { &hf_fcs_platformname,
1111 {"Platform Name", "fcs.platform.name", FT_STRING, BASE_HEX, NULL, 0x0,
1113 { &hf_fcs_platformnname,
1114 {"Platform Node Name", "fcs.platform.nodename", FT_STRING, BASE_HEX,
1115 NULL, 0x0, "", HFILL}},
1116 { &hf_fcs_platformtype,
1117 {"Platform Type", "fcs.platform.type", FT_UINT8, BASE_HEX,
1118 VALS (fc_fcs_plat_type_val), 0x0, "", HFILL}},
1119 { &hf_fcs_platformaddr,
1120 {"Management Address", "fcs.platform.mgmtaddr", FT_STRING, BASE_HEX,
1121 NULL, 0x0, "", HFILL}},
1123 {"Reason Code", "fcs.reason", FT_UINT8, BASE_HEX,
1124 VALS (fc_ct_rjt_code_vals), 0x0, "", HFILL}},
1125 { &hf_fcs_rjtdetail,
1126 {"Reason Code Explanantion", "fcs.reasondet", FT_UINT8, BASE_HEX,
1127 VALS (fc_fcs_rjt_code_val), 0x0, "", HFILL}},
1129 {"Vendor Unique Reject Code", "fcs.err.vendor", FT_UINT8, BASE_HEX,
1130 NULL, 0x0, "", HFILL}},
1132 {"Number of Capabilities", "fcs.numcap", FT_UINT32, BASE_DEC, NULL,
1134 { &hf_fcs_mgmt_subtype,
1135 {"Management GS Subtype", "fcs.gssubtype", FT_UINT8, BASE_HEX, NULL,
1137 { &hf_fcs_vnd_capmask,
1138 {"Vendor Unique Capability Bitmask", "fcs.vbitmask", FT_UINT24,
1139 BASE_HEX, NULL, 0x0, "", HFILL}},
1141 {"Subtype Capability Bitmask", "fcs.fcsmask", FT_UINT32, BASE_HEX,
1142 VALS (fc_fcs_fcsmask_val), 0x0, "", HFILL}},
1144 {"Subtype Capability Bitmask", "fcs.unsmask", FT_UINT32, BASE_HEX,
1145 VALS (fc_fcs_unsmask_val), 0x0, "", HFILL}},
1146 { &hf_fcs_maxres_size,
1147 {"Maximum/Residual Size", "fcs.maxres_size", FT_UINT16, BASE_DEC,
1148 NULL, 0x0, "", HFILL}},
1149 { &hf_fcs_releasecode,
1150 {"Release Code", "fcs.releasecode", FT_STRING, BASE_HEX, NULL, 0x0,
1154 /* Setup protocol subtree array */
1155 static gint *ett[] = {
1159 /* Register the protocol name and description */
1160 proto_fcfcs = proto_register_protocol("FC Fabric Configuration Server",
1163 /* Required function calls to register the header fields and subtrees used */
1164 proto_register_field_array(proto_fcfcs, hf, array_length(hf));
1165 proto_register_subtree_array(ett, array_length(ett));
1166 register_init_routine (&fcfcs_init_protocol);
1169 /* If this dissector uses sub-dissector registration add a registration routine.
1170 This format is required because a script is used to find these routines and
1171 create the code that calls these routines.
1174 proto_reg_handoff_fcfcs (void)
1176 dissector_handle_t fcs_handle;
1178 fcs_handle = create_dissector_handle (dissect_fcfcs, proto_fcfcs);
1180 dissector_add("fcct.server", FCCT_GSRVR_FCS, fcs_handle);
1182 data_handle = find_dissector ("data");