2 * Routines for BT-UTP dissection
3 * Copyright 2011, Xiao Xiangquan <xiaoxiangquan@gmail.com>
4 * Copyright 2021, John Thacker <johnthacker@gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1999 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
16 #include <epan/conversation.h>
17 #include <epan/exceptions.h>
18 #include <epan/show_exception.h>
19 #include <epan/expert.h>
20 #include <epan/prefs.h>
21 #include <epan/proto_data.h>
22 #include <epan/unit_strings.h>
24 #include "packet-bt-utp.h"
26 void proto_register_bt_utp(void);
27 void proto_reg_handoff_bt_utp(void);
38 /* V0 hdr: "flags"; V1 hdr: "type" */
39 static const value_string bt_utp_type_vals
[] = {
42 { ST_STATE
, "State" },
43 { ST_RESET
, "Reset" },
50 EXT_SELECTIVE_ACKS
= 1,
51 EXT_EXTENSION_BITS
= 2,
56 static const value_string bt_utp_extension_type_vals
[] = {
57 { EXT_NO_EXTENSION
, "No Extension" },
58 { EXT_SELECTIVE_ACKS
, "Selective ACKs" },
59 { EXT_EXTENSION_BITS
, "Extension bits" },
60 { EXT_CLOSE_REASON
, "Close reason" },
64 /* https://github.com/arvidn/libtorrent/blob/master/include/libtorrent/close_reason.hpp */
65 static const value_string bt_utp_close_reason_vals
[] = {
67 { 1, "Duplicate peer ID" },
68 { 2, "Torrent removed" },
69 { 3, "Memory allocation failed" },
70 { 4, "Port blocked" },
71 { 5, "Address blocked" },
72 { 6, "Upload to upload" },
73 { 7, "Not interested upload only" },
75 { 9, "Timeout: interest" },
76 { 10, "Timeout: activity" },
77 { 11, "Timeout: handshake" },
78 { 12, "Timeout: request" },
79 { 13, "Protocol blocked" },
81 { 15, "Too many connections" },
82 { 16, "Too many files" },
83 /* Reasons caused by the peer sending unexpected data are 256 and up */
84 {256, "Encryption error" },
85 {257, "Invalid info hash" },
86 {258, "Self connection" },
87 {259, "Invalid metadata" },
88 {260, "Metadata too big" },
89 {261, "Message too big" },
90 {262, "Invalid message id" },
91 {263, "Invalid message" },
92 {264, "Invalid piece message" },
93 {265, "Invalid have message" },
94 {266, "Invalid bitfield message" },
95 {267, "Invalid choke message" },
96 {268, "Invalid unchoke message" },
97 {269, "Invalid interested message" },
98 {270, "Invalid not interested message" },
99 {271, "Invalid request message" },
100 {272, "Invalid reject message" },
101 {273, "Invalid allow fast message" },
102 {274, "Invalid extended message" },
103 {275, "Invalid cancel message" },
104 {276, "Invalid DHT port message" },
105 {277, "Invalid suggest message" },
106 {278, "Invalid have all message" },
107 {279, "Invalid don't have message" },
108 {280, "Invalid PEX message" },
109 {281, "Invalid metadata request message" },
110 {282, "Invalid metadata message" },
111 {283, "Invalid metadata offset" },
112 {284, "Request when choked" },
113 {285, "Corrupt pieces" },
114 {286, "PEX message too big" },
115 {287, "PEX too frequent" },
119 static int proto_bt_utp
;
121 /* --- "Original" uTP Header ("version 0" ?) --------------
123 See utp.cpp source code @ https://github.com/bittorrent/libutp
127 +-------+-------+---------------+---------------+---------------+
129 +-------+-------+---------------+---------------+---------------+
130 | timestamp_seconds |
131 +---------------+---------------+---------------+---------------+
132 | timestamp_microseconds |
133 +---------------+---------------+---------------+---------------+
134 | timestamp_difference_microseconds |
135 +---------------+---------------+---------------+---------------+
136 | wnd_size | ext | flags | seq_nr [ho] |
137 +---------------+---------------+---------------+---------------+
138 | seq_nr [lo] | ack_nr |
139 +---------------+---------------+---------------+
141 -- Extension Field(s) --
143 +---------------+---------------+---------------+---------------+
144 | extension | len | bitmask
145 +---------------+---------------+---------------+---------------+
147 +---------------+---------------+....
151 /* --- Version 1 Header ----------------
153 Specifications: BEP-0029
154 http://www.bittorrent.org/beps/bep_0029.html
159 +-------+-------+---------------+---------------+---------------+
160 | type | ver | extension | connection_id |
161 +-------+-------+---------------+---------------+---------------+
162 | timestamp_microseconds |
163 +---------------+---------------+---------------+---------------+
164 | timestamp_difference_microseconds |
165 +---------------+---------------+---------------+---------------+
167 +---------------+---------------+---------------+---------------+
169 +---------------+---------------+---------------+---------------+
171 -- Extension Field(s) --
173 +---------------+---------------+---------------+---------------+
174 | extension | len | bitmask
175 +---------------+---------------+---------------+---------------+
177 +---------------+---------------+....
180 #define V0_FIXED_HDR_SIZE 23
181 #define V1_FIXED_HDR_SIZE 20
183 /* Very early versions of libutp (still used by Transmission) set the max
184 * recv window size to 0x00380000, versions from 2013 and later set it to
185 * 0x00100000, and some other clients use 0x00040000. This is one of the
186 * few possible sources of heuristics.
189 #define V1_MAX_WINDOW_SIZE 0x380000U
191 static dissector_handle_t bt_utp_handle
;
192 static dissector_handle_t bittorrent_handle
;
194 static int hf_bt_utp_ver
;
195 static int hf_bt_utp_type
;
196 static int hf_bt_utp_flags
;
197 static int hf_bt_utp_extension
;
198 static int hf_bt_utp_next_extension_type
;
199 static int hf_bt_utp_extension_len
;
200 static int hf_bt_utp_extension_bitmask
;
201 static int hf_bt_utp_extension_close_reason
;
202 static int hf_bt_utp_extension_unknown
;
203 static int hf_bt_utp_connection_id_v0
;
204 static int hf_bt_utp_connection_id_v1
;
205 static int hf_bt_utp_stream
;
206 static int hf_bt_utp_timestamp_sec
;
207 static int hf_bt_utp_timestamp_us
;
208 static int hf_bt_utp_timestamp_diff_us
;
209 static int hf_bt_utp_wnd_size_v0
;
210 static int hf_bt_utp_wnd_size_v1
;
211 static int hf_bt_utp_seq_nr
;
212 static int hf_bt_utp_ack_nr
;
213 static int hf_bt_utp_len
;
214 static int hf_bt_utp_data
;
215 static int hf_bt_utp_pdu_size
;
216 static int hf_bt_utp_continuation_to
;
218 static expert_field ei_extension_len_invalid
;
220 static int ett_bt_utp
;
221 static int ett_bt_utp_extension
;
223 static bool enable_version0
;
224 static unsigned max_window_size
= V1_MAX_WINDOW_SIZE
;
225 /* XXX: Desegmentation and OOO-reassembly are not supported yet */
226 static bool utp_desegment
;
227 /*static bool utp_reassemble_out_of_order = false;*/
228 static bool utp_analyze_seq
= true;
230 static uint32_t bt_utp_stream_count
;
232 typedef struct _utp_multisegment_pdu
{
236 unsigned first_seq_start_offset
;
237 unsigned last_seq_end_offset
;
239 uint32_t reassembly_id;*/
240 uint32_t first_frame
;
242 } utp_multisegment_pdu
;
244 typedef struct _utp_flow_t
{
246 /* XXX: Some other things to add in later. */
254 wmem_tree_t
*multisegment_pdus
;
264 /* XXX: Some other things to add in later. */
267 uint8_t conversation_completeness
;
271 /* Per-packet header information. */
275 uint32_t connection
; /* The prelease "V0" version is 32 bit */
279 uint32_t seglen
; /* reported length remaining */
282 proto_tree
*tree
; /* For the bittorrent subdissector to access */
285 static utp_stream_info_t
*
286 get_utp_stream_info(packet_info
*pinfo
, utp_info_t
*utp_info
)
288 conversation_t
* conv
;
289 utp_stream_info_t
*stream_info
;
290 uint32_t id_up
, id_down
;
293 /* Handle connection ID wrapping correctly. (Mainline libutp source
294 * does not appear to do this, probably fails to connect if the random
295 * connection ID is GMAX_UINT16 and tries again.)
298 id_up
= utp_info
->connection
+1;
299 id_down
= utp_info
->connection
-1;
301 id_up
= (uint16_t)(utp_info
->connection
+1);
302 id_down
= (uint16_t)(utp_info
->connection
-1);
305 if (utp_info
->type
== ST_SYN
) {
306 /* SYN packets are special, they have the connection ID for the other
307 * side, and allow us to know both.
309 conv
= find_conversation(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
, CONVERSATION_BT_UTP
,
310 id_up
, utp_info
->connection
, 0);
312 /* XXX: A SYN for between the same pair of hosts with a duplicate
313 * connection ID in the same direction is almost surely a retransmission
314 * (unless there's a client that doesn't actually generate random IDs.)
315 * We could check to see if we've gotten a FIN or RST on that same
316 * connection, and also could do like TCP and see if the initial sequence
317 * number matches. (The latter still doesn't help if the client also
318 * doesn't start with random sequence numbers.)
320 conv
= conversation_new(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
, CONVERSATION_BT_UTP
, id_up
, utp_info
->connection
, 0);
323 /* For non-SYN packets, we know our connection ID, but we don't know if
324 * the other side has our ID+1 (src initiated the connection) or our ID-1
325 * (dst initiated). We also don't want find_conversation() to accidentally
326 * call conversation_set_port2() with the wrong ID. So first we see if
327 * we have a wildcarded conversation around (if we've seen previous
328 * non-SYN packets from our current direction but none in the other.)
330 conv
= find_conversation(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
, CONVERSATION_BT_UTP
, utp_info
->connection
, 0, NO_PORT_B
);
332 /* Do we have a complete conversation originated by our src, or
333 * possibly a wildcarded conversation originated in this direction
334 * (but we saw a non-SYN for the non-initiating side first)? */
335 conv
= find_conversation(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
, CONVERSATION_BT_UTP
, utp_info
->connection
, id_up
, 0);
337 /* As above, but dst initiated? */
338 conv
= find_conversation(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
, CONVERSATION_BT_UTP
, utp_info
->connection
, id_down
, 0);
340 /* Didn't find it, so create a new wildcarded conversation. When we
341 * get a packet for the other direction, find_conversation() above
342 * will set port2 with the other connection ID.
344 conv
= conversation_new(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
, CONVERSATION_BT_UTP
, utp_info
->connection
, 0, NO_PORT2
);
350 stream_info
= (utp_stream_info_t
*)conversation_get_proto_data(conv
, proto_bt_utp
);
352 stream_info
= wmem_new0(wmem_file_scope(), utp_stream_info_t
);
353 stream_info
->stream
= bt_utp_stream_count
++;
354 stream_info
->flow
[0].multisegment_pdus
=wmem_tree_new(wmem_file_scope());
355 stream_info
->flow
[1].multisegment_pdus
=wmem_tree_new(wmem_file_scope());
356 conversation_add_proto_data(conv
, proto_bt_utp
, stream_info
);
359 /* check direction */
360 direction
=cmp_address(&pinfo
->src
, &pinfo
->dst
);
361 /* if the addresses are equal, match the ports instead. Use
362 * the UDP ports instead of the uTP connection IDs because
363 * we don't know which ID is smaller if we don't have both. */
365 direction
= (pinfo
->srcport
> pinfo
->destport
) ? 1 : -1;
368 stream_info
->fwd
=&(stream_info
->flow
[0]);
369 stream_info
->rev
=&(stream_info
->flow
[1]);
371 stream_info
->fwd
=&(stream_info
->flow
[1]);
372 stream_info
->rev
=&(stream_info
->flow
[0]);
379 print_pdu_tracking_data(packet_info
*pinfo
, tvbuff_t
*tvb
, proto_tree
*utp_tree
, utp_multisegment_pdu
*msp
)
383 col_prepend_fence_fstr(pinfo
->cinfo
, COL_INFO
, "[Continuation to #%u] ", msp
->first_frame
);
384 item
=proto_tree_add_uint(utp_tree
, hf_bt_utp_continuation_to
,
385 tvb
, 0, 0, msp
->first_frame
);
386 proto_item_set_generated(item
);
390 scan_for_next_pdu(tvbuff_t
*tvb
, proto_tree
*utp_tree
, packet_info
*pinfo
, wmem_tree_t
*multisegment_pdus
)
392 utp_multisegment_pdu
*msp
;
393 utp_info_t
*p_utp_info
;
394 uint16_t seq
, prev_seq
;
396 p_utp_info
= (utp_info_t
*)p_get_proto_data(pinfo
->pool
, pinfo
, proto_bt_utp
, pinfo
->curr_layer_num
);
398 /* XXX: Wraparound is possible, as is cycling through all 16 bit
399 * sequence numbers in a connection. We only do this path if
400 * "seq analysis" is on; that ought to do something (relative
401 * sequence numbers definitely, maybe extend the width?) to help,
404 seq
= p_utp_info
->seq
;
406 msp
= (utp_multisegment_pdu
*)wmem_tree_lookup32_le(multisegment_pdus
, prev_seq
);
409 if(seq
>msp
->first_seq
&& seq
<=msp
->last_seq
) {
410 print_pdu_tracking_data(pinfo
, tvb
, utp_tree
, msp
);
413 /* If this segment is completely within a previous PDU
414 * then we just skip this packet
416 if(seq
>msp
->first_seq
&& seq
<msp
->last_seq
) {
420 if(seq
>msp
->first_seq
&& seq
==msp
->last_seq
) {
421 if (!PINFO_FD_VISITED(pinfo
) && p_utp_info
->have_seglen
) {
422 /* Unlike TCP, the sequence numbers don't measure bytes, so
423 * we can only really update the end of the MSP when the packets
424 * are in order, and if we have the real segment length (so not
425 * an unreassembled IP fragment).
427 if (p_utp_info
->seglen
>= msp
->last_seq_end_offset
) {
428 return msp
->last_seq_end_offset
;
431 msp
->last_seq_end_offset
-= p_utp_info
->seglen
;
435 /* We can still provide a hint to the offset start in some
436 * cases even when we can't update the MSP.
438 if (msp
->last_seq_end_offset
< tvb_reported_length(tvb
)) {
439 return msp
->last_seq_end_offset
;
450 static utp_multisegment_pdu
*
451 pdu_store_sequencenumber_of_next_pdu(packet_info
*pinfo
, uint16_t seq
, int offset
, uint32_t bytes_until_next_pdu
, wmem_tree_t
*multisegment_pdus
)
453 utp_multisegment_pdu
*msp
;
455 msp
= wmem_new(wmem_file_scope(), utp_multisegment_pdu
);
456 msp
->first_seq
= seq
;
457 msp
->first_seq_start_offset
= offset
;
458 msp
->last_seq
= seq
+1;
459 msp
->last_seq_end_offset
= bytes_until_next_pdu
;
460 msp
->first_frame
= pinfo
->num
;
461 wmem_tree_insert32(multisegment_pdus
, seq
, (void *)msp
);
468 desegment_utp(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
469 uint32_t seq
, uint32_t nxtseq
,
470 proto_tree
*tree
, proto_tree
*utp_tree
,
471 utp_stream_info_t
*stream_info
)
478 utp_dissect_pdus(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
479 bool proto_desegment
, unsigned fixed_len
,
480 unsigned (*get_pdu_len
)(packet_info
*, tvbuff_t
*, int, void*),
481 dissector_t dissect_pdu
, void* dissector_data
)
483 volatile int offset
= 0;
485 unsigned captured_length_remaining
;
486 volatile unsigned plen
;
489 proto_item
*item
=NULL
;
490 const char *saved_proto
;
491 uint8_t curr_layer_num
;
492 wmem_list_frame_t
*frame
;
494 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
496 * We use "tvb_ensure_captured_length_remaining()" to make
497 * sure there actually *is* data remaining. The protocol
498 * we're handling could conceivably consists of a sequence of
499 * fixed-length PDUs, and therefore the "get_pdu_len" routine
500 * might not actually fetch anything from the tvbuff, and thus
501 * might not cause an exception to be thrown if we've run past
502 * the end of the tvbuff.
504 * This means we're guaranteed that "captured_length_remaining" is positive.
506 captured_length_remaining
= tvb_ensure_captured_length_remaining(tvb
, offset
);
509 * Can we do reassembly?
511 if (proto_desegment
&& pinfo
->can_desegment
) {
513 * Yes - is the fixed-length part of the PDU split across segment
516 if (captured_length_remaining
< fixed_len
) {
518 * Yes. Tell the uTP dissector where the data for this message
519 * starts in the data it handed us and that we need "some more
520 * data." Don't tell it exactly how many bytes we need because
521 * if/when we ask for even more (after the header) that will
524 pinfo
->desegment_offset
= offset
;
525 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
531 * Get the length of the PDU.
533 plen
= (*get_pdu_len
)(pinfo
, tvb
, offset
, dissector_data
);
536 * Support protocols which have a variable length which cannot
537 * always be determined within the given fixed_len.
540 * If another segment was requested but we can't do reassembly,
541 * abort and warn about the unreassembled packet.
543 THROW_ON(!(proto_desegment
&& pinfo
->can_desegment
), FragmentBoundsError
);
544 pinfo
->desegment_offset
= offset
;
545 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
548 if (plen
< fixed_len
) {
552 * 1) the length value extracted from the fixed-length portion
553 * doesn't include the fixed-length portion's length, and
554 * was so large that, when the fixed-length portion's
555 * length was added to it, the total length overflowed;
557 * 2) the length value extracted from the fixed-length portion
558 * includes the fixed-length portion's length, and the value
559 * was less than the fixed-length portion's length, i.e. it
562 * Report this as a bounds error.
564 show_reported_bounds_error(tvb
, pinfo
, tree
);
568 /* give a hint to uTP where the next PDU starts
569 * so that it can attempt to find it in case it starts
570 * somewhere in the middle of a segment.
572 if(!pinfo
->fd
->visited
&& utp_analyze_seq
) {
573 unsigned remaining_bytes
;
574 remaining_bytes
= tvb_reported_length_remaining(tvb
, offset
);
575 if(plen
>remaining_bytes
) {
576 pinfo
->want_pdu_tracking
=2;
577 pinfo
->bytes_until_next_pdu
=plen
-remaining_bytes
;
582 * Can we do reassembly?
584 if (proto_desegment
&& pinfo
->can_desegment
) {
586 * Yes - is the PDU split across segment boundaries?
588 if (captured_length_remaining
< plen
) {
590 * Yes. Tell the TCP dissector where the data for this message
591 * starts in the data it handed us, and how many more bytes we
594 pinfo
->desegment_offset
= offset
;
595 pinfo
->desegment_len
= plen
- captured_length_remaining
;
600 curr_layer_num
= pinfo
->curr_layer_num
-1;
601 frame
= wmem_list_frame_prev(wmem_list_tail(pinfo
->layers
));
602 while (frame
&& (proto_bt_utp
!= (int) GPOINTER_TO_UINT(wmem_list_frame_data(frame
)))) {
603 frame
= wmem_list_frame_prev(frame
);
607 if (captured_length_remaining
>= plen
|| there are more packets
)
611 * Display the PDU length as a field
613 item
=proto_tree_add_uint(((utp_info_t
*)p_get_proto_data(pinfo
->pool
, pinfo
, proto_bt_utp
, curr_layer_num
))->tree
,
615 tvb
, offset
, plen
, plen
);
616 proto_item_set_generated(item
);
619 item
= proto_tree_add_expert_format((proto_tree
*)p_get_proto_data(pinfo
->pool
, pinfo
, proto_bt_utp
, curr_layer_num
),
621 "PDU Size: %u cut short at %u",plen
,captured_length_remaining
);
622 proto_item_set_generated(item
);
627 * Construct a tvbuff containing the amount of the payload we have
628 * available. Make its reported length the amount of data in the PDU.
630 length
= captured_length_remaining
;
634 next_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, length
, plen
);
635 if (!(proto_desegment
&& pinfo
->can_desegment
)) {
636 /* If we can't do reassembly, give a hint that bounds errors
637 * are probably fragment errors. */
638 tvb_set_fragment(next_tvb
);
644 * If it gets an error that means there's no point in
645 * dissecting any more PDUs, rethrow the exception in
648 * If it gets any other error, report it and continue, as that
649 * means that PDU got an error, but that doesn't mean we should
650 * stop dissecting PDUs within this frame or chunk of reassembled
653 saved_proto
= pinfo
->current_proto
;
655 (*dissect_pdu
)(next_tvb
, pinfo
, tree
, dissector_data
);
657 CATCH_NONFATAL_ERRORS
{
658 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
660 * Restore the saved protocol as well; we do this after
661 * show_exception(), so that the "Malformed packet" indication
662 * shows the protocol for which dissection failed.
664 pinfo
->current_proto
= saved_proto
;
669 * Step to the next PDU.
670 * Make sure we don't overflow.
672 offset_before
= offset
;
674 if (offset
<= offset_before
)
680 get_utp_version(tvbuff_t
*tvb
) {
682 uint8_t v1_ver_type
, ext
, ext_len
;
684 unsigned len
, offset
= 0;
687 /* Simple heuristics inspired by code from utp.cpp */
689 len
= tvb_captured_length(tvb
);
692 if (len
< V1_FIXED_HDR_SIZE
) {
696 v1_ver_type
= tvb_get_uint8(tvb
, 0);
697 ext
= tvb_get_uint8(tvb
, 1);
698 if (((v1_ver_type
& 0x0f) == 1) && ((v1_ver_type
>>4) < ST_NUM_STATES
) &&
699 (ext
< EXT_NUM_EXT
)) {
700 window
= tvb_get_uint32(tvb
, 12, ENC_BIG_ENDIAN
);
701 if (window
> max_window_size
) {
705 offset
= V1_FIXED_HDR_SIZE
;
706 } else if (enable_version0
) {
708 if (len
< V0_FIXED_HDR_SIZE
) {
711 v0_flags
= tvb_get_uint8(tvb
, 18);
712 ext
= tvb_get_uint8(tvb
, 17);
713 if ((v0_flags
< ST_NUM_STATES
) && (ext
< EXT_NUM_EXT
)) {
715 offset
= V0_FIXED_HDR_SIZE
;
723 /* In V0 we could use the microseconds value as a heuristic, because
724 * it was tv_usec, but in the modern V1 we cannot, because it is
725 * computed by converting a time_t into a 64 bit quantity of microseconds
726 * and then taking the lower 32 bits, so all possible values are likely.
728 /* If we have an extension, then check the next two bytes,
729 * the first of which is another extension type (likely NO_EXTENSION)
730 * and the second of which is a length, which must be at least 4.
732 if (ext
!= EXT_NO_EXTENSION
) {
733 if (len
< offset
+ 2) {
736 ext
= tvb_get_uint8(tvb
, offset
);
737 ext_len
= tvb_get_uint8(tvb
, offset
+1);
738 if (ext
>= EXT_NUM_EXT
|| ext_len
< 4) {
747 dissect_utp_header_v0(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, uint8_t *extension_type
)
749 /* "Original" (V0) */
750 utp_info_t
*p_utp_info
= NULL
;
751 utp_stream_info_t
*stream_info
= NULL
;
754 uint32_t type
, connection
, win
, seq
, ack
;
756 p_utp_info
= wmem_new(pinfo
->pool
, utp_info_t
);
757 p_utp_info
->v0
= true;
758 p_add_proto_data(pinfo
->pool
, pinfo
, proto_bt_utp
, pinfo
->curr_layer_num
, p_utp_info
);
760 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_connection_id_v0
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &connection
);
762 proto_tree_add_item(tree
, hf_bt_utp_timestamp_sec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
764 proto_tree_add_item(tree
, hf_bt_utp_timestamp_us
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
766 proto_tree_add_item(tree
, hf_bt_utp_timestamp_diff_us
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
768 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_wnd_size_v0
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &win
);
770 proto_tree_add_item(tree
, hf_bt_utp_next_extension_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
771 *extension_type
= tvb_get_uint8(tvb
, offset
);
773 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_flags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &type
);
776 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Connection ID:%d [%s]", connection
, val_to_str(type
, bt_utp_type_vals
, "Unknown %d"));
777 p_utp_info
->type
= type
;
778 p_utp_info
->connection
= connection
;
780 proto_tree_add_item(tree
, hf_bt_utp_seq_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
782 proto_tree_add_item(tree
, hf_bt_utp_ack_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
785 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_seq_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &seq
);
786 col_append_str_uint(pinfo
->cinfo
, COL_INFO
, "Seq", seq
, " ");
787 p_utp_info
->seq
= seq
;
789 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_ack_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &ack
);
790 col_append_str_uint(pinfo
->cinfo
, COL_INFO
, "Ack", ack
, " ");
791 p_utp_info
->ack
= ack
;
793 col_append_str_uint(pinfo
->cinfo
, COL_INFO
, "Win", win
, " ");
795 stream_info
= get_utp_stream_info(pinfo
, p_utp_info
);
796 ti
= proto_tree_add_uint(tree
, hf_bt_utp_stream
, tvb
, offset
, 0, stream_info
->stream
);
797 p_utp_info
->stream
= stream_info
->stream
;
798 proto_item_set_generated(ti
);
804 dissect_utp_header_v1(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, uint8_t *extension_type
)
807 utp_info_t
*p_utp_info
= NULL
;
808 utp_stream_info_t
*stream_info
= NULL
;
812 uint32_t type
, connection
, win
, seq
, ack
;
814 p_utp_info
= wmem_new(pinfo
->pool
, utp_info_t
);
815 p_utp_info
->v0
= false;
816 p_add_proto_data(pinfo
->pool
, pinfo
, proto_bt_utp
, pinfo
->curr_layer_num
, p_utp_info
);
818 proto_tree_add_item(tree
, hf_bt_utp_ver
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
819 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &type
);
821 proto_tree_add_item(tree
, hf_bt_utp_next_extension_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
822 *extension_type
= tvb_get_uint8(tvb
, offset
);
824 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_connection_id_v1
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &connection
);
827 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Connection ID:%d [%s]", connection
, val_to_str(type
, bt_utp_type_vals
, "Unknown %d"));
828 p_utp_info
->type
= type
;
829 p_utp_info
->connection
= connection
;
831 proto_tree_add_item(tree
, hf_bt_utp_timestamp_us
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
833 proto_tree_add_item(tree
, hf_bt_utp_timestamp_diff_us
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
835 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_wnd_size_v1
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &win
);
837 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_seq_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &seq
);
838 col_append_str_uint(pinfo
->cinfo
, COL_INFO
, "Seq", seq
, " ");
839 p_utp_info
->seq
= seq
;
841 proto_tree_add_item_ret_uint(tree
, hf_bt_utp_ack_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &ack
);
842 col_append_str_uint(pinfo
->cinfo
, COL_INFO
, "Ack", ack
, " ");
843 p_utp_info
->ack
= ack
;
845 col_append_str_uint(pinfo
->cinfo
, COL_INFO
, "Win", win
, " ");
847 stream_info
= get_utp_stream_info(pinfo
, p_utp_info
);
848 ti
= proto_tree_add_uint(tree
, hf_bt_utp_stream
, tvb
, offset
, 0, stream_info
->stream
);
849 p_utp_info
->stream
= stream_info
->stream
;
850 proto_item_set_generated(ti
);
852 /* XXX: Multisegment PDUs are the top priority to add, but a number of
853 * other features in the TCP dissector would be useful- relative sequence
854 * numbers, conversation completeness, maybe even tracking SACKs.
860 dissect_utp_extension(tvbuff_t
*tvb
, packet_info _U_
*pinfo
, proto_tree
*tree
, int offset
, uint8_t *extension_type
)
863 proto_tree
*ext_tree
;
864 uint32_t next_extension
, extension_length
;
865 /* display the extension tree */
867 while(*extension_type
!= EXT_NO_EXTENSION
&& offset
< (int)tvb_reported_length(tvb
))
869 ti
= proto_tree_add_none_format(tree
, hf_bt_utp_extension
, tvb
, offset
, -1, "Extension: %s", val_to_str_const(*extension_type
, bt_utp_extension_type_vals
, "Unknown"));
870 ext_tree
= proto_item_add_subtree(ti
, ett_bt_utp_extension
);
872 proto_tree_add_item_ret_uint(ext_tree
, hf_bt_utp_next_extension_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &next_extension
);
875 proto_tree_add_item_ret_uint(ext_tree
, hf_bt_utp_extension_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &extension_length
);
876 proto_item_append_text(ti
, ", Len=%d", extension_length
);
879 switch(*extension_type
){
880 case EXT_SELECTIVE_ACKS
: /* 1 */
882 proto_tree_add_item(ext_tree
, hf_bt_utp_extension_bitmask
, tvb
, offset
, extension_length
, ENC_NA
);
885 case EXT_EXTENSION_BITS
: /* 2 */
887 proto_tree_add_item(ext_tree
, hf_bt_utp_extension_bitmask
, tvb
, offset
, extension_length
, ENC_NA
);
890 case EXT_CLOSE_REASON
: /* 3 */
892 if (extension_length
!= 4) {
893 expert_add_info(pinfo
, ti
, &ei_extension_len_invalid
);
895 proto_tree_add_item(ext_tree
, hf_bt_utp_extension_close_reason
, tvb
, offset
, 4, ENC_NA
);
899 proto_tree_add_item(ext_tree
, hf_bt_utp_extension_unknown
, tvb
, offset
, extension_length
, ENC_NA
);
902 offset
+= extension_length
;
903 proto_item_set_len(ti
, 1 + 1 + extension_length
);
904 *extension_type
= next_extension
;
911 decode_utp(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
914 proto_tree
*parent_tree
;
916 int save_desegment_offset
;
917 uint32_t save_desegment_len
;
919 /* XXX: Check for retransmission? */
921 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
923 save_desegment_offset
= pinfo
->desegment_offset
;
924 save_desegment_len
= pinfo
->desegment_len
;
926 /* The only possible payload is bittorrent */
928 parent_tree
= proto_tree_get_parent_tree(tree
);
929 if (call_dissector_with_data(bittorrent_handle
, next_tvb
, pinfo
, parent_tree
, NULL
)) {
930 pinfo
->want_pdu_tracking
-= !!(pinfo
->want_pdu_tracking
);
934 DISSECTOR_ASSERT(save_desegment_offset
== pinfo
->desegment_offset
&&
935 save_desegment_len
== pinfo
->desegment_len
);
937 call_data_dissector(tvb
, pinfo
, parent_tree
);
938 pinfo
->want_pdu_tracking
-= !!(pinfo
->want_pdu_tracking
);
944 process_utp_payload(tvbuff_t
*tvb
, packet_info
*pinfo
,
945 proto_tree
*tree
, uint16_t seq
, bool is_utp_segment
,
946 utp_stream_info_t
*stream_info
)
948 volatile int offset
= 0;
949 pinfo
->want_pdu_tracking
= 0;
952 if (is_utp_segment
) {
953 /* See if an unaligned PDU */
954 if (stream_info
&& utp_analyze_seq
&& (!utp_desegment
)) {
955 offset
= scan_for_next_pdu(tvb
, tree
, pinfo
,
956 stream_info
->fwd
->multisegment_pdus
);
960 if ((offset
!= -1) && decode_utp(tvb
, offset
, pinfo
, tree
)) {
962 * We succeeded in handing off to bittorent.
964 * Is this a segment (so we're not desegmenting for whatever
965 * reason)? Then at least do rudimentary PDU tracking.
968 /* if !visited, check want_pdu_tracking and
970 if(stream_info
&& (!pinfo
->fd
->visited
) &&
971 utp_analyze_seq
&& pinfo
->want_pdu_tracking
) {
972 pdu_store_sequencenumber_of_next_pdu(
976 pinfo
->bytes_until_next_pdu
,
977 stream_info
->fwd
->multisegment_pdus
);
983 /* We got an exception. Before dissection is aborted and execution
984 * is transferred back to (probably) the frame dissector, do PDU
985 * tracking if we need to because this is a segment.
987 if (is_utp_segment
) {
988 if(stream_info
&& (!pinfo
->fd
->visited
) &&
989 utp_analyze_seq
&& pinfo
->want_pdu_tracking
) {
990 pdu_store_sequencenumber_of_next_pdu(
994 pinfo
->bytes_until_next_pdu
,
995 stream_info
->fwd
->multisegment_pdus
);
1004 dissect_utp_payload(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1008 utp_info_t
*p_utp_info
;
1010 bool save_fragmented
;
1012 p_utp_info
= (utp_info_t
*)p_get_proto_data(pinfo
->pool
, pinfo
, proto_bt_utp
, pinfo
->curr_layer_num
);
1014 p_utp_info
->tree
= tree
;
1016 utp_stream_info_t
*stream_info
;
1017 stream_info
= get_utp_stream_info(pinfo
, p_utp_info
);
1019 len_tvb
= tvb_reported_length(tvb
);
1021 /* As with TCP, if we've been handed an IP fragment, we don't really
1022 * know how big the segment is, and we don't really want to do anything
1023 * if this is an error packet from ICMP or similar.
1025 * XXX: We don't want to desegment if the UDP checksum is bad either.
1026 * Need to add that to the per-packet info that UDP stores and access
1029 pinfo
->can_desegment
= 0;
1030 if (!pinfo
->fragmented
&& !pinfo
->flags
.in_error_pkt
) {
1031 p_utp_info
->seglen
= len_tvb
;
1032 p_utp_info
->have_seglen
= true;
1034 ti
= proto_tree_add_uint(tree
, hf_bt_utp_len
, tvb
, 0, 0, len_tvb
);
1035 proto_item_set_generated(ti
);
1036 col_append_str_uint(pinfo
->cinfo
, COL_INFO
, "Len", len_tvb
, " ");
1038 if (utp_desegment
&& tvb_bytes_exist(tvb
, 0, len_tvb
)) {
1039 /* If we actually have the bytes too then we can desegment. */
1040 pinfo
->can_desegment
= 2;
1043 p_utp_info
->have_seglen
= false;
1046 if(tvb_captured_length(tvb
)) {
1047 proto_tree_add_item(tree
, hf_bt_utp_data
, tvb
, 0, len_tvb
, ENC_NA
);
1048 if (pinfo
->can_desegment
) {
1049 /* XXX: desegment_utp() is not implemented, but we can't get
1050 * into this code path yet because utp_desegment is false. */
1052 save_fragmented
= pinfo
->fragmented
;
1053 pinfo
->fragmented
= true;
1054 process_utp_payload(tvb
, pinfo
, tree
, p_utp_info
->seq
, true, stream_info
);
1055 pinfo
->fragmented
= save_fragmented
;
1063 dissect_bt_utp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1066 version
= get_utp_version(tvb
);
1068 /* try dissecting */
1071 proto_tree
*sub_tree
= NULL
;
1074 uint8_t extension_type
;
1076 /* set the protocol column */
1077 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "BT-uTP");
1078 col_clear(pinfo
->cinfo
, COL_INFO
);
1080 /* Determine header version */
1083 ti
= proto_tree_add_protocol_format(tree
, proto_bt_utp
, tvb
, 0, -1,
1084 "uTorrent Transport Protocol V0");
1085 sub_tree
= proto_item_add_subtree(ti
, ett_bt_utp
);
1086 offset
= dissect_utp_header_v0(tvb
, pinfo
, sub_tree
, offset
, &extension_type
);
1088 ti
= proto_tree_add_item(tree
, proto_bt_utp
, tvb
, 0, -1, ENC_NA
);
1089 sub_tree
= proto_item_add_subtree(ti
, ett_bt_utp
);
1090 offset
= dissect_utp_header_v1(tvb
, pinfo
, sub_tree
, offset
, &extension_type
);
1093 offset
= dissect_utp_extension(tvb
, pinfo
, sub_tree
, offset
, &extension_type
);
1095 offset
+= dissect_utp_payload(tvb_new_subset_remaining(tvb
, offset
), pinfo
, sub_tree
);
1103 dissect_bt_utp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1106 version
= get_utp_version(tvb
);
1110 conversation_t
*conversation
;
1112 conversation
= find_or_create_conversation(pinfo
);
1113 conversation_set_dissector_from_frame_number(conversation
, pinfo
->num
, bt_utp_handle
);
1115 dissect_bt_utp(tvb
, pinfo
, tree
, data
);
1125 bt_utp_stream_count
= 0;
1129 proto_register_bt_utp(void)
1131 static hf_register_info hf
[] = {
1133 { "Version", "bt-utp.ver",
1134 FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
1138 { "Flags", "bt-utp.flags",
1139 FT_UINT8
, BASE_DEC
, VALS(bt_utp_type_vals
), 0x0,
1143 { "Type", "bt-utp.type",
1144 FT_UINT8
, BASE_DEC
, VALS(bt_utp_type_vals
), 0xF0,
1147 { &hf_bt_utp_extension
,
1148 { "Extension", "bt-utp.extension",
1149 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1152 { &hf_bt_utp_next_extension_type
,
1153 { "Next Extension Type", "bt-utp.next_extension_type",
1154 FT_UINT8
, BASE_DEC
, VALS(bt_utp_extension_type_vals
), 0x0,
1157 { &hf_bt_utp_extension_len
,
1158 { "Extension Length", "bt-utp.extension_len",
1159 FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0x0,
1162 { &hf_bt_utp_extension_bitmask
,
1163 { "Extension Bitmask", "bt-utp.extension_bitmask",
1164 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1167 { &hf_bt_utp_extension_close_reason
,
1168 { "Close Reason", "bt-utp.extension_close_reason",
1169 FT_UINT32
, BASE_DEC
, VALS(bt_utp_close_reason_vals
), 0x0,
1172 { &hf_bt_utp_extension_unknown
,
1173 { "Extension Unknown", "bt-utp.extension_unknown",
1174 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1177 { &hf_bt_utp_connection_id_v0
,
1178 { "Connection ID", "bt-utp.connection_id",
1179 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1182 { &hf_bt_utp_connection_id_v1
,
1183 { "Connection ID", "bt-utp.connection_id",
1184 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1187 { &hf_bt_utp_stream
,
1188 { "Stream index", "bt-utp.stream",
1189 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1192 { &hf_bt_utp_timestamp_sec
,
1193 { "Timestamp seconds", "bt-utp.timestamp_sec",
1194 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1197 { &hf_bt_utp_timestamp_us
,
1198 { "Timestamp Microseconds", "bt-utp.timestamp_us",
1199 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1202 { &hf_bt_utp_timestamp_diff_us
,
1203 { "Timestamp Difference Microseconds", "bt-utp.timestamp_diff_us",
1204 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1207 { &hf_bt_utp_wnd_size_v0
,
1208 { "Window Size", "bt-utp.wnd_size",
1209 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1210 "V0 receive window size, in multiples of 350 bytes", HFILL
}
1212 { &hf_bt_utp_wnd_size_v1
,
1213 { "Window Size", "bt-utp.wnd_size",
1214 FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0x0,
1217 { &hf_bt_utp_seq_nr
,
1218 { "Sequence number", "bt-utp.seq_nr",
1219 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1222 { &hf_bt_utp_ack_nr
,
1223 { "ACK number", "bt-utp.ack_nr",
1224 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1228 { "uTP Segment Len", "bt-utp.len",
1229 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1233 { "Data", "bt-utp.data",
1234 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1237 { &hf_bt_utp_pdu_size
,
1238 { "PDU Size", "bt-utp.pdu.size",
1239 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1240 "The size of this PDU", HFILL
}
1242 { &hf_bt_utp_continuation_to
,
1243 { "This is a continuation to the PDU in frame",
1244 "bt-utp.continuation_to", FT_FRAMENUM
, BASE_NONE
,
1245 NULL
, 0x0, "This is a continuation to the PDU in frame #", HFILL
}
1249 static ei_register_info ei
[] = {
1250 { &ei_extension_len_invalid
,
1251 { "bt-utp.extension_len.invalid", PI_PROTOCOL
, PI_WARN
,
1252 "The extension is an unexpected length", EXPFILL
}
1256 /* Setup protocol subtree array */
1257 static int *ett
[] = { &ett_bt_utp
, &ett_bt_utp_extension
};
1259 module_t
*bt_utp_module
;
1260 expert_module_t
*expert_bt_utp
;
1262 /* Register protocol */
1263 proto_bt_utp
= proto_register_protocol ("uTorrent Transport Protocol", "BT-uTP", "bt-utp");
1265 bt_utp_module
= prefs_register_protocol(proto_bt_utp
, NULL
);
1266 prefs_register_obsolete_preference(bt_utp_module
, "enable");
1267 prefs_register_bool_preference(bt_utp_module
,
1268 "analyze_sequence_numbers",
1269 "Analyze uTP sequence numbers",
1270 "Make the uTP dissector analyze uTP sequence numbers. Currently this "
1271 "just means that it tries to find the correct start offset of a PDU "
1272 "if it detected that previous in-order packets spanned multiple "
1275 prefs_register_bool_preference(bt_utp_module
,
1277 "Dissect prerelease (version 0) packets",
1278 "Whether the dissector should attempt to dissect packets with the "
1279 "obsolete format (version 0) that predates BEP 29 (22-Jun-2009)",
1281 prefs_register_uint_preference(bt_utp_module
,
1283 "Maximum window size (in hex)",
1284 "Maximum receive window size allowed by the dissector. Early clients "
1285 "(and a few modern ones) set this value to 0x380000 (the default), "
1286 "later ones use smaller values like 0x100000 and 0x40000. A higher "
1287 "value can detect nonstandard packets, but at the cost of false "
1289 16, &max_window_size
);
1291 proto_register_field_array(proto_bt_utp
, hf
, array_length(hf
));
1292 proto_register_subtree_array(ett
, array_length(ett
));
1294 expert_bt_utp
= expert_register_protocol(proto_bt_utp
);
1295 expert_register_field_array(expert_bt_utp
, ei
, array_length(ei
));
1297 register_init_routine(utp_init
);
1299 bt_utp_handle
= register_dissector("bt-utp", dissect_bt_utp
, proto_bt_utp
);
1303 proto_reg_handoff_bt_utp(void)
1305 /* disabled by default since heuristic is weak */
1306 /* XXX: The heuristic is stronger now, but might still get false positives
1307 * on packets with lots of zero bytes. Needs more testing before enabling
1310 heur_dissector_add("udp", dissect_bt_utp_heur
, "BitTorrent UTP over UDP", "bt_utp_udp", proto_bt_utp
, HEURISTIC_DISABLE
);
1312 dissector_add_for_decode_as_with_preference("udp.port", bt_utp_handle
);
1314 bittorrent_handle
= find_dissector_add_dependency("bittorrent.utp", proto_bt_utp
);
1323 * indent-tabs-mode: nil
1326 * ex: set shiftwidth=2 tabstop=8 expandtab:
1327 * :indentSize=2:tabSize=8:noTabs=true: