diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-fcct.c | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-fcct.c')
-rw-r--r-- | epan/dissectors/packet-fcct.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/epan/dissectors/packet-fcct.c b/epan/dissectors/packet-fcct.c new file mode 100644 index 00000000..21499a26 --- /dev/null +++ b/epan/dissectors/packet-fcct.c @@ -0,0 +1,290 @@ +/* packet-fcct.c + * Routines for FC Common Transport Protocol (used by GS3 services) + * Copyright 2001, Dinesh G Dutt <ddutt@andiamo.com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <epan/packet.h> +#include <epan/to_str.h> +#include "packet-fc.h" +#include "packet-fcct.h" + +void proto_register_fcct(void); +void proto_reg_handoff_fcct(void); + +static dissector_handle_t fcct_handle; + +/* Initialize the protocol and registered fields */ +static int proto_fcct = -1; +static int hf_fcct_revision = -1; +static int hf_fcct_inid = -1; +static int hf_fcct_gstype = -1; +static int hf_fcct_gssubtype = -1; +static int hf_fcct_options = -1; +static int hf_fcct_server = -1; /* derived field */ + +/* Extended preamble fields */ +#if 0 +static int hf_fcct_ext_said = -1; +static int hf_fcct_ext_tid = -1; +static int hf_fcct_ext_reqname = -1; +static int hf_fcct_ext_tstamp = -1; +static int hf_fcct_ext_authblk = -1; +#endif + +/* Initialize the subtree pointers */ +static gint ett_fcct = -1; +static gint ett_fcct_ext = -1; /* for the extended header */ + +const value_string fc_ct_rjt_code_vals [] = { + {FCCT_RJT_INVCMDCODE, "Invalid Cmd Code"}, + {FCCT_RJT_INVVERSION, "Invalid Version Level"}, + {FCCT_RJT_LOGICALERR, "Logical Error"}, + {FCCT_RJT_INVSIZE, "Invalid CT_IU Size"}, + {FCCT_RJT_LOGICALBSY, "Logical Busy"}, + {FCCT_RJT_PROTOERR, "Protocol Error"}, + {FCCT_RJT_GENFAIL, "Unable to Perform Cmd"}, + {FCCT_RJT_CMDNOTSUPP, "Cmd Not Supported"}, + {0, NULL}, +}; + +const value_string fc_ct_gstype_vals[] = { + {FCCT_GSTYPE_KEYSVC, "Key Service"}, + {FCCT_GSTYPE_ALIASSVC, "Alias Service"}, + {FCCT_GSTYPE_MGMTSVC, "Management Service"}, + {FCCT_GSTYPE_TIMESVC, "Time Service"}, + {FCCT_GSTYPE_DIRSVC, "Directory Service"}, + {FCCT_GSTYPE_FCTLR, "Fabric Controller"}, + {FCCT_GSTYPE_VENDOR, "Vendor-Specific"}, + {0, NULL}, +}; + +const value_string fc_ct_gsserver_vals[] = { + {FCCT_GSRVR_DNS, "dNS"}, + {FCCT_GSRVR_IP, "IP"}, + {FCCT_GSRVR_FCS, "Fabric Config Server"}, + {FCCT_GSRVR_UNS, "Unzoned Name Server"}, + {FCCT_GSRVR_FZS, "Fabric Zone Server"}, + {FCCT_GSRVR_TS, "Time Server"}, + {FCCT_GSRVR_KS, "Key Server"}, + {FCCT_GSRVR_AS, "Alias Server"}, + {FCCT_GSRVR_FCTLR, "Fabric Controller"}, + {0, NULL}, +}; + +static dissector_table_t fcct_gserver_table; + +guint8 +get_gs_server (guint8 gstype, guint8 gssubtype) +{ + switch (gstype) { + case FCCT_GSTYPE_KEYSVC: + return FCCT_GSRVR_KS; + case FCCT_GSTYPE_ALIASSVC: + if (gssubtype == FCCT_GSSUBTYPE_AS) + return FCCT_GSRVR_AS; + return FCCT_GSRVR_UNKNOWN; + case FCCT_GSTYPE_MGMTSVC: + if (gssubtype == FCCT_GSSUBTYPE_FCS) + return FCCT_GSRVR_FCS; + else if (gssubtype == FCCT_GSSUBTYPE_UNS) + return FCCT_GSRVR_UNS; + else if (gssubtype == FCCT_GSSUBTYPE_FZS) + return FCCT_GSRVR_FZS; + else return FCCT_GSRVR_UNKNOWN; + case FCCT_GSTYPE_TIMESVC: + if (gssubtype == FCCT_GSSUBTYPE_TS) + return FCCT_GSRVR_TS; + return FCCT_GSRVR_UNKNOWN; + case FCCT_GSTYPE_DIRSVC: + if (gssubtype == FCCT_GSSUBTYPE_DNS) + return FCCT_GSRVR_DNS; + else if (gssubtype == FCCT_GSSUBTYPE_IP) + return FCCT_GSRVR_IP; + return FCCT_GSRVR_UNKNOWN; + case FCCT_GSRVR_FCTLR: + if (gssubtype == FCCT_GSSUBTYPE_FCTLR) + return (FCCT_GSRVR_FCTLR); + else return (FCCT_GSRVR_UNKNOWN); + default: + return FCCT_GSRVR_UNKNOWN; + } +} + +/* Code to actually dissect the packets */ +static int +dissect_fcct (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) +{ + +/* Set up structures needed to add the protocol subtree and manage it */ + proto_item *ti; + proto_tree *fcct_tree; + tvbuff_t *next_tvb; + int in_id, + offset = 0; + guint8 server; + fc_ct_preamble cthdr; + address addr; + + /* Make entries in Protocol column and Info column on summary display */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "FC_CT"); + + /* + cthdr.revision = tvb_get_guint8 (tvb, offset++); + cthdr.in_id = tvb_get_ntoh24 (tvb, offset); + offset += 3; + + cthdr.gstype = tvb_get_guint8 (tvb, offset++); + cthdr.options = tvb_get_guint8 (tvb, offset++); + */ + tvb_memcpy (tvb, (guint8 *)&cthdr, offset, FCCT_PRMBL_SIZE); + cthdr.revision = tvb_get_guint8 (tvb, offset++); + cthdr.in_id = tvb_get_ntoh24 (tvb, offset); + cthdr.opcode = g_ntohs (cthdr.opcode); + cthdr.maxres_size = g_ntohs (cthdr.maxres_size); + + if (cthdr.opcode < FCCT_MSG_REQ_MAX) { + col_append_str (pinfo->cinfo, COL_INFO, " Request"); + } + else if (cthdr.opcode == FCCT_MSG_ACC) { + col_append_str (pinfo->cinfo, COL_INFO, " Accept"); + } + else if (cthdr.opcode == FCCT_MSG_RJT) { + col_append_fstr (pinfo->cinfo, COL_INFO, " Reject (%s)", + val_to_str (cthdr.rjt_code, fc_ct_rjt_code_vals, "0x%x")); + } + else { + col_append_str (pinfo->cinfo, COL_INFO, " Reserved"); + } + + in_id = cthdr.in_id; + in_id = g_htonl (in_id) >> 8; + + /* Determine server */ + server = get_gs_server (cthdr.gstype, cthdr.gssubtype); + + if (tree) { + offset = 0; + ti = proto_tree_add_protocol_format (tree, proto_fcct, tvb, 0, FCCT_PRMBL_SIZE, + "FC_CT"); + fcct_tree = proto_item_add_subtree (ti, ett_fcct); + + proto_tree_add_item (fcct_tree, hf_fcct_revision, tvb, offset++, + sizeof (guint8), ENC_BIG_ENDIAN); + set_address(&addr, AT_FC, 3, &in_id); + proto_tree_add_string (fcct_tree, hf_fcct_inid, tvb, offset, 3, + address_to_str(pinfo->pool, &addr)); + offset += 3; /* sizeof FC address */ + + proto_tree_add_item (fcct_tree, hf_fcct_gstype, tvb, offset++, + sizeof (guint8), ENC_BIG_ENDIAN); + proto_tree_add_item (fcct_tree, hf_fcct_gssubtype, tvb, offset, + sizeof (guint8), ENC_BIG_ENDIAN); + proto_tree_add_uint (fcct_tree, hf_fcct_server, tvb, offset++, 1, + server); + proto_tree_add_item (fcct_tree, hf_fcct_options, tvb, offset++, + sizeof (guint8), ENC_BIG_ENDIAN); + + } + /* We do not change the starting offset for the next protocol in the + * chain since the fc_ct header is common to the sub-protocols. + * Pass the fchdr* received from parent dissector through to sub-protocols + */ + next_tvb = tvb_new_subset_remaining (tvb, 0); + if (!dissector_try_uint_new(fcct_gserver_table, server, next_tvb, pinfo, + tree, TRUE, data)) { + call_data_dissector(next_tvb, pinfo, tree); + } + + return tvb_captured_length(tvb); +} + +/* Register the protocol with Wireshark */ + +void +proto_register_fcct(void) +{ + +/* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_fcct_revision, + {"Revision", "fcct.revision", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + { &hf_fcct_inid, + {"IN_ID", "fcct.in_id", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + { &hf_fcct_gstype, + {"GS Type", "fcct.gstype", FT_UINT8, BASE_HEX, VALS(fc_ct_gstype_vals), + 0x0, NULL, HFILL}}, + { &hf_fcct_gssubtype, + {"GS Subtype", "fcct.gssubtype", FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL}}, + { &hf_fcct_server, + {"Server", "fcct.server", FT_UINT8, BASE_HEX, + VALS (fc_ct_gsserver_vals), 0x0, + "Derived from GS Type & Subtype fields", HFILL}}, + { &hf_fcct_options, + {"Options", "fcct.options", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, + HFILL}}, +#if 0 + { &hf_fcct_ext_said, + {"Auth SAID", "fcct.ext_said", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, + HFILL}}, + { &hf_fcct_ext_tid, + {"Transaction ID", "fcct.ext_tid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, + HFILL}}, + { &hf_fcct_ext_reqname, + {"Requestor Port Name", "fcct.ext_reqnm", FT_BYTES, BASE_NONE, NULL, + 0x0, NULL, HFILL}}, + { &hf_fcct_ext_tstamp, + {"Timestamp", "fcct.ext_tstamp", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, + HFILL}}, + { &hf_fcct_ext_authblk, + {"Auth Hash Blk", "fcct.ext_authblk", FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL}}, +#endif + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_fcct, + &ett_fcct_ext, + }; + + /* Register the protocol name and description */ + proto_fcct = proto_register_protocol("Fibre Channel Common Transport", "FC_CT", "fcct"); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_fcct, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + fcct_gserver_table = register_dissector_table ("fcct.server", + "FCCT Server", + proto_fcct, FT_UINT8, BASE_HEX); + + fcct_handle = register_dissector("fcct", dissect_fcct, proto_fcct); +} + +void +proto_reg_handoff_fcct (void) +{ + dissector_add_uint("fc.ftype", FC_FTYPE_FCCT, fcct_handle); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |