diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2025-05-20 15:48:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-20 15:48:56 +0200 |
commit | 0d2213f7ff154af85d8deaaaaa6537e09676574f (patch) | |
tree | e99d5c38bb86de79cc1b83c5183389c02cf0d3e5 /src | |
parent | 6512c18acf528695a54b6c4dd9aed12c7cbef0a7 (diff) |
Gnutella: simplify code, to support only gtk-gnutella client (#2830)
Close #2818
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_typedefs.h | 3 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/gnutella.c | 277 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 5 |
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 */ |