diff options
author | Luca Deri <deri@ntop.org> | 2023-07-13 21:54:51 +0200 |
---|---|---|
committer | Luca Deri <deri@ntop.org> | 2023-07-13 21:54:51 +0200 |
commit | 1f55dc511f9eb4e2bc8f880f1599f01c527a6397 (patch) | |
tree | ac48162be9a38d7ffdca002efd03cdb549c01b21 | |
parent | bd0fcb2e62e5fa1fb3f4342e605e15f1f4920efc (diff) |
Implemented Count-Min Sketch [count how many times a value has been observed]
- ndpi_cm_sketch_init()
- ndpi_cm_sketch_add()
- ndpi_cm_sketch_count()
- ndpi_cm_sketch_destroy()
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | example/ndpiReader.c | 514 | ||||
-rw-r--r-- | example/reader_util.c | 6 | ||||
-rw-r--r-- | src/include/ndpi_api.h | 14 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 6 | ||||
-rw-r--r-- | src/lib/Makefile.in | 2 | ||||
-rw-r--r-- | src/lib/ndpi_analyze.c | 117 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 16 |
8 files changed, 436 insertions, 241 deletions
diff --git a/configure.ac b/configure.ac index c7f72a596..00f53e6da 100644 --- a/configure.ac +++ b/configure.ac @@ -384,6 +384,8 @@ dnl> ADDITIONAL_LIBS="${ADDITIONAL_LIBS} -lcurl" dnl> AC_DEFINE_UNQUOTED(HAVE_CURL, 1, [curl is present]) dnl> fi +CC="${CC} -fno-color-diagnostics" + AC_CONFIG_FILES([Makefile example/Makefile example/Makefile.dpdk tests/Makefile tests/unit/Makefile tests/performance/Makefile tests/dga/Makefile rrdtool/Makefile influxdb/Makefile libndpi.pc src/include/ndpi_define.h src/lib/Makefile fuzz/Makefile doc/Doxyfile.cfg]) AC_CONFIG_FILES([tests/do.sh], [chmod +x tests/do.sh]) AC_CONFIG_HEADERS(src/include/ndpi_config.h) diff --git a/example/ndpiReader.c b/example/ndpiReader.c index be85bf0cc..053cfe38b 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1562,16 +1562,16 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa if(flow->multimedia_flow_type != ndpi_multimedia_unknown_flow) { const char *content; - + switch(flow->multimedia_flow_type) { case ndpi_multimedia_audio_flow: content = "Audio"; break; - + case ndpi_multimedia_video_flow: content = "Video"; break; - + case ndpi_multimedia_screen_sharing_flow: content = "Screen Sharing"; break; @@ -1580,10 +1580,10 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa content = "???"; break; } - - fprintf(out, "[Stream Content: %s]", content); + + fprintf(out, "[Stream Content: %s]", content); } - + fprintf(out, "[%s]", ndpi_is_encrypted_proto(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol) ? "Encrypted" : "ClearText"); @@ -3611,7 +3611,7 @@ static void printResults(u_int64_t processing_time_usec, u_int64_t setup_time_us /* Automas */ for(i = 0; i < NDPI_AUTOMA_MAX; i++) { - struct ndpi_automa_stats s; + struct ndpi_automa_stats s; ndpi_get_automa_stats(ndpi_thread_info[thread_id].workflow->ndpi_struct, i, &s); cumulative_stats.automa_stats[i].n_search += s.n_search; cumulative_stats.automa_stats[i].n_found += s.n_found; @@ -3648,9 +3648,9 @@ static void printResults(u_int64_t processing_time_usec, u_int64_t setup_time_us (long long unsigned int)cumulative_stats.raw_packet_count); /* In order to prevent Floating point exception in case of no traffic*/ if(cumulative_stats.total_ip_bytes && cumulative_stats.raw_packet_count) - { - avg_pkt_size = (unsigned int)(cumulative_stats.total_ip_bytes/cumulative_stats.raw_packet_count); - } + { + avg_pkt_size = (unsigned int)(cumulative_stats.total_ip_bytes/cumulative_stats.raw_packet_count); + } printf("\tIP bytes: %-13llu (avg pkt size %u bytes)\n", (long long unsigned int)cumulative_stats.total_ip_bytes,avg_pkt_size); printf("\tUnique flows: %-13u\n", cumulative_stats.ndpi_flow_count); @@ -3668,238 +3668,238 @@ static void printResults(u_int64_t processing_time_usec, u_int64_t setup_time_us printf("\tPacket Len 1024-1500: %-13lu\n", (unsigned long)cumulative_stats.packet_len[4]); printf("\tPacket Len > 1500: %-13lu\n", (unsigned long)cumulative_stats.packet_len[5]); - if(processing_time_usec > 0) { - char buf[32], buf1[32], when[64]; - float t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)processing_time_usec; - float b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)processing_time_usec; - float traffic_duration; - struct tm result; - - if(live_capture) traffic_duration = processing_time_usec; - else traffic_duration = ((u_int64_t)pcap_end.tv_sec*1000000 + pcap_end.tv_usec) - ((u_int64_t)pcap_start.tv_sec*1000000 + pcap_start.tv_usec); - - printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); - if(traffic_duration != 0) { - t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; - b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; - } else { - t = 0; - b = 0; - } + if(processing_time_usec > 0) { + char buf[32], buf1[32], when[64]; + float t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)processing_time_usec; + float b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)processing_time_usec; + float traffic_duration; + struct tm result; + + if(live_capture) traffic_duration = processing_time_usec; + else traffic_duration = ((u_int64_t)pcap_end.tv_sec*1000000 + pcap_end.tv_usec) - ((u_int64_t)pcap_start.tv_sec*1000000 + pcap_start.tv_usec); + + printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); + if(traffic_duration != 0) { + t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; + b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; + } else { + t = 0; + b = 0; + } #ifdef WIN32 - /* localtime() on Windows is thread-safe */ - time_t tv_sec = pcap_start.tv_sec; - struct tm * tm_ptr = localtime(&tv_sec); - result = *tm_ptr; + /* localtime() on Windows is thread-safe */ + time_t tv_sec = pcap_start.tv_sec; + struct tm * tm_ptr = localtime(&tv_sec); + result = *tm_ptr; #else - localtime_r(&pcap_start.tv_sec, &result); + localtime_r(&pcap_start.tv_sec, &result); #endif - strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", &result); - printf("\tAnalysis begin: %s\n", when); + strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", &result); + printf("\tAnalysis begin: %s\n", when); #ifdef WIN32 - /* localtime() on Windows is thread-safe */ - tv_sec = pcap_end.tv_sec; - tm_ptr = localtime(&tv_sec); - result = *tm_ptr; + /* localtime() on Windows is thread-safe */ + tv_sec = pcap_end.tv_sec; + tm_ptr = localtime(&tv_sec); + result = *tm_ptr; #else - localtime_r(&pcap_end.tv_sec, &result); + localtime_r(&pcap_end.tv_sec, &result); #endif - strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", &result); - printf("\tAnalysis end: %s\n", when); - printf("\tTraffic throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); - printf("\tTraffic duration: %.3f sec\n", traffic_duration/1000000); - } + strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", &result); + printf("\tAnalysis end: %s\n", when); + printf("\tTraffic throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); + printf("\tTraffic duration: %.3f sec\n", traffic_duration/1000000); + } - if(enable_protocol_guess) - printf("\tGuessed flow protos: %-13u\n", cumulative_stats.guessed_flow_protocols); - - if(cumulative_stats.flow_count[0]) - printf("\tDPI Packets (TCP): %-13llu (%.2f pkts/flow)\n", - (long long unsigned int)cumulative_stats.dpi_packet_count[0], - cumulative_stats.dpi_packet_count[0] / (float)cumulative_stats.flow_count[0]); - if(cumulative_stats.flow_count[1]) - printf("\tDPI Packets (UDP): %-13llu (%.2f pkts/flow)\n", - (long long unsigned int)cumulative_stats.dpi_packet_count[1], - cumulative_stats.dpi_packet_count[1] / (float)cumulative_stats.flow_count[1]); - if(cumulative_stats.flow_count[2]) - printf("\tDPI Packets (other): %-13llu (%.2f pkts/flow)\n", - (long long unsigned int)cumulative_stats.dpi_packet_count[2], - cumulative_stats.dpi_packet_count[2] / (float)cumulative_stats.flow_count[2]); - - for(i = 0; i < sizeof(cumulative_stats.flow_confidence)/sizeof(cumulative_stats.flow_confidence[0]); i++) { - if(cumulative_stats.flow_confidence[i] != 0) - printf("\tConfidence: %-10s %-13llu (flows)\n", ndpi_confidence_get_name(i), - (long long unsigned int)cumulative_stats.flow_confidence[i]); - } + if(enable_protocol_guess) + printf("\tGuessed flow protos: %-13u\n", cumulative_stats.guessed_flow_protocols); + + if(cumulative_stats.flow_count[0]) + printf("\tDPI Packets (TCP): %-13llu (%.2f pkts/flow)\n", + (long long unsigned int)cumulative_stats.dpi_packet_count[0], + cumulative_stats.dpi_packet_count[0] / (float)cumulative_stats.flow_count[0]); + if(cumulative_stats.flow_count[1]) + printf("\tDPI Packets (UDP): %-13llu (%.2f pkts/flow)\n", + (long long unsigned int)cumulative_stats.dpi_packet_count[1], + cumulative_stats.dpi_packet_count[1] / (float)cumulative_stats.flow_count[1]); + if(cumulative_stats.flow_count[2]) + printf("\tDPI Packets (other): %-13llu (%.2f pkts/flow)\n", + (long long unsigned int)cumulative_stats.dpi_packet_count[2], + cumulative_stats.dpi_packet_count[2] / (float)cumulative_stats.flow_count[2]); + + for(i = 0; i < sizeof(cumulative_stats.flow_confidence)/sizeof(cumulative_stats.flow_confidence[0]); i++) { + if(cumulative_stats.flow_confidence[i] != 0) + printf("\tConfidence: %-10s %-13llu (flows)\n", ndpi_confidence_get_name(i), + (long long unsigned int)cumulative_stats.flow_confidence[i]); + } - if(dump_internal_stats) { - char buf[1024]; - - if(cumulative_stats.ndpi_flow_count) - printf("\tNum dissector calls: %-13llu (%.2f diss/flow)\n", - (long long unsigned int)cumulative_stats.num_dissector_calls, - cumulative_stats.num_dissector_calls / (float)cumulative_stats.ndpi_flow_count); - - printf("\tLRU cache ookla: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_found); - printf("\tLRU cache bittorrent: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_found); - printf("\tLRU cache zoom: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_found); - printf("\tLRU cache stun: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_found); - printf("\tLRU cache tls_cert: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_found); - printf("\tLRU cache mining: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_found); - printf("\tLRU cache msteams: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_found); - printf("\tLRU cache stun_zoom: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_found); - - printf("\tAutoma host: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_found); - printf("\tAutoma domain: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_found); - printf("\tAutoma tls cert: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_found); - printf("\tAutoma risk mask: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_found); - printf("\tAutoma common alpns: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_found); - - printf("\tPatricia risk mask: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_search, - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_found); - printf("\tPatricia risk: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_search, - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_found); - printf("\tPatricia protocols: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_search, - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_found); - - if(enable_malloc_bins) - printf("\tData-path malloc histogram: %s\n", ndpi_print_bin(&malloc_bins, 0, buf, sizeof(buf))); - } + if(dump_internal_stats) { + char buf[1024]; + + if(cumulative_stats.ndpi_flow_count) + printf("\tNum dissector calls: %-13llu (%.2f diss/flow)\n", + (long long unsigned int)cumulative_stats.num_dissector_calls, + cumulative_stats.num_dissector_calls / (float)cumulative_stats.ndpi_flow_count); + + printf("\tLRU cache ookla: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_found); + printf("\tLRU cache bittorrent: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_found); + printf("\tLRU cache zoom: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_found); + printf("\tLRU cache stun: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_found); + printf("\tLRU cache tls_cert: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_found); + printf("\tLRU cache mining: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_found); + printf("\tLRU cache msteams: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_found); + printf("\tLRU cache stun_zoom: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_found); + + printf("\tAutoma host: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_found); + printf("\tAutoma domain: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_found); + printf("\tAutoma tls cert: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_found); + printf("\tAutoma risk mask: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_found); + printf("\tAutoma common alpns: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_found); + + printf("\tPatricia risk mask: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_search, + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_found); + printf("\tPatricia risk: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_search, + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_found); + printf("\tPatricia protocols: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_search, + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_found); + + if(enable_malloc_bins) + printf("\tData-path malloc histogram: %s\n", ndpi_print_bin(&malloc_bins, 0, buf, sizeof(buf))); } + } - if(results_file) { - if(enable_protocol_guess) - fprintf(results_file, "Guessed flow protos:\t%u\n\n", cumulative_stats.guessed_flow_protocols); - - if(cumulative_stats.flow_count[0]) - fprintf(results_file, "DPI Packets (TCP):\t%llu\t(%.2f pkts/flow)\n", - (long long unsigned int)cumulative_stats.dpi_packet_count[0], - cumulative_stats.dpi_packet_count[0] / (float)cumulative_stats.flow_count[0]); - if(cumulative_stats.flow_count[1]) - fprintf(results_file, "DPI Packets (UDP):\t%llu\t(%.2f pkts/flow)\n", - (long long unsigned int)cumulative_stats.dpi_packet_count[1], - cumulative_stats.dpi_packet_count[1] / (float)cumulative_stats.flow_count[1]); - if(cumulative_stats.flow_count[2]) - fprintf(results_file, "DPI Packets (other):\t%llu\t(%.2f pkts/flow)\n", - (long long unsigned int)cumulative_stats.dpi_packet_count[2], - cumulative_stats.dpi_packet_count[2] / (float)cumulative_stats.flow_count[2]); - - for(i = 0; i < sizeof(cumulative_stats.flow_confidence)/sizeof(cumulative_stats.flow_confidence[0]); i++) { - if(cumulative_stats.flow_confidence[i] != 0) - fprintf(results_file, "Confidence %-17s: %llu (flows)\n", - ndpi_confidence_get_name(i), - (long long unsigned int)cumulative_stats.flow_confidence[i]); - } + if(results_file) { + if(enable_protocol_guess) + fprintf(results_file, "Guessed flow protos:\t%u\n\n", cumulative_stats.guessed_flow_protocols); + + if(cumulative_stats.flow_count[0]) + fprintf(results_file, "DPI Packets (TCP):\t%llu\t(%.2f pkts/flow)\n", + (long long unsigned int)cumulative_stats.dpi_packet_count[0], + cumulative_stats.dpi_packet_count[0] / (float)cumulative_stats.flow_count[0]); + if(cumulative_stats.flow_count[1]) + fprintf(results_file, "DPI Packets (UDP):\t%llu\t(%.2f pkts/flow)\n", + (long long unsigned int)cumulative_stats.dpi_packet_count[1], + cumulative_stats.dpi_packet_count[1] / (float)cumulative_stats.flow_count[1]); + if(cumulative_stats.flow_count[2]) + fprintf(results_file, "DPI Packets (other):\t%llu\t(%.2f pkts/flow)\n", + (long long unsigned int)cumulative_stats.dpi_packet_count[2], + cumulative_stats.dpi_packet_count[2] / (float)cumulative_stats.flow_count[2]); + + for(i = 0; i < sizeof(cumulative_stats.flow_confidence)/sizeof(cumulative_stats.flow_confidence[0]); i++) { + if(cumulative_stats.flow_confidence[i] != 0) + fprintf(results_file, "Confidence %-17s: %llu (flows)\n", + ndpi_confidence_get_name(i), + (long long unsigned int)cumulative_stats.flow_confidence[i]); + } - if(dump_internal_stats) { - char buf[1024]; - - if(cumulative_stats.ndpi_flow_count) - fprintf(results_file, "Num dissector calls: %llu (%.2f diss/flow)\n", - (long long unsigned int)cumulative_stats.num_dissector_calls, - cumulative_stats.num_dissector_calls / (float)cumulative_stats.ndpi_flow_count); - - fprintf(results_file, "LRU cache ookla: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_found); - fprintf(results_file, "LRU cache bittorrent: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_found); - fprintf(results_file, "LRU cache zoom: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_found); - fprintf(results_file, "LRU cache stun: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_found); - fprintf(results_file, "LRU cache tls_cert: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_found); - fprintf(results_file, "LRU cache mining: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_found); - fprintf(results_file, "LRU cache msteams: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_found); - fprintf(results_file, "LRU cache stun_zoom: %llu/%llu/%llu (insert/search/found)\n", - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_insert, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_search, - (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_found); - - fprintf(results_file, "Automa host: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_found); - fprintf(results_file, "Automa domain: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_found); - fprintf(results_file, "Automa tls cert: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_found); - fprintf(results_file, "Automa risk mask: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_found); - fprintf(results_file, "Automa common alpns: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_search, - (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_found); - - fprintf(results_file, "Patricia risk mask: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_search, - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_found); - fprintf(results_file, "Patricia risk: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_search, - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_found); - fprintf(results_file, "Patricia protocols: %llu/%llu (search/found)\n", - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_search, - (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_found); - - if(enable_malloc_bins) - fprintf(results_file, "Data-path malloc histogram: %s\n", ndpi_print_bin(&malloc_bins, 0, buf, sizeof(buf))); - } + if(dump_internal_stats) { + char buf[1024]; + + if(cumulative_stats.ndpi_flow_count) + fprintf(results_file, "Num dissector calls: %llu (%.2f diss/flow)\n", + (long long unsigned int)cumulative_stats.num_dissector_calls, + cumulative_stats.num_dissector_calls / (float)cumulative_stats.ndpi_flow_count); + + fprintf(results_file, "LRU cache ookla: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_OOKLA].n_found); + fprintf(results_file, "LRU cache bittorrent: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_BITTORRENT].n_found); + fprintf(results_file, "LRU cache zoom: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_ZOOM].n_found); + fprintf(results_file, "LRU cache stun: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN].n_found); + fprintf(results_file, "LRU cache tls_cert: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_TLS_CERT].n_found); + fprintf(results_file, "LRU cache mining: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MINING].n_found); + fprintf(results_file, "LRU cache msteams: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_MSTEAMS].n_found); + fprintf(results_file, "LRU cache stun_zoom: %llu/%llu/%llu (insert/search/found)\n", + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_insert, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_search, + (long long unsigned int)cumulative_stats.lru_stats[NDPI_LRUCACHE_STUN_ZOOM].n_found); + + fprintf(results_file, "Automa host: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_HOST].n_found); + fprintf(results_file, "Automa domain: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_DOMAIN].n_found); + fprintf(results_file, "Automa tls cert: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_TLS_CERT].n_found); + fprintf(results_file, "Automa risk mask: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_RISK_MASK].n_found); + fprintf(results_file, "Automa common alpns: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_search, + (long long unsigned int)cumulative_stats.automa_stats[NDPI_AUTOMA_COMMON_ALPNS].n_found); + + fprintf(results_file, "Patricia risk mask: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_search, + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK_MASK].n_found); + fprintf(results_file, "Patricia risk: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_search, + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_RISK].n_found); + fprintf(results_file, "Patricia protocols: %llu/%llu (search/found)\n", + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_search, + (long long unsigned int)cumulative_stats.patricia_stats[NDPI_PTREE_PROTOCOLS].n_found); + + if(enable_malloc_bins) + fprintf(results_file, "Data-path malloc histogram: %s\n", ndpi_print_bin(&malloc_bins, 0, buf, sizeof(buf))); + } - fprintf(results_file, "\n"); + fprintf(results_file, "\n"); } if(!quiet_mode) printf("\n\nDetected protocols:\n"); @@ -5283,7 +5283,7 @@ void linearUnitTest() { u_int32_t const num = NDPI_ARRAY_LENGTH(values); bool do_trace = false; int rc = ndpi_predict_linear(values, num, 2*num, &prediction); - + if(do_trace) { printf("[rc: %d][predicted value: %u]\n", rc, prediction); } @@ -5291,6 +5291,51 @@ void linearUnitTest() { /* *********************************************** */ +void sketchUnitTest() { + struct ndpi_cm_sketch *sketch; + +#if 0 + ndpi_cm_sketch_init(8); + ndpi_cm_sketch_init(16); + ndpi_cm_sketch_init(32); + ndpi_cm_sketch_init(64); + ndpi_cm_sketch_init(256); + ndpi_cm_sketch_init(512); + ndpi_cm_sketch_init(1024); + ndpi_cm_sketch_init(2048); + ndpi_cm_sketch_init(4096); + ndpi_cm_sketch_init(8192); + exit(0); +#endif + + sketch = ndpi_cm_sketch_init(32); + + if(sketch) { + u_int32_t i, num_one = 0; + bool do_trace = false; + + srand(time(NULL)); + + for(i=0; i<10000; i++) { + u_int32_t v = rand() % 1000; + + if(v == 1) num_one++; + ndpi_cm_sketch_add(sketch, v); + } + + if(do_trace) + printf("The estimated count of 1 is %u [expectedl: %u]\n", + ndpi_cm_sketch_count(sketch, 1), num_one); + + ndpi_cm_sketch_destroy(sketch); + + if(do_trace) + exit(0); + } +} + +/* *********************************************** */ + /** @brief MAIN FUNCTION **/ @@ -5330,6 +5375,7 @@ int main(int argc, char **argv) { exit(0); #endif + sketchUnitTest(); linearUnitTest(); zscoreUnitTest(); sesUnitTest(); @@ -5384,7 +5430,7 @@ int main(int argc, char **argv) { } signal(SIGINT, sigproc); - + for(i=0; i<num_loops; i++) test_lib(); @@ -5393,9 +5439,9 @@ int main(int argc, char **argv) { if(extcap_dumper) pcap_dump_close(extcap_dumper); if(extcap_fifo_h) pcap_close(extcap_fifo_h); if(ndpi_info_mod) ndpi_exit_detection_module(ndpi_info_mod); - if(enable_malloc_bins) - ndpi_free_bin(&malloc_bins); + if(enable_malloc_bins) ndpi_free_bin(&malloc_bins); if(csv_fp) fclose(csv_fp); + ndpi_free(_debug_protocols); ndpi_free(_disabled_protocols); diff --git a/example/reader_util.c b/example/reader_util.c index 1f53bd3b5..b9112b92e 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -111,8 +111,8 @@ struct payload_stats *pstats = NULL; u_int32_t max_num_packets_per_flow = 10; /* ETTA requires min 10 pkts for record. */ u_int32_t max_packet_payload_dissection = 128; u_int32_t max_num_reported_top_payloads = 25; -u_int16_t min_pattern_len = 4; -u_int16_t max_pattern_len = 8; +u_int16_t min_pattern_len = 4; +u_int16_t max_pattern_len = 8; /* *********************************************************** */ @@ -861,7 +861,7 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr; flow.src_port = htons(*sport), flow.dst_port = htons(*dport); flow.hashval = hashval = flow.protocol + ntohl(flow.src_ip) + ntohl(flow.dst_ip) - + ntohs(flow.src_port) + ntohs(flow.dst_port); + + ntohs(flow.src_port) + ntohs(flow.dst_port); #if 0 { diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 258c09ae8..ce124bbf6 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -1747,7 +1747,8 @@ extern "C" { /* ******************************* */ u_int32_t ndpi_crc32(const void* data, size_t n_bytes); - + u_int32_t ndpi_nearest_power_of_two(u_int32_t x); + /* ******************************* */ int ndpi_des_init(struct ndpi_des_struct *des, double alpha, double beta, float significance); @@ -1793,7 +1794,7 @@ extern "C" { /* ******************************* */ - /* HyperLogLog cardinality estimator */ + /* HyperLogLog cardinality estimator [count unique items] */ /* Memory lifecycle */ int ndpi_hll_init(struct ndpi_hll *hll, u_int8_t bits); @@ -1809,6 +1810,15 @@ extern "C" { /* ******************************* */ + /* Count-Min Sketch [count how many times a value has been observed] */ + + struct ndpi_cm_sketch *ndpi_cm_sketch_init(u_int16_t depth); + void ndpi_cm_sketch_add(struct ndpi_cm_sketch *sketch, u_int32_t element); + u_int32_t ndpi_cm_sketch_count(struct ndpi_cm_sketch *sketch, u_int32_t element); + void ndpi_cm_sketch_destroy(struct ndpi_cm_sketch *sketch); + + /* ******************************* */ + int ndpi_init_bin(struct ndpi_bin *b, enum ndpi_bin_family f, u_int16_t num_bins); void ndpi_free_bin(struct ndpi_bin *b); struct ndpi_bin* ndpi_clone_bin(struct ndpi_bin *b); diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index e3a649892..373a704da 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1897,6 +1897,12 @@ struct ndpi_hll { u_int8_t *registers; }; +struct ndpi_cm_sketch { + u_int16_t num_hashes; /* depth: Number of hash tables */ + u_int32_t num_hash_buckets; /* Number pf nuckets of each hash */ + u_int32_t *tables; +}; + /* **************************************** */ enum ndpi_bin_family { diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in index 7ed7fabd6..7867f5424 100644 --- a/src/lib/Makefile.in +++ b/src/lib/Makefile.in @@ -41,7 +41,7 @@ endif BUILD_MINGW = @BUILD_MINGW@ ifeq ($(OS),Darwin) -CC=clang +CC=clang -fno-color-diagnostics SONAME_FLAG= else ifneq ($(BUILD_MINGW),) diff --git a/src/lib/ndpi_analyze.c b/src/lib/ndpi_analyze.c index d9828ad62..62d14fdd4 100644 --- a/src/lib/ndpi_analyze.c +++ b/src/lib/ndpi_analyze.c @@ -266,7 +266,7 @@ void ndpi_data_print_window_values(struct ndpi_analyze_struct *s) { for(i=0; i<n; i++) printf("[%u: %" PRIu64 "]", i, s->values[i]); - + printf("\n"); } } @@ -1715,3 +1715,118 @@ u_int32_t ndpi_crc32(const void* data, size_t n_bytes) { __crc32(data, n_bytes, &crc); return crc; } + +/* ********************************************************************************* */ +/* ********************************************************************************* */ + +/* + Count-Min Sketch: Memory Usage + + https://florian.github.io/count-min-sketch/ + https://medium.com/@nehasingh18.9/count-min-sketch-for-beginners-f1e441bbe7a4 + https://sites.google.com/site/countminsketch/code + + [Depth: 8][Total memory: 1040] + [Depth: 16][Total memory: 2064] + [Depth: 32][Total memory: 4112] + [Depth: 64][Total memory: 8208] + [Depth: 256][Total memory: 32784] + [Depth: 512][Total memory: 65552] + [Depth: 1024][Total memory: 131088] + [Depth: 2048][Total memory: 262160] + [Depth: 4096][Total memory: 524304] + [Depth: 8192][Total memory: 1048592] +*/ + +#define NDPI_COUNT_MIN_SKETCH_NUM_BUCKETS 1024 + +// #define DEBUG + +struct ndpi_cm_sketch *ndpi_cm_sketch_init(u_int16_t num_hashes) { +#ifdef DEBUG + u_int32_t tot_mem; +#endif + u_int32_t len; + struct ndpi_cm_sketch *sketch; + + len = sizeof(struct ndpi_cm_sketch); + sketch = (struct ndpi_cm_sketch*)ndpi_malloc(len); + + if(!sketch) + return(NULL); + +#ifdef DEBUG + tot_mem = len; +#endif + + if(num_hashes < 2) num_hashes = 2; + + sketch->num_hashes = num_hashes; + sketch->num_hash_buckets = num_hashes * NDPI_COUNT_MIN_SKETCH_NUM_BUCKETS; + sketch->num_hash_buckets = ndpi_nearest_power_of_two(sketch->num_hash_buckets)-1, + + len = num_hashes * NDPI_COUNT_MIN_SKETCH_NUM_BUCKETS * sizeof(u_int32_t); + sketch->tables = (u_int32_t*)ndpi_calloc(num_hashes, NDPI_COUNT_MIN_SKETCH_NUM_BUCKETS * sizeof(u_int32_t)); + +#ifdef DEBUG + tot_mem += len; +#endif + +#ifdef DEBUG + printf("[Num_Hashes: %u][Total memory: %u]\n", num_hashes, tot_mem); +#endif + + if(!sketch->tables) { + ndpi_free(sketch); + return(NULL); + } + + return(sketch); +} + +/* ********************************************************************************* */ + +#define ndpi_simple_hash(value, seed) (value * seed) + +/* ********************************************************************************* */ + +void ndpi_cm_sketch_add(struct ndpi_cm_sketch *sketch, u_int32_t element) { + u_int32_t idx; + + for(idx = 1; idx <= sketch->num_hashes; idx++) { + u_int32_t hashval = ndpi_simple_hash(element, idx) & sketch->num_hash_buckets; + + sketch->tables[hashval]++; + +#ifdef DEBUG + printf("ndpi_add_sketch_add() [hash: %d][num_hash_buckets: %u][hashval: %d][value: %d]\n", + idx, sketch->num_hash_buckets, hashval, sketch->tables[hashval]); +#endif + } +} + +/* ********************************************************************************* */ + +u_int32_t ndpi_cm_sketch_count(struct ndpi_cm_sketch *sketch, u_int32_t element) { + u_int32_t min_value = INT_MAX, idx; + + for(idx = 1; idx <= sketch->num_hashes; idx++) { + u_int32_t hashval = ndpi_simple_hash(element, idx) & sketch->num_hash_buckets; + +#ifdef DEBUG + printf("ndpi_add_sketch_add() [hash: %d][num_hash_buckets: %u][hashval: %d][value: %d]\n", + idx, sketch->num_hash_buckets, hashval, sketch->tables[hashval]); +#endif + + min_value = ndpi_min(min_value, sketch->tables[hashval]); + } + + return(min_value); +} + +/* ********************************************************************************* */ + +void ndpi_cm_sketch_destroy(struct ndpi_cm_sketch *sketch) { + ndpi_free(sketch->tables); + ndpi_free(sketch); +} diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index bd7c922ad..75201e55e 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -2989,3 +2989,19 @@ char* ndpi_intoav4(unsigned int addr, char* buf, u_int16_t bufLen) { return(cp); } +/* ******************************************* */ + +/* Find the nearest (>=) value of x */ +u_int32_t ndpi_nearest_power_of_two(u_int32_t x) { + x--; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + x++; + return(x); +} + |