diff options
-rw-r--r-- | example/ndpiReader.c | 54 | ||||
-rw-r--r-- | example/reader_util.c | 5 | ||||
-rw-r--r-- | src/include/ndpi_api.h | 4 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 2 | ||||
-rw-r--r-- | src/lib/ndpi_analyze.c | 95 |
5 files changed, 107 insertions, 53 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 20518c446..e77630f1e 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -75,8 +75,8 @@ static char *_jsonFilePath = NULL; /**< JSON file path */ static FILE *stats_fp = NULL; /**< for Top Stats JSON file */ #endif #ifdef HAVE_JSON_C -static json_object *jArray_known_flows, *jArray_unknown_flows; -static json_object *jArray_topStats; +static json_object *jArray_known_flows = NULL, *jArray_unknown_flows = NULL; +static json_object *jArray_topStats = NULL; #endif static u_int8_t live_capture = 0; static u_int8_t undetected_flows_deleted = 0; @@ -107,7 +107,7 @@ static time_t capture_until = 0; static u_int32_t num_flows; static struct ndpi_detection_module_struct *ndpi_info_mod = NULL; -extern u_int32_t max_num_packets_per_flow, max_packet_payload_dissection; +extern u_int32_t max_num_packets_per_flow, max_packet_payload_dissection, max_num_reported_top_payloads; extern u_int16_t min_pattern_len, max_pattern_len; struct flow_info { @@ -328,7 +328,7 @@ flowGetBDMeanandVariance(struct ndpi_flow_info* flow) { if(num_bytes != 0) { double entropy = ndpi_flow_get_byte_count_entropy(array, num_bytes); - + fprintf(out, "[entropy: %f]", entropy); fprintf(out, "[total_entropy: %f]", entropy * num_bytes); } @@ -369,12 +369,13 @@ static void help(u_int long_help) { " -J | Display flow SPLT (sequence of packet length and time)\n" " | and BD (byte distribution). See https://github.com/cisco/joy\n" " -t | Dissect GTP/TZSP tunnels\n" - " -P <a>:<b>:<c>:<d> | Enable payload analysis:\n" + " -P <a>:<b>:<c>:<d>:<e> | Enable payload analysis:\n" " | <a> = min pattern len to search\n" " | <b> = max pattern len to search\n" " | <c> = max num packets per flow\n" " | <d> = max packet payload dissection\n" - " | Default: %u:%u:%u:%u\n" + " | <d> = max num reported payloads\n" + " | Default: %u:%u:%u:%u:%u\n" " -r | Print nDPI version and git revision\n" " -c <path> | Load custom categories from the specified file\n" " -w <path> | Write test output on the specified file. This is useful for\n" @@ -395,8 +396,7 @@ static void help(u_int long_help) { , human_readeable_string_len, min_pattern_len, max_pattern_len, max_num_packets_per_flow, max_packet_payload_dissection, - max_num_tcp_dissected_pkts, max_num_udp_dissected_pkts - ); + max_num_reported_top_payloads, max_num_tcp_dissected_pkts, max_num_udp_dissected_pkts); #ifndef WIN32 printf("\nExcap (wireshark) options:\n" @@ -707,18 +707,24 @@ static void parseOptions(int argc, char **argv) { case 'P': { - int _min_pattern_len, _max_pattern_len, _max_num_packets_per_flow, _max_packet_payload_dissection; + int _min_pattern_len, _max_pattern_len, + _max_num_packets_per_flow, _max_packet_payload_dissection, + _max_num_reported_top_payloads; enable_payload_analyzer = 1; - if(sscanf(optarg, "%d:%d:%d:%d", &_min_pattern_len, &_max_pattern_len, - &_max_num_packets_per_flow, &_max_packet_payload_dissection) == 4) { + if(sscanf(optarg, "%d:%d:%d:%d:%d", &_min_pattern_len, &_max_pattern_len, + &_max_num_packets_per_flow, + &_max_packet_payload_dissection, + &_max_num_reported_top_payloads) == 5) { min_pattern_len = _min_pattern_len, max_pattern_len = _max_pattern_len; max_num_packets_per_flow = _max_num_packets_per_flow, max_packet_payload_dissection = _max_packet_payload_dissection; + max_num_reported_top_payloads = _max_num_reported_top_payloads; if(min_pattern_len > max_pattern_len) min_pattern_len = max_pattern_len; if(min_pattern_len < 2) min_pattern_len = 2; if(max_pattern_len > 16) max_pattern_len = 16; if(max_num_packets_per_flow == 0) max_num_packets_per_flow = 1; if(max_packet_payload_dissection < 4) max_packet_payload_dissection = 4; + if(max_num_reported_top_payloads == 0) max_num_reported_top_payloads = 1; } else { printf("Invalid -P format. Ignored\n"); help(0); @@ -1844,9 +1850,20 @@ static void json_init() { * @brief JSON destroy function */ static void json_destroy() { - json_object_put(jArray_known_flows); - json_object_put(jArray_unknown_flows); - json_object_put(jArray_topStats); + if(jArray_known_flows) { + json_object_put(jArray_known_flows); + jArray_known_flows = NULL; + } + + if(jArray_unknown_flows) { + json_object_put(jArray_unknown_flows); + jArray_unknown_flows = NULL; + } + + if(jArray_topStats) { + json_object_put(jArray_topStats); + jArray_topStats = NULL; + } } #endif @@ -3383,6 +3400,8 @@ void serializerUnitTest() { /* *********************************************** */ +// #define RUN_DATA_ANALYSIS_THEN_QUIT 1 + void analyzeUnitTest() { struct ndpi_analyze_struct *s = ndpi_init_data_analysis(32); u_int32_t i; @@ -3397,7 +3416,10 @@ void analyzeUnitTest() { #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)); + printf("Entropy: %f\n", ndpi_data_entropy(s)); + + printf("Min/Max: %u/%u\n", + ndpi_data_min(s), ndpi_data_max(s)); #endif ndpi_free_data_analysis(s); @@ -3985,7 +4007,7 @@ int orginal_main(int argc, char **argv) { /* Internal checks */ automataUnitTest(); serializerUnitTest(); - // analyzeUnitTest(); + 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 136d7ea5b..0a49dbace 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -105,6 +105,7 @@ struct payload_stats { struct payload_stats *pstats = NULL; u_int32_t max_num_packets_per_flow = 32; 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; @@ -237,14 +238,14 @@ void print_payload_stat(struct payload_stats *p) { void ndpi_report_payload_stats() { struct payload_stats *p, *tmp; - u_int num = 0, max_num = 25; + u_int num = 0; printf("\n\nPayload Analysis\n"); HASH_SORT(pstats, payload_stats_sort_asc); HASH_ITER(hh, pstats, p, tmp) { - if(num <= max_num) + if(num <= max_num_reported_top_payloads) print_payload_stat(p); free(p->pattern); diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 12387cd70..97ae56b86 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -906,7 +906,11 @@ extern "C" { float ndpi_data_entropy(struct ndpi_analyze_struct *s); float ndpi_data_variance(struct ndpi_analyze_struct *s); float ndpi_data_stddev(struct ndpi_analyze_struct *s); + u_int32_t ndpi_data_min(struct ndpi_analyze_struct *s); + u_int32_t ndpi_data_max(struct ndpi_analyze_struct *s); float ndpi_data_ratio(u_int32_t sent, u_int32_t rcvd); + + const char* ndpi_data_ratio2str(float ratio); void ndpi_data_print_window_values(struct ndpi_analyze_struct *s); /* debug */ diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 9ffb2d5c4..679cb3993 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1380,7 +1380,7 @@ typedef struct { struct ndpi_analyze_struct { u_int32_t *values; - u_int32_t sum_total, num_data_entries, next_value_insert_index; + u_int32_t min_val, max_val, sum_total, num_data_entries, next_value_insert_index; u_int16_t num_values_array_len /* lenght of the values array */; struct { diff --git a/src/lib/ndpi_analyze.c b/src/lib/ndpi_analyze.c index eb36cb516..68f6a7aeb 100644 --- a/src/lib/ndpi_analyze.c +++ b/src/lib/ndpi_analyze.c @@ -46,15 +46,17 @@ struct ndpi_analyze_struct* ndpi_init_data_analysis(u_int16_t _max_series_len) { 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; + if(ret->num_values_array_len > 0) { + 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); } else - memset(ret->values, 0, len); + ret->values = NULL; return(ret); } @@ -62,7 +64,7 @@ struct ndpi_analyze_struct* ndpi_init_data_analysis(u_int16_t _max_series_len) { /* ********************************************************************************* */ void ndpi_free_data_analysis(struct ndpi_analyze_struct *d) { - ndpi_free(d->values); + if(d->values) ndpi_free(d->values); ndpi_free(d); } @@ -74,11 +76,22 @@ 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 tmp_mu; - s->sum_total += value, s->num_data_entries++, s->values[s->next_value_insert_index] = value; + if(s->sum_total == 0) + s->min_val = s->max_val = value; + else { + if(value < s->min_val) s->min_val = value; + if(value > s->max_val) s->max_val = value; + } - if(++s->next_value_insert_index == s->num_values_array_len) - s->next_value_insert_index = 0; + s->sum_total += value, s->num_data_entries++; + + if(s->num_values_array_len) { + 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; + } + /* Update stddev */ tmp_mu = s->stddev.mu; s->stddev.mu = ((s->stddev.mu * (s->num_data_entries - 1)) + value) / s->num_data_entries; @@ -94,6 +107,12 @@ float ndpi_data_average(struct ndpi_analyze_struct *s) { /* ********************************************************************************* */ +/* Return min/max on all values */ +u_int32_t ndpi_data_min(struct ndpi_analyze_struct *s) { return(s->min_val); } +u_int32_t ndpi_data_max(struct ndpi_analyze_struct *s) { return(s->max_val); } + +/* ********************************************************************************* */ + /* Compute the variance on all values */ float ndpi_data_variance(struct ndpi_analyze_struct *s) { return(s->num_data_entries ? (s->stddev.q / s->num_data_entries) : 0); @@ -110,13 +129,16 @@ float ndpi_data_stddev(struct ndpi_analyze_struct *s) { /* 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); + if(s->num_values_array_len) { + 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); + for(i=0; i<n; i++) + sum += s->values[i]; + + return((float)sum / (float)n); + } else + return(0); } /* ********************************************************************************* */ @@ -125,31 +147,36 @@ float ndpi_data_window_average(struct ndpi_analyze_struct *s) { Compute entropy on the last sliding window values */ float ndpi_data_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]; + if(s->num_values_array_len) { + int i; + float sum = 0.0, total = 0.0; - for (i=0; i<s->num_values_array_len; i++) { - float tmp = (float)s->values[i] / (float)total; + for(i=0; i<s->num_values_array_len; i++) + total += s->values[i]; - if(tmp > FLT_EPSILON) - sum -= tmp * logf(tmp); - } - - return(sum / logf(2.0)); + 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)); + } else + return(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"); + if(s->num_values_array_len) { + 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"); + } } /* ********************************************************************************* */ |