Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify ndpi_internal_guess_undetected_protocol() #1941

Merged
merged 1 commit into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions fuzz/fuzz_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
10 changes: 1 addition & 9 deletions src/include/ndpi_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
3 changes: 1 addition & 2 deletions src/include/ndpi_protocols.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
95 changes: 21 additions & 74 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7841,91 +7841,41 @@ 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) {
u_int32_t rc;
struct in_addr addr;
struct ndpi_flow_struct *flow, u_int8_t proto) {
ndpi_protocol ret = NDPI_PROTOCOL_NULL;
u_int8_t user_defined_proto;

if(!ndpi_str)
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);

Expand All @@ -7939,11 +7889,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);
Expand Down
17 changes: 2 additions & 15 deletions src/lib/protocols/tcp_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -51,27 +44,21 @@ 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;

if(!ndpi_struct || !flow || flow->host_server_name[0] != '\0')
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,
flow,
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);
Expand Down