From 91930bb5a004106f760f94e8ede913cce466428e Mon Sep 17 00:00:00 2001 From: Nardi Ivan Date: Tue, 11 Apr 2023 18:32:43 +0200 Subject: [PATCH] Simplify `ndpi_internal_guess_undetected_protocol()` `ndpi_guess_undetected_protocol()/ndpi_internal_guess_undetected_protocol()` is a strange function: * it is exported by the library and it is actively used by `ntopng` * it is intrinsecally ipv4-only * it returns basically something like "classification_by_ip"/"classification_by_port" (these information have already been calculated in `ndpi_do_guess()`...) * it access the bittorrent LRU caches (similarly to `ndpi_detection_giveup()` but without all the other caches...) So: * make the interface IPv4/6 agnostic * use the classifications already available This work will allow to make the Bittorrent caches IPV6-aware (see 81e1ea5). Handle Dropbox classification "by-port" in the "standard" way. --- fuzz/fuzz_config.cpp | 9 ++-- src/include/ndpi_api.h | 10 +--- src/include/ndpi_protocols.h | 3 +- src/lib/ndpi_main.c | 94 ++++++++---------------------------- src/lib/protocols/tcp_udp.c | 17 +------ 5 files changed, 28 insertions(+), 105 deletions(-) diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp index 2e0a27ff4c0..177266ba782 100644 --- a/fuzz/fuzz_config.cpp +++ b/fuzz/fuzz_config.cpp @@ -156,14 +156,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_get_flow_risk_info(&flow, out, sizeof(out), 1); ndpi_get_flow_ndpi_proto(ndpi_info_mod, &flow, &p2); ndpi_is_proto(p, NDPI_PROTOCOL_TLS); - /* ndpi_guess_undetected_protocol() is a "strange" function (since is ipv4 only) - but it is exported by the library and it is used by ntopng. Try fuzzing it, here */ + /* ndpi_guess_undetected_protocol() is a "strange" function. Try fuzzing it, here */ if(!ndpi_is_protocol_detected(ndpi_info_mod, p)) { + ndpi_guess_undetected_protocol(ndpi_info_mod, bool_value ? &flow : NULL, + flow.l4_proto); if(!flow.is_ipv6) { - ndpi_guess_undetected_protocol(ndpi_info_mod, bool_value ? &flow : NULL, - flow.l4_proto, - flow.c_address.v4, flow.s_address.v4, - flow.c_port, flow.s_port); /* Another "strange" function (ipv4 only): fuzz it here, for lack of a better alternative */ ndpi_find_ipv4_category_userdata(ndpi_info_mod, flow.c_address.v4); } diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 2edcd69ad13..16dc2014df1 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -427,20 +427,12 @@ extern "C" { * @par ndpi_struct = the detection module * @par flow = the flow we're trying to guess, NULL if not available * @par proto = the l4 protocol number - * @par shost = source address in host byte order - * @par sport = source port number - * @par dhost = destination address in host byte order - * @par dport = destination port number * @return the struct ndpi_protocol that match the port base protocol * */ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int8_t proto, - u_int32_t shost, - u_int16_t sport, - u_int32_t dhost, - u_int16_t dport); + u_int8_t proto); /** * Check if the string passed match with a protocol * diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h index 422a279e4c2..443bc941b28 100644 --- a/src/include/ndpi_protocols.h +++ b/src/include/ndpi_protocols.h @@ -46,8 +46,7 @@ ndpi_port_range* ndpi_build_default_ports(ndpi_port_range *ports, u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int8_t protocol, - u_int32_t saddr, u_int32_t daddr, - u_int16_t sport, u_int16_t dport); + u_int32_t saddr, u_int32_t daddr); void init_diameter_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id); diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index c51d2a84ee6..702a7b1245d 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -7841,11 +7841,8 @@ u_int16_t ndpi_get_upper_proto(ndpi_protocol proto) { /* ****************************************************** */ static ndpi_protocol ndpi_internal_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_str, - struct ndpi_flow_struct *flow, u_int8_t proto, - u_int32_t shost /* host byte order */, u_int16_t sport, - u_int32_t dhost /* host byte order */, u_int16_t dport) { + struct ndpi_flow_struct *flow, u_int8_t proto) { u_int32_t rc; - struct in_addr addr; ndpi_protocol ret = NDPI_PROTOCOL_NULL; u_int8_t user_defined_proto; @@ -7853,79 +7850,33 @@ static ndpi_protocol ndpi_internal_guess_undetected_protocol(struct ndpi_detecti return(ret); #ifdef BITTORRENT_CACHE_DEBUG - printf("[%s:%u] ndpi_guess_undetected_protocol(%08X, %u, %08X, %u) [flow: %p]\n", - __FILE__, __LINE__, shost, sport, dhost, dport, flow); + printf("[%s:%u] [flow: %p] proto %u\n", __FILE__, __LINE__, flow, proto); #endif - if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) { - rc = ndpi_search_tcp_or_udp_raw(ndpi_str, flow, proto, shost, dhost, sport, dport); + if(flow && ((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP))) { - if(rc != NDPI_PROTOCOL_UNKNOWN) { - if(flow && (proto == IPPROTO_UDP) && - NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_not_guessable_protocol(rc)) - ; - else { - ret.app_protocol = rc, - ret.master_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto); - - if(ret.app_protocol == ret.master_protocol) - ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; - -#ifdef BITTORRENT_CACHE_DEBUG - printf("[%s:%u] Guessed %u.%u\n", __FILE__, __LINE__, ret.master_protocol, ret.app_protocol); -#endif - - ret.category = ndpi_get_proto_category(ndpi_str, ret); - return(ret); - } - } - - rc = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto); - if(rc != NDPI_PROTOCOL_UNKNOWN) { - if(flow && (proto == IPPROTO_UDP) && - NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_not_guessable_protocol(rc)) - ; - else { - ret.app_protocol = rc; - - if(rc == NDPI_PROTOCOL_TLS) - goto check_guessed_skype; - else { -#ifdef BITTORRENT_CACHE_DEBUG - printf("[%s:%u] Guessed %u.%u\n", __FILE__, __LINE__, ret.master_protocol, ret.app_protocol); -#endif - - ret.category = ndpi_get_proto_category(ndpi_str, ret); - return(ret); - } + if(flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) { + if(flow->guessed_protocol_id_by_ip != NDPI_PROTOCOL_UNKNOWN) { + ret.master_protocol = flow->guessed_protocol_id; + ret.app_protocol = flow->guessed_protocol_id_by_ip; + } else { + ret.app_protocol = flow->guessed_protocol_id; } + } else { + ret.app_protocol = flow->guessed_protocol_id_by_ip; } - if(ndpi_search_into_bittorrent_cache(ndpi_str, NULL /* flow */, - htonl(shost), htons(sport), - htonl(dhost), htons(dport))) { + if(ret.app_protocol == NDPI_PROTOCOL_UNKNOWN && + !flow->is_ipv6 && /* TODO */ + ndpi_search_into_bittorrent_cache(ndpi_str, flow, + flow->c_address.v4, flow->c_port, + flow->s_address.v4, flow->s_port)) { /* This looks like BitTorrent */ ret.app_protocol = NDPI_PROTOCOL_BITTORRENT; - ret.category = ndpi_get_proto_category(ndpi_str, ret); - -#ifdef BITTORRENT_CACHE_DEBUG - printf("[%s:%u] Guessed %u.%u\n", __FILE__, __LINE__, ret.master_protocol, ret.app_protocol); -#endif - - return(ret); - } - - check_guessed_skype: - addr.s_addr = htonl(shost); - if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE_TEAMS) { - ret.app_protocol = NDPI_PROTOCOL_SKYPE_TEAMS; - } else { - addr.s_addr = htonl(dhost); - if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE_TEAMS) - ret.app_protocol = NDPI_PROTOCOL_SKYPE_TEAMS; } - } else - ret.app_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto); + } else { + ret.app_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, 0, 0, &user_defined_proto); + } ret.category = ndpi_get_proto_category(ndpi_str, ret); @@ -7939,11 +7890,8 @@ static ndpi_protocol ndpi_internal_guess_undetected_protocol(struct ndpi_detecti /* ****************************************************** */ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_str, - struct ndpi_flow_struct *flow, u_int8_t proto, - u_int32_t shost /* host byte order */, u_int16_t sport, - u_int32_t dhost /* host byte order */, u_int16_t dport) { - ndpi_protocol p = ndpi_internal_guess_undetected_protocol(ndpi_str, flow, proto, - shost, sport, dhost, dport); + struct ndpi_flow_struct *flow, u_int8_t proto) { + ndpi_protocol p = ndpi_internal_guess_undetected_protocol(ndpi_str, flow, proto); p.master_protocol = ndpi_map_ndpi_id_to_user_proto_id(ndpi_str, p.master_protocol), p.app_protocol = ndpi_map_ndpi_id_to_user_proto_id(ndpi_str, p.app_protocol); diff --git a/src/lib/protocols/tcp_udp.c b/src/lib/protocols/tcp_udp.c index ec49e63bae5..473260adf5e 100644 --- a/src/lib/protocols/tcp_udp.c +++ b/src/lib/protocols/tcp_udp.c @@ -25,18 +25,11 @@ u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int8_t protocol, - u_int32_t saddr, u_int32_t daddr, /* host endianess */ - u_int16_t sport, u_int16_t dport) /* host endianess */ + u_int32_t saddr, u_int32_t daddr) /* host endianess */ { u_int16_t rc; struct in_addr host; - if(protocol == IPPROTO_UDP) { - if((sport == dport) && (sport == 17500)) { - return(NDPI_PROTOCOL_DROPBOX); - } - } - if(flow) return(flow->guessed_protocol_id_by_ip); else { @@ -51,7 +44,6 @@ u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struc void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - u_int16_t sport, dport; u_int proto; struct ndpi_packet_struct *packet; @@ -59,10 +51,6 @@ void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, st return; packet = &ndpi_struct->packet; - - if(packet->udp) sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); - else if(packet->tcp) sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); - else sport = dport = 0; if(packet->iph /* IPv4 Only: we need to support packet->iphv6 at some point */) { proto = ndpi_search_tcp_or_udp_raw(ndpi_struct, @@ -70,8 +58,7 @@ void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, st packet->iph ? packet->iph->protocol : packet->iphv6->ip6_hdr.ip6_un1_nxt, ntohl(packet->iph->saddr), - ntohl(packet->iph->daddr), - sport, dport); + ntohl(packet->iph->daddr)); if(proto != NDPI_PROTOCOL_UNKNOWN) ndpi_set_detected_protocol(ndpi_struct, flow, proto, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_MATCH_BY_PORT);