aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2014-03-18 08:17:28 -0400
committerEvan Huus <eapache@gmail.com>2014-06-19 18:23:09 +0000
commit53594f34e499d309c66f56b22f373bf502802620 (patch)
treeee4cc1e0f12ec8738ab70032c493b5ec5acfb1b4 /epan
parent0b245a4cf8a46110ef0803e091e11fd894e017b2 (diff)
Dissectors for totemnet and totemsrp protocols implemented in corosync cluster engine. Bug 3232.
From Masatake YAMATO changes in patch3 (Masatake YAMATO): * Fix a typo(s/Sequnce/Sequence/) * Use variable len instead of a number literal * Put _U_ marker to length parameter of dissect_corosync_totemsrp_ip_address * Use tvb_report_length instread of tvb_length changes in patch5 (Masatake YAMATO): * packet-corosync-totemsrp.c: Adapt to new dissector_try_heuristic interface + pass hdtbl_entry argument to dissector_try_heuristic. * packet-corosync-totemnet.c: Initialize corosync_totemnet_port to 5405 changes in patch6 (Masatake YAMATO): * packet-corosync-totemsrp.c: Use tvb_reported_length instead of tvb_length. * packet-corosync-totemsrp.c: Remove unnecessary trailing space in string literals. * packet-corosync-totemnet.c: Remove SVN Id tag in a comment. changes in patch8 (Masatake YAMATO): * packet-corosync-totemnet.c: Remove SVN Id tag in comment(again). * packet-corosync-totemsrp.c: Use val_to_str_const instead of val_to_str. changes in patch9 (Masatake YAMATO): * wsutil/sober128.[ch]: New files derived from packet-corosync-totemnet.c. Decryption code is moved here. * packet-corosync-totemnet.c: Remove all decryption code from this file. Change-Id: Id832d9c5ce1be1668c857c9bbf39e8a84c31880c Reviewed-on: https://code.wireshark.org/review/725 Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/CMakeLists.txt2
-rw-r--r--epan/dissectors/Makefile.common2
-rw-r--r--epan/dissectors/packet-corosync-totemnet.c525
-rw-r--r--epan/dissectors/packet-corosync-totemsrp.c1168
4 files changed, 1697 insertions, 0 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index e16f7c13c6..9dc27cacdd 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -474,6 +474,8 @@ set(DISSECTOR_SRC
dissectors/packet-collectd.c
dissectors/packet-componentstatus.c
dissectors/packet-cops.c
+ dissectors/packet-corosync-totemnet.c
+ dissectors/packet-corosync-totemsrp.c
dissectors/packet-cosine.c
dissectors/packet-cpfi.c
dissectors/packet-cpha.c
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index 96444eb246..712596598a 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -400,6 +400,8 @@ DISSECTOR_SRC = \
packet-collectd.c \
packet-componentstatus.c \
packet-cops.c \
+ packet-corosync-totemnet.c \
+ packet-corosync-totemsrp.c \
packet-cosine.c \
packet-cpfi.c \
packet-cpha.c \
diff --git a/epan/dissectors/packet-corosync-totemnet.c b/epan/dissectors/packet-corosync-totemnet.c
new file mode 100644
index 0000000000..29d75d3479
--- /dev/null
+++ b/epan/dissectors/packet-corosync-totemnet.c
@@ -0,0 +1,525 @@
+/* packet-corosync-totemnet.c
+ * Dissector routines for the lowest level(encryption/decryption) protocol used in Corosync cluster engine
+ * Copyright 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.
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <wsutil/sha1.h>
+#include <wsutil/sober128.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+static dissector_handle_t corosync_totemsrp_handle;
+
+/* This dissector deals packets defined in totemnet.c of corosync
+ cluster engine. In the totemnet.c the packet is encrypted and decrypted
+ with LibTomCrypt. This dissector tries decrypting the packet with
+ sober128 and sha1 functions in wireshark. */
+
+/*
+ * Dissector body
+ */
+
+#define PORT_COROSYNC_TOTEMNET 5405
+
+/* Forward declaration we need below */
+void proto_reg_handoff_corosync_totemnet(void);
+
+/* Initialize the protocol and registered fields */
+static int proto_corosync_totemnet = -1;
+
+/* field of struct security_header */
+static int hf_corosync_totemnet_security_header_hash_digest = -1;
+static int hf_corosync_totemnet_security_header_salt = -1;
+static int hf_corosync_totemnet_security_crypto_type = -1;
+static int hf_corosync_totemnet_security_crypto_key = -1;
+
+/* configurable parameters */
+static guint corosync_totemnet_port = PORT_COROSYNC_TOTEMNET;
+static gchar* corosync_totemnet_private_keys = NULL;
+static gchar** corosync_totemnet_private_keys_list = NULL;
+
+/* Initialize the subtree pointers */
+static gint ett_corosync_totemnet_security_header = -1;
+
+
+#define HMAC_HASH_SIZE 20
+#define SALT_SIZE 16
+
+#define TOTEM_CRYPTO_SOBER 0
+#define TOTEM_CRYPTO_NSS 1
+
+static const value_string corosync_totemnet_crypto_type[] = {
+ { TOTEM_CRYPTO_SOBER, "SOBER" },
+ { TOTEM_CRYPTO_NSS, "NSS" },
+ { 0, NULL }
+};
+
+
+static int
+dissect_corosync_totemnet_security_header(tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *parent_tree,
+ gboolean check_crypt_type,
+ const gchar* key)
+{
+ proto_item *item;
+ proto_tree *tree;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "COROSYNC/TOTEMNET");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ if (parent_tree)
+ {
+ item = proto_tree_add_item(parent_tree, proto_corosync_totemnet, tvb, 0,
+ -1, FALSE);
+ tree = proto_item_add_subtree(item, ett_corosync_totemnet_security_header);
+
+ proto_tree_add_item(tree,
+ hf_corosync_totemnet_security_header_hash_digest,
+ tvb, 0, HMAC_HASH_SIZE, FALSE);
+ proto_tree_add_item(tree,
+ hf_corosync_totemnet_security_header_salt,
+ tvb, HMAC_HASH_SIZE, SALT_SIZE, FALSE);
+
+ if (check_crypt_type)
+ {
+ int io_len = tvb_reported_length(tvb);
+ proto_item * key_item;
+
+ proto_tree_add_item(tree,
+ hf_corosync_totemnet_security_crypto_type,
+ tvb, io_len - 1, 1, FALSE);
+ key_item = proto_tree_add_string(tree,
+ hf_corosync_totemnet_security_crypto_key,
+ tvb, 0, 0, key);
+ PROTO_ITEM_SET_GENERATED(key_item);
+ }
+ }
+ return HMAC_HASH_SIZE + SALT_SIZE;
+}
+
+/* About totemnet.c of corosync cluster engine:
+ *
+ * dissect_corosynec_totemnet_with_decryption() is derived from
+ * totemnet.c in corosync which is licensed under 3-clause BSD license.
+ * However, to merge this dissector to wireshark official source tree,
+ * corosync developers permit EXPLICITLY to reuse totemnet.c in GPL.
+ *
+ http://permalink.gmane.org/gmane.linux.redhat.cluster/19087
+ ------------------------------------------------------------
+ Steven Dake | 4 Jan 2011 22:02
+ Re: [Openais] packet dissectors for totempg, cman, clvmd, rgmanager, cpg,
+
+On 12/14/2010 08:04 AM, Masatake YAMATO wrote:
+> Thank you for replying.
+>
+>> Masatake,
+>>
+>> Masatake YAMATO napsal(a):
+>>> I'd like to your advice more detail seriously.
+>>> I've been developing this code for three years.
+>>> I don't want to make this code garbage.
+>>>
+>>>> Masatake,
+>>>> I'm pretty sure that biggest problem of your code was that it was
+>>>> licensed under BSD (three clause, same as Corosync has)
+>>>> license. Wireshark is licensed under GPL and even I like BSD licenses
+>>>> much more, I would recommend you to try to relicense code under GPL
+>>>> and send them this code.
+>>>>
+>>>> Regards,
+>>>> Honza
+>>> I got the similar comment from wireshark developer.
+>>> Please, read the discussion:
+>>> https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3232
+>>>
+>>
+>> I've read that thread long time before I've sent previous mail, so
+>> thats reason why I think that Wireshark developers just feel MUCH more
+>> comfortable with GPL and thats reason why they just ignoring it.
+>
+> I see.
+>
+>>> In my understanding there is no legal problem in putting 3-clause BSD
+>>> code into GPL code. Acutally wireshark includes some 3-clause BSD
+>>> code:
+>>>
+nnn>>
+>> Actually there is really not. BSD to GPL works without problem, but
+>> many people just don't know it...
+>
+> ...it is too bad. I strongly believe FOSS developers should know the
+> intent behind of the both licenses.
+>
+>>> epan/dissectors/packet-radiotap-defs.h:
+>>> *//*-
+>>> * Copyright (c) 2003, 2004 David Young. All rights reserved.
+>>> *
+...
+>>> *
+>>> * Redistribution and use in source and binary forms, with or without
+>>> * modification, are permitted provided that the following conditions
+>>> * are met:
+>>> * 1. Redistributions of source code must retain the above copyright
+>>> * notice, this list of conditions and the following disclaimer.
+>>> * 2. Redistributions in binary form must reproduce the above copyright
+>>> * notice, this list of conditions and the following disclaimer in the
+>>> * documentation and/or other materials provided with the distribution.
+>>> * 3. The name of David Young may not be used to endorse or promote
+>>> * products derived from this software without specific prior
+>>> * written permission.
+>>> *
+>>> * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+>>> * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+>>> * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+>>> * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
+>>> * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+>>> * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+>>> * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+>>> * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+>>> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+>>> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+>>> * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+>>> * OF SUCH DAMAGE.
+>>> *//*
+>>> I'd like to separate the legal issue and preference. I think I
+>>> understand the importance of preference of upstream
+>>> developers. However, I'd like to clear the legal issue first.
+>>>
+>>
+>> Legally it's ok. But as you said, developers preference are
+>> different. And because you are trying to change THEIR code it's
+>> sometimes better to play they rules.
+>
+> I see.
+>
+>>> I can image there are people who prefer to GPL as the license covering
+>>> their software. But here I've taken some corosync code in my
+>>> dissector. It is essential part of my dissector. And corosync is
+>>
+>> ^^^ This may be problem. Question is how big is that part and if it
+>> can be possible to make exception there. Can you point that code?
+>>
+>> Steve, we were able to relicense HUGE portion of code in case of
+>> libqb, are we able to make the same for Wireshark dissector?
+>
+> Could you see https://github.com/masatake/wireshark-plugin-rhcs/blob/master/src/packet-corosync-totemnet.c#L156
+> I refer totemnet.c to write dissect_corosynec_totemnet_with_decryption() function.
+>
+>>> licensed in 3-clause BSD, as you know. I'd like to change the license
+>>> to merge my code to upstream project. I cannot do it in this context.
+>>> See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3232#c13
+>>> Thank you.
+>>
+>> Regards,
+>> Honza
+>
+> Masatake YAMATO
+
+Masatake,
+
+Red Hat is the author of the totemnet file and can provide that code
+under GPL if you like. We cannot modify the license for libtomcrypt as
+we are not the authors. Feel free to change the license for that
+particular code you rewrote in the link
+
+> Could you see
+https://github.com/masatake/wireshark-plugin-rhcs/blob/master/src/packet-corosync-totemnet.c#L156
+
+under a GPL license if it helps move things along.
+
+Regards
+-steveu
+ */
+
+static int
+dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *parent_tree,
+ gboolean check_crypt_type,
+ const gchar* key_for_trial)
+{
+ unsigned char keys[48];
+ sober128_prng keygen_prng_state;
+ sober128_prng stream_prng_state;
+ unsigned char *hmac_key = &keys[32];
+ unsigned char *cipher_key = &keys[16];
+ unsigned char *initial_vector = &keys[0];
+ unsigned char digest_comparison[HMAC_HASH_SIZE];
+
+ int io_len;
+ guint8 *io_base;
+
+#define PRIVATE_KEY_LEN_MAX 256
+ gchar private_key[PRIVATE_KEY_LEN_MAX];
+ unsigned int private_key_len;
+ unsigned char* hash_digest;
+ unsigned char* salt;
+
+ io_len = tvb_reported_length(tvb) - (check_crypt_type? 1: 0);
+ if (io_len < HMAC_HASH_SIZE + SALT_SIZE) {
+ return 0;
+ }
+
+ io_base = (guint8 *)tvb_memdup(pinfo->pool, tvb, 0, io_len + (check_crypt_type? 1: 0));
+ if (check_crypt_type &&
+ ( io_base[io_len] != TOTEM_CRYPTO_SOBER )) {
+ return 0;
+ }
+
+ hash_digest = io_base;
+ salt = io_base + HMAC_HASH_SIZE;
+
+
+ memset(private_key, 0, sizeof(private_key));
+
+ private_key_len = (strlen(key_for_trial)+4) & 0xFC;
+ if (private_key_len > PRIVATE_KEY_LEN_MAX)
+ private_key_len = PRIVATE_KEY_LEN_MAX;
+ g_strlcpy(private_key, key_for_trial, private_key_len);
+
+ /*
+ * Generate MAC, CIPHER, IV keys from private key
+ */
+ memset (keys, 0, sizeof(keys));
+ sober128_start (&keygen_prng_state);
+ sober128_add_entropy(private_key,
+ private_key_len, &keygen_prng_state);
+ sober128_add_entropy (salt, SALT_SIZE, &keygen_prng_state);
+ sober128_read (keys, sizeof (keys), &keygen_prng_state);
+
+ /*
+ * Setup stream cipher
+ */
+ sober128_start (&stream_prng_state);
+ sober128_add_entropy (cipher_key, 16, &stream_prng_state);
+ sober128_add_entropy (initial_vector, 16, &stream_prng_state);
+
+ /*
+ * Authenticate contents of message
+ */
+ sha1_hmac(hmac_key, 16,
+ io_base + HMAC_HASH_SIZE, io_len - HMAC_HASH_SIZE,
+ digest_comparison);
+
+ if (memcmp (digest_comparison, hash_digest, HMAC_HASH_SIZE) != 0)
+ return 0;
+
+ /*
+ * Decrypt the contents of the message with the cipher key
+ */
+
+ sober128_read (io_base + HMAC_HASH_SIZE + SALT_SIZE,
+ io_len - (HMAC_HASH_SIZE + SALT_SIZE),
+ &stream_prng_state);
+
+
+ /*
+ * Dissect the decrypted data
+ */
+ {
+ tvbuff_t *decrypted_tvb;
+ tvbuff_t *next_tvb;
+
+
+ decrypted_tvb = tvb_new_real_data(io_base, io_len, io_len);
+
+ tvb_set_child_real_data_tvbuff(tvb, decrypted_tvb);
+ add_new_data_source(pinfo, decrypted_tvb, "Decrypted Data");
+
+
+ dissect_corosync_totemnet_security_header(decrypted_tvb, pinfo, parent_tree,
+ check_crypt_type, key_for_trial);
+
+ next_tvb = tvb_new_subset(decrypted_tvb,
+ HMAC_HASH_SIZE + SALT_SIZE,
+ io_len - (HMAC_HASH_SIZE + SALT_SIZE),
+ io_len - (HMAC_HASH_SIZE + SALT_SIZE));
+
+ return call_dissector(corosync_totemsrp_handle, next_tvb, pinfo, parent_tree) + HMAC_HASH_SIZE + SALT_SIZE;
+ }
+}
+
+static int
+dissect_corosynec_totemnet(tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *parent_tree,
+ void *data _U_)
+{
+ if (corosync_totemnet_private_keys_list)
+ {
+ static int last_key_index = -1;
+ int key_index;
+
+ static int last_check_crypt_type_index;
+ int check_crypt_type_index = -1;
+ gboolean check_crypt_type_list[] = {FALSE, TRUE};
+
+
+ if (last_key_index != -1)
+ {
+ int r;
+
+ r = dissect_corosynec_totemnet_with_decryption(tvb,
+ pinfo,
+ parent_tree,
+ check_crypt_type_list[last_check_crypt_type_index],
+ corosync_totemnet_private_keys_list[last_key_index]);
+ if (r > 0)
+ return r;
+ else
+ last_key_index = -1;
+ }
+
+ for (key_index = 0;
+ corosync_totemnet_private_keys_list[key_index];
+ key_index++)
+ {
+ for (check_crypt_type_index = 0;
+ check_crypt_type_index < 2;
+ check_crypt_type_index++)
+ {
+ int r;
+
+ r = dissect_corosynec_totemnet_with_decryption(tvb,
+ pinfo,
+ parent_tree,
+ check_crypt_type_list[check_crypt_type_index],
+ corosync_totemnet_private_keys_list[key_index]);
+ if (r > 0)
+ {
+ last_key_index = key_index;
+ last_check_crypt_type_index = check_crypt_type_index;
+ return r;
+ }
+ else if (r < 0)
+ break;
+
+ }
+ }
+ }
+
+ /* Not encrypted */
+ return call_dissector(corosync_totemsrp_handle, tvb, pinfo, parent_tree);
+}
+
+
+void
+proto_register_corosync_totemnet(void)
+{
+ module_t *corosync_totemnet_module;
+
+ static hf_register_info hf[] = {
+ { &hf_corosync_totemnet_security_header_hash_digest,
+ { "Hash digest", "corosync_totemnet.security_header_hash_digest",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_corosync_totemnet_security_header_salt,
+ { "Salt", "corosync_totemnet.security_header_salt",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_corosync_totemnet_security_crypto_type,
+ { "Cryptographic Type", "corosync_totemnet.security_crypto_type",
+ FT_UINT8, BASE_DEC, VALS(corosync_totemnet_crypto_type), 0x0,
+ NULL, HFILL }},
+ { &hf_corosync_totemnet_security_crypto_key,
+ { "Private Key for decryption", "corosync_totemnet.security_crypto_key",
+ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ };
+
+ static gint *ett_corosync_totemnet[] = {
+ &ett_corosync_totemnet_security_header,
+ };
+
+ proto_corosync_totemnet = proto_register_protocol("Totemnet Layer of Corosync Cluster Engine",
+ "COROSYNC/TOTEMNET", "corosync_totemnet");
+ proto_register_field_array(proto_corosync_totemnet, hf, array_length(hf));
+ proto_register_subtree_array(ett_corosync_totemnet, array_length(ett_corosync_totemnet));
+
+ corosync_totemnet_module = prefs_register_protocol(proto_corosync_totemnet,
+ proto_reg_handoff_corosync_totemnet);
+
+ prefs_register_uint_preference(corosync_totemnet_module, "udp.port",
+ "UDP Port",
+ "Set the UDP port for totem ring protocol implemented in corosync cluster engine",
+ 10,
+ &corosync_totemnet_port);
+ prefs_register_string_preference(corosync_totemnet_module, "private_keys", "Private keys",
+ "Semicolon-separated list of keys for decryption(e.g. key1;key2;..." ,
+ (const gchar **)&corosync_totemnet_private_keys);
+}
+
+void
+proto_reg_handoff_corosync_totemnet(void)
+{
+ static gboolean register_dissector = FALSE;
+ static dissector_handle_t corosync_totemnet_handle;
+ static int port = 0;
+
+
+ if (register_dissector)
+ {
+ dissector_delete_uint("udp.port", port, corosync_totemnet_handle);
+ dissector_delete_uint("udp.port", port - 1, corosync_totemnet_handle);
+ }
+ else
+ {
+ corosync_totemnet_handle = new_create_dissector_handle(dissect_corosynec_totemnet,
+ proto_corosync_totemnet);
+ corosync_totemsrp_handle = find_dissector("corosync_totemsrp");
+
+ register_dissector = TRUE;
+ }
+
+ if (corosync_totemnet_private_keys_list) {
+ g_strfreev(corosync_totemnet_private_keys_list);
+ corosync_totemnet_private_keys_list = NULL;
+ }
+ corosync_totemnet_private_keys_list = g_strsplit(corosync_totemnet_private_keys,
+ ";",
+ 0);
+ port = corosync_totemnet_port;
+ dissector_add_uint("udp.port", port, corosync_totemnet_handle);
+ dissector_add_uint("udp.port", port - 1, corosync_totemnet_handle);
+}
+
+/*
+ * Editor modelines - http://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:
+ */
+
+/* packet-corosync-totemnet.c ends here */
diff --git a/epan/dissectors/packet-corosync-totemsrp.c b/epan/dissectors/packet-corosync-totemsrp.c
new file mode 100644
index 0000000000..4791bb8e2c
--- /dev/null
+++ b/epan/dissectors/packet-corosync-totemsrp.c
@@ -0,0 +1,1168 @@
+/* packet-corosync-totemsrp.c
+ * Dissectors for totem single ring protocol implementated 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"*/
+
+
+# include "config.h"
+
+#include <epan/packet.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+/*
+ * Utilities for subdissectors of corosync_totemsrp.
+ */
+struct corosync_totemsrp_info {
+ guint encoding;
+ guint nodeid;
+};
+
+/* Forward declaration we need below */
+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[] = {
+ { AF_INET, "AF_INET" },
+ { AF_INET6, "AF_INET6" },
+ { 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 AF_INET:
+ len = 4;
+ proto_tree_add_item(tree, hf_corosync_totemsrp_ip_address_addr4, tvb, offset, len, ENC_BIG_ENDIAN);
+ break;
+ case 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 = (sizeof(struct e_in6_addr) - len);
+ proto_tree_add_item (tree, hf_corosync_totemsrp_ip_address_addr4_padding,
+ tvb, offset, padding_len, FALSE);
+ 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_canel */
+ { &hf_corosync_totemsrp_token_hold_cancel,
+ {"Hold cancel token", "corosync_totemsrp.token_hold_canel",
+ 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));
+
+ register_heur_dissector_list("corosync_totemsrp.mcast", &heur_subdissector_list);
+
+ new_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:
+ */