Skip to content

Commit

Permalink
eDonkey: improve/update classification (#2410)
Browse files Browse the repository at this point in the history
eDonkey is definitely not as used as >10 years ago, but it seems it is
still active.

While having a basic TCP support seems easy, identification over UDP doesn't
work and it is hard to do it rightly (packets might be only 2 bytes long):
remove it.

Credits to V.G <v.gavrilov@securitycode.ru>
  • Loading branch information
IvanNardi authored May 4, 2024
1 parent 57ecbf3 commit a6fd981
Show file tree
Hide file tree
Showing 145 changed files with 160 additions and 311 deletions.
3 changes: 0 additions & 3 deletions src/include/ndpi_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1469,9 +1469,6 @@ struct ndpi_flow_struct {
/* NDPI_PROTOCOL_SOCKS */
u_int8_t socks5_stage:2, socks4_stage:2; // 0 - 3

/* NDPI_PROTOCOL_EDONKEY */
u_int8_t edonkey_stage:2; // 0 - 3

/* NDPI_PROTOCOL_FTP_CONTROL */
u_int8_t ftp_control_stage:2;

Expand Down
178 changes: 15 additions & 163 deletions src/lib/protocols/edonkey.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/*
* edonkey.c
*
* Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
*
* The signature is based on the Libprotoident library.
* Copyright (C) 2024 - ntop.org and contributors
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
Expand All @@ -30,179 +28,33 @@
#include "ndpi_api.h"
#include "ndpi_private.h"


static void ndpi_int_edonkey_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
NDPI_LOG_INFO(ndpi_struct, "found EDONKEY\n");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_EDONKEY, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
}

static int ndpi_edonkey_payload_check(const u_int8_t *data, u_int32_t len) {
if((len >= 4) && (data[0] == 0xe3) && (data[2] == 0x00) && (data[3] == 0x00))
return 1;

if((len >= 4) && (data[0] == 0xc5) && (data[2] == 0x00) && (data[3] == 0x00))
return 1;

if((len >= 2) && (data[0] == 0xe5) && (data[1] == 0x43))
return 1;

if((len >= 4) && (data[0] == 0xe5) && (data[1] == 0x08) && (data[2] == 0x78) && (data[3] == 0xda))
return 1;

if((len >= 4) && (data[0] == 0xe5) && (data[1] == 0x28) && (data[2] == 0x78) && (data[3] == 0xda))
return 1;

if((len >= 2) && (data[0] == 0xc5) && (data[1] == 0x90))
return 1;

if((len >= 2) && (data[0] == 0xc5) && (data[1] == 0x91))
return 1;

if((len == 2) && (data[0] == 0xc5) && (data[1] == 0x92))
return 1;

if((len == 2) && (data[0] == 0xc5) && (data[1] == 0x93))
return 1;

if((len >= 38 && len <= 70) && (data[0] == 0xc5) && (data[1] == 0x94))
return 1;

if((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x9a))
return 1;

if((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x9b))
return 1;

if((len == 6) && (data[0] == 0xe3) && (data[1] == 0x96))
return 1;

if((len <= 34 && ((len - 2) % 4 == 0)) && (data[0] == 0xe3) && (data[1] == 0x97))
return 1;

if((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x92))
return 1;

if((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x94))
return 1;

if((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x98))
return 1;

if((len >= 2) && (data[0] == 0xe3) && (data[1] == 0x99))
return 1;

if((len == 6) && (data[0] == 0xe3) && (data[1] == 0xa2))
return 1;

if((len >= 2) && (data[0] == 0xe3) && (data[1] == 0xa3))
return 1;

if((len == 27) && (data[0] == 0xe4) && (data[1] == 0x00))
return 1;

if((len == 529) && (data[0] == 0xe4) && (data[1] == 0x08))
return 1;

if((len == 18) && (data[0] == 0xe4) && (data[1] == 0x01) && (data[2] == 0x00) && (data[3] == 0x00))
return 1;

if((len == 523) && (data[0] == 0xe4) && (data[1] == 0x09))
return 1;

if((len == 35) && (data[0] == 0xe4) && (data[1] == 0x21))
return 1;

if((len == 19) && (data[0] == 0xe4) && (data[1] == 0x4b))
return 1;

if((len >= 2) && (data[0] == 0xe4) && (data[1] == 0x11))
return 1;

if((len == 22 || len == 38 || len == 28) && (data[0] == 0xe4) && (data[1] == 0x19))
return 1;

if((len == 35) && (data[0] == 0xe4) && (data[1] == 0x20))
return 1;

if((len == 27) && (data[0] == 0xe4) && (data[1] == 0x18))
return 1;

if((len == 27) && (data[0] == 0xe4) && (data[1] == 0x10))
return 1;

if((len == 6) && (data[0] == 0xe4) && (data[1] == 0x58))
return 1;

if((len == 4) && (data[0] == 0xe4) && (data[1] == 0x50))
return 1;

if((len == 36) && (data[0] == 0xe4) && (data[1] == 0x52))
return 1;

if((len == 48) && (data[0] == 0xe4) && (data[1] == 0x40))
return 1;

if((len == 225) && (data[0] == 0xe4) && (data[1] == 0x43))
return 1;

if((len == 19) && (data[0] == 0xe4) && (data[1] == 0x48))
return 1;

if((len == 119 || len == 69 || len == 294) && (data[0] == 0xe4) && (data[1] == 0x29))
return 1;

if((len == 119 || len == 69 || len == 294 || len == 44 || len == 269) && (data[0] == 0xe4) && (data[1] == 0x28))
return 1;

return 0;
}

static void ndpi_check_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
static void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
u_int32_t payload_len = packet->payload_packet_len;

/* Break after 10 packets. */
if(flow->packet_counter > 10) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
return;
}

/* Check if we so far detected the protocol in the request or not. */
if(flow->edonkey_stage == 0) {
NDPI_LOG_DBG2(ndpi_struct, "EDONKEY stage 0: \n");
u_int8_t protocol;
u_int32_t message_length;

if(ndpi_edonkey_payload_check(packet->payload, payload_len)) {
NDPI_LOG_DBG2(ndpi_struct, "Possible EDONKEY request detected, we will look further for the response\n");
NDPI_LOG_DBG(ndpi_struct, "search EDONKEY\n");

/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
flow->edonkey_stage = packet->packet_direction + 1;
} else
if(packet->payload_packet_len > 5) {
protocol = packet->payload[0];
/* 0xE3: Edonkey, 0xC5: eMule extensions, 0xD4: eMule compressed */
if(protocol != 0xE3 && protocol != 0xC5 && protocol != 0xD4) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
} else {
NDPI_LOG_DBG2(ndpi_struct, "EDONKEY stage %u: \n", flow->edonkey_stage);

/* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
if((flow->edonkey_stage - packet->packet_direction) == 1) {
return;
}

/* This is a packet in another direction. Check if we find the proper response. */
if(ndpi_edonkey_payload_check(packet->payload, payload_len)) {
NDPI_LOG_INFO(ndpi_struct, "found EDONKEY\n");
message_length = packet->payload_packet_len - 5;
if(message_length == le32toh(get_u_int32_t(packet->payload, 1))) {
ndpi_int_edonkey_add_connection(ndpi_struct, flow);
} else {
NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to EDONKEY, resetting the stage to 0\n");
flow->edonkey_stage = 0;
return;
}
}

if(flow->packet_counter > 5)
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}

static void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
NDPI_LOG_DBG(ndpi_struct, "search EDONKEY\n");

ndpi_check_edonkey(ndpi_struct, flow);
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}


Expand All @@ -211,7 +63,7 @@ void init_edonkey_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_
ndpi_set_bitmask_protocol_detection("eDonkey", ndpi_struct, *id,
NDPI_PROTOCOL_EDONKEY,
ndpi_search_edonkey,
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
SAVE_DETECTION_BITMASK_AS_UNKNOWN,
ADD_TO_DETECTION_BITMASK);

Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/caches_cfg/result/teams.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Confidence Unknown : 1 (flows)
Confidence Match by port : 1 (flows)
Confidence DPI (partial) : 1 (flows)
Confidence DPI : 80 (flows)
Num dissector calls: 536 (6.46 diss/flow)
Num dissector calls: 534 (6.43 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/9/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/caches_global/result/lru_ipv6_caches.pcapng.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ DPI Packets (TCP): 9 (3.00 pkts/flow)
DPI Packets (UDP): 45 (5.00 pkts/flow)
Confidence DPI (cache) : 4 (flows)
Confidence DPI : 8 (flows)
Num dissector calls: 641 (53.42 diss/flow)
Num dissector calls: 635 (52.92 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 25/7/2 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/caches_global/result/teams.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Confidence Unknown : 1 (flows)
Confidence Match by port : 1 (flows)
Confidence DPI (partial) : 5 (flows)
Confidence DPI : 76 (flows)
Num dissector calls: 536 (6.46 diss/flow)
Num dissector calls: 534 (6.43 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/9/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/caches_global/result/zoom_p2p.pcapng.out
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ DPI Packets (UDP): 49 (4.90 pkts/flow)
DPI Packets (other): 2 (1.00 pkts/flow)
Confidence DPI (partial cache): 4 (flows)
Confidence DPI : 8 (flows)
Num dissector calls: 853 (71.08 diss/flow)
Num dissector calls: 848 (70.67 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/12/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/1kxun.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ DPI Packets (UDP): 120 (1.21 pkts/flow)
Confidence Unknown : 14 (flows)
Confidence Match by port : 6 (flows)
Confidence DPI : 177 (flows)
Num dissector calls: 5040 (25.58 diss/flow)
Num dissector calls: 4961 (25.18 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/60/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/4in4tunnel.pcap.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 5 (5.00 pkts/flow)
Confidence Unknown : 1 (flows)
Num dissector calls: 196 (196.00 diss/flow)
Num dissector calls: 195 (195.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/3/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/6in6tunnel.pcap.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 2 (2.00 pkts/flow)
Confidence Unknown : 1 (flows)
Num dissector calls: 152 (152.00 diss/flow)
Num dissector calls: 151 (151.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/3/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/EAQ.pcap.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
DPI Packets (TCP): 12 (6.00 pkts/flow)
DPI Packets (UDP): 116 (4.00 pkts/flow)
Confidence DPI : 31 (flows)
Num dissector calls: 5097 (164.42 diss/flow)
Num dissector calls: 5068 (163.48 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 7 (1.40 pkts/flow)
Confidence DPI : 5 (flows)
Num dissector calls: 161 (32.20 diss/flow)
Num dissector calls: 160 (32.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/KakaoTalk_talk.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ DPI Packets (UDP): 10 (2.00 pkts/flow)
Confidence Match by port : 8 (flows)
Confidence DPI : 11 (flows)
Confidence Match by IP : 1 (flows)
Num dissector calls: 1236 (61.80 diss/flow)
Num dissector calls: 1232 (61.60 diss/flow)
LRU cache ookla: 0/2/0 (insert/search/found)
LRU cache bittorrent: 0/27/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/activision.pcap.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 4 (1.00 pkts/flow)
Confidence DPI : 4 (flows)
Num dissector calls: 360 (90.00 diss/flow)
Num dissector calls: 356 (89.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/agora-sd-rtn.pcap.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 26 (1.00 pkts/flow)
Confidence DPI : 26 (flows)
Num dissector calls: 2158 (83.00 diss/flow)
Num dissector calls: 2132 (82.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/android.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DPI Packets (other): 4 (1.00 pkts/flow)
Confidence Match by port : 2 (flows)
Confidence DPI : 60 (flows)
Confidence Match by IP : 1 (flows)
Num dissector calls: 246 (3.90 diss/flow)
Num dissector calls: 240 (3.81 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/9/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/anyconnect-vpn.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DPI Packets (other): 10 (1.00 pkts/flow)
Confidence Unknown : 2 (flows)
Confidence Match by port : 6 (flows)
Confidence DPI : 61 (flows)
Num dissector calls: 851 (12.33 diss/flow)
Num dissector calls: 837 (12.13 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/24/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/avast_securedns.pcapng.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 39 (1.00 pkts/flow)
Confidence DPI : 39 (flows)
Num dissector calls: 3120 (80.00 diss/flow)
Num dissector calls: 3081 (79.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/117/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/bfcp.pcapng.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
DPI Packets (TCP): 6 (6.00 pkts/flow)
DPI Packets (UDP): 2 (2.00 pkts/flow)
Confidence DPI : 2 (flows)
Num dissector calls: 331 (165.50 diss/flow)
Num dissector calls: 330 (165.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/bittorrent_utp.pcap.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 8 (4.00 pkts/flow)
Confidence DPI : 2 (flows)
Num dissector calls: 140 (70.00 diss/flow)
Num dissector calls: 138 (69.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 10/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/can.pcap.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DPI Packets (UDP): 8 (1.00 pkts/flow)
Confidence DPI : 8 (flows)
Num dissector calls: 872 (109.00 diss/flow)
Num dissector calls: 864 (108.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/3/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/collectd.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Guessed flow protos: 3
DPI Packets (UDP): 13 (1.62 pkts/flow)
Confidence Match by port : 3 (flows)
Confidence DPI : 5 (flows)
Num dissector calls: 482 (60.25 diss/flow)
Num dissector calls: 479 (59.88 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/9/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/cfgs/default/result/corba.pcap.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
DPI Packets (TCP): 4 (4.00 pkts/flow)
DPI Packets (UDP): 1 (1.00 pkts/flow)
Confidence DPI : 2 (flows)
Num dissector calls: 114 (57.00 diss/flow)
Num dissector calls: 113 (56.50 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
Expand Down
Loading

0 comments on commit a6fd981

Please sign in to comment.