aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-drb.c
blob: 4bb39d30e264fca406d6045f4c6a132bd9ef13e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* packet-drb.c
 *
 * Routines for Ruby Marshal Object
 *
 * Copyright 2018, Dario Lombardo (lomato@gmail.com)
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "config.h"
#include <epan/packet.h>
#include <file-rbm.h>

static int proto_drb = -1;

static int hf_drb_len = -1;

static gint ett_drb = -1;
static gint ett_ref = -1;

void proto_register_drb(void);
void proto_reg_handoff_drb(void);

static void dissect_drb_object(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, gint* offset, const gchar* label)
{
	guint32 len;
	proto_tree* obj_tree;
	gchar* type;
	gchar* value;

	len = tvb_get_guint32(tvb, *offset, ENC_BIG_ENDIAN);
	obj_tree = proto_tree_add_subtree(tree, tvb, *offset, 4 + len, ett_ref, NULL, label);
	proto_tree_add_item(obj_tree, hf_drb_len, tvb, *offset, 4, ENC_NA);
	*offset += 4;
	dissect_rbm_inline(tvb, pinfo, obj_tree, offset, &type, &value);
	if (type)
		proto_item_append_text(obj_tree, "Type: %s", type);
	if (value)
		proto_item_append_text(obj_tree, "Value: %s", value);
}

static void dissect_drb_response(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, gint* offset)
{
	col_append_str(pinfo->cinfo, COL_INFO, " (response)");
	dissect_drb_object(tvb, pinfo, tree, offset, "Success");
	dissect_drb_object(tvb, pinfo, tree, offset, "Response");
}

static void dissect_drb_request(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, gint* offset)
{
	gint32 nargs;
	gint32 i;
	guint len;
	gchar* loop_label;

	col_append_str(pinfo->cinfo, COL_INFO, " (request)");
	dissect_drb_object(tvb, pinfo, tree, offset, "Ref");
	dissect_drb_object(tvb, pinfo, tree, offset, "Msg ID");
	get_rbm_integer(tvb, *offset + 4 + 3, &nargs, &len);
	dissect_drb_object(tvb, pinfo, tree, offset, "Arg length");
	for (i = 0; i < nargs; i++) {
		loop_label = wmem_strdup_printf(wmem_packet_scope(), "Arg %d", i + 1);
		dissect_drb_object(tvb, pinfo, tree, offset, loop_label);
	}
	dissect_drb_object(tvb, pinfo, tree, offset, "Block");
}

static int dissect_drb(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
{
	int offset = 0;
	proto_tree* ti;
	proto_tree* drb_tree;
	guint8 type;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRb");
	col_clear(pinfo->cinfo, COL_INFO);
	col_set_str(pinfo->cinfo, COL_INFO, "Distributed Ruby");

	ti = proto_tree_add_item(tree, proto_drb, tvb, 0, -1, ENC_NA);
	drb_tree = proto_item_add_subtree(ti, ett_drb);

	type = tvb_get_guint8(tvb, 6);
	if (type == 'T' || type == 'F') {
		dissect_drb_response(tvb, pinfo, drb_tree, &offset);
	} else {
		dissect_drb_request(tvb, pinfo, drb_tree, &offset);
	}

	return offset;
}

void proto_register_drb(void)
{
	static hf_register_info hf[] = {
		{ &hf_drb_len,
			{ "Length", "drb.length", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
		}
	};

	/* Setup protocol subtree array */
	static gint* ett[] = {
		&ett_drb,
		&ett_ref
	};

	proto_drb = proto_register_protocol("Distributed Ruby", "DRb", "drb");

	proto_register_field_array(proto_drb, hf, array_length(hf));
	proto_register_subtree_array(ett, array_length(ett));
}

void proto_reg_handoff_drb(void)
{
	dissector_handle_t drb_handle;

	drb_handle = create_dissector_handle(dissect_drb, proto_drb);
	dissector_add_for_decode_as_with_preference("tcp.port", drb_handle);
}

/*
 * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 8
 * tab-width: 8
 * indent-tabs-mode: t
 * End:
 *
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
 * :indentSize=8:tabSize=8:noTabs=false:
 */