diff options
-rw-r--r-- | example/ndpiReader.c | 29 | ||||
-rw-r--r-- | example/reader_util.c | 11 | ||||
-rw-r--r-- | example/reader_util.h | 3 | ||||
-rw-r--r-- | src/include/ndpi_api.h | 11 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 12 | ||||
-rw-r--r-- | src/lib/ndpi_analyze.c | 131 | ||||
-rw-r--r-- | src/lib/ndpi_classify.c | 1 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 4 |
8 files changed, 197 insertions, 5 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index aad1f9eb9..22af8cfa7 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -3353,6 +3353,32 @@ void serializerUnitTest() { /* *********************************************** */ +void analyzeUnitTest() { + struct ndpi_analyze_struct *s = ndpi_init_data_analysis(32); + u_int32_t i; + + for(i=0; i<256; i++) { + ndpi_data_add_value(s, rand()*i); + // ndpi_data_add_value(s, i+1); + } + + // ndpi_data_print_window_values(s); + +#ifdef RUN_DATA_ANALYSIS_THEN_QUIT + printf("Average: [all: %f][window: %f]\n", + ndpi_data_average(s), ndpi_data_window_average(s)); + printf("Entropy: %f\n", ndpi_entropy(s)); +#endif + + ndpi_free_data_analysis(s); + +#ifdef RUN_DATA_ANALYSIS_THEN_QUIT + exit(0); +#endif +} + +/* *********************************************** */ + /** * @brief Produce bpf filter to filter ports and hosts * in order to remove a peak in terms of number of packets @@ -3929,7 +3955,8 @@ int orginal_main(int argc, char **argv) { /* Internal checks */ automataUnitTest(); serializerUnitTest(); - + // analyzeUnitTest(); + gettimeofday(&startup_time, NULL); ndpi_info_mod = ndpi_init_detection_module(); diff --git a/example/reader_util.c b/example/reader_util.c index 2e6cec674..820bd9d57 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -56,6 +56,9 @@ #define SNAP 0xaa #define BSTP 0x42 /* Bridge Spanning Tree Protocol */ +/* Keep last 32 packets */ +#define DATA_ANALUYSIS_SLIDING_WINDOW 32 + /* mask for FCF */ #define WIFI_DATA 0x2 /* 0000 0010 */ #define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */ @@ -259,6 +262,8 @@ void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) { if(flow->ndpi_flow) { ndpi_flow_free(flow->ndpi_flow); flow->ndpi_flow = NULL; } if(flow->src_id) { ndpi_free(flow->src_id); flow->src_id = NULL; } if(flow->dst_id) { ndpi_free(flow->dst_id); flow->dst_id = NULL; } + if(flow->bytes_c_to_s) ndpi_free_data_analysis(flow->bytes_c_to_s); + if(flow->bytes_s_to_c) ndpi_free_data_analysis(flow->bytes_s_to_c); } /* ***************************************************** */ @@ -693,7 +698,9 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow newflow->src_ip = iph->saddr, newflow->dst_ip = iph->daddr; newflow->src_port = htons(*sport), newflow->dst_port = htons(*dport); newflow->ip_version = version; - + newflow->bytes_c_to_s = ndpi_init_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW), + newflow->bytes_s_to_c = ndpi_init_data_analysis(DATA_ANALUYSIS_SLIDING_WINDOW); + if(version == IPVERSION) { inet_ntop(AF_INET, &newflow->src_ip, newflow->src_name, sizeof(newflow->src_name)); inet_ntop(AF_INET, &newflow->dst_ip, newflow->dst_name, sizeof(newflow->dst_name)); @@ -978,9 +985,11 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, if(src_to_dst_direction) { flow->src2dst_packets++, flow->src2dst_bytes += rawsize; flow->src2dst_l4_bytes += payload_len; + // ndpi_data_add_value(flow->bytes_c_to_s, rawsize); } else { flow->dst2src_packets++, flow->dst2src_bytes += rawsize; flow->dst2src_l4_bytes += payload_len; + // ndpi_data_add_value(flow->bytes_s_to_c, rawsize); } if(enable_payload_analyzer && (payload_len > 0)) diff --git a/example/reader_util.h b/example/reader_util.h index cf6acc7ec..62001d527 100644 --- a/example/reader_util.h +++ b/example/reader_util.h @@ -145,6 +145,9 @@ typedef struct ndpi_flow_info { // result only, not used for flow identification ndpi_protocol detected_protocol; + // Flow data analysis + struct ndpi_analyze_struct *bytes_c_to_s, *bytes_s_to_c; + char info[96]; char host_server_name[256]; char bittorent_hash[41]; diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 9350cd543..03f21d4cd 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -891,6 +891,17 @@ extern "C" { ndpi_string *key, float *value); int ndpi_deserialize_end_of_record(ndpi_deserializer *deserializer); + /* Data analysis */ + struct ndpi_analyze_struct* ndpi_init_data_analysis(u_int16_t _max_series_len); + void ndpi_free_data_analysis(struct ndpi_analyze_struct *d); + void ndpi_data_add_value(struct ndpi_analyze_struct *s, const u_int32_t value); + + float ndpi_data_average(struct ndpi_analyze_struct *s); + float ndpi_data_window_average(struct ndpi_analyze_struct *s); + + float ndpi_entropy(struct ndpi_analyze_struct *s); + + void ndpi_data_print_window_values(struct ndpi_analyze_struct *s); /* debug */ #ifdef __cplusplus } #endif diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index bdb5a76e1..2aacf847a 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1363,4 +1363,16 @@ typedef struct { u_int16_t str_len; } ndpi_string; +/* **************************************** */ + +struct ndpi_analyze_struct { + u_int32_t *values; + u_int32_t sum_total, num_data_entries, next_value_insert_index; + u_int16_t num_values_array_len /* lenght of the values array */; +}; + +#define DEFAULT_SERIES_LEN 64 +#define MAX_SERIES_LEN 512 +#define MIN_SERIES_LEN 8 + #endif /* __NDPI_TYPEDEFS_H__ */ diff --git a/src/lib/ndpi_analyze.c b/src/lib/ndpi_analyze.c new file mode 100644 index 000000000..502c2d858 --- /dev/null +++ b/src/lib/ndpi_analyze.c @@ -0,0 +1,131 @@ +/* + * ndpi_analyze.c + * + * Copyright (C) 2019 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library. + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifdef HAVE_CONFIG_H +#include "ndpi_config.h" +#endif + +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <stdint.h> +#include <math.h> +#include <float.h> /* FLT_EPSILON */ +#include "ndpi_api.h" +#include "ndpi_config.h" + +/* ********************************************************************************* */ + +struct ndpi_analyze_struct* ndpi_init_data_analysis(u_int16_t _max_series_len) { + struct ndpi_analyze_struct *ret = ndpi_malloc(sizeof(struct ndpi_analyze_struct)); + u_int32_t len; + + if(ret == NULL) + return(ret); + else + memset(ret, 0, sizeof(struct ndpi_analyze_struct)); + + if(_max_series_len > MAX_SERIES_LEN) _max_series_len = MAX_SERIES_LEN; + if(_max_series_len == 0) _max_series_len = 1; /* At least 1 element */ + ret->num_values_array_len = _max_series_len; + + len = sizeof(u_int32_t)*ret->num_values_array_len; + if((ret->values = ndpi_malloc(len)) == NULL) { + ndpi_free(ret); + ret = NULL; + } else + memset(ret->values, 0, len); + + return(ret); +} + +/* ********************************************************************************* */ + +void ndpi_free_data_analysis(struct ndpi_analyze_struct *d) { + ndpi_free(d->values); + ndpi_free(d); +} + +/* ********************************************************************************* */ + +/* + Add a new point to analyze + */ +void ndpi_data_add_value(struct ndpi_analyze_struct *s, const u_int32_t value) { + s->sum_total += value, s->num_data_entries++, s->values[s->next_value_insert_index] = value; + if(++s->next_value_insert_index == s->num_values_array_len) + s->next_value_insert_index = 0; +} + +/* ********************************************************************************* */ + +/* Compute the average on all value */ +float ndpi_data_average(struct ndpi_analyze_struct *s) { + return((float)s->sum_total / (float)s->num_data_entries); +} + +/* ********************************************************************************* */ + +/* Compute the average only on the sliding window */ +float ndpi_data_window_average(struct ndpi_analyze_struct *s) { + float sum = 0.0; + u_int16_t i, n = ndpi_min(s->num_data_entries, s->num_values_array_len); + + for(i=0; i<n; i++) + sum += s->values[i]; + + return((float)sum / (float)n); +} + +/* ********************************************************************************* */ + +/* + Compute entropy on the last sliding window values +*/ +float ndpi_entropy(struct ndpi_analyze_struct *s) { + int i; + float sum = 0.0, total = 0.0; + + for(i=0; i<s->num_values_array_len; i++) + total += s->values[i]; + + for (i=0; i<s->num_values_array_len; i++) { + float tmp = (float)s->values[i] / (float)total; + + if(tmp > FLT_EPSILON) + sum -= tmp * logf(tmp); + } + + return(sum / logf(2.0)); +} + +/* ********************************************************************************* */ + +void ndpi_data_print_window_values(struct ndpi_analyze_struct *s) { + u_int16_t i, n = ndpi_min(s->num_data_entries, s->num_values_array_len); + + for(i=0; i<n; i++) + printf("[%u: %u]", i, s->values[i]); + + printf("\n"); +} diff --git a/src/lib/ndpi_classify.c b/src/lib/ndpi_classify.c index 79cf1c234..96b2ecbb0 100644 --- a/src/lib/ndpi_classify.c +++ b/src/lib/ndpi_classify.c @@ -52,7 +52,6 @@ #include <stdlib.h> #include <stdint.h> #include <math.h> - #include "ndpi_main.h" #include "ndpi_classify.h" diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index cca061856..c8e5adaea 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -118,8 +118,8 @@ void ndpi_flow_free(void *ptr) { /* ****************************************** */ -void * ndpi_realloc(void *ptr, size_t old_size, size_t new_size) -{ +void * ndpi_realloc(void *ptr, size_t old_size, + size_t new_size) { void *ret = ndpi_malloc(new_size); if(!ret) |