aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2023-07-13 21:54:51 +0200
committerLuca Deri <deri@ntop.org>2023-07-13 21:54:51 +0200
commit1f55dc511f9eb4e2bc8f880f1599f01c527a6397 (patch)
treeac48162be9a38d7ffdca002efd03cdb549c01b21
parentbd0fcb2e62e5fa1fb3f4342e605e15f1f4920efc (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.ac2
-rw-r--r--example/ndpiReader.c514
-rw-r--r--example/reader_util.c6
-rw-r--r--src/include/ndpi_api.h14
-rw-r--r--src/include/ndpi_typedefs.h6
-rw-r--r--src/lib/Makefile.in2
-rw-r--r--src/lib/ndpi_analyze.c117
-rw-r--r--src/lib/ndpi_utils.c16
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);
+}
+