diff options
author | Luca Deri <deri@ntop.org> | 2021-03-09 12:55:14 +0100 |
---|---|---|
committer | Luca Deri <deri@ntop.org> | 2021-03-09 12:55:14 +0100 |
commit | 3032864ec9a647034599d343fad29f2f8fb11064 (patch) | |
tree | e3e2dbdc050aed6acc5930b9afc03b468d8a4869 | |
parent | db716d0ab02e47ff2b0e4edc12de9fad4222d348 (diff) |
Added Ookla detection over IPv6
-rw-r--r-- | src/include/ndpi_api.h.in | 1 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 12 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 23 | ||||
-rw-r--r-- | src/lib/protocols/ookla.c | 77 |
4 files changed, 90 insertions, 23 deletions
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in index c99e978a4..c12910609 100644 --- a/src/include/ndpi_api.h.in +++ b/src/include/ndpi_api.h.in @@ -972,6 +972,7 @@ extern "C" { ndpi_serializer *serializer); void ndpi_md5(const u_char *data, size_t data_len, u_char hash[16]); + u_int32_t ndpi_quick_hash(unsigned char *str, u_int str_len); const char* ndpi_http_method2str(ndpi_http_method m); ndpi_http_method ndpi_http_str2method(const char* method, u_int16_t method_len); diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index a00f9bdd4..36ec8db5b 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -7244,6 +7244,18 @@ uint8_t ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, /* ******************************************************************** */ + /* Based on djb2 hash - http://www.cse.yorku.ca/~oz/hash.html */ + u_int32_t ndpi_quick_hash(unsigned char *str, u_int str_len) { + u_int32_t hash = 5381, i; + + for(i=0; i<str_len; i++) + hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */ + + return hash; + } + + /* ******************************************************************** */ + void ndpi_md5(const u_char *data, size_t data_len, u_char hash[16]) { ndpi_MD5_CTX ctx; diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index cc1d39917..443fc80f8 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -930,13 +930,24 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct if(ndpi_struct->ookla_cache == NULL) ndpi_struct->ookla_cache = ndpi_lru_cache_init(1024); - if(packet->iph != NULL && ndpi_struct->ookla_cache != NULL) { - if(packet->tcp->source == htons(8080)) - ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->saddr, 1 /* dummy */); - else - ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->daddr, 1 /* dummy */); + if(ndpi_struct->ookla_cache != NULL) { + if(packet->iph != NULL) { + if(packet->tcp->source == htons(8080)) + ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->saddr, 1 /* dummy */); + else + ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->daddr, 1 /* dummy */); + } else if(packet->iphv6 != NULL) { + u_int32_t h; + + if(packet->tcp->source == htons(8080)) + h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_src, sizeof(packet->iphv6->ip6_src)); + else + h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, sizeof(packet->iphv6->ip6_dst)); + + ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, h, 1 /* dummy */); + } } - + return; } diff --git a/src/lib/protocols/ookla.c b/src/lib/protocols/ookla.c index f3c2108bc..f9c294632 100644 --- a/src/lib/protocols/ookla.c +++ b/src/lib/protocols/ookla.c @@ -1,7 +1,7 @@ /* * ookla.c * - * Copyright (C) 2018 - ntop.org + * Copyright (C) 2018-21 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,40 +23,83 @@ #include "ndpi_api.h" +/* ************************************************************* */ void ndpi_search_ookla(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { struct ndpi_packet_struct* packet = &flow->packet; u_int32_t addr = 0; - + u_int16_t eighty_eighty = htons(8080); + NDPI_LOG_DBG(ndpi_struct, "Ookla detection\n"); - if(packet->tcp->source == htons(8080)) - addr = packet->iph->saddr; - else if(packet->tcp->dest == htons(8080)) - addr = packet->iph->daddr; - else - goto ookla_exclude; - - if(ndpi_struct->ookla_cache != NULL) { - u_int16_t dummy; + if(packet->iphv6 != NULL) { + if((packet->tcp->dest == eighty_eighty) && (packet->payload_packet_len >= 3)) { + u_int32_t h; + + if((packet->payload_packet_len == 3) + && (packet->payload[0] == 0x48) /* HI\n */ + && (packet->payload[1] == 0x49) + && (packet->payload[2] == 0x0A)) { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN); + + if(ndpi_struct->ookla_cache == NULL) + ndpi_struct->ookla_cache = ndpi_lru_cache_init(1024); + + if(ndpi_struct->ookla_cache != NULL) { + /* In order to avoid creating an IPv6 LRU we hash the IPv6 address */ + h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, sizeof(packet->iphv6->ip6_dst)); + + ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, h, 1 /* dummy */); + } + return; + } else { + if(packet->tcp->source == eighty_eighty) + h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_src, sizeof(packet->iphv6->ip6_src)); + else + h = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, sizeof(packet->iphv6->ip6_dst)); + + if(ndpi_struct->ookla_cache != NULL) { + u_int16_t dummy; + + if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, h, &dummy, 0 /* Don't remove it as it can be used for other connections */)) { + NDPI_LOG_INFO(ndpi_struct, "found ookla tcp connection\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN); + return; + } + } + } + } + } else { + if(packet->tcp->source == eighty_eighty) + addr = packet->iph->saddr; + else if(packet->tcp->dest == eighty_eighty) + addr = packet->iph->daddr; + else + goto ookla_exclude; - if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, addr, &dummy, 0 /* Don't remove it as it can be used for other connections */)) { - NDPI_LOG_INFO(ndpi_struct, "found ookla tcp connection\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN); - return; + if(ndpi_struct->ookla_cache != NULL) { + u_int16_t dummy; + + if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, addr, &dummy, 0 /* Don't remove it as it can be used for other connections */)) { + NDPI_LOG_INFO(ndpi_struct, "found ookla tcp connection\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN); + return; + } } } - + ookla_exclude: NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } +/* ************************************************************* */ + void init_ookla_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("Ookla", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_OOKLA, ndpi_search_ookla, - NDPI_SELECTION_BITMASK_PROTOCOL_TCP, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); |