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-fortinet-fgcp.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-fortinet-fgcp.c')
-rw-r--r-- | epan/dissectors/packet-fortinet-fgcp.c | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/epan/dissectors/packet-fortinet-fgcp.c b/epan/dissectors/packet-fortinet-fgcp.c new file mode 100644 index 00000000..0992fa76 --- /dev/null +++ b/epan/dissectors/packet-fortinet-fgcp.c @@ -0,0 +1,408 @@ +/* packet-fortinet-fgcp.c + * Routines for FortiGate Cluster Protocol dissection + * Copyright 2023, Alexis La Goutte <alexis.lagoutte at gmail dot com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * No spec/doc is available based on reverse/analysis of protocol... + * + */ + +#include "config.h" + +#include <wireshark.h> + +#include <epan/packet.h> +#include <epan/expert.h> +#include <epan/prefs.h> +#include <epan/etypes.h> + +void proto_reg_handoff_fortinet_fgcp(void); +void proto_register_fortinet_fgcp(void); + +static int proto_fortinet_fgcp_hb = -1; +static int hf_fortinet_fgcp_hb_magic = -1; +static int hf_fortinet_fgcp_hb_flag = -1; +static int hf_fortinet_fgcp_hb_flag_b74 = -1; +static int hf_fortinet_fgcp_hb_flag_b3 = -1; +static int hf_fortinet_fgcp_hb_flag_b2 = -1; +static int hf_fortinet_fgcp_hb_flag_authentication = -1; +static int hf_fortinet_fgcp_hb_flag_encryption = -1; +static int hf_fortinet_fgcp_hb_mode = -1; +static int hf_fortinet_fgcp_hb_gn = -1; +static int hf_fortinet_fgcp_hb_group_id = -1; +static int hf_fortinet_fgcp_hb_port = -1; +static int hf_fortinet_fgcp_hb_revision = -1; +static int hf_fortinet_fgcp_hb_sn = -1; +static int hf_fortinet_fgcp_hb_payload_encrypted = -1; +static int hf_fortinet_fgcp_hb_authentication = -1; + +static int hf_fortinet_fgcp_hb_tlv = -1; +static int hf_fortinet_fgcp_hb_tlv_type = -1; +static int hf_fortinet_fgcp_hb_tlv_length = -1; +static int hf_fortinet_fgcp_hb_tlv_value = -1; +static int hf_fortinet_fgcp_hb_tlv_vcluster_id = -1; +static int hf_fortinet_fgcp_hb_tlv_priority = -1; +static int hf_fortinet_fgcp_hb_tlv_override = -1; + +//static int hf_fortinet_fgcp_hb_unknown = -1; +static int hf_fortinet_fgcp_hb_unknown_uint16 = -1; + +static dissector_handle_t fortinet_fgcp_hb_handle; + +static gint ett_fortinet_fgcp_hb = -1; +static gint ett_fortinet_fgcp_hb_flag = -1; +static gint ett_fortinet_fgcp_hb_tlv = -1; + +static const value_string fortinet_fgcp_hb_mode_vals[] = { + { 0x1, "A/A (Active/Active)"}, + { 0x2, "A/P (Active/Passive)"}, + {0, NULL } +}; + +#define HB_TLV_END_OF_TLV 0x00 +#define HB_TLV_VCLUSTER_ID 0x0B +#define HB_TLV_PRIORITY 0x0C +#define HB_TLV_OVERRIDE 0x0D + +static const value_string fortinet_fgcp_hb_tlv_vals[] = { + { HB_TLV_END_OF_TLV, "End of TLV" }, + { HB_TLV_PRIORITY, "Port Priority" }, + { HB_TLV_OVERRIDE, "Override" }, + { 0, NULL } +}; + + +static int +dissect_fortinet_fgcp_hb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data _U_) +{ + proto_item *ti; + proto_tree *fortinet_hb_tree; + guint offset = 0, length, auth_len=0; + guint8 flags; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "FGCP-HB"); + + col_add_fstr(pinfo->cinfo, COL_INFO, "Cluster: %s(%u) - monitor: %s - SN: %s", + tvb_get_string_enc(pinfo->pool, tvb, offset+4, 32, ENC_ASCII), /* Group Name*/ + tvb_get_guint16(tvb, (offset+4+32+2), ENC_LITTLE_ENDIAN), /* Group ID*/ + tvb_get_string_enc(pinfo->pool, tvb, offset+4+32+2+14, 16, ENC_ASCII), /* Port */ + tvb_get_string_enc(pinfo->pool, tvb, offset+4+32+2+14+16+2+2, 16, ENC_ASCII) /* Serial Number */); + + ti = proto_tree_add_item(tree, proto_fortinet_fgcp_hb, tvb, 0, -1, ENC_NA); + + fortinet_hb_tree = proto_item_add_subtree(ti, ett_fortinet_fgcp_hb); + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_magic, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_mode, tvb, offset, 1, ENC_NA); + offset += 1; + + static int * const fortinet_fgcp_hb_flag[] = { + &hf_fortinet_fgcp_hb_flag_b74, + &hf_fortinet_fgcp_hb_flag_b3, + &hf_fortinet_fgcp_hb_flag_b2, + &hf_fortinet_fgcp_hb_flag_authentication, + &hf_fortinet_fgcp_hb_flag_encryption, + NULL + }; + + proto_tree_add_bitmask(fortinet_hb_tree, tvb, offset, hf_fortinet_fgcp_hb_flag, ett_fortinet_fgcp_hb_flag, + fortinet_fgcp_hb_flag, ENC_NA); + flags = tvb_get_guint8(tvb, offset); + offset += 1; + + /* Group Name */ + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_gn, tvb, offset, 32, ENC_ASCII); + offset += 32; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + /* Group Id */ + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_group_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + /* Heartbeat Port */ + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_port, tvb, offset, 16, ENC_ASCII); + offset += 16; + + /* Revision ? */ + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_revision, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + /* Hash/crc ? change after each revision*/ + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_NA); + offset += 2; + + /* Serial Number */ + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_sn, tvb, offset, 16, ENC_ASCII); + offset += 16; + + if (flags & 0x02) { /* Authentication ? */ + /* the payload finish with 32bits of authentication (hash ?) */ + auth_len = 32; + } + + if (flags & 0x01) { /* Encrypted Payload ?*/ + length = tvb_reported_length_remaining(tvb, offset) - auth_len; + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_payload_encrypted, tvb, offset, length, ENC_NA); + offset += length; + } else { + guint next_offset; + + length = tvb_reported_length_remaining(tvb, offset) - auth_len; + next_offset = offset + length; + + while (offset < next_offset) { + guint32 type, len; + proto_item *ti_tlv; + proto_tree *tlv_tree; + + ti_tlv = proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_tlv, tvb, offset, 3, ENC_NA); + tlv_tree = proto_item_add_subtree(ti_tlv, ett_fortinet_fgcp_hb_tlv); + proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, &type); + offset += 2; + proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &len); + offset += 2; + + proto_item_append_text(ti_tlv, ": (t=%u,l=%d) %s", type, len, val_to_str_const(type, fortinet_fgcp_hb_tlv_vals ,"Unknown type") ); + proto_item_set_len(ti_tlv, 2 + 2 + len); + + proto_tree_add_item(tlv_tree, hf_fortinet_fgcp_hb_tlv_value, tvb, offset, len, ENC_NA); + switch (type) { + case HB_TLV_VCLUSTER_ID:{ + guint32 vcluster_id; + proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_vcluster_id, tvb, offset, 1, ENC_NA, &vcluster_id); + proto_item_append_text(ti_tlv, ": %u", vcluster_id); + offset += 1; + } + break; + case HB_TLV_PRIORITY:{ + guint32 priority; + proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_priority, tvb, offset, 1, ENC_NA, &priority); + proto_item_append_text(ti_tlv, ": %u", priority); + offset += 1; + } + break; + case HB_TLV_OVERRIDE:{ + guint32 override; + proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_override, tvb, offset, 1, ENC_NA, &override); + if (override){ + proto_item_append_text(ti_tlv, ": True"); + } else { + proto_item_append_text(ti_tlv, ": False"); + } + offset += 1; + } + break; + default: + offset += len; + break; + } + } + } + + if (auth_len) { /* Authentication ? */ + proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_authentication, tvb, offset, 32, ENC_NA); + offset += 32; + } + + return offset; +} + +void +proto_register_fortinet_fgcp(void) +{ + + static hf_register_info hf[] = { + /* HeartBeat */ + { &hf_fortinet_fgcp_hb_magic, + { "Magic Number", "fortinet_fgcp.hb.magic", + FT_UINT16, BASE_HEX_DEC, NULL, 0x0, + "Magic Number ?", HFILL } + }, + { &hf_fortinet_fgcp_hb_flag, + { "Flag", "fortinet_fgcp.hb.flag", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_flag_b74, + { "Bit 7 to 4", "fortinet_fgcp.hb.flag.b74", + FT_UINT8, BASE_HEX, NULL, 0xF0, + "Unknown", HFILL } + }, + { &hf_fortinet_fgcp_hb_flag_b3, + { "Bit b3", "fortinet_fgcp.hb.flag.b3", + FT_UINT8, BASE_HEX, NULL, 0x08, + "Unknown", HFILL } + }, + { &hf_fortinet_fgcp_hb_flag_b2, + { "Bit b2", "fortinet_fgcp.hb.flag.b2", + FT_UINT8, BASE_HEX, NULL, 0x04, + "Unknown", HFILL } + }, + { &hf_fortinet_fgcp_hb_flag_authentication, + { "Authentication", "fortinet_fgcp.hb.flag.authentication", + FT_BOOLEAN, 8, NULL, 0x02, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_flag_encryption, + { "Encryption", "fortinet_fgcp.hb.flag.encryption", + FT_BOOLEAN, 8, NULL, 0x01, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_mode, + { "Mode", "fortinet_fgcp.hb.mode", + FT_UINT8, BASE_DEC, VALS(fortinet_fgcp_hb_mode_vals), 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_gn, + { "Group Name", "fortinet_fgcp.hb.gn", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_group_id, + { "Group Id", "fortinet_fgcp.hb.group_id", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_port, + { "Port", "fortinet_fgcp.hb.port", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_revision, + { "Revision", "fortinet_fgcp.hb.revision", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Number of revision config for HA", HFILL } + }, + { &hf_fortinet_fgcp_hb_sn, + { "Serial Number", "fortinet_fgcp.hb.sn", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_payload_encrypted, + { "Payload (encrypted)", "fortinet_fgcp.hb.payload_encrypted", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_authentication, + { "Authentication", "fortinet_fgcp.hb.authentication", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + { &hf_fortinet_fgcp_hb_tlv, + { "TLV", "fortinet_fgcp.hb.tlv", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_tlv_type, + { "Type", "fortinet_fgcp.hb.tlv.type", + FT_UINT16, BASE_HEX, VALS(fortinet_fgcp_hb_tlv_vals), 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_tlv_length, + { "Length", "fortinet_fgcp.hb.tlv.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_tlv_value, + { "Value", "fortinet_fgcp.hb.tlv.value", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + { &hf_fortinet_fgcp_hb_tlv_vcluster_id, + { "Vcluster ID", "fortinet_fgcp.hb.tlv.vcluster_id", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_tlv_priority, + { "Port Priority", "fortinet_fgcp.hb.tlv.priority", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fortinet_fgcp_hb_tlv_override, + { "Override", "fortinet_fgcp.hb.tlv.override", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + /* + { &hf_fortinet_fgcp_hb_unknown, + { "Unknown", "fortinet_fgcp.hb.unknown", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Always NULL ?", HFILL } + }, + */ + { &hf_fortinet_fgcp_hb_unknown_uint16, + { "Unknown", "fortinet_fgcp.hb.unknown.uint16", + FT_UINT16, BASE_DEC_HEX, NULL, 0x0, + NULL, HFILL } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_fortinet_fgcp_hb, + &ett_fortinet_fgcp_hb_flag, + &ett_fortinet_fgcp_hb_tlv + }; + + /* Register the protocol name and description */ + proto_fortinet_fgcp_hb = proto_register_protocol("FortiGate Cluster Protocol - HeartBeat", + "fortinet_fgcp_hb", "fortinet_fgcp_hb"); + + /* Required function calls to register the header fields and subtrees */ + proto_register_field_array(proto_fortinet_fgcp_hb, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + fortinet_fgcp_hb_handle = register_dissector("fortinet_fgcp_hb", dissect_fortinet_fgcp_hb, + proto_fortinet_fgcp_hb); + +} + + +void +proto_reg_handoff_fortinet_fgcp(void) +{ + dissector_add_uint("ethertype", ETHERTYPE_FORTINET_FGCP_HB, fortinet_fgcp_hb_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: + */ |