aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/intrusion_detection.c445
-rw-r--r--example/intrusion_detection.h34
-rw-r--r--example/ndpiReader.c76
-rw-r--r--example/reader_util.c45
-rw-r--r--example/reader_util.h10
5 files changed, 599 insertions, 11 deletions
diff --git a/example/intrusion_detection.c b/example/intrusion_detection.c
new file mode 100644
index 000000000..216432e8f
--- /dev/null
+++ b/example/intrusion_detection.c
@@ -0,0 +1,445 @@
+#include "intrusion_detection.h"
+
+double normalize(ndpi_norm_value* tresholds){
+ if(tresholds->upper_bound != tresholds->lower_bound){
+ tresholds->norm_value = (tresholds->value - tresholds->lower_bound) / (tresholds->upper_bound - tresholds->lower_bound);
+ }else{
+ if(tresholds->value > tresholds->upper_bound){
+ tresholds->norm_value = 1 + (tresholds->value - tresholds->lower_bound) / tresholds->upper_bound;
+ }else{
+ tresholds->norm_value = 1 - (tresholds->value - tresholds->lower_bound) / tresholds->upper_bound;
+ }
+
+ }
+ if(tresholds->norm_value >= 0){
+ return tresholds->norm_value * tresholds->weight;
+ }
+ else{
+ return (1 - tresholds->norm_value) * tresholds->weight;
+ }
+}
+
+double get_flow_score(ndpi_norm_value* scores, int n_metrics){
+ double flow_score = 0;
+ for(int i=0; i<n_metrics; i++){
+ flow_score += normalize(&scores[i]);
+ }
+ return flow_score;
+}
+
+/* ********************************** */
+
+double Ddos_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* pktlen_c_to_s_avg */
+ int i = 0;
+ scores[i].lower_bound = 70.0;
+ scores[i].upper_bound = 263.4799999999999;
+ scores[i].weight = 0.21257330032661592;
+ scores[i].value = ndpi_data_average(flow->pktlen_c_to_s);
+
+ /* pktlen_s_to_c_max */
+ i++;
+ scores[i].lower_bound = 90.0;
+ scores[i].upper_bound = 2974.0;
+ scores[i].weight = 0.21073785073559176;
+ scores[i].value = ndpi_data_max(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_avg */
+ i++;
+ scores[i].lower_bound = 72.7;
+ scores[i].upper_bound = 1130.4199999999996;
+ scores[i].weight = 0.21257330032661592;
+ scores[i].value = ndpi_data_average(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_stddev */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 906.0;
+ scores[i].weight = 0.20990954527912953;
+ scores[i].value = ndpi_data_stddev(flow->pktlen_s_to_c);
+
+ /* fin */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.07710300166602348;
+ scores[i].value = flow->fin_count;
+
+ /* s_to_c_fin */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.07710300166602348;
+ scores[i].value = flow->dst2src_fin_count;
+
+ // sum = 1.0
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
+
+double Dos_goldeneye_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* pktlen_s_to_c_max */
+ int i = 0;
+ scores[i].lower_bound = 74.0;
+ scores[i].upper_bound = 3292.6699999999764;
+ scores[i].weight = 0.3123007140611667;
+ scores[i].value = ndpi_data_max(flow->pktlen_s_to_c);
+ /* pktlen_s_to_c_avg */
+ i++;
+ scores[i].lower_bound = 68.7;
+ scores[i].upper_bound = 1354.0569999999987;
+ scores[i].weight = 0.23802038891633356;
+ scores[i].value = ndpi_data_average(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_stddev */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 959.4469999999993;
+ scores[i].weight = 0.3111779763775991;
+ scores[i].value = ndpi_data_stddev(flow->pktlen_s_to_c);
+
+ /* syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.0464364305923564;
+ scores[i].value = flow->syn_count;
+
+ /* c_to_s_syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 1.0;
+ scores[i].weight = 0.04562805946018772;
+ scores[i].value = flow->src2dst_syn_count;
+
+ /* s_to_c_syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.0464364305923564;
+ scores[i].value = flow->dst2src_syn_count;
+
+ // sum = 0.9999999999999998
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
+
+double Dos_hulk_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* duration */
+ int i = 0;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 539.40668006422;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = (l - f);
+
+ /* src2dst_packets */
+ i++;
+ scores[i].lower_bound = 2.0;
+ scores[i].upper_bound = 41.0;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = flow->src2dst_packets;
+
+ /* dst2src_packets */
+ i++;
+ scores[i].lower_bound = 2.0;
+ scores[i].upper_bound = 45.0;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = flow->dst2src_packets;
+
+ /* src2dst_bytes */
+ i++;
+ scores[i].lower_bound = 146.0;
+ scores[i].upper_bound = 6306.300000000001;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = flow->src2dst_bytes;
+
+ /* ack */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 82.0;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = flow->ack_count;
+
+ /* syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = flow->syn_count;
+
+ // sum = 0.9999999999999999
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
+
+double Dos_slow_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* pktlen_s_to_c_max */
+ int i = 0;
+ scores[i].lower_bound = 90.0;
+ scores[i].upper_bound = 3135.0;
+ scores[i].weight = 0.1760747755022144;
+ scores[i].value = ndpi_data_max(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_avg */
+ i++;
+ scores[i].lower_bound = 80.37100000000001;
+ scores[i].upper_bound = 1292.5900000000008;
+ scores[i].weight = 0.17600137023171597;
+ scores[i].value = ndpi_data_average(flow->pktlen_s_to_c);
+
+ /* dst2src_bytes */
+ i++;
+ scores[i].lower_bound = 262.0;
+ scores[i].upper_bound = 53227.80000000002;
+ scores[i].weight = 0.16919914849886225;
+ scores[i].value = flow->dst2src_bytes;
+
+ /* syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.168000195747388;
+ scores[i].value = flow->syn_count;
+
+ /* c_to_s_syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 1.0;
+ scores[i].weight = 0.14272431427243143;
+ scores[i].value = flow->src2dst_syn_count;
+
+ /* s_to_c_syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.168000195747388;
+ scores[i].value = flow->dst2src_syn_count;
+
+ // sum = 1.0
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
+
+double Ftp_patator_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* iat_flow_min */
+ int i = 0;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 24.0;
+ scores[i].weight = 0.002732919254658385;
+ scores[i].value = ndpi_data_min(flow->iat_flow);
+
+ /* pktlen_s_to_c_max */
+ i++;
+ scores[i].lower_bound = 90.0;
+ scores[i].upper_bound = 3393.0;
+ scores[i].weight = 0.007453416149068323;
+ scores[i].value = ndpi_data_max(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_avg */
+ i++;
+ scores[i].lower_bound = 81.3;
+ scores[i].upper_bound = 1315.021;
+ scores[i].weight = 0.9833540372670807;
+ scores[i].value = ndpi_data_average(flow->pktlen_s_to_c);
+
+ /* dst2src_bytes */
+ i++;
+ scores[i].lower_bound = 256.0;
+ scores[i].upper_bound = 56434.0;
+ scores[i].weight = 0.0034782608695652175;
+ scores[i].value = flow->dst2src_bytes;
+
+ /* fin */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.0014906832298136647;
+ scores[i].value = flow->fin_count;
+
+ /* rst */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.0014906832298136647;
+ scores[i].value = flow->rst_count;
+
+ // sum = 1.0
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
+
+double Hearthbleed_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* iat_flow_max */
+ int i = 0;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 595213.3999999999;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = ndpi_data_max(flow->iat_flow);
+
+ /* iat_flow_stddev */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 245377.74799999973;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = ndpi_data_stddev(flow->iat_flow);
+
+ /* pktlen_s_to_c_max */
+ i++;
+ scores[i].lower_bound = 74.0;
+ scores[i].upper_bound = 3380.0;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = ndpi_data_max(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_avg */
+ i++;
+ scores[i].lower_bound = 70.0;
+ scores[i].upper_bound = 1344.6399999999996;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = ndpi_data_average(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_stddev */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 944.6399999999996;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = ndpi_data_stddev(flow->pktlen_s_to_c);
+
+ /* duration */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 711.6677598000391;
+ scores[i].weight = 0.16666666666666666;
+ scores[i].value = (l - f);
+
+ // sum = 0.9999999999999999
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
+
+double Infiltration_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* pktlen_c_to_s_max */
+ int i = 0;
+ scores[i].lower_bound = 72.0;
+ scores[i].upper_bound = 1840.739999999998;
+ scores[i].weight = 0.11937557392102846;
+ scores[i].value = ndpi_data_max(flow->pktlen_c_to_s);
+
+ /* pktlen_c_to_s_avg */
+ i++;
+ scores[i].lower_bound = 70.0;
+ scores[i].upper_bound = 296.56599999999816;
+ scores[i].weight = 0.12526782981328435;
+ scores[i].value = ndpi_data_average(flow->pktlen_c_to_s);
+
+ /* pktlen_s_to_c_max */
+ i++;
+ scores[i].lower_bound = 90.0;
+ scores[i].upper_bound = 3496.1399999999776;
+ scores[i].weight = 0.13927150290786652;
+ scores[i].value = ndpi_data_max(flow->pktlen_s_to_c);
+
+ /* pktlen_s_to_c_avg */
+ i++;
+ scores[i].lower_bound = 72.6;
+ scores[i].upper_bound = 1367.7959999999991;
+ scores[i].weight = 0.12182430364248545;
+ scores[i].value = ndpi_data_average(flow->pktlen_s_to_c);
+
+ /* src2dst_bytes */
+ i++;
+ scores[i].lower_bound = 144.0;
+ scores[i].upper_bound = 7847.69999999999;
+ scores[i].weight = 0.12059993878175697;
+ scores[i].value = flow->src2dst_bytes;
+
+ /* dst2src_bytes */
+ i++;
+ scores[i].lower_bound = 236.0;
+ scores[i].upper_bound = 74486.7799999998;
+ scores[i].weight = 0.3736608509335782;
+ scores[i].value = flow->dst2src_bytes;
+
+ // sum = 1.0
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
+
+double Ssh_patator_score(struct ndpi_flow_info* flow){
+ double f = (double)flow->first_seen/1000.0, l = (double)flow->last_seen/1000.0;
+ int n_metrics = 6;
+ ndpi_norm_value* scores = malloc(n_metrics * sizeof(ndpi_norm_value));
+ /* fin */
+ int i = 0;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.0033738191632928477;
+ scores[i].value = flow->fin_count;
+
+ /* psh */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 30.0;
+ scores[i].weight = 0.33076923076923076;
+ scores[i].value = flow->psh_count;
+
+ /* c_to_s_syn */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 1.0;
+ scores[i].weight = 0.0004048582995951417;
+ scores[i].value = flow->src2dst_syn_count;
+
+ /* c_to_s_psh */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 12.0;
+ scores[i].weight = 0.33130904183535764;
+ scores[i].value = flow->src2dst_psh_count;
+
+ /* s_to_c_fin */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 2.0;
+ scores[i].weight = 0.0033738191632928477;
+ scores[i].value = flow->dst2src_fin_count;
+
+ /* s_to_c_psh */
+ i++;
+ scores[i].lower_bound = 0.0;
+ scores[i].upper_bound = 30.0;
+ scores[i].weight = 0.33076923076923076;
+ scores[i].value = flow->dst2src_psh_count;
+
+ // sum = 1.0
+ double flow_score = get_flow_score(scores, n_metrics);
+ free(scores);
+ return flow_score;
+}
diff --git a/example/intrusion_detection.h b/example/intrusion_detection.h
new file mode 100644
index 000000000..b31890c96
--- /dev/null
+++ b/example/intrusion_detection.h
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "reader_util.h"
+#include "ndpi_api.h"
+
+typedef struct norm_values{
+ double upper_bound;
+ double lower_bound;
+ double weight;
+ double value;
+ double norm_value;
+}ndpi_norm_value;
+
+double normalize(ndpi_norm_value* tresholds);
+
+double get_flow_score(ndpi_norm_value* scores, int n_metrics);
+
+/* ********************************** */
+
+double Ddos_score(struct ndpi_flow_info* flow);
+
+double Dos_goldeneye_score(struct ndpi_flow_info* flow);
+
+double Dos_hulk_score(struct ndpi_flow_info* flow);
+
+double Dos_slow_score(struct ndpi_flow_info* flow);
+
+double Ftp_patator_score(struct ndpi_flow_info* flow);
+
+double Hearthbleed_score(struct ndpi_flow_info* flow);
+
+double Infiltration_score(struct ndpi_flow_info* flow);
+
+double Ssh_patator_score(struct ndpi_flow_info* flow); \ No newline at end of file
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index ae79bc526..bbc78bf02 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -53,6 +53,7 @@
#include <libgen.h>
#include "reader_util.h"
+#include "intrusion_detection.h"
/** Client parameters **/
@@ -566,6 +567,7 @@ void printCSVHeader() {
if(!csv_fp) return;
fprintf(csv_fp, "#flow_id,protocol,first_seen,last_seen,duration,src_ip,src_port,dst_ip,dst_port,ndpi_proto_num,ndpi_proto,");
+ fprintf(csv_fp, "benign_score,dos_slow_score,dos_goldeneye_score,dos_hulk_score,ddos_score,hearthbleed_score,ftp_patator_score,ssh_patator_score,infiltration_score,");
fprintf(csv_fp, "src2dst_packets,src2dst_bytes,src2dst_goodput_bytes,dst2src_packets,dst2src_bytes,dst2src_goodput_bytes,");
fprintf(csv_fp, "data_ratio,str_data_ratio,src2dst_goodput_ratio,dst2src_goodput_ratio,");
@@ -578,6 +580,16 @@ void printCSVHeader() {
fprintf(csv_fp, "pktlen_c_to_s_min,pktlen_c_to_s_avg,pktlen_c_to_s_max,pktlen_c_to_s_stddev,");
fprintf(csv_fp, "pktlen_s_to_c_min,pktlen_s_to_c_avg,pktlen_s_to_c_max,pktlen_s_to_c_stddev,");
+ /* TCP flags */
+ fprintf(csv_fp, "cwr,ece,urg,ack,psh,rst,syn,fin,");
+
+ fprintf(csv_fp, "c_to_s_cwr,c_to_s_ece,c_to_s_urg,c_to_s_ack,c_to_s_psh,c_to_s_rst,c_to_s_syn,c_to_s_fin,");
+
+ fprintf(csv_fp, "s_to_c_cwr,s_to_c_ece,s_to_c_urg,s_to_c_ack,s_to_c_psh,s_to_c_rst,s_to_c_syn,s_to_c_fin,");
+
+ /* TCP window */
+ fprintf(csv_fp, "c_to_s_init_win,s_to_c_init_win,");
+
/* Flow info */
fprintf(csv_fp, "client_info,server_info,");
fprintf(csv_fp, "tls_version,ja3c,tls_client_unsafe,");
@@ -967,11 +979,40 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa
char buf[32], buf1[64];
u_int i;
+ double dos_ge_score;
+ double dos_slow_score;
+ double dos_hulk_score;
+ double ddos_score;
+
+ double hearthbleed_score;
+
+ double ftp_patator_score;
+ double ssh_patator_score;
+
+ double inf_score;
+
if(csv_fp != NULL) {
float data_ratio = ndpi_data_ratio(flow->src2dst_bytes, flow->dst2src_bytes);
double f = (double)flow->first_seen, l = (double)flow->last_seen;
/* PLEASE KEEP IN SYNC WITH printCSVHeader() */
+ dos_ge_score = Dos_goldeneye_score(flow);
+
+ dos_slow_score = Dos_slow_score(flow);
+ dos_hulk_score = Dos_hulk_score(flow);
+ ddos_score = Ddos_score(flow);
+
+ hearthbleed_score = Hearthbleed_score(flow);
+
+ ftp_patator_score = Ftp_patator_score(flow);
+ ssh_patator_score = Ssh_patator_score(flow);
+
+ inf_score = Infiltration_score(flow);
+
+
+ double benign_score = dos_ge_score < 1 && dos_slow_score < 1 && \
+ dos_hulk_score < 1 && ddos_score < 1 && hearthbleed_score < 1 && \
+ ftp_patator_score < 1 && ssh_patator_score < 1 && inf_score < 1 ? 1.1 : 0;
fprintf(csv_fp, "%u,%u,%.3f,%.3f,%.3f,%s,%u,%s,%u,",
flow->flow_id,
@@ -987,12 +1028,17 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa
ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct,
flow->detected_protocol, buf, sizeof(buf)));
+ fprintf(csv_fp, "%.9lf,%.9lf,%.9lf,%.9lf,%.9lf,%.9lf,%.9lf,%.9lf,%9.lf,", \
+ benign_score, dos_slow_score, dos_ge_score, dos_hulk_score, \
+ ddos_score, hearthbleed_score, ftp_patator_score, \
+ ssh_patator_score, inf_score);
+
fprintf(csv_fp, "%u,%llu,%llu,", flow->src2dst_packets,
(long long unsigned int) flow->src2dst_bytes, (long long unsigned int) flow->src2dst_goodput_bytes);
fprintf(csv_fp, "%u,%llu,%llu,", flow->dst2src_packets,
(long long unsigned int) flow->dst2src_bytes, (long long unsigned int) flow->dst2src_goodput_bytes);
fprintf(csv_fp, "%.3f,%s,", data_ratio, ndpi_data_ratio2str(data_ratio));
- fprintf(csv_fp, "%.1f,%.1f", 100.0*((float)flow->src2dst_goodput_bytes / (float)(flow->src2dst_bytes+1)),
+ fprintf(csv_fp, "%.1f,%.1f,", 100.0*((float)flow->src2dst_goodput_bytes / (float)(flow->src2dst_bytes+1)),
100.0*((float)flow->dst2src_goodput_bytes / (float)(flow->dst2src_bytes+1)));
/* IAT (Inter Arrival Time) */
@@ -1008,22 +1054,32 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa
ndpi_data_min(flow->pktlen_c_to_s), ndpi_data_average(flow->pktlen_c_to_s), ndpi_data_max(flow->pktlen_c_to_s), ndpi_data_stddev(flow->pktlen_c_to_s),
ndpi_data_min(flow->pktlen_s_to_c), ndpi_data_average(flow->pktlen_s_to_c), ndpi_data_max(flow->pktlen_s_to_c), ndpi_data_stddev(flow->pktlen_s_to_c));
+ /* TCP flags */
+ fprintf(csv_fp, "%d,%d,%d,%d,%d,%d,%d,%d,", flow->cwr_count, flow->ece_count, flow->urg_count, flow->ack_count, flow->psh_count, flow->rst_count, flow->syn_count, flow->fin_count);
+
+ fprintf(csv_fp, "%d,%d,%d,%d,%d,%d,%d,%d,", flow->src2dst_cwr_count, flow->src2dst_ece_count, flow->src2dst_urg_count, flow->src2dst_ack_count, flow->src2dst_psh_count, flow->src2dst_rst_count, flow->src2dst_syn_count, flow->src2dst_fin_count);
+
+ fprintf(csv_fp, "%d,%d,%d,%d,%d,%d,%d,%d,", flow->dst2src_cwr_count, flow->ece_count, flow->urg_count, flow->ack_count, flow->psh_count, flow->rst_count, flow->syn_count, flow->fin_count);
+
+ /* TCP window */
+ fprintf(csv_fp, "%u,%u,", flow->c_to_s_init_win, flow->s_to_c_init_win);
+
fprintf(csv_fp, "%s,%s,",
- (flow->ssh_tls.client_info[0] != '\0') ? flow->ssh_tls.client_info : "",
- (flow->ssh_tls.server_info[0] != '\0') ? flow->ssh_tls.server_info : "");
+ (flow->ssh_tls.client_info[0] != '\0') ? flow->ssh_tls.client_info : "0",
+ (flow->ssh_tls.server_info[0] != '\0') ? flow->ssh_tls.server_info : "0");
fprintf(csv_fp, "%s,%s,%s,",
- (flow->ssh_tls.ssl_version != 0) ? ndpi_ssl_version2str(flow->ssh_tls.ssl_version, &known_tls) : "",
- (flow->ssh_tls.ja3_client[0] != '\0') ? flow->ssh_tls.ja3_client : "",
- (flow->ssh_tls.ja3_client[0] != '\0') ? is_unsafe_cipher(flow->ssh_tls.client_unsafe_cipher) : "");
+ (flow->ssh_tls.ssl_version != 0) ? ndpi_ssl_version2str(flow->ssh_tls.ssl_version, &known_tls) : "0",
+ (flow->ssh_tls.ja3_client[0] != '\0') ? flow->ssh_tls.ja3_client : "0",
+ (flow->ssh_tls.ja3_client[0] != '\0') ? is_unsafe_cipher(flow->ssh_tls.client_unsafe_cipher) : "0");
fprintf(csv_fp, "%s,%s,",
- (flow->ssh_tls.ja3_server[0] != '\0') ? flow->ssh_tls.ja3_server : "",
- (flow->ssh_tls.ja3_server[0] != '\0') ? is_unsafe_cipher(flow->ssh_tls.server_unsafe_cipher) : "");
+ (flow->ssh_tls.ja3_server[0] != '\0') ? flow->ssh_tls.ja3_server : "0",
+ (flow->ssh_tls.ja3_server[0] != '\0') ? is_unsafe_cipher(flow->ssh_tls.server_unsafe_cipher) : "0");
fprintf(csv_fp, "%s,%s",
- (flow->ssh_tls.client_hassh[0] != '\0') ? flow->ssh_tls.client_hassh : "",
- (flow->ssh_tls.server_hassh[0] != '\0') ? flow->ssh_tls.server_hassh : ""
+ (flow->ssh_tls.client_hassh[0] != '\0') ? flow->ssh_tls.client_hassh : "0",
+ (flow->ssh_tls.server_hassh[0] != '\0') ? flow->ssh_tls.server_hassh : "0"
);
fprintf(csv_fp, "\n");
diff --git a/example/reader_util.c b/example/reader_util.c
index cf3c82475..b90cf8256 100644
--- a/example/reader_util.c
+++ b/example/reader_util.c
@@ -1062,6 +1062,41 @@ ndpi_clear_entropy_stats(struct ndpi_flow_info *flow) {
}
}
+void update_tcp_flags_count(struct ndpi_flow_info* flow, struct ndpi_tcphdr* tcp, u_int8_t src_to_dst_direction){
+ if(tcp->cwr){
+ flow->cwr_count++;
+ src_to_dst_direction ? flow->src2dst_cwr_count++ : flow->dst2src_cwr_count++;
+ }
+ if(tcp->ece){
+ flow->ece_count++;
+ src_to_dst_direction ? flow->src2dst_ece_count++ : flow->dst2src_ece_count++;
+ }
+ if(tcp->rst){
+ flow->rst_count++;
+ src_to_dst_direction ? flow->src2dst_rst_count++ : flow->dst2src_rst_count++;
+ }
+ if(tcp->ack){
+ flow->ack_count++;
+ src_to_dst_direction ? flow->src2dst_ack_count++ : flow->dst2src_ack_count++;
+ }
+ if(tcp->fin){
+ flow->fin_count++;
+ src_to_dst_direction ? flow->src2dst_fin_count++ : flow->dst2src_fin_count++;
+ }
+ if(tcp->syn){
+ flow->syn_count++;
+ src_to_dst_direction ? flow->src2dst_syn_count++ : flow->dst2src_syn_count++;
+ }
+ if(tcp->psh){
+ flow->psh_count++;
+ src_to_dst_direction ? flow->src2dst_psh_count++ : flow->dst2src_psh_count++;
+ }
+ if(tcp->urg){
+ flow->urg_count++;
+ src_to_dst_direction ? flow->src2dst_urg_count++ : flow->dst2src_urg_count++;
+ }
+}
+
/* ****************************************************** */
/**
Function to process the packet:
@@ -1116,6 +1151,15 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow,
workflow->stats.total_ip_bytes += rawsize;
ndpi_flow = flow->ndpi_flow;
+ if(tcph != NULL){
+ update_tcp_flags_count(flow, tcph, src_to_dst_direction);
+ if(tcph->syn && !flow->src2dst_bytes){
+ flow->c_to_s_init_win = rawsize;
+ }else if(tcph->syn && tcph->ack && flow->src2dst_bytes == flow->c_to_s_init_win){
+ flow->s_to_c_init_win = rawsize;
+ }
+ }
+
if((tcph != NULL) && (tcph->fin || tcph->rst || tcph->syn))
begin_or_end_tcp = 1;
@@ -1155,7 +1199,6 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow,
ndpi_data_add_value(flow->iat_s_to_c, ms);
}
}
-
ndpi_data_add_value(flow->pktlen_s_to_c, rawsize);
flow->dst2src_packets++, flow->dst2src_bytes += rawsize, flow->dst2src_goodput_bytes += payload_len;
memcpy(&flow->entropy.dst2src_last_pkt_time, &when, sizeof(when));
diff --git a/example/reader_util.h b/example/reader_util.h
index 99f8c5ada..c420ca211 100644
--- a/example/reader_util.h
+++ b/example/reader_util.h
@@ -32,6 +32,7 @@
#include "uthash.h"
#include <pcap.h>
#include "ndpi_classify.h"
+#include "ndpi_typedefs.h"
#ifdef USE_DPDK
#include <rte_eal.h>
@@ -164,6 +165,15 @@ typedef struct ndpi_flow_info {
struct ndpi_flow_struct *ndpi_flow;
char src_name[48], dst_name[48];
u_int8_t ip_version;
+ u_int32_t cwr_count, src2dst_cwr_count, dst2src_cwr_count;
+ u_int32_t ece_count, src2dst_ece_count, dst2src_ece_count;
+ u_int32_t urg_count, src2dst_urg_count, dst2src_urg_count;
+ u_int32_t ack_count, src2dst_ack_count, dst2src_ack_count;
+ u_int32_t psh_count, src2dst_psh_count, dst2src_psh_count;
+ u_int32_t syn_count, src2dst_syn_count, dst2src_syn_count;
+ u_int32_t fin_count, src2dst_fin_count, dst2src_fin_count;
+ u_int32_t rst_count, src2dst_rst_count, dst2src_rst_count;
+ u_int32_t c_to_s_init_win, s_to_c_init_win;
u_int64_t first_seen, last_seen;
u_int64_t src2dst_bytes, dst2src_bytes;
u_int64_t src2dst_goodput_bytes, dst2src_goodput_bytes;