aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/bittorrent.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/protocols/bittorrent.c')
-rw-r--r--src/lib/protocols/bittorrent.c123
1 files changed, 67 insertions, 56 deletions
diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c
index 99420b85e..fd8ab20c0 100644
--- a/src/lib/protocols/bittorrent.c
+++ b/src/lib/protocols/bittorrent.c
@@ -31,9 +31,24 @@
#define NDPI_PROTOCOL_PLAIN_DETECTION 0
#define NDPI_PROTOCOL_WEBSEED_DETECTION 2
static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ int bt_offset,
const u_int8_t save_detection, const u_int8_t encrypted_connection/* , */
/* ndpi_protocol_type_t protocol_type */)
{
+ const char *bt_hash = NULL; /* 20 bytes long */
+ const char *peer_id = NULL; /* 20 bytes long */
+
+ if(bt_offset == -1) {
+ const char *bt_magic = ndpi_strnstr((const char *)flow->packet.payload,
+ "BitTorrent protocol", flow->packet.payload_packet_len);
+
+ if(bt_magic)
+ bt_hash = &bt_magic[19], peer_id = &bt_magic[39];
+ } else
+ bt_hash = &flow->packet.payload[28], peer_id = &flow->packet.payload[48];
+
+ if(bt_hash) memcpy(flow->bittorent_hash, bt_hash, 20);
+
ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_UNKNOWN);
}
@@ -43,17 +58,17 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
struct ndpi_packet_struct *packet = &flow->packet;
u_int16_t a = 0;
- if (packet->payload_packet_len == 1 && packet->payload[0] == 0x13) {
+ if(packet->payload_packet_len == 1 && packet->payload[0] == 0x13) {
/* reset stage back to 0 so we will see the next packet here too */
flow->bittorrent_stage = 0;
return 0;
}
- if (flow->packet_counter == 2 && packet->payload_packet_len > 20) {
- if (memcmp(&packet->payload[0], "BitTorrent protocol", 19) == 0) {
+ if(flow->packet_counter == 2 && packet->payload_packet_len > 20) {
+ if(memcmp(&packet->payload[0], "BitTorrent protocol", 19) == 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, 19,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_REAL_PROTOCOL */);
return 1;
@@ -61,13 +76,12 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
}
- if (packet->payload_packet_len > 20) {
+ if(packet->payload_packet_len > 20) {
/* test for match 0x13+"BitTorrent protocol" */
- if (packet->payload[0] == 0x13) {
- if (memcmp(&packet->payload[1], "BitTorrent protocol", 19) == 0) {
- NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
- ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ if(packet->payload[0] == 0x13) {
+ if(memcmp(&packet->payload[1], "BitTorrent protocol", 19) == 0) {
+ NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, 20,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_REAL_PROTOCOL */);
return 1;
@@ -75,10 +89,10 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
}
}
- if (packet->payload_packet_len > 23 && memcmp(packet->payload, "GET /webseed?info_hash=", 23) == 0) {
+ if(packet->payload_packet_len > 23 && memcmp(packet->payload, "GET /webseed?info_hash=", 23) == 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
NDPI_LOG_TRACE, "BT: plain webseed BitTorrent protocol detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
@@ -86,18 +100,18 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
/* seen Azureus as server for webseed, possibly other servers existing, to implement */
/* is Server: hypertracker Bittorrent? */
/* no asymmetric detection possible for answer of pattern "GET /data?fid=". */
- if (packet->payload_packet_len > 60
+ if(packet->payload_packet_len > 60
&& memcmp(packet->payload, "GET /data?fid=", 14) == 0 && memcmp(&packet->payload[54], "&size=", 6) == 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
NDPI_LOG_TRACE, "BT: plain Bitcomet persistent seed protocol detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
}
- if (packet->payload_packet_len > 90 && (memcmp(packet->payload, "GET ", 4) == 0
+ if(packet->payload_packet_len > 90 && (memcmp(packet->payload, "GET ", 4) == 0
|| memcmp(packet->payload, "POST ", 5) == 0)) {
const u_int8_t *ptr = &packet->payload[4];
u_int16_t len = packet->payload_packet_len - 4;
@@ -107,32 +121,32 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
/* parse complete get packet here into line structure elements */
ndpi_parse_packet_line_info(ndpi_struct, flow);
/* answer to this pattern is HTTP....Server: hypertracker */
- if (packet->user_agent_line.ptr != NULL
+ if(packet->user_agent_line.ptr != NULL
&& ((packet->user_agent_line.len > 8 && memcmp(packet->user_agent_line.ptr, "Azureus ", 8) == 0)
|| (packet->user_agent_line.len >= 10 && memcmp(packet->user_agent_line.ptr, "BitTorrent", 10) == 0)
|| (packet->user_agent_line.len >= 11 && memcmp(packet->user_agent_line.ptr, "BTWebClient", 11) == 0))) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
NDPI_LOG_TRACE, "Azureus /Bittorrent user agent line detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
}
- if (packet->user_agent_line.ptr != NULL
+ if(packet->user_agent_line.ptr != NULL
&& (packet->user_agent_line.len >= 9 && memcmp(packet->user_agent_line.ptr, "Shareaza ", 9) == 0)
&& (packet->parsed_lines > 8 && packet->line[8].ptr != 0
&& packet->line[8].len >= 9 && memcmp(packet->line[8].ptr, "X-Queue: ", 9) == 0)) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
NDPI_LOG_TRACE, "Bittorrent Shareaza detected.\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
}
/* this is a self built client, not possible to catch asymmetrically */
- if ((packet->parsed_lines == 10 || (packet->parsed_lines == 11 && packet->line[11].len == 0))
+ if((packet->parsed_lines == 10 || (packet->parsed_lines == 11 && packet->line[11].len == 0))
&& packet->user_agent_line.ptr != NULL
&& packet->user_agent_line.len > 12
&& memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 ",
@@ -160,15 +174,14 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
&& packet->line[8].len > 22 && memcmp(packet->line[8].ptr, "Cache-Control: no-cache", 23) == 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Bitcomet LTS detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
-
}
/* FlashGet pattern */
- if (packet->parsed_lines == 8
+ if(packet->parsed_lines == 8
&& packet->user_agent_line.ptr != NULL
&& packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1)
&& memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;",
@@ -187,13 +200,13 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
&& packet->line[6].len > 21 && memcmp(packet->line[6].ptr, "Connection: Keep-Alive", 22) == 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
-
}
- if (packet->parsed_lines == 7
+
+ if(packet->parsed_lines == 7
&& packet->user_agent_line.ptr != NULL
&& packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1)
&& memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;",
@@ -209,19 +222,18 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
&& packet->line[5].len > 21 && memcmp(packet->line[5].ptr, "Connection: Keep-Alive", 22) == 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
-
}
/* answer to this pattern is not possible to implement asymmetrically */
while (1) {
- if (len < 50 || ptr[0] == 0x0d) {
+ if(len < 50 || ptr[0] == 0x0d) {
goto ndpi_end_bt_tracker_check;
}
- if (memcmp(ptr, "info_hash=", 10) == 0) {
+ if(memcmp(ptr, "info_hash=", 10) == 0) {
break;
}
len--;
@@ -237,40 +249,40 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
/* parse bt hash */
for (a = 0; a < 20; a++) {
- if (len < 3) {
+ if(len < 3) {
goto ndpi_end_bt_tracker_check;
}
- if (*ptr == '%') {
+ if(*ptr == '%') {
u_int8_t x1 = 0xFF;
u_int8_t x2 = 0xFF;
- if (ptr[1] >= '0' && ptr[1] <= '9') {
+ if(ptr[1] >= '0' && ptr[1] <= '9') {
x1 = ptr[1] - '0';
}
- if (ptr[1] >= 'a' && ptr[1] <= 'f') {
+ if(ptr[1] >= 'a' && ptr[1] <= 'f') {
x1 = 10 + ptr[1] - 'a';
}
- if (ptr[1] >= 'A' && ptr[1] <= 'F') {
+ if(ptr[1] >= 'A' && ptr[1] <= 'F') {
x1 = 10 + ptr[1] - 'A';
}
- if (ptr[2] >= '0' && ptr[2] <= '9') {
+ if(ptr[2] >= '0' && ptr[2] <= '9') {
x2 = ptr[2] - '0';
}
- if (ptr[2] >= 'a' && ptr[2] <= 'f') {
+ if(ptr[2] >= 'a' && ptr[2] <= 'f') {
x2 = 10 + ptr[2] - 'a';
}
- if (ptr[2] >= 'A' && ptr[2] <= 'F') {
+ if(ptr[2] >= 'A' && ptr[2] <= 'F') {
x2 = 10 + ptr[2] - 'A';
}
- if (x1 == 0xFF || x2 == 0xFF) {
+ if(x1 == 0xFF || x2 == 0xFF) {
goto ndpi_end_bt_tracker_check;
}
ptr += 3;
len -= 3;
- } else if (*ptr >= 32 && *ptr < 127) {
+ } else if(*ptr >= 32 && *ptr < 127) {
ptr++;
len--;
} else {
@@ -280,7 +292,7 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
NDPI_LOG_TRACE, " BT stat: tracker info hash parsed\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
@@ -288,7 +300,7 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
ndpi_end_bt_tracker_check:
- if (packet->payload_packet_len == 80) {
+ if(packet->payload_packet_len == 80) {
/* Warez 80 Bytes Packet
* +----------------+---------------+-----------------+-----------------+
* |20 BytesPattern | 32 Bytes Value| 12 BytesPattern | 16 Bytes Data |
@@ -306,28 +318,28 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
};
/* did not see this pattern anywhere */
- if ((memcmp(&packet->payload[0], pattern_20_bytes, 20) == 0)
+ if((memcmp(&packet->payload[0], pattern_20_bytes, 20) == 0)
&& (memcmp(&packet->payload[52], pattern_12_bytes, 12) == 0)) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
NDPI_LOG_TRACE, "BT: Warez - Plain BitTorrent protocol detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_REAL_PROTOCOL */);
return 1;
}
}
- else if (packet->payload_packet_len > 50) {
- if (memcmp(packet->payload, "GET", 3) == 0) {
+ else if(packet->payload_packet_len > 50) {
+ if(memcmp(packet->payload, "GET", 3) == 0) {
ndpi_parse_packet_line_info(ndpi_struct, flow);
/* haven't fount this pattern anywhere */
- if (packet->host_line.ptr != NULL
+ if(packet->host_line.ptr != NULL
&& packet->host_line.len >= 9 && memcmp(packet->host_line.ptr, "ip2p.com:", 9) == 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
ndpi_struct, NDPI_LOG_TRACE,
"BT: Warez - Plain BitTorrent protocol detected due to Host: ip2p.com: pattern\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */
/* NDPI_CORRELATED_PROTOCOL */);
return 1;
@@ -341,17 +353,16 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
/*Search for BitTorrent commands*/
static void ndpi_int_search_bittorrent_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
-
struct ndpi_packet_struct *packet = &flow->packet;
- if (packet->payload_packet_len == 0) {
+ if(packet->payload_packet_len == 0) {
return;
}
- if (flow->bittorrent_stage == 0 && packet->payload_packet_len != 0) {
+ if(flow->bittorrent_stage == 0 && packet->payload_packet_len != 0) {
/* exclude stage 0 detection from next run */
flow->bittorrent_stage = 1;
- if (ndpi_int_search_bittorrent_tcp_zero(ndpi_struct, flow) != 0) {
+ if(ndpi_int_search_bittorrent_tcp_zero(ndpi_struct, flow) != 0) {
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_DEBUG,
"stage 0 has detected something, returning\n");
return;
@@ -378,10 +389,10 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st
return;
}
- if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) {
+ if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) {
/* check for tcp retransmission here */
- if ((packet->tcp != NULL)
+ if((packet->tcp != NULL)
&& (packet->tcp_retransmission == 0 || packet->num_retried_bytes)) {
ndpi_int_search_bittorrent_tcp(ndpi_struct, flow);
}
@@ -400,7 +411,7 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st
if(packet->payload_packet_len >= 23 /* min header size */) {
if(strncmp((const char*)packet->payload, bt_search, strlen(bt_search)) == 0) {
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_REAL_PROTOCOL */);
return;
@@ -456,7 +467,7 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st
bittorrent_found:
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
- ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1,
NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
/* NDPI_REAL_PROTOCOL */);
return;