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-corosync-totemsrp.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-corosync-totemsrp.c')
-rw-r--r-- | epan/dissectors/packet-corosync-totemsrp.c | 1174 |
1 files changed, 1174 insertions, 0 deletions
diff --git a/epan/dissectors/packet-corosync-totemsrp.c b/epan/dissectors/packet-corosync-totemsrp.c new file mode 100644 index 0000000..6f0feaf --- /dev/null +++ b/epan/dissectors/packet-corosync-totemsrp.c @@ -0,0 +1,1174 @@ +/* packet-corosync-totemsrp.c + * Dissectors for totem single ring protocol implemented in corosync cluster engine + * Copyright 2007 2009 2010 2014 Masatake YAMATO <yamato@redhat.com> + * Copyright (c) 2010 2014 Red Hat, Inc. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* Fields description are taken from + + Y.AMIR, L.E.MOSER, P.M.MELLIAR-SMITH, D.A.AGARWAL, P.CIARFELLA. + "The Totem Single-Ring Ordering and Membership Protocol"*/ + +/* + * NOTE: the source code at www.corosync.org looks as if it will not + * work with multiple OSes in a cluster if it uses IPv6, as it appears + * to use the OS's AF_ values in packets, and the value of AF_INET6 + * is ***NOT*** the same in all OSes. + * + * (It'll work with IPv4, because AF_INET came out of 4.2BSD and + * most if not all OSes just picked up BSD's value of 2.) + * + * So we just check for all the AF_INET6 values we know about. + * + * We get the AF_ values from epan/aftypes.h, *not* from the OS + * we happen to be built for. + */ + +# include "config.h" + +#include <epan/packet.h> +#include <epan/aftypes.h> + +/* + * Utilities for subdissectors of corosync_totemsrp. + */ +struct corosync_totemsrp_info { + guint encoding; + guint nodeid; +}; + +/* Forward declaration we need below */ +void proto_register_corosync_totemsrp(void); +void proto_reg_handoff_corosync_totemsrp(void); + +/* Initialize the protocol and registered fields */ +static int proto_corosync_totemsrp = -1; + +static heur_dissector_list_t heur_subdissector_list; + +/* fields for struct message_header */ +static int hf_corosync_totemsrp_message_header_type = -1; +static int hf_corosync_totemsrp_message_header_encapsulated = -1; +static int hf_corosync_totemsrp_message_header_endian_detector = -1; +static int hf_corosync_totemsrp_message_header_nodeid = -1; + +/* fields for struct orf_token */ +static int hf_corosync_totemsrp_orf_token = -1; +static int hf_corosync_totemsrp_orf_token_seq = -1; +static int hf_corosync_totemsrp_orf_token_token_seq = -1; +static int hf_corosync_totemsrp_orf_token_aru = -1; +static int hf_corosync_totemsrp_orf_token_aru_addr = -1; +static int hf_corosync_totemsrp_orf_token_backlog = -1; +static int hf_corosync_totemsrp_orf_token_fcc = -1; +static int hf_corosync_totemsrp_orf_token_retrnas_flg = -1; +static int hf_corosync_totemsrp_orf_token_rtr_list_entries = -1; + +/* field for struct memb_ring_id */ +static int hf_corosync_totemsrp_memb_ring_id = -1; +static int hf_corosync_totemsrp_memb_ring_id_seq = -1; + +/* field for struct totem_ip_address */ +static int hf_corosync_totemsrp_ip_address = -1; +static int hf_corosync_totemsrp_ip_address_nodeid = -1; +static int hf_corosync_totemsrp_ip_address_family = -1; +static int hf_corosync_totemsrp_ip_address_addr = -1; +static int hf_corosync_totemsrp_ip_address_addr4 = -1; +static int hf_corosync_totemsrp_ip_address_addr4_padding = -1; +static int hf_corosync_totemsrp_ip_address_addr6 = -1; + +/* field of struct mcast */ +static int hf_corosync_totemsrp_mcast = -1; +static int hf_corosync_totemsrp_mcast_seq = -1; +static int hf_corosync_totemsrp_mcast_this_seqno = -1; +static int hf_corosync_totemsrp_mcast_node_id = -1; +static int hf_corosync_totemsrp_mcast_system_from = -1; +static int hf_corosync_totemsrp_mcast_guarantee = -1; + +/* field of struct memb_merge_detect */ +static int hf_corosync_totemsrp_memb_merge_detect = -1; + +/* field of struct struct srp_addr */ +static int hf_corosync_totemsrp_srp_addr = -1; + +/* field of struct rtr_item */ +static int hf_corosync_totemsrp_rtr_item = -1; +static int hf_corosync_totemsrp_rtr_item_seq = -1; + +/* field of struct memb_join */ +static int hf_corosync_totemsrp_memb_join = -1; +static int hf_corosync_totemsrp_memb_join_proc_list_entries = -1; +static int hf_corosync_totemsrp_memb_join_failed_list_entries = -1; +static int hf_corosync_totemsrp_memb_join_ring_seq = -1; + +/* field of struct memb_commit_token */ +static int hf_corosync_totemsrp_memb_commit_token = -1; +static int hf_corosync_totemsrp_memb_commit_token_token_seq = -1; +static int hf_corosync_totemsrp_memb_commit_token_retrans_flg = -1; +static int hf_corosync_totemsrp_memb_commit_token_memb_index = -1; +static int hf_corosync_totemsrp_memb_commit_token_addr_entries = -1; + +/* field of struct memb_commit_token_memb_entry */ +static int hf_corosync_totemsrp_memb_commit_token_memb_entry = -1; +static int hf_corosync_totemsrp_memb_commit_token_memb_entry_aru = -1; +static int hf_corosync_totemsrp_memb_commit_token_memb_entry_high_delivered = -1; +static int hf_corosync_totemsrp_memb_commit_token_memb_entry_received_flg = -1; + +/* field of struct token_hold_cancel */ +static int hf_corosync_totemsrp_token_hold_cancel = -1; + +/* Initialize the subtree pointers */ +static gint ett_corosync_totemsrp = -1; +static gint ett_corosync_totemsrp_orf_token = -1; +static gint ett_corosync_totemsrp_memb_ring_id = -1; +static gint ett_corosync_totemsrp_ip_address = -1; +static gint ett_corosync_totemsrp_mcast = -1; +static gint ett_corosync_totemsrp_memb_merge_detect = -1; +static gint ett_corosync_totemsrp_srp_addr = -1; +static gint ett_corosync_totemsrp_rtr_item = -1; +static gint ett_corosync_totemsrp_memb_join = -1; +static gint ett_corosync_totemsrp_memb_commit_token = -1; +static gint ett_corosync_totemsrp_memb_commit_token_memb_entry = -1; +static gint ett_corosync_totemsrp_token_hold_cancel = -1; +static gint ett_corosync_totemsrp_memb_join_proc_list = -1; +static gint ett_corosync_totemsrp_memb_join_failed_list = -1; + + +/* + * Value strings + */ +#define COROSYNC_TOTEMSRP_MESSAGE_TYPE_ORF_TOKEN 0 +#define COROSYNC_TOTEMSRP_MESSAGE_TYPE_MCAST 1 +#define COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_MERGE_DETECT 2 +#define COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_JOIN 3 +#define COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_COMMIT_TOKEN 4 +#define COROSYNC_TOTEMSRP_MESSAGE_TYPE_TOKEN_HOLD_CANCEL 5 + +static const value_string corosync_totemsrp_message_header_type[] = { + { COROSYNC_TOTEMSRP_MESSAGE_TYPE_ORF_TOKEN, "orf" }, + { COROSYNC_TOTEMSRP_MESSAGE_TYPE_MCAST, "mcast" }, + { COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_MERGE_DETECT, "merge rings" }, + { COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_JOIN, "join message" }, + { COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_COMMIT_TOKEN, "commit token" }, + { COROSYNC_TOTEMSRP_MESSAGE_TYPE_TOKEN_HOLD_CANCEL, "cancel" }, + { 0, NULL } +}; + +#define COROSYNC_TOTEMSRP_MESSAGE_ENCAPSULATED 1 +#define COROSYNC_TOTEMSRP_MESSAGE_NOT_ENCAPSULATED 2 + +static const value_string corosync_totemsrp_message_header_encapsulated[] = { + { 0, "not mcast message" }, + { COROSYNC_TOTEMSRP_MESSAGE_ENCAPSULATED, "encapsulated" }, + { COROSYNC_TOTEMSRP_MESSAGE_NOT_ENCAPSULATED, "not encapsulated" }, + { 0, NULL } +}; + + +static const value_string corosync_totemsrp_ip_address_family[] = { + { COMMON_AF_INET, "AF_INET" }, + { BSD_AF_INET6_BSD, "AF_INET6 (most BSD)" }, + { BSD_AF_INET6_FREEBSD, "AF_INET6 (FreeBSD)" }, + { BSD_AF_INET6_DARWIN, "AF_INET6 (macOS and iOS)" }, + { LINUX_AF_INET6, "AF_INET6 (Linux)" }, + { SOLARIS_AF_INET6, "AF_INET6 (Solaris)" }, + { WINSOCK_AF_INET6, "AF_INET6 (Windows)" }, + { 0, NULL } +}; + +static guint16 +corosync_totemsrp_get_guint16(tvbuff_t* tvb, gint offset, const guint encoding) +{ + if (encoding == ENC_LITTLE_ENDIAN) + return tvb_get_letohs(tvb, offset); + + return tvb_get_ntohs(tvb, offset); +} + + +static guint32 +corosync_totemsrp_get_guint32(tvbuff_t* tvb, gint offset, const guint encoding) +{ + if (encoding == ENC_LITTLE_ENDIAN) + return tvb_get_letohl(tvb, offset); + + return tvb_get_ntohl(tvb, offset); +} + +static guint64 +corosync_totemsrp_get_guint64(tvbuff_t* tvb, gint offset, const guint encoding) +{ + if (encoding == ENC_LITTLE_ENDIAN) + return tvb_get_letoh64(tvb, offset); + + return tvb_get_ntoh64(tvb, offset); +} + + +#define COROSYNC_TOTEMSRP_SRP_ADDR_INTERFACE_MAX 2 + +static int dissect_corosync_totemsrp0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, + gboolean encapsulated); + + +static int +dissect_corosync_totemsrp_ip_address(tvbuff_t *tvb, + packet_info *pinfo _U_, + proto_tree *parent_tree, + guint length _U_, int offset, + const guint encoding, + gboolean print_interface, + guint interface, + guint *nodeid) +{ + guint16 family; + guint nid; + int original_offset = offset; + proto_tree *tree; + proto_item *item; + gint len; + + nid = corosync_totemsrp_get_guint32(tvb, offset, encoding); + if (nodeid) + *nodeid = nid; + family = corosync_totemsrp_get_guint16(tvb, offset + 4, encoding); + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_ip_address, tvb, offset, + -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_ip_address); + + proto_item_append_text(item, " ("); + if (print_interface) + proto_item_append_text(item, "interface: %u; ", interface); + + proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_nodeid, + tvb, offset, 4, encoding); + proto_item_append_text(item, "node: %u)", nid); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_family, + tvb, offset, 2, encoding); + offset += 2; + + switch (family) + { + case COMMON_AF_INET: + len = 4; + proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_addr4, tvb, offset, len, ENC_BIG_ENDIAN); + break; + case BSD_AF_INET6_BSD: + case BSD_AF_INET6_FREEBSD: + case BSD_AF_INET6_DARWIN: + case LINUX_AF_INET6: + case SOLARIS_AF_INET6: + case WINSOCK_AF_INET6: + len = sizeof(ws_in6_addr); + proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_addr6, tvb, offset, len, ENC_NA); + break; + default: + len = sizeof(ws_in6_addr); + proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_addr, tvb, offset, len, ENC_NA); + break; + } + + offset += len; + + if (len != sizeof(ws_in6_addr)) { + gint padding_len; + + padding_len = (gint)(sizeof(ws_in6_addr) - len); + proto_tree_add_item (tree, hf_corosync_totemsrp_ip_address_addr4_padding, + tvb, offset, padding_len, ENC_NA); + offset += padding_len; + } + + proto_item_set_len(item, offset - original_offset); + return offset - original_offset; +} + +static int +dissect_corosync_totemsrp_memb_ring_id(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + const guint encoding, + guint *node_id, + guint64 *ring_id) +{ + int original_offset = offset; + proto_tree *tree; + proto_item *item; + guint64 rid; + guint nid; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_ring_id, tvb, offset, + -1, encoding); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_ring_id); + + offset += dissect_corosync_totemsrp_ip_address(tvb, pinfo, tree, + length, offset, + encoding, + FALSE, -1, + &nid); + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_ring_id_seq, + tvb, offset, 8, encoding); + rid = corosync_totemsrp_get_guint64(tvb, offset, encoding); + offset += 8; + + proto_item_append_text(item, " (ring: %" PRIu64 ")", rid); + + if (node_id) + *node_id = nid; + if (ring_id) + *ring_id = rid; + + proto_item_set_len(item, offset - original_offset); + return offset - original_offset; +} + +static int +dissect_corosync_totemsrp_rtr_list(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + const guint encoding) +{ + int original_offset = offset; + proto_tree *tree; + proto_item *item; + + guint node_id; + guint64 ring_id; + guint32 seq; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_rtr_item, tvb, offset, + -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_rtr_item); + + offset += dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + encoding, + &node_id, + &ring_id); + + proto_tree_add_item(tree, hf_corosync_totemsrp_rtr_item_seq, + tvb, offset, 4, encoding); + + seq = corosync_totemsrp_get_guint32(tvb, offset, encoding); + proto_item_append_text(item, " (ring: %" PRIu64 " node: %u seq: %u)", + ring_id, node_id, seq); + offset += 4; + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp_orf_token(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + const guint encoding) +{ + int original_offset = offset; + guint32 rtr_list_entries = 0, seq, aru, i; + proto_tree *tree; + proto_item *item; + guint node_id; + guint64 ring_id; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_orf_token, + tvb, offset, -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_orf_token); + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_seq, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_token_seq, + tvb, offset, 4, encoding); + seq = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_aru, + tvb, offset, 4, encoding); + aru = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_aru_addr, + tvb, offset, 4, encoding); + offset += 4; + + offset += dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + encoding, + &node_id, + &ring_id); + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_backlog, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_fcc, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_retrnas_flg, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_orf_token_rtr_list_entries, + tvb, offset, 4, encoding); + rtr_list_entries = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + for (i = 0; i < rtr_list_entries; i++) { + offset += dissect_corosync_totemsrp_rtr_list(tvb, pinfo, + tree, + length, offset, + encoding); + } + + proto_item_append_text(item, " (ring: %" PRIu64 " node: %u nrtr: %d seq: %d au: %u)", + ring_id, node_id, rtr_list_entries, seq, aru); + + proto_item_set_len(item, offset - original_offset); + return offset - original_offset; +} + +static int +dissect_corosync_totemsrp_srp_addr(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + int hf, + const guint encoding) +{ + int original_offset = offset; + proto_tree *tree; + proto_item *item; + guint nodeid; + + item = proto_tree_add_item(parent_tree, hf? hf: hf_corosync_totemsrp_srp_addr, tvb, offset, + -1, encoding); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_srp_addr); + + offset += dissect_corosync_totemsrp_ip_address(tvb, pinfo, tree, + length, offset, + encoding, + TRUE, 0, + &nodeid); + proto_item_append_text(item, " (node: %u)", nodeid); + + offset += dissect_corosync_totemsrp_ip_address(tvb, pinfo, tree, + length, offset, + encoding, + TRUE, 1, + NULL); + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp_mcast(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *tree, + guint length, int offset, + guint8 message_header__encapsulated, + const guint encoding, proto_tree *parent_tree, + struct corosync_totemsrp_info *totemsrp_info) +{ + int original_offset = offset; + proto_tree *mcast_tree; + + proto_item *item; + guint node_id; + guint64 ring_id; + tvbuff_t *next_tvb; + + heur_dtbl_entry_t *hdtbl_entry = NULL; + + item = proto_tree_add_item(tree, hf_corosync_totemsrp_mcast, tvb, offset, + -1, encoding); + mcast_tree = proto_item_add_subtree(item, ett_corosync_totemsrp_mcast); + + offset += dissect_corosync_totemsrp_srp_addr(tvb, pinfo, mcast_tree, + length, offset, + hf_corosync_totemsrp_mcast_system_from, + encoding); + + proto_tree_add_item(mcast_tree, hf_corosync_totemsrp_mcast_seq, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(mcast_tree, hf_corosync_totemsrp_mcast_this_seqno, + tvb, offset, 4, encoding); + offset += 4; + + offset += dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, mcast_tree, + length, offset, + encoding, + &node_id, + &ring_id); + + proto_item_append_text(item, " (ring: %" PRIu64 " node: %u)", + ring_id, node_id); + + proto_tree_add_item(tree, hf_corosync_totemsrp_mcast_node_id, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_mcast_guarantee, + tvb, offset, 4, encoding); + offset += 4; + + next_tvb = tvb_new_subset_remaining(tvb, offset); + + if (message_header__encapsulated == COROSYNC_TOTEMSRP_MESSAGE_ENCAPSULATED) + { + offset += dissect_corosync_totemsrp0(next_tvb, pinfo, tree, TRUE); + } + else + { + if (dissector_try_heuristic(heur_subdissector_list, + next_tvb, + pinfo, + parent_tree, + &hdtbl_entry, + totemsrp_info)) + offset = length; + } + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + + +static int +dissect_corosync_totemsrp_memb_merge_detect(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + const guint encoding) +{ + int original_offset = offset; + proto_tree *tree; + proto_item *item; + guint node_id; + guint64 ring_id; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_merge_detect, tvb, offset, + -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_merge_detect); + + offset += dissect_corosync_totemsrp_srp_addr(tvb, pinfo, tree, + length, offset, + 0, + encoding); + + offset += dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + encoding, + &node_id, + &ring_id); + + proto_item_append_text(item, " (ring: %" PRIu64 " node: %u)", + ring_id, node_id); + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp_memb_join(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + const guint encoding) +{ + int original_offset = offset; + proto_tree *tree; + proto_item *item; + + guint32 proc_list_entries; + proto_tree *proc_tree; + + guint32 failed_list_entries; + proto_tree *failed_tree; + proto_item *failed_item; + + guint i; + + proto_item *proc_item; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_join, tvb, offset, + -1, encoding); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_join); + + + offset += dissect_corosync_totemsrp_srp_addr(tvb, pinfo, tree, + length, offset, + 0, + encoding); + + proc_item = proto_tree_add_item(tree, hf_corosync_totemsrp_memb_join_proc_list_entries, + tvb, offset, 4, encoding); + proc_list_entries = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + failed_item = proto_tree_add_item(tree, hf_corosync_totemsrp_memb_join_failed_list_entries, + tvb, offset, 4, encoding); + failed_list_entries = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_join_ring_seq, + tvb, offset, 8, encoding); + offset += 8; + + proc_tree = proto_item_add_subtree(proc_item, ett_corosync_totemsrp_memb_join_proc_list); + + proto_item_append_text(item, " (nprocs: %u nfailed: %u)", + proc_list_entries, failed_list_entries); + + for (i = 0; i < proc_list_entries; i++) { + offset += dissect_corosync_totemsrp_srp_addr(tvb, pinfo, proc_tree, + length, offset, + 0, + encoding); + } + + failed_tree = proto_item_add_subtree(failed_item, + ett_corosync_totemsrp_memb_join_failed_list); + + for (i = 0; i < failed_list_entries; i++) { + offset += dissect_corosync_totemsrp_srp_addr(tvb, pinfo, failed_tree, + length, offset, + 0, + encoding); + } + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp_memb_commit_token_memb_entry(tvbuff_t *tvb, + packet_info *pinfo, + proto_tree *parent_tree, + guint length, int offset, + const guint encoding, + guint *node_id, + guint64 *ring_id) +{ + int original_offset = offset; + + proto_tree *tree; + proto_item *item; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_commit_token_memb_entry, + tvb, offset, -1, encoding); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_commit_token_memb_entry); + + + offset += dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + encoding, + node_id, + ring_id); + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_commit_token_memb_entry_aru, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_commit_token_memb_entry_high_delivered, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_commit_token_memb_entry_received_flg, + tvb, offset, 4, encoding); + offset += 4; + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp_memb_commit_token(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + const guint encoding) +{ + int original_offset = offset; + proto_tree *tree; + proto_item *item; + + guint32 i, addr_entries; + + guint32 seq; + guint node_id; + guint64 ring_id; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_commit_token, + tvb, offset, -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_commit_token); + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_commit_token_token_seq, + tvb, offset, 4, encoding); + seq = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + offset += dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + encoding, + &node_id, + &ring_id); + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_commit_token_retrans_flg, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_commit_token_memb_index, + tvb, offset, 4, encoding); + offset += 4; + + proto_tree_add_item(tree, hf_corosync_totemsrp_memb_commit_token_addr_entries, + tvb, offset, 4, encoding); + addr_entries = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + for (i = 0; i < addr_entries; i++) { + offset += dissect_corosync_totemsrp_srp_addr(tvb, pinfo, tree, + length, offset, + 0, + encoding); + } + + for (i = 0; i < addr_entries; i++) { + offset += dissect_corosync_totemsrp_memb_commit_token_memb_entry(tvb, pinfo, tree, + length, offset, + encoding, + NULL, + NULL); + } + + proto_item_append_text(item, " (ring: %" PRIu64 " node: %u seq: %u entries: %u)", + ring_id, node_id, seq, addr_entries); + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp_token_hold_cancel(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + const guint encoding) +{ + int original_offset = offset; + proto_tree *tree; + proto_item *item; + guint node_id; + guint64 ring_id; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_token_hold_cancel, tvb, offset, + -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_token_hold_cancel); + + offset += dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + encoding, + &node_id, + &ring_id); + + proto_item_append_text(item, " (ring: %" PRIu64 " node: %u)", + ring_id, node_id); + + proto_item_set_len(item, offset - original_offset); + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_) +{ + return dissect_corosync_totemsrp0(tvb, pinfo, parent_tree, FALSE); +} + +#define COROSYNC_TOTEMSRP_TEST_LITTLE_ENDIAN 0x22FF +#define COROSYNC_TOTEMSRP_TEST_BIG_ENDIAN 0xFF22 + +static int +dissect_corosync_totemsrp0(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *tree, + gboolean encapsulated) +{ + proto_item *item; + guint length; + int offset = 0; + guint16 endian_test; + proto_tree *corosync_tree; + + guint8 message_header__type; + guint8 message_header__encapsulated; + + guint encoding; + struct corosync_totemsrp_info info; + + /* Check that there's enough data */ + length = tvb_reported_length(tvb); + if (length < 1 + 1 + 2 + 4) + return 0; + + /* message header */ + message_header__type = tvb_get_guint8(tvb, 0); + if (message_header__type > 5) + return 0; + + message_header__encapsulated = tvb_get_guint8(tvb, 1); + + /* message_header -- byte order checking */ + endian_test = tvb_get_ntohs(tvb, 2); + if (endian_test == COROSYNC_TOTEMSRP_TEST_LITTLE_ENDIAN) + encoding = ENC_LITTLE_ENDIAN; + else if (endian_test == COROSYNC_TOTEMSRP_TEST_BIG_ENDIAN) + encoding = ENC_BIG_ENDIAN; + else + return 0; + + if (encapsulated == FALSE) + { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "COROSYNC/TOTEMSRP"); + col_set_str(pinfo->cinfo, COL_INFO, + ((message_header__type == COROSYNC_TOTEMSRP_MESSAGE_TYPE_MCAST) + && (message_header__encapsulated == COROSYNC_TOTEMSRP_MESSAGE_ENCAPSULATED))? + "ENCAPSULATED": + val_to_str_const(message_header__type, + corosync_totemsrp_message_header_type, + "Unknown")); + } + + item = proto_tree_add_item(tree, proto_corosync_totemsrp, tvb, offset, -1, ENC_NA); + corosync_tree = proto_item_add_subtree(item, ett_corosync_totemsrp); + + proto_tree_add_item(corosync_tree, hf_corosync_totemsrp_message_header_type, + tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(corosync_tree, hf_corosync_totemsrp_message_header_encapsulated, + tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(corosync_tree, hf_corosync_totemsrp_message_header_endian_detector, + tvb, offset, 2, encoding); + offset += 2; + + proto_tree_add_item(corosync_tree, + hf_corosync_totemsrp_message_header_nodeid, + tvb, offset, 4, encoding); + info.encoding = encoding; + info.nodeid = corosync_totemsrp_get_guint32(tvb, offset, encoding); + offset += 4; + + switch (message_header__type) { + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_ORF_TOKEN: + dissect_corosync_totemsrp_orf_token(tvb, pinfo, corosync_tree, length, offset, encoding); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MCAST: + dissect_corosync_totemsrp_mcast(tvb, pinfo, corosync_tree, length, offset, + message_header__encapsulated, + encoding, tree, &info); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_MERGE_DETECT: + dissect_corosync_totemsrp_memb_merge_detect(tvb, pinfo, corosync_tree, length, offset, + encoding); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_JOIN: + dissect_corosync_totemsrp_memb_join(tvb, pinfo, corosync_tree, length, offset, + encoding); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_COMMIT_TOKEN: + dissect_corosync_totemsrp_memb_commit_token(tvb, pinfo, corosync_tree, length, offset, + encoding); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_TOKEN_HOLD_CANCEL: + dissect_corosync_totemsrp_token_hold_cancel(tvb, pinfo, corosync_tree, length, offset, + encoding); + break; + default: + break; + } + + return length; +} + +void +proto_register_corosync_totemsrp(void) +{ + static hf_register_info hf[] = { + /* message_header */ + { &hf_corosync_totemsrp_message_header_type, + { "Type", "corosync_totemsrp.message_header.type", + FT_INT8, BASE_DEC, VALS(corosync_totemsrp_message_header_type), 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_message_header_encapsulated, + { "Encapsulated", "corosync_totemsrp.message_header.encapsulated", + FT_INT8, BASE_DEC, VALS(corosync_totemsrp_message_header_encapsulated), 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_message_header_endian_detector, + { "Endian detector", "corosync_totemsrp.message_header.endian_detector", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_message_header_nodeid, + { "Node ID", "corosync_totemsrp.message_header.nodeid", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + /* orf_token */ + { &hf_corosync_totemsrp_orf_token, + { "Ordering, Reliability, Flow (ORF) control Token", "corosync_totemsrp.orf_token", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_orf_token_seq, + { "Sequence number allowing recognition of redundant copies of the token", "corosync_totemsrp.orf_token.seq", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_orf_token_token_seq, + { "The largest sequence number", "corosync_totemsrp.orf_token.seq", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The largest sequence number of any message " + "that has been broadcast on the ring" + "[1]" , + HFILL }}, + { &hf_corosync_totemsrp_orf_token_aru, + { "Sequence number all received up to", "corosync_totemsrp.orf_token.aru", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_orf_token_aru_addr, + { "ID of node setting ARU", "corosync_totemsrp.orf_token.aru_addr", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_orf_token_backlog, + { "Backlog", "corosync_totemsrp.orf_token.backlog", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The sum of the number of new message waiting to be transmitted by each processor on the ring " + "at the time at which that processor forwarded the token during the previous rotation" + "[1]", + HFILL }}, + { &hf_corosync_totemsrp_orf_token_fcc, + { "FCC", + "corosync_totemsrp.orf_token.fcc", + FT_UINT32, BASE_DEC, NULL, 0x0, + "A count of the number of messages broadcast by all processors " + "during the previous rotation of the token" + "[1]", + HFILL }}, + { &hf_corosync_totemsrp_orf_token_retrnas_flg, + { "Retransmission flag", "corosync_totemsrp.orf_token.retrans_flg", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_orf_token_rtr_list_entries, + { "The number of retransmission list entries", "corosync_totemsrp.orf_token.rtr_list_entries", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + /* memb_ring_id */ + { &hf_corosync_totemsrp_memb_ring_id, + { "Member ring id", "corosync_totemsrp.memb_ring_id", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_memb_ring_id_seq, + { "Sequence in member ring id", "corosync_totemsrp.memb_ring_id.seq", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + /* totem_ip_address */ + { &hf_corosync_totemsrp_ip_address, + { "Node IP address", "corosync_totemsrp.ip_address", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_ip_address_nodeid, + { "Node ID", "corosync_totemsrp.ip_address.nodeid", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_ip_address_family, + { "Address family", "corosync_totemsrp.ip_address.family", + FT_UINT16, BASE_DEC, VALS(corosync_totemsrp_ip_address_family), 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_ip_address_addr, + { "Address", "corosync_totemsrp.ip_address.addr", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_ip_address_addr4, + { "Address", "corosync_totemsrp.ip_address.addr4", + FT_IPv4, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_ip_address_addr4_padding, + { "Address padding", "corosync_totemsrp.ip_address.addr4_padding", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_ip_address_addr6, + { "Address", "corosync_totemsrp.ip_address.addr6", + FT_IPv6, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + /* mcast */ + { &hf_corosync_totemsrp_mcast, + { "ring ordered multicast message", "corosync_totemsrp.mcast", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_mcast_seq, + {"Multicast sequence number", "corosync_totemsrp.mcast.seq", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_mcast_this_seqno, + {"This Sequence number", "corosync_totemsrp.mcast.this_seqno", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_mcast_node_id, + {"Node id(unused?)", "corosync_totemsrp.mcast.node_id", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_mcast_system_from, + {"System from address", "corosync_totemsrp.mcast.system_from", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_corosync_totemsrp_mcast_guarantee, + {"Guarantee", "corosync_totemsrp.mcast.guarantee", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + /* memb_merge_detect */ + { &hf_corosync_totemsrp_memb_merge_detect, + { "Merge rings if there are available rings", "corosync_totemsrp.memb_merge_detect", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + /* srp_addr */ + { &hf_corosync_totemsrp_srp_addr, + {"Single Ring Protocol Address", "corosync_totemsrp.srp_addr", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + /* rtr_item */ + { &hf_corosync_totemsrp_rtr_item, + {"Retransmission Item", "corosync_totemsrp.rtr_item", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_corosync_totemsrp_rtr_item_seq, + {"Sequence of Retransmission Item", "corosync_totemsrp.rtr_item.seq", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + /* memb_join */ + { &hf_corosync_totemsrp_memb_join, + {"Membership join message", "corosync_totemsrp.memb_join", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_join_proc_list_entries, + {"The number of processor list entries", "corosync_totemsrp.memb_join.proc_list_entries", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_join_failed_list_entries, + {"The number of failed list entries", "corosync_totemsrp.memb_join.failed_list_entries", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_join_ring_seq, + {"Ring sequence number", "corosync_totemsrp.memb_join.ring_seq", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + + /* memb_commit_token */ + { &hf_corosync_totemsrp_memb_commit_token, + {"Membership commit token", "corosync_totemsrp.memb_commit_token", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_commit_token_token_seq, + {"Token sequence", "corosync_totemsrp.memb_commit_token.token_seq", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_commit_token_retrans_flg, + {"Retransmission flag", "corosync_totemsrp.memb_commit_token.retrans_flg", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_commit_token_memb_index, + {"Member index", "corosync_totemsrp.memb_commit_token.memb_index", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_commit_token_addr_entries, + {"The number of address entries", "corosync_totemsrp.memb_commit_token.addr_entries", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + + /* memb_commit_token_memb_entry */ + { &hf_corosync_totemsrp_memb_commit_token_memb_entry, + { "Membership entry", "corosync_totemsrp.memb_commit_token_memb_entry", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_commit_token_memb_entry_aru, + {"Sequence number all received up to", "corosync_totemsrp.memb_commit_token_memb_entry.aru", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_commit_token_memb_entry_high_delivered, + {"High delivered", "corosync_totemsrp.memb_commit_token_memb_entry.high_delivered", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + { &hf_corosync_totemsrp_memb_commit_token_memb_entry_received_flg, + {"Received flag", "corosync_totemsrp.memb_commit_token_memb_entry.received_flg", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, + + /* token_hold_cancel */ + { &hf_corosync_totemsrp_token_hold_cancel, + {"Hold cancel token", "corosync_totemsrp.token_hold_cancel", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL}}, + }; + + static gint *ett[] = { + &ett_corosync_totemsrp, + &ett_corosync_totemsrp_orf_token, + &ett_corosync_totemsrp_memb_ring_id, + &ett_corosync_totemsrp_ip_address, + &ett_corosync_totemsrp_mcast, + &ett_corosync_totemsrp_memb_merge_detect, + &ett_corosync_totemsrp_srp_addr, + &ett_corosync_totemsrp_rtr_item, + &ett_corosync_totemsrp_memb_join, + &ett_corosync_totemsrp_memb_commit_token, + &ett_corosync_totemsrp_memb_commit_token_memb_entry, + &ett_corosync_totemsrp_token_hold_cancel, + &ett_corosync_totemsrp_memb_join_proc_list, + &ett_corosync_totemsrp_memb_join_failed_list + + }; + + proto_corosync_totemsrp = proto_register_protocol("Totem Single Ring Protocol implemented in Corosync Cluster Engine", + "COROSYNC/TOTEMSRP", "corosync_totemsrp"); + proto_register_field_array(proto_corosync_totemsrp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + heur_subdissector_list = register_heur_dissector_list("corosync_totemsrp.mcast", proto_corosync_totemsrp); + + register_dissector( "corosync_totemsrp", dissect_corosync_totemsrp, proto_corosync_totemsrp); +} + +void +proto_reg_handoff_corosync_totemsrp(void) +{ + /* Nothing to be done. + dissect_corosync_totemsrp is directly called from corosync_totemnet dissector. */ +} + + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 2 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=2 tabstop=8 expandtab: + * :indentSize=2:tabSize=8:noTabs=true: + */ |