2 * Routines for Bazaar packet dissection
3 * Copyright 2011, Jelmer Vernooij <jelmer@samba.org>
5 * http://doc.bazaar.canonical.com/developers/network-protocol.html
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * Copied from packet-pop.c
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
34 #include <epan/prefs.h>
35 #include "packet-tcp.h"
37 static int proto_bzr
= -1;
39 static gint ett_bzr
= -1;
40 static gint ett_prefixed_bencode
= -1;
41 static gint ett_prefixed_bytes
= -1;
43 static gint hf_bzr_prefixed_bencode
= -1;
44 static gint hf_bzr_prefixed_bencode_len
= -1;
45 static gint hf_bzr_prefixed_bencode_data
= -1;
46 static gint hf_bzr_bytes
= -1;
47 static gint hf_bzr_bytes_data
= -1;
48 static gint hf_bzr_bytes_length
= -1;
49 static gint hf_bzr_result
= -1;
50 static gint hf_bzr_packet_protocol_version
= -1;
51 static gint hf_bzr_packet_kind
= -1;
53 #define REQUEST_VERSION_TWO "bzr request 2\n"
54 #define RESPONSE_VERSION_TWO "bzr response 2\n"
55 #define MESSAGE_VERSION_THREE "bzr message 3 (bzr 1.6)\n"
57 #define TCP_PORT_BZR 4155
59 static const value_string message_part_kind
[] = {
67 static const value_string message_results
[] = {
73 /* desegmentation of Bazaar over TCP */
74 static gboolean bzr_desegment
= TRUE
;
76 static guint
get_bzr_prefixed_len(tvbuff_t
*tvb
, int offset
)
79 header_len
= tvb_get_ntohl(tvb
, offset
);
80 return 4 + header_len
;
84 get_bzr_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
)
88 gint protocol_version_len
;
91 /* Protocol version */
92 protocol_version_len
= tvb_find_line_end(tvb
, offset
, -1, &next_offset
,
94 if (protocol_version_len
== -1) /* End of the packet not seen yet */
97 len
+= protocol_version_len
+ 1;
100 len
+= get_bzr_prefixed_len(tvb
, next_offset
);
102 while (tvb_reported_length_remaining(tvb
, offset
+ len
) > 0) {
103 cmd
= tvb_get_guint8(tvb
, offset
+ len
);
109 len
+= get_bzr_prefixed_len(tvb
, offset
+ len
);
123 dissect_prefixed_bencode(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo _U_
,
127 proto_tree
*prefixed_bencode_tree
;
130 plen
= tvb_get_ntohl(tvb
, offset
);
132 ti
= proto_tree_add_item(tree
, hf_bzr_prefixed_bencode
, tvb
, offset
, 4 +
134 prefixed_bencode_tree
= proto_item_add_subtree(ti
, ett_prefixed_bencode
);
136 if (prefixed_bencode_tree
)
138 proto_tree_add_item(prefixed_bencode_tree
, hf_bzr_prefixed_bencode_len
,
139 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
141 proto_tree_add_item(prefixed_bencode_tree
, hf_bzr_prefixed_bencode_data
,
142 tvb
, offset
+4, plen
, ENC_NA
);
149 dissect_prefixed_bytes(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo _U_
,
153 proto_tree
*prefixed_bytes_tree
;
156 plen
= tvb_get_ntohl(tvb
, offset
);
158 ti
= proto_tree_add_item(tree
, hf_bzr_bytes
, tvb
, offset
, 4 +
160 prefixed_bytes_tree
= proto_item_add_subtree(ti
, ett_prefixed_bytes
);
162 if (prefixed_bytes_tree
)
164 proto_tree_add_item(prefixed_bytes_tree
, hf_bzr_bytes_length
,
165 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
167 proto_tree_add_item(prefixed_bytes_tree
, hf_bzr_bytes_data
,
168 tvb
, offset
+4, plen
, ENC_NA
);
175 dissect_body(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
, proto_tree
*tree
)
179 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
180 cmd
= tvb_get_guint8(tvb
, offset
);
181 proto_tree_add_item(tree
, hf_bzr_packet_kind
, tvb
, offset
, 1, ENC_NA
);
186 offset
+= dissect_prefixed_bencode(tvb
, offset
, pinfo
, tree
);
189 offset
+= dissect_prefixed_bytes(tvb
, offset
, pinfo
, tree
);
192 proto_tree_add_item(tree
, hf_bzr_result
, tvb
, offset
, 1,
205 dissect_bzr_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
207 proto_tree
*bzr_tree
;
210 gint protocol_version_len
;
212 ti
= proto_tree_add_item(tree
, proto_bzr
, tvb
, offset
, -1, ENC_NA
);
213 bzr_tree
= proto_item_add_subtree(ti
, ett_bzr
);
215 protocol_version_len
= tvb_find_line_end(tvb
, offset
, -1, &offset
, TRUE
);
216 if (protocol_version_len
== -1) /* Invalid packet */
221 proto_tree_add_item(bzr_tree
, hf_bzr_packet_protocol_version
, tvb
, 0,
222 protocol_version_len
+1, ENC_ASCII
|ENC_NA
);
225 offset
+= dissect_prefixed_bencode(tvb
, offset
, pinfo
, bzr_tree
);
226 /*offset +=*/ dissect_body(tvb
, offset
, pinfo
, bzr_tree
);
230 dissect_bzr(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
232 gint offset
= 0, pdu_len
;
235 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "BZR");
237 col_set_str(pinfo
->cinfo
, COL_INFO
, "Bazaar Smart Protocol");
239 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
240 pdu_len
= get_bzr_pdu_len(pinfo
, tvb
, offset
);
242 if (pinfo
->can_desegment
&& bzr_desegment
) {
243 pinfo
->desegment_offset
= offset
;
244 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
247 pdu_len
= tvb_reported_length_remaining(tvb
, offset
);
250 next_tvb
= tvb_new_subset(tvb
, offset
, pdu_len
, pdu_len
);
251 dissect_bzr_pdu(next_tvb
, pinfo
, tree
);
257 proto_register_bzr(void)
259 static hf_register_info hf
[] = {
260 { &hf_bzr_packet_kind
,
261 { "Packet kind", "bzr.kind", FT_UINT8
, BASE_DEC
,
262 VALS(message_part_kind
), 0x0, NULL
, HFILL
},
264 { &hf_bzr_packet_protocol_version
,
265 { "Protocol version", "bzr.protocol_version", FT_STRING
, BASE_NONE
,
266 NULL
, 0x0, NULL
, HFILL
},
268 { &hf_bzr_prefixed_bencode
,
269 { "Bencode packet", "bzr.bencode", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
270 "Serialized structure of integers, dictionaries, strings and "
273 { &hf_bzr_prefixed_bencode_len
,
274 { "Bencode packet length", "bzr.bencode.length", FT_UINT32
,
275 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
},
277 { &hf_bzr_prefixed_bencode_data
,
278 { "Bencode packet data", "bzr.bencode.data", FT_BYTES
, BASE_NONE
,
279 NULL
, 0x0, NULL
, HFILL
},
282 { "Prefixed bytes", "bzr.bytes", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
283 "Bytes field with prefixed 32-bit length", HFILL
},
285 { &hf_bzr_bytes_data
,
286 { "Prefixed bytes data", "bzr.bytes.data", FT_BYTES
, BASE_NONE
,
287 NULL
, 0x0, NULL
, HFILL
},
289 { &hf_bzr_bytes_length
,
290 { "Prefixed bytes length", "bzr.bytes.length", FT_UINT32
, BASE_HEX
,
291 NULL
, 0x0, NULL
, HFILL
},
294 { "Result", "bzr.result", FT_UINT8
, BASE_HEX
,
295 VALS(message_results
), 0x0,
296 "Command result (success or failure with error message)", HFILL
301 static gint
*ett
[] = {
303 &ett_prefixed_bencode
,
307 module_t
*bzr_module
;
308 proto_bzr
= proto_register_protocol("Bazaar Smart Protocol", "Bazaar", "bzr");
309 register_dissector("bzr", dissect_bzr
, proto_bzr
);
310 proto_register_field_array(proto_bzr
, hf
, array_length(hf
));
311 proto_register_subtree_array(ett
, array_length(ett
));
313 bzr_module
= prefs_register_protocol(proto_bzr
, NULL
);
315 prefs_register_bool_preference(bzr_module
, "desegment",
316 "Reassemble Bazaar messages spanning multiple TCP segments",
317 "Whether the Bazaar dissector should reassemble messages spanning multiple TCP segments."
318 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\""
319 " in the TCP protocol settings.",
324 proto_reg_handoff_bzr(void)
326 dissector_handle_t bzr_handle
;
328 bzr_handle
= find_dissector("bzr");
329 dissector_add_uint("tcp.port", TCP_PORT_BZR
, bzr_handle
);