2 * Routines for bittorrent packet dissection
3 * Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Copied from packet-pop.c
11 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/prefs.h>
18 #include <epan/strutil.h>
20 #include "packet-tcp.h"
21 #include "packet-bt-utp.h"
23 void proto_register_bittorrent(void);
24 void proto_reg_handoff_bittorrent(void);
29 * http://bittorrent.com/protocol.html
30 * http://wiki.theory.org/BitTorrentSpecification
31 * http://bitconjurer.org/BitTorrent/protocol.html
34 #define DEFAULT_TCP_PORT_RANGE "6881-6889" /* Not IANA registered */
36 #define BITTORRENT_MESSAGE_CHOKE 0
37 #define BITTORRENT_MESSAGE_UNCHOKE 1
38 #define BITTORRENT_MESSAGE_INTERESTED 2
39 #define BITTORRENT_MESSAGE_NOT_INTERESTED 3
40 #define BITTORRENT_MESSAGE_HAVE 4
41 #define BITTORRENT_MESSAGE_BITFIELD 5
42 #define BITTORRENT_MESSAGE_REQUEST 6
43 #define BITTORRENT_MESSAGE_PIECE 7
44 #define BITTORRENT_MESSAGE_CANCEL 8
45 #define BITTORRENT_MESSAGE_PORT 9
48 * Fast Extension message type
51 #define BITT_FAST_EX_SUGGEST_PIECE 13
52 #define BITT_FAST_EX_HAVE_ALL 14
53 #define BITT_FAST_EX_HAVE_NONE 15
54 #define BITT_FAST_EX_REJECT_REQUEST 16
55 #define BITT_FAST_EX_ALLOWED_FAST 17
56 #define BITTORRENT_MESSAGE_EXTENDED 20
58 #define BITTORRENT_HEADER_LENGTH 4
61 * Azureus messages are specified by name so these are made up numbers
62 * for internal identification only.
64 * Standard BT message types are a single byte, so these won't clash
66 #define AZUREUS_MESSAGE_HANDSHAKE 256
67 #define AZUREUS_MESSAGE_KEEP_ALIVE 257
68 #define AZUREUS_MESSAGE_BT_HANDSHAKE 258
69 #define AZUREUS_MESSAGE_PEER_EXCHANGE 259
70 #define AZUREUS_MESSAGE_JPC_HELLO 260
71 #define AZUREUS_MESSAGE_JPC_REPLY 261
74 static const value_string bittorrent_messages
[] = {
75 { BITTORRENT_MESSAGE_CHOKE
, "Choke" },
76 { BITTORRENT_MESSAGE_UNCHOKE
, "Unchoke" },
77 { BITTORRENT_MESSAGE_INTERESTED
, "Interested" },
78 { BITTORRENT_MESSAGE_NOT_INTERESTED
, "Not Interested" },
79 { BITTORRENT_MESSAGE_HAVE
, "Have" },
80 { BITTORRENT_MESSAGE_BITFIELD
, "Bitfield" },
81 { BITTORRENT_MESSAGE_REQUEST
, "Request" },
82 { BITTORRENT_MESSAGE_PIECE
, "Piece" },
83 { BITTORRENT_MESSAGE_CANCEL
, "Cancel" },
84 { BITTORRENT_MESSAGE_PORT
, "Port" },
85 { BITT_FAST_EX_SUGGEST_PIECE
, "Suggest Piece" },
86 { BITT_FAST_EX_HAVE_ALL
, "Have All" },
87 { BITT_FAST_EX_HAVE_NONE
, "Have None" },
88 { BITT_FAST_EX_REJECT_REQUEST
, "Reject Request" },
89 { BITT_FAST_EX_ALLOWED_FAST
, "Allowed Fast" },
90 { BITTORRENT_MESSAGE_EXTENDED
, "Extended" },
91 { AZUREUS_MESSAGE_KEEP_ALIVE
, "Keepalive" },
92 { AZUREUS_MESSAGE_HANDSHAKE
, "Azureus Handshake" },
93 { AZUREUS_MESSAGE_BT_HANDSHAKE
, "Azureus BitTorrent Handshake" },
94 { AZUREUS_MESSAGE_PEER_EXCHANGE
, "Azureus Peer Exchange" },
95 { AZUREUS_MESSAGE_JPC_HELLO
, "Azureus PeerCache Hello" },
96 { AZUREUS_MESSAGE_JPC_REPLY
, "Azureus PeerCache Reply" },
100 static const value_string azureus_priorities
[] = {
113 static const struct amp_message amp_messages
[] = {
114 { "BT_KEEP_ALIVE", AZUREUS_MESSAGE_KEEP_ALIVE
},
115 { "BT_CHOKE", BITTORRENT_MESSAGE_CHOKE
},
116 { "BT_UNCHOKE", BITTORRENT_MESSAGE_UNCHOKE
},
117 { "BT_INTERESTED", BITTORRENT_MESSAGE_INTERESTED
},
118 { "BT_UNINTERESTED", BITTORRENT_MESSAGE_NOT_INTERESTED
},
119 { "BT_HAVE", BITTORRENT_MESSAGE_HAVE
},
120 { "BT_BITFIELD", BITTORRENT_MESSAGE_BITFIELD
},
121 { "BT_REQUEST", BITTORRENT_MESSAGE_REQUEST
},
122 { "BT_PIECE", BITTORRENT_MESSAGE_PIECE
},
123 { "BT_CANCEL", BITTORRENT_MESSAGE_CANCEL
},
124 { "BT_PORT", BITTORRENT_MESSAGE_PORT
},
125 { "BT_SUGGEST", BITT_FAST_EX_SUGGEST_PIECE
},
126 { "BT_HAVE_ALL", BITT_FAST_EX_HAVE_ALL
},
127 { "BT_HAVE_NONE", BITT_FAST_EX_HAVE_NONE
},
128 { "BT_REJECT_REQUEST",BITT_FAST_EX_REJECT_REQUEST
},
129 { "BT_ALLOWED_FAST", BITT_FAST_EX_ALLOWED_FAST
},
130 { "BT_EXTENDED", BITTORRENT_MESSAGE_EXTENDED
},
131 { "AZ_HANDSHAKE", AZUREUS_MESSAGE_HANDSHAKE
},
132 { "BT_HANDSHAKE", AZUREUS_MESSAGE_BT_HANDSHAKE
},
133 { "AZ_PEER_EXCHANGE", AZUREUS_MESSAGE_PEER_EXCHANGE
},
134 { "JPC_HELLO", AZUREUS_MESSAGE_JPC_HELLO
},
135 { "JPC_REPLY", AZUREUS_MESSAGE_JPC_REPLY
},
139 static dissector_handle_t dissector_handle
;
140 static dissector_handle_t bencode_handle
;
141 static int proto_bittorrent
;
143 /* static int hf_bittorrent_field_length; */
144 static int hf_bittorrent_prot_name_len
;
145 static int hf_bittorrent_prot_name
;
146 static int hf_bittorrent_reserved
;
147 static int hf_bittorrent_sha1_hash
;
148 static int hf_bittorrent_peer_id
;
149 static int hf_bittorrent_msg
;
150 static int hf_bittorrent_msg_len
;
151 static int hf_bittorrent_msg_type
;
152 static int hf_azureus_msg
;
153 static int hf_azureus_msg_type_len
;
154 static int hf_azureus_msg_type
;
155 static int hf_azureus_msg_prio
;
156 static int hf_bittorrent_bitfield_data
;
157 static int hf_bittorrent_piece_index
;
158 static int hf_bittorrent_piece_begin
;
159 static int hf_bittorrent_piece_length
;
160 static int hf_bittorrent_piece_data
;
161 static int hf_azureus_jpc_addrlen
;
162 static int hf_azureus_jpc_addr
;
163 static int hf_azureus_jpc_port
;
164 static int hf_azureus_jpc_session
;
165 static int hf_bittorrent_port
;
166 static int hf_bittorrent_extended_id
;
167 static int hf_bittorrent_extended
;
168 static int hf_bittorrent_continuous_data
;
169 static int hf_bittorrent_version
;
171 static int ett_bittorrent
;
172 static int ett_bittorrent_msg
;
173 static int ett_peer_id
;
175 static bool bittorrent_desegment
= true;
176 static bool decode_client_information
;
178 struct client_information
{
179 char id
[5]; /* string length must be <= 4 to allow space for NUL termination byte */
181 const char *name
; /* NULL means array entry terminates the array */
184 static struct client_information peer_id
[] = {
187 {"-AR", 4, "Arctic"},
188 {"-AT", 4, "Artemis"},
189 {"-AV", 4, "Avicora"},
190 {"-AX", 4, "BitPump"},
191 {"-AZ", 4, "Azureus"},
192 {"-BB", 4, "BitBuddy"},
193 {"-BC", 4, "BitComet"},
194 {"-BF", 4, "Bitflu"},
195 {"-BG", 4, "BTG (uses Rasterbar libtorrent)"},
196 {"-BOW", 3, "Bits on Wheels"},
197 {"-BP", 4, "BitTorrent Pro (Azereus + spyware)"},
198 {"-BR", 4, "BitRocket"},
199 {"-BS", 4, "BTSlave"},
200 {"-BW", 4, "BitWombat"},
201 {"-BX", 4, "Bittorrent X"},
202 {"-CD", 4, "Enhanced CTorrent"},
203 {"-CT", 4, "CTorrent"},
204 {"-DE", 4, "DelugeTorrent"},
205 {"-DP", 4, "Propagate Data Client"},
207 {"-ES", 4, "electric sheep"},
208 {"-FC", 4, "FileCroc"},
209 {"-FG", 4, "FlashGet"},
210 {"-FT", 4, "FoxTorrent"},
211 {"-GS", 4, "GSTorrent"},
212 {"-HK", 4, "Hekate"},
213 {"-HL", 4, "Halite"},
214 {"-HN", 4, "Hydranode"},
216 {"-KT", 4, "KTorrent"},
217 {"-LC", 4, "LeechCraft"},
218 {"-LH", 4, "LH-ABC"},
219 {"-LP", 4, "Lphant"},
220 {"-LT", 4, "libtorrent"},
221 {"-lt", 4, "libTorrent"},
222 {"-LW", 4, "LimeWire"},
223 {"-MO", 4, "MonoTorrent"},
224 {"-MP", 4, "MooPolice"},
226 {"-MT", 4, "MoonlightTorrent"},
227 {"-NE", 4, "BT Next Evolution"},
228 {"-NX", 4, "Net Transport"},
229 {"-OS", 4, "OneSwarm"},
230 {"-OT", 4, "OmegaTorrent"},
232 {"-qB", 4, "qBittorrent"},
233 {"-QD", 4, "QQDownload"},
234 {"-QT", 4, "Qt 4 Torrent example"},
235 {"-RT", 4, "Retriever"},
236 {"-S~", 4, "Shareaza alpha/beta"},
237 {"-SB", 4, "Swiftbit"},
238 {"-SD", 4, "Thunder (aka XunLei)"},
239 {"-SS", 4, "SwarmScope"},
240 {"-ST", 4, "SymTorrent"},
241 {"-st", 4, "sharktorrent"},
242 {"-SZ", 4, "Shareaza"},
243 {"-TN", 4, "TorrentDotNET"},
244 {"-TR", 4, "Transmission"},
245 {"-TS", 4, "Torrentstorm"},
247 {"-UL", 4, "uLeecher!"},
248 {"-UM", 4, "(my)Torrent for Mac"},
249 {"-UT", 4, "(my)Torrent"},
251 {"-WT", 4, "BitLet"},
252 {"-WY", 4, "FireTorrent"},
253 {"-XL", 4, "Xunlei"},
254 {"-XT", 4, "XanTorrent"},
255 {"-XX", 4, "Xtorrent"},
256 {"-ZT", 4, "ZipTorrent"},
257 {"exbc", 2, "BitComet"},
260 {"XBT", 3, "XBT Client"},
262 {"O", 3, "Osprey Permaseed"},
265 {"S", 3, "Shadow's client"},
266 {"T", 3, "BitTornado"},
267 {"U", 3, "UPnP NAT Bit Torrent"},
271 /* Tests a given length for a message type to see if it looks valid.
272 * The exact length is known for many message types, which prevents us
273 * from returning a false positive match based on a single byte when
274 * we're in the middle of Continuation Data or an encrypted transfer.
277 test_type_length(uint16_t type
, uint32_t length
)
281 case BITTORRENT_MESSAGE_UNCHOKE
:
282 case BITTORRENT_MESSAGE_INTERESTED
:
283 case BITTORRENT_MESSAGE_NOT_INTERESTED
:
284 case BITT_FAST_EX_HAVE_ALL
:
285 case BITT_FAST_EX_HAVE_NONE
:
292 case BITTORRENT_MESSAGE_PORT
:
298 case BITTORRENT_MESSAGE_HAVE
:
299 case BITT_FAST_EX_SUGGEST_PIECE
:
300 case BITT_FAST_EX_ALLOWED_FAST
:
306 case BITTORRENT_MESSAGE_REQUEST
:
307 case BITTORRENT_MESSAGE_CANCEL
:
308 case BITT_FAST_EX_REJECT_REQUEST
:
314 /* Now to the messages that can have variable and longer lengths. */
316 case BITTORRENT_MESSAGE_EXTENDED
:
317 case BITTORRENT_MESSAGE_PIECE
:
318 /* All known implementations use 0x4000 for the piece length by default
319 * (only smaller for the last piece at EOF), and disconnect from clients
320 * that use a larger value, which is mentioned in BEP-3. Including the
321 * other parts of the message, that yields a length of 0x4009. There
322 * might exist some non-standard traffic somewhere, I suppose.
324 * This is excessively long for any extension message.
326 if (length
> 0x4009) {
331 case BITTORRENT_MESSAGE_CHOKE
:
332 /* Choke could be an Azureus message instead, which could be any
333 * of the other messages, so it has to be as long as our longest
334 * message. XXX: To reduce false positives (since 0 is a common
335 * byte to see), a pref to disable Azureus support could be useful.
336 * Alternatively, if we tracked conversations, we could disable
337 * support for AMP if the extension bits in the handshake (if seen)
338 * indicated that it's not supported.
340 case AZUREUS_MESSAGE_HANDSHAKE
:
341 case AZUREUS_MESSAGE_KEEP_ALIVE
:
342 case AZUREUS_MESSAGE_BT_HANDSHAKE
:
343 case AZUREUS_MESSAGE_PEER_EXCHANGE
:
344 case AZUREUS_MESSAGE_JPC_HELLO
:
345 case AZUREUS_MESSAGE_JPC_REPLY
:
346 case BITTORRENT_MESSAGE_BITFIELD
:
347 /* A bitfield length is N bits, where N is the number of pieces
348 * in the torrent. The absolute boundary is 2^32 pieces (because
349 * it has to fit in the piece message). In practice the piece
350 * length varies to balance a number of factors. (Some clients
351 * don't work with too many pieces; at one point 2^16 was a common
352 * maximum.) The minimum common piece length is 2^18 bytes, and higher
353 * powers of two are also frequently used.
355 * 0x20000 allows 0x100000 pieces, or over a million. That's more
356 * than most clients support, and cuts down on false positives.
358 if (length
> 0x20000) {
364 if (!try_val_to_str(type
, bittorrent_messages
)) {
373 get_bittorrent_pdu_length(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
374 int offset
, void *data _U_
)
379 if (tvb_get_uint8(tvb
, offset
) == 19 &&
380 tvb_memeql(tvb
, offset
+ 1, (const uint8_t*)"BitTorrent protocol", 19) == 0) {
381 /* Return the length of a Handshake message */
382 return 1 + /* pstrlen */
385 20 + /* SHA1 hash of the info key */
388 /* Try to validate the length of the message indicated by the header. */
389 length
= tvb_get_ntohl(tvb
, offset
);
391 /* keep-alive - no message ID */
392 return BITTORRENT_HEADER_LENGTH
;
394 /* Do some sanity checking of the message, if we have the ID byte */
395 if(tvb_offset_exists(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
)) {
396 type
= tvb_get_uint8(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
);
397 if (test_type_length(type
, length
)) {
398 /* This seems to be a valid BitTorrent header with a known
399 type identifier and valid length */
400 return BITTORRENT_HEADER_LENGTH
+ length
;
402 /* The type is not known, so this message cannot be decoded
403 properly by this dissector. We assume it's continuation
404 data from the middle of a message, and just return the
405 remaining length in the tvbuff so the rest of the tvbuff
406 is displayed as continuation data. */
407 return tvb_reported_length_remaining(tvb
, offset
);
410 /* We don't have the type field, so we can't determine
411 whether this is a valid message. Return 0, which
412 tcp_dissect_pdus (and utp_dissect_pdus) treats as
413 "variable length, needs one more segment". */
420 dissect_bittorrent_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
427 uint32_t typelen
= 0;
431 const char *msgtype
= NULL
;
433 uint32_t piece_index
, piece_begin
, piece_length
;
437 /* Guaranteed BITTORRENT_HEADER_LENGTH by tcp_dissect_pdus */
438 length
= tvb_get_ntohl(tvb
, offset
);
440 /* Keepalive message */
442 ti
= proto_tree_add_item(tree
, hf_bittorrent_msg
, tvb
, offset
, length
+ BITTORRENT_HEADER_LENGTH
, ENC_NA
);
443 mtree
= proto_item_add_subtree(ti
, ett_bittorrent_msg
);
444 proto_tree_add_item(mtree
, hf_bittorrent_msg_len
, tvb
, offset
, BITTORRENT_HEADER_LENGTH
, ENC_BIG_ENDIAN
);
445 col_set_str(pinfo
->cinfo
, COL_INFO
, "KeepAlive");
449 if (tvb_bytes_exist(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
, 1)) {
450 /* Check for data from the middle of a message. */
451 type
= tvb_get_uint8(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
);
453 if (type
==BITTORRENT_MESSAGE_CHOKE
&& length
>4) {
455 * Choke messages have no payload, so this is likely an Azureus
456 * Messaging Protocol packet
458 if (!tvb_bytes_exist(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
, 4))
461 typelen
= tvb_get_ntohl(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
);
462 if (4+typelen
+1<=length
) {
463 if (!tvb_bytes_exist(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
+ 4, typelen
+1))
466 for ( i
=0 ; amp_messages
[i
].name
; i
++ ) {
467 if (strlen(amp_messages
[i
].name
)==typelen
&&
468 tvb_memeql(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
+ 4,
469 amp_messages
[i
].name
, (int)strlen(amp_messages
[i
].name
))==0) {
471 prio
= tvb_get_uint8(tvb
, offset
+ BITTORRENT_HEADER_LENGTH
+ 4 + typelen
);
472 if (prio
==0 || prio
==1 || prio
==2) {
473 type
= amp_messages
[i
].value
;
482 msgtype
= try_val_to_str(type
, bittorrent_messages
);
484 if (msgtype
== NULL
&& isamp
) {
485 msgtype
= try_val_to_str(type
, azureus_messages
);
488 if (msgtype
== NULL
|| !(test_type_length(type
, length
))) {
489 /* In modern captures, this is likely Protocol Encryption/
490 * Message Stream Encryption, particularly if we're actually
491 * desegmenting and have the whole connection starting from
492 * the SYN. We don't try to do that yet.
494 proto_tree_add_item(tree
, hf_bittorrent_continuous_data
, tvb
, offset
, -1, ENC_NA
);
495 col_set_str(pinfo
->cinfo
, COL_INFO
, "Continuation data");
499 /* not enough bytes of the header, stop here */
504 ti
= proto_tree_add_item(tree
, hf_azureus_msg
, tvb
, offset
, length
+ BITTORRENT_HEADER_LENGTH
, ENC_NA
);
506 ti
= proto_tree_add_item(tree
, hf_bittorrent_msg
, tvb
, offset
, length
+ BITTORRENT_HEADER_LENGTH
, ENC_NA
);
508 mtree
= proto_item_add_subtree(ti
, ett_bittorrent_msg
);
510 proto_tree_add_item(mtree
, hf_bittorrent_msg_len
, tvb
, offset
, BITTORRENT_HEADER_LENGTH
, ENC_BIG_ENDIAN
);
511 offset
+= BITTORRENT_HEADER_LENGTH
;
513 /* If the tvb_bytes_exist() call above returned false, this will
514 throw an exception, so we won't use msgtype or type. */
516 proto_tree_add_item(mtree
, hf_azureus_msg_type_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
517 proto_tree_add_item(mtree
, hf_azureus_msg_type
, tvb
, offset
+4, typelen
, ENC_ASCII
);
518 proto_item_append_text(ti
, ": Len %u, %s", length
, msgtype
);
519 proto_tree_add_item(mtree
, hf_azureus_msg_prio
, tvb
, offset
+4+typelen
, 1, ENC_BIG_ENDIAN
);
520 offset
+= 4+typelen
+1;
521 length
-= 4+typelen
+1;
523 proto_tree_add_item(mtree
, hf_bittorrent_msg_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
524 proto_item_append_text(ti
, ": Len:%u, %s", length
, msgtype
);
528 col_set_str(pinfo
->cinfo
, COL_INFO
, msgtype
);
531 case BITTORRENT_MESSAGE_CHOKE
:
532 case BITTORRENT_MESSAGE_UNCHOKE
:
533 case BITTORRENT_MESSAGE_INTERESTED
:
534 case BITTORRENT_MESSAGE_NOT_INTERESTED
:
535 case BITT_FAST_EX_HAVE_ALL
:
536 case BITT_FAST_EX_HAVE_NONE
:
540 case BITTORRENT_MESSAGE_REQUEST
:
541 case BITTORRENT_MESSAGE_CANCEL
:
542 case BITT_FAST_EX_REJECT_REQUEST
:
543 piece_index
= tvb_get_ntohl(tvb
, offset
);
544 proto_tree_add_uint(mtree
, hf_bittorrent_piece_index
, tvb
, offset
, 4, piece_index
); offset
+= 4;
545 piece_begin
= tvb_get_ntohl(tvb
, offset
);
546 proto_tree_add_uint(mtree
, hf_bittorrent_piece_begin
, tvb
, offset
, 4, piece_begin
); offset
+= 4;
547 piece_length
= tvb_get_ntohl(tvb
, offset
);
548 proto_tree_add_uint(mtree
, hf_bittorrent_piece_length
, tvb
, offset
, 4, piece_length
);
549 proto_item_append_text(ti
, ", Piece (Idx:0x%x,Begin:0x%x,Len:0x%x)", piece_index
, piece_begin
, piece_length
);
551 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Piece (Idx:0x%x,Begin:0x%x,Len:0x%x)", piece_index
, piece_begin
, piece_length
);
555 case BITTORRENT_MESSAGE_PORT
:
556 /* port as payload */
557 proto_tree_add_item(mtree
, hf_bittorrent_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
560 case BITTORRENT_MESSAGE_EXTENDED
:
561 /* extended message content */
562 proto_tree_add_item_ret_uint(mtree
, hf_bittorrent_extended_id
, tvb
, offset
, 1, ENC_NA
, &ext_id
);
566 call_dissector(bencode_handle
, tvb_new_subset_length(tvb
, offset
, length
), pinfo
, mtree
);
568 proto_tree_add_item(mtree
, hf_bittorrent_extended
, tvb
, offset
, length
, ENC_NA
);
572 case BITTORRENT_MESSAGE_HAVE
:
573 case BITT_FAST_EX_SUGGEST_PIECE
:
574 case BITT_FAST_EX_ALLOWED_FAST
:
575 piece_index
= tvb_get_ntohl(tvb
, offset
);
576 proto_tree_add_item(mtree
, hf_bittorrent_piece_index
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
577 proto_item_append_text(ti
, ", Piece (Idx:0x%x)", piece_index
);
579 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Piece (Idx:0x%x)", piece_index
);
583 case BITTORRENT_MESSAGE_BITFIELD
:
584 proto_tree_add_item(mtree
, hf_bittorrent_bitfield_data
, tvb
, offset
, length
, ENC_NA
);
585 proto_item_append_text(ti
, ", Len:0x%x", length
);
586 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Len:0x%x", length
);
590 case BITTORRENT_MESSAGE_PIECE
:
591 piece_index
= tvb_get_ntohl(tvb
, offset
);
592 proto_tree_add_uint(mtree
, hf_bittorrent_piece_index
, tvb
, offset
, 4, piece_index
);
595 piece_begin
= tvb_get_ntohl(tvb
, offset
);
596 proto_tree_add_uint(mtree
, hf_bittorrent_piece_begin
, tvb
, offset
, 4, piece_begin
);
599 proto_tree_add_item(mtree
, hf_bittorrent_piece_data
, tvb
, offset
, length
, ENC_NA
);
600 proto_item_append_text(ti
, ", Idx:0x%x,Begin:0x%x,Len:0x%x", piece_index
, piece_begin
, length
);
601 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Idx:0x%x,Begin:0x%x,Len:0x%x", piece_index
, piece_begin
, length
);
605 case AZUREUS_MESSAGE_HANDSHAKE
:
606 case AZUREUS_MESSAGE_PEER_EXCHANGE
:
607 subtvb
= tvb_new_subset_length(tvb
, offset
, length
);
608 call_dissector(bencode_handle
, subtvb
, pinfo
, mtree
);
611 case AZUREUS_MESSAGE_JPC_HELLO
:
612 stringlen
= tvb_get_ntohl(tvb
, offset
);
613 proto_tree_add_item(mtree
, hf_azureus_jpc_addrlen
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
614 proto_tree_add_item(mtree
, hf_azureus_jpc_addr
, tvb
, offset
+4, stringlen
, ENC_ASCII
);
615 proto_tree_add_item(mtree
, hf_azureus_jpc_port
, tvb
, offset
+4+stringlen
, 4, ENC_BIG_ENDIAN
);
616 proto_tree_add_item(mtree
, hf_azureus_jpc_session
, tvb
, offset
+4+stringlen
+4, 4, ENC_BIG_ENDIAN
);
619 case AZUREUS_MESSAGE_JPC_REPLY
:
620 proto_tree_add_item(mtree
, hf_azureus_jpc_session
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
629 dissect_bittorrent_welcome (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
635 col_set_str(pinfo
->cinfo
, COL_INFO
, "Handshake");
637 proto_tree_add_item(tree
, hf_bittorrent_prot_name_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
); offset
+=1;
638 proto_tree_add_item(tree
, hf_bittorrent_prot_name
, tvb
, offset
, 19, ENC_ASCII
); offset
+= 19;
639 proto_tree_add_item(tree
, hf_bittorrent_reserved
, tvb
, offset
, 8, ENC_NA
); offset
+= 8;
641 proto_tree_add_item(tree
, hf_bittorrent_sha1_hash
, tvb
, offset
, 20, ENC_NA
);
644 proto_tree_add_item(tree
, hf_bittorrent_peer_id
, tvb
, offset
, 20, ENC_NA
);
645 if(decode_client_information
) {
646 for(i
= 0; peer_id
[i
].name
!= NULL
; ++i
)
648 if(tvb_memeql(tvb
, offset
, (const uint8_t*)peer_id
[i
].id
, (int)strlen(peer_id
[i
].id
)) == 0) {
649 version
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ (int)strlen(peer_id
[i
].id
),
650 peer_id
[i
].ver_len
, ENC_ASCII
);
651 proto_tree_add_string_format(tree
, hf_bittorrent_version
, tvb
, offset
, 20, version
, "Client is %s v%s",
652 peer_id
[i
].name
, format_text(pinfo
->pool
, (unsigned char*)version
, peer_id
[i
].ver_len
));
662 int dissect_bittorrent_tcp_pdu (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
666 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "BitTorrent");
668 col_set_str(pinfo
->cinfo
, COL_INFO
, "BitTorrent ");
670 ti
= proto_tree_add_item (tree
, proto_bittorrent
, tvb
, 0, -1, ENC_NA
);
671 tree
= proto_item_add_subtree(ti
, ett_bittorrent
);
673 if (tvb_get_uint8(tvb
, 0) == 19 &&
674 tvb_memeql(tvb
, 1, (const uint8_t*)"BitTorrent protocol", 19) == 0) {
675 dissect_bittorrent_welcome(tvb
, pinfo
, tree
);
677 dissect_bittorrent_message(tvb
, pinfo
, tree
);
680 col_append_str(pinfo
->cinfo
, COL_INFO
, " ");
681 col_set_fence(pinfo
->cinfo
, COL_INFO
);
683 return tvb_reported_length(tvb
);
687 int dissect_bittorrent (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
689 tcp_dissect_pdus(tvb
, pinfo
, tree
, bittorrent_desegment
, BITTORRENT_HEADER_LENGTH
,
690 get_bittorrent_pdu_length
, dissect_bittorrent_tcp_pdu
, data
);
691 return tvb_reported_length(tvb
);
695 int dissect_bittorrent_utp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
697 utp_dissect_pdus(tvb
, pinfo
, tree
, bittorrent_desegment
, BITTORRENT_HEADER_LENGTH
,
698 get_bittorrent_pdu_length
, dissect_bittorrent_tcp_pdu
, data
);
699 return tvb_reported_length(tvb
);
703 bool test_bittorrent_packet (tvbuff_t
*tvb
, packet_info
*pinfo
,
704 proto_tree
*tree
, void *data
)
706 conversation_t
*conversation
;
708 if (tvb_captured_length(tvb
) >= 20 &&
709 tvb_get_uint8(tvb
, 0) == 19 &&
710 tvb_memeql(tvb
, 1, (const uint8_t*)"BitTorrent protocol", 19) == 0) {
711 conversation
= find_or_create_conversation(pinfo
);
712 conversation_set_dissector(conversation
, dissector_handle
);
714 dissect_bittorrent(tvb
, pinfo
, tree
, data
);
723 proto_register_bittorrent(void)
725 static hf_register_info hf
[] = {
727 { &hf_bittorrent_field_length
,
728 { "Field Length", "bittorrent.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
731 { &hf_bittorrent_prot_name_len
,
732 { "Protocol Name Length", "bittorrent.protocol.name.length", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
734 { &hf_bittorrent_prot_name
,
735 { "Protocol Name", "bittorrent.protocol.name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
737 { &hf_bittorrent_reserved
,
738 { "Reserved Extension Bytes", "bittorrent.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
740 { &hf_bittorrent_sha1_hash
,
741 { "SHA1 Hash of info dictionary", "bittorrent.info_hash", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
743 { &hf_bittorrent_peer_id
,
744 { "Peer ID", "bittorrent.peer_id", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
746 { &hf_bittorrent_msg
,
747 { "Message", "bittorrent.msg", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
749 { &hf_bittorrent_msg_len
,
750 { "Message Length", "bittorrent.msg.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
752 { &hf_bittorrent_msg_type
,
753 { "Message Type", "bittorrent.msg.type", FT_UINT8
, BASE_DEC
, VALS(bittorrent_messages
), 0x0, NULL
, HFILL
}
756 { "Azureus Message", "bittorrent.azureus_msg", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
758 { &hf_azureus_msg_type_len
,
759 { "Message Type Length", "bittorrent.msg.typelen", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
761 { &hf_azureus_msg_type
,
762 { "Message Type", "bittorrent.msg.aztype", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
764 { &hf_azureus_msg_prio
,
765 { "Message Priority", "bittorrent.msg.prio", FT_UINT8
, BASE_DEC
, VALS(azureus_priorities
), 0x0, NULL
, HFILL
}
767 { &hf_bittorrent_bitfield_data
,
768 { "Bitfield data", "bittorrent.msg.bitfield", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
770 { &hf_bittorrent_piece_index
,
771 { "Piece index", "bittorrent.piece.index", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
773 { &hf_bittorrent_piece_begin
,
774 { "Begin offset of piece", "bittorrent.piece.begin", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
776 { &hf_bittorrent_piece_data
,
777 { "Data in a piece", "bittorrent.piece.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
779 { &hf_bittorrent_piece_length
,
780 { "Piece Length", "bittorrent.piece.length", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
782 { &hf_azureus_jpc_addrlen
,
783 { "Cache Address Length", "bittorrent.jpc.addr.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
785 { &hf_azureus_jpc_addr
,
786 { "Cache Address", "bittorrent.jpc.addr", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
788 { &hf_azureus_jpc_port
,
789 { "Port", "bittorrent.jpc.port", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
791 { &hf_azureus_jpc_session
,
792 { "Session ID", "bittorrent.jpc.session", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
794 { &hf_bittorrent_port
,
795 { "Port", "bittorrent.port", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
797 { &hf_bittorrent_extended_id
,
798 { "Extended Message ID", "bittorrent.extended.id", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
800 { &hf_bittorrent_extended
,
801 { "Extended Message", "bittorrent.extended", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
803 { &hf_bittorrent_continuous_data
,
804 { "Extended Message", "bittorrent.continuous_data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
806 { &hf_bittorrent_version
,
807 { "Client version", "bittorrent.version", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
811 static int *ett
[] = {
817 module_t
*bittorrent_module
;
819 proto_bittorrent
= proto_register_protocol("BitTorrent", "BitTorrent", "bittorrent");
820 proto_register_field_array(proto_bittorrent
, hf
, array_length(hf
));
821 proto_register_subtree_array(ett
, array_length(ett
));
823 dissector_handle
= register_dissector("bittorrent.tcp", dissect_bittorrent
, proto_bittorrent
);
824 register_dissector("bittorrent.utp", dissect_bittorrent_utp
, proto_bittorrent
);
826 bittorrent_module
= prefs_register_protocol(proto_bittorrent
, NULL
);
827 prefs_register_bool_preference(bittorrent_module
, "desegment",
828 "Reassemble BitTorrent messages spanning multiple TCP segments",
829 "Whether the BitTorrent dissector should reassemble messages spanning multiple TCP segments."
830 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
831 &bittorrent_desegment
);
832 prefs_register_bool_preference(bittorrent_module
, "decode_client",
833 "Decode the peer_id of the handshake messages",
834 "Enabling this will tell which BitTorrent client that produced the handshake message",
835 &decode_client_information
);
840 proto_reg_handoff_bittorrent(void)
842 bencode_handle
= find_dissector_add_dependency("bencode", proto_bittorrent
);
844 dissector_add_uint_range_with_preference("tcp.port", DEFAULT_TCP_PORT_RANGE
, dissector_handle
);
846 heur_dissector_add("tcp", test_bittorrent_packet
, "BitTorrent over TCP", "bittorrent_tcp", proto_bittorrent
, HEURISTIC_ENABLE
);
855 * indent-tabs-mode: nil
858 * ex: set shiftwidth=3 tabstop=8 expandtab:
859 * :indentSize=3:tabSize=8:noTabs=true: