From ca15e3295e217578fd08d6677e1f1a346ec15481 Mon Sep 17 00:00:00 2001
From: Luca Deri <deri@ntop.org>
Date: Tue, 18 May 2021 19:34:17 +0200
Subject: Added risk/score dump (ndpiReader -h) Added ndpi_dump_risks_score()
 API score

---
 src/include/ndpi_api.h.in   |    8 +
 src/include/ndpi_typedefs.h |   10 +-
 src/lib/ndpi_main.c         | 5258 ++++++++++++++++++++++---------------------
 src/lib/ndpi_utils.c        |   24 +-
 src/lib/protocols/tls.c     |   24 +-
 5 files changed, 2705 insertions(+), 2619 deletions(-)

(limited to 'src')

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
@@ -680,6 +680,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
    *
@@ -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;
+
+  /* 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_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;
+
+  /* Try to load as IP address first */
+  rv = ndpi_load_ip_category(ndpi_struct, ip_or_name, category);
 
-    return(rv);
+  if(rv < 0) {
+    /* IP load failed, load as hostname */
+    rv = ndpi_load_hostname_category(ndpi_struct, ip_or_name, category);
   }
 
-  /* ********************************************************************************* */
+  return(rv);
+}
 
-  int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str) {
-    int i;
+/* ********************************************************************************* */
 
-    /* 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);
+int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str) {
+  int i;
 
-    /* Free */
-    ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
-			1 /* free patterns strings memory */);
+  /* 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);
 
-    /* Finalize */
-    ac_automata_finalize((AC_AUTOMATA_t *) 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 */);
 
-    /* Swap */
-    ndpi_str->custom_categories.hostnames.ac_automa = ndpi_str->custom_categories.hostnames_shadow.ac_automa;
+  /* Finalize */
+  ac_automata_finalize((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames_shadow.ac_automa);
 
-    /* Realloc */
-    ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_match_handler);
+  /* Swap */
+  ndpi_str->custom_categories.hostnames.ac_automa = 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);
+  /* Realloc */
+  ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_match_handler);
 
-    ndpi_str->custom_categories.ipAddresses = ndpi_str->custom_categories.ipAddresses_shadow;
-    ndpi_str->custom_categories.ipAddresses_shadow = ndpi_patricia_new(32 /* IPv4 */);
+  if(ndpi_str->custom_categories.ipAddresses != NULL)
+    ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->custom_categories.ipAddresses, free_ptree_data);
 
-    ndpi_str->custom_categories.categories_loaded = 1;
+  ndpi_str->custom_categories.ipAddresses = ndpi_str->custom_categories.ipAddresses_shadow;
+  ndpi_str->custom_categories.ipAddresses_shadow = ndpi_patricia_new(32 /* IPv4 */);
 
-    return(0);
-  }
+  ndpi_str->custom_categories.categories_loaded = 1;
 
-  /* ********************************************************************************* */
+  return(0);
+}
 
-  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(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);
+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(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);
       }
+    }
 
-      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);
-	}
-      }
+    if(node) {
+      ret->category = (ndpi_protocol_category_t) node->value.u.uv32.user_value;
 
-      if(node) {
-	ret->category = (ndpi_protocol_category_t) node->value.u.uv32.user_value;
-
-	return(1);
-      }
+      return(1);
     }
+  }
 
-    ret->category = ndpi_get_proto_category(ndpi_str, *ret);
+  ret->category = ndpi_get_proto_category(ndpi_str, *ret);
 
-    return(0);
-  }
+  return(0);
+}
 
-  /* ********************************************************************************* */
+/* ********************************************************************************* */
 
-  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;
+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(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(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);
+    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;
       }
+    }
 
-      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->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;
-	}
+      if(rc == 0) {
+	flow->category = ret->category = (ndpi_protocol_category_t) id;
+	return;
       }
     }
-
-    flow->category = ret->category = ndpi_get_proto_category(ndpi_str, *ret);
   }
 
-  /* ********************************************************************************* */
+  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_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 == NULL)
-	  ndpi_str->msteams_cache = ndpi_lru_cache_init(1024);
+	if(tdiff < 60 /* sec */) {
+	  // printf("====>> NDPI_PROTOCOL_SKYPE(_CALL) -> NDPI_PROTOCOL_MSTEAMS [%u]\n", tdiff);
+	  ret->app_protocol = NDPI_PROTOCOL_MSTEAMS;
 
-	if(ndpi_str->msteams_cache)
+	  /* 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 */
+    break;
+  } /* switch */
 
-    case NDPI_PROTOCOL_ANYDESK:
-      if(flow->packet.tcp) /* TCP only */
-	ndpi_set_risk(flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */
+  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;
+
+    if(ndpi_do_guess(ndpi_str, flow, &ret) == -1)
+      goto invalidate_ptr;
+  }
 
-    num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
+  num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
 
-    a = flow->packet.detected_protocol_stack[0];
-    if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_str->detection_bitmask, a) == 0)
-      a = NDPI_PROTOCOL_UNKNOWN;
+  a = flow->packet.detected_protocol_stack[0];
+  if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_str->detection_bitmask, a) == 0)
+    a = NDPI_PROTOCOL_UNKNOWN;
 
-    if(a != NDPI_PROTOCOL_UNKNOWN) {
-      int i;
+  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;
-	}
+    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;
+/* 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;
-  }
+  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;
+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;
-    }
+    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;
   }
+}
 
-  /* ****************************************************** */
+/* ****************************************************** */
 
-  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);
+int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_str, char *proto) {
+  int 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);
+  for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
+    if(strcasecmp(proto, ndpi_str->proto_defaults[i].protoName) == 0)
+      return(i);
 
-    return(NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
-  }
+  return(-1);
+}
 
-  /* ****************************************************** */
+/* ****************************************************** */
 
-  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;
+int ndpi_get_category_id(struct ndpi_detection_module_struct *ndpi_str, char *cat) {
+  int i;
 
-    return(ndpi_str->proto_defaults[proto_id].protoName);
+  for(i = 0; i < NDPI_PROTOCOL_NUM_CATEGORIES; i++) {
+    const char *name = ndpi_category_get_name(ndpi_str, i);
+
+    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;
+/* ****************************************************** */
 
-    return(ndpi_str->proto_defaults[proto_id].protoBreed);
-  }
+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));
+}
 
-  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(rc1 > 0)
-	ndpi_set_risk(flow, NDPI_RISKY_DOMAIN);
-    }
+  if(ndpi_str->risky_domain_automa.ac_automa != NULL) {
+    u_int16_t rc1 = ndpi_match_string(ndpi_str->risky_domain_automa.ac_automa, buf);
 
-    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;
+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 == 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));
+/* ******************************************************************** */
 
-    if(tree) {
-      tree->v4 = ndpi_patricia_new(32);
-      tree->v6 = ndpi_patricia_new(128);
+ndpi_ptree_t *ndpi_ptree_create(void) {
+  ndpi_ptree_t *tree = (ndpi_ptree_t *) ndpi_malloc(sizeof(ndpi_ptree_t));
 
-      if((!tree->v4) || (!tree->v6)) {
-	ndpi_ptree_destroy(tree);
-	return(NULL);
-      }
-    }
+  if(tree) {
+    tree->v4 = ndpi_patricia_new(32);
+    tree->v6 = ndpi_patricia_new(128);
 
-    return(tree);
+    if((!tree->v4) || (!tree->v6)) {
+      ndpi_ptree_destroy(tree);
+      return(NULL);
+    }
   }
 
-  /* ******************************************************************** */
+  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);
+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);
-    }
+    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!");
 
-	tmp[j] = '\0';
-	len = j;
+	return(1);
+      }
 
-	for(word = strtok_r(tmp, ".", &tok_tmp); ; word = strtok_r(NULL, ".", &tok_tmp)) {
-	  if(!word) break;
+      tmp[j] = '\0';
+      len = j;
 
-	  num_words++;
+      for(word = strtok_r(tmp, ".", &tok_tmp); ; word = strtok_r(NULL, ".", &tok_tmp)) {
+	if(!word) break;
 
-	  if(strlen(word) < 3) continue;
+	num_words++;
 
-	  if(ndpi_verbose_dga_detection)
-	    printf("-> word(%s) [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
+	if(strlen(word) < 3) continue;
 
-	  trigram_char_skip = 0;
+	if(ndpi_verbose_dga_detection)
+	  printf("-> word(%s) [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
+
+	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;
 
-	    if(ndpi_match_bigram(ndpi_str,
-				 &ndpi_str->impossible_bigrams_automa,
-				 &word[i])) {
-	      if(ndpi_verbose_dga_detection)
-		printf("IMPOSSIBLE %s\n", &word[i]);
+	  case '.':
+	    continue;
+	    break;
+	  }
+	  num_bigram_checks++;
 
-	      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_verbose_dga_detection)
+	    printf("-> Checking %c%c\n", word[i], word[i+1]);
+
+	  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
-- 
cgit v1.2.3