wireshark/epan/dissectors/packet-corosync-totemsrp.c
Guy Harris 357cfd3b03 A bunch of "{Mac} OS X" -> "macOS" changes.
Avoid anachronisms, however; there was no "macOS 10.0" or even "OS X
10.0", for example.  It was "Mac OS X" until 10.8 (although 10.7 was
sometimes called "OS X" and sometimes called "Mac OS X"), and it was "OS
X" from 10.8 to 10.11.

Change-Id: Ie4a848997dcc6c45c2245c1fb84ec526032375c3
Reviewed-on: https://code.wireshark.org/review/20933
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2017-04-05 19:16:22 +00:00

1187 lines
46 KiB
C

/* 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
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* 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(struct e_in6_addr);
proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_addr6, tvb, offset, len, ENC_NA);
break;
default:
len = sizeof(struct e_in6_addr);
proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_addr, tvb, offset, len, ENC_NA);
break;
}
offset += len;
if (len != sizeof(struct e_in6_addr)) {
gint padding_len;
padding_len = (gint)(sizeof(struct e_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: %" G_GINT64_MODIFIER "u)", 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: %" G_GINT64_MODIFIER "u 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: %" G_GINT64_MODIFIER "u 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: %" G_GINT64_MODIFIER "u 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: %" G_GINT64_MODIFIER "u 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: %" G_GINT64_MODIFIER "u 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: %" G_GINT64_MODIFIER "u 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 - http://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:
*/