2 * Routines for FC Fabric Configuration 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-fcfcs.h"
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
)
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
;
782 /* Make entries in Protocol column and Info column on summary display */
783 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "FC-FCS");
786 ti
= proto_tree_add_protocol_format (tree
, proto_fcfcs
, tvb
, 0,
787 tvb_reported_length (tvb
),
789 fcfcs_tree
= proto_item_add_subtree (ti
, ett_fcfcs
);
792 tvb_memcpy (tvb
, (guint8
*)&cthdr
, offset
, FCCT_PRMBL_SIZE
);
793 cthdr
.revision
= tvb_get_guint8 (tvb
, offset
);
794 cthdr
.in_id
= tvb_get_ntoh24 (tvb
, offset
+1);
795 cthdr
.opcode
= g_ntohs (cthdr
.opcode
);
796 opcode
= tvb_get_ntohs (tvb
, offset
+8);
797 cthdr
.maxres_size
= g_ntohs (cthdr
.maxres_size
);
799 if ((opcode
!= FCCT_MSG_ACC
) && (opcode
!= FCCT_MSG_RJT
)) {
800 conversation
= find_conversation (pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
801 pinfo
->ptype
, pinfo
->oxid
,
802 pinfo
->rxid
, NO_PORT2
);
804 conversation
= conversation_new (pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
805 pinfo
->ptype
, pinfo
->oxid
,
806 pinfo
->rxid
, NO_PORT2
);
809 ckey
.conv_idx
= conversation
->index
;
811 cdata
= (fcfcs_conv_data_t
*)g_hash_table_lookup (fcfcs_req_hash
,
814 /* Since we never free the memory used by an exchange, this maybe a
815 * case of another request using the same exchange as a previous
818 cdata
->opcode
= opcode
;
821 req_key
= wmem_new(wmem_file_scope(), fcfcs_conv_key_t
);
822 req_key
->conv_idx
= conversation
->index
;
824 cdata
= wmem_new(wmem_file_scope(), fcfcs_conv_data_t
);
825 cdata
->opcode
= opcode
;
827 g_hash_table_insert (fcfcs_req_hash
, req_key
, cdata
);
829 col_add_str (pinfo
->cinfo
, COL_INFO
,
830 val_to_str (opcode
, fc_fcs_opcode_abbrev_val
, "0x%x"));
833 /* Opcode is ACC or RJT */
834 conversation
= find_conversation (pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
835 pinfo
->ptype
, pinfo
->oxid
,
836 pinfo
->rxid
, NO_PORT2
);
839 if (opcode
== FCCT_MSG_ACC
) {
840 col_add_str (pinfo
->cinfo
, COL_INFO
,
841 val_to_str (opcode
, fc_fcs_opcode_abbrev_val
,
843 /* No record of what this accept is for. Can't decode */
844 proto_tree_add_text (fcfcs_tree
, tvb
, 0, tvb_length (tvb
),
845 "No record of Exchg. Unable to decode MSG_ACC/RJT");
850 ckey
.conv_idx
= conversation
->index
;
852 cdata
= (fcfcs_conv_data_t
*)g_hash_table_lookup (fcfcs_req_hash
,
856 if (opcode
== FCCT_MSG_ACC
)
857 opcode
= cdata
->opcode
;
859 failed_opcode
= cdata
->opcode
;
862 if (opcode
!= FCCT_MSG_RJT
) {
863 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "MSG_ACC (%s)",
864 val_to_str (opcode
, fc_fcs_opcode_abbrev_val
,
868 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "MSG_RJT (%s)",
869 val_to_str (failed_opcode
,
870 fc_fcs_opcode_abbrev_val
,
875 if ((cdata
== NULL
) && (opcode
!= FCCT_MSG_RJT
)) {
876 /* No record of what this accept is for. Can't decode */
877 proto_tree_add_text (fcfcs_tree
, tvb
, 0, tvb_length (tvb
),
878 "No record of Exchg. Unable to decode MSG_ACC/RJT");
887 proto_tree_add_item (fcfcs_tree
, hf_fcs_opcode
, tvb
, offset
+8, 2, ENC_BIG_ENDIAN
);
888 proto_tree_add_item (fcfcs_tree
, hf_fcs_maxres_size
, tvb
, offset
+10,
894 dissect_fcfcs_rjt (tvb
, fcfcs_tree
);
897 dissect_fcfcs_giel (tvb
, fcfcs_tree
, isreq
);
900 dissect_fcfcs_giet (tvb
, fcfcs_tree
, isreq
);
903 dissect_fcfcs_gdid (tvb
, fcfcs_tree
, isreq
);
906 dissect_fcfcs_gmid (tvb
, fcfcs_tree
, isreq
);
909 dissect_fcfcs_gfn (tvb
, fcfcs_tree
, isreq
);
912 dissect_fcfcs_gieln (tvb
, fcfcs_tree
, isreq
);
915 dissect_fcfcs_gmal (tvb
, fcfcs_tree
, isreq
);
918 dissect_fcfcs_gieil (tvb
, fcfcs_tree
, isreq
);
921 dissect_fcfcs_gpl (tvb
, fcfcs_tree
, isreq
);
924 dissect_fcfcs_gpt (tvb
, fcfcs_tree
, isreq
);
927 dissect_fcfcs_gppn (tvb
, fcfcs_tree
, isreq
);
930 dissect_fcfcs_gapnl (tvb
, fcfcs_tree
, isreq
);
933 dissect_fcfcs_gps (tvb
, fcfcs_tree
, isreq
);
936 dissect_fcfcs_gplnl (tvb
, fcfcs_tree
, isreq
);
939 dissect_fcfcs_gplt (tvb
, fcfcs_tree
, isreq
);
942 dissect_fcfcs_gplml (tvb
, fcfcs_tree
, isreq
);
945 dissect_fcfcs_gnpl (tvb
, fcfcs_tree
, isreq
);
948 dissect_fcfcs_gpnl (tvb
, fcfcs_tree
, isreq
);
951 dissect_fcfcs_rieln (tvb
, fcfcs_tree
, isreq
);
954 dissect_fcfcs_rpl (tvb
, fcfcs_tree
, isreq
);
957 dissect_fcfcs_rpln (tvb
, fcfcs_tree
, isreq
);
960 dissect_fcfcs_rplt (tvb
, fcfcs_tree
, isreq
);
963 dissect_fcfcs_rplm (tvb
, fcfcs_tree
, isreq
);
966 dissect_fcfcs_dpl (tvb
, fcfcs_tree
, isreq
);
969 dissect_fcfcs_dpln (tvb
, fcfcs_tree
, isreq
);
972 dissect_fcfcs_dplml (tvb
, fcfcs_tree
, isreq
);
975 dissect_fcfcs_gcap (tvb
, fcfcs_tree
, isreq
);
978 call_dissector (data_handle
, tvb
, pinfo
, fcfcs_tree
);
983 /* Register the protocol with Wireshark */
986 proto_register_fcfcs (void)
989 static hf_register_info hf
[] = {
991 {"Opcode", "fcs.opcode", FT_UINT16
, BASE_HEX
,
992 VALS (fc_fcs_opcode_val
), 0x0, NULL
, HFILL
}},
994 {"Interconnect Element Name", "fcs.ie.name", FT_STRING
, BASE_NONE
,
995 NULL
, 0x0, NULL
, HFILL
}},
997 {"Interconnect Element Type", "fcs.ie.type", FT_UINT8
, BASE_HEX
,
998 VALS (fc_fcs_ietype_val
), 0x0, NULL
, HFILL
}},
999 { &hf_fcs_iedomainid
,
1000 {"Interconnect Element Domain ID", "fcs.ie.domainid", FT_UINT8
,
1001 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
1003 {"Interconnect Element Mgmt. ID", "fcs.ie.mgmtid", FT_STRING
,
1004 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1005 { &hf_fcs_fabricname
,
1006 {"Interconnect Element Fabric Name", "fcs.ie.fname", FT_STRING
,
1007 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1009 {"Interconnect Element Mgmt. Address", "fcs.ie.mgmtaddr", FT_STRING
,
1010 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1012 {"Interconnect Element Logical Name", "fcs.ie.logname", FT_STRING
,
1013 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1014 { &hf_fcs_vendorname
,
1015 {"Vendor Name", "fcs.vendorname", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
,
1017 { &hf_fcs_modelname
,
1018 {"Model Name/Number", "fcs.modelname", FT_STRING
, BASE_NONE
, NULL
,
1021 {"Port Name", "fcs.port.name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
,
1023 { &hf_fcs_portmodtype
,
1024 {"Port Module Type", "fcs.port.moduletype", FT_UINT8
, BASE_HEX
,
1025 VALS (fc_fcs_port_modtype_val
), 0x0, NULL
, HFILL
}},
1026 { &hf_fcs_porttxtype
,
1027 {"Port TX Type", "fcs.port.txtype", FT_UINT8
, BASE_HEX
,
1028 VALS (fc_fcs_port_txtype_val
), 0x0, NULL
, HFILL
}},
1030 {"Port Type", "fcs.port.type", FT_UINT8
, BASE_HEX
,
1031 VALS (fc_fcs_port_type_val
), 0x0, NULL
, HFILL
}},
1032 { &hf_fcs_physportnum
,
1033 {"Physical Port Number", "fcs.port.physportnum", FT_BYTES
, BASE_NONE
,
1034 NULL
, 0x0, NULL
, HFILL
}},
1035 { &hf_fcs_portflags
,
1036 {"Port Flags", "fcs.port.flags", FT_BOOLEAN
, BASE_NONE
,
1037 TFS (&fc_fcs_portflags_tfs
), 0x0, NULL
, HFILL
}},
1038 { &hf_fcs_portstate
,
1039 {"Port State", "fcs.port.state", FT_UINT8
, BASE_HEX
,
1040 VALS (fc_fcs_port_state_val
), 0x0, NULL
, HFILL
}},
1041 { &hf_fcs_platformname
,
1042 {"Platform Name", "fcs.platform.name", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1044 { &hf_fcs_platformnname
,
1045 {"Platform Node Name", "fcs.platform.nodename", FT_STRING
, BASE_NONE
,
1046 NULL
, 0x0, NULL
, HFILL
}},
1047 { &hf_fcs_platformtype
,
1048 {"Platform Type", "fcs.platform.type", FT_UINT8
, BASE_HEX
,
1049 VALS (fc_fcs_plat_type_val
), 0x0, NULL
, HFILL
}},
1050 { &hf_fcs_platformaddr
,
1051 {"Management Address", "fcs.platform.mgmtaddr", FT_STRING
, BASE_NONE
,
1052 NULL
, 0x0, NULL
, HFILL
}},
1054 {"Reason Code", "fcs.reason", FT_UINT8
, BASE_HEX
,
1055 VALS (fc_ct_rjt_code_vals
), 0x0, NULL
, HFILL
}},
1056 { &hf_fcs_rjtdetail
,
1057 {"Reason Code Explanantion", "fcs.reasondet", FT_UINT8
, BASE_HEX
,
1058 VALS (fc_fcs_rjt_code_val
), 0x0, NULL
, HFILL
}},
1060 {"Vendor Unique Reject Code", "fcs.err.vendor", FT_UINT8
, BASE_HEX
,
1061 NULL
, 0x0, NULL
, HFILL
}},
1063 {"Number of Capabilities", "fcs.numcap", FT_UINT32
, BASE_DEC
, NULL
,
1065 { &hf_fcs_mgmt_subtype
,
1066 {"Management GS Subtype", "fcs.gssubtype", FT_UINT8
, BASE_HEX
, NULL
,
1068 { &hf_fcs_vnd_capmask
,
1069 {"Vendor Unique Capability Bitmask", "fcs.vbitmask", FT_UINT24
,
1070 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
1072 {"Subtype Capability Bitmask", "fcs.fcsmask", FT_UINT32
, BASE_HEX
,
1073 VALS (fc_fcs_fcsmask_val
), 0x0, NULL
, HFILL
}},
1075 {"Subtype Capability Bitmask", "fcs.unsmask", FT_UINT32
, BASE_HEX
,
1076 VALS (fc_fcs_unsmask_val
), 0x0, NULL
, HFILL
}},
1077 { &hf_fcs_maxres_size
,
1078 {"Maximum/Residual Size", "fcs.maxres_size", FT_UINT16
, BASE_DEC
,
1079 NULL
, 0x0, NULL
, HFILL
}},
1080 { &hf_fcs_releasecode
,
1081 {"Release Code", "fcs.releasecode", FT_STRING
, BASE_NONE
, NULL
, 0x0,
1085 static gint
*ett
[] = {
1089 proto_fcfcs
= proto_register_protocol("FC Fabric Configuration Server",
1092 proto_register_field_array(proto_fcfcs
, hf
, array_length(hf
));
1093 proto_register_subtree_array(ett
, array_length(ett
));
1094 register_init_routine (&fcfcs_init_protocol
);
1098 proto_reg_handoff_fcfcs (void)
1100 dissector_handle_t fcs_handle
;
1102 fcs_handle
= create_dissector_handle (dissect_fcfcs
, proto_fcfcs
);
1104 dissector_add_uint("fcct.server", FCCT_GSRVR_FCS
, fcs_handle
);
1106 data_handle
= find_dissector ("data");