aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2021-05-18 19:34:17 +0200
committerLuca Deri <deri@ntop.org>2021-05-18 19:34:17 +0200
commitca15e3295e217578fd08d6677e1f1a346ec15481 (patch)
tree56d6a63cbce0687558a5fd03ac14028fcdeabcd7 /src
parent0b3d627185db10c690026a32828d76d4db52eeef (diff)
Added risk/score dump (ndpiReader -h)
Added ndpi_dump_risks_score() API score
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_api.h.in8
-rw-r--r--src/include/ndpi_typedefs.h10
-rw-r--r--src/lib/ndpi_main.c5258
-rw-r--r--src/lib/ndpi_utils.c24
-rw-r--r--src/lib/protocols/tls.c24
5 files changed, 2705 insertions, 2619 deletions
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in
index ecf696f7f..c44440cc8 100644
--- a/src/include/ndpi_api.h.in
+++ b/src/include/ndpi_api.h.in
@@ -681,6 +681,13 @@ extern "C" {
void ndpi_dump_protocols(struct ndpi_detection_module_struct *mod);
/**
+ * Write the list of the scores and their associated risks
+ *
+ * @par ndpi_mod = the detection module
+ */
+ void ndpi_dump_risks_score();
+
+ /**
* Read a file and load the protocols
*
* Format: <tcp|udp>:<port>,<tcp|udp>:<port>,.....@<proto>
@@ -1512,6 +1519,7 @@ extern "C" {
void ndpi_serialize_risk(ndpi_serializer *serializer, struct ndpi_flow_struct *flow);
const char* ndpi_risk2str(ndpi_risk_enum risk);
+ const char* ndpi_severity2str(ndpi_risk_severity s);
ndpi_risk_severity ndpi_risk2severity(ndpi_risk_enum risk);
u_int16_t ndpi_risk2score(ndpi_risk risk);
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index ab8066aad..42c1e9f94 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -114,10 +114,12 @@ typedef enum {
NDPI_RISK_SEVERE
} ndpi_risk_severity;
-#define NDPI_SCORE_RISK_LOW 10
-#define NDPI_SCORE_RISK_MEDIUM 50
-#define NDPI_SCORE_RISK_HIGH 100
-#define NDPI_SCORE_RISK_SEVERE 250
+typedef enum {
+ NDPI_SCORE_RISK_LOW = 10,
+ NDPI_SCORE_RISK_MEDIUM = 50,
+ NDPI_SCORE_RISK_HIGH = 100,
+ NDPI_SCORE_RISK_SEVERE = 250,
+} ndpi_risk_score;
/* NDPI_VISIT */
typedef enum {
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index d517e7540..b73dc0c21 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -325,10 +325,10 @@ void ndpi_set_proto_subprotocols(struct ndpi_detection_module_struct *ndpi_str,
va_start(ap, protoId);
while (current_arg != NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS)
- {
- ndpi_str->proto_defaults[protoId].subprotocol_count++;
- current_arg = va_arg(ap, int);
- }
+ {
+ ndpi_str->proto_defaults[protoId].subprotocol_count++;
+ current_arg = va_arg(ap, int);
+ }
va_end(ap);
ndpi_str->proto_defaults[protoId].subprotocols = NULL;
@@ -337,9 +337,9 @@ void ndpi_set_proto_subprotocols(struct ndpi_detection_module_struct *ndpi_str,
ndpi_str->proto_defaults[protoId].subprotocol_count--;
/* No subprotocol was set before NDPI_NO_MORE_SUBPROTOCOLS. */
if (ndpi_str->proto_defaults[protoId].subprotocol_count == 0)
- {
- return;
- }
+ {
+ return;
+ }
ndpi_str->proto_defaults[protoId].subprotocols =
ndpi_malloc(sizeof(protoId) * ndpi_str->proto_defaults[protoId].subprotocol_count);
@@ -348,10 +348,10 @@ void ndpi_set_proto_subprotocols(struct ndpi_detection_module_struct *ndpi_str,
va_start(ap, protoId);
current_arg = va_arg(ap, int);
while (current_arg != NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS)
- {
- ndpi_str->proto_defaults[protoId].subprotocols[i++] = current_arg;
- current_arg = va_arg(ap, int);
- }
+ {
+ ndpi_str->proto_defaults[protoId].subprotocols[i++] = current_arg;
+ current_arg = va_arg(ap, int);
+ }
va_end(ap);
}
@@ -790,8 +790,8 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_a, 53, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 53, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_DNS,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_DNS can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_DNS can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IPP,
"IPP", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
@@ -805,16 +805,16 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_a, 80, 0 /* ntop */, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP,
- NDPI_PROTOCOL_AIMINI,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_AIMINI,
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MDNS,
"MDNS", NDPI_PROTOCOL_CATEGORY_NETWORK,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 5353, 5354, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_MDNS,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_MDNS can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_MDNS can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NTP,
"NTP", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
@@ -1156,15 +1156,15 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_a, 443, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_TLS,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_TLS can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_TLS can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_DTLS,
"DTLS", NDPI_PROTOCOL_CATEGORY_WEB,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_DTLS,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_DTLS can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_DTLS can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSH,
"SSH", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
ndpi_build_default_ports(ports_a, 22, 0, 0, 0, 0) /* TCP */,
@@ -1290,15 +1290,15 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP_CONNECT,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP_CONNECT can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP_CONNECT can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_PROXY,
"HTTP_Proxy", NDPI_PROTOCOL_CATEGORY_WEB,
ndpi_build_default_ports(ports_a, 8080, 3128, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP_PROXY,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP_PROXY can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP_PROXY can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CITRIX,
"Citrix", NDPI_PROTOCOL_CATEGORY_NETWORK,
ndpi_build_default_ports(ports_a, 1494, 2598, 0, 0, 0) /* TCP */,
@@ -1340,8 +1340,8 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 443, 80, 0, 0, 0) /* UDP */);
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_QUIC,
- NDPI_PROTOCOL_MATCHED_BY_CONTENT,
- NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_QUIC can have (content-matched) subprotocols */
+ NDPI_PROTOCOL_MATCHED_BY_CONTENT,
+ NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_QUIC can have (content-matched) subprotocols */
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DIAMETER,
"Diameter", NDPI_PROTOCOL_CATEGORY_NETWORK,
ndpi_build_default_ports(ports_a, 3868, 0, 0, 0, 0) /* TCP */,
@@ -1822,11 +1822,11 @@ u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_str
if(ndpi_str->ndpi_num_custom_protocols == 0) {
/*
- In case we don't have defined any custom protocol we check the ptree
- only in case of public IP addresses as in ndpi_content_match.c.inc
- we only have public IP addresses. Instead with custom protocols, users
- might have defined private protocols hence we should not skip
- the checks below
+ In case we don't have defined any custom protocol we check the ptree
+ only in case of public IP addresses as in ndpi_content_match.c.inc
+ we only have public IP addresses. Instead with custom protocols, users
+ might have defined private protocols hence we should not skip
+ the checks below
*/
if(ndpi_is_public_ipv4(ntohl(pin->s_addr)) == 0)
@@ -2607,7 +2607,7 @@ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_str) {
if(ndpi_str->malicious_sha1_automa.ac_automa != NULL)
ac_automata_release((AC_AUTOMATA_t *) ndpi_str->malicious_sha1_automa.ac_automa,
- 1 /* free patterns strings memory */);
+ 1 /* free patterns strings memory */);
if(ndpi_str->custom_categories.hostnames.ac_automa != NULL)
ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
@@ -2972,7 +2972,7 @@ int ndpi_load_categories_file(struct ndpi_detection_module_struct *ndpi_str, con
/* ******************************************************************** */
static int ndpi_load_risky_domain(struct ndpi_detection_module_struct *ndpi_str,
- char* domain_name) {
+ char* domain_name) {
if(ndpi_str->risky_domain_automa.ac_automa == NULL)
ndpi_str->risky_domain_automa.ac_automa = ac_automata_init(ac_match_handler);
@@ -4032,52 +4032,52 @@ void ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct *flow, struct nd
/* ****************************************************** */
void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
- if(flow) {
- if(flow->http.url)
- ndpi_free(flow->http.url);
-
- if(flow->http.content_type)
- ndpi_free(flow->http.content_type);
-
- if(flow->http.request_content_type)
- ndpi_free(flow->http.request_content_type);
-
- if(flow->http.user_agent)
- ndpi_free(flow->http.user_agent);
-
- if(flow->kerberos_buf.pktbuf)
- ndpi_free(flow->kerberos_buf.pktbuf);
-
- if(flow_is_proto(flow, NDPI_PROTOCOL_QUIC) ||
- flow_is_proto(flow, NDPI_PROTOCOL_TLS) ||
- flow_is_proto(flow, NDPI_PROTOCOL_DTLS) ||
- flow_is_proto(flow, NDPI_PROTOCOL_MAIL_SMTPS) ||
- flow_is_proto(flow, NDPI_PROTOCOL_MAIL_POPS) ||
- flow_is_proto(flow, NDPI_PROTOCOL_MAIL_IMAPS)) {
- if(flow->protos.tls_quic_stun.tls_quic.server_names)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.server_names);
-
- if(flow->protos.tls_quic_stun.tls_quic.alpn)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.alpn);
-
- if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions);
-
- if(flow->protos.tls_quic_stun.tls_quic.issuerDN)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.issuerDN);
-
- if(flow->protos.tls_quic_stun.tls_quic.subjectDN)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.subjectDN);
-
- if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni)
- ndpi_free(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni);
- }
+ if(flow) {
+ if(flow->http.url)
+ ndpi_free(flow->http.url);
+
+ if(flow->http.content_type)
+ ndpi_free(flow->http.content_type);
+
+ if(flow->http.request_content_type)
+ ndpi_free(flow->http.request_content_type);
+
+ if(flow->http.user_agent)
+ ndpi_free(flow->http.user_agent);
+
+ if(flow->kerberos_buf.pktbuf)
+ ndpi_free(flow->kerberos_buf.pktbuf);
+
+ if(flow_is_proto(flow, NDPI_PROTOCOL_QUIC) ||
+ flow_is_proto(flow, NDPI_PROTOCOL_TLS) ||
+ flow_is_proto(flow, NDPI_PROTOCOL_DTLS) ||
+ flow_is_proto(flow, NDPI_PROTOCOL_MAIL_SMTPS) ||
+ flow_is_proto(flow, NDPI_PROTOCOL_MAIL_POPS) ||
+ flow_is_proto(flow, NDPI_PROTOCOL_MAIL_IMAPS)) {
+ if(flow->protos.tls_quic_stun.tls_quic.server_names)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.server_names);
+
+ if(flow->protos.tls_quic_stun.tls_quic.alpn)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.alpn);
+
+ if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions);
+
+ if(flow->protos.tls_quic_stun.tls_quic.issuerDN)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.issuerDN);
+
+ if(flow->protos.tls_quic_stun.tls_quic.subjectDN)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.subjectDN);
+
+ if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni)
+ ndpi_free(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni);
+ }
- if(flow->l4_proto == IPPROTO_TCP) {
- if(flow->l4.tcp.tls.message.buffer)
- ndpi_free(flow->l4.tcp.tls.message.buffer);
- }
+ if(flow->l4_proto == IPPROTO_TCP) {
+ if(flow->l4.tcp.tls.message.buffer)
+ ndpi_free(flow->l4.tcp.tls.message.buffer);
}
+ }
}
/* ************************************************ */
@@ -4114,7 +4114,7 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
if(decaps_iph && decaps_iph->version == IPVERSION && decaps_iph->ihl >= 5) {
NDPI_LOG_DBG2(ndpi_str, "ipv4 header\n");
} else if(decaps_iph && decaps_iph->version == 6 && l3len >= sizeof(struct ndpi_ipv6hdr) &&
- (ndpi_str->ip_version_limit & NDPI_DETECTION_ONLY_IPV4) == 0) {
+ (ndpi_str->ip_version_limit & NDPI_DETECTION_ONLY_IPV4) == 0) {
NDPI_LOG_DBG2(ndpi_str, "ipv6 header\n");
flow->packet.iphv6 = (struct ndpi_ipv6hdr *) flow->packet.iph;
flow->packet.iph = NULL;
@@ -4199,1675 +4199,1672 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
/* ************************************************ */
- void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow) {
- if(!flow) {
- return;
- } else {
- /* const for gcc code optimization and cleaner code */
- struct ndpi_packet_struct *packet = &flow->packet;
- const struct ndpi_iphdr *iph = packet->iph;
- const struct ndpi_ipv6hdr *iphv6 = packet->iphv6;
- const struct ndpi_tcphdr *tcph = packet->tcp;
- const struct ndpi_udphdr *udph = packet->udp;
+void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow) {
+ if(!flow) {
+ return;
+ } else {
+ /* const for gcc code optimization and cleaner code */
+ struct ndpi_packet_struct *packet = &flow->packet;
+ const struct ndpi_iphdr *iph = packet->iph;
+ const struct ndpi_ipv6hdr *iphv6 = packet->iphv6;
+ const struct ndpi_tcphdr *tcph = packet->tcp;
+ const struct ndpi_udphdr *udph = packet->udp;
- packet->tcp_retransmission = 0, packet->packet_direction = 0;
+ packet->tcp_retransmission = 0, packet->packet_direction = 0;
- if(ndpi_str->direction_detect_disable) {
- packet->packet_direction = flow->packet_direction;
- } else {
- if(iph != NULL && ntohl(iph->saddr) < ntohl(iph->daddr))
- packet->packet_direction = 1;
+ if(ndpi_str->direction_detect_disable) {
+ packet->packet_direction = flow->packet_direction;
+ } else {
+ if(iph != NULL && ntohl(iph->saddr) < ntohl(iph->daddr))
+ packet->packet_direction = 1;
- if((iphv6 != NULL)
- && NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(&iphv6->ip6_src, &iphv6->ip6_dst) != 0)
- packet->packet_direction = 1;
- }
+ if((iphv6 != NULL)
+ && NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(&iphv6->ip6_src, &iphv6->ip6_dst) != 0)
+ packet->packet_direction = 1;
+ }
- packet->packet_lines_parsed_complete = 0;
+ packet->packet_lines_parsed_complete = 0;
- if(flow->init_finished == 0) {
- flow->init_finished = 1;
- flow->setup_packet_direction = packet->packet_direction;
- }
+ if(flow->init_finished == 0) {
+ flow->init_finished = 1;
+ flow->setup_packet_direction = packet->packet_direction;
+ }
- if(tcph != NULL) {
- /* reset retried bytes here before setting it */
- packet->num_retried_bytes = 0;
+ if(tcph != NULL) {
+ /* reset retried bytes here before setting it */
+ packet->num_retried_bytes = 0;
- if(!ndpi_str->direction_detect_disable)
- packet->packet_direction = (ntohs(tcph->source) < ntohs(tcph->dest)) ? 1 : 0;
+ if(!ndpi_str->direction_detect_disable)
+ packet->packet_direction = (ntohs(tcph->source) < ntohs(tcph->dest)) ? 1 : 0;
- if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0 &&
+ if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0 &&
+ flow->l4.tcp.seen_ack == 0) {
+ flow->l4.tcp.seen_syn = 1;
+ } else
+ if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0 &&
flow->l4.tcp.seen_ack == 0) {
- flow->l4.tcp.seen_syn = 1;
+ flow->l4.tcp.seen_syn_ack = 1;
} else
- if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0 &&
+ if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 &&
flow->l4.tcp.seen_ack == 0) {
- flow->l4.tcp.seen_syn_ack = 1;
- } else
- if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 &&
- flow->l4.tcp.seen_ack == 0) {
- flow->l4.tcp.seen_ack = 1;
- }
-
- if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0) ||
- (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0)) {
- /* initialize tcp sequence counters */
- /* the ack flag needs to be set to get valid sequence numbers from the other
- * direction. Usually it will catch the second packet syn+ack but it works
- * also for asymmetric traffic where it will use the first data packet
- *
- * if the syn flag is set add one to the sequence number,
- * otherwise use the payload length.
- */
- if(tcph->ack != 0) {
- flow->next_tcp_seq_nr[flow->packet.packet_direction] =
- ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);
-
- /*
- Check to avoid discrepancies in case we analyze a flow that does not start with SYN...
- but that is already started when nDPI being to process it. See also (***) below
- */
- if(flow->num_processed_pkts > 1)
- flow->next_tcp_seq_nr[1 - flow->packet.packet_direction] = ntohl(tcph->ack_seq);
- }
- } else if(packet->payload_packet_len > 0) {
- /* check tcp sequence counters */
- if(((u_int32_t)(ntohl(tcph->seq) - flow->next_tcp_seq_nr[packet->packet_direction])) >
- ndpi_str->tcp_max_retransmission_window_size) {
- packet->tcp_retransmission = 1;
-
- /* CHECK IF PARTIAL RETRY IS HAPPENING */
- if((flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq) <
- packet->payload_packet_len)) {
- /* num_retried_bytes actual_payload_len hold info about the partial retry
- analyzer which require this info can make use of this info
- Other analyzer can use packet->payload_packet_len */
- packet->num_retried_bytes =
- (u_int16_t)(flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq));
- packet->actual_payload_len = packet->payload_packet_len - packet->num_retried_bytes;
-
- if(flow->num_processed_pkts > 1) /* See also (***) above */
- flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
- }
+ flow->l4.tcp.seen_ack = 1;
}
- /* normal path
- actual_payload_len is initialized to payload_packet_len during tcp header parsing itself.
- It will be changed only in case of retransmission */
- else {
- packet->num_retried_bytes = 0;
- flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
+ if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0) ||
+ (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0)) {
+ /* initialize tcp sequence counters */
+ /* the ack flag needs to be set to get valid sequence numbers from the other
+ * direction. Usually it will catch the second packet syn+ack but it works
+ * also for asymmetric traffic where it will use the first data packet
+ *
+ * if the syn flag is set add one to the sequence number,
+ * otherwise use the payload length.
+ */
+ if(tcph->ack != 0) {
+ flow->next_tcp_seq_nr[flow->packet.packet_direction] =
+ ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);
+
+ /*
+ Check to avoid discrepancies in case we analyze a flow that does not start with SYN...
+ but that is already started when nDPI being to process it. See also (***) below
+ */
+ if(flow->num_processed_pkts > 1)
+ flow->next_tcp_seq_nr[1 - flow->packet.packet_direction] = ntohl(tcph->ack_seq);
+ }
+ } else if(packet->payload_packet_len > 0) {
+ /* check tcp sequence counters */
+ if(((u_int32_t)(ntohl(tcph->seq) - flow->next_tcp_seq_nr[packet->packet_direction])) >
+ ndpi_str->tcp_max_retransmission_window_size) {
+ packet->tcp_retransmission = 1;
+
+ /* CHECK IF PARTIAL RETRY IS HAPPENING */
+ if((flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq) <
+ packet->payload_packet_len)) {
+ /* num_retried_bytes actual_payload_len hold info about the partial retry
+ analyzer which require this info can make use of this info
+ Other analyzer can use packet->payload_packet_len */
+ packet->num_retried_bytes =
+ (u_int16_t)(flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq));
+ packet->actual_payload_len = packet->payload_packet_len - packet->num_retried_bytes;
+
+ if(flow->num_processed_pkts > 1) /* See also (***) above */
+ flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
}
}
- if(tcph->rst) {
- flow->next_tcp_seq_nr[0] = 0;
- flow->next_tcp_seq_nr[1] = 0;
+ /* normal path
+ actual_payload_len is initialized to payload_packet_len during tcp header parsing itself.
+ It will be changed only in case of retransmission */
+ else {
+ packet->num_retried_bytes = 0;
+ flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
}
- } else if(udph != NULL) {
- if(!ndpi_str->direction_detect_disable)
- packet->packet_direction = (htons(udph->source) < htons(udph->dest)) ? 1 : 0;
}
- if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) {
- flow->packet_counter++;
+ if(tcph->rst) {
+ flow->next_tcp_seq_nr[0] = 0;
+ flow->next_tcp_seq_nr[1] = 0;
}
+ } else if(udph != NULL) {
+ if(!ndpi_str->direction_detect_disable)
+ packet->packet_direction = (htons(udph->source) < htons(udph->dest)) ? 1 : 0;
+ }
- if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER &&
- packet->payload_packet_len) {
- flow->packet_direction_counter[packet->packet_direction]++;
- }
+ if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) {
+ flow->packet_counter++;
+ }
- if(flow->byte_counter[packet->packet_direction] + packet->payload_packet_len >
- flow->byte_counter[packet->packet_direction]) {
- flow->byte_counter[packet->packet_direction] += packet->payload_packet_len;
- }
+ if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER &&
+ packet->payload_packet_len) {
+ flow->packet_direction_counter[packet->packet_direction]++;
+ }
+
+ if(flow->byte_counter[packet->packet_direction] + packet->payload_packet_len >
+ flow->byte_counter[packet->packet_direction]) {
+ flow->byte_counter[packet->packet_direction] += packet->payload_packet_len;
}
}
+}
- /* ************************************************ */
+/* ************************************************ */
- static u_int32_t check_ndpi_detection_func(struct ndpi_detection_module_struct * const ndpi_str,
- struct ndpi_flow_struct * const flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE const ndpi_selection_packet,
- struct ndpi_call_function_struct const * const callback_buffer,
- uint32_t callback_buffer_size)
- {
- void *func = NULL;
- u_int8_t is_tcp_without_payload = (callback_buffer == ndpi_str->callback_buffer_tcp_no_payload);
- u_int32_t num_calls = (is_tcp_without_payload != 0 ? 1 : 0);
- u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
- u_int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
- NDPI_PROTOCOL_BITMASK detection_bitmask;
-
- NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
-
- if ((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
- NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
- ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
- NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
- (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & ndpi_selection_packet) ==
- ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask)
+static u_int32_t check_ndpi_detection_func(struct ndpi_detection_module_struct * const ndpi_str,
+ struct ndpi_flow_struct * const flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE const ndpi_selection_packet,
+ struct ndpi_call_function_struct const * const callback_buffer,
+ uint32_t callback_buffer_size)
+{
+ void *func = NULL;
+ u_int8_t is_tcp_without_payload = (callback_buffer == ndpi_str->callback_buffer_tcp_no_payload);
+ u_int32_t num_calls = (is_tcp_without_payload != 0 ? 1 : 0);
+ u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
+ u_int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
+ NDPI_PROTOCOL_BITMASK detection_bitmask;
+
+ NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
+
+ if ((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
+ NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
+ ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
+ NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
+ (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & ndpi_selection_packet) ==
+ ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask)
{
if ((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
(ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL) &&
(is_tcp_without_payload == 0 ||
((ndpi_str->callback_buffer[flow->guessed_protocol_id].ndpi_selection_bitmask &
- NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0)))
- {
- ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow);
- func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func;
- num_calls++;
- }
+ NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0)))
+ {
+ ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow);
+ func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func;
+ num_calls++;
+ }
}
- if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
+ if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
{
for (u_int32_t a = 0; a < callback_buffer_size; a++) {
if ((func != callback_buffer[a].func) &&
(callback_buffer[a].ndpi_selection_bitmask & ndpi_selection_packet) ==
- callback_buffer[a].ndpi_selection_bitmask &&
+ callback_buffer[a].ndpi_selection_bitmask &&
NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
callback_buffer[a].excluded_protocol_bitmask) == 0 &&
NDPI_BITMASK_COMPARE(callback_buffer[a].detection_bitmask,
detection_bitmask) != 0)
- {
- callback_buffer[a].func(ndpi_str, flow);
- num_calls++;
-
- if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
- {
- break; /* Stop after the first detected protocol. */
- }
- }
+ {
+ callback_buffer[a].func(ndpi_str, flow);
+ num_calls++;
+
+ if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ {
+ break; /* Stop after the first detected protocol. */
+ }
+ }
}
}
- /* Check for subprotocols. */
- for (u_int32_t a = 0; a < ndpi_str->proto_defaults[flow->detected_protocol_stack[0]].subprotocol_count; a++)
+ /* Check for subprotocols. */
+ for (u_int32_t a = 0; a < ndpi_str->proto_defaults[flow->detected_protocol_stack[0]].subprotocol_count; a++)
{
u_int16_t subproto_id = ndpi_str->proto_defaults[flow->detected_protocol_stack[0]].subprotocols[a];
if (subproto_id == (uint16_t)NDPI_PROTOCOL_MATCHED_BY_CONTENT)
- {
- continue;
- }
+ {
+ continue;
+ }
u_int16_t subproto_index = ndpi_str->proto_defaults[subproto_id].protoIdx;
if ((func != ndpi_str->proto_defaults[subproto_id].func) &&
(ndpi_str->callback_buffer[subproto_index].ndpi_selection_bitmask & ndpi_selection_packet) ==
- ndpi_str->callback_buffer[subproto_index].ndpi_selection_bitmask &&
+ ndpi_str->callback_buffer[subproto_index].ndpi_selection_bitmask &&
NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
ndpi_str->callback_buffer[subproto_index].excluded_protocol_bitmask) == 0 &&
NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[subproto_index].detection_bitmask,
detection_bitmask) != 0)
- {
- ndpi_str->callback_buffer[subproto_index].func(ndpi_str, flow);
- num_calls++;
- }
+ {
+ ndpi_str->callback_buffer[subproto_index].func(ndpi_str, flow);
+ num_calls++;
+ }
if (flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
- {
- break; /* Stop after the first detected subprotocol. */
- }
+ {
+ break; /* Stop after the first detected subprotocol. */
+ }
}
- return num_calls;
- }
+ return num_calls;
+}
- /* ************************************************ */
+/* ************************************************ */
- u_int32_t check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
- {
- return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
- ndpi_str->callback_buffer_non_tcp_udp,
- ndpi_str->callback_buffer_size_non_tcp_udp);
- }
+u_int32_t check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
+{
+ return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
+ ndpi_str->callback_buffer_non_tcp_udp,
+ ndpi_str->callback_buffer_size_non_tcp_udp);
+}
- /* ************************************************ */
+/* ************************************************ */
- static u_int32_t check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
- {
- return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
- ndpi_str->callback_buffer_udp,
- ndpi_str->callback_buffer_size_udp);
- }
+static u_int32_t check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
+{
+ return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
+ ndpi_str->callback_buffer_udp,
+ ndpi_str->callback_buffer_size_udp);
+}
- /* ************************************************ */
+/* ************************************************ */
- static u_int32_t check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
- {
- if (flow->packet.payload_packet_len != 0) {
- return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
- ndpi_str->callback_buffer_tcp_payload,
- ndpi_str->callback_buffer_size_tcp_payload);
- } else {
- /* no payload */
- return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
- ndpi_str->callback_buffer_tcp_no_payload,
- ndpi_str->callback_buffer_size_tcp_no_payload);
- }
+static u_int32_t check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
+{
+ if (flow->packet.payload_packet_len != 0) {
+ return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
+ ndpi_str->callback_buffer_tcp_payload,
+ ndpi_str->callback_buffer_size_tcp_payload);
+ } else {
+ /* no payload */
+ return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
+ ndpi_str->callback_buffer_tcp_no_payload,
+ ndpi_str->callback_buffer_size_tcp_no_payload);
}
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- u_int32_t ndpi_check_flow_func(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
- if(!flow)
- return(0);
- else if(flow->packet.tcp != NULL)
- return(check_ndpi_tcp_flow_func(ndpi_str, flow, ndpi_selection_packet));
- else if(flow->packet.udp != NULL)
- return(check_ndpi_udp_flow_func(ndpi_str, flow, ndpi_selection_packet));
- else
- return(check_ndpi_other_flow_func(ndpi_str, flow, ndpi_selection_packet));
- }
+u_int32_t ndpi_check_flow_func(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
+ if(!flow)
+ return(0);
+ else if(flow->packet.tcp != NULL)
+ return(check_ndpi_tcp_flow_func(ndpi_str, flow, ndpi_selection_packet));
+ else if(flow->packet.udp != NULL)
+ return(check_ndpi_udp_flow_func(ndpi_str, flow, ndpi_selection_packet));
+ else
+ return(check_ndpi_other_flow_func(ndpi_str, flow, ndpi_selection_packet));
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow) {
- u_int16_t ret = NDPI_PROTOCOL_UNKNOWN;
+u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow) {
+ u_int16_t ret = NDPI_PROTOCOL_UNKNOWN;
- if(flow->packet.iph) {
- struct in_addr addr;
- u_int16_t sport, dport;
+ if(flow->packet.iph) {
+ struct in_addr addr;
+ u_int16_t sport, dport;
- addr.s_addr = flow->packet.iph->saddr;
+ addr.s_addr = flow->packet.iph->saddr;
- if((flow->l4_proto == IPPROTO_TCP) && flow->packet.tcp)
- sport = flow->packet.tcp->source, dport = flow->packet.tcp->dest;
- else if((flow->l4_proto == IPPROTO_UDP) && flow->packet.udp)
- sport = flow->packet.udp->source, dport = flow->packet.udp->dest;
- else
- sport = dport = 0;
+ if((flow->l4_proto == IPPROTO_TCP) && flow->packet.tcp)
+ sport = flow->packet.tcp->source, dport = flow->packet.tcp->dest;
+ else if((flow->l4_proto == IPPROTO_UDP) && flow->packet.udp)
+ sport = flow->packet.udp->source, dport = flow->packet.udp->dest;
+ else
+ sport = dport = 0;
- /* guess host protocol */
- ret = ndpi_network_port_ptree_match(ndpi_str, &addr, sport);
+ /* guess host protocol */
+ ret = ndpi_network_port_ptree_match(ndpi_str, &addr, sport);
- if(ret == NDPI_PROTOCOL_UNKNOWN) {
- addr.s_addr = flow->packet.iph->daddr;
- ret = ndpi_network_port_ptree_match(ndpi_str, &addr, dport);
- }
+ if(ret == NDPI_PROTOCOL_UNKNOWN) {
+ addr.s_addr = flow->packet.iph->daddr;
+ ret = ndpi_network_port_ptree_match(ndpi_str, &addr, dport);
}
-
- return(ret);
}
- /* ********************************************************************************* */
+ return(ret);
+}
- ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int8_t enable_guess, u_int8_t *protocol_was_guessed) {
- ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
+/* ********************************************************************************* */
- *protocol_was_guessed = 0;
+ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int8_t enable_guess, u_int8_t *protocol_was_guessed) {
+ ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
- if(flow == NULL)
- return(ret);
+ *protocol_was_guessed = 0;
- /* Init defaults */
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
- ret.category = flow->category;
+ if(flow == NULL)
+ return(ret);
- /* Ensure that we don't change our mind if detection is already complete */
- if((ret.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
- return(ret);
+ /* Init defaults */
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+ ret.category = flow->category;
- if(ndpi_str->mining_cache && flow->packet.iph) {
- u_int16_t cached_proto;
- u_int32_t key = flow->packet.iph->saddr + flow->packet.iph->daddr;
+ /* Ensure that we don't change our mind if detection is already complete */
+ if((ret.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
+ return(ret);
+
+ if(ndpi_str->mining_cache && flow->packet.iph) {
+ u_int16_t cached_proto;
+ u_int32_t key = flow->packet.iph->saddr + flow->packet.iph->daddr;
- if(ndpi_lru_find_cache(ndpi_str->mining_cache, key,
- &cached_proto, 0 /* Don't remove it as it can be used for other connections */)) {
- ndpi_set_detected_protocol(ndpi_str, flow, cached_proto, NDPI_PROTOCOL_UNKNOWN);
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
- return(ret);
- }
+ if(ndpi_lru_find_cache(ndpi_str->mining_cache, key,
+ &cached_proto, 0 /* Don't remove it as it can be used for other connections */)) {
+ ndpi_set_detected_protocol(ndpi_str, flow, cached_proto, NDPI_PROTOCOL_UNKNOWN);
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+ return(ret);
}
+ }
- /* TODO: add the remaining stage_XXXX protocols */
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
- u_int16_t guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN, guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
-
- if(flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)
- goto check_stun_export;
- else if((flow->guessed_protocol_id == NDPI_PROTOCOL_HANGOUT_DUO) ||
- (flow->guessed_protocol_id == NDPI_PROTOCOL_MESSENGER) ||
- (flow->guessed_protocol_id == NDPI_PROTOCOL_WHATSAPP_CALL)) {
- *protocol_was_guessed = 1;
- ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_protocol_id, NDPI_PROTOCOL_UNKNOWN);
- }
- else if((flow->l4.tcp.tls.hello_processed == 1) &&
- (flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0')) {
- *protocol_was_guessed = 1;
- ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_TLS, NDPI_PROTOCOL_UNKNOWN);
- } else if(enable_guess) {
- if((flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) && (flow->packet.l4_protocol == IPPROTO_TCP) &&
- flow->l4.tcp.tls.hello_processed)
- flow->guessed_protocol_id = NDPI_PROTOCOL_TLS;
-
- guessed_protocol_id = flow->guessed_protocol_id, guessed_host_protocol_id = flow->guessed_host_protocol_id;
-
- if((guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- ((flow->packet.l4_protocol == IPPROTO_UDP) &&
- NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_host_protocol_id) &&
- is_udp_guessable_protocol(guessed_host_protocol_id)))
- flow->guessed_host_protocol_id = guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
-
- /* Ignore guessed protocol if they have been discarded */
- if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
- // && (guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN)
- && (flow->packet.l4_protocol == IPPROTO_UDP) &&
- NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_protocol_id) &&
- is_udp_guessable_protocol(guessed_protocol_id))
- flow->guessed_protocol_id = guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN;
-
- if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) || (guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
- if((guessed_protocol_id == 0) && (flow->protos.tls_quic_stun.stun.num_binding_requests > 0) &&
- (flow->protos.tls_quic_stun.stun.num_processed_pkts > 0))
- guessed_protocol_id = NDPI_PROTOCOL_STUN;
-
- if(flow->host_server_name[0] != '\0') {
- ndpi_protocol_match_result ret_match;
-
- memset(&ret_match, 0, sizeof(ret_match));
-
- ndpi_match_host_subprotocol(ndpi_str, flow, (char *) flow->host_server_name,
- strlen((const char *) flow->host_server_name), &ret_match,
- NDPI_PROTOCOL_DNS);
-
- if(ret_match.protocol_id != NDPI_PROTOCOL_UNKNOWN)
- guessed_host_protocol_id = ret_match.protocol_id;
- }
-
- *protocol_was_guessed = 1;
- ndpi_int_change_protocol(ndpi_str, flow, guessed_host_protocol_id, guessed_protocol_id);
- }
- }
+ /* TODO: add the remaining stage_XXXX protocols */
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ u_int16_t guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN, guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+
+ if(flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)
+ goto check_stun_export;
+ else if((flow->guessed_protocol_id == NDPI_PROTOCOL_HANGOUT_DUO) ||
+ (flow->guessed_protocol_id == NDPI_PROTOCOL_MESSENGER) ||
+ (flow->guessed_protocol_id == NDPI_PROTOCOL_WHATSAPP_CALL)) {
+ *protocol_was_guessed = 1;
+ ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_protocol_id, NDPI_PROTOCOL_UNKNOWN);
+ }
+ else if((flow->l4.tcp.tls.hello_processed == 1) &&
+ (flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0')) {
+ *protocol_was_guessed = 1;
+ ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_TLS, NDPI_PROTOCOL_UNKNOWN);
} else if(enable_guess) {
- if(flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- *protocol_was_guessed = 1;
- flow->detected_protocol_stack[1] = flow->guessed_protocol_id;
- }
-
- if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- *protocol_was_guessed = 1;
- flow->detected_protocol_stack[0] = flow->guessed_host_protocol_id;
- }
+ if((flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) && (flow->packet.l4_protocol == IPPROTO_TCP) &&
+ flow->l4.tcp.tls.hello_processed)
+ flow->guessed_protocol_id = NDPI_PROTOCOL_TLS;
+
+ guessed_protocol_id = flow->guessed_protocol_id, guessed_host_protocol_id = flow->guessed_host_protocol_id;
+
+ if((guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ ((flow->packet.l4_protocol == IPPROTO_UDP) &&
+ NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_host_protocol_id) &&
+ is_udp_guessable_protocol(guessed_host_protocol_id)))
+ flow->guessed_host_protocol_id = guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+
+ /* Ignore guessed protocol if they have been discarded */
+ if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ // && (guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN)
+ && (flow->packet.l4_protocol == IPPROTO_UDP) &&
+ NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_protocol_id) &&
+ is_udp_guessable_protocol(guessed_protocol_id))
+ flow->guessed_protocol_id = guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+
+ if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) || (guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
+ if((guessed_protocol_id == 0) && (flow->protos.tls_quic_stun.stun.num_binding_requests > 0) &&
+ (flow->protos.tls_quic_stun.stun.num_processed_pkts > 0))
+ guessed_protocol_id = NDPI_PROTOCOL_STUN;
+
+ if(flow->host_server_name[0] != '\0') {
+ ndpi_protocol_match_result ret_match;
+
+ memset(&ret_match, 0, sizeof(ret_match));
+
+ ndpi_match_host_subprotocol(ndpi_str, flow, (char *) flow->host_server_name,
+ strlen((const char *) flow->host_server_name), &ret_match,
+ NDPI_PROTOCOL_DNS);
+
+ if(ret_match.protocol_id != NDPI_PROTOCOL_UNKNOWN)
+ guessed_host_protocol_id = ret_match.protocol_id;
+ }
- if(flow->detected_protocol_stack[1] == flow->detected_protocol_stack[0]) {
*protocol_was_guessed = 1;
- flow->detected_protocol_stack[1] = flow->guessed_host_protocol_id;
+ ndpi_int_change_protocol(ndpi_str, flow, guessed_host_protocol_id, guessed_protocol_id);
}
}
-
- if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) &&
- (flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)) {
- check_stun_export:
- /* if(flow->protos.tls_quic_stun.stun.num_processed_pkts || flow->protos.tls_quic_stun.stun.num_udp_pkts) */
- {
- // if(/* (flow->protos.tls_quic_stun.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */
- *protocol_was_guessed = 1;
- ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_STUN);
- }
+ } else if(enable_guess) {
+ if(flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ *protocol_was_guessed = 1;
+ flow->detected_protocol_stack[1] = flow->guessed_protocol_id;
}
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+ if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ *protocol_was_guessed = 1;
+ flow->detected_protocol_stack[0] = flow->guessed_host_protocol_id;
+ }
- if(ret.master_protocol == NDPI_PROTOCOL_STUN) {
- if(ret.app_protocol == NDPI_PROTOCOL_FACEBOOK)
- ret.app_protocol = NDPI_PROTOCOL_MESSENGER;
- else if(ret.app_protocol == NDPI_PROTOCOL_GOOGLE) {
- /*
- As Google has recently introduced Duo,
- we need to distinguish between it and hangout
- thing that should be handled by the STUN dissector
- */
- ret.app_protocol = NDPI_PROTOCOL_HANGOUT_DUO;
- }
+ if(flow->detected_protocol_stack[1] == flow->detected_protocol_stack[0]) {
+ *protocol_was_guessed = 1;
+ flow->detected_protocol_stack[1] = flow->guessed_host_protocol_id;
}
+ }
- if(ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) {
+ if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) &&
+ (flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)) {
+ check_stun_export:
+ /* if(flow->protos.tls_quic_stun.stun.num_processed_pkts || flow->protos.tls_quic_stun.stun.num_udp_pkts) */
+ {
+ // if(/* (flow->protos.tls_quic_stun.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */
*protocol_was_guessed = 1;
- ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+ ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_STUN);
}
+ }
- return(ret);
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
+
+ if(ret.master_protocol == NDPI_PROTOCOL_STUN) {
+ if(ret.app_protocol == NDPI_PROTOCOL_FACEBOOK)
+ ret.app_protocol = NDPI_PROTOCOL_MESSENGER;
+ else if(ret.app_protocol == NDPI_PROTOCOL_GOOGLE) {
+ /*
+ As Google has recently introduced Duo,
+ we need to distinguish between it and hangout
+ thing that should be handled by the STUN dissector
+ */
+ ret.app_protocol = NDPI_PROTOCOL_HANGOUT_DUO;
+ }
}
- /* ********************************************************************************* */
+ if(ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) {
+ *protocol_was_guessed = 1;
+ ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+ }
- void ndpi_process_extra_packet(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- const unsigned char *packet, const unsigned short packetlen,
- const u_int64_t current_time_ms, struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
- if(flow == NULL)
- return;
+ return(ret);
+}
- if(flow->server_id == NULL)
- flow->server_id = dst; /* Default */
+/* ********************************************************************************* */
- /* need at least 20 bytes for ip header */
- if(packetlen < 20) {
- return;
- }
+void ndpi_process_extra_packet(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ const unsigned char *packet, const unsigned short packetlen,
+ const u_int64_t current_time_ms, struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
+ if(flow == NULL)
+ return;
- flow->packet.current_time_ms = current_time_ms;
+ if(flow->server_id == NULL)
+ flow->server_id = dst; /* Default */
- /* parse packet */
- flow->packet.iph = (struct ndpi_iphdr *) packet;
- /* we are interested in ipv4 packet */
+ /* need at least 20 bytes for ip header */
+ if(packetlen < 20) {
+ return;
+ }
- /* set up the packet headers for the extra packet function to use if it wants */
- if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
- return;
+ flow->packet.current_time_ms = current_time_ms;
- /* detect traffic for tcp or udp only */
- flow->src = src, flow->dst = dst;
+ /* parse packet */
+ flow->packet.iph = (struct ndpi_iphdr *) packet;
+ /* we are interested in ipv4 packet */
- ndpi_connection_tracking(ndpi_str, flow);
+ /* set up the packet headers for the extra packet function to use if it wants */
+ if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
+ return;
- /* call the extra packet function (which may add more data/info to flow) */
- if(flow->extra_packets_func) {
- if((flow->extra_packets_func(ndpi_str, flow)) == 0)
- flow->check_extra_packets = 0;
+ /* detect traffic for tcp or udp only */
+ flow->src = src, flow->dst = dst;
- if(++flow->num_extra_packets_checked == flow->max_extra_packets_to_check)
- flow->extra_packets_func = NULL; /* Enough packets detected */
- }
- }
+ ndpi_connection_tracking(ndpi_str, flow);
- /* ********************************************************************************* */
+ /* call the extra packet function (which may add more data/info to flow) */
+ if(flow->extra_packets_func) {
+ if((flow->extra_packets_func(ndpi_str, flow)) == 0)
+ flow->check_extra_packets = 0;
- int ndpi_load_ip_category(struct ndpi_detection_module_struct *ndpi_str, const char *ip_address_and_mask,
- ndpi_protocol_category_t category) {
- ndpi_patricia_node_t *node;
- struct in_addr pin;
- int bits = 32;
- char *ptr;
- char ipbuf[64];
+ if(++flow->num_extra_packets_checked == flow->max_extra_packets_to_check)
+ flow->extra_packets_func = NULL; /* Enough packets detected */
+ }
+}
- strncpy(ipbuf, ip_address_and_mask, sizeof(ipbuf));
- ipbuf[sizeof(ipbuf) - 1] = '\0';
+/* ********************************************************************************* */
- ptr = strrchr(ipbuf, '/');
+int ndpi_load_ip_category(struct ndpi_detection_module_struct *ndpi_str, const char *ip_address_and_mask,
+ ndpi_protocol_category_t category) {
+ ndpi_patricia_node_t *node;
+ struct in_addr pin;
+ int bits = 32;
+ char *ptr;
+ char ipbuf[64];
- if(ptr) {
- *(ptr++) = '\0';
- if(atoi(ptr) >= 0 && atoi(ptr) <= 32)
- bits = atoi(ptr);
- }
+ strncpy(ipbuf, ip_address_and_mask, sizeof(ipbuf));
+ ipbuf[sizeof(ipbuf) - 1] = '\0';
- if(inet_pton(AF_INET, ipbuf, &pin) != 1) {
- NDPI_LOG_DBG2(ndpi_str, "Invalid ip/ip+netmask: %s\n", ip_address_and_mask);
- return(-1);
- }
+ ptr = strrchr(ipbuf, '/');
- if((node = add_to_ptree(ndpi_str->custom_categories.ipAddresses_shadow, AF_INET, &pin, bits)) != NULL) {
- node->value.u.uv32.user_value = (u_int16_t)category, node->value.u.uv32.additional_user_value = 0;
- }
+ if(ptr) {
+ *(ptr++) = '\0';
+ if(atoi(ptr) >= 0 && atoi(ptr) <= 32)
+ bits = atoi(ptr);
+ }
- return(0);
+ if(inet_pton(AF_INET, ipbuf, &pin) != 1) {
+ NDPI_LOG_DBG2(ndpi_str, "Invalid ip/ip+netmask: %s\n", ip_address_and_mask);
+ return(-1);
}
+ if((node = add_to_ptree(ndpi_str->custom_categories.ipAddresses_shadow, AF_INET, &pin, bits)) != NULL) {
+ node->value.u.uv32.user_value = (u_int16_t)category, node->value.u.uv32.additional_user_value = 0;
+ }
- /* ********************************************************************************* */
+ return(0);
+}
- int ndpi_load_hostname_category(struct ndpi_detection_module_struct *ndpi_str, const char *name_to_add,
- ndpi_protocol_category_t category) {
- char *name;
- u_int len;
- AC_PATTERN_t ac_pattern;
- AC_ERROR_t rc;
- if(name_to_add == NULL)
- return(-1);
- else
- len = strlen(name_to_add);
+/* ********************************************************************************* */
- if((name = (char*)ndpi_malloc(len+3)) == NULL)
- return(-1);
+int ndpi_load_hostname_category(struct ndpi_detection_module_struct *ndpi_str, const char *name_to_add,
+ ndpi_protocol_category_t category) {
+ char *name;
+ u_int len;
+ AC_PATTERN_t ac_pattern;
+ AC_ERROR_t rc;
- memset(&ac_pattern, 0, sizeof(ac_pattern));
- ac_pattern.length = snprintf(name, len+2, "%s%s", name_to_add,
- ndpi_is_middle_string_char(name_to_add[len-1]) ? "" : "$");
+ if(name_to_add == NULL)
+ return(-1);
+ else
+ len = strlen(name_to_add);
-#if 0
- printf("===> %s() Loading %s as %u\n", __FUNCTION__, name, category);
-#endif
+ if((name = (char*)ndpi_malloc(len+3)) == NULL)
+ return(-1);
- if(ndpi_str->custom_categories.hostnames_shadow.ac_automa == NULL) {
- ndpi_free(name);
- return(-1);
- }
+ memset(&ac_pattern, 0, sizeof(ac_pattern));
+ ac_pattern.length = snprintf(name, len+2, "%s%s", name_to_add,
+ ndpi_is_middle_string_char(name_to_add[len-1]) ? "" : "$");
- ac_pattern.astring = name;
- ac_pattern.rep.number = (u_int32_t) category, ac_pattern.rep.category = category;
+#if 0
+ printf("===> %s() Loading %s as %u\n", __FUNCTION__, name, category);
+#endif
- rc = ac_automata_add(ndpi_str->custom_categories.hostnames_shadow.ac_automa, &ac_pattern);
- if(rc != ACERR_DUPLICATE_PATTERN && rc != ACERR_SUCCESS) {
- ndpi_free(name);
- return(-1);
- }
+ if(ndpi_str->custom_categories.hostnames_shadow.ac_automa == NULL) {
+ ndpi_free(name);
+ return(-1);
+ }
- if(rc == ACERR_DUPLICATE_PATTERN)
- ndpi_free(name);
+ ac_pattern.astring = name;
+ ac_pattern.rep.number = (u_int32_t) category, ac_pattern.rep.category = category;
- return(0);
+ rc = ac_automata_add(ndpi_str->custom_categories.hostnames_shadow.ac_automa, &ac_pattern);
+ if(rc != ACERR_DUPLICATE_PATTERN && rc != ACERR_SUCCESS) {
+ ndpi_free(name);
+ return(-1);
}
- /* ********************************************************************************* */
+ if(rc == ACERR_DUPLICATE_PATTERN)
+ ndpi_free(name);
- /* Loads an IP or name category */
- int ndpi_load_category(struct ndpi_detection_module_struct *ndpi_struct, const char *ip_or_name,
- ndpi_protocol_category_t category) {
- int rv;
+ return(0);
+}
- /* Try to load as IP address first */
- rv = ndpi_load_ip_category(ndpi_struct, ip_or_name, category);
+/* ********************************************************************************* */
- if(rv < 0) {
- /* IP load failed, load as hostname */
- rv = ndpi_load_hostname_category(ndpi_struct, ip_or_name, category);
- }
+/* Loads an IP or name category */
+int ndpi_load_category(struct ndpi_detection_module_struct *ndpi_struct, const char *ip_or_name,
+ ndpi_protocol_category_t category) {
+ int rv;
- return(rv);
- }
+ /* Try to load as IP address first */
+ rv = ndpi_load_ip_category(ndpi_struct, ip_or_name, category);
- /* ********************************************************************************* */
+ if(rv < 0) {
+ /* IP load failed, load as hostname */
+ rv = ndpi_load_hostname_category(ndpi_struct, ip_or_name, category);
+ }
- int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str) {
- int i;
+ return(rv);
+}
- /* First add the nDPI known categories matches */
- for(i = 0; category_match[i].string_to_match != NULL; i++)
- ndpi_load_category(ndpi_str, category_match[i].string_to_match, category_match[i].protocol_category);
+/* ********************************************************************************* */
- /* Free */
- ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
- 1 /* free patterns strings memory */);
+int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str) {
+ int i;
- /* Finalize */
- ac_automata_finalize((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames_shadow.ac_automa);
+ /* First add the nDPI known categories matches */
+ for(i = 0; category_match[i].string_to_match != NULL; i++)
+ ndpi_load_category(ndpi_str, category_match[i].string_to_match, category_match[i].protocol_category);
- /* Swap */
- ndpi_str->custom_categories.hostnames.ac_automa = ndpi_str->custom_categories.hostnames_shadow.ac_automa;
+ /* Free */
+ ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
+ 1 /* free patterns strings memory */);
- /* Realloc */
- ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_match_handler);
+ /* Finalize */
+ ac_automata_finalize((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames_shadow.ac_automa);
- if(ndpi_str->custom_categories.ipAddresses != NULL)
- ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->custom_categories.ipAddresses, free_ptree_data);
+ /* Swap */
+ ndpi_str->custom_categories.hostnames.ac_automa = ndpi_str->custom_categories.hostnames_shadow.ac_automa;
- ndpi_str->custom_categories.ipAddresses = ndpi_str->custom_categories.ipAddresses_shadow;
- ndpi_str->custom_categories.ipAddresses_shadow = ndpi_patricia_new(32 /* IPv4 */);
+ /* Realloc */
+ ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_match_handler);
- ndpi_str->custom_categories.categories_loaded = 1;
+ if(ndpi_str->custom_categories.ipAddresses != NULL)
+ ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->custom_categories.ipAddresses, free_ptree_data);
- return(0);
- }
+ ndpi_str->custom_categories.ipAddresses = ndpi_str->custom_categories.ipAddresses_shadow;
+ ndpi_str->custom_categories.ipAddresses_shadow = ndpi_patricia_new(32 /* IPv4 */);
- /* ********************************************************************************* */
+ ndpi_str->custom_categories.categories_loaded = 1;
- int ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct *ndpi_str, u_int32_t saddr, u_int32_t daddr,
- ndpi_protocol *ret) {
- if(ndpi_str->custom_categories.categories_loaded) {
- ndpi_prefix_t prefix;
- ndpi_patricia_node_t *node;
+ return(0);
+}
- if(saddr == 0)
- node = NULL;
- else {
- /* Make sure all in network byte order otherwise compares wont work */
- ndpi_fill_prefix_v4(&prefix, (struct in_addr *) &saddr, 32,
- ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
- node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
- }
+/* ********************************************************************************* */
- if(!node) {
- if(daddr != 0) {
- ndpi_fill_prefix_v4(&prefix, (struct in_addr *) &daddr, 32,
- ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
- node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
- }
- }
+int ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct *ndpi_str, u_int32_t saddr, u_int32_t daddr,
+ ndpi_protocol *ret) {
+ if(ndpi_str->custom_categories.categories_loaded) {
+ ndpi_prefix_t prefix;
+ ndpi_patricia_node_t *node;
- if(node) {
- ret->category = (ndpi_protocol_category_t) node->value.u.uv32.user_value;
+ if(saddr == 0)
+ node = NULL;
+ else {
+ /* Make sure all in network byte order otherwise compares wont work */
+ ndpi_fill_prefix_v4(&prefix, (struct in_addr *) &saddr, 32,
+ ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
+ node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
+ }
- return(1);
+ if(!node) {
+ if(daddr != 0) {
+ ndpi_fill_prefix_v4(&prefix, (struct in_addr *) &daddr, 32,
+ ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
+ node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
}
}
- ret->category = ndpi_get_proto_category(ndpi_str, *ret);
+ if(node) {
+ ret->category = (ndpi_protocol_category_t) node->value.u.uv32.user_value;
- return(0);
+ return(1);
+ }
}
- /* ********************************************************************************* */
+ ret->category = ndpi_get_proto_category(ndpi_str, *ret);
- void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- ndpi_protocol *ret) {
- if((ret->master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret->app_protocol == NDPI_PROTOCOL_UNKNOWN))
- return;
+ return(0);
+}
- if(ndpi_str->custom_categories.categories_loaded) {
- if(flow->guessed_header_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) {
- flow->category = ret->category = flow->guessed_header_category;
- return;
- }
+/* ********************************************************************************* */
- if(flow->host_server_name[0] != '\0') {
- u_int32_t id;
- int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->host_server_name,
- strlen((char *) flow->host_server_name), &id);
+void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ ndpi_protocol *ret) {
+ if((ret->master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret->app_protocol == NDPI_PROTOCOL_UNKNOWN))
+ return;
- if(rc == 0) {
- flow->category = ret->category = (ndpi_protocol_category_t) id;
- return;
- }
- }
+ if(ndpi_str->custom_categories.categories_loaded) {
+ if(flow->guessed_header_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) {
+ flow->category = ret->category = flow->guessed_header_category;
+ return;
+ }
- if(flow->l4.tcp.tls.hello_processed == 1 &&
- flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') {
- u_int32_t id;
- int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.tls_quic_stun.tls_quic.client_requested_server_name,
- strlen(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), &id);
+ if(flow->host_server_name[0] != '\0') {
+ u_int32_t id;
+ int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->host_server_name,
+ strlen((char *) flow->host_server_name), &id);
- if(rc == 0) {
- flow->category = ret->category = (ndpi_protocol_category_t) id;
- return;
- }
+ if(rc == 0) {
+ flow->category = ret->category = (ndpi_protocol_category_t) id;
+ return;
}
}
- flow->category = ret->category = ndpi_get_proto_category(ndpi_str, *ret);
+ if(flow->l4.tcp.tls.hello_processed == 1 &&
+ flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') {
+ u_int32_t id;
+ int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.tls_quic_stun.tls_quic.client_requested_server_name,
+ strlen(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), &id);
+
+ if(rc == 0) {
+ flow->category = ret->category = (ndpi_protocol_category_t) id;
+ return;
+ }
+ }
}
- /* ********************************************************************************* */
+ flow->category = ret->category = ndpi_get_proto_category(ndpi_str, *ret);
+}
- static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) {
- packet->parsed_lines = 0, packet->empty_line_position_set = 0, packet->host_line.ptr = NULL,
- packet->host_line.len = 0, packet->referer_line.ptr = NULL, packet->referer_line.len = 0,
- packet->content_line.ptr = NULL, packet->content_line.len = 0, packet->accept_line.ptr = NULL,
- packet->accept_line.len = 0, packet->user_agent_line.ptr = NULL, packet->user_agent_line.len = 0,
- packet->http_url_name.ptr = NULL, packet->http_url_name.len = 0, packet->http_encoding.ptr = NULL,
- packet->http_encoding.len = 0, packet->http_transfer_encoding.ptr = NULL, packet->http_transfer_encoding.len = 0,
- packet->http_contentlen.ptr = NULL, packet->http_contentlen.len = 0, packet->content_disposition_line.ptr = NULL,
- packet->content_disposition_line.len = 0, packet->http_cookie.ptr = NULL,
- packet->http_cookie.len = 0, packet->http_origin.len = 0, packet->http_origin.ptr = NULL,
- packet->http_x_session_type.ptr = NULL, packet->http_x_session_type.len = 0, packet->server_line.ptr = NULL,
- packet->server_line.len = 0, packet->http_method.ptr = NULL, packet->http_method.len = 0,
- packet->http_response.ptr = NULL, packet->http_response.len = 0, packet->http_num_headers = 0,
- packet->forwarded_line.ptr = NULL, packet->forwarded_line.len = 0;
- }
+/* ********************************************************************************* */
+
+static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) {
+ packet->parsed_lines = 0, packet->empty_line_position_set = 0, packet->host_line.ptr = NULL,
+ packet->host_line.len = 0, packet->referer_line.ptr = NULL, packet->referer_line.len = 0,
+ packet->content_line.ptr = NULL, packet->content_line.len = 0, packet->accept_line.ptr = NULL,
+ packet->accept_line.len = 0, packet->user_agent_line.ptr = NULL, packet->user_agent_line.len = 0,
+ packet->http_url_name.ptr = NULL, packet->http_url_name.len = 0, packet->http_encoding.ptr = NULL,
+ packet->http_encoding.len = 0, packet->http_transfer_encoding.ptr = NULL, packet->http_transfer_encoding.len = 0,
+ packet->http_contentlen.ptr = NULL, packet->http_contentlen.len = 0, packet->content_disposition_line.ptr = NULL,
+ packet->content_disposition_line.len = 0, packet->http_cookie.ptr = NULL,
+ packet->http_cookie.len = 0, packet->http_origin.len = 0, packet->http_origin.ptr = NULL,
+ packet->http_x_session_type.ptr = NULL, packet->http_x_session_type.len = 0, packet->server_line.ptr = NULL,
+ packet->server_line.len = 0, packet->http_method.ptr = NULL, packet->http_method.len = 0,
+ packet->http_response.ptr = NULL, packet->http_response.len = 0, packet->http_num_headers = 0,
+ packet->forwarded_line.ptr = NULL, packet->forwarded_line.len = 0;
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- static int ndpi_is_ntop_protocol(ndpi_protocol *ret) {
- if((ret->master_protocol == NDPI_PROTOCOL_HTTP) && (ret->app_protocol == NDPI_PROTOCOL_NTOP))
- return(1);
- else
- return(0);
- }
+static int ndpi_is_ntop_protocol(ndpi_protocol *ret) {
+ if((ret->master_protocol == NDPI_PROTOCOL_HTTP) && (ret->app_protocol == NDPI_PROTOCOL_NTOP))
+ return(1);
+ else
+ return(0);
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- static int ndpi_check_protocol_port_mismatch_exceptions(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- ndpi_default_ports_tree_node_t *expected_proto,
- ndpi_protocol *returned_proto) {
- /*
- For TLS (and other protocols) it is not simple to guess the exact protocol so before
- triggering an alert we need to make sure what we have exhausted all the possible
- options available
- */
+static int ndpi_check_protocol_port_mismatch_exceptions(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ ndpi_default_ports_tree_node_t *expected_proto,
+ ndpi_protocol *returned_proto) {
+ /*
+ For TLS (and other protocols) it is not simple to guess the exact protocol so before
+ triggering an alert we need to make sure what we have exhausted all the possible
+ options available
+ */
- if(ndpi_is_ntop_protocol(returned_proto)) return(1);
+ if(ndpi_is_ntop_protocol(returned_proto)) return(1);
- if(returned_proto->master_protocol == NDPI_PROTOCOL_TLS) {
- switch(expected_proto->proto->protoId) {
- case NDPI_PROTOCOL_MAIL_IMAPS:
- case NDPI_PROTOCOL_MAIL_POPS:
- case NDPI_PROTOCOL_MAIL_SMTPS:
- return(1); /* This is a reasonable exception */
- break;
- }
+ if(returned_proto->master_protocol == NDPI_PROTOCOL_TLS) {
+ switch(expected_proto->proto->protoId) {
+ case NDPI_PROTOCOL_MAIL_IMAPS:
+ case NDPI_PROTOCOL_MAIL_POPS:
+ case NDPI_PROTOCOL_MAIL_SMTPS:
+ return(1); /* This is a reasonable exception */
+ break;
}
-
- return(0);
}
- /* ********************************************************************************* */
+ return(0);
+}
- static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- ndpi_protocol *ret) {
+/* ********************************************************************************* */
+
+static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ ndpi_protocol *ret) {
#if 0
- if(flow) {
- /* Do not go for DNS when there is an application protocol. Example DNS.Apple */
- if((flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
- && (flow->detected_protocol_stack[0] /* app */ != flow->detected_protocol_stack[1] /* major */))
- NDPI_CLR_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
- }
+ if(flow) {
+ /* Do not go for DNS when there is an application protocol. Example DNS.Apple */
+ if((flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
+ && (flow->detected_protocol_stack[0] /* app */ != flow->detected_protocol_stack[1] /* major */))
+ NDPI_CLR_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
+ }
#endif
- // printf("====>> %u.%u [%u]\n", ret->master_protocol, ret->app_protocol, flow->detected_protocol_stack[0]);
+ // printf("====>> %u.%u [%u]\n", ret->master_protocol, ret->app_protocol, flow->detected_protocol_stack[0]);
- switch(ret->app_protocol) {
- /*
+ switch(ret->app_protocol) {
+ /*
Skype for a host doing MS Teams means MS Teams
(MS Teams uses Skype as transport protocol for voice/video)
*/
- case NDPI_PROTOCOL_MSTEAMS:
- if(flow->packet.iph && flow->packet.tcp) {
- // printf("====>> NDPI_PROTOCOL_MSTEAMS\n");
+ case NDPI_PROTOCOL_MSTEAMS:
+ if(flow->packet.iph && flow->packet.tcp) {
+ // printf("====>> NDPI_PROTOCOL_MSTEAMS\n");
+
+ if(ndpi_str->msteams_cache == NULL)
+ ndpi_str->msteams_cache = ndpi_lru_cache_init(1024);
+
+ if(ndpi_str->msteams_cache)
+ ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
+ flow->packet.iph->saddr,
+ (flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
+ }
+ break;
+
+ case NDPI_PROTOCOL_SKYPE:
+ case NDPI_PROTOCOL_SKYPE_CALL:
+ if(flow->packet.iph
+ && flow->packet.udp
+ && ndpi_str->msteams_cache) {
+ u_int16_t when;
- if(ndpi_str->msteams_cache == NULL)
- ndpi_str->msteams_cache = ndpi_lru_cache_init(1024);
+ if(ndpi_lru_find_cache(ndpi_str->msteams_cache, flow->packet.iph->saddr,
+ &when, 0 /* Don't remove it as it can be used for other connections */)) {
+ u_int16_t tdiff = ((flow->packet.current_time_ms /1000) & 0xFFFF) - when;
- if(ndpi_str->msteams_cache)
+ if(tdiff < 60 /* sec */) {
+ // printf("====>> NDPI_PROTOCOL_SKYPE(_CALL) -> NDPI_PROTOCOL_MSTEAMS [%u]\n", tdiff);
+ ret->app_protocol = NDPI_PROTOCOL_MSTEAMS;
+
+ /* Refresh cache */
ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
flow->packet.iph->saddr,
(flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
- }
- break;
-
- case NDPI_PROTOCOL_SKYPE:
- case NDPI_PROTOCOL_SKYPE_CALL:
- if(flow->packet.iph
- && flow->packet.udp
- && ndpi_str->msteams_cache) {
- u_int16_t when;
-
- if(ndpi_lru_find_cache(ndpi_str->msteams_cache, flow->packet.iph->saddr,
- &when, 0 /* Don't remove it as it can be used for other connections */)) {
- u_int16_t tdiff = ((flow->packet.current_time_ms /1000) & 0xFFFF) - when;
-
- if(tdiff < 60 /* sec */) {
- // printf("====>> NDPI_PROTOCOL_SKYPE(_CALL) -> NDPI_PROTOCOL_MSTEAMS [%u]\n", tdiff);
- ret->app_protocol = NDPI_PROTOCOL_MSTEAMS;
-
- /* Refresh cache */
- ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
- flow->packet.iph->saddr,
- (flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
- }
}
}
- break;
+ }
+ break;
- case NDPI_PROTOCOL_ANYDESK:
- if(flow->packet.tcp) /* TCP only */
- ndpi_set_risk(flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */
+ case NDPI_PROTOCOL_ANYDESK:
+ if(flow->packet.tcp) /* TCP only */
+ ndpi_set_risk(flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */
+ break;
+ } /* switch */
+
+ if(flow) {
+ switch(ndpi_get_proto_breed(ndpi_str, ret->app_protocol)) {
+ case NDPI_PROTOCOL_UNSAFE:
+ case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
+ case NDPI_PROTOCOL_DANGEROUS:
+ ndpi_set_risk(flow, NDPI_UNSAFE_PROTOCOL);
+ break;
+ default:
+ /* Nothing to do */
break;
- } /* switch */
-
- if(flow) {
- switch(ndpi_get_proto_breed(ndpi_str, ret->app_protocol)) {
- case NDPI_PROTOCOL_UNSAFE:
- case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
- case NDPI_PROTOCOL_DANGEROUS:
- ndpi_set_risk(flow, NDPI_UNSAFE_PROTOCOL);
- break;
- default:
- /* Nothing to do */
- break;
- }
}
-
}
- /* ****************************************************** */
+}
- static int ndpi_do_guess(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, ndpi_protocol *ret) {
- ret->master_protocol = ret->app_protocol = NDPI_PROTOCOL_UNKNOWN, ret->category = 0;
+/* ****************************************************** */
- if(flow->packet.iphv6 || flow->packet.iph) {
- u_int16_t sport, dport;
- u_int8_t protocol;
- u_int8_t user_defined_proto;
+static int ndpi_do_guess(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, ndpi_protocol *ret) {
+ ret->master_protocol = ret->app_protocol = NDPI_PROTOCOL_UNKNOWN, ret->category = 0;
- if(flow->packet.iphv6 != NULL) {
- protocol = flow->packet.iphv6->ip6_hdr.ip6_un1_nxt;
- } else
- protocol = flow->packet.iph->protocol;
+ if(flow->packet.iphv6 || flow->packet.iph) {
+ u_int16_t sport, dport;
+ u_int8_t protocol;
+ u_int8_t user_defined_proto;
- if(flow->packet.udp)
- sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest);
- else if(flow->packet.tcp)
- sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
- else
- sport = dport = 0;
+ if(flow->packet.iphv6 != NULL) {
+ protocol = flow->packet.iphv6->ip6_hdr.ip6_un1_nxt;
+ } else
+ protocol = flow->packet.iph->protocol;
- /* guess protocol */
- flow->guessed_protocol_id = (int16_t) ndpi_guess_protocol_id(ndpi_str, flow, protocol, sport, dport, &user_defined_proto);
- flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
+ if(flow->packet.udp)
+ sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest);
+ else if(flow->packet.tcp)
+ sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
+ else
+ sport = dport = 0;
- if(ndpi_str->custom_categories.categories_loaded && flow->packet.iph) {
- if(ndpi_str->ndpi_num_custom_protocols != 0)
- ndpi_fill_ip_protocol_category(ndpi_str, flow->packet.iph->saddr, flow->packet.iph->daddr, ret);
- flow->guessed_header_category = ret->category;
- } else
- flow->guessed_header_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;
+ /* guess protocol */
+ flow->guessed_protocol_id = (int16_t) ndpi_guess_protocol_id(ndpi_str, flow, protocol, sport, dport, &user_defined_proto);
+ flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
- if(flow->guessed_protocol_id >= NDPI_MAX_SUPPORTED_PROTOCOLS) {
- /* This is a custom protocol and it has priority over everything else */
- ret->master_protocol = NDPI_PROTOCOL_UNKNOWN,
- ret->app_protocol = flow->guessed_protocol_id ? flow->guessed_protocol_id : flow->guessed_host_protocol_id;
+ if(ndpi_str->custom_categories.categories_loaded && flow->packet.iph) {
+ if(ndpi_str->ndpi_num_custom_protocols != 0)
+ ndpi_fill_ip_protocol_category(ndpi_str, flow->packet.iph->saddr, flow->packet.iph->daddr, ret);
+ flow->guessed_header_category = ret->category;
+ } else
+ flow->guessed_header_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;
- // if(ndpi_str->ndpi_num_custom_protocols != 0)
- ndpi_fill_protocol_category(ndpi_str, flow, ret);
- return(-1);
- }
+ if(flow->guessed_protocol_id >= NDPI_MAX_SUPPORTED_PROTOCOLS) {
+ /* This is a custom protocol and it has priority over everything else */
+ ret->master_protocol = NDPI_PROTOCOL_UNKNOWN,
+ ret->app_protocol = flow->guessed_protocol_id ? flow->guessed_protocol_id : flow->guessed_host_protocol_id;
- if(user_defined_proto && flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- if(flow->packet.iph) {
- if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- u_int8_t protocol_was_guessed;
+ // if(ndpi_str->ndpi_num_custom_protocols != 0)
+ ndpi_fill_protocol_category(ndpi_str, flow, ret);
+ return(-1);
+ }
- /* ret->master_protocol = flow->guessed_protocol_id , ret->app_protocol = flow->guessed_host_protocol_id; /\* ****** *\/ */
- *ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
- }
+ if(user_defined_proto && flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ if(flow->packet.iph) {
+ if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ u_int8_t protocol_was_guessed;
- // if(ndpi_str->ndpi_num_custom_protocols != 0)
- ndpi_fill_protocol_category(ndpi_str, flow, ret);
- return(-1);
+ /* ret->master_protocol = flow->guessed_protocol_id , ret->app_protocol = flow->guessed_host_protocol_id; /\* ****** *\/ */
+ *ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
}
- } else {
- /* guess host protocol */
- if(flow->packet.iph) {
- flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
- /*
- We could implement a shortcut here skipping dissectors for
- protocols we have identified by other means such as with the IP
+ // if(ndpi_str->ndpi_num_custom_protocols != 0)
+ ndpi_fill_protocol_category(ndpi_str, flow, ret);
+ return(-1);
+ }
+ } else {
+ /* guess host protocol */
+ if(flow->packet.iph) {
+ flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
- However we do NOT stop here and skip invoking the dissectors
- because we want to dissect the flow (e.g. dissect the TLS)
- and extract metadata.
- */
+ /*
+ We could implement a shortcut here skipping dissectors for
+ protocols we have identified by other means such as with the IP
+
+ However we do NOT stop here and skip invoking the dissectors
+ because we want to dissect the flow (e.g. dissect the TLS)
+ and extract metadata.
+ */
#if SKIP_INVOKING_THE_DISSECTORS
- if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- /*
- We have identified a protocol using the IP address so
- it is not worth to dissect the traffic as we already have
- the solution
- */
- ret->master_protocol = flow->guessed_protocol_id, ret->app_protocol = flow->guessed_host_protocol_id;
- }
-#endif
+ if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
+ /*
+ We have identified a protocol using the IP address so
+ it is not worth to dissect the traffic as we already have
+ the solution
+ */
+ ret->master_protocol = flow->guessed_protocol_id, ret->app_protocol = flow->guessed_host_protocol_id;
}
+#endif
}
}
+ }
- if(flow->guessed_host_protocol_id >= NDPI_MAX_SUPPORTED_PROTOCOLS) {
- //u_int32_t num_calls;
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
-
- /* This is a custom protocol and it has priority over everything else */
- ret->master_protocol = flow->guessed_protocol_id, ret->app_protocol = flow->guessed_host_protocol_id;
+ if(flow->guessed_host_protocol_id >= NDPI_MAX_SUPPORTED_PROTOCOLS) {
+ //u_int32_t num_calls;
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
- //num_calls =
- ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
+ /* This is a custom protocol and it has priority over everything else */
+ ret->master_protocol = flow->guessed_protocol_id, ret->app_protocol = flow->guessed_host_protocol_id;
- //if(ndpi_str->ndpi_num_custom_protocols != 0)
- ndpi_fill_protocol_category(ndpi_str, flow, ret);
- return(-1);
- }
+ //num_calls =
+ ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
- return(0);
+ //if(ndpi_str->ndpi_num_custom_protocols != 0)
+ ndpi_fill_protocol_category(ndpi_str, flow, ret);
+ return(-1);
}
- /* ********************************************************************************* */
+ return(0);
+}
- ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow, const unsigned char *packet,
- const unsigned short packetlen, const u_int64_t current_time_ms,
- struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
- u_int32_t a, num_calls = 0;
- ndpi_protocol ret = { flow->detected_protocol_stack[1], flow->detected_protocol_stack[0], flow->category };
+/* ********************************************************************************* */
- if(ndpi_str->ndpi_log_level >= NDPI_LOG_TRACE)
- NDPI_LOG(flow ? flow->detected_protocol_stack[0] : NDPI_PROTOCOL_UNKNOWN, ndpi_str, NDPI_LOG_TRACE,
- "START packet processing\n");
+ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow, const unsigned char *packet,
+ const unsigned short packetlen, const u_int64_t current_time_ms,
+ struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
+ u_int32_t a, num_calls = 0;
+ ndpi_protocol ret = { flow->detected_protocol_stack[1], flow->detected_protocol_stack[0], flow->category };
- if(flow == NULL)
- return(ret);
- else
- ret.category = flow->category;
+ if(ndpi_str->ndpi_log_level >= NDPI_LOG_TRACE)
+ NDPI_LOG(flow ? flow->detected_protocol_stack[0] : NDPI_PROTOCOL_UNKNOWN, ndpi_str, NDPI_LOG_TRACE,
+ "START packet processing\n");
- if(flow->fail_with_unknown) {
- // printf("%s(): FAIL_WITH_UNKNOWN\n", __FUNCTION__);
- return(ret);
- }
+ if(flow == NULL)
+ return(ret);
+ else
+ ret.category = flow->category;
- flow->num_processed_pkts++;
+ if(flow->fail_with_unknown) {
+ // printf("%s(): FAIL_WITH_UNKNOWN\n", __FUNCTION__);
+ return(ret);
+ }
- /* Init default */
- ret.master_protocol = flow->detected_protocol_stack[1],
- ret.app_protocol = flow->detected_protocol_stack[0];
+ flow->num_processed_pkts++;
- if(flow->server_id == NULL)
- flow->server_id = dst; /* Default */
+ /* Init default */
+ ret.master_protocol = flow->detected_protocol_stack[1],
+ ret.app_protocol = flow->detected_protocol_stack[0];
- if(flow->check_extra_packets) {
- ndpi_process_extra_packet(ndpi_str, flow, packet, packetlen, current_time_ms, src, dst);
- /* Update in case of new match */
- ret.master_protocol = flow->detected_protocol_stack[1],
- ret.app_protocol = flow->detected_protocol_stack[0],
- ret.category = flow->category;
- goto invalidate_ptr;
- } else if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
- goto ret_protocols;
+ if(flow->server_id == NULL)
+ flow->server_id = dst; /* Default */
- /* need at least 20 bytes for ip header */
- if(packetlen < 20) {
- /* reset protocol which is normally done in init_packet_header */
- ndpi_int_reset_packet_protocol(&flow->packet);
- goto invalidate_ptr;
- }
+ if(flow->check_extra_packets) {
+ ndpi_process_extra_packet(ndpi_str, flow, packet, packetlen, current_time_ms, src, dst);
+ /* Update in case of new match */
+ ret.master_protocol = flow->detected_protocol_stack[1],
+ ret.app_protocol = flow->detected_protocol_stack[0],
+ ret.category = flow->category;
+ goto invalidate_ptr;
+ } else if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ goto ret_protocols;
- flow->packet.current_time_ms = current_time_ms;
+ /* need at least 20 bytes for ip header */
+ if(packetlen < 20) {
+ /* reset protocol which is normally done in init_packet_header */
+ ndpi_int_reset_packet_protocol(&flow->packet);
+ goto invalidate_ptr;
+ }
- /* parse packet */
- flow->packet.iph = (struct ndpi_iphdr *) packet;
- /* we are interested in ipv4 packet */
+ flow->packet.current_time_ms = current_time_ms;
- if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
- goto invalidate_ptr;
+ /* parse packet */
+ flow->packet.iph = (struct ndpi_iphdr *) packet;
+ /* we are interested in ipv4 packet */
- /* detect traffic for tcp or udp only */
- flow->src = src, flow->dst = dst;
+ if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
+ goto invalidate_ptr;
- ndpi_connection_tracking(ndpi_str, flow);
+ /* detect traffic for tcp or udp only */
+ flow->src = src, flow->dst = dst;
- /* build ndpi_selection packet bitmask */
- ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
- if(flow->packet.iph != NULL)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
+ ndpi_connection_tracking(ndpi_str, flow);
- if(flow->packet.tcp != NULL)
- ndpi_selection_packet |=
- (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
+ /* build ndpi_selection packet bitmask */
+ ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
+ if(flow->packet.iph != NULL)
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
- if(flow->packet.udp != NULL)
- ndpi_selection_packet |=
- (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
+ if(flow->packet.tcp != NULL)
+ ndpi_selection_packet |=
+ (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
- if(flow->packet.payload_packet_len != 0)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
+ if(flow->packet.udp != NULL)
+ ndpi_selection_packet |=
+ (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
- if(flow->packet.tcp_retransmission == 0)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION;
+ if(flow->packet.payload_packet_len != 0)
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
- if(flow->packet.iphv6 != NULL)
- ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
+ if(flow->packet.tcp_retransmission == 0)
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION;
- if(!flow->protocol_id_already_guessed) {
- flow->protocol_id_already_guessed = 1;
+ if(flow->packet.iphv6 != NULL)
+ ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
- if(ndpi_do_guess(ndpi_str, flow, &ret) == -1)
- goto invalidate_ptr;
- }
+ if(!flow->protocol_id_already_guessed) {
+ flow->protocol_id_already_guessed = 1;
- num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
+ if(ndpi_do_guess(ndpi_str, flow, &ret) == -1)
+ goto invalidate_ptr;
+ }
- a = flow->packet.detected_protocol_stack[0];
- if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_str->detection_bitmask, a) == 0)
- a = NDPI_PROTOCOL_UNKNOWN;
+ num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
- if(a != NDPI_PROTOCOL_UNKNOWN) {
- int i;
+ a = flow->packet.detected_protocol_stack[0];
+ if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_str->detection_bitmask, a) == 0)
+ a = NDPI_PROTOCOL_UNKNOWN;
- for(i = 0; i < sizeof(flow->host_server_name); i++) {
- if(flow->host_server_name[i] != '\0')
- flow->host_server_name[i] = tolower(flow->host_server_name[i]);
- else {
- flow->host_server_name[i] = '\0';
- break;
- }
+ if(a != NDPI_PROTOCOL_UNKNOWN) {
+ int i;
+
+ for(i = 0; i < sizeof(flow->host_server_name); i++) {
+ if(flow->host_server_name[i] != '\0')
+ flow->host_server_name[i] = tolower(flow->host_server_name[i]);
+ else {
+ flow->host_server_name[i] = '\0';
+ break;
}
}
+ }
- ret_protocols:
- if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
- ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
-
- if(ret.app_protocol == ret.master_protocol)
- ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
- } else
- ret.app_protocol = flow->detected_protocol_stack[0];
-
- /* Don't overwrite the category if already set */
- if((flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
- ndpi_fill_protocol_category(ndpi_str, flow, &ret);
- else
- ret.category = flow->category;
-
- if((flow->num_processed_pkts == 1) && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) &&
- (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) && flow->packet.tcp && (flow->packet.tcp->syn == 0) &&
- (flow->guessed_protocol_id == 0)) {
- u_int8_t protocol_was_guessed;
-
- /*
- This is a TCP flow
- - whose first packet is NOT a SYN
- - no protocol has been detected
+ ret_protocols:
+ if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
+ ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
- We don't see how future packets can match anything
- hence we giveup here
- */
- ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
- }
+ if(ret.app_protocol == ret.master_protocol)
+ ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
+ } else
+ ret.app_protocol = flow->detected_protocol_stack[0];
- if((ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) &&
- (flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
- ret.master_protocol = ret.app_protocol;
- ret.app_protocol = flow->guessed_host_protocol_id;
- }
+ /* Don't overwrite the category if already set */
+ if((flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
+ ndpi_fill_protocol_category(ndpi_str, flow, &ret);
+ else
+ ret.category = flow->category;
- if((!flow->risk_checked) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) {
- ndpi_default_ports_tree_node_t *found;
- u_int16_t *default_ports, sport, dport;
-
- if(flow->packet.udp)
- found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_UDP,
- sport = ntohs(flow->packet.udp->source),
- dport = ntohs(flow->packet.udp->dest)),
- default_ports = ndpi_str->proto_defaults[ret.master_protocol].udp_default_ports;
- else if(flow->packet.tcp)
- found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_TCP,
- sport = ntohs(flow->packet.tcp->source),
- dport = ntohs(flow->packet.tcp->dest)),
- default_ports = ndpi_str->proto_defaults[ret.master_protocol].tcp_default_ports;
- else
- found = NULL, default_ports = NULL, sport = dport = 0;
+ if((flow->num_processed_pkts == 1) && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) &&
+ (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) && flow->packet.tcp && (flow->packet.tcp->syn == 0) &&
+ (flow->guessed_protocol_id == 0)) {
+ u_int8_t protocol_was_guessed;
- if(found
- && (found->proto->protoId != NDPI_PROTOCOL_UNKNOWN)
- && (found->proto->protoId != ret.master_protocol)
- && (found->proto->protoId != ret.app_protocol)
- ) {
- // printf("******** %u / %u\n", found->proto->protoId, ret.master_protocol);
+ /*
+ This is a TCP flow
+ - whose first packet is NOT a SYN
+ - no protocol has been detected
- if(!ndpi_check_protocol_port_mismatch_exceptions(ndpi_str, flow, found, &ret))
- ndpi_set_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
- } else if((!ndpi_is_ntop_protocol(&ret)) && default_ports && (default_ports[0] != 0)) {
- u_int8_t found = 0, i, num_loops = 0;
+ We don't see how future packets can match anything
+ hence we giveup here
+ */
+ ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
+ }
- check_default_ports:
- for(i=0; (i<MAX_DEFAULT_PORTS) && (default_ports[i] != 0); i++) {
- if((default_ports[i] == sport) || (default_ports[i] == dport)) {
- found = 1;
- break;
- }
- } /* for */
+ if((ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) &&
+ (flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
+ ret.master_protocol = ret.app_protocol;
+ ret.app_protocol = flow->guessed_host_protocol_id;
+ }
- if((num_loops == 0) && (!found)) {
- if(flow->packet.udp)
- default_ports = ndpi_str->proto_defaults[ret.app_protocol].udp_default_ports;
- else
- default_ports = ndpi_str->proto_defaults[ret.app_protocol].tcp_default_ports;
+ if((!flow->risk_checked) && (ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)) {
+ ndpi_default_ports_tree_node_t *found;
+ u_int16_t *default_ports, sport, dport;
- num_loops = 1;
- goto check_default_ports;
+ if(flow->packet.udp)
+ found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_UDP,
+ sport = ntohs(flow->packet.udp->source),
+ dport = ntohs(flow->packet.udp->dest)),
+ default_ports = ndpi_str->proto_defaults[ret.master_protocol].udp_default_ports;
+ else if(flow->packet.tcp)
+ found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_TCP,
+ sport = ntohs(flow->packet.tcp->source),
+ dport = ntohs(flow->packet.tcp->dest)),
+ default_ports = ndpi_str->proto_defaults[ret.master_protocol].tcp_default_ports;
+ else
+ found = NULL, default_ports = NULL, sport = dport = 0;
+
+ if(found
+ && (found->proto->protoId != NDPI_PROTOCOL_UNKNOWN)
+ && (found->proto->protoId != ret.master_protocol)
+ && (found->proto->protoId != ret.app_protocol)
+ ) {
+ // printf("******** %u / %u\n", found->proto->protoId, ret.master_protocol);
+
+ if(!ndpi_check_protocol_port_mismatch_exceptions(ndpi_str, flow, found, &ret))
+ ndpi_set_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
+ } else if((!ndpi_is_ntop_protocol(&ret)) && default_ports && (default_ports[0] != 0)) {
+ u_int8_t found = 0, i, num_loops = 0;
+
+ check_default_ports:
+ for(i=0; (i<MAX_DEFAULT_PORTS) && (default_ports[i] != 0); i++) {
+ if((default_ports[i] == sport) || (default_ports[i] == dport)) {
+ found = 1;
+ break;
}
+ } /* for */
- if(!found) {
- // printf("******** Invalid default port\n");
- ndpi_set_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
- }
+ if((num_loops == 0) && (!found)) {
+ if(flow->packet.udp)
+ default_ports = ndpi_str->proto_defaults[ret.app_protocol].udp_default_ports;
+ else
+ default_ports = ndpi_str->proto_defaults[ret.app_protocol].tcp_default_ports;
+
+ num_loops = 1;
+ goto check_default_ports;
}
- flow->risk_checked = 1;
+ if(!found) {
+ // printf("******** Invalid default port\n");
+ ndpi_set_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
+ }
}
- ndpi_reconcile_protocols(ndpi_str, flow, &ret);
+ flow->risk_checked = 1;
+ }
- if(num_calls == 0)
- flow->fail_with_unknown = 1;
+ ndpi_reconcile_protocols(ndpi_str, flow, &ret);
- invalidate_ptr:
- /*
- Invalidate packet memory to avoid accessing the pointers below
- when the packet is no longer accessible
- */
- flow->packet.iph = NULL, flow->packet.tcp = NULL, flow->packet.udp = NULL, flow->packet.payload = NULL;
- ndpi_reset_packet_line_info(&flow->packet);
+ if(num_calls == 0)
+ flow->fail_with_unknown = 1;
- return(ret);
- }
+ invalidate_ptr:
+ /*
+ Invalidate packet memory to avoid accessing the pointers below
+ when the packet is no longer accessible
+ */
+ flow->packet.iph = NULL, flow->packet.tcp = NULL, flow->packet.udp = NULL, flow->packet.payload = NULL;
+ ndpi_reset_packet_line_info(&flow->packet);
- /* ********************************************************************************* */
+ return(ret);
+}
- u_int32_t ndpi_bytestream_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int32_t val;
- val = 0;
+/* ********************************************************************************* */
- // cancel if eof, ' ' or line end chars are reached
- while(*str >= '0' && *str <= '9' && max_chars_to_read > 0) {
- val *= 10;
- val += *str - '0';
- str++;
- max_chars_to_read = max_chars_to_read - 1;
- *bytes_read = *bytes_read + 1;
- }
+u_int32_t ndpi_bytestream_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int32_t val;
+ val = 0;
- return(val);
+ // cancel if eof, ' ' or line end chars are reached
+ while(*str >= '0' && *str <= '9' && max_chars_to_read > 0) {
+ val *= 10;
+ val += *str - '0';
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
}
- /* ********************************************************************************* */
+ return(val);
+}
+
+/* ********************************************************************************* */
#ifdef CODE_UNUSED
- u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int32_t val;
- val = 0;
- if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
- return(ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read));
- } else {
- /*use base 16 system */
- str += 2;
- max_chars_to_read -= 2;
- *bytes_read = *bytes_read + 2;
-
- while(max_chars_to_read > 0) {
- if(*str >= '0' && *str <= '9') {
- val *= 16;
- val += *str - '0';
- } else if(*str >= 'a' && *str <= 'f') {
- val *= 16;
- val += *str + 10 - 'a';
- } else if(*str >= 'A' && *str <= 'F') {
- val *= 16;
- val += *str + 10 - 'A';
- } else {
- break;
- }
- str++;
- max_chars_to_read = max_chars_to_read - 1;
- *bytes_read = *bytes_read + 1;
+u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int32_t val;
+ val = 0;
+ if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
+ return(ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read));
+ } else {
+ /*use base 16 system */
+ str += 2;
+ max_chars_to_read -= 2;
+ *bytes_read = *bytes_read + 2;
+
+ while(max_chars_to_read > 0) {
+ if(*str >= '0' && *str <= '9') {
+ val *= 16;
+ val += *str - '0';
+ } else if(*str >= 'a' && *str <= 'f') {
+ val *= 16;
+ val += *str + 10 - 'a';
+ } else if(*str >= 'A' && *str <= 'F') {
+ val *= 16;
+ val += *str + 10 - 'A';
+ } else {
+ break;
}
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
}
-
- return(val);
}
+ return(val);
+}
+
#endif
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- u_int64_t ndpi_bytestream_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int64_t val;
- val = 0;
- // cancel if eof, ' ' or line end chars are reached
- while(max_chars_to_read > 0 && *str >= '0' && *str <= '9') {
- val *= 10;
- val += *str - '0';
- str++;
- max_chars_to_read = max_chars_to_read - 1;
- *bytes_read = *bytes_read + 1;
- }
- return(val);
+u_int64_t ndpi_bytestream_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int64_t val;
+ val = 0;
+ // cancel if eof, ' ' or line end chars are reached
+ while(max_chars_to_read > 0 && *str >= '0' && *str <= '9') {
+ val *= 10;
+ val += *str - '0';
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
}
+ return(val);
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read,
- u_int16_t *bytes_read) {
- u_int64_t val;
- val = 0;
- if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
- return(ndpi_bytestream_to_number64(str, max_chars_to_read, bytes_read));
- } else {
- /*use base 16 system */
- str += 2;
- max_chars_to_read -= 2;
- *bytes_read = *bytes_read + 2;
- while(max_chars_to_read > 0) {
- if(*str >= '0' && *str <= '9') {
- val *= 16;
- val += *str - '0';
- } else if(*str >= 'a' && *str <= 'f') {
- val *= 16;
- val += *str + 10 - 'a';
- } else if(*str >= 'A' && *str <= 'F') {
- val *= 16;
- val += *str + 10 - 'A';
- } else {
- break;
- }
- str++;
- max_chars_to_read = max_chars_to_read - 1;
- *bytes_read = *bytes_read + 1;
+u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read,
+ u_int16_t *bytes_read) {
+ u_int64_t val;
+ val = 0;
+ if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
+ return(ndpi_bytestream_to_number64(str, max_chars_to_read, bytes_read));
+ } else {
+ /*use base 16 system */
+ str += 2;
+ max_chars_to_read -= 2;
+ *bytes_read = *bytes_read + 2;
+ while(max_chars_to_read > 0) {
+ if(*str >= '0' && *str <= '9') {
+ val *= 16;
+ val += *str - '0';
+ } else if(*str >= 'a' && *str <= 'f') {
+ val *= 16;
+ val += *str + 10 - 'a';
+ } else if(*str >= 'A' && *str <= 'F') {
+ val *= 16;
+ val += *str + 10 - 'A';
+ } else {
+ break;
}
+ str++;
+ max_chars_to_read = max_chars_to_read - 1;
+ *bytes_read = *bytes_read + 1;
}
- return(val);
}
+ return(val);
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int32_t val;
- u_int16_t read = 0;
- u_int16_t oldread;
- u_int32_t c;
+u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int32_t val;
+ u_int16_t read = 0;
+ u_int16_t oldread;
+ u_int32_t c;
- /* ip address must be X.X.X.X with each X between 0 and 255 */
- oldread = read;
- c = ndpi_bytestream_to_number(str, max_chars_to_read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
- return(0);
+ /* ip address must be X.X.X.X with each X between 0 and 255 */
+ oldread = read;
+ c = ndpi_bytestream_to_number(str, max_chars_to_read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return(0);
- read++;
- val = c << 24;
- oldread = read;
- c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
- return(0);
+ read++;
+ val = c << 24;
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return(0);
- read++;
- val = val + (c << 16);
- oldread = read;
- c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
- return(0);
+ read++;
+ val = val + (c << 16);
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
+ return(0);
- read++;
- val = val + (c << 8);
- oldread = read;
- c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
- if(c > 255 || oldread == read || max_chars_to_read == read)
- return(0);
+ read++;
+ val = val + (c << 8);
+ oldread = read;
+ c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
+ if(c > 255 || oldread == read || max_chars_to_read == read)
+ return(0);
- val = val + c;
+ val = val + c;
- *bytes_read = *bytes_read + read;
+ *bytes_read = *bytes_read + read;
- return(htonl(val));
- }
+ return(htonl(val));
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- /* internal function for every detection to parse one packet and to increase the info buffer */
- void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
- u_int32_t a;
- struct ndpi_packet_struct *packet = &flow->packet;
+/* internal function for every detection to parse one packet and to increase the info buffer */
+void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
+ u_int32_t a;
+ struct ndpi_packet_struct *packet = &flow->packet;
- if((packet->payload_packet_len < 3) || (packet->payload == NULL))
- return;
+ if((packet->payload_packet_len < 3) || (packet->payload == NULL))
+ return;
- if(packet->packet_lines_parsed_complete != 0)
- return;
+ if(packet->packet_lines_parsed_complete != 0)
+ return;
- packet->packet_lines_parsed_complete = 1;
- ndpi_reset_packet_line_info(packet);
+ packet->packet_lines_parsed_complete = 1;
+ ndpi_reset_packet_line_info(packet);
- packet->line[packet->parsed_lines].ptr = packet->payload;
- packet->line[packet->parsed_lines].len = 0;
+ packet->line[packet->parsed_lines].ptr = packet->payload;
+ packet->line[packet->parsed_lines].len = 0;
- for(a = 0; ((a+1) < packet->payload_packet_len) && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET); a++) {
- if((packet->payload[a] == 0x0d) && (packet->payload[a+1] == 0x0a)) {
- /* If end of line char sequence CR+NL "\r\n", process line */
+ for(a = 0; ((a+1) < packet->payload_packet_len) && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET); a++) {
+ if((packet->payload[a] == 0x0d) && (packet->payload[a+1] == 0x0a)) {
+ /* If end of line char sequence CR+NL "\r\n", process line */
- if(((a + 3) < packet->payload_packet_len)
- && (packet->payload[a+2] == 0x0d)
- && (packet->payload[a+3] == 0x0a)) {
- /* \r\n\r\n */
- int diff; /* No unsigned ! */
- u_int32_t a1 = a + 4;
+ if(((a + 3) < packet->payload_packet_len)
+ && (packet->payload[a+2] == 0x0d)
+ && (packet->payload[a+3] == 0x0a)) {
+ /* \r\n\r\n */
+ int diff; /* No unsigned ! */
+ u_int32_t a1 = a + 4;
- diff = packet->payload_packet_len - a1;
+ diff = packet->payload_packet_len - a1;
- if(diff > 0) {
- diff = ndpi_min(diff, sizeof(flow->initial_binary_bytes));
- memcpy(&flow->initial_binary_bytes, &packet->payload[a1], diff);
- flow->initial_binary_bytes_len = diff;
- }
+ if(diff > 0) {
+ diff = ndpi_min(diff, sizeof(flow->initial_binary_bytes));
+ memcpy(&flow->initial_binary_bytes, &packet->payload[a1], diff);
+ flow->initial_binary_bytes_len = diff;
}
+ }
+
+ packet->line[packet->parsed_lines].len =
+ (u_int16_t)(((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
- packet->line[packet->parsed_lines].len =
- (u_int16_t)(((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
+ /* First line of a HTTP response parsing. Expected a "HTTP/1.? ???" */
+ if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.X 200 ") &&
+ strncasecmp((const char *) packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 &&
+ packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] > '0' && /* response code between 000 and 699 */
+ packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] < '6') {
+ packet->http_response.ptr = &packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")];
+ packet->http_response.len = packet->line[0].len - NDPI_STATICSTRING_LEN("HTTP/1.1 ");
+ packet->http_num_headers++;
- /* First line of a HTTP response parsing. Expected a "HTTP/1.? ???" */
- if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.X 200 ") &&
- strncasecmp((const char *) packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 &&
- packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] > '0' && /* response code between 000 and 699 */
- packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] < '6') {
- packet->http_response.ptr = &packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")];
- packet->http_response.len = packet->line[0].len - NDPI_STATICSTRING_LEN("HTTP/1.1 ");
- packet->http_num_headers++;
+ /* Set server HTTP response code */
+ if(packet->payload_packet_len >= 12) {
+ char buf[4];
/* Set server HTTP response code */
- if(packet->payload_packet_len >= 12) {
- char buf[4];
-
- /* Set server HTTP response code */
- strncpy(buf, (char *) &packet->payload[9], 3);
- buf[3] = '\0';
+ strncpy(buf, (char *) &packet->payload[9], 3);
+ buf[3] = '\0';
- flow->http.response_status_code = atoi(buf);
- /* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */
- if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509))
- flow->http.response_status_code = 0; /* Out of range */
- }
+ flow->http.response_status_code = atoi(buf);
+ /* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */
+ if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509))
+ flow->http.response_status_code = 0; /* Out of range */
}
+ }
- /* "Server:" header line in HTTP response */
- if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
- "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) {
- // some stupid clients omit a space and place the servername directly after the colon
- if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') {
- packet->server_line.ptr =
- &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:") + 1];
- packet->server_line.len =
- packet->line[packet->parsed_lines].len - (NDPI_STATICSTRING_LEN("Server:") + 1);
- } else {
- packet->server_line.ptr = &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")];
- packet->server_line.len = packet->line[packet->parsed_lines].len - NDPI_STATICSTRING_LEN("Server:");
- }
- packet->http_num_headers++;
+ /* "Server:" header line in HTTP response */
+ if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
+ "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) {
+ // some stupid clients omit a space and place the servername directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') {
+ packet->server_line.ptr =
+ &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:") + 1];
+ packet->server_line.len =
+ packet->line[packet->parsed_lines].len - (NDPI_STATICSTRING_LEN("Server:") + 1);
+ } else {
+ packet->server_line.ptr = &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")];
+ packet->server_line.len = packet->line[packet->parsed_lines].len - NDPI_STATICSTRING_LEN("Server:");
}
- /* "Host:" header line in HTTP request */
- if(packet->line[packet->parsed_lines].len > 6 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) {
- // some stupid clients omit a space and place the hostname directly after the colon
- if(packet->line[packet->parsed_lines].ptr[5] == ' ') {
- packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6];
- packet->host_line.len = packet->line[packet->parsed_lines].len - 6;
- } else {
- packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[5];
- packet->host_line.len = packet->line[packet->parsed_lines].len - 5;
- }
- packet->http_num_headers++;
+ packet->http_num_headers++;
+ }
+ /* "Host:" header line in HTTP request */
+ if(packet->line[packet->parsed_lines].len > 6 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) {
+ // some stupid clients omit a space and place the hostname directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[5] == ' ') {
+ packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6];
+ packet->host_line.len = packet->line[packet->parsed_lines].len - 6;
+ } else {
+ packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[5];
+ packet->host_line.len = packet->line[packet->parsed_lines].len - 5;
}
- /* "X-Forwarded-For:" header line in HTTP request. Commonly used for HTTP proxies. */
- if(packet->line[packet->parsed_lines].len > 17 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) {
- // some stupid clients omit a space and place the hostname directly after the colon
- if(packet->line[packet->parsed_lines].ptr[16] == ' ') {
- packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17];
- packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 17;
- } else {
- packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[16];
- packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 16;
- }
- packet->http_num_headers++;
+ packet->http_num_headers++;
+ }
+ /* "X-Forwarded-For:" header line in HTTP request. Commonly used for HTTP proxies. */
+ if(packet->line[packet->parsed_lines].len > 17 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) {
+ // some stupid clients omit a space and place the hostname directly after the colon
+ if(packet->line[packet->parsed_lines].ptr[16] == ' ') {
+ packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17];
+ packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 17;
+ } else {
+ packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 16;
}
- /* "Content-Type:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 14 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Type: ", 14) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) {
- packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[14];
- packet->content_line.len = packet->line[packet->parsed_lines].len - 14;
+ packet->http_num_headers++;
+ }
+ /* "Content-Type:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 14 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Type: ", 14) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) {
+ packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[14];
+ packet->content_line.len = packet->line[packet->parsed_lines].len - 14;
- while((packet->content_line.len > 0) && (packet->content_line.ptr[0] == ' '))
- packet->content_line.len--, packet->content_line.ptr++;
+ while((packet->content_line.len > 0) && (packet->content_line.ptr[0] == ' '))
+ packet->content_line.len--, packet->content_line.ptr++;
- packet->http_num_headers++;
- }
- /* "Content-Type:" header line in HTTP AGAIN. Probably a bogus response without space after ":" */
- if((packet->content_line.len == 0) && (packet->line[packet->parsed_lines].len > 13) &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0)) {
- packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[13];
- packet->content_line.len = packet->line[packet->parsed_lines].len - 13;
- packet->http_num_headers++;
- }
+ packet->http_num_headers++;
+ }
+ /* "Content-Type:" header line in HTTP AGAIN. Probably a bogus response without space after ":" */
+ if((packet->content_line.len == 0) && (packet->line[packet->parsed_lines].len > 13) &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0)) {
+ packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[13];
+ packet->content_line.len = packet->line[packet->parsed_lines].len - 13;
+ packet->http_num_headers++;
+ }
- if(packet->content_line.len > 0) {
- /* application/json; charset=utf-8 */
- char separator[] = {';', '\r', '\0'};
- int i;
+ if(packet->content_line.len > 0) {
+ /* application/json; charset=utf-8 */
+ char separator[] = {';', '\r', '\0'};
+ int i;
- for(i = 0; separator[i] != '\0'; i++) {
- char *c = memchr((char *) packet->content_line.ptr, separator[i], packet->content_line.len);
+ for(i = 0; separator[i] != '\0'; i++) {
+ char *c = memchr((char *) packet->content_line.ptr, separator[i], packet->content_line.len);
- if(c != NULL)
- packet->content_line.len = c - (char *) packet->content_line.ptr;
- }
+ if(c != NULL)
+ packet->content_line.len = c - (char *) packet->content_line.ptr;
}
+ }
- /* "Accept:" header line in HTTP request. */
- if(packet->line[packet->parsed_lines].len > 8 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) {
- packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8];
- packet->accept_line.len = packet->line[packet->parsed_lines].len - 8;
- packet->http_num_headers++;
- }
- /* "Referer:" header line in HTTP request. */
- if(packet->line[packet->parsed_lines].len > 9 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) {
- packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9];
- packet->referer_line.len = packet->line[packet->parsed_lines].len - 9;
- packet->http_num_headers++;
- }
- /* "User-Agent:" header line in HTTP request. */
- if(packet->line[packet->parsed_lines].len > 12 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) {
- packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12];
- packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12;
- packet->http_num_headers++;
- }
- /* "Content-Encoding:" header line in HTTP response (and request?). */
- if(packet->line[packet->parsed_lines].len > 18 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) {
- packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18];
- packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18;
- packet->http_num_headers++;
- }
- /* "Transfer-Encoding:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 19 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) {
- packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19];
- packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19;
- packet->http_num_headers++;
- }
- /* "Content-Length:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 16 &&
- ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) ||
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) {
- packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16];
- packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16;
- packet->http_num_headers++;
- }
- /* "Content-Disposition"*/
- if(packet->line[packet->parsed_lines].len > 21 &&
- ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Disposition: ", 21) == 0))) {
- packet->content_disposition_line.ptr = &packet->line[packet->parsed_lines].ptr[21];
- packet->content_disposition_line.len = packet->line[packet->parsed_lines].len - 21;
- packet->http_num_headers++;
- }
- /* "Cookie:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 8 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) {
- packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8];
- packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8;
- packet->http_num_headers++;
- }
- /* "Origin:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 8 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) {
- packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8];
- packet->http_origin.len = packet->line[packet->parsed_lines].len - 8;
- packet->http_num_headers++;
- }
- /* "X-Session-Type:" header line in HTTP. */
- if(packet->line[packet->parsed_lines].len > 16 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) {
- packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16];
- packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16;
- packet->http_num_headers++;
- }
- /* Identification and counting of other HTTP headers.
- * We consider the most common headers, but there are many others,
- * which can be seen at references below:
- * - https://tools.ietf.org/html/rfc7230
- * - https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
- */
- if((packet->line[packet->parsed_lines].len > 6 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Date: ", 6) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Vary: ", 6) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "ETag: ", 6) == 0)) ||
- (packet->line[packet->parsed_lines].len > 8 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Pragma: ", 8) == 0) ||
- (packet->line[packet->parsed_lines].len > 9 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Expires: ", 9) == 0) ||
- (packet->line[packet->parsed_lines].len > 12 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Set-Cookie: ", 12) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Keep-Alive: ", 12) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Connection: ", 12) == 0)) ||
- (packet->line[packet->parsed_lines].len > 15 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Last-Modified: ", 15) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Ranges: ", 15) == 0)) ||
- (packet->line[packet->parsed_lines].len > 17 &&
- (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Language: ", 17) == 0 ||
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Encoding: ", 17) == 0)) ||
- (packet->line[packet->parsed_lines].len > 27 &&
- strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
- "Upgrade-Insecure-Requests: ", 27) == 0)) {
- /* Just count. In the future, if needed, this if can be splited to parse these headers */
- packet->http_num_headers++;
- }
+ /* "Accept:" header line in HTTP request. */
+ if(packet->line[packet->parsed_lines].len > 8 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) {
+ packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->accept_line.len = packet->line[packet->parsed_lines].len - 8;
+ packet->http_num_headers++;
+ }
+ /* "Referer:" header line in HTTP request. */
+ if(packet->line[packet->parsed_lines].len > 9 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) {
+ packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9];
+ packet->referer_line.len = packet->line[packet->parsed_lines].len - 9;
+ packet->http_num_headers++;
+ }
+ /* "User-Agent:" header line in HTTP request. */
+ if(packet->line[packet->parsed_lines].len > 12 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) {
+ packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12];
+ packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12;
+ packet->http_num_headers++;
+ }
+ /* "Content-Encoding:" header line in HTTP response (and request?). */
+ if(packet->line[packet->parsed_lines].len > 18 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) {
+ packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18];
+ packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18;
+ packet->http_num_headers++;
+ }
+ /* "Transfer-Encoding:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 19 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) {
+ packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19];
+ packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19;
+ packet->http_num_headers++;
+ }
+ /* "Content-Length:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 16 &&
+ ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) ||
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) {
+ packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16;
+ packet->http_num_headers++;
+ }
+ /* "Content-Disposition"*/
+ if(packet->line[packet->parsed_lines].len > 21 &&
+ ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Disposition: ", 21) == 0))) {
+ packet->content_disposition_line.ptr = &packet->line[packet->parsed_lines].ptr[21];
+ packet->content_disposition_line.len = packet->line[packet->parsed_lines].len - 21;
+ packet->http_num_headers++;
+ }
+ /* "Cookie:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 8 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) {
+ packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8;
+ packet->http_num_headers++;
+ }
+ /* "Origin:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 8 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) {
+ packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8];
+ packet->http_origin.len = packet->line[packet->parsed_lines].len - 8;
+ packet->http_num_headers++;
+ }
+ /* "X-Session-Type:" header line in HTTP. */
+ if(packet->line[packet->parsed_lines].len > 16 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) {
+ packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16];
+ packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16;
+ packet->http_num_headers++;
+ }
+ /* Identification and counting of other HTTP headers.
+ * We consider the most common headers, but there are many others,
+ * which can be seen at references below:
+ * - https://tools.ietf.org/html/rfc7230
+ * - https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
+ */
+ if((packet->line[packet->parsed_lines].len > 6 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Date: ", 6) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Vary: ", 6) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "ETag: ", 6) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 8 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Pragma: ", 8) == 0) ||
+ (packet->line[packet->parsed_lines].len > 9 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Expires: ", 9) == 0) ||
+ (packet->line[packet->parsed_lines].len > 12 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Set-Cookie: ", 12) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Keep-Alive: ", 12) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Connection: ", 12) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 15 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Last-Modified: ", 15) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Ranges: ", 15) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 17 &&
+ (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Language: ", 17) == 0 ||
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Encoding: ", 17) == 0)) ||
+ (packet->line[packet->parsed_lines].len > 27 &&
+ strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
+ "Upgrade-Insecure-Requests: ", 27) == 0)) {
+ /* Just count. In the future, if needed, this if can be splited to parse these headers */
+ packet->http_num_headers++;
+ }
- if(packet->line[packet->parsed_lines].len == 0) {
- packet->empty_line_position = a;
- packet->empty_line_position_set = 1;
- }
+ if(packet->line[packet->parsed_lines].len == 0) {
+ packet->empty_line_position = a;
+ packet->empty_line_position_set = 1;
+ }
- if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
- return;
+ if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
+ return;
- packet->parsed_lines++;
- packet->line[packet->parsed_lines].ptr = &packet->payload[a + 2];
- packet->line[packet->parsed_lines].len = 0;
+ packet->parsed_lines++;
+ packet->line[packet->parsed_lines].ptr = &packet->payload[a + 2];
+ packet->line[packet->parsed_lines].len = 0;
- a++; /* next char in the payload */
- }
+ a++; /* next char in the payload */
}
+ }
- if(packet->parsed_lines >= 1) {
- packet->line[packet->parsed_lines].len =
- (u_int16_t)(((size_t) &packet->payload[packet->payload_packet_len]) -
- ((size_t) packet->line[packet->parsed_lines].ptr));
- packet->parsed_lines++;
- }
+ if(packet->parsed_lines >= 1) {
+ packet->line[packet->parsed_lines].len =
+ (u_int16_t)(((size_t) &packet->payload[packet->payload_packet_len]) -
+ ((size_t) packet->line[packet->parsed_lines].ptr));
+ packet->parsed_lines++;
}
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &flow->packet;
- u_int32_t a;
- u_int16_t end = packet->payload_packet_len;
+void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t a;
+ u_int16_t end = packet->payload_packet_len;
- if(packet->packet_lines_parsed_complete != 0)
- return;
+ if(packet->packet_lines_parsed_complete != 0)
+ return;
- packet->packet_lines_parsed_complete = 1;
- packet->parsed_lines = 0;
+ packet->packet_lines_parsed_complete = 1;
+ packet->parsed_lines = 0;
- if(packet->payload_packet_len == 0)
- return;
+ if(packet->payload_packet_len == 0)
+ return;
- packet->line[packet->parsed_lines].ptr = packet->payload;
- packet->line[packet->parsed_lines].len = 0;
+ packet->line[packet->parsed_lines].ptr = packet->payload;
+ packet->line[packet->parsed_lines].len = 0;
- for(a = 0; a < end; a++) {
- if(packet->payload[a] == 0x0a) {
- packet->line[packet->parsed_lines].len = (u_int16_t)(
- ((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
+ for(a = 0; a < end; a++) {
+ if(packet->payload[a] == 0x0a) {
+ packet->line[packet->parsed_lines].len = (u_int16_t)(
+ ((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
- if(a > 0 && packet->payload[a - 1] == 0x0d)
- packet->line[packet->parsed_lines].len--;
+ if(a > 0 && packet->payload[a - 1] == 0x0d)
+ packet->line[packet->parsed_lines].len--;
- if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
- break;
+ if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
+ break;
- packet->parsed_lines++;
- packet->line[packet->parsed_lines].ptr = &packet->payload[a + 1];
- packet->line[packet->parsed_lines].len = 0;
+ packet->parsed_lines++;
+ packet->line[packet->parsed_lines].ptr = &packet->payload[a + 1];
+ packet->line[packet->parsed_lines].len = 0;
- if((a + 1) >= packet->payload_packet_len)
- break;
+ if((a + 1) >= packet->payload_packet_len)
+ break;
- //a++;
- }
+ //a++;
}
}
+}
- /* ********************************************************************************* */
-
- u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t counter) {
- struct ndpi_packet_struct *packet = &flow->packet;
+/* ********************************************************************************* */
- NDPI_LOG_DBG2(ndpi_str, "called ndpi_check_for_email_address\n");
+u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t counter) {
+ struct ndpi_packet_struct *packet = &flow->packet;
- if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
- (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
- (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
- packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
- NDPI_LOG_DBG2(ndpi_str, "first letter\n");
+ NDPI_LOG_DBG2(ndpi_str, "called ndpi_check_for_email_address\n");
+
+ if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
+ (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
+ (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
+ packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
+ NDPI_LOG_DBG2(ndpi_str, "first letter\n");
+ counter++;
+ while(packet->payload_packet_len > counter &&
+ ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
+ (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
+ (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
+ packet->payload[counter] == '-' || packet->payload[counter] == '_' ||
+ packet->payload[counter] == '.')) {
+ NDPI_LOG_DBG2(ndpi_str, "further letter\n");
counter++;
- while(packet->payload_packet_len > counter &&
- ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
- (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
- (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
- packet->payload[counter] == '-' || packet->payload[counter] == '_' ||
- packet->payload[counter] == '.')) {
- NDPI_LOG_DBG2(ndpi_str, "further letter\n");
+ if(packet->payload_packet_len > counter && packet->payload[counter] == '@') {
+ NDPI_LOG_DBG2(ndpi_str, "@\n");
counter++;
- if(packet->payload_packet_len > counter && packet->payload[counter] == '@') {
- NDPI_LOG_DBG2(ndpi_str, "@\n");
+ while(packet->payload_packet_len > counter &&
+ ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
+ (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
+ (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
+ packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
+ NDPI_LOG_DBG2(ndpi_str, "letter\n");
counter++;
- while(packet->payload_packet_len > counter &&
- ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
- (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
- (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
- packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
- NDPI_LOG_DBG2(ndpi_str, "letter\n");
+ if(packet->payload_packet_len > counter && packet->payload[counter] == '.') {
+ NDPI_LOG_DBG2(ndpi_str, ".\n");
counter++;
- if(packet->payload_packet_len > counter && packet->payload[counter] == '.') {
- NDPI_LOG_DBG2(ndpi_str, ".\n");
- counter++;
- if(packet->payload_packet_len > counter + 1 &&
- ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') &&
- (packet->payload[counter + 1] >= 'a' && packet->payload[counter + 1] <= 'z'))) {
- NDPI_LOG_DBG2(ndpi_str, "two letters\n");
- counter += 2;
+ if(packet->payload_packet_len > counter + 1 &&
+ ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') &&
+ (packet->payload[counter + 1] >= 'a' && packet->payload[counter + 1] <= 'z'))) {
+ NDPI_LOG_DBG2(ndpi_str, "two letters\n");
+ counter += 2;
+ if(packet->payload_packet_len > counter &&
+ (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
+ NDPI_LOG_DBG2(ndpi_str, "whitespace1\n");
+ return(counter);
+ } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
+ packet->payload[counter] <= 'z') {
+ NDPI_LOG_DBG2(ndpi_str, "one letter\n");
+ counter++;
if(packet->payload_packet_len > counter &&
(packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
- NDPI_LOG_DBG2(ndpi_str, "whitespace1\n");
+ NDPI_LOG_DBG2(ndpi_str, "whitespace2\n");
return(counter);
} else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
packet->payload[counter] <= 'z') {
- NDPI_LOG_DBG2(ndpi_str, "one letter\n");
counter++;
if(packet->payload_packet_len > counter &&
(packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
- NDPI_LOG_DBG2(ndpi_str, "whitespace2\n");
+ NDPI_LOG_DBG2(ndpi_str, "whitespace3\n");
return(counter);
- } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
- packet->payload[counter] <= 'z') {
- counter++;
- if(packet->payload_packet_len > counter &&
- (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
- NDPI_LOG_DBG2(ndpi_str, "whitespace3\n");
- return(counter);
- } else {
- return(0);
- }
} else {
return(0);
}
@@ -5877,1664 +5874,1705 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
} else {
return(0);
}
+ } else {
+ return(0);
}
}
- return(0);
}
+ return(0);
}
}
- return(0);
}
+ return(0);
+}
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_str, const char **file,
- const char **func, u_int32_t *line) {
- *file = "";
- *func = "";
+void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_str, const char **file,
+ const char **func, u_int32_t *line) {
+ *file = "";
+ *func = "";
- if(ndpi_str->ndpi_debug_print_file != NULL)
- *file = ndpi_str->ndpi_debug_print_file;
+ if(ndpi_str->ndpi_debug_print_file != NULL)
+ *file = ndpi_str->ndpi_debug_print_file;
- if(ndpi_str->ndpi_debug_print_function != NULL)
- *func = ndpi_str->ndpi_debug_print_function;
+ if(ndpi_str->ndpi_debug_print_function != NULL)
+ *func = ndpi_str->ndpi_debug_print_function;
- *line = ndpi_str->ndpi_debug_print_line;
- }
+ *line = ndpi_str->ndpi_debug_print_line;
+}
#endif
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- u_int8_t ndpi_detection_get_l4(const u_int8_t *l3, u_int16_t l3_len, const u_int8_t **l4_return,
- u_int16_t *l4_len_return, u_int8_t *l4_protocol_return, u_int32_t flags) {
- return(ndpi_detection_get_l4_internal(NULL, l3, l3_len, l4_return, l4_len_return, l4_protocol_return, flags));
- }
+u_int8_t ndpi_detection_get_l4(const u_int8_t *l3, u_int16_t l3_len, const u_int8_t **l4_return,
+ u_int16_t *l4_len_return, u_int8_t *l4_protocol_return, u_int32_t flags) {
+ return(ndpi_detection_get_l4_internal(NULL, l3, l3_len, l4_return, l4_len_return, l4_protocol_return, flags));
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
- struct ndpi_id_struct *src = flow->src, *dst = flow->dst;
+void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
+ struct ndpi_id_struct *src = flow->src, *dst = flow->dst;
- ndpi_int_change_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
+ ndpi_int_change_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
- if(src != NULL) {
- NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, upper_detected_protocol);
+ if(src != NULL) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, upper_detected_protocol);
- if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
- NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, lower_detected_protocol);
- }
+ if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
+ NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, lower_detected_protocol);
+ }
- if(dst != NULL) {
- NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, upper_detected_protocol);
+ if(dst != NULL) {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, upper_detected_protocol);
- if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
- NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, lower_detected_protocol);
- }
+ if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
+ NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, lower_detected_protocol);
}
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
- return(flow->detected_protocol_stack[1]);
- }
+u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
+ return(flow->detected_protocol_stack[1]);
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
- if(!flow)
- return;
+void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
+ if(!flow)
+ return;
- flow->detected_protocol_stack[0] = upper_detected_protocol,
- flow->detected_protocol_stack[1] = lower_detected_protocol;
- }
+ flow->detected_protocol_stack[0] = upper_detected_protocol,
+ flow->detected_protocol_stack[1] = lower_detected_protocol;
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
- struct ndpi_packet_struct *packet = &flow->packet;
- /* NOTE: everything below is identically to change_flow_protocol
- * except flow->packet If you want to change something here,
- * don't! Change it for the flow function and apply it here
- * as well */
+void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+ /* NOTE: everything below is identically to change_flow_protocol
+ * except flow->packet If you want to change something here,
+ * don't! Change it for the flow function and apply it here
+ * as well */
- if(!packet)
- return;
+ if(!packet)
+ return;
- packet->detected_protocol_stack[0] = upper_detected_protocol,
- packet->detected_protocol_stack[1] = lower_detected_protocol;
- }
+ packet->detected_protocol_stack[0] = upper_detected_protocol,
+ packet->detected_protocol_stack[1] = lower_detected_protocol;
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- /* generic function for changing the protocol
- *
- * what it does is:
- * 1.update the flow protocol stack with the new protocol
- * 2.update the packet protocol stack with the new protocol
- */
- void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
- if((upper_detected_protocol == NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN))
- upper_detected_protocol = lower_detected_protocol;
-
- if(upper_detected_protocol == lower_detected_protocol)
- lower_detected_protocol = NDPI_PROTOCOL_UNKNOWN;
-
- if((upper_detected_protocol != NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol == NDPI_PROTOCOL_UNKNOWN)) {
- if((flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- (upper_detected_protocol != flow->guessed_host_protocol_id)) {
- if(ndpi_str->proto_defaults[upper_detected_protocol].subprotocol_count > 0) {
- lower_detected_protocol = upper_detected_protocol;
- upper_detected_protocol = flow->guessed_host_protocol_id;
- }
+/* generic function for changing the protocol
+ *
+ * what it does is:
+ * 1.update the flow protocol stack with the new protocol
+ * 2.update the packet protocol stack with the new protocol
+ */
+void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
+ if((upper_detected_protocol == NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN))
+ upper_detected_protocol = lower_detected_protocol;
+
+ if(upper_detected_protocol == lower_detected_protocol)
+ lower_detected_protocol = NDPI_PROTOCOL_UNKNOWN;
+
+ if((upper_detected_protocol != NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol == NDPI_PROTOCOL_UNKNOWN)) {
+ if((flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ (upper_detected_protocol != flow->guessed_host_protocol_id)) {
+ if(ndpi_str->proto_defaults[upper_detected_protocol].subprotocol_count > 0) {
+ lower_detected_protocol = upper_detected_protocol;
+ upper_detected_protocol = flow->guessed_host_protocol_id;
}
}
-
- ndpi_int_change_flow_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
- ndpi_int_change_packet_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
}
- /* ********************************************************************************* */
+ ndpi_int_change_flow_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
+ ndpi_int_change_packet_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
+}
- void ndpi_int_change_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
- ndpi_protocol_category_t protocol_category) {
- flow->category = protocol_category;
- }
+/* ********************************************************************************* */
- /* ********************************************************************************* */
+void ndpi_int_change_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
+ ndpi_protocol_category_t protocol_category) {
+ flow->category = protocol_category;
+}
- /* turns a packet back to unknown */
- void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) {
- int a;
+/* ********************************************************************************* */
- for(a = 0; a < NDPI_PROTOCOL_SIZE; a++)
- packet->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
- }
+/* turns a packet back to unknown */
+void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) {
+ int a;
- /* ********************************************************************************* */
+ for(a = 0; a < NDPI_PROTOCOL_SIZE; a++)
+ packet->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
+}
- void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) {
- if(flow) {
- int a;
+/* ********************************************************************************* */
- for(a = 0; a < NDPI_PROTOCOL_SIZE; a++)
- flow->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
- }
+void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) {
+ if(flow) {
+ int a;
+
+ for(a = 0; a < NDPI_PROTOCOL_SIZE; a++)
+ flow->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
}
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- void NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t *ip) {
- memset(ip, 0, sizeof(ndpi_ip_addr_t));
- }
+void NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t *ip) {
+ memset(ip, 0, sizeof(ndpi_ip_addr_t));
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
#ifdef CODE_UNUSED
- /* NTOP */
- int NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t *ip) {
- return(memcmp(ip, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(ndpi_ip_addr_t)) != 0);
- }
+/* NTOP */
+int NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t *ip) {
+ return(memcmp(ip, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(ndpi_ip_addr_t)) != 0);
+}
#endif
- /* ********************************************************************************* */
-
- /* check if the source ip address in packet and ip are equal */
- /* NTOP */
- int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
- /* IPv6 */
- if(packet->iphv6 != NULL) {
- if(packet->iphv6->ip6_src.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
- packet->iphv6->ip6_src.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
- packet->iphv6->ip6_src.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
- packet->iphv6->ip6_src.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
- return(1);
- //else
- return(0);
- }
-
- /* IPv4 */
- if(packet->iph->saddr == ip->ipv4)
+/* ********************************************************************************* */
+
+/* check if the source ip address in packet and ip are equal */
+/* NTOP */
+int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
+ /* IPv6 */
+ if(packet->iphv6 != NULL) {
+ if(packet->iphv6->ip6_src.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
+ packet->iphv6->ip6_src.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
+ packet->iphv6->ip6_src.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
+ packet->iphv6->ip6_src.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
return(1);
+ //else
return(0);
}
- /* ********************************************************************************* */
+ /* IPv4 */
+ if(packet->iph->saddr == ip->ipv4)
+ return(1);
+ return(0);
+}
- /* check if the destination ip address in packet and ip are equal */
- int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
- /* IPv6 */
- if(packet->iphv6 != NULL) {
- if(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
- packet->iphv6->ip6_dst.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
- packet->iphv6->ip6_dst.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
- packet->iphv6->ip6_dst.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
- return(1);
- //else
- return(0);
- }
+/* ********************************************************************************* */
- /* IPv4 */
- if(packet->iph->saddr == ip->ipv4)
+/* check if the destination ip address in packet and ip are equal */
+int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
+ /* IPv6 */
+ if(packet->iphv6 != NULL) {
+ if(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
+ packet->iphv6->ip6_dst.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
+ packet->iphv6->ip6_dst.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
+ packet->iphv6->ip6_dst.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
return(1);
-
+ //else
return(0);
}
- /* ********************************************************************************* */
+ /* IPv4 */
+ if(packet->iph->saddr == ip->ipv4)
+ return(1);
- /* get the source ip address from packet and put it into ip */
- /* NTOP */
- void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
- NDPI_PROTOCOL_IP_clear(ip);
+ return(0);
+}
- /* IPv6 */
- if(packet->iphv6 != NULL) {
- ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_src.u6_addr.u6_addr32[0];
- ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_src.u6_addr.u6_addr32[1];
- ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_src.u6_addr.u6_addr32[2];
- ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_src.u6_addr.u6_addr32[3];
- } else {
- /* IPv4 */
- ip->ipv4 = packet->iph->saddr;
- }
- }
+/* ********************************************************************************* */
- /* ********************************************************************************* */
+/* get the source ip address from packet and put it into ip */
+/* NTOP */
+void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
+ NDPI_PROTOCOL_IP_clear(ip);
- /* get the destination ip address from packet and put it into ip */
- /* NTOP */
- void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
- NDPI_PROTOCOL_IP_clear(ip);
+ /* IPv6 */
+ if(packet->iphv6 != NULL) {
+ ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_src.u6_addr.u6_addr32[0];
+ ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_src.u6_addr.u6_addr32[1];
+ ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_src.u6_addr.u6_addr32[2];
+ ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_src.u6_addr.u6_addr32[3];
+ } else {
+ /* IPv4 */
+ ip->ipv4 = packet->iph->saddr;
+ }
+}
- if(packet->iphv6 != NULL) {
- ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[0];
- ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[1];
- ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[2];
- ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[3];
+/* ********************************************************************************* */
- } else
- ip->ipv4 = packet->iph->daddr;
- }
+/* get the destination ip address from packet and put it into ip */
+/* NTOP */
+void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
+ NDPI_PROTOCOL_IP_clear(ip);
- /* ********************************************************************************* */
+ if(packet->iphv6 != NULL) {
+ ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[0];
+ ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[1];
+ ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[2];
+ ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[3];
- u_int8_t ndpi_is_ipv6(const ndpi_ip_addr_t *ip) {
- return(ip->ipv6.u6_addr.u6_addr32[1] != 0 || ip->ipv6.u6_addr.u6_addr32[2] != 0 ||
- ip->ipv6.u6_addr.u6_addr32[3] != 0);
- }
+ } else
+ ip->ipv4 = packet->iph->daddr;
+}
- /* ********************************************************************************* */
+/* ********************************************************************************* */
- char *ndpi_get_ip_string(const ndpi_ip_addr_t *ip, char *buf, u_int buf_len) {
- const u_int8_t *a = (const u_int8_t *) &ip->ipv4;
+u_int8_t ndpi_is_ipv6(const ndpi_ip_addr_t *ip) {
+ return(ip->ipv6.u6_addr.u6_addr32[1] != 0 || ip->ipv6.u6_addr.u6_addr32[2] != 0 ||
+ ip->ipv6.u6_addr.u6_addr32[3] != 0);
+}
- if(ndpi_is_ipv6(ip)) {
- if(inet_ntop(AF_INET6, &ip->ipv6.u6_addr, buf, buf_len) == NULL)
- buf[0] = '\0';
+/* ********************************************************************************* */
- return(buf);
- }
+char *ndpi_get_ip_string(const ndpi_ip_addr_t *ip, char *buf, u_int buf_len) {
+ const u_int8_t *a = (const u_int8_t *) &ip->ipv4;
- snprintf(buf, buf_len, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
+ if(ndpi_is_ipv6(ip)) {
+ if(inet_ntop(AF_INET6, &ip->ipv6.u6_addr, buf, buf_len) == NULL)
+ buf[0] = '\0';
return(buf);
}
- /* ****************************************************** */
+ snprintf(buf, buf_len, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
- /* Returns -1 on failutre, otherwise fills parsed_ip and returns the IP version */
- int ndpi_parse_ip_string(const char *ip_str, ndpi_ip_addr_t *parsed_ip) {
- int rv = -1;
- memset(parsed_ip, 0, sizeof(*parsed_ip));
+ return(buf);
+}
- if(strchr(ip_str, '.')) {
- if(inet_pton(AF_INET, ip_str, &parsed_ip->ipv4) > 0)
- rv = 4;
- } else {
- if(inet_pton(AF_INET6, ip_str, &parsed_ip->ipv6) > 0)
- rv = 6;
- }
+/* ****************************************************** */
+
+/* Returns -1 on failutre, otherwise fills parsed_ip and returns the IP version */
+int ndpi_parse_ip_string(const char *ip_str, ndpi_ip_addr_t *parsed_ip) {
+ int rv = -1;
+ memset(parsed_ip, 0, sizeof(*parsed_ip));
- return(rv);
+ if(strchr(ip_str, '.')) {
+ if(inet_pton(AF_INET, ip_str, &parsed_ip->ipv4) > 0)
+ rv = 4;
+ } else {
+ if(inet_pton(AF_INET6, ip_str, &parsed_ip->ipv6) > 0)
+ rv = 6;
}
- /* ****************************************************** */
+ return(rv);
+}
- u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t *str,
- u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
- u_int16_t val = ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read);
- return(ntohs(val));
- }
+/* ****************************************************** */
- /* ****************************************************** */
+u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t *str,
+ u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
+ u_int16_t val = ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read);
+ return(ntohs(val));
+}
- u_int8_t ndpi_is_proto(ndpi_protocol proto, u_int16_t p) {
- return(((proto.app_protocol == p) || (proto.master_protocol == p)) ? 1 : 0);
- }
+/* ****************************************************** */
- /* ****************************************************** */
+u_int8_t ndpi_is_proto(ndpi_protocol proto, u_int16_t p) {
+ return(((proto.app_protocol == p) || (proto.master_protocol == p)) ? 1 : 0);
+}
- u_int16_t ndpi_get_lower_proto(ndpi_protocol proto) {
- return((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.master_protocol : proto.app_protocol);
- }
+/* ****************************************************** */
- /* ****************************************************** */
+u_int16_t ndpi_get_lower_proto(ndpi_protocol proto) {
+ return((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.master_protocol : proto.app_protocol);
+}
- u_int16_t ndpi_get_upper_proto(ndpi_protocol proto) {
- return((proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.app_protocol : proto.master_protocol);
- }
+/* ****************************************************** */
+
+u_int16_t ndpi_get_upper_proto(ndpi_protocol proto) {
+ return((proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.app_protocol : proto.master_protocol);
+}
/* ****************************************************** */
- ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow, u_int8_t proto,
- u_int32_t shost /* host byte order */, u_int16_t sport,
- u_int32_t dhost /* host byte order */, u_int16_t dport) {
- u_int32_t rc;
- struct in_addr addr;
- ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
- u_int8_t user_defined_proto;
+ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow, u_int8_t proto,
+ u_int32_t shost /* host byte order */, u_int16_t sport,
+ u_int32_t dhost /* host byte order */, u_int16_t dport) {
+ u_int32_t rc;
+ struct in_addr addr;
+ ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
+ u_int8_t user_defined_proto;
- if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
- rc = ndpi_search_tcp_or_udp_raw(ndpi_str, flow, proto, shost, dhost, sport, dport);
+ if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
+ rc = ndpi_search_tcp_or_udp_raw(ndpi_str, flow, proto, shost, dhost, sport, dport);
- if(rc != NDPI_PROTOCOL_UNKNOWN) {
- if(flow && (proto == IPPROTO_UDP) &&
- NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
- ;
- else {
- ret.app_protocol = rc,
- ret.master_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
+ if(rc != NDPI_PROTOCOL_UNKNOWN) {
+ if(flow && (proto == IPPROTO_UDP) &&
+ NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
+ ;
+ else {
+ ret.app_protocol = rc,
+ ret.master_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
- if(ret.app_protocol == ret.master_protocol)
- ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
+ if(ret.app_protocol == ret.master_protocol)
+ ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
- ret.category = ndpi_get_proto_category(ndpi_str, ret);
- return(ret);
- }
+ ret.category = ndpi_get_proto_category(ndpi_str, ret);
+ return(ret);
}
+ }
- rc = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
- if(rc != NDPI_PROTOCOL_UNKNOWN) {
- if(flow && (proto == IPPROTO_UDP) &&
- NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
- ;
- else {
- ret.app_protocol = rc;
+ rc = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
+ if(rc != NDPI_PROTOCOL_UNKNOWN) {
+ if(flow && (proto == IPPROTO_UDP) &&
+ NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
+ ;
+ else {
+ ret.app_protocol = rc;
- if(rc == NDPI_PROTOCOL_TLS)
- goto check_guessed_skype;
- else {
- ret.category = ndpi_get_proto_category(ndpi_str, ret);
- return(ret);
- }
+ if(rc == NDPI_PROTOCOL_TLS)
+ goto check_guessed_skype;
+ else {
+ ret.category = ndpi_get_proto_category(ndpi_str, ret);
+ return(ret);
}
}
+ }
- check_guessed_skype:
- addr.s_addr = htonl(shost);
- if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE) {
+ check_guessed_skype:
+ addr.s_addr = htonl(shost);
+ if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE) {
+ ret.app_protocol = NDPI_PROTOCOL_SKYPE;
+ } else {
+ addr.s_addr = htonl(dhost);
+ if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE)
ret.app_protocol = NDPI_PROTOCOL_SKYPE;
- } else {
- addr.s_addr = htonl(dhost);
- if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE)
- ret.app_protocol = NDPI_PROTOCOL_SKYPE;
- }
- } else
- ret.app_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
+ }
+ } else
+ ret.app_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
- ret.category = ndpi_get_proto_category(ndpi_str, ret);
- return(ret);
- }
+ ret.category = ndpi_get_proto_category(ndpi_str, ret);
+ return(ret);
+}
+
+/* ****************************************************** */
+
+char *ndpi_protocol2id(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol proto, char *buf, u_int buf_len) {
+ if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
+ if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
+ snprintf(buf, buf_len, "%u.%u", proto.master_protocol, proto.app_protocol);
+ else
+ snprintf(buf, buf_len, "%u", proto.master_protocol);
+ } else
+ snprintf(buf, buf_len, "%u", proto.app_protocol);
- /* ****************************************************** */
+ return(buf);
+}
+
+/* ****************************************************** */
- char *ndpi_protocol2id(struct ndpi_detection_module_struct *ndpi_str,
+char *ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_str,
ndpi_protocol proto, char *buf, u_int buf_len) {
- if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
- if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
- snprintf(buf, buf_len, "%u.%u", proto.master_protocol, proto.app_protocol);
- else
- snprintf(buf, buf_len, "%u", proto.master_protocol);
- } else
- snprintf(buf, buf_len, "%u", proto.app_protocol);
+ if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
+ if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
+ snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol),
+ ndpi_get_proto_name(ndpi_str, proto.app_protocol));
+ else
+ snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol));
+ } else
+ snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.app_protocol));
- return(buf);
+ return(buf);
+}
+
+/* ****************************************************** */
+
+int ndpi_is_custom_category(ndpi_protocol_category_t category) {
+ switch(category) {
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
+ return(1);
+ break;
+
+ default:
+ return(0);
+ break;
}
+}
- /* ****************************************************** */
+/* ****************************************************** */
- char *ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol proto, char *buf, u_int buf_len) {
- if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
- if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
- snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol),
- ndpi_get_proto_name(ndpi_str, proto.app_protocol));
- else
- snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol));
- } else
- snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.app_protocol));
+void ndpi_category_set_name(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol_category_t category,
+ char *name) {
+ if(!name)
+ return;
- return(buf);
+ switch(category) {
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
+ snprintf(ndpi_str->custom_category_labels[0], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
+ snprintf(ndpi_str->custom_category_labels[1], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
+ snprintf(ndpi_str->custom_category_labels[2], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
+ snprintf(ndpi_str->custom_category_labels[3], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
+ case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
+ snprintf(ndpi_str->custom_category_labels[4], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
+ break;
+
+ default:
+ break;
}
+}
+
+/* ****************************************************** */
+
+const char *ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol_category_t category) {
+ if((!ndpi_str) || (category >= NDPI_PROTOCOL_NUM_CATEGORIES)) {
+ static char b[24];
- /* ****************************************************** */
+ if(!ndpi_str)
+ snprintf(b, sizeof(b), "NULL nDPI");
+ else
+ snprintf(b, sizeof(b), "Invalid category %d", (int) category);
+ return(b);
+ }
- int ndpi_is_custom_category(ndpi_protocol_category_t category) {
+ if((category >= NDPI_PROTOCOL_CATEGORY_CUSTOM_1) && (category <= NDPI_PROTOCOL_CATEGORY_CUSTOM_5)) {
switch(category) {
case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
+ return(ndpi_str->custom_category_labels[0]);
case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
+ return(ndpi_str->custom_category_labels[1]);
case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
+ return(ndpi_str->custom_category_labels[2]);
case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
+ return(ndpi_str->custom_category_labels[3]);
case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
- return(1);
- break;
-
+ return(ndpi_str->custom_category_labels[4]);
+ case NDPI_PROTOCOL_NUM_CATEGORIES:
+ return("Code should not use this internal constant");
default:
- return(0);
- break;
+ return("Unspecified");
}
- }
+ } else
+ return(categories[category]);
+}
- /* ****************************************************** */
+/* ****************************************************** */
- void ndpi_category_set_name(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol_category_t category,
- char *name) {
- if(!name)
- return;
+ndpi_protocol_category_t ndpi_get_proto_category(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol proto) {
+ if(proto.category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
+ return(proto.category);
- switch(category) {
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
- snprintf(ndpi_str->custom_category_labels[0], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+ /* simple rule: sub protocol first, master after */
+ else if((proto.master_protocol == NDPI_PROTOCOL_UNKNOWN) ||
+ (ndpi_str->proto_defaults[proto.app_protocol].protoCategory != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)) {
+ if(proto.app_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ return(ndpi_str->proto_defaults[proto.app_protocol].protoCategory);
+ } else if(proto.master_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ return(ndpi_str->proto_defaults[proto.master_protocol].protoCategory);
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
- snprintf(ndpi_str->custom_category_labels[1], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+ return(NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
+}
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
- snprintf(ndpi_str->custom_category_labels[2], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+/* ****************************************************** */
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
- snprintf(ndpi_str->custom_category_labels[3], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+char *ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_str,
+ u_int16_t proto_id) {
+ if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
+ (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
+ (ndpi_str->proto_defaults[proto_id].protoName == NULL))
+ proto_id = NDPI_PROTOCOL_UNKNOWN;
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
- snprintf(ndpi_str->custom_category_labels[4], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
- break;
+ return(ndpi_str->proto_defaults[proto_id].protoName);
+}
- default:
- break;
- }
- }
+/* ****************************************************** */
- /* ****************************************************** */
+ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_str,
+ u_int16_t proto_id) {
+ if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
+ (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
+ (ndpi_str->proto_defaults[proto_id].protoName == NULL))
+ proto_id = NDPI_PROTOCOL_UNKNOWN;
- const char *ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol_category_t category) {
- if((!ndpi_str) || (category >= NDPI_PROTOCOL_NUM_CATEGORIES)) {
- static char b[24];
+ return(ndpi_str->proto_defaults[proto_id].protoBreed);
+}
- if(!ndpi_str)
- snprintf(b, sizeof(b), "NULL nDPI");
- else
- snprintf(b, sizeof(b), "Invalid category %d", (int) category);
- return(b);
- }
+/* ****************************************************** */
- if((category >= NDPI_PROTOCOL_CATEGORY_CUSTOM_1) && (category <= NDPI_PROTOCOL_CATEGORY_CUSTOM_5)) {
- switch(category) {
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
- return(ndpi_str->custom_category_labels[0]);
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
- return(ndpi_str->custom_category_labels[1]);
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
- return(ndpi_str->custom_category_labels[2]);
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
- return(ndpi_str->custom_category_labels[3]);
- case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
- return(ndpi_str->custom_category_labels[4]);
- case NDPI_PROTOCOL_NUM_CATEGORIES:
- return("Code should not use this internal constant");
- default:
- return("Unspecified");
- }
- } else
- return(categories[category]);
+char *ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_protocol_breed_t breed_id) {
+ switch(breed_id) {
+ case NDPI_PROTOCOL_SAFE:
+ return("Safe");
+ break;
+ case NDPI_PROTOCOL_ACCEPTABLE:
+ return("Acceptable");
+ break;
+ case NDPI_PROTOCOL_FUN:
+ return("Fun");
+ break;
+ case NDPI_PROTOCOL_UNSAFE:
+ return("Unsafe");
+ break;
+ case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
+ return("Potentially Dangerous");
+ break;
+ case NDPI_PROTOCOL_TRACKER_ADS:
+ return("Tracker/Ads");
+ break;
+ case NDPI_PROTOCOL_DANGEROUS:
+ return("Dangerous");
+ break;
+ case NDPI_PROTOCOL_UNRATED:
+ return("Unrated");
+ break;
+ default:
+ return("???");
+ break;
}
+}
+
+/* ****************************************************** */
- /* ****************************************************** */
+int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_str, char *proto) {
+ int i;
- ndpi_protocol_category_t ndpi_get_proto_category(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol proto) {
- if(proto.category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
- return(proto.category);
+ for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
+ if(strcasecmp(proto, ndpi_str->proto_defaults[i].protoName) == 0)
+ return(i);
- /* simple rule: sub protocol first, master after */
- else if((proto.master_protocol == NDPI_PROTOCOL_UNKNOWN) ||
- (ndpi_str->proto_defaults[proto.app_protocol].protoCategory != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)) {
- if(proto.app_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
- return(ndpi_str->proto_defaults[proto.app_protocol].protoCategory);
- } else if(proto.master_protocol < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
- return(ndpi_str->proto_defaults[proto.master_protocol].protoCategory);
+ return(-1);
+}
- return(NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
- }
+/* ****************************************************** */
- /* ****************************************************** */
+int ndpi_get_category_id(struct ndpi_detection_module_struct *ndpi_str, char *cat) {
+ int i;
- char *ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_str,
- u_int16_t proto_id) {
- if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
- (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
- (ndpi_str->proto_defaults[proto_id].protoName == NULL))
- proto_id = NDPI_PROTOCOL_UNKNOWN;
+ for(i = 0; i < NDPI_PROTOCOL_NUM_CATEGORIES; i++) {
+ const char *name = ndpi_category_get_name(ndpi_str, i);
- return(ndpi_str->proto_defaults[proto_id].protoName);
+ if(strcasecmp(cat, name) == 0)
+ return(i);
}
- /* ****************************************************** */
+ return(-1);
+}
+
+/* ****************************************************** */
- ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_str,
- u_int16_t proto_id) {
- if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
- (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS)) ||
- (ndpi_str->proto_defaults[proto_id].protoName == NULL))
- proto_id = NDPI_PROTOCOL_UNKNOWN;
+void ndpi_dump_protocols(struct ndpi_detection_module_struct *ndpi_str) {
+ int i;
- return(ndpi_str->proto_defaults[proto_id].protoBreed);
- }
+ for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
+ printf("%3d %-22s %-8s %-12s %s\n", i, ndpi_str->proto_defaults[i].protoName,
+ ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_str, i)),
+ ndpi_get_proto_breed_name(ndpi_str, ndpi_str->proto_defaults[i].protoBreed),
+ ndpi_category_get_name(ndpi_str, ndpi_str->proto_defaults[i].protoCategory));
+}
- /* ****************************************************** */
+/* ****************************************************** */
- char *ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_protocol_breed_t breed_id) {
- switch(breed_id) {
- case NDPI_PROTOCOL_SAFE:
- return("Safe");
- break;
- case NDPI_PROTOCOL_ACCEPTABLE:
- return("Acceptable");
- break;
- case NDPI_PROTOCOL_FUN:
- return("Fun");
- break;
- case NDPI_PROTOCOL_UNSAFE:
- return("Unsafe");
- break;
- case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
- return("Potentially Dangerous");
- break;
- case NDPI_PROTOCOL_TRACKER_ADS:
- return("Tracker/Ads");
+void ndpi_dump_risks_score() {
+ u_int i;
+
+ printf("%3s %-48s %-8s %s\n",
+ "Id", "Risk", "Severity", "Score");
+
+ for(i = 1; i < NDPI_MAX_RISK; i++) {
+ ndpi_risk_enum r = (ndpi_risk_enum)i;
+ ndpi_risk_severity s = ndpi_risk2severity(r);
+ u_int16_t score;
+
+ switch(s) {
+ case NDPI_RISK_LOW:
+ score = NDPI_SCORE_RISK_LOW;
break;
- case NDPI_PROTOCOL_DANGEROUS:
- return("Dangerous");
+
+ case NDPI_RISK_MEDIUM:
+ score = NDPI_SCORE_RISK_MEDIUM;
break;
- case NDPI_PROTOCOL_UNRATED:
- return("Unrated");
+
+ case NDPI_RISK_HIGH:
+ score = NDPI_SCORE_RISK_HIGH;
break;
- default:
- return("???");
+
+ case NDPI_RISK_SEVERE:
+ score = NDPI_SCORE_RISK_SEVERE;
break;
}
+
+ printf("%3d %-48s %-8s %u\n",
+ i, ndpi_risk2str(r),
+ ndpi_severity2str(s),
+ score);
}
+}
- /* ****************************************************** */
+/* ****************************************************** */
- int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_str, char *proto) {
- int i;
+/*
+ * Find the first occurrence of find in s, where the search is limited to the
+ * first slen characters of s.
+ */
+char *ndpi_strnstr(const char *s, const char *find, size_t slen) {
+ char c;
+ size_t len;
- for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
- if(strcasecmp(proto, ndpi_str->proto_defaults[i].protoName) == 0)
- return(i);
+ if((c = *find++) != '\0') {
+ len = strnlen(find, slen);
+ do {
+ char sc;
- return(-1);
+ do {
+ if(slen-- < 1 || (sc = *s++) == '\0')
+ return(NULL);
+ } while(sc != c);
+ if(len > slen)
+ return(NULL);
+ } while(strncmp(s, find, len) != 0);
+ s--;
}
- /* ****************************************************** */
+ return((char *) s);
+}
- int ndpi_get_category_id(struct ndpi_detection_module_struct *ndpi_str, char *cat) {
- int i;
+/* ****************************************************** */
- for(i = 0; i < NDPI_PROTOCOL_NUM_CATEGORIES; i++) {
- const char *name = ndpi_category_get_name(ndpi_str, i);
+/*
+ * Same as ndpi_strnstr but case-insensitive
+ */
+const char * ndpi_strncasestr(const char *str1, const char *str2, size_t len) {
+ size_t str1_len = strnlen(str1, len);
+ size_t str2_len = strlen(str2);
+ size_t i;
- if(strcasecmp(cat, name) == 0)
- return(i);
- }
+ for(i = 0; i < (str1_len - str2_len + 1); i++){
+ if(str1[0] == '\0')
+ return NULL;
+ else if(strncasecmp(str1, str2, str2_len) == 0)
+ return(str1);
- return(-1);
+ str1++;
}
- /* ****************************************************** */
+ return NULL;
+}
- void ndpi_dump_protocols(struct ndpi_detection_module_struct *ndpi_str) {
- int i;
+/* ****************************************************** */
- for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
- printf("%3d %-22s %-8s %-12s %s\n", i, ndpi_str->proto_defaults[i].protoName,
- ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_str, i)),
- ndpi_get_proto_breed_name(ndpi_str, ndpi_str->proto_defaults[i].protoBreed),
- ndpi_category_get_name(ndpi_str, ndpi_str->proto_defaults[i].protoCategory));
- }
+int ndpi_match_prefix(const u_int8_t *payload,
+ size_t payload_len, const char *str, size_t str_len) {
+ int rc = str_len <= payload_len ? memcmp(payload, str, str_len) == 0 : 0;
- /* ****************************************************** */
+ return(rc);
+}
- /*
- * Find the first occurrence of find in s, where the search is limited to the
- * first slen characters of s.
- */
- char *ndpi_strnstr(const char *s, const char *find, size_t slen) {
- char c;
- size_t len;
+/* ****************************************************** */
- if((c = *find++) != '\0') {
- len = strnlen(find, slen);
- do {
- char sc;
+int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str, char *string_to_match,
+ u_int string_to_match_len, ndpi_protocol_match_result *ret_match,
+ u_int8_t is_host_match) {
+ AC_TEXT_t ac_input_text;
+ ndpi_automa *automa = is_host_match ? &ndpi_str->host_automa : &ndpi_str->content_automa;
+ AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
+ int rc;
- do {
- if(slen-- < 1 || (sc = *s++) == '\0')
- return(NULL);
- } while(sc != c);
- if(len > slen)
- return(NULL);
- } while(strncmp(s, find, len) != 0);
- s--;
- }
+ if((automa->ac_automa == NULL) || (string_to_match_len == 0))
+ return(NDPI_PROTOCOL_UNKNOWN);
- return((char *) s);
+ if(!automa->ac_automa_finalized) {
+ printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initialization()\n", __FILE__, __LINE__);
+ return(0); /* No matches */
}
- /* ****************************************************** */
+ ac_input_text.astring = string_to_match, ac_input_text.length = string_to_match_len;
+ rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
/*
- * Same as ndpi_strnstr but case-insensitive
- */
- const char * ndpi_strncasestr(const char *str1, const char *str2, size_t len) {
- size_t str1_len = strnlen(str1, len);
- size_t str2_len = strlen(str2);
- size_t i;
-
- for(i = 0; i < (str1_len - str2_len + 1); i++){
- if(str1[0] == '\0')
- return NULL;
- else if(strncasecmp(str1, str2, str2_len) == 0)
- return(str1);
-
- str1++;
- }
-
- return NULL;
- }
-
- /* ****************************************************** */
-
- int ndpi_match_prefix(const u_int8_t *payload,
- size_t payload_len, const char *str, size_t str_len) {
- int rc = str_len <= payload_len ? memcmp(payload, str, str_len) == 0 : 0;
-
- return(rc);
- }
-
- /* ****************************************************** */
-
- int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str, char *string_to_match,
- u_int string_to_match_len, ndpi_protocol_match_result *ret_match,
- u_int8_t is_host_match) {
- AC_TEXT_t ac_input_text;
- ndpi_automa *automa = is_host_match ? &ndpi_str->host_automa : &ndpi_str->content_automa;
- AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
- int rc;
+ As ac_automata_search can detect partial matches and continue the search process
+ in case rc == 0 (i.e. no match), we need to check if there is a partial match
+ and in this case return it
+ */
+ if((rc == 0) && (match.number != 0))
+ rc = 1;
- if((automa->ac_automa == NULL) || (string_to_match_len == 0))
- return(NDPI_PROTOCOL_UNKNOWN);
+ /* We need to take into account also rc == 0 that is used for partial matches */
+ ret_match->protocol_id = match.number, ret_match->protocol_category = match.category,
+ ret_match->protocol_breed = match.breed;
- if(!automa->ac_automa_finalized) {
- printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initialization()\n", __FILE__, __LINE__);
- return(0); /* No matches */
- }
+ return(rc ? match.number : 0);
+}
- ac_input_text.astring = string_to_match, ac_input_text.length = string_to_match_len;
- rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
+/* **************************************** */
- /*
- As ac_automata_search can detect partial matches and continue the search process
- in case rc == 0 (i.e. no match), we need to check if there is a partial match
- and in this case return it
- */
- if((rc == 0) && (match.number != 0))
- rc = 1;
+static u_int8_t ndpi_is_more_generic_protocol(u_int16_t previous_proto, u_int16_t new_proto) {
+ /* Sometimes certificates are more generic than previously identified protocols */
- /* We need to take into account also rc == 0 that is used for partial matches */
- ret_match->protocol_id = match.number, ret_match->protocol_category = match.category,
- ret_match->protocol_breed = match.breed;
+ if((previous_proto == NDPI_PROTOCOL_UNKNOWN) || (previous_proto == new_proto))
+ return(0);
- return(rc ? match.number : 0);
+ switch(previous_proto) {
+ case NDPI_PROTOCOL_WHATSAPP_CALL:
+ case NDPI_PROTOCOL_WHATSAPP_FILES:
+ if(new_proto == NDPI_PROTOCOL_WHATSAPP)
+ return(1);
}
- /* **************************************** */
-
- static u_int8_t ndpi_is_more_generic_protocol(u_int16_t previous_proto, u_int16_t new_proto) {
- /* Sometimes certificates are more generic than previously identified protocols */
-
- if((previous_proto == NDPI_PROTOCOL_UNKNOWN) || (previous_proto == new_proto))
- return(0);
-
- switch(previous_proto) {
- case NDPI_PROTOCOL_WHATSAPP_CALL:
- case NDPI_PROTOCOL_WHATSAPP_FILES:
- if(new_proto == NDPI_PROTOCOL_WHATSAPP)
- return(1);
- }
-
- return(0);
- }
+ return(0);
+}
- /* ****************************************************** */
+/* ****************************************************** */
- static u_int16_t ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow, char *string_to_match,
- u_int string_to_match_len, u_int16_t master_protocol_id,
- ndpi_protocol_match_result *ret_match, u_int8_t is_host_match) {
- int matching_protocol_id;
- struct ndpi_packet_struct *packet = &flow->packet;
+static u_int16_t ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow, char *string_to_match,
+ u_int string_to_match_len, u_int16_t master_protocol_id,
+ ndpi_protocol_match_result *ret_match, u_int8_t is_host_match) {
+ int matching_protocol_id;
+ struct ndpi_packet_struct *packet = &flow->packet;
- matching_protocol_id =
- ndpi_match_string_subprotocol(ndpi_str, string_to_match, string_to_match_len, ret_match, is_host_match);
+ matching_protocol_id =
+ ndpi_match_string_subprotocol(ndpi_str, string_to_match, string_to_match_len, ret_match, is_host_match);
#ifdef DEBUG
- {
- char m[256];
- int len = ndpi_min(sizeof(m), string_to_match_len);
+ {
+ char m[256];
+ int len = ndpi_min(sizeof(m), string_to_match_len);
- strncpy(m, string_to_match, len);
- m[len] = '\0';
+ strncpy(m, string_to_match, len);
+ m[len] = '\0';
- NDPI_LOG_DBG2(ndpi_str, "[NDPI] ndpi_match_host_subprotocol(%s): %s\n", m,
- ndpi_str->proto_defaults[matching_protocol_id].protoName);
- }
+ NDPI_LOG_DBG2(ndpi_str, "[NDPI] ndpi_match_host_subprotocol(%s): %s\n", m,
+ ndpi_str->proto_defaults[matching_protocol_id].protoName);
+ }
#endif
- if((matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
- (!ndpi_is_more_generic_protocol(packet->detected_protocol_stack[0], matching_protocol_id))) {
- /* Move the protocol on slot 0 down one position */
- packet->detected_protocol_stack[1] = master_protocol_id,
- packet->detected_protocol_stack[0] = matching_protocol_id;
+ if((matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
+ (!ndpi_is_more_generic_protocol(packet->detected_protocol_stack[0], matching_protocol_id))) {
+ /* Move the protocol on slot 0 down one position */
+ packet->detected_protocol_stack[1] = master_protocol_id,
+ packet->detected_protocol_stack[0] = matching_protocol_id;
- flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0],
- flow->detected_protocol_stack[1] = packet->detected_protocol_stack[1];
+ flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0],
+ flow->detected_protocol_stack[1] = packet->detected_protocol_stack[1];
- if(flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
- flow->category = ret_match->protocol_category;
+ if(flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
+ flow->category = ret_match->protocol_category;
- return(packet->detected_protocol_stack[0]);
- }
+ return(packet->detected_protocol_stack[0]);
+ }
#ifdef DEBUG
- string_to_match[string_to_match_len] = '\0';
- NDPI_LOG_DBG2(ndpi_str, "[NTOP] Unable to find a match for '%s'\n", string_to_match);
+ string_to_match[string_to_match_len] = '\0';
+ NDPI_LOG_DBG2(ndpi_str, "[NTOP] Unable to find a match for '%s'\n", string_to_match);
#endif
- ret_match->protocol_id = NDPI_PROTOCOL_UNKNOWN, ret_match->protocol_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
- ret_match->protocol_breed = NDPI_PROTOCOL_UNRATED;
+ ret_match->protocol_id = NDPI_PROTOCOL_UNKNOWN, ret_match->protocol_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
+ ret_match->protocol_breed = NDPI_PROTOCOL_UNRATED;
- return(NDPI_PROTOCOL_UNKNOWN);
- }
+ return(NDPI_PROTOCOL_UNKNOWN);
+}
- /* ****************************************************** */
+/* ****************************************************** */
- void ndpi_check_subprotocol_risk(struct ndpi_flow_struct *flow, u_int16_t subprotocol_id) {
- switch(subprotocol_id) {
- case NDPI_PROTOCOL_ANYDESK:
- ndpi_set_risk(flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */
- break;
- }
+void ndpi_check_subprotocol_risk(struct ndpi_flow_struct *flow, u_int16_t subprotocol_id) {
+ switch(subprotocol_id) {
+ case NDPI_PROTOCOL_ANYDESK:
+ ndpi_set_risk(flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */
+ break;
}
+}
- /* ****************************************************** */
+/* ****************************************************** */
- u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- char *string_to_match, u_int string_to_match_len,
- ndpi_protocol_match_result *ret_match,
- u_int16_t master_protocol_id) {
- u_int16_t rc, buf_len, i;
- ndpi_protocol_category_t id;
- char buf[96];
+u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ char *string_to_match, u_int string_to_match_len,
+ ndpi_protocol_match_result *ret_match,
+ u_int16_t master_protocol_id) {
+ u_int16_t rc, buf_len, i;
+ ndpi_protocol_category_t id;
+ char buf[96];
- buf_len = ndpi_min(string_to_match_len, sizeof(buf)-2);
- for(i=0; i<buf_len; i++) buf[i] = tolower(string_to_match[i]);
- buf[i++] = '$'; /* Add trailer $ */
- buf[i] = '\0';
+ buf_len = ndpi_min(string_to_match_len, sizeof(buf)-2);
+ for(i=0; i<buf_len; i++) buf[i] = tolower(string_to_match[i]);
+ buf[i++] = '$'; /* Add trailer $ */
+ buf[i] = '\0';
- rc = ndpi_automa_match_string_subprotocol(ndpi_str, flow, buf, i,
- master_protocol_id, ret_match, 1);
- id = ret_match->protocol_category;
+ rc = ndpi_automa_match_string_subprotocol(ndpi_str, flow, buf, i,
+ master_protocol_id, ret_match, 1);
+ id = ret_match->protocol_category;
- if(ndpi_get_custom_category_match(ndpi_str, buf, i, &id) != -1) {
- /* if(id != -1) */ {
- flow->category = ret_match->protocol_category = id;
- rc = master_protocol_id;
- }
+ if(ndpi_get_custom_category_match(ndpi_str, buf, i, &id) != -1) {
+ /* if(id != -1) */ {
+ flow->category = ret_match->protocol_category = id;
+ rc = master_protocol_id;
}
+ }
- if(ndpi_str->risky_domain_automa.ac_automa != NULL) {
- u_int16_t rc1 = ndpi_match_string(ndpi_str->risky_domain_automa.ac_automa, buf);
+ if(ndpi_str->risky_domain_automa.ac_automa != NULL) {
+ u_int16_t rc1 = ndpi_match_string(ndpi_str->risky_domain_automa.ac_automa, buf);
- if(rc1 > 0)
- ndpi_set_risk(flow, NDPI_RISKY_DOMAIN);
- }
-
- return(rc);
+ if(rc1 > 0)
+ ndpi_set_risk(flow, NDPI_RISKY_DOMAIN);
}
- /* **************************************** */
+ return(rc);
+}
- int ndpi_match_hostname_protocol(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow,
- u_int16_t master_protocol, char *name, u_int name_len) {
- ndpi_protocol_match_result ret_match;
- u_int16_t subproto, what_len;
- char *what;
+/* **************************************** */
- if((name_len > 2) && (name[0] == '*') && (name[1] == '.'))
- what = &name[1], what_len = name_len - 1;
- else
- what = name, what_len = name_len;
+int ndpi_match_hostname_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t master_protocol, char *name, u_int name_len) {
+ ndpi_protocol_match_result ret_match;
+ u_int16_t subproto, what_len;
+ char *what;
- subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, what, what_len,
- &ret_match, master_protocol);
+ if((name_len > 2) && (name[0] == '*') && (name[1] == '.'))
+ what = &name[1], what_len = name_len - 1;
+ else
+ what = name, what_len = name_len;
- if(subproto != NDPI_PROTOCOL_UNKNOWN) {
- ndpi_set_detected_protocol(ndpi_struct, flow, subproto, master_protocol);
- ndpi_int_change_category(ndpi_struct, flow, ret_match.protocol_category);
- return(1);
- } else
- return(0);
- }
+ subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, what, what_len,
+ &ret_match, master_protocol);
- /* ****************************************************** */
+ if(subproto != NDPI_PROTOCOL_UNKNOWN) {
+ ndpi_set_detected_protocol(ndpi_struct, flow, subproto, master_protocol);
+ ndpi_int_change_category(ndpi_struct, flow, ret_match.protocol_category);
+ return(1);
+ } else
+ return(0);
+}
- u_int16_t ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- char *string_to_match, u_int string_to_match_len,
- ndpi_protocol_match_result *ret_match,
- u_int16_t master_protocol_id) {
- return(ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
- master_protocol_id, ret_match, 0));
- }
+/* ****************************************************** */
- /* ****************************************************** */
+u_int16_t ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ char *string_to_match, u_int string_to_match_len,
+ ndpi_protocol_match_result *ret_match,
+ u_int16_t master_protocol_id) {
+ return(ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
+ master_protocol_id, ret_match, 0));
+}
- int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_automa *automa, char *bigram_to_match) {
- AC_TEXT_t ac_input_text;
- AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
- int rc;
+/* ****************************************************** */
- if((automa->ac_automa == NULL) || (bigram_to_match == NULL))
- return(-1);
+int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_automa *automa, char *bigram_to_match) {
+ AC_TEXT_t ac_input_text;
+ AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
+ int rc;
+
+ if((automa->ac_automa == NULL) || (bigram_to_match == NULL))
+ return(-1);
- if(!automa->ac_automa_finalized) {
+ if(!automa->ac_automa_finalized) {
#if 1
- ndpi_finalize_initialization(ndpi_str);
+ ndpi_finalize_initialization(ndpi_str);
#else
- printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initialization()\n", __FILE__, __LINE__);
- return(0); /* No matches */
+ printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initialization()\n", __FILE__, __LINE__);
+ return(0); /* No matches */
#endif
- }
+ }
- ac_input_text.astring = bigram_to_match, ac_input_text.length = 2;
- rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
+ ac_input_text.astring = bigram_to_match, ac_input_text.length = 2;
+ rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
- /*
- As ac_automata_search can detect partial matches and continue the search process
- in case rc == 0 (i.e. no match), we need to check if there is a partial match
- and in this case return it
- */
- if((rc == 0) && (match.number != 0))
- rc = 1;
+ /*
+ As ac_automata_search can detect partial matches and continue the search process
+ in case rc == 0 (i.e. no match), we need to check if there is a partial match
+ and in this case return it
+ */
+ if((rc == 0) && (match.number != 0))
+ rc = 1;
- return(rc ? match.number : 0);
- }
+ return(rc ? match.number : 0);
+}
- /* ****************************************************** */
+/* ****************************************************** */
- int ndpi_match_trigram(struct ndpi_detection_module_struct *ndpi_str,
- ndpi_automa *automa, char *trigram_to_match) {
- AC_TEXT_t ac_input_text;
- AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
- int rc;
+int ndpi_match_trigram(struct ndpi_detection_module_struct *ndpi_str,
+ ndpi_automa *automa, char *trigram_to_match) {
+ AC_TEXT_t ac_input_text;
+ AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
+ int rc;
- if((automa->ac_automa == NULL) || (trigram_to_match == NULL))
- return(-1);
+ if((automa->ac_automa == NULL) || (trigram_to_match == NULL))
+ return(-1);
- if(!automa->ac_automa_finalized) {
+ if(!automa->ac_automa_finalized) {
#if 1
- ndpi_finalize_initialization(ndpi_str);
+ ndpi_finalize_initialization(ndpi_str);
#else
- printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initialization()\n", __FILE__, __LINE__);
- return(0); /* No matches */
+ printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initialization()\n", __FILE__, __LINE__);
+ return(0); /* No matches */
#endif
- }
+ }
- ac_input_text.astring = trigram_to_match, ac_input_text.length = 3;
- rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
+ ac_input_text.astring = trigram_to_match, ac_input_text.length = 3;
+ rc = ac_automata_search(((AC_AUTOMATA_t *) automa->ac_automa), &ac_input_text, &match);
- /*
- As ac_automata_search can detect partial matches and continue the search process
- in case rc == 0 (i.e. no match), we need to check if there is a partial match
- and in this case return it
- */
- if((rc == 0) && (match.number != 0))
- rc = 1;
-
- if(ndpi_verbose_dga_detection && rc && match.number) {
- printf("[%s:%d] [NDPI] Trigram %c%c%c\n",
- __FILE__, __LINE__,
- trigram_to_match[0],
- trigram_to_match[1],
- trigram_to_match[2]);
- }
+ /*
+ As ac_automata_search can detect partial matches and continue the search process
+ in case rc == 0 (i.e. no match), we need to check if there is a partial match
+ and in this case return it
+ */
+ if((rc == 0) && (match.number != 0))
+ rc = 1;
- return(rc ? match.number : 0);
+ if(ndpi_verbose_dga_detection && rc && match.number) {
+ printf("[%s:%d] [NDPI] Trigram %c%c%c\n",
+ __FILE__, __LINE__,
+ trigram_to_match[0],
+ trigram_to_match[1],
+ trigram_to_match[2]);
}
- /* ****************************************************** */
+ return(rc ? match.number : 0);
+}
- void ndpi_free_flow(struct ndpi_flow_struct *flow) {
- if(flow) {
- ndpi_free_flow_data(flow);
- ndpi_free(flow);
- }
+/* ****************************************************** */
+
+void ndpi_free_flow(struct ndpi_flow_struct *flow) {
+ if(flow) {
+ ndpi_free_flow_data(flow);
+ ndpi_free(flow);
}
+}
- /* ****************************************************** */
+/* ****************************************************** */
- char *ndpi_revision() {
- return(NDPI_GIT_RELEASE);
- }
+char *ndpi_revision() {
+ return(NDPI_GIT_RELEASE);
+}
- /* ****************************************************** */
+/* ****************************************************** */
#ifdef WIN32
- /* https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */
- int gettimeofday(struct timeval *tp, struct timezone *tzp) {
- // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
- // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
- // until 00:00:00 January 1, 1970
- static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
+/* https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */
+int gettimeofday(struct timeval *tp, struct timezone *tzp) {
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
+ // until 00:00:00 January 1, 1970
+ static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
- SYSTEMTIME system_time;
- FILETIME file_time;
- uint64_t time;
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
- GetSystemTime(&system_time);
- SystemTimeToFileTime(&system_time, &file_time);
- time = ((uint64_t) file_time.dwLowDateTime);
- time += ((uint64_t) file_time.dwHighDateTime) << 32;
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ time = ((uint64_t) file_time.dwLowDateTime);
+ time += ((uint64_t) file_time.dwHighDateTime) << 32;
- tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
- tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
- return(0);
- }
+ tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+ return(0);
+}
#endif
- int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
- int i;
-
- for(i = 0; i < NDPI_NUM_FDS_BITS; i++) {
- if(a.fds_bits[i] & b.fds_bits[i])
- return(1);
- }
+int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
+ int i;
- return(0);
+ for(i = 0; i < NDPI_NUM_FDS_BITS; i++) {
+ if(a.fds_bits[i] & b.fds_bits[i])
+ return(1);
}
+ return(0);
+}
+
#ifdef CODE_UNUSED
- int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) {
- int i;
+int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) {
+ int i;
- for(i = 0; i < NDPI_NUM_FDS_BITS; i++)
- if(a.fds_bits[i] != 0)
- return(0);
+ for(i = 0; i < NDPI_NUM_FDS_BITS; i++)
+ if(a.fds_bits[i] != 0)
+ return(0);
- return(1);
- }
+ return(1);
+}
- void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) {
- int i;
+void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) {
+ int i;
- for(i = 0; i < NDPI_NUM_FDS_BITS; i++)
- printf("[%d=%u]", i, a.fds_bits[i]);
+ for(i = 0; i < NDPI_NUM_FDS_BITS; i++)
+ printf("[%d=%u]", i, a.fds_bits[i]);
- printf("\n");
- }
+ printf("\n");
+}
#endif
- u_int16_t ndpi_get_api_version() {
- return(NDPI_API_VERSION);
- }
+u_int16_t ndpi_get_api_version() {
+ return(NDPI_API_VERSION);
+}
- const char *ndpi_get_gcrypt_version(void) {
+const char *ndpi_get_gcrypt_version(void) {
#ifdef HAVE_LIBGCRYPT
- return gcry_check_version(NULL);
+ return gcry_check_version(NULL);
#endif
- return NULL;
- }
+ return NULL;
+}
- ndpi_proto_defaults_t *ndpi_get_proto_defaults(struct ndpi_detection_module_struct *ndpi_str) {
- return(ndpi_str->proto_defaults);
- }
+ndpi_proto_defaults_t *ndpi_get_proto_defaults(struct ndpi_detection_module_struct *ndpi_str) {
+ return(ndpi_str->proto_defaults);
+}
- u_int ndpi_get_ndpi_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_str) {
- return(ndpi_str->ndpi_num_supported_protocols);
- }
+u_int ndpi_get_ndpi_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_str) {
+ return(ndpi_str->ndpi_num_supported_protocols);
+}
- u_int ndpi_get_ndpi_num_custom_protocols(struct ndpi_detection_module_struct *ndpi_str) {
- return(ndpi_str->ndpi_num_custom_protocols);
- }
+u_int ndpi_get_ndpi_num_custom_protocols(struct ndpi_detection_module_struct *ndpi_str) {
+ return(ndpi_str->ndpi_num_custom_protocols);
+}
- u_int ndpi_get_ndpi_detection_module_size() {
- return(sizeof(struct ndpi_detection_module_struct));
- }
+u_int ndpi_get_ndpi_detection_module_size() {
+ return(sizeof(struct ndpi_detection_module_struct));
+}
- void ndpi_set_debug_bitmask(struct ndpi_detection_module_struct *ndpi_str, NDPI_PROTOCOL_BITMASK debug_bitmask) {
+void ndpi_set_debug_bitmask(struct ndpi_detection_module_struct *ndpi_str, NDPI_PROTOCOL_BITMASK debug_bitmask) {
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
- ndpi_str->debug_bitmask = debug_bitmask;
+ ndpi_str->debug_bitmask = debug_bitmask;
#endif
- }
+}
- void ndpi_set_log_level(struct ndpi_detection_module_struct *ndpi_str, u_int l){
- ndpi_str->ndpi_log_level = l;
- }
+void ndpi_set_log_level(struct ndpi_detection_module_struct *ndpi_str, u_int l){
+ ndpi_str->ndpi_log_level = l;
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- /* LRU cache */
- struct ndpi_lru_cache *ndpi_lru_cache_init(u_int32_t num_entries) {
- struct ndpi_lru_cache *c = (struct ndpi_lru_cache *) ndpi_malloc(sizeof(struct ndpi_lru_cache));
+/* LRU cache */
+struct ndpi_lru_cache *ndpi_lru_cache_init(u_int32_t num_entries) {
+ struct ndpi_lru_cache *c = (struct ndpi_lru_cache *) ndpi_malloc(sizeof(struct ndpi_lru_cache));
- if(!c)
- return(NULL);
+ if(!c)
+ return(NULL);
- c->entries = (struct ndpi_lru_cache_entry *) ndpi_calloc(num_entries, sizeof(struct ndpi_lru_cache_entry));
+ c->entries = (struct ndpi_lru_cache_entry *) ndpi_calloc(num_entries, sizeof(struct ndpi_lru_cache_entry));
- if(!c->entries) {
- ndpi_free(c);
- return(NULL);
- } else
- c->num_entries = num_entries;
+ if(!c->entries) {
+ ndpi_free(c);
+ return(NULL);
+ } else
+ c->num_entries = num_entries;
- return(c);
- }
+ return(c);
+}
- void ndpi_lru_free_cache(struct ndpi_lru_cache *c) {
- ndpi_free(c->entries);
- ndpi_free(c);
- }
+void ndpi_lru_free_cache(struct ndpi_lru_cache *c) {
+ ndpi_free(c->entries);
+ ndpi_free(c);
+}
- u_int8_t ndpi_lru_find_cache(struct ndpi_lru_cache *c, u_int32_t key,
- u_int16_t *value, u_int8_t clean_key_when_found) {
- u_int32_t slot = key % c->num_entries;
+u_int8_t ndpi_lru_find_cache(struct ndpi_lru_cache *c, u_int32_t key,
+ u_int16_t *value, u_int8_t clean_key_when_found) {
+ u_int32_t slot = key % c->num_entries;
- if(c->entries[slot].is_full) {
- *value = c->entries[slot].value;
- if(clean_key_when_found)
- c->entries[slot].is_full = 0;
- return(1);
- } else
- return(0);
- }
+ if(c->entries[slot].is_full) {
+ *value = c->entries[slot].value;
+ if(clean_key_when_found)
+ c->entries[slot].is_full = 0;
+ return(1);
+ } else
+ return(0);
+}
- void ndpi_lru_add_to_cache(struct ndpi_lru_cache *c, u_int32_t key, u_int16_t value) {
- u_int32_t slot = key % c->num_entries;
+void ndpi_lru_add_to_cache(struct ndpi_lru_cache *c, u_int32_t key, u_int16_t value) {
+ u_int32_t slot = key % c->num_entries;
- c->entries[slot].is_full = 1, c->entries[slot].key = key, c->entries[slot].value = value;
- }
+ c->entries[slot].is_full = 1, c->entries[slot].key = key, c->entries[slot].value = value;
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- /*
- This function tells if it's possible to further dissect a given flow
- 0 - All possible dissection has been completed
- 1 - Additional dissection is possible
- */
- u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow) {
- u_int16_t proto =
- flow->detected_protocol_stack[1] ? flow->detected_protocol_stack[1] : flow->detected_protocol_stack[0];
+/*
+ This function tells if it's possible to further dissect a given flow
+ 0 - All possible dissection has been completed
+ 1 - Additional dissection is possible
+*/
+u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow) {
+ u_int16_t proto =
+ flow->detected_protocol_stack[1] ? flow->detected_protocol_stack[1] : flow->detected_protocol_stack[0];
#if 0
- printf("[DEBUG] %s(%u.%u): %u\n", __FUNCTION__,
- flow->detected_protocol_stack[0],
- flow->detected_protocol_stack[1],
- proto);
+ printf("[DEBUG] %s(%u.%u): %u\n", __FUNCTION__,
+ flow->detected_protocol_stack[0],
+ flow->detected_protocol_stack[1],
+ proto);
#endif
- switch(proto) {
- case NDPI_PROTOCOL_TLS:
- case NDPI_PROTOCOL_DTLS:
- if(flow->l4.tcp.tls.certificate_processed) return(0);
-
- if(flow->l4.tcp.tls.num_tls_blocks <= ndpi_str->num_tls_blocks_to_follow) {
- // printf("*** %u/%u\n", flow->l4.tcp.tls.num_tls_blocks, ndpi_str->num_tls_blocks_to_follow);
- return(1);
- }
- break;
+ switch(proto) {
+ case NDPI_PROTOCOL_TLS:
+ case NDPI_PROTOCOL_DTLS:
+ if(flow->l4.tcp.tls.certificate_processed) return(0);
- case NDPI_PROTOCOL_HTTP:
- if((flow->host_server_name[0] == '\0') || (flow->http.response_status_code == 0))
- return(1);
- break;
+ if(flow->l4.tcp.tls.num_tls_blocks <= ndpi_str->num_tls_blocks_to_follow) {
+ // printf("*** %u/%u\n", flow->l4.tcp.tls.num_tls_blocks, ndpi_str->num_tls_blocks_to_follow);
+ return(1);
+ }
+ break;
- case NDPI_PROTOCOL_DNS:
- case NDPI_PROTOCOL_MDNS:
- if(flow->protos.dns.num_answers == 0)
- return(1);
- break;
+ case NDPI_PROTOCOL_HTTP:
+ if((flow->host_server_name[0] == '\0') || (flow->http.response_status_code == 0))
+ return(1);
+ break;
- case NDPI_PROTOCOL_FTP_CONTROL:
- case NDPI_PROTOCOL_MAIL_POP:
- case NDPI_PROTOCOL_MAIL_IMAP:
- case NDPI_PROTOCOL_MAIL_SMTP:
- if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0')
- return(1);
- break;
+ case NDPI_PROTOCOL_DNS:
+ case NDPI_PROTOCOL_MDNS:
+ if(flow->protos.dns.num_answers == 0)
+ return(1);
+ break;
- case NDPI_PROTOCOL_SSH:
- if((flow->protos.ssh.hassh_client[0] == '\0') || (flow->protos.ssh.hassh_server[0] == '\0'))
- return(1);
- break;
+ case NDPI_PROTOCOL_FTP_CONTROL:
+ case NDPI_PROTOCOL_MAIL_POP:
+ case NDPI_PROTOCOL_MAIL_IMAP:
+ case NDPI_PROTOCOL_MAIL_SMTP:
+ if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0')
+ return(1);
+ break;
- case NDPI_PROTOCOL_TELNET:
- if(!flow->protos.telnet.password_detected)
- return(1);
- break;
+ case NDPI_PROTOCOL_SSH:
+ if((flow->protos.ssh.hassh_client[0] == '\0') || (flow->protos.ssh.hassh_server[0] == '\0'))
+ return(1);
+ break;
- case NDPI_PROTOCOL_SKYPE:
- if(flow->extra_packets_func)
- return(1);
- break;
+ case NDPI_PROTOCOL_TELNET:
+ if(!flow->protos.telnet.password_detected)
+ return(1);
+ break;
- case NDPI_PROTOCOL_QUIC:
- if(flow->extra_packets_func)
- return(1);
- break;
- }
+ case NDPI_PROTOCOL_SKYPE:
+ if(flow->extra_packets_func)
+ return(1);
+ break;
- return(0);
+ case NDPI_PROTOCOL_QUIC:
+ if(flow->extra_packets_func)
+ return(1);
+ break;
}
- /* ******************************************************************** */
+ return(0);
+}
- const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
- switch(proto) {
- case ndpi_l4_proto_unknown:
- return("");
- break;
+/* ******************************************************************** */
- case ndpi_l4_proto_tcp_only:
- return("TCP");
- break;
+const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
+ switch(proto) {
+ case ndpi_l4_proto_unknown:
+ return("");
+ break;
- case ndpi_l4_proto_udp_only:
- return("UDP");
- break;
+ case ndpi_l4_proto_tcp_only:
+ return("TCP");
+ break;
- case ndpi_l4_proto_tcp_and_udp:
- return("TCP/UDP");
- break;
- }
+ case ndpi_l4_proto_udp_only:
+ return("UDP");
+ break;
- return("");
+ case ndpi_l4_proto_tcp_and_udp:
+ return("TCP/UDP");
+ break;
}
- /* ******************************************************************** */
+ return("");
+}
- ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
- u_int16_t ndpi_proto_id) {
- if(ndpi_proto_id < ndpi_struct->ndpi_num_supported_protocols) {
- u_int16_t idx = ndpi_struct->proto_defaults[ndpi_proto_id].protoIdx;
- NDPI_SELECTION_BITMASK_PROTOCOL_SIZE bm = ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask;
+/* ******************************************************************** */
- if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP)
- return(ndpi_l4_proto_tcp_only);
- else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP)
- return(ndpi_l4_proto_udp_only);
- else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP)
- return(ndpi_l4_proto_tcp_and_udp);
- }
+ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t ndpi_proto_id) {
+ if(ndpi_proto_id < ndpi_struct->ndpi_num_supported_protocols) {
+ u_int16_t idx = ndpi_struct->proto_defaults[ndpi_proto_id].protoIdx;
+ NDPI_SELECTION_BITMASK_PROTOCOL_SIZE bm = ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask;
- return(ndpi_l4_proto_unknown); /* default */
+ if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP)
+ return(ndpi_l4_proto_tcp_only);
+ else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP)
+ return(ndpi_l4_proto_udp_only);
+ else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP)
+ return(ndpi_l4_proto_tcp_and_udp);
}
- /* ******************************************************************** */
+ return(ndpi_l4_proto_unknown); /* default */
+}
+
+/* ******************************************************************** */
- ndpi_ptree_t *ndpi_ptree_create(void) {
- ndpi_ptree_t *tree = (ndpi_ptree_t *) ndpi_malloc(sizeof(ndpi_ptree_t));
+ndpi_ptree_t *ndpi_ptree_create(void) {
+ ndpi_ptree_t *tree = (ndpi_ptree_t *) ndpi_malloc(sizeof(ndpi_ptree_t));
- if(tree) {
- tree->v4 = ndpi_patricia_new(32);
- tree->v6 = ndpi_patricia_new(128);
+ if(tree) {
+ tree->v4 = ndpi_patricia_new(32);
+ tree->v6 = ndpi_patricia_new(128);
- if((!tree->v4) || (!tree->v6)) {
- ndpi_ptree_destroy(tree);
- return(NULL);
- }
+ if((!tree->v4) || (!tree->v6)) {
+ ndpi_ptree_destroy(tree);
+ return(NULL);
}
-
- return(tree);
}
- /* ******************************************************************** */
+ return(tree);
+}
- void ndpi_ptree_destroy(ndpi_ptree_t *tree) {
- if(tree) {
- if(tree->v4)
- ndpi_patricia_destroy(tree->v4, free_ptree_data);
- if(tree->v6)
- ndpi_patricia_destroy(tree->v6, free_ptree_data);
+/* ******************************************************************** */
- ndpi_free(tree);
- }
- }
+void ndpi_ptree_destroy(ndpi_ptree_t *tree) {
+ if(tree) {
+ if(tree->v4)
+ ndpi_patricia_destroy(tree->v4, free_ptree_data);
+ if(tree->v6)
+ ndpi_patricia_destroy(tree->v6, free_ptree_data);
- /* ******************************************************************** */
+ ndpi_free(tree);
+ }
+}
- int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr,
- u_int8_t bits, u_int64_t user_data) {
- u_int8_t is_v6 = ndpi_is_ipv6(addr);
- ndpi_patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
- ndpi_prefix_t prefix;
- ndpi_patricia_node_t *node;
+/* ******************************************************************** */
- if(bits > ptree->maxbits)
- return(-1);
+int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr,
+ u_int8_t bits, u_int64_t user_data) {
+ u_int8_t is_v6 = ndpi_is_ipv6(addr);
+ ndpi_patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
+ ndpi_prefix_t prefix;
+ ndpi_patricia_node_t *node;
- if(is_v6)
- ndpi_fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
- else
- ndpi_fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
+ if(bits > ptree->maxbits)
+ return(-1);
- /* Verify that the node does not already exist */
- node = ndpi_patricia_search_best(ptree, &prefix);
+ if(is_v6)
+ ndpi_fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
+ else
+ ndpi_fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
- if(node && (node->prefix->bitlen == bits))
- return(-2);
+ /* Verify that the node does not already exist */
+ node = ndpi_patricia_search_best(ptree, &prefix);
- node = ndpi_patricia_lookup(ptree, &prefix);
+ if(node && (node->prefix->bitlen == bits))
+ return(-2);
- if(node != NULL) {
- node->value.u.uv64 = user_data;
+ node = ndpi_patricia_lookup(ptree, &prefix);
- return(0);
- }
+ if(node != NULL) {
+ node->value.u.uv64 = user_data;
- return(-3);
+ return(0);
}
- /* ******************************************************************** */
+ return(-3);
+}
- int ndpi_ptree_match_addr(ndpi_ptree_t *tree,
- const ndpi_ip_addr_t *addr, u_int64_t *user_data) {
- u_int8_t is_v6 = ndpi_is_ipv6(addr);
- ndpi_patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
- ndpi_prefix_t prefix;
- ndpi_patricia_node_t *node;
- int bits = ptree->maxbits;
+/* ******************************************************************** */
- if(is_v6)
- ndpi_fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
- else
- ndpi_fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
+int ndpi_ptree_match_addr(ndpi_ptree_t *tree,
+ const ndpi_ip_addr_t *addr, u_int64_t *user_data) {
+ u_int8_t is_v6 = ndpi_is_ipv6(addr);
+ ndpi_patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
+ ndpi_prefix_t prefix;
+ ndpi_patricia_node_t *node;
+ int bits = ptree->maxbits;
- node = ndpi_patricia_search_best(ptree, &prefix);
+ if(is_v6)
+ ndpi_fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
+ else
+ ndpi_fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
- if(node) {
- *user_data = node->value.u.uv64;
+ node = ndpi_patricia_search_best(ptree, &prefix);
- return(0);
- }
+ if(node) {
+ *user_data = node->value.u.uv64;
- return(-1);
+ return(0);
}
- /* ******************************************************************** */
+ return(-1);
+}
+
+/* ******************************************************************** */
- /* Based on djb2 hash - http://www.cse.yorku.ca/~oz/hash.html */
- u_int32_t ndpi_quick_hash(unsigned char *str, u_int str_len) {
- u_int32_t hash = 5381, i;
+/* Based on djb2 hash - http://www.cse.yorku.ca/~oz/hash.html */
+u_int32_t ndpi_quick_hash(unsigned char *str, u_int str_len) {
+ u_int32_t hash = 5381, i;
- for(i=0; i<str_len; i++)
- hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */
+ for(i=0; i<str_len; i++)
+ hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */
- return hash;
- }
+ return hash;
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- void ndpi_md5(const u_char *data, size_t data_len, u_char hash[16]) {
- ndpi_MD5_CTX ctx;
+void ndpi_md5(const u_char *data, size_t data_len, u_char hash[16]) {
+ ndpi_MD5_CTX ctx;
- ndpi_MD5Init(&ctx);
- ndpi_MD5Update(&ctx, data, data_len);
- ndpi_MD5Final(hash, &ctx);
- }
+ ndpi_MD5Init(&ctx);
+ ndpi_MD5Update(&ctx, data, data_len);
+ ndpi_MD5Final(hash, &ctx);
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- static int enough(int a, int b) {
- u_int8_t percentage = 20;
+static int enough(int a, int b) {
+ u_int8_t percentage = 20;
- if(b <= 1) return(0);
- if(a == 0) return(1);
+ if(b <= 1) return(0);
+ if(a == 0) return(1);
- if(b > (((a+1)*percentage)/100)) return(1);
+ if(b > (((a+1)*percentage)/100)) return(1);
- return(0);
- }
+ return(0);
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- static u_int8_t endsWith(char *str, char *ends, u_int8_t ends_len) {
- u_int str_len = str ? strlen(str) : 0;
- u_int8_t rc;
+static u_int8_t endsWith(char *str, char *ends, u_int8_t ends_len) {
+ u_int str_len = str ? strlen(str) : 0;
+ u_int8_t rc;
- if(str_len < ends_len) return(0);
+ if(str_len < ends_len) return(0);
- rc = (strncmp(&str[str_len-ends_len], ends, ends_len) != 0) ? 0 : 1;
+ rc = (strncmp(&str[str_len-ends_len], ends, ends_len) != 0) ? 0 : 1;
#ifdef DGA_DEBUG
- printf("[DGA] %s / %s [rc: %u]\n", str, ends, rc);
+ printf("[DGA] %s / %s [rc: %u]\n", str, ends, rc);
#endif
- return(rc);
- }
+ return(rc);
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- static int ndpi_is_trigram_char(char c) {
- if(isdigit(c) || (c == '.') || (c == '-'))
- return(0);
- else
- return(1);
- }
+static int ndpi_is_trigram_char(char c) {
+ if(isdigit(c) || (c == '.') || (c == '-'))
+ return(0);
+ else
+ return(1);
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- static int ndpi_is_vowel(char c) {
- switch(c) {
- case 'a':
- case 'e':
- case 'i':
- case 'o':
- case 'u':
- case 'y': // Not a real vowel...
- case 'x': // Not a real vowel...
- return(1);
- break;
+static int ndpi_is_vowel(char c) {
+ switch(c) {
+ case 'a':
+ case 'e':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'y': // Not a real vowel...
+ case 'x': // Not a real vowel...
+ return(1);
+ break;
- default:
- return(0);
- }
+ default:
+ return(0);
}
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
- int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
- struct ndpi_flow_struct *flow,
- char *name, u_int8_t is_hostname) {
- if(ndpi_dga_function != NULL) {
- /* A custom DGA function is defined */
- int rc = ndpi_dga_function(name, is_hostname);
+int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
+ struct ndpi_flow_struct *flow,
+ char *name, u_int8_t is_hostname) {
+ if(ndpi_dga_function != NULL) {
+ /* A custom DGA function is defined */
+ int rc = ndpi_dga_function(name, is_hostname);
- if(rc) {
- if(flow)
- ndpi_set_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
- }
+ if(rc) {
+ if(flow)
+ ndpi_set_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
+ }
- return(rc);
- } else {
- int len, rc = 0, trigram_char_skip = 0;
- u_int8_t max_num_char_repetitions = 0, last_char = 0, num_char_repetitions = 0, num_dots = 0, num_trigram_dots = 0;
- u_int8_t max_domain_element_len = 0, curr_domain_element_len = 0, first_element_is_numeric = 1;
-
- if((!name)
- || (strchr(name, '_') != NULL)
- || (endsWith(name, "in-addr.arpa", 12))
- || (endsWith(name, "ip6.arpa", 8))
- /* Ignore TLD .local .lan and .home */
- || (endsWith(name, ".local", 6))
- || (endsWith(name, ".lan", 4))
- || (endsWith(name, ".home", 5))
- )
- return(0);
+ return(rc);
+ } else {
+ int len, rc = 0, trigram_char_skip = 0;
+ u_int8_t max_num_char_repetitions = 0, last_char = 0, num_char_repetitions = 0, num_dots = 0, num_trigram_dots = 0;
+ u_int8_t max_domain_element_len = 0, curr_domain_element_len = 0, first_element_is_numeric = 1;
+
+ if((!name)
+ || (strchr(name, '_') != NULL)
+ || (endsWith(name, "in-addr.arpa", 12))
+ || (endsWith(name, "ip6.arpa", 8))
+ /* Ignore TLD .local .lan and .home */
+ || (endsWith(name, ".local", 6))
+ || (endsWith(name, ".lan", 4))
+ || (endsWith(name, ".home", 5))
+ )
+ return(0);
- if(flow && (flow->packet.detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN))
- return(0); /* Ignore DGA check for protocols already fully detected */
+ if(flow && (flow->packet.detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN))
+ return(0); /* Ignore DGA check for protocols already fully detected */
- if(strncmp(name, "www.", 4) == 0)
- name = &name[4];
+ if(strncmp(name, "www.", 4) == 0)
+ name = &name[4];
- if(ndpi_verbose_dga_detection)
- printf("[DGA check] %s\n", name);
+ if(ndpi_verbose_dga_detection)
+ printf("[DGA check] %s\n", name);
- len = strlen(name);
+ len = strlen(name);
- if(len >= 5) {
- int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0,
- num_trigram_found = 0, num_trigram_checked = 0, num_dash = 0,
- num_digits = 0, num_vowels = 0, num_trigram_vowels = 0, num_words = 0, skip_next_bigram = 0;
- char tmp[128], *word, *tok_tmp;
- u_int max_tmp_len = sizeof(tmp)-1;
+ if(len >= 5) {
+ int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0,
+ num_trigram_found = 0, num_trigram_checked = 0, num_dash = 0,
+ num_digits = 0, num_vowels = 0, num_trigram_vowels = 0, num_words = 0, skip_next_bigram = 0;
+ char tmp[128], *word, *tok_tmp;
+ u_int max_tmp_len = sizeof(tmp)-1;
- len = snprintf(tmp, max_tmp_len, "%s", name);
- if(len < 0) {
+ len = snprintf(tmp, max_tmp_len, "%s", name);
+ if(len < 0) {
- if(ndpi_verbose_dga_detection)
- printf("[DGA] Too short");
+ if(ndpi_verbose_dga_detection)
+ printf("[DGA] Too short");
- return(0);
- } else
- tmp[len < max_tmp_len ? len : max_tmp_len] = '\0';
+ return(0);
+ } else
+ tmp[len < max_tmp_len ? len : max_tmp_len] = '\0';
- for(i=0, j=0; (i<len) && (j<max_tmp_len); i++) {
- tmp[j] = tolower(name[i]);
+ for(i=0, j=0; (i<len) && (j<max_tmp_len); i++) {
+ tmp[j] = tolower(name[i]);
- if(tmp[j] == '.') {
- num_dots++;
- } else if(num_dots == 0) {
- if(!isdigit(tmp[j]))
- first_element_is_numeric = 0;
- }
+ if(tmp[j] == '.') {
+ num_dots++;
+ } else if(num_dots == 0) {
+ if(!isdigit(tmp[j]))
+ first_element_is_numeric = 0;
+ }
- if(ndpi_is_vowel(tmp[j]))
- num_vowels++;
+ if(ndpi_is_vowel(tmp[j]))
+ num_vowels++;
- if(last_char == tmp[j]) {
- if(++num_char_repetitions > max_num_char_repetitions)
- max_num_char_repetitions = num_char_repetitions;
- } else
- num_char_repetitions = 1, last_char = tmp[j];
+ if(last_char == tmp[j]) {
+ if(++num_char_repetitions > max_num_char_repetitions)
+ max_num_char_repetitions = num_char_repetitions;
+ } else
+ num_char_repetitions = 1, last_char = tmp[j];
- if(isdigit(tmp[j])) {
- num_digits++;
+ if(isdigit(tmp[j])) {
+ num_digits++;
- if(((j+2)<len) && isdigit(tmp[j+1]) && (tmp[j+2] == '.')) {
- /* Check if there are too many digits */
- if(num_digits < 4)
- return(0); /* Double digits */
- }
+ if(((j+2)<len) && isdigit(tmp[j+1]) && (tmp[j+2] == '.')) {
+ /* Check if there are too many digits */
+ if(num_digits < 4)
+ return(0); /* Double digits */
}
+ }
- switch(tmp[j]) {
- case '.':
- case '-':
- case '_':
- case '/':
- case ')':
- case '(':
- case ';':
- case ':':
- case '[':
- case ']':
- case ' ':
- /*
- Domain/word separator chars
-
- NOTE:
- this function is used also to detect other type of issues
- such as invalid/suspiciuous user agent
- */
- if(curr_domain_element_len > max_domain_element_len)
- max_domain_element_len = curr_domain_element_len;
+ switch(tmp[j]) {
+ case '.':
+ case '-':
+ case '_':
+ case '/':
+ case ')':
+ case '(':
+ case ';':
+ case ':':
+ case '[':
+ case ']':
+ case ' ':
+ /*
+ Domain/word separator chars
- curr_domain_element_len = 0;
- break;
+ NOTE:
+ this function is used also to detect other type of issues
+ such as invalid/suspiciuous user agent
+ */
+ if(curr_domain_element_len > max_domain_element_len)
+ max_domain_element_len = curr_domain_element_len;
- default:
- curr_domain_element_len++;
- break;
- }
+ curr_domain_element_len = 0;
+ break;
- j++;
+ default:
+ curr_domain_element_len++;
+ break;
}
- if(num_dots == 0) /* Doesn't look like a domain name */
- return(0);
+ j++;
+ }
- if(curr_domain_element_len > max_domain_element_len)
- max_domain_element_len = curr_domain_element_len;
+ if(num_dots == 0) /* Doesn't look like a domain name */
+ return(0);
- if(ndpi_verbose_dga_detection)
- printf("[DGA] [max_num_char_repetitions: %u][max_domain_element_len: %u]\n",
- max_num_char_repetitions, max_domain_element_len);
-
- if(
- (is_hostname
- && (num_dots > 5)
- && (!first_element_is_numeric)
- )
- || (max_num_char_repetitions > 5 /* num or consecutive repeated chars */)
- /*
- In case of a name with too many consecutive chars an alert is triggered
- This is the case for instance of the wildcard DNS query used by NetBIOS
- (ckaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) and that can be exploited
- for reflection attacks
- - https://www.akamai.com/uk/en/multimedia/documents/state-of-the-internet/ddos-reflection-netbios-name-server-rpc-portmap-sentinel-udp-threat-advisory.pdf
- - http://ubiqx.org/cifs/NetBIOS.html
- */
- || ((max_domain_element_len >= 19 /* word too long. Example bbcbedxhgjmdobdprmen.com */) && ((num_char_repetitions > 1) || (num_digits > 1)))
- ) {
- if(flow) ndpi_set_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
+ if(curr_domain_element_len > max_domain_element_len)
+ max_domain_element_len = curr_domain_element_len;
- if(ndpi_verbose_dga_detection)
- printf("[DGA] Found!");
+ if(ndpi_verbose_dga_detection)
+ printf("[DGA] [max_num_char_repetitions: %u][max_domain_element_len: %u]\n",
+ max_num_char_repetitions, max_domain_element_len);
+
+ if(
+ (is_hostname
+ && (num_dots > 5)
+ && (!first_element_is_numeric)
+ )
+ || (max_num_char_repetitions > 5 /* num or consecutive repeated chars */)
+ /*
+ In case of a name with too many consecutive chars an alert is triggered
+ This is the case for instance of the wildcard DNS query used by NetBIOS
+ (ckaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) and that can be exploited
+ for reflection attacks
+ - https://www.akamai.com/uk/en/multimedia/documents/state-of-the-internet/ddos-reflection-netbios-name-server-rpc-portmap-sentinel-udp-threat-advisory.pdf
+ - http://ubiqx.org/cifs/NetBIOS.html
+ */
+ || ((max_domain_element_len >= 19 /* word too long. Example bbcbedxhgjmdobdprmen.com */) && ((num_char_repetitions > 1) || (num_digits > 1)))
+ ) {
+ if(flow) ndpi_set_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
- return(1);
- }
+ if(ndpi_verbose_dga_detection)
+ printf("[DGA] Found!");
+
+ return(1);
+ }
- tmp[j] = '\0';
- len = j;
+ tmp[j] = '\0';
+ len = j;
- for(word = strtok_r(tmp, ".", &tok_tmp); ; word = strtok_r(NULL, ".", &tok_tmp)) {
- if(!word) break;
+ for(word = strtok_r(tmp, ".", &tok_tmp); ; word = strtok_r(NULL, ".", &tok_tmp)) {
+ if(!word) break;
- num_words++;
+ num_words++;
- if(strlen(word) < 3) continue;
+ if(strlen(word) < 3) continue;
- if(ndpi_verbose_dga_detection)
- printf("-> word(%s) [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
+ if(ndpi_verbose_dga_detection)
+ printf("-> word(%s) [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
- trigram_char_skip = 0;
+ trigram_char_skip = 0;
- for(i = 0; word[i+1] != '\0'; i++) {
- switch(word[i]) {
- case '-':
- num_dash++;
- /*
- Let's check for double+consecutive --
- that are usually ok
- r2---sn-uxaxpu5ap5-2n5e.gvt1.com
- */
- if(word[i+1] == '-')
- return(0); /* Double dash */
-
- case '_':
- case ':':
- continue;
- break;
-
- case '.':
- continue;
- break;
- }
- num_bigram_checks++;
+ for(i = 0; word[i+1] != '\0'; i++) {
+ switch(word[i]) {
+ case '-':
+ num_dash++;
+ /*
+ Let's check for double+consecutive --
+ that are usually ok
+ r2---sn-uxaxpu5ap5-2n5e.gvt1.com
+ */
+ if(word[i+1] == '-')
+ return(0); /* Double dash */
- if(ndpi_verbose_dga_detection)
- printf("-> Checking %c%c\n", word[i], word[i+1]);
+ case '_':
+ case ':':
+ continue;
+ break;
+
+ case '.':
+ continue;
+ break;
+ }
+ num_bigram_checks++;
- if(ndpi_match_bigram(ndpi_str,
- &ndpi_str->impossible_bigrams_automa,
- &word[i])) {
- if(ndpi_verbose_dga_detection)
- printf("IMPOSSIBLE %s\n", &word[i]);
+ if(ndpi_verbose_dga_detection)
+ printf("-> Checking %c%c\n", word[i], word[i+1]);
- num_impossible++;
- } else {
- if(!skip_next_bigram) {
- if(ndpi_match_bigram(ndpi_str, &ndpi_str->bigrams_automa, &word[i])) {
- num_found++, skip_next_bigram = 1;
- }
- } else
- skip_next_bigram = 0;
- }
+ if(ndpi_match_bigram(ndpi_str,
+ &ndpi_str->impossible_bigrams_automa,
+ &word[i])) {
+ if(ndpi_verbose_dga_detection)
+ printf("IMPOSSIBLE %s\n", &word[i]);
+
+ num_impossible++;
+ } else {
+ if(!skip_next_bigram) {
+ if(ndpi_match_bigram(ndpi_str, &ndpi_str->bigrams_automa, &word[i])) {
+ num_found++, skip_next_bigram = 1;
+ }
+ } else
+ skip_next_bigram = 0;
+ }
- if((num_trigram_dots < 2) && (word[i+2] != '\0')) {
- if(ndpi_verbose_dga_detection)
- printf("***> %s [trigram_char_skip: %u]\n", &word[i], trigram_char_skip);
+ if((num_trigram_dots < 2) && (word[i+2] != '\0')) {
+ if(ndpi_verbose_dga_detection)
+ printf("***> %s [trigram_char_skip: %u]\n", &word[i], trigram_char_skip);
- if(ndpi_is_trigram_char(word[i]) && ndpi_is_trigram_char(word[i+1]) && ndpi_is_trigram_char(word[i+2])) {
- if(trigram_char_skip) {
- trigram_char_skip--;
- } else {
- num_trigram_checked++;
+ if(ndpi_is_trigram_char(word[i]) && ndpi_is_trigram_char(word[i+1]) && ndpi_is_trigram_char(word[i+2])) {
+ if(trigram_char_skip) {
+ trigram_char_skip--;
+ } else {
+ num_trigram_checked++;
- if(ndpi_match_trigram(ndpi_str, &ndpi_str->trigrams_automa, &word[i]))
- num_trigram_found++, trigram_char_skip = 2 /* 1 char overlap */;
- else if(ndpi_verbose_dga_detection)
- printf("[NDPI] NO Trigram %c%c%c\n", word[i], word[i+1], word[i+2]);
+ if(ndpi_match_trigram(ndpi_str, &ndpi_str->trigrams_automa, &word[i]))
+ num_trigram_found++, trigram_char_skip = 2 /* 1 char overlap */;
+ else if(ndpi_verbose_dga_detection)
+ printf("[NDPI] NO Trigram %c%c%c\n", word[i], word[i+1], word[i+2]);
- /* Count vowels */
- num_trigram_vowels += ndpi_is_vowel(word[i]) + ndpi_is_vowel(word[i+1]) + ndpi_is_vowel(word[i+2]);
- }
- } else {
- if(word[i] == '.')
- num_trigram_dots++;
-
- trigram_char_skip = 0;
+ /* Count vowels */
+ num_trigram_vowels += ndpi_is_vowel(word[i]) + ndpi_is_vowel(word[i+1]) + ndpi_is_vowel(word[i+2]);
}
+ } else {
+ if(word[i] == '.')
+ num_trigram_dots++;
+
+ trigram_char_skip = 0;
}
- } /* for */
+ }
} /* for */
+ } /* for */
- if(ndpi_verbose_dga_detection)
- printf("[%s][num_found: %u][num_impossible: %u][num_digits: %u][num_bigram_checks: %u][num_vowels: %u/%u][num_trigram_vowels: %u][num_trigram_found: %u/%u][vowels: %u][rc: %u]\n",
- name, num_found, num_impossible, num_digits, num_bigram_checks, num_vowels, len, num_trigram_vowels,
- num_trigram_checked, num_trigram_found, num_vowels, rc);
-
- if((len > 16) && (num_dots < 3) && ((num_vowels*4) < (len-num_dots))) {
- if((num_trigram_checked > 2) && (num_trigram_vowels >= (num_trigram_found-1)))
- ; /* skip me */
- else
- rc = 1;
- }
-
- if(num_bigram_checks
- && (num_dots > 0)
- && ((num_found == 0) || ((num_digits > 5) && (num_words <= 3))
- || enough(num_found, num_impossible)
- || ((num_trigram_checked > 2)
- && ((num_trigram_found < (num_trigram_checked/2))
- || ((num_trigram_vowels < (num_trigram_found-1)) && (num_dash == 0) && (num_dots > 1)))
- )
- )
- )
+ if(ndpi_verbose_dga_detection)
+ printf("[%s][num_found: %u][num_impossible: %u][num_digits: %u][num_bigram_checks: %u][num_vowels: %u/%u][num_trigram_vowels: %u][num_trigram_found: %u/%u][vowels: %u][rc: %u]\n",
+ name, num_found, num_impossible, num_digits, num_bigram_checks, num_vowels, len, num_trigram_vowels,
+ num_trigram_checked, num_trigram_found, num_vowels, rc);
+
+ if((len > 16) && (num_dots < 3) && ((num_vowels*4) < (len-num_dots))) {
+ if((num_trigram_checked > 2) && (num_trigram_vowels >= (num_trigram_found-1)))
+ ; /* skip me */
+ else
rc = 1;
+ }
+
+ if(num_bigram_checks
+ && (num_dots > 0)
+ && ((num_found == 0) || ((num_digits > 5) && (num_words <= 3))
+ || enough(num_found, num_impossible)
+ || ((num_trigram_checked > 2)
+ && ((num_trigram_found < (num_trigram_checked/2))
+ || ((num_trigram_vowels < (num_trigram_found-1)) && (num_dash == 0) && (num_dots > 1)))
+ )
+ )
+ )
+ rc = 1;
- if((num_trigram_checked > 2) && (num_vowels == 0))
- rc = 1;
+ if((num_trigram_checked > 2) && (num_vowels == 0))
+ rc = 1;
- if(num_dash > 2)
- rc = 0;
+ if(num_dash > 2)
+ rc = 0;
- if(ndpi_verbose_dga_detection) {
- if(rc)
- printf("DGA %s [num_found: %u][num_impossible: %u]\n",
- name, num_found, num_impossible);
- }
+ if(ndpi_verbose_dga_detection) {
+ if(rc)
+ printf("DGA %s [num_found: %u][num_impossible: %u]\n",
+ name, num_found, num_impossible);
}
+ }
- if(ndpi_verbose_dga_detection)
- printf("[DGA] Result: %u\n", rc);
+ if(ndpi_verbose_dga_detection)
+ printf("[DGA] Result: %u\n", rc);
- if(rc && flow)
- ndpi_set_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
+ if(rc && flow)
+ ndpi_set_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
- return(rc);
- }
+ return(rc);
}
+}
- /* ******************************************************************** */
+/* ******************************************************************** */
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index 12140cdc9..0f784bb7e 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1714,7 +1714,7 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) {
return("Possibly Malicious JA3 Fingerprint");
case NDPI_MALICIOUS_SHA1_CERTIFICATE:
- return("Possibly Malicious SSL Certificate SHA1 Fingerprint");
+ return("Possibly Malicious SSL Cert. SHA1 Fingerprint");
case NDPI_DESKTOP_OR_FILE_SHARING_SESSION:
return("Desktop/File Sharing Session");
@@ -1781,6 +1781,28 @@ ndpi_risk_severity ndpi_risk2severity(ndpi_risk_enum risk) {
/* ******************************************************************** */
+const char* ndpi_severity2str(ndpi_risk_severity s) {
+ switch(s) {
+ case NDPI_RISK_LOW:
+ return("Low");
+ break;
+
+ case NDPI_RISK_MEDIUM:
+ return("Medium");
+ break;
+
+ case NDPI_RISK_HIGH:
+ return("High");
+ break;
+
+ case NDPI_RISK_SEVERE:
+ return("Severe");
+ break;
+ }
+}
+
+/* ******************************************************************** */
+
u_int16_t ndpi_risk2score(ndpi_risk risk) {
u_int16_t score = 0;
u_int32_t i;
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 0b900be64..6f30400f7 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -43,6 +43,8 @@ extern int is_version_with_var_int_transport_params(uint32_t version);
// #define DEBUG_TLS_BLOCKS 1
// #define DEBUG_CERTIFICATE_HASH
+// #define DEBUG_HEURISTIC
+
// #define DEBUG_JA3C 1
/* #define DEBUG_FINGERPRINT 1 */
@@ -1513,6 +1515,12 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_chrome_tls = 1;
else if(safari_ciphers == 12)
flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_safari_tls = 1;
+
+#ifdef DEBUG_HEURISTIC
+ printf("[is_chrome_tls: %u][is_safari_tls: %u]\n",
+ flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_chrome_tls,
+ flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_safari_tls);
+#endif
} else {
invalid_ja3 = 1;
#ifdef DEBUG_TLS
@@ -1725,11 +1733,12 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
}
for(i=0; i<tot_signature_algorithms_len; i+=2) {
- u_int16_t cipher_id = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+i]));
-
- // printf("=>> %04X\n", cipher_id);
+ u_int16_t signature_algo = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+i]));
- switch(cipher_id) {
+#ifdef DEBUG_HEURISTIC
+ printf("[TLS Signature Algorithm] 0x%04X\n", signature_algo);
+#endif
+ switch(signature_algo) {
case ECDSA_SECP521R1_SHA512:
flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_firefox_tls = 1;
break;
@@ -1757,6 +1766,13 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
if(chrome_signature_algorithms != 8)
flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_chrome_tls = 0;
+#ifdef DEBUG_HEURISTIC
+ printf("[is_firefox_tls: %u][is_chrome_tls: %u][is_safari_tls: %u]\n",
+ flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_firefox_tls,
+ flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_chrome_tls,
+ flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_safari_tls);
+#endif
+
ja3.client.signature_algorithms[i*2] = '\0';
#ifdef DEBUG_TLS