diff options
Diffstat (limited to 'src/lib/protocols/bittorrent.c')
-rw-r--r-- | src/lib/protocols/bittorrent.c | 123 |
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; |