aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2025-05-20 15:48:56 +0200
committerGitHub <noreply@github.com>2025-05-20 15:48:56 +0200
commit0d2213f7ff154af85d8deaaaaa6537e09676574f (patch)
treee99d5c38bb86de79cc1b83c5183389c02cf0d3e5 /src
parent6512c18acf528695a54b6c4dd9aed12c7cbef0a7 (diff)
Gnutella: simplify code, to support only gtk-gnutella client (#2830)
Close #2818
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_typedefs.h3
-rw-r--r--src/lib/ndpi_main.c2
-rw-r--r--src/lib/protocols/gnutella.c277
-rw-r--r--src/lib/protocols/http.c5
4 files changed, 20 insertions, 267 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 6abe3b713..3e9f44e27 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -888,9 +888,6 @@ struct ndpi_flow_tcp_struct {
/* NDPI_PROTOCOL_IRC */
u_int8_t irc_stage;
- /* NDPI_PROTOCOL_GNUTELLA */
- u_int8_t gnutella_msg_id[3];
-
/* NDPI_PROTOCOL_NEST_LOG_SINK */
u_int8_t nest_log_sink_matches;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 8bbd747a8..55d537e4f 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1146,7 +1146,7 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP,
NDPI_PROTOCOL_WEBSOCKET,
NDPI_PROTOCOL_CROSSFIRE, NDPI_PROTOCOL_SOAP,
- NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_GNUTELLA,
+ NDPI_PROTOCOL_BITTORRENT,
NDPI_PROTOCOL_ZATTOO,
NDPI_PROTOCOL_IRC,
NDPI_PROTOCOL_IPP,
diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c
index 6a9f413b8..f0f81e376 100644
--- a/src/lib/protocols/gnutella.c
+++ b/src/lib/protocols/gnutella.c
@@ -42,22 +42,10 @@ static void ndpi_int_gnutella_add_connection(struct ndpi_detection_module_struct
static void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
-
- u_int16_t c;
NDPI_LOG_DBG(ndpi_struct, "search GNUTELLA\n");
- /* skip packets without payload */
- if (packet->payload_packet_len < 2) {
- return;
- }
if (packet->tcp != NULL) {
- /* this case works asymmetrically */
- if (packet->payload_packet_len > 10 && memcmp(packet->payload, "GNUTELLA/", 9) == 0) {
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- /* this case works asymmetrically */
if (packet->payload_packet_len > 17 && memcmp(packet->payload, "GNUTELLA CONNECT/", 17) == 0) {
ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
/* Extract some metadata HTTP-like */
@@ -66,266 +54,29 @@ static void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struc
ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len);
return;
}
-
- if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0)
- || (memcmp(packet->payload, "GET /uri-res/", 13) == 0)
- )) {
- ndpi_parse_packet_line_info(ndpi_struct, flow);
- for (c = 0; c < packet->parsed_lines; c++) {
- if ((packet->line[c].len > 19 && memcmp(packet->line[c].ptr, "User-Agent: Gnutella", 20) == 0)
- || (packet->line[c].len > 10 && memcmp(packet->line[c].ptr, "X-Gnutella-", 11) == 0)
- || (packet->line[c].len > 7 && memcmp(packet->line[c].ptr, "X-Queue:", 8) == 0)
- || (packet->line[c].len > 36 && memcmp(packet->line[c].ptr,
- "Content-Type: application/x-gnutella-", 37) == 0)) {
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- /* Extract some metadata HTTP-like */
- if(packet->user_agent_line.ptr != NULL)
- ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len);
- return;
- }
- }
- }
- if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET / HTTP", 10) == 0))) {
- ndpi_parse_packet_line_info(ndpi_struct, flow);
- if ((packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 15
- && memcmp(packet->user_agent_line.ptr, "BearShare Lite ", 15) == 0)
- || (packet->accept_line.ptr != NULL && packet->accept_line.len > 24
- && memcmp(packet->accept_line.ptr, "application n/x-gnutella", 24) == 0)) {
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- /* Extract some metadata HTTP-like */
- if(packet->user_agent_line.ptr != NULL)
- ndpi_user_agent_set(flow, packet->user_agent_line.ptr, packet->user_agent_line.len);
- }
-
- }
- /* haven't found this pattern in any trace. */
- if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0)
- || (memcmp(packet->payload, "GET /uri-res/", 13) == 0))) {
- c = 8;
- while (c < (packet->payload_packet_len - 9)) {
- if (packet->payload[c] == '?') {
- c++;
- break;
- }
- c++;
- }
-
- if (c < (packet->payload_packet_len - 9) && memcmp(&packet->payload[c], "urn:sha1:", 9) == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "detected GET /get/ or GET /uri-res/\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- }
-
- }
-
- /* answer to this packet is HTTP/1.1 ..... Content-Type: application/x-gnutella-packets,
- * it is searched in the upper paragraph. */
- if (packet->payload_packet_len > 30 && memcmp(packet->payload, "HEAD /gnutella/push-proxy?", 26) == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "detected HEAD /gnutella/push-proxy?\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- /* haven't found any trace with this pattern */
- if (packet->payload_packet_len == 46
- && memcmp(packet->payload, "\x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a", 10) == 0) {
- NDPI_LOG_DBG2(ndpi_struct,
- "detected \x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- /* haven't found any trace with this pattern */
- if (packet->payload_packet_len > 250 && memcmp(packet->payload, "GET /gnutella/", 14) == 0)
- //PATTERN IS :: GET /gnutella/tigertree/v3?urn:tree:tiger/:
- {
- const u_int16_t end = packet->payload_packet_len - 3;
-
- c = 13;
- while (c < end) {
- if ((memcmp(&packet->payload[14], "tigertree/", 10) == 0)
- || (end - c > 18 && memcmp(&packet->payload[c], "\r\nUser-Agent: Foxy", 18) == 0)
- || (end - c > 44
- && memcmp(&packet->payload[c],
- "\r\nAccept: application/tigertree-breadthfirst",
- 44) == 0) || (end - c > 10 && memcmp(&packet->payload[c], "\r\nX-Queue:", 10) == 0)
- || (end - c > 13 && memcmp(&packet->payload[c], "\r\nX-Features:", 13) == 0)) {
-
- NDPI_LOG_DBG2(ndpi_struct, "FOXY :: GNUTELLA GET 2 DETECTED\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
-
- c++;
- }
- }
- /* haven't found any trace with this pattern */
- if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == 0x0a
- && packet->payload[packet->payload_packet_len - 2] == 0x0a) {
- if (packet->payload_packet_len > 3 && memcmp(packet->payload, "GIV", 3) == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "MORPHEUS GIV DETECTED\n");
- /* Not Excluding the flow now.. We shall Check the next Packet too for Gnutella Patterns */
- return;
- }
- }
- /* might be super tricky new ssl gnutella transmission, but the certificate is strange... */
- if (packet->payload_packet_len == 46 && get_u_int32_t(packet->payload, 0) == htonl(0x802c0103) &&
- get_u_int32_t(packet->payload, 4) == htonl(0x01000300) && get_u_int32_t(packet->payload, 8) == htonl(0x00002000) &&
- get_u_int16_t(packet->payload, 12) == htons(0x0034)) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella len == 46\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- if (packet->payload_packet_len == 49 &&
- memcmp(packet->payload, "\x80\x2f\x01\x03\x01\x00\x06\x00\x00\x00\x20\x00\x00\x34\x00\x00\xff\x4d\x6c",
- 19) == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella len == 49\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- if (packet->payload_packet_len == 89 && memcmp(&packet->payload[43], "\x20\x4d\x6c", 3) == 0 &&
- memcmp(packet->payload, "\x16\x03\x01\x00\x54\x01\x00\x00\x50\x03\x01\x4d\x6c", 13) == 0 &&
- memcmp(&packet->payload[76], "\x00\x02\x00\x34\x01\x00\x00\x05", 8) == 0) {
- NDPI_LOG_DBG2(ndpi_struct,
- "detected gnutella asymmetrically len == 388.\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- } else if (packet->payload_packet_len == 82) {
- if (get_u_int32_t(packet->payload, 0) == htonl(0x16030100)
- && get_u_int32_t(packet->payload, 4) == htonl(0x4d010000)
- && get_u_int16_t(packet->payload, 8) == htons(0x4903)
- && get_u_int16_t(packet->payload, 76) == htons(0x0002)
- && get_u_int32_t(packet->payload, 78) == htonl(0x00340100)) {
- NDPI_LOG_DBG2(ndpi_struct, "detected len == 82\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- }
} else if (packet->udp != NULL) {
/* Check for Mojito-DHT encapsulated gnutella (gtk-gnutella). */
- if (packet->payload_packet_len >= 28 &&
- ntohl(get_u_int32_t(packet->payload, 24)) == 0x47544b47 /* GTKG */)
- {
- u_int32_t gnutella_payload_len = le32toh(get_u_int32_t(packet->payload, 19));
-
- if (gnutella_payload_len == (u_int32_t)packet->payload_packet_len - 23)
- {
- NDPI_LOG_DBG2(ndpi_struct, "detected mojito-dht/gnutella udp\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- }
-
- /* observations:
- * all the following patterns send out many packets which are the only ones of their flows,
- * often on the very beginning of the traces, or flows with many packets in one direction only.
- * but then suddenly, one gets an answer as you can see in netpeker-gnutella-rpc.pcap packet 11483.
- * Maybe gnutella tries to send out keys?
- */
- if (packet->payload_packet_len == 23 && packet->payload[15] == 0x00
- && packet->payload[16] == 0x41 && packet->payload[17] == 0x01
- && packet->payload[18] == 0x00 && packet->payload[19] == 0x00
- && packet->payload[20] == 0x00 && packet->payload[21] == 0x00 && packet->payload[22] == 0x00) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 23\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
-
- return;
- }
- if (packet->payload_packet_len == 35 && packet->payload[25] == 0x49
- && packet->payload[26] == 0x50 && packet->payload[27] == 0x40
- && packet->payload[28] == 0x83 && packet->payload[29] == 0x53
- && packet->payload[30] == 0x43 && packet->payload[31] == 0x50 && packet->payload[32] == 0x41) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 35\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- if (packet->payload_packet_len == 32
- && (memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00\x4c\x49\x4d\x45", 11) == 0)) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 32\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- if (packet->payload_packet_len == 34 && (memcmp(&packet->payload[25], "SCP@", 4) == 0)
- && (memcmp(&packet->payload[30], "DNA@", 4) == 0)) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 34\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- if ((packet->payload_packet_len == 73 || packet->payload_packet_len == 96)
- && memcmp(&packet->payload[32], "urn:sha1:", 9) == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 73,96\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
-
- if (packet->payload_packet_len >= 3 && memcmp(packet->payload, "GND", 3) == 0) {
- if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0))
- || (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5)
- == 0)) || (packet->payload_packet_len == 17
- &&
- (memcmp
- (&packet->payload[6], "\x01\x01\x4c\x05\x50",
- 5) == 0))
- || (packet->payload_packet_len == 28
- && (memcmp(&packet->payload[6], "\x01\x01\x54\x0f\x51\x4b\x52\x50\x06\x52", 10) == 0))
- || (packet->payload_packet_len == 41
- && (memcmp(&packet->payload[6], "\x01\x01\x5c\x1b\x50\x55\x53\x48\x48\x10", 10) == 0))
- || (packet->payload_packet_len > 200 && packet->payload_packet_len < 300 && packet->payload[3] == 0x03)
- || (packet->payload_packet_len > 300 && (packet->payload[3] == 0x01 || packet->payload[3] == 0x03))) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, GND\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
+ if (packet->payload_packet_len > 23) {
+ u_int32_t gnutella_payload_len = le32toh(get_u_int32_t(packet->payload, 19));
+
+ /* Some of the Mojito-DHT packets have also this pattern:
+ ntohl(get_u_int32_t(packet->payload, 24)) == 0x47544b47 GTKG
+ but not all of them, and sometime not the first packets in the flow.
+ If the following check is not enough to avoid false positives, we could add
+ that pattern back somehow... */
+
+ if (gnutella_payload_len == (u_int32_t)packet->payload_packet_len - 23) {
+ NDPI_LOG_DBG2(ndpi_struct, "detected mojito-dht/gnutella udp\n");
+ ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
+ return;
}
}
+
if (packet->payload_packet_len >= 4 && memcmp(packet->payload, "GND\x10", 4) == 0) {
NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, GND (2)\n");
ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
return;
}
-
- if ((packet->payload_packet_len == 32)
- && memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00", 7) == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 32 ii\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- if ((packet->payload_packet_len == 23)
- && memcmp(&packet->payload[16], "\x00\x01\x00\x00\x00\x00\x00", 7) == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "detected gnutella udp, len = 23 ii\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- }
- //neonet detection follows
-
- /* haven't found any trace with this pattern */
- if (packet->tcp != NULL && ntohs(packet->tcp->source) >= 1024 && ntohs(packet->tcp->dest) >= 1024) {
- if (flow->l4.tcp.gnutella_stage == 0) {
- if (flow->packet_counter == 1
- && (packet->payload_packet_len == 11
- || packet->payload_packet_len == 33 || packet->payload_packet_len == 37)) {
- flow->l4.tcp.gnutella_msg_id[0] = packet->payload[4];
- flow->l4.tcp.gnutella_msg_id[1] = packet->payload[6];
- flow->l4.tcp.gnutella_msg_id[2] = packet->payload[8];
- flow->l4.tcp.gnutella_stage = 1 + packet->packet_direction;
- return;
- }
- } else if (flow->l4.tcp.gnutella_stage == 1 + packet->packet_direction) {
- if (flow->packet_counter == 2 && (packet->payload_packet_len == 33 || packet->payload_packet_len == 22)
- && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0]
- && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2]
- && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]) {
- NDPI_LOG_DBG2(ndpi_struct, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- } else if (flow->l4.tcp.gnutella_stage == 2 - packet->packet_direction) {
- if (flow->packet_counter == 2 && (packet->payload_packet_len == 10 || packet->payload_packet_len == 75)
- && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0]
- && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2]
- && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]) {
- NDPI_LOG_DBG2(ndpi_struct, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n");
- ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
- return;
- }
- }
}
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index c9dbd36fe..2fc9331d3 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -651,6 +651,11 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UBNTAC2, master_protocol, NDPI_CONFIDENCE_DPI);
}
+ if ((flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) &&
+ flow->http.user_agent && strstr(flow->http.user_agent, "gtk-gnutella")) {
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GNUTELLA, master_protocol, NDPI_CONFIDENCE_DPI);
+ }
+
if(flow->http.request_header_observed) {
if(flow->http.first_payload_after_header_observed == 0) {
/* Skip the last part of the HTTP request */