FreePastry/tools/wireshark/packet-replication.c

351 lines
11 KiB
C
Raw Normal View History

2019-05-13 12:45:05 +00:00
/* packet-replication.c
* Routines for Replication
* Copyright 2007, David Dugoujon <dav176fr@yahoo.fr>
*
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gmodule.h>
#include <epan/packet.h>
#include <epan/emem.h>
#include <epan/prefs.h>
#include "packet-replication.h"
#include "packet-freepastry.h"
static int proto_replication = -1;
static int hf_replication_type = -1;
static int hf_replication_version = -1;
static int hf_replication_num_bloomfilters = -1;
static int hf_replication_num_ranges = -1;
static int hf_replication_num_rows = -1;
static int hf_replication_num_cols = -1;
static int hf_bloom_filter_length = -1;
static int hf_bloom_filter_num_params = -1;
static int hf_bloom_filter_param = -1;
static int hf_bloom_filter_num_bits = -1;
static int hf_bloom_filter_bits = -1;
static int hf_id_range_cw = -1;
static int hf_id_range_ccw = -1;
static int hf_id_range_empty = -1;
static gint ett_replication = -1;
static gint ett_replication_bloomfilter = -1;
static gint ett_replication_idrange = -1;
static dissector_handle_t replication_handle;
static const value_string replication_msg_type[] = {
{ REP_REQUEST_MSG, "Request"},
{ REP_RESPONSE_MSG, "Response"},
{ 0, NULL }
};
gint
decode_bloom_filter(tvbuff_t *tvb, proto_tree *parent_tree, gint offset, gchar *attribute_name)
{
proto_item *ti = NULL;
proto_tree *bloomfilter_tree = NULL;
guint32 length;
guint32 num_params;
guint32 num_bits;
guint32 num_bytes;
guint32 i;
ti = proto_tree_add_text(parent_tree, tvb, offset, 1, attribute_name);
bloomfilter_tree = proto_item_add_subtree(ti, ett_replication_bloomfilter);
length = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(bloomfilter_tree, hf_bloom_filter_length, tvb, offset, 4, length);
offset += 4;
/* if ((guint32) tvb_reported_length_remaining(tvb, offset) < length){
proto_tree_add_text(bloomfilter_tree, tvb, offset, -1, "Malformed bloom filter!");
return -1;
}*/
num_params = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(bloomfilter_tree, hf_bloom_filter_num_params, tvb, offset, 4, num_params);
offset += 4;
for (i = 0; i < num_params; ++i){
proto_tree_add_item(bloomfilter_tree, hf_bloom_filter_param, tvb, offset, 4, FALSE);
offset += 4;
}
num_bits = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(bloomfilter_tree, hf_bloom_filter_num_bits, tvb, offset, 4, num_bits);
offset += 4;
if (num_bits != 0) {
num_bytes = num_bits >> 3;
if ((num_bits % 8) != 0){
num_bytes++;
}
proto_tree_add_item(bloomfilter_tree, hf_bloom_filter_bits, tvb, offset, num_bytes, FALSE);
offset += num_bytes;
} else {
proto_tree_add_item(bloomfilter_tree, hf_bloom_filter_bits, tvb, offset, 1, FALSE);
offset += 1;
}
proto_item_set_end(ti, tvb, offset);
return offset;
}
gint
decode_id_range(tvbuff_t *tvb, proto_tree *parent_tree, gint offset, gchar *attribute_name)
{
proto_item *ti = NULL;
proto_tree *idrange_tree = NULL;
ti = proto_tree_add_text(parent_tree, tvb, offset, 1, attribute_name);
idrange_tree = proto_item_add_subtree(ti, ett_replication_idrange);
if (tvb_reported_length_remaining(tvb, offset) < 41){
proto_tree_add_text(idrange_tree, tvb, offset, -1, "Malformed ID range attribute!");
return -1;
}
proto_tree_add_string(idrange_tree, hf_id_range_cw, tvb, offset, 20, get_id_full(tvb, offset));
offset += 20;
proto_tree_add_string(idrange_tree, hf_id_range_ccw, tvb, offset, 20, get_id_full(tvb, offset));
offset += 20;
proto_tree_add_item(idrange_tree, hf_id_range_empty, tvb, offset, 1, FALSE);
offset++;
proto_item_set_end(ti, tvb, offset);
return offset;
}
void
decode_replication_request(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
if (tree){
guint32 num_filters;
guint32 num_ranges;
guint32 i, j;
num_filters = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(tree, hf_replication_num_bloomfilters, tvb, offset, 4, num_filters);
offset += 4;
for (i = 0; i < num_filters; ++i){
offset = decode_bloom_filter(tvb, tree, offset, ep_strdup_printf("Bloom filter #%d", i+1));
if (offset == -1){
return;
}
}
num_ranges = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(tree, hf_replication_num_ranges, tvb, offset, 4, num_ranges);
offset += 4;
for (j = 0; j < num_ranges; ++j){
offset = decode_id_range(tvb, tree, offset, ep_strdup_printf("ID range #%d", j+1));
if (offset == -1){
return;
}
}/*end for each range*/
}
}
void
decode_replication_response(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
if (tree){
guint32 num_rows;
guint32 i, k;
guint32 num_ranges;
num_rows = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(tree, hf_replication_num_rows, tvb, offset, 4, num_rows);
offset += 4;
for (i = 0; i < num_rows; ++i){
guint32 num_cols;
guint32 j;
num_cols = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(tree, hf_replication_num_cols, tvb, offset, 4, num_cols);
offset += 4;
for (j = 0; j < num_cols; ++j){
offset = decode_type_and_id(tvb, tree, offset);
if (offset == -1){
return;
}
}
}/*end for each rows*/
num_ranges = tvb_get_ntohl(tvb, offset);
proto_tree_add_uint(tree, hf_replication_num_ranges, tvb, offset, 4, num_ranges);
offset += 4;
for (k = 0; k < num_ranges; ++k){
offset = decode_id_range(tvb, tree, offset, ep_strdup_printf("ID range #%d", k+1));
if (offset == -1){
return;
}
}/*end for each range*/
}
}
static void
dissect_replication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti = NULL;
proto_tree *replication_tree = NULL;
const gchar *type_string = NULL;
guint16 type;
gint offset = 0;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Replication");
type = tvb_get_ntohs(tvb, offset);
type_string = val_to_str(type, replication_msg_type, "<Unknown type %d>");
if (check_col(pinfo->cinfo, COL_INFO)){
col_clear (pinfo->cinfo, COL_INFO);
col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d %s",
pinfo->srcport, pinfo->destport, type_string);
}
if (tree){
ti = proto_tree_add_item(tree, proto_replication, tvb, 0, -1, FALSE);
replication_tree = proto_item_add_subtree(ti, ett_replication);
proto_tree_add_item(replication_tree, hf_replication_type, tvb, offset, 2, FALSE);
proto_tree_add_item(replication_tree, hf_replication_version, tvb, offset + 2, 1, FALSE);
offset = decode_nodehandle(tvb, replication_tree, offset + 3 , "Source");
} else {
offset = get_node_handle_len(tvb, offset + 3);
}
if (offset == -1){
return;
}
switch (type){
case REP_REQUEST_MSG:
decode_replication_request(tvb, replication_tree, offset);
break;
case REP_RESPONSE_MSG:
decode_replication_response(tvb, replication_tree, offset);
break;
default:
return;/*stop dissection*/
}
}
void
proto_register_replication(void)
{
static hf_register_info hf[] = {
{ &hf_replication_type,
{ "Type", "replication.type",
FT_UINT16, BASE_DEC, VALS(replication_msg_type), 0x0,
"", HFILL }},
{ &hf_replication_version,
{ "Version", "replication.version",
FT_UINT8, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_replication_num_bloomfilters,
{ "Number of Bloom filters", "replication.num_bloomfilters",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_replication_num_ranges,
{ "Number of ID ranges", "replication.num_ranges",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_replication_num_rows,
{ "Number of rows", "replication.num_rows",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_replication_num_cols,
{ "Number of columns", "replication.num_cols",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_bloom_filter_length,
{ "Set lenght", "replication.bloomfilter.length",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_bloom_filter_num_params,
{ "Number of parameter", "replication.bloomfilter.num_params",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_bloom_filter_param,
{ "Parameter", "replication.bloomfilter.param",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_bloom_filter_num_bits,
{ "Number of bits", "replication.bloomfilter.num_bits",
FT_UINT32, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_bloom_filter_bits,
{ "Bits field", "replication.bloomfilter.bits",
FT_BYTES, BASE_HEX, NULL, 0x0,
"", HFILL }},
{ &hf_id_range_cw,
{ "Clockwise ID", "replication.idrange.cw",
FT_STRING, BASE_NONE, NULL, 0x0,
"", HFILL }},
{ &hf_id_range_ccw,
{ "Counter clockwise ID", "replication.idrange.ccw",
FT_STRING, BASE_NONE, NULL, 0x0,
"", HFILL }},
{ &hf_id_range_empty,
{ "Is empty", "replication.idrange.empty",
FT_BOOLEAN, 8, NULL, 0x0,
"", HFILL }},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_replication,
&ett_replication_bloomfilter,
&ett_replication_idrange
};
module_t *replication_module;
if (proto_replication == -1) {
proto_replication = proto_register_protocol (
"Replication Manager (Common API Application)", /* name */
"Replication", /* short name */
"replication" /* abbrev */
);
}
replication_module = prefs_register_protocol(proto_replication, NULL);
proto_register_field_array(proto_replication, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_replication(void)
{
static int Initialized=FALSE;
if (!Initialized) {
replication_handle = create_dissector_handle(dissect_replication, proto_replication);
dissector_add("commonapi.app", REPLICATION_SUB_ADDRESS, replication_handle);
}
}