aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/ndpiReader.c54
-rw-r--r--example/reader_util.c5
-rw-r--r--src/include/ndpi_api.h4
-rw-r--r--src/include/ndpi_typedefs.h2
-rw-r--r--src/lib/ndpi_analyze.c95
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");
+ }
}
/* ********************************************************************************* */