2 * Routines for Bazaar packet dissection
3 * Copyright 2011,2013 Jelmer Vernooij <jelmer@samba.org>
5 * http://doc.bazaar.canonical.com/developers/network-protocol.html
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-pop.c
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
19 #include <epan/prefs.h>
21 void proto_register_bzr(void);
22 void proto_reg_handoff_bzr(void);
27 static int ett_prefixed_bencode
;
28 static int ett_prefixed_bytes
;
30 static int hf_bzr_prefixed_bencode
;
31 static int hf_bzr_prefixed_bencode_len
;
32 static int hf_bzr_bytes
;
33 static int hf_bzr_bytes_data
;
34 static int hf_bzr_bytes_length
;
35 static int hf_bzr_result
;
36 static int hf_bzr_packet_protocol_version
;
37 static int hf_bzr_packet_kind
;
39 static dissector_handle_t bencode_handle
;
40 static dissector_handle_t bzr_handle
;
42 #define REQUEST_VERSION_TWO "bzr request 2\n"
43 #define RESPONSE_VERSION_TWO "bzr response 2\n"
44 #define MESSAGE_VERSION_THREE "bzr message 3 (bzr 1.6)\n"
46 #define TCP_PORT_BZR 4155
48 static const value_string message_part_kind
[] = {
56 static const value_string message_results
[] = {
62 /* desegmentation of Bazaar over TCP */
63 static bool bzr_desegment
= true;
65 static unsigned get_bzr_prefixed_len(tvbuff_t
*tvb
, int offset
)
68 header_len
= tvb_get_ntohl(tvb
, offset
);
69 return 4 + header_len
;
73 get_bzr_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
)
76 int len
= 0, current_len
;
77 int protocol_version_len
;
80 /* Protocol version */
81 protocol_version_len
= tvb_find_line_end(tvb
, offset
, -1, &next_offset
,
83 if (protocol_version_len
== -1) /* End of the packet not seen yet */
86 len
+= protocol_version_len
+ 1;
90 len
+= get_bzr_prefixed_len(tvb
, next_offset
);
91 if (current_len
> len
) /* Make sure we're not going backwards */
94 while (tvb_reported_length_remaining(tvb
, offset
+ len
) > 0) {
95 cmd
= tvb_get_uint8(tvb
, offset
+ len
);
102 len
+= get_bzr_prefixed_len(tvb
, offset
+ len
);
103 if (current_len
> len
) /* Make sure we're not going backwards */
118 dissect_prefixed_bencode(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
122 proto_tree
*prefixed_bencode_tree
;
126 plen
= tvb_get_ntohl(tvb
, offset
);
128 ti
= proto_tree_add_item(tree
, hf_bzr_prefixed_bencode
, tvb
, offset
, -1,
130 prefixed_bencode_tree
= proto_item_add_subtree(ti
, ett_prefixed_bencode
);
132 proto_tree_add_item(prefixed_bencode_tree
, hf_bzr_prefixed_bencode_len
,
133 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
135 subtvb
= tvb_new_subset_length(tvb
, offset
+4, plen
);
136 call_dissector(bencode_handle
, subtvb
, pinfo
, prefixed_bencode_tree
);
138 proto_item_set_len(ti
, 4 + plen
);
144 dissect_prefixed_bytes(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
,
148 proto_tree
*prefixed_bytes_tree
;
151 plen
= tvb_get_ntohl(tvb
, offset
);
153 ti
= proto_tree_add_item(tree
, hf_bzr_bytes
, tvb
, offset
, -1, ENC_NA
);
154 prefixed_bytes_tree
= proto_item_add_subtree(ti
, ett_prefixed_bytes
);
156 proto_tree_add_item(prefixed_bytes_tree
, hf_bzr_bytes_length
,
157 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
159 proto_tree_add_item(prefixed_bytes_tree
, hf_bzr_bytes_data
,
160 tvb
, offset
+4, plen
, ENC_NA
);
162 proto_item_set_len(ti
, 4 + plen
);
168 dissect_body(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
)
172 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
173 cmd
= tvb_get_uint8(tvb
, offset
);
174 proto_tree_add_item(tree
, hf_bzr_packet_kind
, tvb
, offset
, 1, ENC_ASCII
|ENC_NA
);
179 offset
+= dissect_prefixed_bencode(tvb
, offset
, pinfo
, tree
);
182 offset
+= dissect_prefixed_bytes(tvb
, offset
, pinfo
, tree
);
185 proto_tree_add_item(tree
, hf_bzr_result
, tvb
, offset
, 1,
198 dissect_bzr_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
200 proto_tree
*bzr_tree
;
203 int protocol_version_len
;
205 ti
= proto_tree_add_item(tree
, proto_bzr
, tvb
, offset
, -1, ENC_NA
);
206 bzr_tree
= proto_item_add_subtree(ti
, ett_bzr
);
208 protocol_version_len
= tvb_find_line_end(tvb
, offset
, -1, &offset
, true);
209 if (protocol_version_len
== -1) /* Invalid packet */
214 proto_tree_add_item(bzr_tree
, hf_bzr_packet_protocol_version
, tvb
, 0,
215 protocol_version_len
+1, ENC_ASCII
);
218 offset
+= dissect_prefixed_bencode(tvb
, offset
, pinfo
, bzr_tree
);
219 /*offset +=*/ dissect_body(tvb
, offset
, pinfo
, bzr_tree
);
223 dissect_bzr(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
225 int offset
= 0, pdu_len
;
228 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "BZR");
230 col_set_str(pinfo
->cinfo
, COL_INFO
, "Bazaar Smart Protocol");
232 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
233 pdu_len
= get_bzr_pdu_len(pinfo
, tvb
, offset
);
235 if (pinfo
->can_desegment
&& bzr_desegment
) {
236 pinfo
->desegment_offset
= offset
;
237 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
238 return tvb_captured_length(tvb
);
240 pdu_len
= tvb_reported_length_remaining(tvb
, offset
);
243 next_tvb
= tvb_new_subset_length(tvb
, offset
, pdu_len
);
244 dissect_bzr_pdu(next_tvb
, pinfo
, tree
);
248 return tvb_captured_length(tvb
);
252 proto_register_bzr(void)
254 static hf_register_info hf
[] = {
255 { &hf_bzr_packet_kind
,
256 { "Packet kind", "bzr.kind", FT_CHAR
, BASE_HEX
,
257 VALS(message_part_kind
), 0x0, NULL
, HFILL
},
259 { &hf_bzr_packet_protocol_version
,
260 { "Protocol version", "bzr.protocol_version", FT_STRING
, BASE_NONE
,
261 NULL
, 0x0, NULL
, HFILL
},
263 { &hf_bzr_prefixed_bencode
,
264 { "Bencode packet", "bzr.bencode", FT_NONE
, BASE_NONE
, NULL
, 0x0,
265 "Serialized structure of integers, dictionaries, strings and "
268 { &hf_bzr_prefixed_bencode_len
,
269 { "Bencode packet length", "bzr.bencode.length", FT_UINT32
,
270 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
},
273 { "Prefixed bytes", "bzr.bytes", FT_NONE
, BASE_NONE
, NULL
, 0x0,
274 "Bytes field with prefixed 32-bit length", HFILL
},
276 { &hf_bzr_bytes_data
,
277 { "Prefixed bytes data", "bzr.bytes.data", FT_BYTES
, BASE_NONE
,
278 NULL
, 0x0, NULL
, HFILL
},
280 { &hf_bzr_bytes_length
,
281 { "Prefixed bytes length", "bzr.bytes.length", FT_UINT32
, BASE_HEX
,
282 NULL
, 0x0, NULL
, HFILL
},
285 { "Result", "bzr.result", FT_CHAR
, BASE_HEX
,
286 VALS(message_results
), 0x0,
287 "Command result (success or failure with error message)", HFILL
292 static int *ett
[] = {
294 &ett_prefixed_bencode
,
298 module_t
*bzr_module
;
299 proto_bzr
= proto_register_protocol("Bazaar Smart Protocol", "Bazaar", "bzr");
300 bzr_handle
= register_dissector("bzr", dissect_bzr
, proto_bzr
);
301 proto_register_field_array(proto_bzr
, hf
, array_length(hf
));
302 proto_register_subtree_array(ett
, array_length(ett
));
304 bzr_module
= prefs_register_protocol(proto_bzr
, NULL
);
306 prefs_register_bool_preference(bzr_module
, "desegment",
307 "Reassemble Bazaar messages spanning multiple TCP segments",
308 "Whether the Bazaar dissector should reassemble messages spanning multiple TCP segments."
309 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\""
310 " in the TCP protocol settings.",
315 proto_reg_handoff_bzr(void)
317 bencode_handle
= find_dissector_add_dependency("bencode", proto_bzr
);
319 dissector_add_uint_with_preference("tcp.port", TCP_PORT_BZR
, bzr_handle
);
323 * Editor modelines - https://www.wireshark.org/tools/modelines.html
328 * indent-tabs-mode: nil
331 * vi: set shiftwidth=4 tabstop=8 expandtab:
332 * :indentSize=4:tabSize=8:noTabs=true: