mirror of
https://github.com/ChronosX88/FreePastry.git
synced 2024-12-04 15:22:18 +00:00
351 lines
11 KiB
C
351 lines
11 KiB
C
/* 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);
|
|
}
|
|
}
|