2 * Routines for FC Common Transport Protocol (used by GS3 services)
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
14 #include <epan/packet.h>
15 #include <epan/to_str.h>
16 #include "packet-fc.h"
17 #include "packet-fcct.h"
19 void proto_register_fcct(void);
20 void proto_reg_handoff_fcct(void);
22 static dissector_handle_t fcct_handle
;
24 /* Initialize the protocol and registered fields */
25 static int proto_fcct
;
26 static int hf_fcct_revision
;
27 static int hf_fcct_inid
;
28 static int hf_fcct_gstype
;
29 static int hf_fcct_gssubtype
;
30 static int hf_fcct_options
;
31 static int hf_fcct_server
; /* derived field */
33 /* Extended preamble fields */
35 static int hf_fcct_ext_said
;
36 static int hf_fcct_ext_tid
;
37 static int hf_fcct_ext_reqname
;
38 static int hf_fcct_ext_tstamp
;
39 static int hf_fcct_ext_authblk
;
42 /* Initialize the subtree pointers */
44 static int ett_fcct_ext
; /* for the extended header */
46 const value_string fc_ct_rjt_code_vals
[] = {
47 {FCCT_RJT_INVCMDCODE
, "Invalid Cmd Code"},
48 {FCCT_RJT_INVVERSION
, "Invalid Version Level"},
49 {FCCT_RJT_LOGICALERR
, "Logical Error"},
50 {FCCT_RJT_INVSIZE
, "Invalid CT_IU Size"},
51 {FCCT_RJT_LOGICALBSY
, "Logical Busy"},
52 {FCCT_RJT_PROTOERR
, "Protocol Error"},
53 {FCCT_RJT_GENFAIL
, "Unable to Perform Cmd"},
54 {FCCT_RJT_CMDNOTSUPP
, "Cmd Not Supported"},
58 const value_string fc_ct_gstype_vals
[] = {
59 {FCCT_GSTYPE_KEYSVC
, "Key Service"},
60 {FCCT_GSTYPE_ALIASSVC
, "Alias Service"},
61 {FCCT_GSTYPE_MGMTSVC
, "Management Service"},
62 {FCCT_GSTYPE_TIMESVC
, "Time Service"},
63 {FCCT_GSTYPE_DIRSVC
, "Directory Service"},
64 {FCCT_GSTYPE_FCTLR
, "Fabric Controller"},
65 {FCCT_GSTYPE_VENDOR
, "Vendor-Specific"},
69 const value_string fc_ct_gsserver_vals
[] = {
70 {FCCT_GSRVR_DNS
, "dNS"},
71 {FCCT_GSRVR_IP
, "IP"},
72 {FCCT_GSRVR_FCS
, "Fabric Config Server"},
73 {FCCT_GSRVR_UNS
, "Unzoned Name Server"},
74 {FCCT_GSRVR_FZS
, "Fabric Zone Server"},
75 {FCCT_GSRVR_TS
, "Time Server"},
76 {FCCT_GSRVR_KS
, "Key Server"},
77 {FCCT_GSRVR_AS
, "Alias Server"},
78 {FCCT_GSRVR_FCTLR
, "Fabric Controller"},
82 static dissector_table_t fcct_gserver_table
;
85 get_gs_server (uint8_t gstype
, uint8_t gssubtype
)
88 case FCCT_GSTYPE_KEYSVC
:
90 case FCCT_GSTYPE_ALIASSVC
:
91 if (gssubtype
== FCCT_GSSUBTYPE_AS
)
93 return FCCT_GSRVR_UNKNOWN
;
94 case FCCT_GSTYPE_MGMTSVC
:
95 if (gssubtype
== FCCT_GSSUBTYPE_FCS
)
96 return FCCT_GSRVR_FCS
;
97 else if (gssubtype
== FCCT_GSSUBTYPE_UNS
)
98 return FCCT_GSRVR_UNS
;
99 else if (gssubtype
== FCCT_GSSUBTYPE_FZS
)
100 return FCCT_GSRVR_FZS
;
101 else return FCCT_GSRVR_UNKNOWN
;
102 case FCCT_GSTYPE_TIMESVC
:
103 if (gssubtype
== FCCT_GSSUBTYPE_TS
)
104 return FCCT_GSRVR_TS
;
105 return FCCT_GSRVR_UNKNOWN
;
106 case FCCT_GSTYPE_DIRSVC
:
107 if (gssubtype
== FCCT_GSSUBTYPE_DNS
)
108 return FCCT_GSRVR_DNS
;
109 else if (gssubtype
== FCCT_GSSUBTYPE_IP
)
110 return FCCT_GSRVR_IP
;
111 return FCCT_GSRVR_UNKNOWN
;
112 case FCCT_GSRVR_FCTLR
:
113 if (gssubtype
== FCCT_GSSUBTYPE_FCTLR
)
114 return (FCCT_GSRVR_FCTLR
);
115 else return (FCCT_GSRVR_UNKNOWN
);
117 return FCCT_GSRVR_UNKNOWN
;
121 /* Code to actually dissect the packets */
123 dissect_fcct (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
126 /* Set up structures needed to add the protocol subtree and manage it */
128 proto_tree
*fcct_tree
;
133 fc_ct_preamble cthdr
;
136 /* Make entries in Protocol column and Info column on summary display */
137 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "FC_CT");
140 cthdr.revision = tvb_get_uint8 (tvb, offset++);
141 cthdr.in_id = tvb_get_ntoh24 (tvb, offset);
144 cthdr.gstype = tvb_get_uint8 (tvb, offset++);
145 cthdr.options = tvb_get_uint8 (tvb, offset++);
147 tvb_memcpy (tvb
, (uint8_t *)&cthdr
, offset
, FCCT_PRMBL_SIZE
);
148 cthdr
.revision
= tvb_get_uint8 (tvb
, offset
++);
149 cthdr
.in_id
= tvb_get_ntoh24 (tvb
, offset
);
150 cthdr
.opcode
= g_ntohs (cthdr
.opcode
);
151 cthdr
.maxres_size
= g_ntohs (cthdr
.maxres_size
);
153 if (cthdr
.opcode
< FCCT_MSG_REQ_MAX
) {
154 col_append_str (pinfo
->cinfo
, COL_INFO
, " Request");
156 else if (cthdr
.opcode
== FCCT_MSG_ACC
) {
157 col_append_str (pinfo
->cinfo
, COL_INFO
, " Accept");
159 else if (cthdr
.opcode
== FCCT_MSG_RJT
) {
160 col_append_fstr (pinfo
->cinfo
, COL_INFO
, " Reject (%s)",
161 val_to_str (cthdr
.rjt_code
, fc_ct_rjt_code_vals
, "0x%x"));
164 col_append_str (pinfo
->cinfo
, COL_INFO
, " Reserved");
168 in_id
= g_htonl (in_id
) >> 8;
170 /* Determine server */
171 server
= get_gs_server (cthdr
.gstype
, cthdr
.gssubtype
);
175 ti
= proto_tree_add_protocol_format (tree
, proto_fcct
, tvb
, 0, FCCT_PRMBL_SIZE
,
177 fcct_tree
= proto_item_add_subtree (ti
, ett_fcct
);
179 proto_tree_add_item (fcct_tree
, hf_fcct_revision
, tvb
, offset
++,
180 sizeof (uint8_t), ENC_BIG_ENDIAN
);
181 set_address(&addr
, AT_FC
, 3, &in_id
);
182 proto_tree_add_string (fcct_tree
, hf_fcct_inid
, tvb
, offset
, 3,
183 address_to_str(pinfo
->pool
, &addr
));
184 offset
+= 3; /* sizeof FC address */
186 proto_tree_add_item (fcct_tree
, hf_fcct_gstype
, tvb
, offset
++,
187 sizeof (uint8_t), ENC_BIG_ENDIAN
);
188 proto_tree_add_item (fcct_tree
, hf_fcct_gssubtype
, tvb
, offset
,
189 sizeof (uint8_t), ENC_BIG_ENDIAN
);
190 proto_tree_add_uint (fcct_tree
, hf_fcct_server
, tvb
, offset
++, 1,
192 proto_tree_add_item (fcct_tree
, hf_fcct_options
, tvb
, offset
++,
193 sizeof (uint8_t), ENC_BIG_ENDIAN
);
196 /* We do not change the starting offset for the next protocol in the
197 * chain since the fc_ct header is common to the sub-protocols.
198 * Pass the fchdr* received from parent dissector through to sub-protocols
200 next_tvb
= tvb_new_subset_remaining (tvb
, 0);
201 if (!dissector_try_uint_with_data(fcct_gserver_table
, server
, next_tvb
, pinfo
,
203 call_data_dissector(next_tvb
, pinfo
, tree
);
206 return tvb_captured_length(tvb
);
209 /* Register the protocol with Wireshark */
212 proto_register_fcct(void)
215 /* Setup list of header fields See Section 1.6.1 for details*/
216 static hf_register_info hf
[] = {
218 {"Revision", "fcct.revision", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
220 {"IN_ID", "fcct.in_id", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
222 {"GS Type", "fcct.gstype", FT_UINT8
, BASE_HEX
, VALS(fc_ct_gstype_vals
),
224 { &hf_fcct_gssubtype
,
225 {"GS Subtype", "fcct.gssubtype", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
228 {"Server", "fcct.server", FT_UINT8
, BASE_HEX
,
229 VALS (fc_ct_gsserver_vals
), 0x0,
230 "Derived from GS Type & Subtype fields", HFILL
}},
232 {"Options", "fcct.options", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
,
236 {"Auth SAID", "fcct.ext_said", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
,
239 {"Transaction ID", "fcct.ext_tid", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
,
241 { &hf_fcct_ext_reqname
,
242 {"Requestor Port Name", "fcct.ext_reqnm", FT_BYTES
, BASE_NONE
, NULL
,
244 { &hf_fcct_ext_tstamp
,
245 {"Timestamp", "fcct.ext_tstamp", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
,
247 { &hf_fcct_ext_authblk
,
248 {"Auth Hash Blk", "fcct.ext_authblk", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
253 /* Setup protocol subtree array */
254 static int *ett
[] = {
259 /* Register the protocol name and description */
260 proto_fcct
= proto_register_protocol("Fibre Channel Common Transport", "FC_CT", "fcct");
262 /* Required function calls to register the header fields and subtrees used */
263 proto_register_field_array(proto_fcct
, hf
, array_length(hf
));
264 proto_register_subtree_array(ett
, array_length(ett
));
266 fcct_gserver_table
= register_dissector_table ("fcct.server",
268 proto_fcct
, FT_UINT8
, BASE_HEX
);
270 fcct_handle
= register_dissector("fcct", dissect_fcct
, proto_fcct
);
274 proto_reg_handoff_fcct (void)
276 dissector_add_uint("fc.ftype", FC_FTYPE_FCCT
, fcct_handle
);
280 * Editor modelines - https://www.wireshark.org/tools/modelines.html
285 * indent-tabs-mode: nil
288 * vi: set shiftwidth=4 tabstop=8 expandtab:
289 * :indentSize=4:tabSize=8:noTabs=true: