Index: wireshark-1.4.1/epan/dissectors/Makefile.common =================================================================== --- wireshark-1.4.1.orig/epan/dissectors/Makefile.common +++ wireshark-1.4.1/epan/dissectors/Makefile.common @@ -307,6 +307,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 \ Index: wireshark-1.4.1/epan/dissectors/packet-corosync-totemnet.c =================================================================== --- /dev/null +++ wireshark-1.4.1/epan/dissectors/packet-corosync-totemnet.c @@ -0,0 +1,1274 @@ +/* packet-corosync-totemnet.c + * Routines for the lowest level(encryption/decryption) protocol used in Corosync cluster engine + * Copyright 2009 2010 Masatake YAMATO + * Copyright (c) 2010 Red Hat, Inc. + * + * $Id:$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "packet-corosync-totemsrp.h" + +/* 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 + the library and sha1 functions in wireshark. */ + + +/* crypto.h */ + +/* About LibTomCrypt: + * --------------------------------------------------------------------- + * LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.com + */ + +/* + * Modifications in packet-corosync-totemnet.c done by Masatake YAMATO + * --------------------------------------------------------------------- + * + * - added `corocrypto' as symbol prefix to some symbols, and + * - added `static' modifier to functions and symbols to narrow the scope. + * + */ +struct sober128_prng { + unsigned long R[17], /* Working storage for the shift register */ + initR[17], /* saved register contents */ + konst, /* key dependent constant */ + sbuf; /* partial word encryption buffer */ + + int nbuf, /* number of part-word stream bits buffered */ + flag, /* first add_entropy call or not? */ + set; /* did we call add_entropy to set key? */ + +}; + +static int corocrypto_sober128_start(struct sober128_prng *prng); +static int corocrypto_sober128_add_entropy(const unsigned char *buf, unsigned long len, struct sober128_prng *prng); +static unsigned long corocrypto_sober128_read(unsigned char *buf, unsigned long len, struct sober128_prng *prng); + + +/* + * 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; + +/* configurable parameters */ +static guint corosync_totemnet_port = PORT_COROSYNC_TOTEMNET; +static gchar* corosync_totemnet_private_key = NULL; + +/* Initialize the subtree pointers */ +static gint ett_corosync_totemnet_security_header = -1; + + +#define HMAC_HASH_SIZE 20 +#define SALT_SIZE 16 + + + +static int +dissect_corosync_totemnet_security_header(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree) +{ + proto_item *item; + proto_tree *tree; + + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "COROSYNC/TOTEMNET"); + + if (check_col(pinfo->cinfo, COL_INFO)) + 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); + + } + 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. + * + * --------------------------------------------------------------------- + * Copyright (c) 2005 MontaVista Software, Inc. + * Copyright (c) 2006-2007 Red Hat, Inc. + * Copyright (c) 2006 Sun Microsystems, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sdake@redhat.com) + + * This software licensed under BSD license, the text of which follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of the MontaVista Software, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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. + */ +static int +dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree) +{ + unsigned char keys[48]; + struct sober128_prng keygen_prng_state; + struct 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]; + + + guint8 *io_base; + guint io_len; + +#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_length(tvb); + if (io_len < HMAC_HASH_SIZE + SALT_SIZE) + return 0; + + io_base = tvb_memdup(tvb, 0, io_len); + hash_digest = io_base; + salt = io_base + HMAC_HASH_SIZE; + + + memset(private_key, 0, sizeof(private_key)); + + private_key_len = (strlen(corosync_totemnet_private_key)+4) & 0xFC; + if (private_key_len > PRIVATE_KEY_LEN_MAX) + private_key_len = PRIVATE_KEY_LEN_MAX; + g_strlcpy(private_key, corosync_totemnet_private_key, private_key_len); + + + /* + * Generate MAC, CIPHER, IV keys from private key + */ + memset (keys, 0, sizeof(keys)); + corocrypto_sober128_start (&keygen_prng_state); + corocrypto_sober128_add_entropy(private_key, + private_key_len, &keygen_prng_state); + corocrypto_sober128_add_entropy (salt, SALT_SIZE, &keygen_prng_state); + corocrypto_sober128_read (keys, sizeof (keys), &keygen_prng_state); + + /* + * Setup stream cipher + */ + corocrypto_sober128_start (&stream_prng_state); + corocrypto_sober128_add_entropy (cipher_key, 16, &stream_prng_state); + corocrypto_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) + { + g_free(io_base); + return 0; + } + + + /* + * Decrypt the contents of the message with the cipher key + */ + + corocrypto_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_free_cb(decrypted_tvb, g_free); + + 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); + + 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 dissect_corosync_totemsrp(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) +{ + if (corosync_totemnet_private_key) + { + int r; + + r = dissect_corosynec_totemnet_with_decryption(tvb, pinfo, parent_tree); + + if (r > 0) + return r; + } + return dissect_corosync_totemsrp(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 }}, + }; + + 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); + /* tserong@novell.com: private key as a string doesn't work for + * secauth with /etc/corosync/authkey, so leaving this out until + * we come up with a better solution + prefs_register_string_preference(corosync_totemnet_module, "private_key", + "Private key", + "Key to decrypt the communications on corosync cluster engine", + (const gchar **)&corosync_totemnet_private_key); + */ +} + +void +proto_reg_handoff_corosync_totemnet(void) +{ + static gboolean register_dissector = FALSE; + + static int port = 0; + + static dissector_handle_t corosync_totemnet_handle; + + if (register_dissector) + { + dissector_delete("udp.port", port, corosync_totemnet_handle); + } + else + { + corosync_totemnet_handle = new_create_dissector_handle(dissect_corosynec_totemnet, + proto_corosync_totemnet); + register_dissector = TRUE; + } + + port = corosync_totemnet_port; + dissector_add("udp.port", port, corosync_totemnet_handle); +} + + + +/* crypto.c */ + +/* About LibTomCrypt: + * --------------------------------------------------------------------- + * LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.com + */ +#define CONST64(n) n ## ULL + +typedef unsigned long ulong32; +typedef unsigned long long ulong64; + +#ifdef WORDS_BIGENDIAN +#define ENDIAN_BIG +#else +#define ENDIAN_LITTLE +#endif + +#if defined(__WORDSIZE) +#if __WORDSIZE == 64 +#define ENDIAN_64BITWORD +#endif +#if __WORDSIZE == 32 +#define ENDIAN_32BITWORD +#endif +#else +/* XXX need to find a better default + */ +#define ENDIAN_32BITWORD +#endif + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif /* ENDIAN_NEUTRAL */ + +#ifdef ENDIAN_LITTLE + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64L(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64L(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ + +#endif /* ENDIAN_LITTLE */ + +#ifdef ENDIAN_BIG +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ + (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64H(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64H(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + +#if defined(__GNUC__) && defined(__i386__) && !defined(INTEL_CC) + +static inline unsigned long ROL(unsigned long word, int i) +{ + __asm__("roll %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned long ROR(unsigned long word, int i) +{ + __asm__("rorl %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#else + +/* rotates the hard way */ +#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +#endif + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#undef MAX +#undef MIN +#define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#define MIN(x, y) ( ((x)<(y))?(x):(y) ) + +/* extract a byte portably */ +#define byte(x, n) (((x) >> (8 * (n))) & 255) + +#define CONST64(n) n ## ULL + + +/* + * The mycrypt_macros.h file + */ + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif /* ENDIAN_NEUTRAL */ + +#ifdef ENDIAN_LITTLE + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64L(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64L(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ + +#endif /* ENDIAN_LITTLE */ + +#ifdef ENDIAN_BIG +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ + (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64H(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64H(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#undef MAX +#undef MIN +#define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#define MIN(x, y) ( ((x)<(y))?(x):(y) ) + +/* extract a byte portably */ +#define byte(x, n) (((x) >> (8 * (n))) & 255) + +/* $Id: s128multab.h 213 2003-12-16 04:27:12Z ggr $ */ +/* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */ +/* Multiplication table for Turing using 0xD02B4367 */ + +static const ulong32 Multab[256] = { + 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9, + 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478, + 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746, + 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697, + 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A, + 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB, + 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5, + 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04, + 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2, + 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613, + 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D, + 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC, + 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51, + 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80, + 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE, + 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F, + 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F, + 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE, + 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90, + 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41, + 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC, + 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D, + 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703, + 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2, + 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14, + 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5, + 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB, + 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A, + 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787, + 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656, + 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568, + 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9, + 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748, + 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699, + 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7, + 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476, + 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB, + 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A, + 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34, + 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5, + 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523, + 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2, + 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC, + 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D, + 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0, + 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61, + 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F, + 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E, + 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E, + 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F, + 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71, + 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0, + 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D, + 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC, + 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2, + 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433, + 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5, + 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24, + 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A, + 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB, + 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566, + 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7, + 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789, + 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658, +}; + +/* $Id: s128sbox.h 213 2003-12-16 04:27:12Z ggr $ */ +/* Sbox for SOBER-128 */ +/* + * This is really the combination of two SBoxes; the least significant + * 24 bits comes from: + * 8->32 Sbox generated by Millan et. al. at Queensland University of + * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter, + * "On the Design of 8*32 S-boxes". Unpublished report, by the + * Information Systems Research Centre, + * Queensland University of Technology, 1999. + * + * The most significant 8 bits are the Skipjack "F table", which can be + * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf . + * In this optimised table, though, the intent is to XOR the word from + * the table selected by the high byte with the input word. Thus, the + * high byte is actually the Skipjack F-table entry XORED with its + * table index. + */ +static const ulong32 Sbox[256] = { + 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4, + 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae, + 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c, + 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35, + 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e, + 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b, + 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f, + 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1, + 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd, + 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3, + 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f, + 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36, + 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf, + 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816, + 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d, + 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af, + 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6, + 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418, + 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0, + 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd, + 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088, + 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759, + 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895, + 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66, + 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc, + 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1, + 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911, + 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e, + 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515, + 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133, + 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226, + 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084, + 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb, + 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184, + 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420, + 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02, + 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655, + 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c, + 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418, + 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473, + 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a, + 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0, + 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21, + 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36, + 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5, + 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6, + 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0, + 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795, + 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0, + 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78, + 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da, + 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a, + 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118, + 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed, + 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd, + 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b, + 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921, + 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e, + 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5, + 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8, + 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376, + 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a, + 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8, + 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40, +}; + + +/* Implementation of SOBER-128 by Tom St Denis. + * Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM. + */ + +/* don't change these... */ +#define N 17 +#define FOLD N /* how many iterations of folding to do */ +#define INITKONST 0x6996c53a /* value of KONST to use during key loading */ +#define KEYP 15 /* where to insert key words */ +#define FOLDP 4 /* where to insert non-linear feedback */ + +#define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF)) + +static ulong32 BYTE2WORD(unsigned char *b) +{ + ulong32 t; + LOAD32L(t, b); + return t; +} + +#define WORD2BYTE(w, b) STORE32L(b, w) + +static void XORWORD(ulong32 w, unsigned char *b) +{ + ulong32 t; + LOAD32L(t, b); + t ^= w; + STORE32L(t, b); +} + +/* give correct offset for the current position of the register, + * where logically R[0] is at position "zero". + */ +#define OFF(zero, i) (((zero)+(i)) % N) + +/* step the LFSR */ +/* After stepping, "zero" moves right one place */ +#define STEP(R,z) \ + R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF]; + +static void cycle(ulong32 *R) +{ + ulong32 t; + int i; + + STEP(R,0); + t = R[0]; + for (i = 1; i < N; ++i) { + R[i-1] = R[i]; + } + R[N-1] = t; +} + +/* Return a non-linear function of some parts of the register. + */ +#define NLFUNC(c,z) \ +{ \ + t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \ + t ^= Sbox[(t >> 24) & 0xFF]; \ + t = ROR(t, 8); \ + t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \ + t ^= Sbox[(t >> 24) & 0xFF]; \ + t = t + c->R[OFF(z,13)]; \ +} + +static ulong32 nltap(struct sober128_prng *c) +{ + ulong32 t; + NLFUNC(c, 0); + return t; +} + +/* initialise to known state + */ +int corocrypto_sober128_start(struct sober128_prng *c) +{ + int i; + + /* Register initialised to Fibonacci numbers */ + c->R[0] = 1; + c->R[1] = 1; + for (i = 2; i < N; ++i) { + c->R[i] = c->R[i-1] + c->R[i-2]; + } + c->konst = INITKONST; + + /* next add_entropy will be the key */ + c->flag = 1; + c->set = 0; + + return 0; +} + +/* Save the current register state + */ +static void s128_savestate(struct sober128_prng *c) +{ + int i; + for (i = 0; i < N; ++i) { + c->initR[i] = c->R[i]; + } +} + +/* initialise to previously saved register state + */ +static void s128_reloadstate(struct sober128_prng *c) +{ + int i; + + for (i = 0; i < N; ++i) { + c->R[i] = c->initR[i]; + } +} + +/* Initialise "konst" + */ +static void s128_genkonst(struct sober128_prng *c) +{ + ulong32 newkonst; + + do { + cycle(c->R); + newkonst = nltap(c); + } while ((newkonst & 0xFF000000) == 0); + c->konst = newkonst; +} + +/* Load key material into the register + */ +#define ADDKEY(k) \ + c->R[KEYP] += (k); + +#define XORNL(nl) \ + c->R[FOLDP] ^= (nl); + +/* nonlinear diffusion of register for key */ +#define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; +static void s128_diffuse(struct sober128_prng *c) +{ + ulong32 t; + /* relies on FOLD == N == 17! */ + DROUND(0); + DROUND(1); + DROUND(2); + DROUND(3); + DROUND(4); + DROUND(5); + DROUND(6); + DROUND(7); + DROUND(8); + DROUND(9); + DROUND(10); + DROUND(11); + DROUND(12); + DROUND(13); + DROUND(14); + DROUND(15); + DROUND(16); +} + +static int corocrypto_sober128_add_entropy(const unsigned char *buf, unsigned long len, struct sober128_prng *c) +{ + ulong32 i, k; + + + if (c->flag == 1) { + /* this is the first call to the add_entropy so this input is the key */ + /* len must be multiple of 4 bytes */ + assert ((len & 3) == 0); + + for (i = 0; i < len; i += 4) { + k = BYTE2WORD((unsigned char *)&buf[i]); + ADDKEY(k); + cycle(c->R); + XORNL(nltap(c)); + } + + /* also fold in the length of the key */ + ADDKEY(len); + + /* now diffuse */ + s128_diffuse(c); + + s128_genkonst(c); + s128_savestate(c); + c->nbuf = 0; + c->flag = 0; + c->set = 1; + } else { + /* ok we are adding an IV then... */ + s128_reloadstate(c); + + /* len must be multiple of 4 bytes */ + assert ((len & 3) == 0); + + for (i = 0; i < len; i += 4) { + k = BYTE2WORD((unsigned char *)&buf[i]); + ADDKEY(k); + cycle(c->R); + XORNL(nltap(c)); + } + + /* also fold in the length of the key */ + ADDKEY(len); + + /* now diffuse */ + s128_diffuse(c); + c->nbuf = 0; + } + + return 0; +} + +/* XOR pseudo-random bytes into buffer + */ +#define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, buf+(z*4)); + +static unsigned long corocrypto_sober128_read(unsigned char *buf, unsigned long nbytes, struct sober128_prng *c) +{ + ulong32 t, tlen; + + t = 0; + tlen = nbytes; + + /* handle any previously buffered bytes */ + while (c->nbuf != 0 && nbytes != 0) { + *buf++ ^= c->sbuf & 0xFF; + c->sbuf >>= 8; + c->nbuf -= 8; + --nbytes; + } + +#ifndef SMALL_CODE + /* do lots at a time, if there's enough to do */ + while (nbytes >= N*4) { + SROUND(0); + SROUND(1); + SROUND(2); + SROUND(3); + SROUND(4); + SROUND(5); + SROUND(6); + SROUND(7); + SROUND(8); + SROUND(9); + SROUND(10); + SROUND(11); + SROUND(12); + SROUND(13); + SROUND(14); + SROUND(15); + SROUND(16); + buf += 4*N; + nbytes -= 4*N; + } +#endif + + /* do small or odd size buffers the slow way */ + while (4 <= nbytes) { + cycle(c->R); + t = nltap(c); + XORWORD(t, buf); + buf += 4; + nbytes -= 4; + } + + /* handle any trailing bytes */ + if (nbytes != 0) { + cycle(c->R); + c->sbuf = nltap(c); + c->nbuf = 32; + while (c->nbuf != 0 && nbytes != 0) { + *buf++ ^= c->sbuf & 0xFF; + c->sbuf >>= 8; + c->nbuf -= 8; + --nbytes; + } + } + + return tlen; +} + +/* packet-corosync-totemnet.c ends here */ Index: wireshark-1.4.1/epan/dissectors/packet-corosync-totemsrp.c =================================================================== --- /dev/null +++ wireshark-1.4.1/epan/dissectors/packet-corosync-totemsrp.c @@ -0,0 +1,1379 @@ +/* packet-corosync-totemsrp.c + * Dissectors for totem single ring protocol implementated in corosync cluster engine + * Copyright 2007 2009 2010 Masatake YAMATO + * Copyright (c) 2010 Red Hat, Inc. + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 + + 1. "The Totem Single-Ring Ordering and Membership Protocol" + Y.AMIR, L.E.MOSER, P.M.MELLIAR-SMITH, D.A.AGARWAL, P.CIARFELLA */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include + +#include + +#include "packet-corosync-totemsrp.h" + + +/* 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, "multicast message" }, + { 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, gboolean little_endian); + +static guint32 corosync_totemsrp_get_guint32(tvbuff_t* tvb, gint offset, gboolean little_endian); +static gint32 corosync_totemsrp_get_gint32 (tvbuff_t* tvb, gint offset, gboolean little_endian); + + +#define COROSYNC_TOTEMSRP_ENDIAN_LOCAL {0xff, 0x22} + + +#define COROSYNC_TOTEMSRP_SRP_ADDR_INTERFACE_MAX 2 + +struct corosync_totemsrp_info { + void* original_private_data; + gboolean little_endian; + proto_tree* master_tree; +}; + +static int +dissect_corosync_totemsrp_ip_address(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + gboolean little_endian, + gboolean print_interface, + guint interface, + guint *nodeid) +{ + int original_offset; + proto_tree *tree; + proto_item *item; + + guint16 family; + gint hf; + gint len; + + if ((length - offset) < corosync_totemsrp_ip_address_length) + return 0; + original_offset = offset; + + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_ip_address, tvb, offset, + corosync_totemsrp_ip_address_length, little_endian); + 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); + + + offset += 0; + proto_tree_add_item(tree, + hf_corosync_totemsrp_ip_address_nodeid, + tvb, offset, 4, little_endian); + { + guint nid; + + nid = corosync_totemsrp_get_guint32(tvb, offset, little_endian); + proto_item_append_text(item, "node: %u", nid); + if (nodeid) + *nodeid = nid; + } + proto_item_append_text(item, ")"); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_ip_address_family, + tvb, offset, 2, little_endian); + family = corosync_totemsrp_get_guint16(tvb, offset, little_endian); + + offset += 2; + switch (family) + { + case AF_INET: + hf = hf_corosync_totemsrp_ip_address_addr4; + len = 4; + break; + case AF_INET6: + hf = hf_corosync_totemsrp_ip_address_addr6; + len = COROSYNC_TOTEMSRP_IP_ADDRLEN; + break; + default: + hf = hf_corosync_totemsrp_ip_address_addr; + len = COROSYNC_TOTEMSRP_IP_ADDRLEN; + break; + } + proto_tree_add_item(tree, + hf, + tvb, offset, len, FALSE); + offset += len; + + if (len != COROSYNC_TOTEMSRP_IP_ADDRLEN) { + gint padding_len; + + padding_len = (COROSYNC_TOTEMSRP_IP_ADDRLEN - len); + proto_tree_add_item (tree, + hf_corosync_totemsrp_ip_address_addr4_padding, + tvb, offset, padding_len, FALSE); + offset += padding_len; + } + + + return offset - original_offset; + + pinfo = pinfo; +} + +static int +dissect_corosync_totemsrp_memb_ring_id(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + guint nodeid; + + if ((length - offset) < corosync_totemsrp_memb_ring_id_length) { + fprintf(stderr, "We have: %d, expected: %lu\n", + (length - offset), + corosync_totemsrp_memb_ring_id_length); + return 0; + } + original_offset = offset; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_ring_id, tvb, offset, + corosync_totemsrp_memb_ring_id_length, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_ring_id); + + offset += 0; + sub_length = dissect_corosync_totemsrp_ip_address(tvb, pinfo, tree, + length, offset, + little_endian, + FALSE, -1, + &nodeid); + + if (sub_length == 0) + goto out; + proto_item_append_text(item, " (node: %u)", nodeid); + + + offset += sub_length; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_ring_id_seq, + tvb, offset, 8, little_endian); + + offset += 8; +out: + 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, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + +#define corosync_totemsrp_rtr_list_length (corosync_totemsrp_memb_ring_id_length + 4) + if ((length - offset) < corosync_totemsrp_rtr_list_length) + return 0; + original_offset = offset; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_rtr_item, tvb, offset, + corosync_totemsrp_rtr_list_length, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_rtr_item); + + offset += 0; + sub_length = dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + proto_tree_add_item(tree, + hf_corosync_totemsrp_rtr_item_seq, + tvb, offset, 4, little_endian); + + offset += 4; +out: + 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, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + + gint32 rtr_list_entries; + gint32 i; + +#define corosync_totemsrp_orf_token_length ( 4 \ + + 4 \ + + 4 \ + + 4 \ + + corosync_totemsrp_memb_ring_id_length \ + + 4 \ + + 4 \ + + 4 \ + + 4) + if ((length - offset) < corosync_totemsrp_orf_token_length) + return 0; + original_offset = offset; + + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_orf_token, tvb, offset, + -1, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_orf_token); + + offset += 0; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_seq, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_token_seq, + tvb, offset, 4, little_endian); + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_aru, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_aru_addr, + tvb, offset, 4, little_endian); + + offset += 4; + sub_length = dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_backlog, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_fcc, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_retrnas_flg, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_orf_token_rtr_list_entries, + tvb, offset, 4, little_endian); + + + + rtr_list_entries = corosync_totemsrp_get_gint32(tvb, offset, little_endian); + if ((length - offset) < (rtr_list_entries * corosync_totemsrp_rtr_list_length) ) + goto out; + + offset += 4; + for (i = 0; i < rtr_list_entries; i++) { + sub_length = dissect_corosync_totemsrp_rtr_list(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + offset += sub_length; + } +out: + return offset - original_offset; + + pinfo = pinfo; +} + +static int +dissect_corosync_totemsrp_srp_addr(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + int hf, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + +#define corosync_totemsrp_srp_addr_length (corosync_totemsrp_ip_address_length * COROSYNC_TOTEMSRP_SRP_ADDR_INTERFACE_MAX) + if ((length - offset) < corosync_totemsrp_srp_addr_length) + return 0; + original_offset = offset; + + item = proto_tree_add_item(parent_tree, hf? hf: hf_corosync_totemsrp_srp_addr, tvb, offset, + corosync_totemsrp_srp_addr_length, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_srp_addr); + + offset += 0; + sub_length = dissect_corosync_totemsrp_ip_address(tvb, pinfo, tree, + length, offset, + little_endian, + TRUE, 0, + NULL); + if (sub_length == 0) + goto out; + + + offset += sub_length; + sub_length = dissect_corosync_totemsrp_ip_address(tvb, pinfo, tree, + length, offset, + little_endian, + TRUE, 1, + NULL); + if (sub_length == 0) + goto out; + + offset += sub_length; +out: + return (offset - original_offset); +} + +static int +dissect_corosync_totemsrp_mcast (tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree, + guint length, int offset, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + + +#define corosync_totemsrp_mcast_length (corosync_totemsrp_srp_addr_length \ + + 4 \ + + 4 \ + + corosync_totemsrp_memb_ring_id_length \ + + 4 \ + + 4) + if ((length - offset) < corosync_totemsrp_mcast_length) { + return 0; + } + original_offset = offset; + + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_mcast, tvb, offset, + -1, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_mcast); + + offset += 0; + sub_length = dissect_corosync_totemsrp_srp_addr(tvb, pinfo, tree, + length, offset, + hf_corosync_totemsrp_mcast_system_from, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + proto_tree_add_item(tree, + hf_corosync_totemsrp_mcast_seq, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_mcast_this_seqno, + tvb, offset, 4, little_endian); + + offset += 4; + sub_length = dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + proto_tree_add_item(tree, + hf_corosync_totemsrp_mcast_node_id, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_mcast_guarantee, + tvb, offset, 4, little_endian); + + offset += 4; + + { + gint len, reported_len; + tvbuff_t *next_tvb; + struct corosync_totemsrp_info* info; + + len = tvb_length_remaining(tvb, offset); + reported_len = tvb_reported_length_remaining(tvb, offset); + + next_tvb = tvb_new_subset(tvb, offset, len, reported_len); + + info = (struct corosync_totemsrp_info*)pinfo->private_data; + if (dissector_try_heuristic(heur_subdissector_list, + next_tvb, + pinfo, + info->master_tree)) + offset = length ; + } + +out: + 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, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + +#define corosync_totemsrp_memb_merge_detect_length (corosync_totemsrp_srp_addr_length + corosync_totemsrp_memb_ring_id_length) + if ((length - offset) < corosync_totemsrp_memb_merge_detect_length) { + return 0; + } + original_offset = offset; + + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_merge_detect, tvb, offset, + -1, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_merge_detect); + + offset += 0; + sub_length = dissect_corosync_totemsrp_srp_addr(tvb, pinfo, tree, + length, offset, + 0, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + sub_length = dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; +out: + 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, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + + guint32 proc_list_entries; + proto_tree *proc_tree; + proto_item *proc_item; + + guint32 failed_list_entries; + proto_tree *failed_tree; + proto_item *failed_item; + + guint i; + + +#define corosync_totemsrp_memb_join_length ( corosync_totemsrp_srp_addr_length \ + + 4 \ + + 4 \ + + 8) + if ((length - offset) < corosync_totemsrp_memb_join_length) + return 0; + + original_offset = offset; + + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_join, tvb, offset, + -1, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_join); + + + offset += 0; + sub_length = dissect_corosync_totemsrp_srp_addr(tvb, pinfo, tree, + length, offset, + 0, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + proc_item = proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_join_proc_list_entries, + tvb, offset, 4, little_endian); + proc_list_entries = corosync_totemsrp_get_guint32(tvb, offset, little_endian); + + offset += 4; + failed_item = proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_join_failed_list_entries, + tvb, offset, 4, little_endian); + failed_list_entries = corosync_totemsrp_get_guint32(tvb, offset, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_join_ring_seq, + tvb, offset, 8, little_endian); + + offset += 8; + proc_tree = proto_item_add_subtree(proc_item, ett_corosync_totemsrp_memb_join_proc_list); + for (i = 0; i < proc_list_entries; i++) { + sub_length = dissect_corosync_totemsrp_srp_addr(tvb, pinfo, proc_tree, + length, offset, + 0, + little_endian); + if (sub_length == 0) + goto out; + offset += sub_length; + } + + failed_tree = proto_item_add_subtree(failed_item, ett_corosync_totemsrp_memb_join_failed_list); + for (i = 0; i < failed_list_entries; i++) { + sub_length = dissect_corosync_totemsrp_srp_addr(tvb, pinfo, failed_tree, + length, offset, + 0, + little_endian); + if (sub_length == 0) + goto out; + offset += sub_length; + } + +out: + 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, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + + +#define corosync_totemsrp_memb_commit_token_memb_entry_length ( corosync_totemsrp_memb_ring_id_length \ + + 4 \ + + 4 \ + + 4 ) + if ((length - offset) < corosync_totemsrp_memb_commit_token_memb_entry_length) + return 0; + original_offset = offset; + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_commit_token_memb_entry, + tvb, offset, + corosync_totemsrp_memb_commit_token_memb_entry_length, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_commit_token_memb_entry); + + + offset += 0; + sub_length = dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_commit_token_memb_entry_aru, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_commit_token_memb_entry_high_delivered, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_commit_token_memb_entry_received_flg, + tvb, offset, 4, little_endian); + + + offset += 4; +out: + 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, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + + gint32 addr_entries; + gint i; + +#define corosync_totemsrp_memb_commit_token_length ( 4 \ + + corosync_totemsrp_memb_ring_id_length \ + + 4 \ + + 4 \ + + 4) + if ((length - offset) < corosync_totemsrp_memb_commit_token_length) + return 0; + + original_offset = offset; + + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_memb_commit_token, + tvb, offset, -1, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_memb_commit_token); + + + offset += 0; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_commit_token_token_seq, + tvb, offset, 4, little_endian); + + offset += 4; + sub_length = dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_commit_token_retrans_flg, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_commit_token_memb_index, + tvb, offset, 4, little_endian); + + offset += 4; + proto_tree_add_item(tree, + hf_corosync_totemsrp_memb_commit_token_addr_entries, + tvb, offset, 4, little_endian); + addr_entries = corosync_totemsrp_get_gint32(tvb, offset, little_endian); + + + offset += 4; + if ((length - offset) < ((corosync_totemsrp_srp_addr_length + * addr_entries) + + (corosync_totemsrp_memb_commit_token_memb_entry_length + * addr_entries))) + goto out; + + for (i = 0; i < addr_entries; i++) { + sub_length = dissect_corosync_totemsrp_srp_addr(tvb, pinfo, tree, + length, offset, + 0, + little_endian); + if (sub_length == 0) + goto out; + offset += sub_length; + } + + for (i = 0; i < addr_entries; i++) { + sub_length = dissect_corosync_totemsrp_memb_commit_token_memb_entry(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + offset += sub_length; + } + +out: + 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, + gboolean little_endian) +{ + int original_offset; + int sub_length; + proto_tree *tree; + proto_item *item; + +#define corosync_totemsrp_token_hold_cancel_length ( corosync_totemsrp_memb_ring_id_length ) + if ((length - offset) < corosync_totemsrp_token_hold_cancel_length) + return 0; + + original_offset = offset; + + + item = proto_tree_add_item(parent_tree, hf_corosync_totemsrp_token_hold_cancel, tvb, offset, + -1, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp_token_hold_cancel); + + + offset += 0; + sub_length = dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, tree, + length, offset, + little_endian); + if (sub_length == 0) + goto out; + + offset += sub_length; +out: + return (offset - original_offset); +} + +int +dissect_corosync_totemsrp(tvbuff_t *tvb, + packet_info *pinfo, proto_tree *parent_tree) +{ + proto_item *item; + proto_tree *tree; + guint length; + int offset; + + + guint8 message_header__type; + guint8 message_header__encapsulated; + + union EndianDetector { + guint16 f; + guint8 b[2]; + } message_header__endian_detector; + guint8 endian_expect[2] = COROSYNC_TOTEMSRP_ENDIAN_LOCAL; + + gboolean little_endian; + + struct corosync_totemsrp_info info; + + + + /* Check that there's enough data */ + length = tvb_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); + if ( + /* + There is a version of corosync which encapsulated is not initialized. + The packet sent from the version of corosync, this dissector could not + recognize it as corosync packet. So I put special condition here: + don't check encapsulated field if the packet type is MESSAGE_TYPE_TOKEN_HOLD_CANCEL. + + ------------------------------------------------------------------------ + r2660 | sdake | 2010-02-19 05:08:39 +0900 (Fri, 19 Feb 2010) | 3 lines + + Patch to set unset value in token hold cancel structure as to not crash + wireshark. + + ------------------------------------------------------------------------ + Index: exec/totemsrp.c + =================================================================== + --- exec/totemsrp.c (revision 2659) + +++ exec/totemsrp.c (revision 2660) + @@ -2627,6 +2627,7 @@ + + token_hold_cancel.header.type = MESSAGE_TYPE_TOKEN_HOLD_CANCEL; + token_hold_cancel.header.endian_detector = ENDIAN_LOCAL; + + token_hold_cancel.header.encapsulated = 0; + token_hold_cancel.header.nodeid = instance->my_id.addr[0].nodeid; + memcpy (&token_hold_cancel.ring_id, &instance->my_ring_id, + sizeof (struct memb_ring_id)); + */ + (message_header__type != COROSYNC_TOTEMSRP_MESSAGE_TYPE_TOKEN_HOLD_CANCEL) + && message_header__encapsulated > 2) + return 0; + + /* message_header -- byte order checking */ + tvb_memcpy(tvb, &message_header__endian_detector.f, 2, 2); + + if ((message_header__endian_detector.b[0] == endian_expect[1]) + && (message_header__endian_detector.b[1] == endian_expect[0])) + little_endian = TRUE; + else if ((message_header__endian_detector.b[0] == endian_expect[0]) + && (message_header__endian_detector.b[1] == endian_expect[1])) + little_endian = FALSE; + else + return 0; + + info.little_endian = little_endian; + info.original_private_data = pinfo->private_data; + info.master_tree = parent_tree; + pinfo->private_data = &info; + + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "COROSYNC/TOTEMSRP"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, + "COROSYNC/TOTEMSRP"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, + val_to_str(message_header__type, + corosync_totemsrp_message_header_type, + "packet-corosync-totemsrp.c internal bug")); + + if (parent_tree) { + offset = 0; + + item = proto_tree_add_item(parent_tree, proto_corosync_totemsrp, tvb, offset, + -1, little_endian); + tree = proto_item_add_subtree(item, ett_corosync_totemsrp); + + offset += 0; + proto_tree_add_item(tree, + hf_corosync_totemsrp_message_header_type, + tvb, offset, 1, little_endian); + offset += 1; + proto_tree_add_item(tree, + hf_corosync_totemsrp_message_header_encapsulated, + tvb, offset, 1, little_endian); + + offset += 1; + proto_tree_add_item(tree, + hf_corosync_totemsrp_message_header_endian_detector, + tvb, offset, 2, little_endian); + + offset += 2; + proto_tree_add_item(tree, + hf_corosync_totemsrp_message_header_nodeid, + tvb, offset, 4, little_endian); + + offset += 4; + + switch (message_header__type) { + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_ORF_TOKEN: + dissect_corosync_totemsrp_orf_token(tvb, pinfo, tree, length, offset, + little_endian); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MCAST: + dissect_corosync_totemsrp_mcast(tvb, pinfo, tree, length, offset, + little_endian); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_MERGE_DETECT: + dissect_corosync_totemsrp_memb_merge_detect(tvb, pinfo, tree, length, offset, + little_endian); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_JOIN: + dissect_corosync_totemsrp_memb_join(tvb, pinfo, tree, length, offset, + little_endian); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_MEMB_COMMIT_TOKEN: + dissect_corosync_totemsrp_memb_commit_token(tvb, pinfo, tree, length, offset, + little_endian); + break; + case COROSYNC_TOTEMSRP_MESSAGE_TYPE_TOKEN_HOLD_CANCEL: + dissect_corosync_totemsrp_token_hold_cancel(tvb, pinfo, tree, length, offset, + little_endian); + break; + default: + break; + } + } + + pinfo->private_data = info.original_private_data; + return tvb_length(tvb); +} + +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, + { "Sequnce 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, + { "Squence 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, + {"Sequnce 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); +} + + +/* Some code copyed from packet-dlm3.c. */ +void +proto_reg_handoff_corosync_totemsrp(void) +{ + /* Nothing to be done. + dissect_corosync_totemsrp is directly called from corosync_totemnet dissector. */ +} + + + +static guint16 +corosync_totemsrp_get_guint16(tvbuff_t* tvb, gint offset, gboolean little_endian) +{ + return (little_endian? tvb_get_letohs: tvb_get_ntohs)(tvb, offset); +} + + +static guint32 +corosync_totemsrp_get_guint32(tvbuff_t* tvb, gint offset, gboolean little_endian) +{ + return (little_endian? tvb_get_letohl: tvb_get_ntohl)(tvb, offset); +} + +static gint32 +corosync_totemsrp_get_gint32 (tvbuff_t* tvb, gint offset, gboolean little_endian) +{ + union { + guint32 u; + gint32 i; + } v; + + v.u = corosync_totemsrp_get_guint32(tvb, offset, little_endian); + return v.i; +} + + + + +gboolean +corosync_totemsrp_is_little_endian(packet_info *pinfo) +{ + struct corosync_totemsrp_info* info; + + + info = (struct corosync_totemsrp_info*)pinfo->private_data; + return info->little_endian; +} + +int +corosync_totemsrp_dissect_memb_ring_id(tvbuff_t *tvb, + packet_info *pinfo, + proto_tree *parent_tree, + guint length, int offset) +{ + return dissect_corosync_totemsrp_memb_ring_id(tvb, pinfo, parent_tree, + length, offset, + corosync_totemsrp_is_little_endian(pinfo)); +} + Index: wireshark-1.4.1/epan/dissectors/packet-corosync-totemsrp.h =================================================================== --- /dev/null +++ wireshark-1.4.1/epan/dissectors/packet-corosync-totemsrp.h @@ -0,0 +1,53 @@ +/* packet-corosync-totemsrp.h + * Dissectors for totem single ring protocol implemented in corosync cluster engine + * Copyright 2007 2009 2010 Masatake YAMATO + * Copyright (c) 2010 Red Hat, Inc. + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +#ifndef __PACKET_COROSYNC_TOTEMSRP_H__ +#define __PACKET_COROSYNC_TOTEMSRP_H__ + +#include + +extern int dissect_corosync_totemsrp (tvbuff_t *tvb, + packet_info *pinfo, + proto_tree *parent_tree); + + +/* subdissectors for corosync_totemsrp can know the endian information + embedded in totemsrp packet header. */ +extern gboolean corosync_totemsrp_is_little_endian(packet_info *pinfo); + + +#define COROSYNC_TOTEMSRP_IP_ADDRLEN (sizeof(struct in6_addr)) +#define corosync_totemsrp_ip_address_length ( 4 + 2 + COROSYNC_TOTEMSRP_IP_ADDRLEN ) +#define corosync_totemsrp_memb_ring_id_length ( 8 + corosync_totemsrp_ip_address_length ) + +extern int corosync_totemsrp_dissect_memb_ring_id(tvbuff_t *tvb, + packet_info *pinfo, + proto_tree *parent_tree, + guint length, + int offset); + + +#endif /* packet-totemsrp.h */ Index: wireshark-1.4.1/epan/dissectors/Makefile.in =================================================================== --- wireshark-1.4.1.orig/epan/dissectors/Makefile.in +++ wireshark-1.4.1/epan/dissectors/Makefile.in @@ -224,6 +224,8 @@ am__objects_3 = libdissectors_la-packet- libdissectors_la-packet-collectd.lo \ libdissectors_la-packet-componentstatus.lo \ libdissectors_la-packet-cops.lo \ + libdissectors_la-packet-corosync-totemnet.lo \ + libdissectors_la-packet-corosync-totemsrp.lo \ libdissectors_la-packet-cosine.lo \ libdissectors_la-packet-cpfi.lo \ libdissectors_la-packet-cpha.lo \ @@ -1486,6 +1488,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 \ @@ -2773,6 +2777,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-collectd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-componentstatus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-cops.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-corosync-totemnet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-corosync-totemsrp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-cosine.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-cpfi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-cpha.Plo@am__quote@ @@ -4406,6 +4412,20 @@ libdissectors_la-packet-cops.lo: packet- @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -c -o libdissectors_la-packet-cops.lo `test -f 'packet-cops.c' || echo '$(srcdir)/'`packet-cops.c +libdissectors_la-packet-corosync-totemnet.lo: packet-corosync-totemnet.c +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -MT libdissectors_la-packet-corosync-totemnet.lo -MD -MP -MF "$(DEPDIR)/libdissectors_la-packet-corosync-totemnet.Tpo" -c -o libdissectors_la-packet-corosync-totemnet.lo `test -f 'packet-corosync-totemnet.c' || echo '$(srcdir)/'`packet-corosync-totemnet.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdissectors_la-packet-corosync-totemnet.Tpo" "$(DEPDIR)/libdissectors_la-packet-corosync-totemnet.Plo"; else rm -f "$(DEPDIR)/libdissectors_la-packet-corosync-totemnet.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet-corosync-totemnet.c' object='libdissectors_la-packet-corosync-totemnet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -c -o libdissectors_la-packet-corosync-totemnet.lo `test -f 'packet-corosync-totemnet.c' || echo '$(srcdir)/'`packet-corosync-totemnet.c + +libdissectors_la-packet-corosync-totemsrp.lo: packet-corosync-totemsrp.c +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -MT libdissectors_la-packet-corosync-totemsrp.lo -MD -MP -MF "$(DEPDIR)/libdissectors_la-packet-corosync-totemsrp.Tpo" -c -o libdissectors_la-packet-corosync-totemsrp.lo `test -f 'packet-corosync-totemsrp.c' || echo '$(srcdir)/'`packet-corosync-totemsrp.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdissectors_la-packet-corosync-totemsrp.Tpo" "$(DEPDIR)/libdissectors_la-packet-corosync-totemsrp.Plo"; else rm -f "$(DEPDIR)/libdissectors_la-packet-corosync-totemsrp.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet-corosync-totemsrp.c' object='libdissectors_la-packet-corosync-totemsrp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -c -o libdissectors_la-packet-corosync-totemsrp.lo `test -f 'packet-corosync-totemsrp.c' || echo '$(srcdir)/'`packet-corosync-totemsrp.c + libdissectors_la-packet-cosine.lo: packet-cosine.c @am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -MT libdissectors_la-packet-cosine.lo -MD -MP -MF "$(DEPDIR)/libdissectors_la-packet-cosine.Tpo" -c -o libdissectors_la-packet-cosine.lo `test -f 'packet-cosine.c' || echo '$(srcdir)/'`packet-cosine.c; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdissectors_la-packet-cosine.Tpo" "$(DEPDIR)/libdissectors_la-packet-cosine.Plo"; else rm -f "$(DEPDIR)/libdissectors_la-packet-cosine.Tpo"; exit 1; fi