1 /*
2  * ndpi_main.c
3  *
4  * Copyright (C) 2011-21 - ntop.org
5  *
6  * This file is part of nDPI, an open source deep packet inspection
7  * library based on the OpenDPI and PACE technology by ipoque GmbH
8  *
9  * nDPI is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * nDPI is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23 
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 
28 #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_UNKNOWN
29 
30 #include "ndpi_config.h"
31 #include "ndpi_api.h"
32 #include "ahocorasick.h"
33 #include "libcache.h"
34 
35 #ifdef HAVE_LIBGCRYPT
36 #include <gcrypt.h>
37 #endif
38 
39 #include <time.h>
40 #ifndef WIN32
41 #include <unistd.h>
42 #endif
43 
44 #if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __DragonFly__
45 #include <sys/endian.h>
46 #endif
47 
48 #include "ndpi_content_match.c.inc"
49 #include "third_party/include/ndpi_patricia.h"
50 #include "third_party/include/ndpi_md5.h"
51 
52 /* stun.c */
53 extern u_int32_t get_stun_lru_key(struct ndpi_flow_struct *flow, u_int8_t rev);
54 
55 static int _ndpi_debug_callbacks = 0;
56 
57 /* #define DGA_DEBUG 1 */
58 /* #define MATCH_DEBUG 1 */
59 
60 u_int ndpi_verbose_dga_detection = 0;
61 
62 /* ****************************************** */
63 
64 static void *(*_ndpi_flow_malloc)(size_t size);
65 static void (*_ndpi_flow_free)(void *ptr);
66 
67 static void *(*_ndpi_malloc)(size_t size);
68 static void (*_ndpi_free)(void *ptr);
69 
70 /* ****************************************** */
71 
72 static ndpi_risk_info ndpi_known_risks[] = {
73   { NDPI_NO_RISK,                               NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE },
74   { NDPI_URL_POSSIBLE_XSS,                      NDPI_RISK_SEVERE, CLIENT_HIGH_RISK_PERCENTAGE },
75   { NDPI_URL_POSSIBLE_SQL_INJECTION,            NDPI_RISK_SEVERE, CLIENT_HIGH_RISK_PERCENTAGE },
76   { NDPI_URL_POSSIBLE_RCE_INJECTION,            NDPI_RISK_SEVERE, CLIENT_HIGH_RISK_PERCENTAGE },
77   { NDPI_BINARY_APPLICATION_TRANSFER,           NDPI_RISK_SEVERE, CLIENT_FAIR_RISK_PERCENTAGE },
78   { NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT,   NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE },
79   { NDPI_TLS_SELFSIGNED_CERTIFICATE,            NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
80   { NDPI_TLS_OBSOLETE_VERSION,                  NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
81   { NDPI_TLS_WEAK_CIPHER,                       NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
82   { NDPI_TLS_CERTIFICATE_EXPIRED,               NDPI_RISK_HIGH,   CLIENT_FAIR_RISK_PERCENTAGE },
83   { NDPI_TLS_CERTIFICATE_MISMATCH,              NDPI_RISK_HIGH,   CLIENT_FAIR_RISK_PERCENTAGE },
84   { NDPI_HTTP_SUSPICIOUS_USER_AGENT,            NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
85   { NDPI_HTTP_NUMERIC_IP_HOST,                  NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE },
86   { NDPI_HTTP_SUSPICIOUS_URL,                   NDPI_RISK_HIGH,   CLIENT_HIGH_RISK_PERCENTAGE },
87   { NDPI_HTTP_SUSPICIOUS_HEADER,                NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
88   { NDPI_TLS_NOT_CARRYING_HTTPS,                NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE },
89   { NDPI_SUSPICIOUS_DGA_DOMAIN,                 NDPI_RISK_HIGH,   CLIENT_HIGH_RISK_PERCENTAGE },
90   { NDPI_MALFORMED_PACKET,                      NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE },
91   { NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER, NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
92   { NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER, NDPI_RISK_MEDIUM, CLIENT_LOW_RISK_PERCENTAGE  },
93   { NDPI_SMB_INSECURE_VERSION,                  NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
94   { NDPI_TLS_SUSPICIOUS_ESNI_USAGE,             NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
95   { NDPI_UNSAFE_PROTOCOL,                       NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE },
96   { NDPI_DNS_SUSPICIOUS_TRAFFIC,                NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
97   { NDPI_TLS_MISSING_SNI,                       NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
98   { NDPI_HTTP_SUSPICIOUS_CONTENT,               NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
99   { NDPI_RISKY_ASN,                             NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE },
100   { NDPI_RISKY_DOMAIN,                          NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE },
101   { NDPI_MALICIOUS_JA3,                         NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
102   { NDPI_MALICIOUS_SHA1_CERTIFICATE,            NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE },
103   { NDPI_DESKTOP_OR_FILE_SHARING_SESSION,       NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE },
104   { NDPI_TLS_UNCOMMON_ALPN,                     NDPI_RISK_MEDIUM, CLIENT_HIGH_RISK_PERCENTAGE },
105   { NDPI_TLS_CERT_VALIDITY_TOO_LONG,            NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE },
106   { NDPI_TLS_EXTENSION_SUSPICIOUS,              NDPI_RISK_HIGH,   CLIENT_HIGH_RISK_PERCENTAGE },
107 
108   /* Leave this as last member */
109   { NDPI_MAX_RISK,                              NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE }
110 };
111 
112 /* ****************************************** */
113 
114 /* Forward */
115 static void addDefaultPort(struct ndpi_detection_module_struct *ndpi_str, ndpi_port_range *range,
116                            ndpi_proto_defaults_t *def, u_int8_t customUserProto, ndpi_default_ports_tree_node_t **root,
117                            const char *_func, int _line);
118 
119 static int removeDefaultPort(ndpi_port_range *range, ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root);
120 
121 /* ****************************************** */
122 
123 ndpi_custom_dga_predict_fctn ndpi_dga_function = NULL;
124 
125 /* ****************************************** */
126 
flow_is_proto(struct ndpi_flow_struct * flow,u_int16_t p)127 static inline uint8_t flow_is_proto(struct ndpi_flow_struct *flow, u_int16_t p) {
128   return((flow->detected_protocol_stack[0] == p) || (flow->detected_protocol_stack[1] == p));
129 }
130 
131 /* ****************************************** */
132 
ndpi_malloc(size_t size)133 void *ndpi_malloc(size_t size) {
134   return(_ndpi_malloc ? _ndpi_malloc(size) : malloc(size));
135 }
ndpi_flow_malloc(size_t size)136 void *ndpi_flow_malloc(size_t size) {
137   return(_ndpi_flow_malloc ? _ndpi_flow_malloc(size) : ndpi_malloc(size));
138 }
139 
140 /* ****************************************** */
141 
ndpi_calloc(unsigned long count,size_t size)142 void *ndpi_calloc(unsigned long count, size_t size) {
143   size_t len = count * size;
144   void *p = ndpi_malloc(len);
145 
146   if(p)
147     memset(p, 0, len);
148 
149   return(p);
150 }
151 
152 /* ****************************************** */
153 
ndpi_free(void * ptr)154 void ndpi_free(void *ptr) {
155   if(_ndpi_free) {
156     if(ptr)
157       _ndpi_free(ptr);
158   } else {
159     if(ptr)
160       free(ptr);
161   }
162 }
163 
164 /* ****************************************** */
165 
ndpi_flow_free(void * ptr)166 void ndpi_flow_free(void *ptr) {
167   if(_ndpi_flow_free)
168     _ndpi_flow_free(ptr);
169   else
170     ndpi_free_flow((struct ndpi_flow_struct *) ptr);
171 }
172 
173 /* ****************************************** */
174 
ndpi_realloc(void * ptr,size_t old_size,size_t new_size)175 void *ndpi_realloc(void *ptr, size_t old_size, size_t new_size) {
176   void *ret = ndpi_malloc(new_size);
177 
178   if(!ret)
179     return(ret);
180   else {
181     if(ptr != NULL) {
182       memcpy(ret, ptr, old_size);
183       ndpi_free(ptr);
184     }
185     return(ret);
186   }
187 }
188 /* ****************************************** */
189 
ndpi_strdup(const char * s)190 char *ndpi_strdup(const char *s) {
191   if(s == NULL ){
192     return NULL;
193   }
194 
195   int len = strlen(s);
196   char *m = ndpi_malloc(len + 1);
197 
198   if(m) {
199     memcpy(m, s, len);
200     m[len] = '\0';
201   }
202 
203   return(m);
204 }
205 
206 /* *********************************************************************************** */
207 
208 /* Opaque structure defined here */
209 struct ndpi_ptree
210 {
211   ndpi_patricia_tree_t *v4;
212   ndpi_patricia_tree_t *v6;
213 };
214 
215 /* *********************************************************************************** */
216 
ndpi_detection_get_sizeof_ndpi_flow_struct(void)217 u_int32_t ndpi_detection_get_sizeof_ndpi_flow_struct(void) {
218   return(sizeof(struct ndpi_flow_struct));
219 }
220 
221 /* *********************************************************************************** */
222 
ndpi_detection_get_sizeof_ndpi_id_struct(void)223 u_int32_t ndpi_detection_get_sizeof_ndpi_id_struct(void) {
224   return(sizeof(struct ndpi_id_struct));
225 }
226 
227 /* *********************************************************************************** */
228 
ndpi_detection_get_sizeof_ndpi_flow_tcp_struct(void)229 u_int32_t ndpi_detection_get_sizeof_ndpi_flow_tcp_struct(void) {
230   return(sizeof(struct ndpi_flow_tcp_struct));
231 }
232 
233 /* *********************************************************************************** */
234 
ndpi_detection_get_sizeof_ndpi_flow_udp_struct(void)235 u_int32_t ndpi_detection_get_sizeof_ndpi_flow_udp_struct(void) {
236   return(sizeof(struct ndpi_flow_udp_struct));
237 }
238 
239 /* *********************************************************************************** */
240 
ndpi_get_proto_by_id(struct ndpi_detection_module_struct * ndpi_str,u_int id)241 char *ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_str, u_int id) {
242   return((id >= ndpi_str->ndpi_num_supported_protocols) ? NULL : ndpi_str->proto_defaults[id].protoName);
243 }
244 
245 /* *********************************************************************************** */
246 
ndpi_get_proto_by_name(struct ndpi_detection_module_struct * ndpi_str,const char * name)247 u_int16_t ndpi_get_proto_by_name(struct ndpi_detection_module_struct *ndpi_str, const char *name) {
248   u_int16_t i, num = ndpi_get_num_supported_protocols(ndpi_str);
249 
250   for(i = 0; i < num; i++)
251     if(strcasecmp(ndpi_get_proto_by_id(ndpi_str, i), name) == 0)
252       return(i);
253 
254   return(NDPI_PROTOCOL_UNKNOWN);
255 }
256 
257 /* ************************************************************************************* */
258 
259 #ifdef CODE_UNUSED
ndpi_build_default_ports_range(ndpi_port_range * ports,u_int16_t portA_low,u_int16_t portA_high,u_int16_t portB_low,u_int16_t portB_high,u_int16_t portC_low,u_int16_t portC_high,u_int16_t portD_low,u_int16_t portD_high,u_int16_t portE_low,u_int16_t portE_high)260 ndpi_port_range *ndpi_build_default_ports_range(ndpi_port_range *ports, u_int16_t portA_low, u_int16_t portA_high,
261                                                 u_int16_t portB_low, u_int16_t portB_high, u_int16_t portC_low,
262                                                 u_int16_t portC_high, u_int16_t portD_low, u_int16_t portD_high,
263                                                 u_int16_t portE_low, u_int16_t portE_high) {
264   int i = 0;
265 
266   ports[i].port_low = portA_low, ports[i].port_high = portA_high;
267   i++;
268   ports[i].port_low = portB_low, ports[i].port_high = portB_high;
269   i++;
270   ports[i].port_low = portC_low, ports[i].port_high = portC_high;
271   i++;
272   ports[i].port_low = portD_low, ports[i].port_high = portD_high;
273   i++;
274   ports[i].port_low = portE_low, ports[i].port_high = portE_high;
275 
276   return(ports);
277 }
278 #endif
279 
280 /* *********************************************************************************** */
281 
ndpi_build_default_ports(ndpi_port_range * ports,u_int16_t portA,u_int16_t portB,u_int16_t portC,u_int16_t portD,u_int16_t portE)282 ndpi_port_range *ndpi_build_default_ports(ndpi_port_range *ports, u_int16_t portA, u_int16_t portB, u_int16_t portC,
283                                           u_int16_t portD, u_int16_t portE) {
284   int i = 0;
285 
286   ports[i].port_low = portA, ports[i].port_high = portA;
287   i++;
288   ports[i].port_low = portB, ports[i].port_high = portB;
289   i++;
290   ports[i].port_low = portC, ports[i].port_high = portC;
291   i++;
292   ports[i].port_low = portD, ports[i].port_high = portD;
293   i++;
294   ports[i].port_low = portE, ports[i].port_high = portE;
295 
296   return(ports);
297 }
298 
299 /* ********************************************************************************** */
300 
ndpi_set_proto_breed(struct ndpi_detection_module_struct * ndpi_str,u_int16_t protoId,ndpi_protocol_breed_t breed)301 void ndpi_set_proto_breed(struct ndpi_detection_module_struct *ndpi_str, u_int16_t protoId, ndpi_protocol_breed_t breed) {
302   if(!ndpi_is_valid_protoId(protoId))
303     return;
304   else
305     ndpi_str->proto_defaults[protoId].protoBreed = breed;
306 }
307 
308 /* ********************************************************************************** */
309 
ndpi_set_proto_category(struct ndpi_detection_module_struct * ndpi_str,u_int16_t protoId,ndpi_protocol_category_t protoCategory)310 void ndpi_set_proto_category(struct ndpi_detection_module_struct *ndpi_str, u_int16_t protoId,
311                              ndpi_protocol_category_t protoCategory) {
312   if(!ndpi_is_valid_protoId(protoId))
313     return;
314   else
315     ndpi_str->proto_defaults[protoId].protoCategory = protoCategory;
316 }
317 
318 /* ********************************************************************************** */
319 
320 /*
321   There are some (master) protocols that are informative, meaning that it shows
322   what is the subprotocol about, but also that the subprotocol isn't a real protocol.
323 
324   Example:
325   - DNS is informative as if we see a DNS request for www.facebook.com, the
326   returned protocol is DNS.Facebook, but Facebook isn't a real subprotocol but
327   rather it indicates a query for Facebook and not Facebook traffic.
328   - HTTP/SSL are NOT informative as SSL.Facebook (likely) means that this is
329   SSL (HTTPS) traffic containg Facebook traffic.
330 */
ndpi_is_subprotocol_informative(struct ndpi_detection_module_struct * ndpi_str,u_int16_t protoId)331 u_int8_t ndpi_is_subprotocol_informative(struct ndpi_detection_module_struct *ndpi_str, u_int16_t protoId) {
332   if(!ndpi_is_valid_protoId(protoId))
333     return(0);
334 
335   switch(protoId) {
336     /* All dissectors that have calls to ndpi_match_host_subprotocol() */
337   case NDPI_PROTOCOL_DNS:
338     return(1);
339     break;
340 
341   default:
342     return(0);
343   }
344 }
345 /* ********************************************************************************** */
346 
ndpi_exclude_protocol(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,u_int16_t protocol_id,const char * _file,const char * _func,int _line)347 void ndpi_exclude_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
348                            u_int16_t protocol_id, const char *_file, const char *_func, int _line) {
349   if(ndpi_is_valid_protoId(protocol_id)) {
350 #ifdef NDPI_ENABLE_DEBUG_MESSAGES
351     if(ndpi_str && ndpi_str->ndpi_log_level >= NDPI_LOG_DEBUG && ndpi_str->ndpi_debug_printf != NULL) {
352       (*(ndpi_str->ndpi_debug_printf))(protocol_id, ndpi_str, NDPI_LOG_DEBUG, _file, _func, _line, "exclude %s\n",
353 				       ndpi_get_proto_name(ndpi_str, protocol_id));
354     }
355 #endif
356     NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, protocol_id);
357   }
358 }
359 
360 /* ********************************************************************************** */
361 
ndpi_set_proto_subprotocols(struct ndpi_detection_module_struct * ndpi_str,int protoId,...)362 void ndpi_set_proto_subprotocols(struct ndpi_detection_module_struct *ndpi_str, int protoId, ...)
363 {
364   va_list ap;
365   int current_arg = protoId;
366 
367   va_start(ap, protoId);
368   while (current_arg != NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS)
369     {
370       ndpi_str->proto_defaults[protoId].subprotocol_count++;
371       current_arg = va_arg(ap, int);
372     }
373   va_end(ap);
374 
375   ndpi_str->proto_defaults[protoId].subprotocols = NULL;
376 
377   /* The last protocol is not a subprotocol. */
378   ndpi_str->proto_defaults[protoId].subprotocol_count--;
379   /* No subprotocol was set before NDPI_NO_MORE_SUBPROTOCOLS. */
380   if (ndpi_str->proto_defaults[protoId].subprotocol_count == 0)
381     {
382       return;
383     }
384 
385   ndpi_str->proto_defaults[protoId].subprotocols =
386     ndpi_malloc(sizeof(protoId) * ndpi_str->proto_defaults[protoId].subprotocol_count);
387 
388   size_t i = 0;
389   va_start(ap, protoId);
390   current_arg = va_arg(ap, int);
391   while (current_arg != NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS)
392     {
393       ndpi_str->proto_defaults[protoId].subprotocols[i++] = current_arg;
394       current_arg = va_arg(ap, int);
395     }
396   va_end(ap);
397 }
398 
399 /* ********************************************************************************** */
400 
ndpi_set_proto_defaults(struct ndpi_detection_module_struct * ndpi_str,u_int8_t is_cleartext,ndpi_protocol_breed_t breed,u_int16_t protoId,char * protoName,ndpi_protocol_category_t protoCategory,ndpi_port_range * tcpDefPorts,ndpi_port_range * udpDefPorts)401 void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_str,
402 			     u_int8_t is_cleartext, ndpi_protocol_breed_t breed,
403                              u_int16_t protoId, char *protoName, ndpi_protocol_category_t protoCategory,
404                              ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts) {
405   char *name;
406   int j;
407 
408   if(!ndpi_is_valid_protoId(protoId)) {
409 #ifdef DEBUG
410     NDPI_LOG_ERR(ndpi_str, "[NDPI] %s/protoId=%d: INTERNAL ERROR\n", protoName, protoId);
411 #endif
412     return;
413   }
414 
415   if(ndpi_str->proto_defaults[protoId].protoName != NULL) {
416 #ifdef DEBUG
417     NDPI_LOG_ERR(ndpi_str, "[NDPI] %s/protoId=%d: already initialized. Ignoring it\n", protoName, protoId);
418 #endif
419     return;
420   }
421 
422   name = ndpi_strdup(protoName);
423 
424   if(ndpi_str->proto_defaults[protoId].protoName)
425     ndpi_free(ndpi_str->proto_defaults[protoId].protoName);
426 
427   ndpi_str->proto_defaults[protoId].isClearTextProto = is_cleartext;
428   ndpi_str->proto_defaults[protoId].protoName = name;
429   ndpi_str->proto_defaults[protoId].protoCategory = protoCategory;
430   ndpi_str->proto_defaults[protoId].protoId = protoId;
431   ndpi_str->proto_defaults[protoId].protoBreed = breed;
432   ndpi_str->proto_defaults[protoId].subprotocols = NULL;
433   ndpi_str->proto_defaults[protoId].subprotocol_count = 0;
434 
435   for(j = 0; j < MAX_DEFAULT_PORTS; j++) {
436     if(udpDefPorts[j].port_low != 0)
437       addDefaultPort(ndpi_str, &udpDefPorts[j], &ndpi_str->proto_defaults[protoId], 0, &ndpi_str->udpRoot,
438 		     __FUNCTION__, __LINE__);
439 
440     if(tcpDefPorts[j].port_low != 0)
441       addDefaultPort(ndpi_str, &tcpDefPorts[j], &ndpi_str->proto_defaults[protoId], 0, &ndpi_str->tcpRoot,
442 		     __FUNCTION__, __LINE__);
443 
444     /* No port range, just the lower port */
445     ndpi_str->proto_defaults[protoId].tcp_default_ports[j] = tcpDefPorts[j].port_low;
446     ndpi_str->proto_defaults[protoId].udp_default_ports[j] = udpDefPorts[j].port_low;
447   }
448 }
449 
450 /* ******************************************************************** */
451 
ndpi_default_ports_tree_node_t_cmp(const void * a,const void * b)452 static int ndpi_default_ports_tree_node_t_cmp(const void *a, const void *b) {
453   ndpi_default_ports_tree_node_t *fa = (ndpi_default_ports_tree_node_t *) a;
454   ndpi_default_ports_tree_node_t *fb = (ndpi_default_ports_tree_node_t *) b;
455 
456   //printf("[NDPI] %s(%d, %d)\n", __FUNCTION__, fa->default_port, fb->default_port);
457 
458   return((fa->default_port == fb->default_port) ? 0 : ((fa->default_port < fb->default_port) ? -1 : 1));
459 }
460 
461 /* ******************************************************************** */
462 
ndpi_default_ports_tree_node_t_walker(const void * node,const ndpi_VISIT which,const int depth)463 void ndpi_default_ports_tree_node_t_walker(const void *node, const ndpi_VISIT which, const int depth) {
464   ndpi_default_ports_tree_node_t *f = *(ndpi_default_ports_tree_node_t **) node;
465 
466   printf("<%d>Walk on node %s (%u)\n", depth,
467 	 which == ndpi_preorder ?
468 	 "ndpi_preorder" :
469 	 which == ndpi_postorder ?
470 	 "ndpi_postorder" :
471 	 which == ndpi_endorder ? "ndpi_endorder" : which == ndpi_leaf ? "ndpi_leaf" : "unknown",
472 	 f->default_port);
473 }
474 
475 /* ******************************************************************** */
476 
addDefaultPort(struct ndpi_detection_module_struct * ndpi_str,ndpi_port_range * range,ndpi_proto_defaults_t * def,u_int8_t customUserProto,ndpi_default_ports_tree_node_t ** root,const char * _func,int _line)477 static void addDefaultPort(struct ndpi_detection_module_struct *ndpi_str, ndpi_port_range *range,
478                            ndpi_proto_defaults_t *def, u_int8_t customUserProto, ndpi_default_ports_tree_node_t **root,
479                            const char *_func, int _line) {
480   u_int16_t port;
481 
482   for(port = range->port_low; port <= range->port_high; port++) {
483     ndpi_default_ports_tree_node_t *node =
484       (ndpi_default_ports_tree_node_t *) ndpi_malloc(sizeof(ndpi_default_ports_tree_node_t));
485     ndpi_default_ports_tree_node_t *ret;
486 
487     if(!node) {
488       NDPI_LOG_ERR(ndpi_str, "%s:%d not enough memory\n", _func, _line);
489       break;
490     }
491 
492     node->proto = def, node->default_port = port, node->customUserProto = customUserProto;
493     ret = (ndpi_default_ports_tree_node_t *) ndpi_tsearch(node, (void *) root, ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */
494 
495     if(ret != node) {
496       NDPI_LOG_DBG(ndpi_str, "[NDPI] %s:%d found duplicate for port %u: overwriting it with new value\n", _func,
497 		   _line, port);
498 
499       ret->proto = def;
500       ndpi_free(node);
501     }
502   }
503 }
504 
505 /* ****************************************************** */
506 
507 /*
508   NOTE
509 
510   This function must be called with a semaphore set, this in order to avoid
511   changing the datastructures while using them
512 */
removeDefaultPort(ndpi_port_range * range,ndpi_proto_defaults_t * def,ndpi_default_ports_tree_node_t ** root)513 static int removeDefaultPort(ndpi_port_range *range, ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root) {
514   ndpi_default_ports_tree_node_t node;
515   u_int16_t port;
516 
517   for(port = range->port_low; port <= range->port_high; port++) {
518     ndpi_default_ports_tree_node_t *ret;
519 
520     node.proto = def, node.default_port = port;
521     ret = (ndpi_default_ports_tree_node_t *) ndpi_tdelete(
522 							  &node, (void *) root, ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */
523 
524     if(ret != NULL) {
525       ndpi_free((ndpi_default_ports_tree_node_t *) ret);
526       return(0);
527     }
528   }
529 
530   return(-1);
531 }
532 
533 /* ****************************************************** */
534 
535 /*
536   This is a function used to see if we need to
537   add a trailer $ in case the string is complete
538   or is a string that can be matched in the
539   middle of a domain name
540 
541   Example:
542   microsoft.com    ->     microsoft.com$
543   apple.           ->     apple.
544 */
ndpi_is_middle_string_char(char c)545 static u_int8_t ndpi_is_middle_string_char(char c) {
546   switch(c) {
547   case '.':
548   case '-':
549     return(1);
550     break;
551 
552   default:
553     return(0);
554   }
555 }
556 
557 /*******************************************************/
558 
559 static const u_int8_t ndpi_domain_level_automat[4][4]= {
560   /* symbol,'.','-',inc */
561   { 2,1,2,0 }, // start state
562   { 2,0,0,0 }, // first char is '.'; disable .. or .-
563   { 2,3,2,0 }, // part of domain name
564   { 2,0,0,1 }  // next level domain name; disable .. or .-
565 };
566 
567 /*
568  * domain level
569  *  a. = 1
570  * .a. = 1
571  * a.b = 2
572  */
573 
ndpi_domain_level(const char * name)574 static u_int8_t ndpi_domain_level(const char *name) {
575   u_int8_t level = 1, state = 0;
576   char c;
577   while((c = *name++) != '\0') {
578     c = c == '-' ? 2 : (c == '.' ? 1:0);
579     level += ndpi_domain_level_automat[state][3];
580     state  = ndpi_domain_level_automat[state][(uint8_t)c];
581     if(!state) break;
582   }
583   return state >= 2 ? level:0;
584 }
585 
586 /* ****************************************************** */
587 
ndpi_string_to_automa(struct ndpi_detection_module_struct * ndpi_str,AC_AUTOMATA_t * ac_automa,const char * value,u_int16_t protocol_id,ndpi_protocol_category_t category,ndpi_protocol_breed_t breed,uint8_t level,u_int8_t add_ends_with)588 static int ndpi_string_to_automa(struct ndpi_detection_module_struct *ndpi_str,
589 				 AC_AUTOMATA_t *ac_automa, const char *value,
590                                  u_int16_t protocol_id, ndpi_protocol_category_t category,
591 				 ndpi_protocol_breed_t breed, uint8_t level,
592                                  u_int8_t add_ends_with) {
593   AC_PATTERN_t ac_pattern;
594   AC_ERROR_t rc;
595   u_int len;
596   char *value_dup = NULL;
597 
598   if(!ndpi_is_valid_protoId(protocol_id)) {
599     NDPI_LOG_ERR(ndpi_str, "[NDPI] protoId=%d: INTERNAL ERROR\n", protocol_id);
600     return(-1);
601   }
602 
603   if((ac_automa == NULL) || (value == NULL) || !*value)
604     return(-2);
605 
606   value_dup = ndpi_strdup(value);
607   if(!value_dup)
608     return(-1);
609 
610   memset(&ac_pattern, 0, sizeof(ac_pattern));
611 
612   len = strlen(value);
613 
614   ac_pattern.astring      = value_dup;
615   ac_pattern.length       = len;
616   ac_pattern.rep.number   = protocol_id;
617   ac_pattern.rep.category = (u_int16_t) category;
618   ac_pattern.rep.breed    = (u_int16_t) breed;
619   ac_pattern.rep.level    = level ? level : ndpi_domain_level(value);
620   ac_pattern.rep.at_end   = add_ends_with && !ndpi_is_middle_string_char(value[len-1]); /* len != 0 */
621   ac_pattern.rep.dot      = memchr(value,'.',len) != NULL;
622 
623 #ifdef MATCH_DEBUG
624   printf("Adding to %s %lx [%s%s][protocol_id: %u][category: %u][breed: %u][level: %u]\n",
625 	 ac_automa->name,(unsigned long int)ac_automa,
626 	 ac_pattern.astring,ac_pattern.rep.at_end? "$":"", protocol_id, category, breed,ac_pattern.rep.level);
627 #endif
628 
629   rc = ac_automata_add(ac_automa, &ac_pattern);
630 
631   if(rc != ACERR_SUCCESS) {
632     ndpi_free(value_dup);
633 
634     if(rc != ACERR_DUPLICATE_PATTERN)
635       return (-2);
636   }
637 
638   return(0);
639 }
640 
641 /* ****************************************************** */
642 
ndpi_add_host_url_subprotocol(struct ndpi_detection_module_struct * ndpi_str,char * value,int protocol_id,ndpi_protocol_category_t category,ndpi_protocol_breed_t breed,uint8_t level)643 static int ndpi_add_host_url_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
644 					 char *value, int protocol_id,
645                                          ndpi_protocol_category_t category,
646 					 ndpi_protocol_breed_t breed, uint8_t level) {
647 #ifndef DEBUG
648   NDPI_LOG_DBG2(ndpi_str, "[NDPI] Adding [%s][%d]\n", value, protocol_id);
649 #endif
650 
651   return ndpi_string_to_automa(ndpi_str, (AC_AUTOMATA_t *)ndpi_str->host_automa.ac_automa,
652 			       value, protocol_id, category, breed, level, 1);
653 
654 }
655 
656 /* ****************************************************** */
657 
658 /*
659   NOTE
660 
661   This function must be called with a semaphore set, this in order to avoid
662   changing the datastructures while using them
663 */
ndpi_remove_host_url_subprotocol(struct ndpi_detection_module_struct * ndpi_str,char * value,int protocol_id)664 static int ndpi_remove_host_url_subprotocol(struct ndpi_detection_module_struct *ndpi_str, char *value, int protocol_id) {
665   NDPI_LOG_ERR(ndpi_str, "[NDPI] Missing implementation for proto %s/%d\n", value, protocol_id);
666   return(-1);
667 }
668 
669 /* ******************************************************************** */
670 
ndpi_init_protocol_match(struct ndpi_detection_module_struct * ndpi_str,ndpi_protocol_match * match)671 void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_str,
672 			      ndpi_protocol_match *match) {
673   ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS];
674 
675   if(ndpi_str->proto_defaults[match->protocol_id].protoName == NULL) {
676     ndpi_str->proto_defaults[match->protocol_id].protoName = ndpi_strdup(match->proto_name);
677 
678     ndpi_str->proto_defaults[match->protocol_id].protoId = match->protocol_id;
679     ndpi_str->proto_defaults[match->protocol_id].protoCategory = match->protocol_category;
680     ndpi_str->proto_defaults[match->protocol_id].protoBreed = match->protocol_breed;
681 
682     ndpi_set_proto_defaults(ndpi_str,
683 			    ndpi_str->proto_defaults[match->protocol_id].isClearTextProto,
684 			    ndpi_str->proto_defaults[match->protocol_id].protoBreed,
685 			    ndpi_str->proto_defaults[match->protocol_id].protoId,
686 			    ndpi_str->proto_defaults[match->protocol_id].protoName,
687 			    ndpi_str->proto_defaults[match->protocol_id].protoCategory,
688 			    ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
689 			    ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
690   }
691 
692   ndpi_add_host_url_subprotocol(ndpi_str, match->string_to_match,
693 				match->protocol_id, match->protocol_category,
694 				match->protocol_breed, match->level);
695 }
696 
697 /* ******************************************************************** */
698 
699 /* Self check function to be called only for testing purposes */
ndpi_self_check_host_match()700 void ndpi_self_check_host_match() {
701   u_int32_t i, j;
702 
703   for(i = 0; host_match[i].string_to_match != NULL; i++) {
704     for(j = 0; host_match[j].string_to_match != NULL; j++) {
705       if((i != j) && (strcmp(host_match[i].string_to_match, host_match[j].string_to_match) == 0)) {
706 	printf("[INTERNAL ERROR]: Duplicate string detected '%s' [id: %u, id %u]\n",
707 	       host_match[i].string_to_match, i, j);
708 	printf("\nPlease fix host_match[] in ndpi_content_match.c.inc\n");
709 	exit(0);
710       }
711     }
712   }
713 }
714 
715 /* ******************************************************************** */
716 
717 #define XGRAMS_C 26
718 static int ndpi_xgrams_inited = 0;
719 static unsigned int bigrams_bitmap[(XGRAMS_C*XGRAMS_C+31)/32];
720 static unsigned int imposible_bigrams_bitmap[(XGRAMS_C*XGRAMS_C+31)/32];
721 static unsigned int trigrams_bitmap[(XGRAMS_C*XGRAMS_C*XGRAMS_C+31)/32];
722 
723 
ndpi_xgrams_init(unsigned int * dst,size_t dn,const char ** src,size_t sn,int l)724 static void ndpi_xgrams_init(unsigned int *dst,size_t dn, const char **src,size_t sn,int l) {
725   unsigned int i,j,c;
726   for(i=0;i < sn && src[i]; i++) {
727     for(j=0,c=0; j < l; j++) {
728       unsigned char a = (unsigned char)src[i][j];
729       if(a < 'a' || a > 'z') { printf("%u: c%u %c\n",i,j,a); abort(); }
730       c *= XGRAMS_C;
731       c += a - 'a';
732     }
733     if(src[i][l]) { printf("%u: c[%d] != 0\n",i,l); abort(); }
734     if((c >> 3) >= dn) abort();
735     dst[c >> 5] |= 1u << (c & 0x1f);
736   }
737 }
738 
init_string_based_protocols(struct ndpi_detection_module_struct * ndpi_str)739 static void init_string_based_protocols(struct ndpi_detection_module_struct *ndpi_str) {
740   int i;
741 
742   for(i = 0; host_match[i].string_to_match != NULL; i++)
743     ndpi_init_protocol_match(ndpi_str, &host_match[i]);
744 
745   /* ************************ */
746 
747   for(i = 0; tls_certificate_match[i].string_to_match != NULL; i++) {
748 
749 #if 0
750     printf("%s() %s / %u\n", __FUNCTION__,
751 	   tls_certificate_match[i].string_to_match,
752 	   tls_certificate_match[i].protocol_id);
753 #endif
754 
755     /* Note: string_to_match is not malloc'ed here as ac_automata_release is
756      * called with free_pattern = 0 */
757     ndpi_add_string_value_to_automa(ndpi_str->tls_cert_subject_automa.ac_automa,
758 				    tls_certificate_match[i].string_to_match,
759                                     tls_certificate_match[i].protocol_id);
760   }
761 
762   /* ************************ */
763 
764   ndpi_enable_loaded_categories(ndpi_str);
765 
766 #ifdef MATCH_DEBUG
767   // ac_automata_display(ndpi_str->host_automa.ac_automa, 'n');
768 #endif
769   if(!ndpi_xgrams_inited) {
770     ndpi_xgrams_inited = 1;
771     ndpi_xgrams_init(bigrams_bitmap,sizeof(bigrams_bitmap),
772 		     ndpi_en_bigrams,sizeof(ndpi_en_bigrams)/sizeof(ndpi_en_bigrams[0]), 2);
773 
774     ndpi_xgrams_init(imposible_bigrams_bitmap,sizeof(imposible_bigrams_bitmap),
775 		     ndpi_en_impossible_bigrams,sizeof(ndpi_en_impossible_bigrams)/sizeof(ndpi_en_impossible_bigrams[0]), 2);
776     ndpi_xgrams_init(trigrams_bitmap,sizeof(trigrams_bitmap),
777 		     ndpi_en_trigrams,sizeof(ndpi_en_trigrams)/sizeof(ndpi_en_trigrams[0]), 3);
778   }
779 }
780 
781 /* ******************************************************************** */
782 
ndpi_set_detection_preferences(struct ndpi_detection_module_struct * ndpi_str,ndpi_detection_preference pref,int value)783 int ndpi_set_detection_preferences(struct ndpi_detection_module_struct *ndpi_str, ndpi_detection_preference pref,
784                                    int value) {
785   switch(pref) {
786   case ndpi_pref_direction_detect_disable:
787     ndpi_str->direction_detect_disable = (u_int8_t) value;
788     break;
789 
790   case ndpi_pref_enable_tls_block_dissection:
791     /*
792       If this option is enabled only the TLS Application data blocks past the
793       certificate negotiation are considered
794     */
795     ndpi_str->num_tls_blocks_to_follow = NDPI_MAX_NUM_TLS_APPL_BLOCKS;
796     ndpi_str->skip_tls_blocks_until_change_cipher = 1;
797     break;
798 
799   default:
800     return(-1);
801   }
802 
803   return(0);
804 }
805 
806 /* ******************************************************************** */
807 
ndpi_validate_protocol_initialization(struct ndpi_detection_module_struct * ndpi_str)808 static void ndpi_validate_protocol_initialization(struct ndpi_detection_module_struct *ndpi_str) {
809   u_int i, val;
810 
811   for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++) {
812     if(ndpi_str->proto_defaults[i].protoName == NULL) {
813       NDPI_LOG_ERR(ndpi_str,
814 		   "[NDPI] INTERNAL ERROR missing protoName initialization for [protoId=%d]: recovering\n", i);
815     } else {
816       if((i != NDPI_PROTOCOL_UNKNOWN) &&
817 	 (ndpi_str->proto_defaults[i].protoCategory == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)) {
818 	NDPI_LOG_ERR(ndpi_str,
819 		     "[NDPI] INTERNAL ERROR missing category [protoId=%d/%s] initialization: recovering\n", i,
820 		     ndpi_str->proto_defaults[i].protoName ? ndpi_str->proto_defaults[i].protoName : "???");
821       }
822     }
823   }
824 
825   /* Sanity check for risks initialization */
826   val = (sizeof(ndpi_known_risks) / sizeof(ndpi_risk_info)) - 1;
827   if(val != NDPI_MAX_RISK) {
828     NDPI_LOG_ERR(ndpi_str,  "[NDPI] INTERNAL ERROR Invalid ndpi_known_risks[] initialization [%u != %u]\n", val, NDPI_MAX_RISK);
829     exit(0);
830   }
831 }
832 
833 /* ******************************************************************** */
834 
835 /* This function is used to map protocol name and default ports and it MUST
836    be updated whenever a new protocol is added to NDPI.
837 
838    Do NOT add web services (NDPI_SERVICE_xxx) here.
839 */
ndpi_init_protocol_defaults(struct ndpi_detection_module_struct * ndpi_str)840 static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndpi_str) {
841   ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS];
842 
843   /* Reset all settings */
844   memset(ndpi_str->proto_defaults, 0, sizeof(ndpi_str->proto_defaults));
845 
846   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNRATED, NDPI_PROTOCOL_UNKNOWN,
847 			  "Unknown", NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
848 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
849 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
850   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_FTP_CONTROL,
851 			  "FTP_CONTROL", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
852 			  ndpi_build_default_ports(ports_a, 21, 0, 0, 0, 0) /* TCP */,
853 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
854   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_FTP_DATA,
855 			  "FTP_DATA", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
856 			  ndpi_build_default_ports(ports_a, 20, 0, 0, 0, 0) /* TCP */,
857 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
858   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_POP,
859 			  "POP3", NDPI_PROTOCOL_CATEGORY_MAIL,
860 			  ndpi_build_default_ports(ports_a, 110, 0, 0, 0, 0) /* TCP */,
861 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
862   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_POPS,
863 			  "POPS", NDPI_PROTOCOL_CATEGORY_MAIL,
864 			  ndpi_build_default_ports(ports_a, 995, 0, 0, 0, 0) /* TCP */,
865 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
866   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MAIL_SMTP,
867 			  "SMTP", NDPI_PROTOCOL_CATEGORY_MAIL,
868 			  ndpi_build_default_ports(ports_a, 25, 0, 0, 0, 0) /* TCP */,
869 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
870   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_SMTPS,
871 			  "SMTPS", NDPI_PROTOCOL_CATEGORY_MAIL,
872 			  ndpi_build_default_ports(ports_a, 465, 587, 0, 0, 0) /* TCP */,
873 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
874   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MAIL_IMAP,
875 			  "IMAP", NDPI_PROTOCOL_CATEGORY_MAIL,
876 			  ndpi_build_default_ports(ports_a, 143, 0, 0, 0, 0) /* TCP */,
877 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
878   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MAIL_IMAPS,
879 			  "IMAPS", NDPI_PROTOCOL_CATEGORY_MAIL,
880 			  ndpi_build_default_ports(ports_a, 993, 0, 0, 0, 0) /* TCP */,
881 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
882   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DNS,
883 			  "DNS", NDPI_PROTOCOL_CATEGORY_NETWORK,
884 			  ndpi_build_default_ports(ports_a, 53, 0, 0, 0, 0) /* TCP */,
885 			  ndpi_build_default_ports(ports_b, 53, 0, 0, 0, 0) /* UDP */);
886   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_DNS,
887 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
888 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_DNS can have (content-matched) subprotocols */
889   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IPP,
890 			  "IPP", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
891 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
892 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
893   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IMO,
894 			  "IMO", NDPI_PROTOCOL_CATEGORY_VOIP,
895 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
896 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
897   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP,
898 			  "HTTP", NDPI_PROTOCOL_CATEGORY_WEB,
899 			  ndpi_build_default_ports(ports_a, 80, 0 /* ntop */, 0, 0, 0) /* TCP */,
900 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
901   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP,
902 			      NDPI_PROTOCOL_AIMINI, NDPI_PROTOCOL_CROSSFIRE,
903 			      NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK, NDPI_PROTOCOL_GNUTELLA,
904 			      NDPI_PROTOCOL_MAPLESTORY, NDPI_PROTOCOL_ZATTOO, NDPI_PROTOCOL_WORLDOFWARCRAFT,
905 			      NDPI_PROTOCOL_THUNDER, NDPI_PROTOCOL_IRC,
906 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
907 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP can have (content-matched) subprotocols */
908   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MDNS,
909 			  "MDNS", NDPI_PROTOCOL_CATEGORY_NETWORK,
910 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
911 			  ndpi_build_default_ports(ports_b, 5353, 5354, 0, 0, 0) /* UDP */);
912   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_MDNS,
913 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
914 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_MDNS can have (content-matched) subprotocols */
915   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NTP,
916 			  "NTP", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
917 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
918 			  ndpi_build_default_ports(ports_b, 123, 0, 0, 0, 0) /* UDP */);
919   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NETBIOS,
920 			  "NetBIOS", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
921 			  ndpi_build_default_ports(ports_a, 139, 0, 0, 0, 0) /* TCP */,
922 			  ndpi_build_default_ports(ports_b, 137, 138, 139, 0, 0) /* UDP */);
923   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NFS,
924 			  "NFS", NDPI_PROTOCOL_CATEGORY_DATA_TRANSFER,
925 			  ndpi_build_default_ports(ports_a, 2049, 0, 0, 0, 0) /* TCP */,
926 			  ndpi_build_default_ports(ports_b, 2049, 0, 0, 0, 0) /* UDP */);
927   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSDP,
928 			  "SSDP", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
929 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
930 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
931   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BGP,
932 			  "BGP", NDPI_PROTOCOL_CATEGORY_NETWORK,
933 			  ndpi_build_default_ports(ports_a, 179, 2605, 0, 0, 0) /* TCP */,
934 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
935   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SNMP,
936 			  "SNMP", NDPI_PROTOCOL_CATEGORY_NETWORK,
937 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
938 			  ndpi_build_default_ports(ports_b, 161, 162, 0, 0, 0) /* UDP */);
939   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_XDMCP,
940 			  "XDMCP", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
941 			  ndpi_build_default_ports(ports_a, 177, 0, 0, 0, 0) /* TCP */,
942 			  ndpi_build_default_ports(ports_b, 177, 0, 0, 0, 0) /* UDP */);
943   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_DANGEROUS, NDPI_PROTOCOL_SMBV1,
944 			  "SMBv1", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
945 			  ndpi_build_default_ports(ports_a, 445, 0, 0, 0, 0) /* TCP */,
946 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
947   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SYSLOG,
948 			  "Syslog", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
949 			  ndpi_build_default_ports(ports_a, 514, 0, 0, 0, 0) /* TCP */,
950 			  ndpi_build_default_ports(ports_b, 514, 0, 0, 0, 0) /* UDP */);
951   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DHCP,
952 			  "DHCP", NDPI_PROTOCOL_CATEGORY_NETWORK,
953 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
954 			  ndpi_build_default_ports(ports_b, 67, 68, 0, 0, 0) /* UDP */);
955   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_POSTGRES,
956 			  "PostgreSQL", NDPI_PROTOCOL_CATEGORY_DATABASE,
957 			  ndpi_build_default_ports(ports_a, 5432, 0, 0, 0, 0) /* TCP */,
958 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
959   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MYSQL,
960 			  "MySQL", NDPI_PROTOCOL_CATEGORY_DATABASE,
961 			  ndpi_build_default_ports(ports_a, 3306, 0, 0, 0, 0) /* TCP */,
962 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
963   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DIRECT_DOWNLOAD_LINK,
964 			  "Direct_Download_Link", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
965 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
966 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
967   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_APPLEJUICE,
968 			  "AppleJuice", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
969 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
970 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
971   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_DIRECTCONNECT,
972 			  "DirectConnect", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
973 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
974 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
975   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NATS,
976 			  "Nats", NDPI_PROTOCOL_CATEGORY_RPC,
977 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
978 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
979   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_AMONG_US,
980 			  "AmongUs", NDPI_PROTOCOL_CATEGORY_GAME,
981 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
982 			  ndpi_build_default_ports(ports_b, 22023, 0, 0, 0, 0) /* UDP */);
983   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_NTOP,
984 			  "ntop", NDPI_PROTOCOL_CATEGORY_NETWORK,
985 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
986 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
987   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VMWARE,
988 			  "VMware", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
989 			  ndpi_build_default_ports(ports_a, 903, 0, 0, 0, 0) /* TCP */,
990 			  ndpi_build_default_ports(ports_b, 902, 903, 0, 0, 0) /* UDP */);
991   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_KONTIKI,
992 			  "Kontiki", NDPI_PROTOCOL_CATEGORY_MEDIA,
993 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
994 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
995   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_OPENFT,
996 			  "OpenFT", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
997 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
998 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
999   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_FASTTRACK,
1000 			  "FastTrack", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1001 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1002 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1003   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_GNUTELLA,
1004 			  "Gnutella", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1005 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1006 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1007   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_EDONKEY,
1008 			  "eDonkey", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1009 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1010 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1011   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BITTORRENT,
1012 			  "BitTorrent", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1013 			  ndpi_build_default_ports(ports_a, 51413, 53646, 0, 0, 0) /* TCP */,
1014 			  ndpi_build_default_ports(ports_b, 6771, 51413, 0, 0, 0) /* UDP */);
1015   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYPE_TEAMS,
1016 			  "Skype_Teams", NDPI_PROTOCOL_CATEGORY_VOIP,
1017 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1018 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1019   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKYPE_CALL,
1020 			  "SkypeCall", NDPI_PROTOCOL_CATEGORY_VOIP,
1021 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1022 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1023   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_TIKTOK,
1024 			  "TikTok", NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK,
1025 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1026 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1027   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEREDO,
1028 			  "Teredo", NDPI_PROTOCOL_CATEGORY_NETWORK,
1029 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1030 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1031   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WECHAT,
1032 			  "WeChat", NDPI_PROTOCOL_CATEGORY_CHAT,
1033 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1034 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1035   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEMCACHED,
1036 			  "Memcached", NDPI_PROTOCOL_CATEGORY_NETWORK,
1037 			  ndpi_build_default_ports(ports_a, 11211, 0, 0, 0, 0) /* TCP */,
1038 			  ndpi_build_default_ports(ports_b, 11211, 0, 0, 0, 0) /* UDP */);
1039   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SMBV23,
1040 			  "SMBv23", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
1041 			  ndpi_build_default_ports(ports_a, 445, 0, 0, 0, 0) /* TCP */,
1042 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1043   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_MINING,
1044 			  "Mining", CUSTOM_CATEGORY_MINING,
1045 			  ndpi_build_default_ports(ports_a, 8333, 30303, 0, 0, 0) /* TCP */,
1046 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1047   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NEST_LOG_SINK,
1048 			  "NestLogSink", NDPI_PROTOCOL_CATEGORY_CLOUD,
1049 			  ndpi_build_default_ports(ports_a, 11095, 0, 0, 0, 0) /* TCP */,
1050 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1051   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MODBUS,
1052 			  "Modbus", NDPI_PROTOCOL_CATEGORY_IOT_SCADA,
1053 			  ndpi_build_default_ports(ports_a, 502, 0, 0, 0, 0) /* TCP */,
1054 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1055   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHATSAPP_CALL,
1056 			  "WhatsAppCall", NDPI_PROTOCOL_CATEGORY_VOIP,
1057 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1058 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1059   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DATASAVER,
1060 			  "DataSaver", NDPI_PROTOCOL_CATEGORY_WEB /* dummy */,
1061 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1062 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1063   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SIGNAL,
1064 			  "Signal", NDPI_PROTOCOL_CATEGORY_CHAT,
1065 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1066 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1067   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DOH_DOT,
1068 			  "DoH_DoT", NDPI_PROTOCOL_CATEGORY_NETWORK /* dummy */,
1069 			  ndpi_build_default_ports(ports_a, 853, 0, 0, 0, 0) /* TCP */,
1070 			  ndpi_build_default_ports(ports_b, 784, 0, 0, 0, 0) /* UDP */);
1071   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_REDDIT,
1072 			  "Reddit", NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK,
1073 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1074 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1075   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WIREGUARD,
1076 			  "WireGuard", NDPI_PROTOCOL_CATEGORY_VPN,
1077 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1078 			  ndpi_build_default_ports(ports_b, 51820, 0, 0, 0, 0) /* UDP */);
1079   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PPSTREAM,
1080 			  "PPStream", NDPI_PROTOCOL_CATEGORY_STREAMING,
1081 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1082 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1083   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_XBOX,
1084 			  "Xbox", NDPI_PROTOCOL_CATEGORY_GAME,
1085 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1086 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1087   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PLAYSTATION,
1088 			  "Playstation", NDPI_PROTOCOL_CATEGORY_GAME,
1089 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1090 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1091   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQ,
1092 			  "QQ", NDPI_PROTOCOL_CATEGORY_CHAT,
1093 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1094 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1095   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_RTSP,
1096 			  "RTSP", NDPI_PROTOCOL_CATEGORY_MEDIA,
1097 			  ndpi_build_default_ports(ports_a, 554, 0, 0, 0, 0) /* TCP */,
1098 			  ndpi_build_default_ports(ports_b, 554, 0, 0, 0, 0) /* UDP */);
1099   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ICECAST,
1100 			  "IceCast", NDPI_PROTOCOL_CATEGORY_MEDIA,
1101 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1102 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1103   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_CPHA,
1104 			  "CPHA", NDPI_PROTOCOL_CATEGORY_NETWORK,
1105 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1106 			  ndpi_build_default_ports(ports_b, 8116, 0, 0, 0, 0) /* UDP */);
1107   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ZATTOO,
1108 			  "Zattoo", NDPI_PROTOCOL_CATEGORY_VIDEO,
1109 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1110 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1111   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SHOUTCAST,
1112 			  "ShoutCast", NDPI_PROTOCOL_CATEGORY_MUSIC,
1113 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1114 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1115   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SOPCAST,
1116 			  "Sopcast", NDPI_PROTOCOL_CATEGORY_VIDEO,
1117 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1118 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1119   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DISCORD,
1120 			  "Discord", NDPI_PROTOCOL_CATEGORY_COLLABORATIVE,
1121 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1122 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1123   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_TVUPLAYER,
1124 			  "TVUplayer", NDPI_PROTOCOL_CATEGORY_VIDEO,
1125 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1126 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1127   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQLIVE,
1128 			  "QQLive", NDPI_PROTOCOL_CATEGORY_VIDEO,
1129 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1130 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1131   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_THUNDER,
1132 			  "Thunder", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1133 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1134 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1135   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_SOULSEEK,
1136 			  "Soulseek", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1137 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1138 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1139   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_PS_VUE,
1140 			  "PS_VUE", NDPI_PROTOCOL_CATEGORY_VIDEO,
1141 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1142 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1143   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_IRC,
1144 			  "IRC", NDPI_PROTOCOL_CATEGORY_CHAT,
1145 			  ndpi_build_default_ports(ports_a, 194, 0, 0, 0, 0) /* TCP */,
1146 			  ndpi_build_default_ports(ports_b, 194, 0, 0, 0, 0) /* UDP */);
1147   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AYIYA,
1148 			  "Ayiya", NDPI_PROTOCOL_CATEGORY_NETWORK,
1149 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1150 			  ndpi_build_default_ports(ports_b, 5072, 0, 0, 0, 0) /* UDP */);
1151   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_JABBER,
1152 			  "Jabber", NDPI_PROTOCOL_CATEGORY_WEB,
1153 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1154 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1155   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DISNEYPLUS,
1156 			  "DisneyPlus", NDPI_PROTOCOL_CATEGORY_STREAMING,
1157 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1158 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1159   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_VRRP,
1160 			  "VRRP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1161 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1162 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1163   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_STEAM,
1164 			  "Steam", NDPI_PROTOCOL_CATEGORY_GAME,
1165 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1166 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1167   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HALFLIFE2,
1168 			  "HalfLife2", NDPI_PROTOCOL_CATEGORY_GAME,
1169 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1170 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1171   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WORLDOFWARCRAFT,
1172 			  "WorldOfWarcraft", NDPI_PROTOCOL_CATEGORY_GAME,
1173 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1174 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1175   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_HOTSPOT_SHIELD,
1176 			  "HotspotShield", NDPI_PROTOCOL_CATEGORY_VPN,
1177 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1178 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1179   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_TELNET,
1180 			  "Telnet", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
1181 			  ndpi_build_default_ports(ports_a, 23, 0, 0, 0, 0) /* TCP */,
1182 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1183   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_STUN,
1184 			  "STUN", NDPI_PROTOCOL_CATEGORY_NETWORK,
1185 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1186 			  ndpi_build_default_ports(ports_b, 3478, 0, 0, 0, 0) /* UDP */);
1187   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_IP_IPSEC,
1188 			  "IPsec", NDPI_PROTOCOL_CATEGORY_VPN,
1189 			  ndpi_build_default_ports(ports_a, 500, 0, 0, 0, 0) /* TCP */,
1190 			  ndpi_build_default_ports(ports_b, 500, 4500, 0, 0, 0) /* UDP */);
1191   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_GRE,
1192 			  "GRE", NDPI_PROTOCOL_CATEGORY_NETWORK,
1193 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1194 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1195   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_ICMP,
1196 			  "ICMP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1197 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1198 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1199   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_IGMP,
1200 			  "IGMP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1201 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1202 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1203   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_EGP,
1204 			  "EGP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1205 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1206 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1207   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_SCTP,
1208 			  "SCTP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1209 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1210 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1211   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_OSPF,
1212 			  "OSPF", NDPI_PROTOCOL_CATEGORY_NETWORK,
1213 			  ndpi_build_default_ports(ports_a, 2604, 0, 0, 0, 0) /* TCP */,
1214 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1215   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_IP_IN_IP,
1216 			  "IP_in_IP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1217 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1218 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1219   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTP,
1220 			  "RTP", NDPI_PROTOCOL_CATEGORY_MEDIA,
1221 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1222 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1223   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RDP,
1224 			  "RDP", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
1225 			  ndpi_build_default_ports(ports_a, 3389, 0, 0, 0, 0) /* TCP */,
1226 			  ndpi_build_default_ports(ports_b, 3389, 0, 0, 0, 0) /* UDP */);
1227   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VNC,
1228 			  "VNC", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
1229 			  ndpi_build_default_ports(ports_a, 5900, 5901, 5800, 0, 0) /* TCP */,
1230 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1231   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_TUMBLR,
1232 			  "Tumblr", NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK,
1233 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1234 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1235   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZOOM,
1236 			  "Zoom", NDPI_PROTOCOL_CATEGORY_VIDEO,
1237 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1238 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1239   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHATSAPP_FILES,
1240 			  "WhatsAppFiles", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1241 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1242 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1243   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHATSAPP,
1244 			  "WhatsApp", NDPI_PROTOCOL_CATEGORY_CHAT,
1245 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1246 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1247   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_TLS,
1248 			  "TLS", NDPI_PROTOCOL_CATEGORY_WEB,
1249 			  ndpi_build_default_ports(ports_a, 443, 0, 0, 0, 0) /* TCP */,
1250 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1251   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_TLS,
1252 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
1253 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_TLS can have (content-matched) subprotocols */
1254   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_DTLS,
1255 			  "DTLS", NDPI_PROTOCOL_CATEGORY_WEB,
1256 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1257 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1258   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_DTLS,
1259 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
1260 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_DTLS can have (content-matched) subprotocols */
1261   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SSH,
1262 			  "SSH", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
1263 			  ndpi_build_default_ports(ports_a, 22, 0, 0, 0, 0) /* TCP */,
1264 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1265   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_USENET,
1266 			  "Usenet", NDPI_PROTOCOL_CATEGORY_WEB,
1267 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1268 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1269   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MGCP,
1270 			  "MGCP", NDPI_PROTOCOL_CATEGORY_VOIP,
1271 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1272 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1273   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IAX,
1274 			  "IAX", NDPI_PROTOCOL_CATEGORY_VOIP,
1275 			  ndpi_build_default_ports(ports_a, 4569, 0, 0, 0, 0) /* TCP */,
1276 			  ndpi_build_default_ports(ports_b, 4569, 0, 0, 0, 0) /* UDP */);
1277   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AFP,
1278 			  "AFP", NDPI_PROTOCOL_CATEGORY_DATA_TRANSFER,
1279 			  ndpi_build_default_ports(ports_a, 548, 0, 0, 0, 0) /* TCP */,
1280 			  ndpi_build_default_ports(ports_b, 548, 0, 0, 0, 0) /* UDP */);
1281   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_HULU,
1282 			  "Hulu", NDPI_PROTOCOL_CATEGORY_STREAMING,
1283 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1284 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1285   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CHECKMK,
1286 			  "CHECKMK", NDPI_PROTOCOL_CATEGORY_DATA_TRANSFER,
1287 			  ndpi_build_default_ports(ports_a, 6556, 0, 0, 0, 0) /* TCP */,
1288 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1289   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_STEALTHNET,
1290 			  "Stealthnet", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1291 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1292 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1293   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_AIMINI,
1294 			  "Aimini", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1295 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1296 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1297   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SIP,
1298 			  "SIP", NDPI_PROTOCOL_CATEGORY_VOIP,
1299 			  ndpi_build_default_ports(ports_a, 5060, 5061, 0, 0, 0) /* TCP */,
1300 			  ndpi_build_default_ports(ports_b, 5060, 5061, 0, 0, 0) /* UDP */);
1301   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TRUPHONE,
1302 			  "TruPhone", NDPI_PROTOCOL_CATEGORY_VOIP,
1303 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1304 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1305   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IP_ICMPV6,
1306 			  "ICMPV6", NDPI_PROTOCOL_CATEGORY_NETWORK,
1307 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1308 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1309   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DHCPV6,
1310 			  "DHCPV6", NDPI_PROTOCOL_CATEGORY_NETWORK,
1311 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1312 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1313   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ARMAGETRON,
1314 			  "Armagetron", NDPI_PROTOCOL_CATEGORY_GAME,
1315 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1316 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1317   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_CROSSFIRE,
1318 			  "Crossfire", NDPI_PROTOCOL_CATEGORY_RPC,
1319 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1320 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1321   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DOFUS,
1322 			  "Dofus", NDPI_PROTOCOL_CATEGORY_GAME,
1323 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1324 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1325   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_FIESTA,
1326 			  "Fiesta", NDPI_PROTOCOL_CATEGORY_GAME,
1327 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1328 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1329   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_FLORENSIA,
1330 			  "Florensia", NDPI_PROTOCOL_CATEGORY_GAME,
1331 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1332 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1333   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_GUILDWARS,
1334 			  "Guildwars", NDPI_PROTOCOL_CATEGORY_GAME,
1335 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1336 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1337   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AMAZON_ALEXA,
1338 			  "AmazonAlexa", NDPI_PROTOCOL_CATEGORY_VIRTUAL_ASSISTANT,
1339 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1340 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1341   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_KERBEROS,
1342 			  "Kerberos", NDPI_PROTOCOL_CATEGORY_NETWORK,
1343 			  ndpi_build_default_ports(ports_a, 88, 0, 0, 0, 0) /* TCP */,
1344 			  ndpi_build_default_ports(ports_b, 88, 0, 0, 0, 0) /* UDP */);
1345   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LDAP,
1346 			  "LDAP", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
1347 			  ndpi_build_default_ports(ports_a, 389, 0, 0, 0, 0) /* TCP */,
1348 			  ndpi_build_default_ports(ports_b, 389, 0, 0, 0, 0) /* UDP */);
1349   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_MAPLESTORY,
1350 			  "MapleStory", NDPI_PROTOCOL_CATEGORY_GAME,
1351 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1352 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1353   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MSSQL_TDS,
1354 			  "MsSQL-TDS", NDPI_PROTOCOL_CATEGORY_DATABASE,
1355 			  ndpi_build_default_ports(ports_a, 1433, 1434, 0, 0, 0) /* TCP */,
1356 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1357   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_PPTP,
1358 			  "PPTP", NDPI_PROTOCOL_CATEGORY_VPN,
1359 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1360 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1361   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WARCRAFT3,
1362 			  "Warcraft3", NDPI_PROTOCOL_CATEGORY_GAME,
1363 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1364 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1365   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_WORLD_OF_KUNG_FU,
1366 			  "WorldOfKungFu", NDPI_PROTOCOL_CATEGORY_GAME,
1367 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1368 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1369   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DCERPC,
1370 			  "DCE_RPC", NDPI_PROTOCOL_CATEGORY_RPC,
1371 			  ndpi_build_default_ports(ports_a, 135, 0, 0, 0, 0) /* TCP */,
1372 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1373   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NETFLOW,
1374 			  "NetFlow", NDPI_PROTOCOL_CATEGORY_NETWORK,
1375 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1376 			  ndpi_build_default_ports(ports_b, 2055, 0, 0, 0, 0) /* UDP */);
1377   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SFLOW,
1378 			  "sFlow", NDPI_PROTOCOL_CATEGORY_NETWORK,
1379 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1380 			  ndpi_build_default_ports(ports_b, 6343, 0, 0, 0, 0) /* UDP */);
1381   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_CONNECT,
1382 			  "HTTP_Connect", NDPI_PROTOCOL_CATEGORY_WEB,
1383 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1384 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1385   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP_CONNECT,
1386 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
1387 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP_CONNECT can have (content-matched) subprotocols */
1388   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HTTP_PROXY,
1389 			  "HTTP_Proxy", NDPI_PROTOCOL_CATEGORY_WEB,
1390 			  ndpi_build_default_ports(ports_a, 8080, 3128, 0, 0, 0) /* TCP */,
1391 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1392   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP_PROXY,
1393 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
1394 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_HTTP_PROXY can have (content-matched) subprotocols */
1395   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CITRIX,
1396 			  "Citrix", NDPI_PROTOCOL_CATEGORY_NETWORK,
1397 			  ndpi_build_default_ports(ports_a, 1494, 2598, 0, 0, 0) /* TCP */,
1398 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1399   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WEBEX,
1400 			  "Webex", NDPI_PROTOCOL_CATEGORY_VOIP,
1401 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1402 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1403   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RADIUS,
1404 			  "Radius", NDPI_PROTOCOL_CATEGORY_NETWORK,
1405 			  ndpi_build_default_ports(ports_a, 1812, 1813, 0, 0, 0) /* TCP */,
1406 			  ndpi_build_default_ports(ports_b, 1812, 1813, 0, 0, 0) /* UDP */);
1407   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEAMVIEWER,
1408 			  "TeamViewer", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
1409 			  ndpi_build_default_ports(ports_a, 5938, 0, 0, 0, 0) /* TCP */,
1410 			  ndpi_build_default_ports(ports_b, 5938, 0, 0, 0, 0) /* UDP */);
1411   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LOTUS_NOTES,
1412 			  "LotusNotes", NDPI_PROTOCOL_CATEGORY_COLLABORATIVE,
1413 			  ndpi_build_default_ports(ports_a, 1352, 0, 0, 0, 0) /* TCP */,
1414 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1415   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SAP,
1416 			  "SAP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1417 			  ndpi_build_default_ports(ports_a, 3201, 0, 0, 0, 0) /* TCP */,
1418 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */
1419   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_GTP,
1420 			  "GTP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1421 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1422 			  ndpi_build_default_ports(ports_b, 2152, 2123, 0, 0, 0) /* UDP */);
1423   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WSD,
1424 			  "WSD", NDPI_PROTOCOL_CATEGORY_NETWORK,
1425 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1426 			  ndpi_build_default_ports(ports_b, 3702, 0, 0, 0, 0) /* UDP */);
1427   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TELEGRAM,
1428 			  "Telegram", NDPI_PROTOCOL_CATEGORY_CHAT,
1429 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1430 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1431   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_QUIC,
1432 			  "QUIC", NDPI_PROTOCOL_CATEGORY_WEB,
1433 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1434 			  ndpi_build_default_ports(ports_b, 443, 80, 0, 0, 0) /* UDP */);
1435   ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_QUIC,
1436 			      NDPI_PROTOCOL_MATCHED_BY_CONTENT,
1437 			      NDPI_PROTOCOL_NO_MORE_SUBPROTOCOLS); /* NDPI_PROTOCOL_QUIC can have (content-matched) subprotocols */
1438   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DIAMETER,
1439 			  "Diameter", NDPI_PROTOCOL_CATEGORY_NETWORK,
1440 			  ndpi_build_default_ports(ports_a, 3868, 0, 0, 0, 0) /* TCP */,
1441 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1442   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_APPLE_PUSH,
1443 			  "ApplePush", NDPI_PROTOCOL_CATEGORY_CLOUD,
1444 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1445 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1446   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DROPBOX,
1447 			  "Dropbox", NDPI_PROTOCOL_CATEGORY_CLOUD,
1448 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1449 			  ndpi_build_default_ports(ports_b, 17500, 0, 0, 0, 0) /* UDP */);
1450   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SPOTIFY,
1451 			  "Spotify", NDPI_PROTOCOL_CATEGORY_MUSIC,
1452 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1453 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1454   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MESSENGER,
1455 			  "Messenger", NDPI_PROTOCOL_CATEGORY_VOIP,
1456 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1457 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1458   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LISP,
1459 			  "LISP", NDPI_PROTOCOL_CATEGORY_CLOUD,
1460 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1461 			  ndpi_build_default_ports(ports_b, 4342, 4341, 0, 0, 0) /* UDP */);
1462   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EAQ,
1463 			  "EAQ", NDPI_PROTOCOL_CATEGORY_NETWORK,
1464 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1465 			  ndpi_build_default_ports(ports_b, 6000, 0, 0, 0, 0) /* UDP */);
1466   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_KAKAOTALK_VOICE,
1467 			  "KakaoTalk_Voice", NDPI_PROTOCOL_CATEGORY_VOIP,
1468 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1469 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1470   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_MPEGTS,
1471 			  "MPEG_TS", NDPI_PROTOCOL_CATEGORY_MEDIA,
1472 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1473 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1474   /* http://en.wikipedia.org/wiki/Link-local_Multicast_Name_Resolution */
1475   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_LLMNR,
1476 			  "LLMNR", NDPI_PROTOCOL_CATEGORY_NETWORK,
1477 			  ndpi_build_default_ports(ports_a, 5355, 0, 0, 0, 0) /* TCP */,
1478 			  ndpi_build_default_ports(ports_b, 5355, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */
1479   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_REMOTE_SCAN,
1480 			  "RemoteScan", NDPI_PROTOCOL_CATEGORY_NETWORK,
1481 			  ndpi_build_default_ports(ports_a, 6077, 0, 0, 0, 0) /* TCP */,
1482 			  ndpi_build_default_ports(ports_b, 6078, 0, 0, 0, 0) /* UDP */); /* Missing dissector: port based only */
1483   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_H323,
1484 			  "H323", NDPI_PROTOCOL_CATEGORY_VOIP,
1485 			  ndpi_build_default_ports(ports_a, 1719, 1720, 0, 0, 0) /* TCP */,
1486 			  ndpi_build_default_ports(ports_b, 1719, 1720, 0, 0, 0) /* UDP */);
1487   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_OPENVPN,
1488 			  "OpenVPN", NDPI_PROTOCOL_CATEGORY_VPN,
1489 			  ndpi_build_default_ports(ports_a, 1194, 0, 0, 0, 0) /* TCP */,
1490 			  ndpi_build_default_ports(ports_b, 1194, 0, 0, 0, 0) /* UDP */);
1491   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_NOE,
1492 			  "NOE", NDPI_PROTOCOL_CATEGORY_VOIP,
1493 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1494 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1495   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CISCOVPN,
1496 			  "CiscoVPN", NDPI_PROTOCOL_CATEGORY_VPN,
1497 			  ndpi_build_default_ports(ports_a, 10000, 8008, 8009, 0, 0) /* TCP */,
1498 			  ndpi_build_default_ports(ports_b, 10000, 0, 0, 0, 0) /* UDP */);
1499   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TEAMSPEAK,
1500 			  "TeamSpeak", NDPI_PROTOCOL_CATEGORY_VOIP,
1501 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1502 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1503   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS, NDPI_PROTOCOL_TOR,
1504 			  "Tor", NDPI_PROTOCOL_CATEGORY_VPN,
1505 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1506 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1507   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SKINNY,
1508 			  "CiscoSkinny", NDPI_PROTOCOL_CATEGORY_VOIP,
1509 			  ndpi_build_default_ports(ports_a, 2000, 0, 0, 0, 0) /* TCP */,
1510 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1511   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTCP,
1512 			  "RTCP", NDPI_PROTOCOL_CATEGORY_VOIP,
1513 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1514 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1515   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RSYNC,
1516 			  "RSYNC", NDPI_PROTOCOL_CATEGORY_DATA_TRANSFER,
1517 			  ndpi_build_default_ports(ports_a, 873, 0, 0, 0, 0) /* TCP */,
1518 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1519   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ORACLE,
1520 			  "Oracle", NDPI_PROTOCOL_CATEGORY_DATABASE,
1521 			  ndpi_build_default_ports(ports_a, 1521, 0, 0, 0, 0) /* TCP */,
1522 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1523   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CORBA,
1524 			  "Corba", NDPI_PROTOCOL_CATEGORY_RPC,
1525 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1526 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1527   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_UBUNTUONE,
1528 			  "UbuntuONE", NDPI_PROTOCOL_CATEGORY_CLOUD,
1529 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1530 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1531   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHOIS_DAS,
1532 			  "Whois-DAS", NDPI_PROTOCOL_CATEGORY_NETWORK,
1533 			  ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0), /* TCP */
1534 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0));    /* UDP */
1535   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_COLLECTD,
1536 			  "Collectd", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
1537 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),      /* TCP */
1538 			  ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0)); /* UDP */
1539   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS,
1540 			  "SOCKS", NDPI_PROTOCOL_CATEGORY_WEB,
1541 			  ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0),  /* TCP */
1542 			  ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0)); /* UDP */
1543   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TFTP,
1544 			  "TFTP", NDPI_PROTOCOL_CATEGORY_DATA_TRANSFER,
1545 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),   /* TCP */
1546 			  ndpi_build_default_ports(ports_b, 69, 0, 0, 0, 0)); /* UDP */
1547   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTMP,
1548 			  "RTMP", NDPI_PROTOCOL_CATEGORY_MEDIA,
1549 			  ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0), /* TCP */
1550 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0));   /* UDP */
1551   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PINTEREST,
1552 			  "Pinterest", NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK,
1553 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1554 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1555   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEGACO,
1556 			  "Megaco", NDPI_PROTOCOL_CATEGORY_VOIP,
1557 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),     /* TCP */
1558 			  ndpi_build_default_ports(ports_b, 2944, 0, 0, 0, 0)); /* UDP */
1559   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_REDIS,
1560 			  "Redis", NDPI_PROTOCOL_CATEGORY_DATABASE,
1561 			  ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0), /* TCP */
1562 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0));   /* UDP */
1563   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZMQ,
1564 			  "ZeroMQ", NDPI_PROTOCOL_CATEGORY_RPC,
1565 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1566 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1567   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_VHUA,
1568 			  "VHUA", NDPI_PROTOCOL_CATEGORY_VOIP,
1569 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),      /* TCP */
1570 			  ndpi_build_default_ports(ports_b, 58267, 0, 0, 0, 0)); /* UDP */
1571   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_STARCRAFT,
1572 			  "Starcraft", NDPI_PROTOCOL_CATEGORY_GAME,
1573 			  ndpi_build_default_ports(ports_a, 1119, 0, 0, 0, 0),  /* TCP */
1574 			  ndpi_build_default_ports(ports_b, 1119, 0, 0, 0, 0)); /* UDP */
1575   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_UBNTAC2,
1576 			  "UBNTAC2", NDPI_PROTOCOL_CATEGORY_NETWORK,
1577 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),      /* TCP */
1578 			  ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */
1579   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VIBER,
1580 			  "Viber", NDPI_PROTOCOL_CATEGORY_VOIP,
1581 			  ndpi_build_default_ports(ports_a, 7985, 5242, 5243, 4244, 0),     /* TCP */
1582 			  ndpi_build_default_ports(ports_b, 7985, 7987, 5242, 5243, 4244)); /* UDP */
1583   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_COAP,
1584 			  "COAP", NDPI_PROTOCOL_CATEGORY_RPC,
1585 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),        /* TCP */
1586 			  ndpi_build_default_ports(ports_b, 5683, 5684, 0, 0, 0)); /* UDP */
1587   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MQTT,
1588 			  "MQTT", NDPI_PROTOCOL_CATEGORY_RPC,
1589 			  ndpi_build_default_ports(ports_a, 1883, 8883, 0, 0, 0), /* TCP */
1590 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0));      /* UDP */
1591   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOMEIP,
1592 			  "SOMEIP", NDPI_PROTOCOL_CATEGORY_RPC,
1593 			  ndpi_build_default_ports(ports_a, 30491, 30501, 0, 0, 0),      /* TCP */
1594 			  ndpi_build_default_ports(ports_b, 30491, 30501, 30490, 0, 0)); /* UDP */
1595   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RX,
1596 			  "RX", NDPI_PROTOCOL_CATEGORY_RPC,
1597 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1598 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1599   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_GIT,
1600 			  "Git", NDPI_PROTOCOL_CATEGORY_COLLABORATIVE,
1601 			  ndpi_build_default_ports(ports_a, 9418, 0, 0, 0, 0), /* TCP */
1602 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0));   /* UDP */
1603   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DRDA,
1604 			  "DRDA", NDPI_PROTOCOL_CATEGORY_DATABASE,
1605 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1606 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1607   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HANGOUT_DUO,
1608 			  "GoogleHangoutDuo", NDPI_PROTOCOL_CATEGORY_VOIP,
1609 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1610 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1611   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BJNP,
1612 			  "BJNP", NDPI_PROTOCOL_CATEGORY_SYSTEM_OS,
1613 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1614 			  ndpi_build_default_ports(ports_b, 8612, 0, 0, 0, 0) /* UDP */);
1615   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SMPP,
1616 			  "SMPP", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
1617 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1618 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1619   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_OOKLA,
1620 			  "Ookla", NDPI_PROTOCOL_CATEGORY_NETWORK,
1621 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1622 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1623   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AMQP,
1624 			  "AMQP", NDPI_PROTOCOL_CATEGORY_RPC,
1625 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1626 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1627   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_DNSCRYPT,
1628 			  "DNScrypt", NDPI_PROTOCOL_CATEGORY_NETWORK,
1629 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1630 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1631   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TINC,
1632 			  "TINC", NDPI_PROTOCOL_CATEGORY_VPN,
1633 			  ndpi_build_default_ports(ports_a, 655, 0, 0, 0, 0) /* TCP */,
1634 			  ndpi_build_default_ports(ports_b, 655, 0, 0, 0, 0) /* UDP */);
1635   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_FIX,
1636 			  "FIX", NDPI_PROTOCOL_CATEGORY_RPC,
1637 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1638 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1639   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_NINTENDO,
1640 			  "Nintendo", NDPI_PROTOCOL_CATEGORY_GAME,
1641 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1642 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1643   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_CSGO,
1644 			  "CSGO", NDPI_PROTOCOL_CATEGORY_GAME,
1645 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1646 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1647   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AJP,
1648 			  "AJP", NDPI_PROTOCOL_CATEGORY_WEB,
1649 			  ndpi_build_default_ports(ports_a, 8009, 8010, 0, 0, 0) /* TCP */,
1650 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1651   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TARGUS_GETDATA,
1652 			  "TargusDataspeed", NDPI_PROTOCOL_CATEGORY_NETWORK,
1653 			  ndpi_build_default_ports(ports_a, 5001, 5201, 0, 0, 0) /* TCP */,
1654 			  ndpi_build_default_ports(ports_b, 5001, 5201, 0, 0, 0) /* UDP */);
1655   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AMAZON_VIDEO,
1656 			  "AmazonVideo", NDPI_PROTOCOL_CATEGORY_CLOUD,
1657 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1658 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1659   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DNP3,
1660 			  "DNP3", NDPI_PROTOCOL_CATEGORY_IOT_SCADA,
1661 			  ndpi_build_default_ports(ports_a, 20000, 0, 0, 0, 0) /* TCP */,
1662 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1663   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_IEC60870,
1664 			  "IEC60870", NDPI_PROTOCOL_CATEGORY_IOT_SCADA,
1665 			  ndpi_build_default_ports(ports_a, 2404, 0, 0, 0, 0) /* TCP */,
1666 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1667   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_BLOOMBERG,
1668 			  "Bloomberg", NDPI_PROTOCOL_CATEGORY_NETWORK,
1669 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1670 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1671   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_CAPWAP,
1672 			  "CAPWAP", NDPI_PROTOCOL_CATEGORY_NETWORK,
1673 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1674 			  ndpi_build_default_ports(ports_b, 5246, 5247, 0, 0, 0) /* UDP */);
1675   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZABBIX,
1676 			  "Zabbix", NDPI_PROTOCOL_CATEGORY_NETWORK,
1677 			  ndpi_build_default_ports(ports_a, 10050, 0, 0, 0, 0) /* TCP */,
1678 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1679   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_S7COMM,
1680 			  "s7comm", NDPI_PROTOCOL_CATEGORY_NETWORK,
1681 			  ndpi_build_default_ports(ports_a, 102, 0, 0, 0, 0) /* TCP */,
1682 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1683   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MSTEAMS,
1684 			  "Teams", NDPI_PROTOCOL_CATEGORY_COLLABORATIVE,
1685 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1686 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1687   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WEBSOCKET,
1688 			  "WebSocket", NDPI_PROTOCOL_CATEGORY_WEB,
1689 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1690 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1691   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ANYDESK,
1692 			  "AnyDesk", NDPI_PROTOCOL_CATEGORY_REMOTE_ACCESS,
1693 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1694 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1695   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOAP,
1696 			  "SOAP", NDPI_PROTOCOL_CATEGORY_RPC,
1697 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1698 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1699   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MONGODB,
1700 			  "MongoDB", NDPI_PROTOCOL_CATEGORY_DATABASE,
1701 			  ndpi_build_default_ports(ports_a, 27017, 0, 0, 0, 0) /* TCP */,
1702 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1703   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_APPLE_SIRI,
1704 			  "AppleSiri", NDPI_PROTOCOL_CATEGORY_VIRTUAL_ASSISTANT,
1705 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1706 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1707   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SNAPCHAT_CALL,
1708 			  "SnapchatCall", NDPI_PROTOCOL_CATEGORY_VOIP,
1709 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1710 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1711   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_HPVIRTGRP,
1712 			  "HP Virtual Machine Group Management", NDPI_PROTOCOL_CATEGORY_NETWORK,
1713 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1714 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1715   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_GENSHIN_IMPACT,
1716 			  "GenshinImpact", NDPI_PROTOCOL_CATEGORY_GAME,
1717 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1718 			  ndpi_build_default_ports(ports_b, 22102, 0, 0, 0, 0) /* UDP */);
1719   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ACTIVISION,
1720 			  "Activision", NDPI_PROTOCOL_CATEGORY_GAME,
1721 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1722 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1723   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_FORTICLIENT,
1724 			  "FortiClient", NDPI_PROTOCOL_CATEGORY_VPN,
1725 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1726 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1727   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_Z3950,
1728 			  "Z39.50", NDPI_PROTOCOL_CATEGORY_NETWORK,
1729 			  ndpi_build_default_ports(ports_a, 210, 0, 0, 0, 0) /* TCP */,
1730 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1731   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_LIKEE,
1732 			  "Likee", NDPI_PROTOCOL_CATEGORY_SOCIAL_NETWORK,
1733 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1734 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1735   ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_GITLAB,
1736 			  "GitLab", NDPI_PROTOCOL_CATEGORY_COLLABORATIVE,
1737 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
1738 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
1739   ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_AVAST_SECUREDNS,
1740 			  "AVAST SecureDNS", NDPI_PROTOCOL_CATEGORY_NETWORK,
1741 			  ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0),  /* TCP */
1742 			  ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
1743 
1744 #ifdef CUSTOM_NDPI_PROTOCOLS
1745 #include "../../../nDPI-custom/custom_ndpi_main.c"
1746 #endif
1747 
1748   /* calling function for host and content matched protocols */
1749   init_string_based_protocols(ndpi_str);
1750 
1751   ndpi_validate_protocol_initialization(ndpi_str);
1752 }
1753 
1754 /* ****************************************************** */
1755 
1756 #ifdef CUSTOM_NDPI_PROTOCOLS
1757 #include "../../../nDPI-custom/custom_ndpi_protocols.c"
1758 #endif
1759 
1760 /* ****************************************************** */
1761 
1762 #define MATCH_DEBUG_INFO(fmt, ...) if(txt->option & AC_FEATURE_DEBUG) printf(fmt, ##__VA_ARGS__)
1763 
ac_domain_match_handler(AC_MATCH_t * m,AC_TEXT_t * txt,AC_REP_t * match)1764 static int ac_domain_match_handler(AC_MATCH_t *m, AC_TEXT_t *txt, AC_REP_t *match) {
1765   AC_PATTERN_t *pattern = m->patterns;
1766   int i,start,end = m->position;
1767 
1768   for(i=0; i < m->match_num; i++,pattern++) {
1769     /*
1770      * See ac_automata_exact_match()
1771      * The bit is set if the pattern exactly matches AND
1772      * the length of the pattern is longer than that of the previous one.
1773      * Skip shorter (less precise) templates.
1774      */
1775     if(!(m->match_map & (1 << i)))
1776       continue;
1777     start = end - pattern->length;
1778 
1779     MATCH_DEBUG_INFO("[NDPI] Searching: [to search: %.*s/%u][pattern: %s%.*s%s/%u l:%u] %d-%d\n",
1780 		     txt->length, txt->astring,(unsigned int) txt->length,
1781 		     m->patterns[0].rep.from_start ? "^":"",
1782 		     (unsigned int) pattern->length, pattern->astring,
1783 		     m->patterns[0].rep.at_end ? "$":"", (unsigned int) pattern->length,m->patterns[0].rep.level,
1784 		     start,end);
1785 
1786     if(start == 0 && end == txt->length) {
1787       *match = pattern->rep; txt->match.last = pattern;
1788       MATCH_DEBUG_INFO("[NDPI] Searching: Found exact match. Proto %d \n",pattern->rep.number);
1789       return 1;
1790     }
1791     /* pattern is DOMAIN.NAME and string x.DOMAIN.NAME ? */
1792     if(start > 1 && !ndpi_is_middle_string_char(pattern->astring[0]) && pattern->rep.dot) {
1793       /*
1794 	The patch below allows in case of pattern ws.amazon.com
1795 	to avoid matching aws.amazon.com whereas a.ws.amazon.com
1796 	has to match
1797       */
1798       if(ndpi_is_middle_string_char(txt->astring[start-1])) {
1799 	if(!txt->match.last || txt->match.last->rep.level < pattern->rep.level) {
1800 	  txt->match.last = pattern; *match = pattern->rep;
1801 	  MATCH_DEBUG_INFO("[NDPI] Searching: Found domain match. Proto %d \n",pattern->rep.number);
1802 	}
1803       }
1804       continue;
1805     }
1806 
1807     if(!txt->match.last || txt->match.last->rep.level < pattern->rep.level) {
1808       txt->match.last = pattern; *match = pattern->rep;
1809       MATCH_DEBUG_INFO("[NDPI] Searching: matched. Proto %d \n",pattern->rep.number);
1810     }
1811   }
1812   return 0;
1813 }
1814 
1815 /* ******************************************************************** */
1816 
ndpi_patricia_get_maxbits(ndpi_patricia_tree_t * tree)1817 u_int16_t ndpi_patricia_get_maxbits(ndpi_patricia_tree_t *tree) {
1818   return(tree->maxbits);
1819 }
1820 
1821 /* ******************************************************************** */
1822 
ndpi_fill_prefix_v4(ndpi_prefix_t * p,const struct in_addr * a,int b,int mb)1823 int ndpi_fill_prefix_v4(ndpi_prefix_t *p, const struct in_addr *a, int b, int mb) {
1824   if(b < 0 || b > mb)
1825     return(-1);
1826 
1827   memset(p, 0, sizeof(ndpi_prefix_t));
1828   memcpy(&p->add.sin, a, (mb + 7) / 8);
1829   p->family = AF_INET;
1830   p->bitlen = b;
1831   p->ref_count = 0;
1832 
1833   return(0);
1834 }
1835 
1836 /* ******************************************* */
1837 
ndpi_fill_prefix_v6(ndpi_prefix_t * prefix,const struct in6_addr * addr,int bits,int maxbits)1838 int ndpi_fill_prefix_v6(ndpi_prefix_t *prefix, const struct in6_addr *addr, int bits, int maxbits) {
1839   if(bits < 0 || bits > maxbits)
1840     return -1;
1841 
1842   memcpy(&prefix->add.sin6, addr, (maxbits + 7) / 8);
1843   prefix->family = AF_INET6, prefix->bitlen = bits, prefix->ref_count = 0;
1844 
1845   return 0;
1846 }
1847 
1848 /* ******************************************* */
1849 
ndpi_fill_prefix_mac(ndpi_prefix_t * prefix,u_int8_t * mac,int bits,int maxbits)1850 int ndpi_fill_prefix_mac(ndpi_prefix_t *prefix, u_int8_t *mac, int bits, int maxbits) {
1851   if(bits < 0 || bits > maxbits)
1852     return -1;
1853 
1854   memcpy(prefix->add.mac, mac, 6);
1855   prefix->family = AF_MAC, prefix->bitlen = bits, prefix->ref_count = 0;
1856 
1857   return 0;
1858 }
1859 
1860 /* ******************************************* */
1861 
ndpi_patricia_get_node_prefix(ndpi_patricia_node_t * node)1862 ndpi_prefix_t *ndpi_patricia_get_node_prefix(ndpi_patricia_node_t *node) {
1863   return(node->prefix);
1864 }
1865 
1866 /* ******************************************* */
1867 
ndpi_patricia_get_node_bits(ndpi_patricia_node_t * node)1868 u_int16_t ndpi_patricia_get_node_bits(ndpi_patricia_node_t *node) {
1869   return(node->bit);
1870 }
1871 
1872 /* ******************************************* */
1873 
ndpi_patricia_set_node_data(ndpi_patricia_node_t * node,void * data)1874 void ndpi_patricia_set_node_data(ndpi_patricia_node_t *node, void *data) {
1875   node->data = data;
1876 }
1877 
1878 /* ******************************************* */
1879 
ndpi_patricia_get_node_data(ndpi_patricia_node_t * node)1880 void *ndpi_patricia_get_node_data(ndpi_patricia_node_t *node) {
1881   return(node->data);
1882 }
1883 
1884 /* ******************************************* */
1885 
ndpi_patricia_set_node_u64(ndpi_patricia_node_t * node,u_int64_t value)1886 void ndpi_patricia_set_node_u64(ndpi_patricia_node_t *node, u_int64_t value) {
1887   node->value.u.uv64 = value;
1888 }
1889 
1890 /* ******************************************* */
1891 
ndpi_patricia_get_node_u64(ndpi_patricia_node_t * node)1892 u_int64_t ndpi_patricia_get_node_u64(ndpi_patricia_node_t *node) {
1893   return(node->value.u.uv64);
1894 }
1895 
1896 /* ******************************************* */
1897 
ndpi_is_public_ipv4(u_int32_t a)1898 u_int8_t ndpi_is_public_ipv4(u_int32_t a /* host byte order */) {
1899   if(   ((a & 0xFF000000) == 0x0A000000 /* 10.0.0.0/8 */)
1900 	|| ((a & 0xFFF00000) == 0xAC100000 /* 172.16.0.0/12 */)
1901 	|| ((a & 0xFFFF0000) == 0xC0A80000 /* 192.168.0.0/16 */)
1902 	|| ((a & 0xFF000000) == 0x7F000000 /* 127.0.0.0/8 */)
1903 	|| ((a & 0xF0000000) == 0xE0000000 /* 224.0.0.0/4 */)
1904 	)
1905     return(0);
1906   else
1907     return(1);
1908 }
1909 
1910 /* ******************************************* */
1911 
ndpi_network_ptree_match(struct ndpi_detection_module_struct * ndpi_str,struct in_addr * pin)1912 u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_str,
1913                                    struct in_addr *pin /* network byte order */) {
1914   ndpi_prefix_t prefix;
1915   ndpi_patricia_node_t *node;
1916 
1917   if(ndpi_str->ndpi_num_custom_protocols == 0) {
1918     /*
1919       In case we don't have defined any custom protocol we check the ptree
1920       only in case of public IP addresses as in ndpi_content_match.c.inc
1921       we only have public IP addresses. Instead with custom protocols, users
1922       might have defined private protocols hence we should not skip
1923       the checks below
1924     */
1925 
1926     if(ndpi_is_public_ipv4(ntohl(pin->s_addr)) == 0)
1927       return(NDPI_PROTOCOL_UNKNOWN); /* Non public IP */
1928   }
1929 
1930   /* Make sure all in network byte order otherwise compares wont work */
1931   ndpi_fill_prefix_v4(&prefix, pin, 32, ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
1932   node = ndpi_patricia_search_best(ndpi_str->protocols_ptree, &prefix);
1933 
1934   return(node ? node->value.u.uv32.user_value : NDPI_PROTOCOL_UNKNOWN);
1935 }
1936 
1937 /* ******************************************* */
1938 
ndpi_network_port_ptree_match(struct ndpi_detection_module_struct * ndpi_str,struct in_addr * pin,u_int16_t port)1939 u_int16_t ndpi_network_port_ptree_match(struct ndpi_detection_module_struct *ndpi_str,
1940 					struct in_addr *pin /* network byte order */,
1941 					u_int16_t port /* network byte order */) {
1942   ndpi_prefix_t prefix;
1943   ndpi_patricia_node_t *node;
1944 
1945   /* Make sure all in network byte order otherwise compares wont work */
1946   ndpi_fill_prefix_v4(&prefix, pin, 32, ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
1947   node = ndpi_patricia_search_best(ndpi_str->protocols_ptree, &prefix);
1948 
1949   if(node) {
1950     if((node->value.u.uv32.additional_user_value == 0)
1951        || (node->value.u.uv32.additional_user_value == port))
1952       return(node->value.u.uv32.user_value);
1953   }
1954 
1955   return(NDPI_PROTOCOL_UNKNOWN);
1956 }
1957 
1958 /* ******************************************* */
1959 
1960 #if 0
1961 static u_int8_t tor_ptree_match(struct ndpi_detection_module_struct *ndpi_str, struct in_addr *pin) {
1962   return((ndpi_network_ptree_match(ndpi_str, pin) == NDPI_PROTOCOL_TOR) ? 1 : 0);
1963 }
1964 #endif
1965 
1966 /* ******************************************* */
1967 
ndpi_is_tor_flow(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow)1968 u_int8_t ndpi_is_tor_flow(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
1969   struct ndpi_packet_struct *packet = &flow->packet;
1970 
1971   if(packet->tcp != NULL) {
1972     if(packet->iph) {
1973       if(flow->guessed_host_protocol_id == NDPI_PROTOCOL_TOR)
1974 	return(1);
1975     }
1976   }
1977 
1978   return(0);
1979 }
1980 
1981 /* ******************************************* */
1982 
add_to_ptree(ndpi_patricia_tree_t * tree,int family,void * addr,int bits)1983 static ndpi_patricia_node_t* add_to_ptree(ndpi_patricia_tree_t *tree, int family, void *addr, int bits) {
1984   ndpi_prefix_t prefix;
1985   ndpi_patricia_node_t *node;
1986 
1987   ndpi_fill_prefix_v4(&prefix, (struct in_addr *) addr, bits, tree->maxbits);
1988 
1989   node = ndpi_patricia_lookup(tree, &prefix);
1990   if(node) memset(&node->value, 0, sizeof(node->value));
1991 
1992   return(node);
1993 }
1994 
1995 /* ******************************************* */
1996 
1997 /*
1998   Load a file containing IPv4 addresses in CIDR format as 'protocol_id'
1999 
2000   Return: the number of entries loaded or -1 in case of error
2001 */
ndpi_load_ipv4_ptree(struct ndpi_detection_module_struct * ndpi_str,const char * path,u_int16_t protocol_id)2002 int ndpi_load_ipv4_ptree(struct ndpi_detection_module_struct *ndpi_str,
2003 			 const char *path, u_int16_t protocol_id) {
2004   char buffer[128], *line, *addr, *cidr, *saveptr;
2005   FILE *fd;
2006   int len;
2007   u_int num_loaded = 0;
2008 
2009   fd = fopen(path, "r");
2010 
2011   if(fd == NULL) {
2012     NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
2013     return(-1);
2014   }
2015 
2016   while(1) {
2017     line = fgets(buffer, sizeof(buffer), fd);
2018 
2019     if(line == NULL)
2020       break;
2021 
2022     len = strlen(line);
2023 
2024     if((len <= 1) || (line[0] == '#'))
2025       continue;
2026 
2027     line[len - 1] = '\0';
2028     addr = strtok_r(line, "/", &saveptr);
2029 
2030     if(addr) {
2031       struct in_addr pin;
2032       ndpi_patricia_node_t *node;
2033 
2034       cidr = strtok_r(NULL, "\n", &saveptr);
2035 
2036       pin.s_addr = inet_addr(addr);
2037       if((node = add_to_ptree(ndpi_str->protocols_ptree, AF_INET, &pin, cidr ? atoi(cidr) : 32 /* bits */)) != NULL) {
2038 	node->value.u.uv32.user_value = protocol_id, node->value.u.uv32.additional_user_value = 0 /* port */;
2039 	num_loaded++;
2040       }
2041     }
2042   }
2043 
2044   fclose(fd);
2045   return(num_loaded);
2046 }
2047 
2048 /* ******************************************* */
2049 
ndpi_init_ptree_ipv4(struct ndpi_detection_module_struct * ndpi_str,void * ptree,ndpi_network host_list[],u_int8_t skip_tor_hosts)2050 static void ndpi_init_ptree_ipv4(struct ndpi_detection_module_struct *ndpi_str,
2051 				 void *ptree, ndpi_network host_list[],
2052                                  u_int8_t skip_tor_hosts) {
2053   int i;
2054 
2055   for(i = 0; host_list[i].network != 0x0; i++) {
2056     struct in_addr pin;
2057     ndpi_patricia_node_t *node;
2058 
2059     if(skip_tor_hosts && (host_list[i].value == NDPI_PROTOCOL_TOR))
2060       continue;
2061 
2062     pin.s_addr = htonl(host_list[i].network);
2063     if((node = add_to_ptree(ptree, AF_INET, &pin, host_list[i].cidr /* bits */)) != NULL) {
2064       node->value.u.uv32.user_value = host_list[i].value, node->value.u.uv32.additional_user_value = 0;
2065     }
2066   }
2067 }
2068 
2069 /* ******************************************* */
2070 
ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct * ndpi_str,char * value,u_int16_t protocol_id)2071 static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
2072 					char *value, u_int16_t protocol_id) {
2073   ndpi_patricia_node_t *node;
2074   struct in_addr pin;
2075   int bits = 32;
2076   char *ptr = strrchr(value, '/');
2077   u_int16_t port = 0; /* Format ip:8.248.73.247:443 */
2078   char *double_column;
2079 
2080   if(ptr) {
2081     ptr[0] = '\0';
2082     ptr++;
2083 
2084     if((double_column = strrchr(ptr, ':')) != NULL) {
2085       double_column[0] = '\0';
2086       port = atoi(&double_column[1]);
2087     }
2088 
2089     if(atoi(ptr) >= 0 && atoi(ptr) <= 32)
2090       bits = atoi(ptr);
2091   } else {
2092     /*
2093       Let's check if there is the port defined
2094       Example: ip:8.248.73.247:443@AmazonPrime
2095     */
2096     double_column = strrchr(value, ':');
2097 
2098     if(double_column) {
2099       double_column[0] = '\0';
2100       port = atoi(&double_column[1]);
2101     }
2102   }
2103 
2104   inet_pton(AF_INET, value, &pin);
2105 
2106   if((node = add_to_ptree(ndpi_str->protocols_ptree, AF_INET, &pin, bits)) != NULL) {
2107     node->value.u.uv32.user_value = protocol_id, node->value.u.uv32.additional_user_value = htons(port);
2108   }
2109 
2110   return(0);
2111 }
2112 
set_ndpi_malloc(void * (* __ndpi_malloc)(size_t size))2113 void set_ndpi_malloc(void *(*__ndpi_malloc)(size_t size)) {
2114   _ndpi_malloc = __ndpi_malloc;
2115 }
set_ndpi_flow_malloc(void * (* __ndpi_flow_malloc)(size_t size))2116 void set_ndpi_flow_malloc(void *(*__ndpi_flow_malloc)(size_t size)) {
2117   _ndpi_flow_malloc = __ndpi_flow_malloc;
2118 }
2119 
set_ndpi_free(void (* __ndpi_free)(void * ptr))2120 void set_ndpi_free(void (*__ndpi_free)(void *ptr)) {
2121   _ndpi_free = __ndpi_free;
2122 }
set_ndpi_flow_free(void (* __ndpi_flow_free)(void * ptr))2123 void set_ndpi_flow_free(void (*__ndpi_flow_free)(void *ptr)) {
2124   _ndpi_flow_free = __ndpi_flow_free;
2125 }
2126 
ndpi_debug_printf(unsigned int proto,struct ndpi_detection_module_struct * ndpi_str,ndpi_log_level_t log_level,const char * file_name,const char * func_name,int line_number,const char * format,...)2127 void ndpi_debug_printf(unsigned int proto, struct ndpi_detection_module_struct *ndpi_str, ndpi_log_level_t log_level,
2128                        const char *file_name, const char *func_name, int line_number, const char *format, ...) {
2129 #ifdef NDPI_ENABLE_DEBUG_MESSAGES
2130   va_list args;
2131 #define MAX_STR_LEN 250
2132   char str[MAX_STR_LEN];
2133   if(ndpi_str != NULL && log_level > NDPI_LOG_ERROR && proto > 0 && proto < NDPI_MAX_SUPPORTED_PROTOCOLS &&
2134      !NDPI_ISSET(&ndpi_str->debug_bitmask, proto))
2135     return;
2136   va_start(args, format);
2137   vsnprintf(str, sizeof(str) - 1, format, args);
2138   va_end(args);
2139 
2140   if(ndpi_str != NULL) {
2141     printf("%s:%s:%-3d - [%s]: %s", file_name, func_name, line_number, ndpi_get_proto_name(ndpi_str, proto), str);
2142   } else {
2143     printf("Proto: %u, %s", proto, str);
2144   }
2145 #endif
2146 }
2147 
set_ndpi_debug_function(struct ndpi_detection_module_struct * ndpi_str,ndpi_debug_function_ptr ndpi_debug_printf)2148 void set_ndpi_debug_function(struct ndpi_detection_module_struct *ndpi_str, ndpi_debug_function_ptr ndpi_debug_printf) {
2149 #ifdef NDPI_ENABLE_DEBUG_MESSAGES
2150   ndpi_str->ndpi_debug_printf = ndpi_debug_printf;
2151 #endif
2152 }
2153 
2154 /* ****************************************** */
2155 
2156 /* Keep it in order and in sync with ndpi_protocol_category_t in ndpi_typedefs.h */
2157 static const char *categories[] = {
2158   "Unspecified",
2159   "Media",
2160   "VPN",
2161   "Email",
2162   "DataTransfer",
2163   "Web",
2164   "SocialNetwork",
2165   "Download",
2166   "Game",
2167   "Chat",
2168   "VoIP",
2169   "Database",
2170   "RemoteAccess",
2171   "Cloud",
2172   "Network",
2173   "Collaborative",
2174   "RPC",
2175   "Streaming",
2176   "System",
2177   "SoftwareUpdate",
2178   "",
2179   "",
2180   "",
2181   "",
2182   "",
2183   "Music",
2184   "Video",
2185   "Shopping",
2186   "Productivity",
2187   "FileSharing",
2188   "ConnCheck",
2189   "IoT-Scada",
2190   "VirtAssistant",
2191   "",
2192   "",
2193   "",
2194   "",
2195   "",
2196   "",
2197   "",
2198   "",
2199   "",
2200   "",
2201   "",
2202   "",
2203   "",
2204   "",
2205   "",
2206   "",
2207   "",
2208   "",
2209   "",
2210   "",
2211   "",
2212   "",
2213   "",
2214   "",
2215   "",
2216   "",
2217   "",
2218   "",
2219   "",
2220   "",
2221   "",
2222   "",
2223   "",
2224   "",
2225   "",
2226   "",
2227   "",
2228   "",
2229   "",
2230   "",
2231   "",
2232   "",
2233   "",
2234   "",
2235   "",
2236   "",
2237   "",
2238   "",
2239   "",
2240   "",
2241   "",
2242   "",
2243   "",
2244   "",
2245   "",
2246   "",
2247   "",
2248   "",
2249   "",
2250   "",
2251   "",
2252   "",
2253   "",
2254   "",
2255   "",
2256   "",
2257   "Mining", /* 99 */
2258   "Malware",
2259   "Advertisement",
2260   "Banned_Site",
2261   "Site_Unavailable",
2262   "Allowed_Site",
2263   "Antimalware",
2264 };
2265 
2266 /* ******************************************************************** */
2267 
2268 #ifdef TEST_LRU_HANDLER
test_lru_handler(ndpi_lru_cache_type cache_type,u_int32_t proto,u_int32_t app_proto)2269 void test_lru_handler(ndpi_lru_cache_type cache_type, u_int32_t proto, u_int32_t app_proto) {
2270 
2271   printf("[test_lru_handler] %u / %u / %u\n", cache_type, proto, app_proto);
2272 }
2273 #endif
2274 
2275 /* ******************************************************************** */
2276 
ndpi_init_detection_module(ndpi_init_prefs prefs)2277 struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs prefs) {
2278   struct ndpi_detection_module_struct *ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct));
2279   int i;
2280 
2281   if(ndpi_str == NULL) {
2282     /* Logging this error is a bit tricky. At this point, we can't use NDPI_LOG*
2283        functions yet, we don't have a custom log function and, as a library,
2284        we shouldn't use stdout/stderr. Since this error is quite unlikely,
2285        simply avoid any logs at all */
2286     return(NULL);
2287   }
2288 
2289   memset(ndpi_str, 0, sizeof(struct ndpi_detection_module_struct));
2290 
2291 #ifdef TEST_LRU_HANDLER
2292   ndpi_str->ndpi_notify_lru_add_handler_ptr = test_lru_handler;
2293 #endif
2294 
2295 #ifdef NDPI_ENABLE_DEBUG_MESSAGES
2296   set_ndpi_debug_function(ndpi_str, (ndpi_debug_function_ptr) ndpi_debug_printf);
2297   NDPI_BITMASK_RESET(ndpi_str->debug_bitmask);
2298 #endif /* NDPI_ENABLE_DEBUG_MESSAGES */
2299 
2300   if(prefs & ndpi_enable_ja3_plus)
2301     ndpi_str->enable_ja3_plus = 1;
2302 
2303 #ifdef HAVE_LIBGCRYPT
2304   if(!(prefs & ndpi_dont_init_libgcrypt)) {
2305     if(!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
2306       const char *gcrypt_ver = gcry_check_version(NULL);
2307       if(!gcrypt_ver) {
2308         NDPI_LOG_ERR(ndpi_str, "Error initializing libgcrypt\n");
2309         ndpi_free(ndpi_str);
2310         return NULL;
2311       }
2312       NDPI_LOG_DBG(ndpi_str, "Libgcrypt %s\n", gcrypt_ver);
2313       /* Tell Libgcrypt that initialization has completed. */
2314       gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
2315     }
2316   } else {
2317     NDPI_LOG_DBG(ndpi_str, "Libgcrypt initialization skipped\n");
2318   }
2319 #endif
2320 
2321   if((ndpi_str->protocols_ptree = ndpi_patricia_new(32 /* IPv4 */)) != NULL)
2322     ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, host_protocol_list, prefs & ndpi_dont_load_tor_hosts);
2323 
2324   ndpi_str->ip_risk_mask_ptree = ndpi_patricia_new(32 /* IPv4 */);
2325 
2326   NDPI_BITMASK_RESET(ndpi_str->detection_bitmask);
2327 #ifdef NDPI_ENABLE_DEBUG_MESSAGES
2328   ndpi_str->user_data = NULL;
2329 #endif
2330 
2331   ndpi_str->ticks_per_second = 1000; /* ndpi_str->ticks_per_second */
2332   ndpi_str->tcp_max_retransmission_window_size = NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE;
2333   ndpi_str->directconnect_connection_ip_tick_timeout =
2334     NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second;
2335 
2336   ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
2337   ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
2338   ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
2339   ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
2340   ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
2341   ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ndpi_str->ticks_per_second;
2342   ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ndpi_str->ticks_per_second;
2343   ndpi_str->soulseek_connection_ip_tick_timeout =
2344     NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second;
2345 
2346   ndpi_str->ndpi_num_supported_protocols = NDPI_MAX_SUPPORTED_PROTOCOLS;
2347   ndpi_str->ndpi_num_custom_protocols = 0;
2348 
2349   ndpi_str->host_automa.ac_automa = ac_automata_init(ac_domain_match_handler);
2350   ndpi_str->content_automa.ac_automa = ac_automata_init(ac_domain_match_handler);
2351   ndpi_str->host_risk_mask_automa.ac_automa = ac_automata_init(ac_domain_match_handler);
2352   ndpi_str->common_alpns_automa.ac_automa = ac_automata_init(ac_domain_match_handler);
2353   load_common_alpns(ndpi_str);
2354   ndpi_str->tls_cert_subject_automa.ac_automa = ac_automata_init(NULL);
2355   ndpi_str->malicious_ja3_automa.ac_automa = NULL; /* Initialized on demand */
2356   ndpi_str->malicious_sha1_automa.ac_automa = NULL; /* Initialized on demand */
2357   ndpi_str->risky_domain_automa.ac_automa = NULL; /* Initialized on demand */
2358 
2359   if((sizeof(categories) / sizeof(char *)) != NDPI_PROTOCOL_NUM_CATEGORIES) {
2360     NDPI_LOG_ERR(ndpi_str, "[NDPI] invalid categories length: expected %u, got %u\n", NDPI_PROTOCOL_NUM_CATEGORIES,
2361 		 (unsigned int) (sizeof(categories) / sizeof(char *)));
2362     return(NULL);
2363   }
2364 
2365   ndpi_str->custom_categories.hostnames.ac_automa = ac_automata_init(ac_domain_match_handler);
2366   ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_domain_match_handler);
2367 
2368   ndpi_str->custom_categories.ipAddresses = ndpi_patricia_new(32 /* IPv4 */);
2369   ndpi_str->custom_categories.ipAddresses_shadow = ndpi_patricia_new(32 /* IPv4 */);
2370 
2371   if(ndpi_str->host_automa.ac_automa)
2372     ac_automata_feature(ndpi_str->host_automa.ac_automa,AC_FEATURE_LC);
2373 
2374   if(ndpi_str->custom_categories.hostnames.ac_automa)
2375     ac_automata_feature(ndpi_str->custom_categories.hostnames.ac_automa,AC_FEATURE_LC);
2376 
2377   if(ndpi_str->custom_categories.hostnames_shadow.ac_automa)
2378     ac_automata_feature(ndpi_str->custom_categories.hostnames_shadow.ac_automa,AC_FEATURE_LC);
2379 
2380   if(ndpi_str->tls_cert_subject_automa.ac_automa)
2381     ac_automata_feature(ndpi_str->tls_cert_subject_automa.ac_automa,AC_FEATURE_LC);
2382 
2383   if(ndpi_str->content_automa.ac_automa)
2384     ac_automata_feature(ndpi_str->content_automa.ac_automa,AC_FEATURE_LC);
2385 
2386   if(ndpi_str->host_risk_mask_automa.ac_automa)
2387     ac_automata_feature(ndpi_str->host_risk_mask_automa.ac_automa,AC_FEATURE_LC);
2388 
2389   if(ndpi_str->common_alpns_automa.ac_automa)
2390     ac_automata_feature(ndpi_str->common_alpns_automa.ac_automa,AC_FEATURE_LC);
2391 
2392   /* ahocorasick debug */
2393   /* Needed ac_automata_enable_debug(1) for show debug */
2394   if(ndpi_str->host_automa.ac_automa)
2395     ac_automata_name(ndpi_str->host_automa.ac_automa,"host",AC_FEATURE_DEBUG);
2396 
2397   if(ndpi_str->custom_categories.hostnames.ac_automa)
2398     ac_automata_name(ndpi_str->custom_categories.hostnames.ac_automa,"ccat",0);
2399 
2400   if(ndpi_str->custom_categories.hostnames_shadow.ac_automa)
2401     ac_automata_name(ndpi_str->custom_categories.hostnames_shadow.ac_automa,"ccat_sh",0);
2402 
2403   if(ndpi_str->tls_cert_subject_automa.ac_automa)
2404     ac_automata_name(ndpi_str->tls_cert_subject_automa.ac_automa,"tls_cert",AC_FEATURE_DEBUG);
2405 
2406   if(ndpi_str->content_automa.ac_automa)
2407     ac_automata_name(ndpi_str->content_automa.ac_automa,"content",AC_FEATURE_DEBUG);
2408 
2409   if(ndpi_str->host_risk_mask_automa.ac_automa)
2410     ac_automata_name(ndpi_str->host_risk_mask_automa.ac_automa,"content",AC_FEATURE_DEBUG);
2411 
2412   if(ndpi_str->common_alpns_automa.ac_automa)
2413     ac_automata_name(ndpi_str->common_alpns_automa.ac_automa,"content",AC_FEATURE_DEBUG);
2414 
2415   if((ndpi_str->custom_categories.ipAddresses == NULL) || (ndpi_str->custom_categories.ipAddresses_shadow == NULL)) {
2416     NDPI_LOG_ERR(ndpi_str, "[NDPI] Error allocating Patricia trees\n");
2417     return(NULL);
2418   }
2419 
2420   ndpi_init_protocol_defaults(ndpi_str);
2421 
2422   for(i = 0; i < NUM_CUSTOM_CATEGORIES; i++)
2423     snprintf(ndpi_str->custom_category_labels[i], CUSTOM_CATEGORY_LABEL_LEN, "User custom category %u",
2424 	     (unsigned int) (i + 1));
2425 
2426   return(ndpi_str);
2427 }
2428 
2429 /* *********************************************** */
2430 
ndpi_finalize_initialization(struct ndpi_detection_module_struct * ndpi_str)2431 void ndpi_finalize_initialization(struct ndpi_detection_module_struct *ndpi_str) {
2432   u_int i;
2433 
2434   if(ndpi_str->ac_automa_finalized) return;
2435 
2436   for(i = 0; i < 99; i++) {
2437     ndpi_automa *automa;
2438 
2439     switch(i) {
2440     case 0:
2441       automa = &ndpi_str->host_automa;
2442       break;
2443 
2444     case 1:
2445       automa = &ndpi_str->content_automa;
2446       break;
2447 
2448     case 2:
2449       automa = &ndpi_str->tls_cert_subject_automa;
2450       break;
2451 
2452     case 3:
2453       automa = &ndpi_str->malicious_ja3_automa;
2454       break;
2455 
2456     case 4:
2457       automa = &ndpi_str->malicious_sha1_automa;
2458       break;
2459 
2460     case 5:
2461       automa = &ndpi_str->host_risk_mask_automa;
2462       break;
2463 
2464     case 6:
2465       automa = &ndpi_str->common_alpns_automa;
2466       break;
2467 
2468     default:
2469       ndpi_str->ac_automa_finalized = 1;
2470       return;
2471     }
2472 
2473     if(automa && automa->ac_automa)
2474       ac_automata_finalize((AC_AUTOMATA_t *) automa->ac_automa);
2475   }
2476 }
2477 
2478 /* *********************************************** */
2479 
2480 /* Wrappers */
ndpi_init_automa(void)2481 void *ndpi_init_automa(void) {
2482   return(ac_automata_init(ac_domain_match_handler));
2483 }
2484 
2485 /* ****************************************************** */
2486 
ndpi_add_string_value_to_automa(void * _automa,char * str,u_int32_t num)2487 int ndpi_add_string_value_to_automa(void *_automa, char *str, u_int32_t num) {
2488   AC_PATTERN_t ac_pattern;
2489   AC_AUTOMATA_t *automa = (AC_AUTOMATA_t *) _automa;
2490   AC_ERROR_t rc;
2491 
2492   if(automa == NULL)
2493     return(-1);
2494 
2495   memset(&ac_pattern, 0, sizeof(ac_pattern));
2496   ac_pattern.astring    = str;
2497   ac_pattern.rep.number = num;
2498   ac_pattern.length     = strlen(ac_pattern.astring);
2499 
2500   rc = ac_automata_add(automa, &ac_pattern);
2501   return(rc == ACERR_SUCCESS || rc == ACERR_DUPLICATE_PATTERN ? 0 : -1);
2502 }
2503 
2504 /* ****************************************************** */
2505 
ndpi_add_string_to_automa(void * _automa,char * str)2506 int ndpi_add_string_to_automa(void *_automa, char *str) {
2507   return(ndpi_add_string_value_to_automa(_automa, str, 1));
2508 }
2509 
2510 /* ****************************************************** */
2511 
ndpi_free_automa(void * _automa)2512 void ndpi_free_automa(void *_automa) {
2513   ac_automata_release((AC_AUTOMATA_t *) _automa, 1);
2514 }
2515 
2516 /* ****************************************************** */
2517 
ndpi_finalize_automa(void * _automa)2518 void ndpi_finalize_automa(void *_automa) {
2519   ac_automata_finalize((AC_AUTOMATA_t *) _automa);
2520 }
2521 
2522 /* ****************************************************** */
2523 
ndpi_match_string_common(AC_AUTOMATA_t * automa,char * string_to_match,size_t string_len,u_int32_t * protocol_id,ndpi_protocol_category_t * category,ndpi_protocol_breed_t * breed)2524 static int ndpi_match_string_common(AC_AUTOMATA_t *automa, char *string_to_match,size_t string_len,
2525 				    u_int32_t *protocol_id, ndpi_protocol_category_t *category,
2526 				    ndpi_protocol_breed_t *breed) {
2527   AC_REP_t match = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED };
2528   AC_TEXT_t ac_input_text;
2529   int rc;
2530 
2531   if(protocol_id) *protocol_id = NDPI_PROTOCOL_UNKNOWN;
2532 
2533   if((automa == NULL) || (string_to_match == NULL) || (string_to_match[0] == '\0')) {
2534     return(-2);
2535   }
2536 
2537   if(automa->automata_open) {
2538     printf("[%s:%d] [NDPI] Internal error: please call ndpi_finalize_initialization()\n", __FILE__, __LINE__);
2539     return(-1);
2540   }
2541 
2542   ac_input_text.astring = string_to_match, ac_input_text.length = string_len;
2543   ac_input_text.option = 0;
2544   rc = ac_automata_search(automa, &ac_input_text, &match);
2545 
2546   if(protocol_id)
2547     *protocol_id = rc ? match.number : NDPI_PROTOCOL_UNKNOWN;
2548 
2549   if(category)
2550     *category = rc ? match.category : 0;
2551 
2552   if(breed)
2553     *breed = rc ? match.breed : 0;
2554 
2555   return rc;
2556 }
2557 
2558 /* ****************************************************** */
2559 
ndpi_match_string(void * _automa,char * string_to_match)2560 int ndpi_match_string(void *_automa, char *string_to_match) {
2561   uint32_t proto_id;
2562   int rc;
2563 
2564   if(!string_to_match)
2565     return(-2);
2566 
2567   rc = ndpi_match_string_common(_automa, string_to_match,
2568 				strlen(string_to_match),
2569 				&proto_id, NULL, NULL);
2570   if(rc < 0) return rc;
2571 
2572   return rc ? proto_id : NDPI_PROTOCOL_UNKNOWN;
2573 }
2574 
2575 /* ****************************************************** */
2576 
ndpi_match_string_protocol_id(void * automa,char * string_to_match,u_int match_len,u_int16_t * protocol_id,ndpi_protocol_category_t * category,ndpi_protocol_breed_t * breed)2577 int ndpi_match_string_protocol_id(void *automa, char *string_to_match,
2578 				  u_int match_len, u_int16_t *protocol_id,
2579 				  ndpi_protocol_category_t *category,
2580 				  ndpi_protocol_breed_t *breed) {
2581   u_int32_t proto_id;
2582   int rc = ndpi_match_string_common((AC_AUTOMATA_t*)automa, string_to_match,
2583 				    match_len, &proto_id, category, breed);
2584   if(rc < 0) return rc;
2585   *protocol_id = (u_int16_t)proto_id;
2586   return(proto_id != NDPI_PROTOCOL_UNKNOWN ? 0 : -1);
2587 }
2588 
2589 /* ****************************************************** */
2590 
ndpi_match_string_value(void * automa,char * string_to_match,u_int match_len,u_int32_t * num)2591 int ndpi_match_string_value(void *automa, char *string_to_match,
2592 			    u_int match_len, u_int32_t *num) {
2593 
2594   int rc = ndpi_match_string_common((AC_AUTOMATA_t *)automa, string_to_match,
2595 				    match_len, num, NULL, NULL);
2596   if(rc < 0) return rc;
2597   return rc ? 0 : -1;
2598 }
2599 
2600 
2601 /* *********************************************** */
2602 
ndpi_match_custom_category(struct ndpi_detection_module_struct * ndpi_str,char * name,u_int name_len,ndpi_protocol_category_t * category)2603 int ndpi_match_custom_category(struct ndpi_detection_module_struct *ndpi_str,
2604 			       char *name, u_int name_len,
2605                                ndpi_protocol_category_t *category) {
2606   u_int32_t id;
2607   int rc = ndpi_match_string_common(ndpi_str->custom_categories.hostnames.ac_automa,
2608 				    name, name_len, &id, category, NULL);
2609   if(rc < 0) return rc;
2610   return(id != NDPI_PROTOCOL_UNKNOWN ? 0 : -1);
2611 }
2612 
2613 /* *********************************************** */
2614 
ndpi_get_custom_category_match(struct ndpi_detection_module_struct * ndpi_str,char * name_or_ip,u_int name_len,ndpi_protocol_category_t * id)2615 int ndpi_get_custom_category_match(struct ndpi_detection_module_struct *ndpi_str,
2616 				   char *name_or_ip, u_int name_len,
2617 				   ndpi_protocol_category_t *id) {
2618   char ipbuf[64], *ptr;
2619   struct in_addr pin;
2620   u_int cp_len = ndpi_min(sizeof(ipbuf) - 1, name_len);
2621 
2622   if(!ndpi_str->custom_categories.categories_loaded)
2623     return(-1);
2624 
2625   if(cp_len > 0) {
2626     memcpy(ipbuf, name_or_ip, cp_len);
2627     ipbuf[cp_len] = '\0';
2628   } else
2629     ipbuf[0] = '\0';
2630 
2631   ptr = strrchr(ipbuf, '/');
2632 
2633   if(ptr)
2634     ptr[0] = '\0';
2635 
2636   if(inet_pton(AF_INET, ipbuf, &pin) == 1) {
2637     /* Search IP */
2638     ndpi_prefix_t prefix;
2639     ndpi_patricia_node_t *node;
2640 
2641     /* Make sure all in network byte order otherwise compares wont work */
2642     ndpi_fill_prefix_v4(&prefix, &pin, 32, ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
2643     node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
2644 
2645     if(node) {
2646       *id = node->value.u.uv32.user_value;
2647 
2648       return(0);
2649     }
2650 
2651     return(-1);
2652   } else {
2653     /* Search Host */
2654     return(ndpi_match_custom_category(ndpi_str, name_or_ip, name_len, id));
2655   }
2656 }
2657 
2658 /* *********************************************** */
2659 
free_ptree_data(void * data)2660 static void free_ptree_data(void *data) {
2661   ;
2662 }
2663 
2664 /* ****************************************************** */
2665 
ndpi_exit_detection_module(struct ndpi_detection_module_struct * ndpi_str)2666 void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_str) {
2667   if(ndpi_str != NULL) {
2668     int i;
2669 
2670     for (i = 0; i < (NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS); i++) {
2671       if (ndpi_str->proto_defaults[i].protoName)
2672         ndpi_free(ndpi_str->proto_defaults[i].protoName);
2673       if (ndpi_str->proto_defaults[i].subprotocols != NULL)
2674         ndpi_free(ndpi_str->proto_defaults[i].subprotocols);
2675     }
2676 
2677     /* NDPI_PROTOCOL_TINC */
2678     if(ndpi_str->tinc_cache)
2679       cache_free((cache_t)(ndpi_str->tinc_cache));
2680 
2681     if(ndpi_str->ookla_cache)
2682       ndpi_lru_free_cache(ndpi_str->ookla_cache);
2683 
2684     if(ndpi_str->stun_cache)
2685       ndpi_lru_free_cache(ndpi_str->stun_cache);
2686 
2687     if(ndpi_str->tls_cert_cache)
2688       ndpi_lru_free_cache(ndpi_str->tls_cert_cache);
2689 
2690     if(ndpi_str->mining_cache)
2691       ndpi_lru_free_cache(ndpi_str->mining_cache);
2692 
2693     if(ndpi_str->msteams_cache)
2694       ndpi_lru_free_cache(ndpi_str->msteams_cache);
2695 
2696     if(ndpi_str->protocols_ptree)
2697       ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree, free_ptree_data);
2698 
2699     if(ndpi_str->ip_risk_mask_ptree)
2700       ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->ip_risk_mask_ptree, free_ptree_data);
2701 
2702     if(ndpi_str->udpRoot != NULL)
2703       ndpi_tdestroy(ndpi_str->udpRoot, ndpi_free);
2704     if(ndpi_str->tcpRoot != NULL)
2705       ndpi_tdestroy(ndpi_str->tcpRoot, ndpi_free);
2706 
2707     if(ndpi_str->host_automa.ac_automa != NULL)
2708       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->host_automa.ac_automa,
2709 			  1 /* free patterns strings memory */);
2710 
2711     if(ndpi_str->content_automa.ac_automa != NULL)
2712       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->content_automa.ac_automa, 0);
2713 
2714     if(ndpi_str->risky_domain_automa.ac_automa != NULL)
2715       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->risky_domain_automa.ac_automa,
2716                           1 /* free patterns strings memory */);
2717 
2718     if(ndpi_str->tls_cert_subject_automa.ac_automa != NULL)
2719       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->tls_cert_subject_automa.ac_automa, 0);
2720 
2721     if(ndpi_str->malicious_ja3_automa.ac_automa != NULL)
2722       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->malicious_ja3_automa.ac_automa,
2723                           1 /* free patterns strings memory */);
2724 
2725     if(ndpi_str->malicious_sha1_automa.ac_automa != NULL)
2726       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->malicious_sha1_automa.ac_automa,
2727 			  1 /* free patterns strings memory */);
2728 
2729     if(ndpi_str->custom_categories.hostnames.ac_automa != NULL)
2730       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
2731 			  1 /* free patterns strings memory */);
2732 
2733     if(ndpi_str->custom_categories.hostnames_shadow.ac_automa != NULL)
2734       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames_shadow.ac_automa,
2735 			  1 /* free patterns strings memory */);
2736 
2737     if(ndpi_str->custom_categories.ipAddresses != NULL)
2738       ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->custom_categories.ipAddresses, free_ptree_data);
2739 
2740     if(ndpi_str->custom_categories.ipAddresses_shadow != NULL)
2741       ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->custom_categories.ipAddresses_shadow, free_ptree_data);
2742 
2743     if(ndpi_str->host_risk_mask_automa.ac_automa != NULL)
2744       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->host_risk_mask_automa.ac_automa,
2745 			  1 /* free patterns strings memory */);
2746 
2747     if(ndpi_str->common_alpns_automa.ac_automa != NULL)
2748       ac_automata_release((AC_AUTOMATA_t *) ndpi_str->common_alpns_automa.ac_automa,
2749 			  1 /* free patterns strings memory */);
2750 
2751 #ifdef CUSTOM_NDPI_PROTOCOLS
2752 #include "../../../nDPI-custom/ndpi_exit_detection_module.c"
2753 #endif
2754 
2755     ndpi_free_geoip(ndpi_str);
2756 
2757     ndpi_free(ndpi_str);
2758   }
2759 }
2760 
2761 /* ****************************************************** */
2762 
ndpi_get_guessed_protocol_id(struct ndpi_detection_module_struct * ndpi_str,u_int8_t proto,u_int16_t sport,u_int16_t dport)2763 static ndpi_default_ports_tree_node_t *ndpi_get_guessed_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
2764                                                                     u_int8_t proto, u_int16_t sport, u_int16_t dport) {
2765   ndpi_default_ports_tree_node_t node;
2766 
2767   if(sport && dport) {
2768     int low = ndpi_min(sport, dport);
2769     int high = ndpi_max(sport, dport);
2770     const void *ret;
2771 
2772     node.default_port = low; /* Check server port first */
2773     ret = ndpi_tfind(&node, (proto == IPPROTO_TCP) ? (void *) &ndpi_str->tcpRoot : (void *) &ndpi_str->udpRoot,
2774 		     ndpi_default_ports_tree_node_t_cmp);
2775 
2776     if(ret == NULL) {
2777       node.default_port = high;
2778       ret = ndpi_tfind(&node, (proto == IPPROTO_TCP) ? (void *) &ndpi_str->tcpRoot : (void *) &ndpi_str->udpRoot,
2779 		       ndpi_default_ports_tree_node_t_cmp);
2780     }
2781 
2782     if(ret)
2783       return(*(ndpi_default_ports_tree_node_t **) ret);
2784   }
2785 
2786   return(NULL);
2787 }
2788 
2789 /* ****************************************************** */
2790 
2791 /*
2792   These are UDP protocols that must fit a single packet
2793   and thus that if have NOT been detected they cannot be guessed
2794   as they have been excluded
2795 */
is_udp_guessable_protocol(u_int16_t l7_guessed_proto)2796 u_int8_t is_udp_guessable_protocol(u_int16_t l7_guessed_proto) {
2797   switch(l7_guessed_proto) {
2798   case NDPI_PROTOCOL_QUIC:
2799   case NDPI_PROTOCOL_SNMP:
2800   case NDPI_PROTOCOL_NETFLOW:
2801     /* TODO: add more protocols (if any missing) */
2802     return(1);
2803   }
2804 
2805   return(0);
2806 }
2807 
2808 /* ****************************************************** */
2809 
ndpi_guess_protocol_id(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,u_int8_t proto,u_int16_t sport,u_int16_t dport,u_int8_t * user_defined_proto)2810 u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
2811                                  u_int8_t proto, u_int16_t sport, u_int16_t dport, u_int8_t *user_defined_proto) {
2812   *user_defined_proto = 0; /* Default */
2813 
2814   if(sport && dport) {
2815     ndpi_default_ports_tree_node_t *found = ndpi_get_guessed_protocol_id(ndpi_str, proto, sport, dport);
2816 
2817     if(found != NULL) {
2818       u_int16_t guessed_proto = found->proto->protoId;
2819 
2820       /* We need to check if the guessed protocol isn't excluded by nDPI */
2821       if(flow && (proto == IPPROTO_UDP) &&
2822 	 NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, guessed_proto) &&
2823 	 is_udp_guessable_protocol(guessed_proto))
2824 	return(NDPI_PROTOCOL_UNKNOWN);
2825       else {
2826 	*user_defined_proto = found->customUserProto;
2827 	return(guessed_proto);
2828       }
2829     }
2830   } else {
2831     /* No TCP/UDP */
2832 
2833     switch(proto) {
2834     case NDPI_IPSEC_PROTOCOL_ESP:
2835     case NDPI_IPSEC_PROTOCOL_AH:
2836       return(NDPI_PROTOCOL_IP_IPSEC);
2837       break;
2838     case NDPI_GRE_PROTOCOL_TYPE:
2839       return(NDPI_PROTOCOL_IP_GRE);
2840       break;
2841     case NDPI_ICMP_PROTOCOL_TYPE:
2842       if(flow) {
2843 	/* Run some basic consistency tests */
2844 
2845 	if(flow->packet.payload_packet_len < sizeof(struct ndpi_icmphdr))
2846 	  ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET);
2847 	else {
2848 	  u_int8_t icmp_type = (u_int8_t)flow->packet.payload[0];
2849 	  u_int8_t icmp_code = (u_int8_t)flow->packet.payload[1];
2850 
2851 	  /* https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml */
2852 	  if(((icmp_type >= 44) && (icmp_type <= 252))
2853 	     || (icmp_code > 15))
2854 	    ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET);
2855 	}
2856       }
2857       return(NDPI_PROTOCOL_IP_ICMP);
2858       break;
2859     case NDPI_IGMP_PROTOCOL_TYPE:
2860       return(NDPI_PROTOCOL_IP_IGMP);
2861       break;
2862     case NDPI_EGP_PROTOCOL_TYPE:
2863       return(NDPI_PROTOCOL_IP_EGP);
2864       break;
2865     case NDPI_SCTP_PROTOCOL_TYPE:
2866       return(NDPI_PROTOCOL_IP_SCTP);
2867       break;
2868     case NDPI_OSPF_PROTOCOL_TYPE:
2869       return(NDPI_PROTOCOL_IP_OSPF);
2870       break;
2871     case NDPI_IPIP_PROTOCOL_TYPE:
2872       return(NDPI_PROTOCOL_IP_IP_IN_IP);
2873       break;
2874     case NDPI_ICMPV6_PROTOCOL_TYPE:
2875       if(flow) {
2876 	/* Run some basic consistency tests */
2877 
2878 	if(flow->packet.payload_packet_len < sizeof(struct ndpi_icmphdr))
2879 	  ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET);
2880 	else {
2881 	  u_int8_t icmp6_type = (u_int8_t)flow->packet.payload[0];
2882 	  u_int8_t icmp6_code = (u_int8_t)flow->packet.payload[1];
2883 
2884 	  /* https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol_for_IPv6 */
2885 	  if(((icmp6_type >= 5) && (icmp6_type <= 127))
2886 	     || (icmp6_type >= 156)
2887 	     || ((icmp6_code > 7) && (icmp6_type != 255)))
2888 	    ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET);
2889 	}
2890       }
2891       return(NDPI_PROTOCOL_IP_ICMPV6);
2892       break;
2893     case 112:
2894       return(NDPI_PROTOCOL_IP_VRRP);
2895       break;
2896     }
2897   }
2898 
2899   return(NDPI_PROTOCOL_UNKNOWN);
2900 }
2901 
2902 /* ******************************************************************** */
2903 
ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct * ndpi_str)2904 u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_str) {
2905   return(ndpi_str->ndpi_num_supported_protocols);
2906 }
2907 
2908 /* ******************************************************************** */
2909 
2910 #ifdef WIN32
strsep(char ** sp,char * sep)2911 char *strsep(char **sp, char *sep) {
2912   char *p, *s;
2913   if(sp == NULL || *sp == NULL || **sp == '\0')
2914     return(NULL);
2915   s = *sp;
2916   p = s + strcspn(s, sep);
2917   if(*p != '\0')
2918     *p++ = '\0';
2919   *sp = p;
2920   return(s);
2921 }
2922 #endif
2923 
2924 /* ******************************************************************** */
2925 
ndpi_add_ip_risk_mask(struct ndpi_detection_module_struct * ndpi_str,char * ip,ndpi_risk mask)2926 int ndpi_add_ip_risk_mask(struct ndpi_detection_module_struct *ndpi_str,
2927 			  char *ip, ndpi_risk mask) {
2928   char *saveptr, *addr = strtok_r(ip, "/", &saveptr);
2929 
2930   if(addr) {
2931     char *cidr = strtok_r(NULL, "\n", &saveptr);
2932     struct in_addr pin;
2933     ndpi_patricia_node_t *node;
2934 
2935     pin.s_addr = inet_addr(addr);
2936     /* FIX: Add IPv6 support */
2937     if((node = add_to_ptree(ndpi_str->ip_risk_mask_ptree, AF_INET,
2938 			    &pin, cidr ? atoi(cidr) : 32 /* bits */)) != NULL) {
2939       node->value.u.uv64 = (u_int64_t)mask;
2940       return(0);
2941     } else
2942       return(-1);
2943   } else
2944     return(-2);
2945 }
2946 
2947 /* ******************************************************************** */
2948 
ndpi_add_host_risk_mask(struct ndpi_detection_module_struct * ndpi_str,char * host,ndpi_risk mask)2949 int ndpi_add_host_risk_mask(struct ndpi_detection_module_struct *ndpi_str,
2950 			    char *host, ndpi_risk mask) {
2951   AC_PATTERN_t ac_pattern;
2952   AC_ERROR_t rc;
2953   u_int len;
2954   char *host_dup = NULL;
2955 
2956   if((ndpi_str->host_risk_mask_automa.ac_automa == NULL) || (host == NULL))
2957     return(-2);
2958 
2959   /* Zap heading/trailing quotes */
2960   switch(host[0]) {
2961   case '"':
2962   case '\'':
2963     {
2964       int len;
2965 
2966       host = &host[1];
2967       len = strlen(host);
2968       if(len > 0)
2969 	host[len-1] = '\0';
2970     }
2971 
2972     break;
2973   }
2974 
2975   host_dup = ndpi_strdup(host);
2976   if(!host_dup)
2977     return(-1);
2978 
2979   memset(&ac_pattern, 0, sizeof(ac_pattern));
2980 
2981   len = strlen(host);
2982 
2983   ac_pattern.astring      = host_dup;
2984   ac_pattern.length       = len;
2985   ac_pattern.rep.number64 = (ndpi_risk)mask;
2986   ac_pattern.rep.level    = ndpi_domain_level(host);
2987   ac_pattern.rep.at_end   = 0;
2988   ac_pattern.rep.dot      = memchr(host,'.',len) != NULL;
2989 
2990   rc = ac_automata_add(ndpi_str->host_risk_mask_automa.ac_automa, &ac_pattern);
2991 
2992   if(rc != ACERR_SUCCESS) {
2993     ndpi_free(host_dup);
2994 
2995     if(rc != ACERR_DUPLICATE_PATTERN)
2996       return (-2);
2997   }
2998 
2999   return(0);
3000 }
3001 
3002 /* ******************************************************************** */
3003 
ndpi_handle_rule(struct ndpi_detection_module_struct * ndpi_str,char * rule,u_int8_t do_add)3004 int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, char *rule, u_int8_t do_add) {
3005   char *at, *proto, *elem;
3006   ndpi_proto_defaults_t *def;
3007   u_int16_t subprotocol_id, i;
3008 
3009   at = strrchr(rule, '@');
3010   if(at == NULL) {
3011     /* This looks like a mask rule or an invalid rule */
3012     char _rule[256], *rule_type, *key;
3013 
3014     snprintf(_rule, sizeof(_rule), "%s", rule);
3015     rule_type = strtok(rule, ":");
3016 
3017     if(!rule_type) {
3018       NDPI_LOG_ERR(ndpi_str, "Invalid rule '%s'\n", rule);
3019       return(-1);
3020     }
3021 
3022     key = strtok(NULL, "=");
3023 
3024     if(key) {
3025       char *mask = strtok(NULL, "=");
3026 
3027       if(mask) {
3028 	ndpi_risk risk_mask = (ndpi_risk)atoll(mask);
3029 
3030 	if(!strcmp(rule_type, "ip_risk_mask")) {
3031 	  return(ndpi_add_ip_risk_mask(ndpi_str, key, risk_mask));
3032 	} else if(!strcmp(rule_type, "host_risk_mask")) {
3033 	  return(ndpi_add_host_risk_mask(ndpi_str, key, risk_mask));
3034 	}
3035       }
3036     }
3037 
3038     NDPI_LOG_ERR(ndpi_str, "Unknown rule '%s'\n", rule);
3039     return(-1);
3040   } else
3041     at[0] = 0, proto = &at[1];
3042 
3043   for(i = 0; proto[i] != '\0'; i++) {
3044     switch(proto[i]) {
3045     case '/':
3046     case '&':
3047     case '^':
3048     case ':':
3049     case ';':
3050     case '\'':
3051     case '"':
3052     case ' ':
3053       proto[i] = '_';
3054       break;
3055     }
3056   }
3057 
3058   for(i = 0, def = NULL; i < (int) ndpi_str->ndpi_num_supported_protocols; i++) {
3059     if(ndpi_str->proto_defaults[i].protoName
3060        && strcasecmp(ndpi_str->proto_defaults[i].protoName, proto) == 0) {
3061       def = &ndpi_str->proto_defaults[i];
3062       subprotocol_id = i;
3063       break;
3064     }
3065   }
3066 
3067   if(def == NULL) {
3068     if(!do_add) {
3069       /* We need to remove a rule */
3070       NDPI_LOG_ERR(ndpi_str, "Unable to find protocol '%s': skipping rule '%s'\n", proto, rule);
3071       return(-3);
3072     } else {
3073       ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS];
3074 
3075       if(ndpi_str->ndpi_num_custom_protocols >= (NDPI_MAX_NUM_CUSTOM_PROTOCOLS - 1)) {
3076 	NDPI_LOG_ERR(ndpi_str, "Too many protocols defined (%u): skipping protocol %s\n",
3077 		     ndpi_str->ndpi_num_custom_protocols, proto);
3078 	return(-2);
3079       }
3080 
3081       ndpi_set_proto_defaults(ndpi_str, 1, NDPI_PROTOCOL_ACCEPTABLE,
3082 			      ndpi_str->ndpi_num_supported_protocols, proto,
3083 			      NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, /* TODO add protocol category support in rules */
3084 			      ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
3085 			      ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
3086       def = &ndpi_str->proto_defaults[ndpi_str->ndpi_num_supported_protocols];
3087       subprotocol_id = ndpi_str->ndpi_num_supported_protocols;
3088       ndpi_str->ndpi_num_supported_protocols++, ndpi_str->ndpi_num_custom_protocols++;
3089     }
3090   }
3091 
3092   while((elem = strsep(&rule, ",")) != NULL) {
3093     char *attr = elem, *value = NULL;
3094     ndpi_port_range range;
3095     int is_tcp = 0, is_udp = 0, is_ip = 0;
3096 
3097     if(strncmp(attr, "tcp:", 4) == 0)
3098       is_tcp = 1, value = &attr[4];
3099     else if(strncmp(attr, "udp:", 4) == 0)
3100       is_udp = 1, value = &attr[4];
3101     else if(strncmp(attr, "ip:", 3) == 0)
3102       is_ip = 1, value = &attr[3];
3103     else if(strncmp(attr, "host:", 5) == 0) {
3104       /* host:"<value>",host:"<value>",.....@<subproto> */
3105       u_int i, max_len;
3106 
3107       value = &attr[5];
3108       if(value[0] == '"')
3109 	value++; /* remove leading " */
3110 
3111       max_len = strlen(value) - 1;
3112       if(value[max_len] == '"')
3113 	value[max_len] = '\0'; /* remove trailing " */
3114 
3115       for(i=0; i<max_len; i++) value[i] = tolower(value[i]);
3116     }
3117 
3118     if(is_tcp || is_udp) {
3119       u_int p_low, p_high;
3120 
3121       if(sscanf(value, "%u-%u", &p_low, &p_high) == 2)
3122 	range.port_low = p_low, range.port_high = p_high;
3123       else
3124 	range.port_low = range.port_high = atoi(&elem[4]);
3125 
3126       if(do_add)
3127 	addDefaultPort(ndpi_str, &range, def, 1 /* Custom user proto */,
3128 		       is_tcp ? &ndpi_str->tcpRoot : &ndpi_str->udpRoot, __FUNCTION__, __LINE__);
3129       else
3130 	removeDefaultPort(&range, def, is_tcp ? &ndpi_str->tcpRoot : &ndpi_str->udpRoot);
3131     } else if(is_ip) {
3132       /* NDPI_PROTOCOL_TOR */
3133       ndpi_add_host_ip_subprotocol(ndpi_str, value, subprotocol_id);
3134     } else {
3135       if(do_add)
3136 	ndpi_add_host_url_subprotocol(ndpi_str, value, subprotocol_id, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
3137 				      NDPI_PROTOCOL_ACCEPTABLE, 0);
3138       else
3139 	ndpi_remove_host_url_subprotocol(ndpi_str, value, subprotocol_id);
3140     }
3141   }
3142 
3143   return(0);
3144 }
3145 
3146 /* ******************************************************************** */
3147 
3148 /*
3149  * Format:
3150  *
3151  * <host|ip>	<category_id>
3152  *
3153  * Notes:
3154  *  - host and category are separated by a single TAB
3155  *  - empty lines or lines starting with # are ignored
3156  */
ndpi_load_categories_file(struct ndpi_detection_module_struct * ndpi_str,const char * path)3157 int ndpi_load_categories_file(struct ndpi_detection_module_struct *ndpi_str, const char *path) {
3158   char buffer[512], *line, *name, *category, *saveptr;
3159   FILE *fd;
3160   int len, num = 0;
3161 
3162   fd = fopen(path, "r");
3163 
3164   if(fd == NULL) {
3165     NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
3166     return(-1);
3167   }
3168 
3169   while(1) {
3170     line = fgets(buffer, sizeof(buffer), fd);
3171 
3172     if(line == NULL)
3173       break;
3174 
3175     len = strlen(line);
3176 
3177     if((len <= 1) || (line[0] == '#'))
3178       continue;
3179 
3180     line[len - 1] = '\0';
3181     name = strtok_r(line, "\t", &saveptr);
3182 
3183     if(name) {
3184       category = strtok_r(NULL, "\t", &saveptr);
3185 
3186       if(category) {
3187 	int rc = ndpi_load_category(ndpi_str, name, (ndpi_protocol_category_t) atoi(category));
3188 
3189 	if(rc >= 0)
3190 	  num++;
3191       }
3192     }
3193   }
3194 
3195   fclose(fd);
3196   ndpi_enable_loaded_categories(ndpi_str);
3197 
3198   return(num);
3199 }
3200 
3201 /* ******************************************************************** */
3202 
ndpi_load_risky_domain(struct ndpi_detection_module_struct * ndpi_str,char * domain_name)3203 static int ndpi_load_risky_domain(struct ndpi_detection_module_struct *ndpi_str,
3204 				  char* domain_name) {
3205   if(ndpi_str->risky_domain_automa.ac_automa == NULL) {
3206     ndpi_str->risky_domain_automa.ac_automa = ac_automata_init(ac_domain_match_handler);
3207     if(!ndpi_str->risky_domain_automa.ac_automa) return -1;
3208     ac_automata_feature(ndpi_str->risky_domain_automa.ac_automa,AC_FEATURE_LC);
3209     ac_automata_name(ndpi_str->risky_domain_automa.ac_automa, "risky", 0);
3210   }
3211 
3212   if(!ndpi_str->risky_domain_automa.ac_automa)
3213     return -1;
3214 
3215   return ndpi_string_to_automa(ndpi_str, (AC_AUTOMATA_t *)ndpi_str->risky_domain_automa.ac_automa,
3216 			       domain_name, 1, 0, 0, 0, 1); /* domain, protocol, category, breed, level , at_end */
3217 }
3218 
3219 /* ******************************************************************** */
3220 
3221 /*
3222  * Format:
3223  *
3224  * <domain name>
3225  *
3226  * Notes:
3227  *  - you can add a .<domain name> to avoid mismatches
3228  */
ndpi_load_risk_domain_file(struct ndpi_detection_module_struct * ndpi_str,const char * path)3229 int ndpi_load_risk_domain_file(struct ndpi_detection_module_struct *ndpi_str, const char *path) {
3230   char buffer[128], *line;
3231   FILE *fd;
3232   int len, num = 0;
3233 
3234   fd = fopen(path, "r");
3235 
3236   if(fd == NULL) {
3237     NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
3238     return(-1);
3239   }
3240 
3241   while(1) {
3242     line = fgets(buffer, sizeof(buffer), fd);
3243 
3244     if(line == NULL)
3245       break;
3246 
3247     len = strlen(line);
3248 
3249     if((len <= 1) || (line[0] == '#'))
3250       continue;
3251 
3252     line[len - 1] = '\0';
3253 
3254     if(ndpi_load_risky_domain(ndpi_str, line) >= 0)
3255       num++;
3256   }
3257 
3258   fclose(fd);
3259 
3260   if(ndpi_str->risky_domain_automa.ac_automa)
3261     ac_automata_finalize((AC_AUTOMATA_t *)ndpi_str->risky_domain_automa.ac_automa);
3262 
3263   return(num);
3264 }
3265 
3266 /* ******************************************************************** */
3267 
3268 /*
3269  * Format:
3270  *
3271  * <ja3 hash>[,<other info>]
3272  *
3273  */
ndpi_load_malicious_ja3_file(struct ndpi_detection_module_struct * ndpi_str,const char * path)3274 int ndpi_load_malicious_ja3_file(struct ndpi_detection_module_struct *ndpi_str, const char *path) {
3275   char buffer[128], *line, *str;
3276   FILE *fd;
3277   int len, num = 0;
3278 
3279   if(ndpi_str->malicious_ja3_automa.ac_automa == NULL)
3280     ndpi_str->malicious_ja3_automa.ac_automa = ac_automata_init(NULL);
3281   if(ndpi_str->malicious_ja3_automa.ac_automa)
3282     ac_automata_name(ndpi_str->malicious_ja3_automa.ac_automa,"ja3",0);
3283 
3284   fd = fopen(path, "r");
3285 
3286   if(fd == NULL) {
3287     NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
3288     return(-1);
3289   }
3290 
3291   while(1) {
3292     char *comma;
3293 
3294     line = fgets(buffer, sizeof(buffer), fd);
3295 
3296     if(line == NULL)
3297       break;
3298 
3299     len = strlen(line);
3300 
3301     if((len <= 1) || (line[0] == '#'))
3302       continue;
3303 
3304     line[len - 1] = '\0';
3305 
3306     if((comma = strchr(line, ',')) != NULL)
3307       comma[0] = '\0';
3308 
3309     str = ndpi_strdup(line);
3310     if (str == NULL) {
3311       NDPI_LOG_ERR(ndpi_str, "Memory allocation failure\n");
3312       return -1;
3313     };
3314 
3315     if(ndpi_add_string_to_automa(ndpi_str->malicious_ja3_automa.ac_automa, str) >= 0)
3316       num++;
3317   }
3318 
3319   fclose(fd);
3320 
3321   return(num);
3322 }
3323 
3324 /* ******************************************************************** */
3325 
3326 /*
3327  * Format:
3328  *
3329  * <sha1 hash>
3330  * <other info>,<sha1 hash>
3331  * <other info>,<sha1 hash>[,<other info>[...]]
3332  *
3333  */
ndpi_load_malicious_sha1_file(struct ndpi_detection_module_struct * ndpi_str,const char * path)3334 int ndpi_load_malicious_sha1_file(struct ndpi_detection_module_struct *ndpi_str, const char *path)
3335 {
3336   char buffer[128];
3337   char *first_comma, *second_comma, *str;
3338   FILE *fd;
3339   size_t len;
3340   int num = 0;
3341 
3342   if (ndpi_str->malicious_sha1_automa.ac_automa == NULL)
3343     ndpi_str->malicious_sha1_automa.ac_automa = ac_automata_init(NULL);
3344   if(ndpi_str->malicious_sha1_automa.ac_automa)
3345     ac_automata_name(ndpi_str->malicious_sha1_automa.ac_automa,"sha1",0);
3346 
3347   fd = fopen(path, "r");
3348 
3349   if (fd == NULL) {
3350     NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
3351     return -1;
3352   }
3353 
3354   while (fgets(buffer, sizeof(buffer), fd) != NULL) {
3355     len = strlen(buffer);
3356 
3357     if (len <= 1 || buffer[0] == '#')
3358       continue;
3359 
3360     first_comma = strchr(buffer, ',');
3361     if (first_comma != NULL) {
3362       first_comma++;
3363       second_comma = strchr(first_comma, ',');
3364       if (second_comma == NULL)
3365         second_comma = &buffer[len - 1];
3366     } else {
3367       first_comma = &buffer[0];
3368       second_comma = &buffer[len - 1];
3369     }
3370 
3371     if ((second_comma - first_comma) != 40)
3372       continue;
3373     second_comma[0] = '\0';
3374 
3375     for (size_t i = 0; i < 40; ++i)
3376       first_comma[i] = toupper(first_comma[i]);
3377 
3378     str = ndpi_strdup(first_comma);
3379     if (str == NULL) {
3380       NDPI_LOG_ERR(ndpi_str, "Memory allocation failure\n");
3381       return -1;
3382     };
3383 
3384     if (ndpi_add_string_to_automa(ndpi_str->malicious_sha1_automa.ac_automa, str) >= 0)
3385       num++;
3386   }
3387 
3388   return num;
3389 }
3390 
3391 /* ******************************************************************** */
3392 
3393 /*
3394   Format:
3395   <tcp|udp>:<port>,<tcp|udp>:<port>,.....@<proto>
3396 
3397   Subprotocols Format:
3398   host:"<value>",host:"<value>",.....@<subproto>
3399 
3400   IP based Subprotocols Format (<value> is IP or CIDR):
3401   ip:<value>,ip:<value>,.....@<subproto>
3402 
3403   Example:
3404   tcp:80,tcp:3128@HTTP
3405   udp:139@NETBIOS
3406 
3407 */
ndpi_load_protocols_file(struct ndpi_detection_module_struct * ndpi_str,const char * path)3408 int ndpi_load_protocols_file(struct ndpi_detection_module_struct *ndpi_str, const char *path) {
3409   FILE *fd;
3410   char *buffer, *old_buffer;
3411   int chunk_len = 512, buffer_len = chunk_len, old_buffer_len;
3412   int i, rc = -1;
3413 
3414   fd = fopen(path, "r");
3415 
3416   if(fd == NULL) {
3417     NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
3418     goto error;
3419   }
3420 
3421   buffer = ndpi_malloc(buffer_len);
3422 
3423   if(buffer == NULL) {
3424     NDPI_LOG_ERR(ndpi_str, "Memory allocation failure\n");
3425     goto close_fd;
3426   }
3427 
3428   while(1) {
3429     char *line = buffer;
3430     int line_len = buffer_len;
3431 
3432     while((line = fgets(line, line_len, fd)) != NULL && line[strlen(line) - 1] != '\n') {
3433       i = strlen(line);
3434       old_buffer = buffer;
3435       old_buffer_len = buffer_len;
3436       buffer_len += chunk_len;
3437 
3438       buffer = ndpi_realloc(old_buffer, old_buffer_len, buffer_len);
3439 
3440       if(buffer == NULL) {
3441 	NDPI_LOG_ERR(ndpi_str, "Memory allocation failure\n");
3442 	ndpi_free(old_buffer);
3443 	goto close_fd;
3444       }
3445 
3446       line = &buffer[i];
3447       line_len = chunk_len;
3448     }
3449 
3450     if(!line) /* safety check */
3451       break;
3452 
3453     i = strlen(buffer);
3454     if((i <= 1) || (buffer[0] == '#'))
3455       continue;
3456     else
3457       buffer[i - 1] = '\0';
3458 
3459     ndpi_handle_rule(ndpi_str, buffer, 1);
3460   }
3461 
3462   rc = 0;
3463 
3464   ndpi_free(buffer);
3465 
3466  close_fd:
3467   fclose(fd);
3468 
3469  error:
3470   return(rc);
3471 }
3472 
3473 /* ******************************************************************** */
3474 
3475 /* ntop */
ndpi_set_bitmask_protocol_detection(char * label,struct ndpi_detection_module_struct * ndpi_str,const NDPI_PROTOCOL_BITMASK * detection_bitmask,const u_int32_t idx,u_int16_t ndpi_protocol_id,void (* func)(struct ndpi_detection_module_struct *,struct ndpi_flow_struct * flow),const NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask,u_int8_t b_save_bitmask_unknow,u_int8_t b_add_detection_bitmask)3476 void ndpi_set_bitmask_protocol_detection(char *label, struct ndpi_detection_module_struct *ndpi_str,
3477                                          const NDPI_PROTOCOL_BITMASK *detection_bitmask, const u_int32_t idx,
3478                                          u_int16_t ndpi_protocol_id,
3479                                          void (*func)(struct ndpi_detection_module_struct *,
3480                                                       struct ndpi_flow_struct *flow),
3481                                          const NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_bitmask,
3482                                          u_int8_t b_save_bitmask_unknow, u_int8_t b_add_detection_bitmask) {
3483   /*
3484     Compare specify protocol bitmask with main detection bitmask
3485   */
3486   if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(*detection_bitmask, ndpi_protocol_id) != 0) {
3487 #ifdef DEBUG
3488     NDPI_LOG_DBG2(ndpi_str,
3489 		  "[NDPI] ndpi_set_bitmask_protocol_detection: %s : [callback_buffer] idx= %u, [proto_defaults] "
3490 		  "protocol_id=%u\n",
3491 		  label, idx, ndpi_protocol_id);
3492 #endif
3493 
3494     if(ndpi_str->proto_defaults[ndpi_protocol_id].protoIdx != 0) {
3495       NDPI_LOG_DBG2(ndpi_str, "[NDPI] Internal error: protocol %s/%u has been already registered\n", label,
3496 		    ndpi_protocol_id);
3497 #ifdef DEBUG
3498     } else {
3499       NDPI_LOG_DBG2(ndpi_str, "[NDPI] Adding %s with protocol id %d\n", label, ndpi_protocol_id);
3500 #endif
3501     }
3502 
3503     /*
3504       Set function and index protocol within proto_default structure for port protocol detection
3505       and callback_buffer function for DPI protocol detection
3506     */
3507     ndpi_str->proto_defaults[ndpi_protocol_id].protoIdx = idx;
3508     ndpi_str->proto_defaults[ndpi_protocol_id].func = ndpi_str->callback_buffer[idx].func = func;
3509     ndpi_str->callback_buffer[idx].ndpi_protocol_id = ndpi_protocol_id;
3510 
3511     /*
3512       Set ndpi_selection_bitmask for protocol
3513     */
3514     ndpi_str->callback_buffer[idx].ndpi_selection_bitmask = ndpi_selection_bitmask;
3515 
3516     /*
3517       Reset protocol detection bitmask via NDPI_PROTOCOL_UNKNOWN and than add specify protocol bitmast to callback
3518       buffer.
3519     */
3520     if(b_save_bitmask_unknow)
3521       NDPI_SAVE_AS_BITMASK(ndpi_str->callback_buffer[idx].detection_bitmask, NDPI_PROTOCOL_UNKNOWN);
3522     if(b_add_detection_bitmask)
3523       NDPI_ADD_PROTOCOL_TO_BITMASK(ndpi_str->callback_buffer[idx].detection_bitmask, ndpi_protocol_id);
3524 
3525     NDPI_SAVE_AS_BITMASK(ndpi_str->callback_buffer[idx].excluded_protocol_bitmask, ndpi_protocol_id);
3526   }
3527 }
3528 
3529 /* ******************************************************************** */
3530 
ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct * ndpi_str,const NDPI_PROTOCOL_BITMASK * dbm)3531 void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *ndpi_str,
3532                                           const NDPI_PROTOCOL_BITMASK *dbm) {
3533   NDPI_PROTOCOL_BITMASK detection_bitmask_local;
3534   NDPI_PROTOCOL_BITMASK *detection_bitmask = &detection_bitmask_local;
3535   u_int32_t a = 0;
3536 
3537   NDPI_BITMASK_SET(detection_bitmask_local, *dbm);
3538   NDPI_BITMASK_SET(ndpi_str->detection_bitmask, *dbm);
3539 
3540   /* set this here to zero to be interrupt safe */
3541   ndpi_str->callback_buffer_size = 0;
3542 
3543   /* HTTP */
3544   init_http_dissector(ndpi_str, &a, detection_bitmask);
3545 
3546   /* STARCRAFT */
3547   init_starcraft_dissector(ndpi_str, &a, detection_bitmask);
3548 
3549   /* TLS+DTLS */
3550   init_tls_dissector(ndpi_str, &a, detection_bitmask);
3551 
3552   /* STUN */
3553   init_stun_dissector(ndpi_str, &a, detection_bitmask);
3554 
3555   /* RTP */
3556   init_rtp_dissector(ndpi_str, &a, detection_bitmask);
3557 
3558   /* RTSP */
3559   init_rtsp_dissector(ndpi_str, &a, detection_bitmask);
3560 
3561   /* RDP */
3562   init_rdp_dissector(ndpi_str, &a, detection_bitmask);
3563 
3564   /* SIP */
3565   init_sip_dissector(ndpi_str, &a, detection_bitmask);
3566 
3567   /* IMO */
3568   init_imo_dissector(ndpi_str, &a, detection_bitmask);
3569 
3570   /* Teredo */
3571   init_teredo_dissector(ndpi_str, &a, detection_bitmask);
3572 
3573   /* EDONKEY */
3574   init_edonkey_dissector(ndpi_str, &a, detection_bitmask);
3575 
3576   /* FASTTRACK */
3577   init_fasttrack_dissector(ndpi_str, &a, detection_bitmask);
3578 
3579   /* GNUTELLA */
3580   init_gnutella_dissector(ndpi_str, &a, detection_bitmask);
3581 
3582   /* DIRECTCONNECT */
3583   init_directconnect_dissector(ndpi_str, &a, detection_bitmask);
3584 
3585   /* NATS */
3586   init_nats_dissector(ndpi_str, &a, detection_bitmask);
3587 
3588   /* APPLEJUICE */
3589   init_applejuice_dissector(ndpi_str, &a, detection_bitmask);
3590 
3591   /* SOULSEEK */
3592   init_soulseek_dissector(ndpi_str, &a, detection_bitmask);
3593 
3594   /* SOCKS */
3595   init_socks_dissector(ndpi_str, &a, detection_bitmask);
3596 
3597   /* IRC */
3598   init_irc_dissector(ndpi_str, &a, detection_bitmask);
3599 
3600   /* JABBER */
3601   init_jabber_dissector(ndpi_str, &a, detection_bitmask);
3602 
3603   /* MAIL_POP */
3604   init_mail_pop_dissector(ndpi_str, &a, detection_bitmask);
3605 
3606   /* MAIL_IMAP */
3607   init_mail_imap_dissector(ndpi_str, &a, detection_bitmask);
3608 
3609   /* MAIL_SMTP */
3610   init_mail_smtp_dissector(ndpi_str, &a, detection_bitmask);
3611 
3612   /* USENET */
3613   init_usenet_dissector(ndpi_str, &a, detection_bitmask);
3614 
3615   /* DNS */
3616   init_dns_dissector(ndpi_str, &a, detection_bitmask);
3617 
3618   /* VMWARE */
3619   init_vmware_dissector(ndpi_str, &a, detection_bitmask);
3620 
3621   /* NON_TCP_UDP */
3622   init_non_tcp_udp_dissector(ndpi_str, &a, detection_bitmask);
3623 
3624   /* SOPCAST */
3625   init_sopcast_dissector(ndpi_str, &a, detection_bitmask);
3626 
3627   /* TVUPLAYER */
3628   init_tvuplayer_dissector(ndpi_str, &a, detection_bitmask);
3629 
3630   /* PPSTREAM */
3631   init_ppstream_dissector(ndpi_str, &a, detection_bitmask);
3632 
3633   /* IAX */
3634   init_iax_dissector(ndpi_str, &a, detection_bitmask);
3635 
3636   /* MGPC */
3637   init_mgpc_dissector(ndpi_str, &a, detection_bitmask);
3638 
3639   /* ZATTOO */
3640   init_zattoo_dissector(ndpi_str, &a, detection_bitmask);
3641 
3642   /* QQ */
3643   init_qq_dissector(ndpi_str, &a, detection_bitmask);
3644 
3645   /* SSH */
3646   init_ssh_dissector(ndpi_str, &a, detection_bitmask);
3647 
3648   /* AYIYA */
3649   init_ayiya_dissector(ndpi_str, &a, detection_bitmask);
3650 
3651   /* THUNDER */
3652   init_thunder_dissector(ndpi_str, &a, detection_bitmask);
3653 
3654   /* VNC */
3655   init_vnc_dissector(ndpi_str, &a, detection_bitmask);
3656 
3657   /* TEAMVIEWER */
3658   init_teamviewer_dissector(ndpi_str, &a, detection_bitmask);
3659 
3660   /* DHCP */
3661   init_dhcp_dissector(ndpi_str, &a, detection_bitmask);
3662 
3663   /* STEAM */
3664   init_steam_dissector(ndpi_str, &a, detection_bitmask);
3665 
3666   /* HALFLIFE2 */
3667   init_halflife2_dissector(ndpi_str, &a, detection_bitmask);
3668 
3669   /* XBOX */
3670   init_xbox_dissector(ndpi_str, &a, detection_bitmask);
3671 
3672   /* SMB */
3673   init_smb_dissector(ndpi_str, &a, detection_bitmask);
3674 
3675   /* MINING */
3676   init_mining_dissector(ndpi_str, &a, detection_bitmask);
3677 
3678   /* TELNET */
3679   init_telnet_dissector(ndpi_str, &a, detection_bitmask);
3680 
3681   /* NTP */
3682   init_ntp_dissector(ndpi_str, &a, detection_bitmask);
3683 
3684   /* NFS */
3685   init_nfs_dissector(ndpi_str, &a, detection_bitmask);
3686 
3687   /* SSDP */
3688   init_ssdp_dissector(ndpi_str, &a, detection_bitmask);
3689 
3690   /* WORLD_OF_WARCRAFT */
3691   init_world_of_warcraft_dissector(ndpi_str, &a, detection_bitmask);
3692 
3693   /* POSTGRES */
3694   init_postgres_dissector(ndpi_str, &a, detection_bitmask);
3695 
3696   /* MYSQL */
3697   init_mysql_dissector(ndpi_str, &a, detection_bitmask);
3698 
3699   /* BGP */
3700   init_bgp_dissector(ndpi_str, &a, detection_bitmask);
3701 
3702   /* SNMP */
3703   init_snmp_dissector(ndpi_str, &a, detection_bitmask);
3704 
3705   /* KONTIKI */
3706   init_kontiki_dissector(ndpi_str, &a, detection_bitmask);
3707 
3708   /* ICECAST */
3709   init_icecast_dissector(ndpi_str, &a, detection_bitmask);
3710 
3711   /* SHOUTCAST */
3712   init_shoutcast_dissector(ndpi_str, &a, detection_bitmask);
3713 
3714   /* KERBEROS */
3715   init_kerberos_dissector(ndpi_str, &a, detection_bitmask);
3716 
3717   /* OPENFT */
3718   init_openft_dissector(ndpi_str, &a, detection_bitmask);
3719 
3720   /* SYSLOG */
3721   init_syslog_dissector(ndpi_str, &a, detection_bitmask);
3722 
3723   /* DIRECT_DOWNLOAD_LINK */
3724   init_directdownloadlink_dissector(ndpi_str, &a, detection_bitmask);
3725 
3726   /* NETBIOS */
3727   init_netbios_dissector(ndpi_str, &a, detection_bitmask);
3728 
3729   /* IPP */
3730   init_ipp_dissector(ndpi_str, &a, detection_bitmask);
3731 
3732   /* LDAP */
3733   init_ldap_dissector(ndpi_str, &a, detection_bitmask);
3734 
3735   /* WARCRAFT3 */
3736   init_warcraft3_dissector(ndpi_str, &a, detection_bitmask);
3737 
3738   /* XDMCP */
3739   init_xdmcp_dissector(ndpi_str, &a, detection_bitmask);
3740 
3741   /* TFTP */
3742   init_tftp_dissector(ndpi_str, &a, detection_bitmask);
3743 
3744   /* MSSQL_TDS */
3745   init_mssql_tds_dissector(ndpi_str, &a, detection_bitmask);
3746 
3747   /* PPTP */
3748   init_pptp_dissector(ndpi_str, &a, detection_bitmask);
3749 
3750   /* STEALTHNET */
3751   init_stealthnet_dissector(ndpi_str, &a, detection_bitmask);
3752 
3753   /* DHCPV6 */
3754   init_dhcpv6_dissector(ndpi_str, &a, detection_bitmask);
3755 
3756   /* AFP */
3757   init_afp_dissector(ndpi_str, &a, detection_bitmask);
3758 
3759   /* check_mk */
3760   init_checkmk_dissector(ndpi_str, &a, detection_bitmask);
3761 
3762   /* cpha */
3763   init_cpha_dissector(ndpi_str, &a, detection_bitmask);
3764 
3765   /* AIMINI */
3766   init_aimini_dissector(ndpi_str, &a, detection_bitmask);
3767 
3768   /* FLORENSIA */
3769   init_florensia_dissector(ndpi_str, &a, detection_bitmask);
3770 
3771   /* MAPLESTORY */
3772   init_maplestory_dissector(ndpi_str, &a, detection_bitmask);
3773 
3774   /* DOFUS */
3775   init_dofus_dissector(ndpi_str, &a, detection_bitmask);
3776 
3777   /* WORLD_OF_KUNG_FU */
3778   init_world_of_kung_fu_dissector(ndpi_str, &a, detection_bitmask);
3779 
3780   /* FIESTA */
3781   init_fiesta_dissector(ndpi_str, &a, detection_bitmask);
3782 
3783   /* CROSSIFIRE */
3784   init_crossfire_dissector(ndpi_str, &a, detection_bitmask);
3785 
3786   /* GUILDWARS */
3787   init_guildwars_dissector(ndpi_str, &a, detection_bitmask);
3788 
3789   /* ARMAGETRON */
3790   init_armagetron_dissector(ndpi_str, &a, detection_bitmask);
3791 
3792   /* DROPBOX */
3793   init_dropbox_dissector(ndpi_str, &a, detection_bitmask);
3794 
3795   /* SPOTIFY */
3796   init_spotify_dissector(ndpi_str, &a, detection_bitmask);
3797 
3798   /* RADIUS */
3799   init_radius_dissector(ndpi_str, &a, detection_bitmask);
3800 
3801   /* CITRIX */
3802   init_citrix_dissector(ndpi_str, &a, detection_bitmask);
3803 
3804   /* LOTUS_NOTES */
3805   init_lotus_notes_dissector(ndpi_str, &a, detection_bitmask);
3806 
3807   /* GTP */
3808   init_gtp_dissector(ndpi_str, &a, detection_bitmask);
3809 
3810   /* DCERPC */
3811   init_dcerpc_dissector(ndpi_str, &a, detection_bitmask);
3812 
3813   /* NETFLOW */
3814   init_netflow_dissector(ndpi_str, &a, detection_bitmask);
3815 
3816   /* SFLOW */
3817   init_sflow_dissector(ndpi_str, &a, detection_bitmask);
3818 
3819   /* H323 */
3820   init_h323_dissector(ndpi_str, &a, detection_bitmask);
3821 
3822   /* OPENVPN */
3823   init_openvpn_dissector(ndpi_str, &a, detection_bitmask);
3824 
3825   /* NOE */
3826   init_noe_dissector(ndpi_str, &a, detection_bitmask);
3827 
3828   /* CISCOVPN */
3829   init_ciscovpn_dissector(ndpi_str, &a, detection_bitmask);
3830 
3831   /* TEAMSPEAK */
3832   init_teamspeak_dissector(ndpi_str, &a, detection_bitmask);
3833 
3834   /* SKINNY */
3835   init_skinny_dissector(ndpi_str, &a, detection_bitmask);
3836 
3837   /* RTCP */
3838   init_rtcp_dissector(ndpi_str, &a, detection_bitmask);
3839 
3840   /* RSYNC */
3841   init_rsync_dissector(ndpi_str, &a, detection_bitmask);
3842 
3843   /* WHOIS_DAS */
3844   init_whois_das_dissector(ndpi_str, &a, detection_bitmask);
3845 
3846   /* ORACLE */
3847   init_oracle_dissector(ndpi_str, &a, detection_bitmask);
3848 
3849   /* CORBA */
3850   init_corba_dissector(ndpi_str, &a, detection_bitmask);
3851 
3852   /* RTMP */
3853   init_rtmp_dissector(ndpi_str, &a, detection_bitmask);
3854 
3855   /* FTP_CONTROL */
3856   init_ftp_control_dissector(ndpi_str, &a, detection_bitmask);
3857 
3858   /* FTP_DATA */
3859   init_ftp_data_dissector(ndpi_str, &a, detection_bitmask);
3860 
3861   /* MEGACO */
3862   init_megaco_dissector(ndpi_str, &a, detection_bitmask);
3863 
3864   /* REDIS */
3865   init_redis_dissector(ndpi_str, &a, detection_bitmask);
3866 
3867   /* VHUA */
3868   init_vhua_dissector(ndpi_str, &a, detection_bitmask);
3869 
3870   /* ZMQ */
3871   init_zmq_dissector(ndpi_str, &a, detection_bitmask);
3872 
3873   /* TELEGRAM */
3874   init_telegram_dissector(ndpi_str, &a, detection_bitmask);
3875 
3876   /* QUIC */
3877   init_quic_dissector(ndpi_str, &a, detection_bitmask);
3878 
3879   /* DIAMETER */
3880   init_diameter_dissector(ndpi_str, &a, detection_bitmask);
3881 
3882   /* APPLE_PUSH */
3883   init_apple_push_dissector(ndpi_str, &a, detection_bitmask);
3884 
3885   /* EAQ */
3886   init_eaq_dissector(ndpi_str, &a, detection_bitmask);
3887 
3888   /* KAKAOTALK_VOICE */
3889   init_kakaotalk_voice_dissector(ndpi_str, &a, detection_bitmask);
3890 
3891   /* MPEGTS */
3892   init_mpegts_dissector(ndpi_str, &a, detection_bitmask);
3893 
3894   /* UBNTAC2 */
3895   init_ubntac2_dissector(ndpi_str, &a, detection_bitmask);
3896 
3897   /* COAP */
3898   init_coap_dissector(ndpi_str, &a, detection_bitmask);
3899 
3900   /* MQTT */
3901   init_mqtt_dissector(ndpi_str, &a, detection_bitmask);
3902 
3903   /* SOME/IP */
3904   init_someip_dissector(ndpi_str, &a, detection_bitmask);
3905 
3906   /* RX */
3907   init_rx_dissector(ndpi_str, &a, detection_bitmask);
3908 
3909   /* GIT */
3910   init_git_dissector(ndpi_str, &a, detection_bitmask);
3911 
3912   /* HANGOUT */
3913   init_hangout_dissector(ndpi_str, &a, detection_bitmask);
3914 
3915   /* DRDA */
3916   init_drda_dissector(ndpi_str, &a, detection_bitmask);
3917 
3918   /* BJNP */
3919   init_bjnp_dissector(ndpi_str, &a, detection_bitmask);
3920 
3921   /* SMPP */
3922   init_smpp_dissector(ndpi_str, &a, detection_bitmask);
3923 
3924   /* TINC */
3925   init_tinc_dissector(ndpi_str, &a, detection_bitmask);
3926 
3927   /* FIX */
3928   init_fix_dissector(ndpi_str, &a, detection_bitmask);
3929 
3930   /* NINTENDO */
3931   init_nintendo_dissector(ndpi_str, &a, detection_bitmask);
3932 
3933   /* MODBUS */
3934   init_modbus_dissector(ndpi_str, &a, detection_bitmask);
3935 
3936   /* CAPWAP */
3937   init_capwap_dissector(ndpi_str, &a, detection_bitmask);
3938 
3939   /* ZABBIX */
3940   init_zabbix_dissector(ndpi_str, &a, detection_bitmask);
3941 
3942   /*** Put false-positive sensitive protocols at the end ***/
3943 
3944   /* VIBER */
3945   init_viber_dissector(ndpi_str, &a, detection_bitmask);
3946 
3947   /* SKYPE */
3948   init_skype_dissector(ndpi_str, &a, detection_bitmask);
3949 
3950   /* BITTORRENT */
3951   init_bittorrent_dissector(ndpi_str, &a, detection_bitmask);
3952 
3953   /* WHATSAPP */
3954   init_whatsapp_dissector(ndpi_str, &a, detection_bitmask);
3955 
3956   /* OOKLA */
3957   init_ookla_dissector(ndpi_str, &a, detection_bitmask);
3958 
3959   /* AMQP */
3960   init_amqp_dissector(ndpi_str, &a, detection_bitmask);
3961 
3962   /* CSGO */
3963   init_csgo_dissector(ndpi_str, &a, detection_bitmask);
3964 
3965   /* LISP */
3966   init_lisp_dissector(ndpi_str, &a, detection_bitmask);
3967 
3968   /* AJP */
3969   init_ajp_dissector(ndpi_str, &a, detection_bitmask);
3970 
3971   /* Memcached */
3972   init_memcached_dissector(ndpi_str, &a, detection_bitmask);
3973 
3974   /* Nest Log Sink */
3975   init_nest_log_sink_dissector(ndpi_str, &a, detection_bitmask);
3976 
3977   /* WireGuard VPN */
3978   init_wireguard_dissector(ndpi_str, &a, detection_bitmask);
3979 
3980   /* Amazon_Video */
3981   init_amazon_video_dissector(ndpi_str, &a, detection_bitmask);
3982 
3983   /* Targus Getdata */
3984   init_targus_getdata_dissector(ndpi_str, &a, detection_bitmask);
3985 
3986   /* S7 comm */
3987   init_s7comm_dissector(ndpi_str, &a, detection_bitmask);
3988 
3989   /* IEC 60870-5-104 */
3990   init_104_dissector(ndpi_str, &a, detection_bitmask);
3991 
3992   /* DNP3 */
3993   init_dnp3_dissector(ndpi_str, &a, detection_bitmask);
3994 
3995   /* WEBSOCKET */
3996   init_websocket_dissector(ndpi_str, &a, detection_bitmask);
3997 
3998   /* SOAP */
3999   init_soap_dissector(ndpi_str, &a, detection_bitmask);
4000 
4001   /* DNScrypt */
4002   init_dnscrypt_dissector(ndpi_str, &a, detection_bitmask);
4003 
4004   /* MongoDB */
4005   init_mongodb_dissector(ndpi_str, &a, detection_bitmask);
4006 
4007   /* AmongUS */
4008   init_among_us_dissector(ndpi_str, &a, detection_bitmask);
4009 
4010   /* HP Virtual Machine Group Management */
4011   init_hpvirtgrp_dissector(ndpi_str, &a, detection_bitmask);
4012 
4013   /* Genshin Impact */
4014   init_genshin_impact_dissector(ndpi_str, &a, detection_bitmask);
4015 
4016   /* Z39.50 international standard client–server, application layer communications protocol */
4017   init_z3950_dissector(ndpi_str, &a, detection_bitmask);
4018 
4019   /* AVAST SecureDNS */
4020   init_avast_securedns_dissector(ndpi_str, &a, detection_bitmask);
4021 
4022 #ifdef CUSTOM_NDPI_PROTOCOLS
4023 #include "../../../nDPI-custom/custom_ndpi_main_init.c"
4024 #endif
4025 
4026   /* ----------------------------------------------------------------- */
4027 
4028   ndpi_str->callback_buffer_size = a;
4029 
4030   NDPI_LOG_DBG2(ndpi_str, "callback_buffer_size is %u\n", ndpi_str->callback_buffer_size);
4031 
4032   /* now build the specific buffer for tcp, udp and non_tcp_udp */
4033   ndpi_str->callback_buffer_size_tcp_payload = 0;
4034   ndpi_str->callback_buffer_size_tcp_no_payload = 0;
4035   for(a = 0; a < ndpi_str->callback_buffer_size; a++) {
4036     if((ndpi_str->callback_buffer[a].ndpi_selection_bitmask &
4037 	(NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP |
4038 	 NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC)) != 0) {
4039       if(_ndpi_debug_callbacks)
4040 	NDPI_LOG_DBG2(ndpi_str, "callback_buffer_tcp_payload, adding buffer %u as entry %u\n", a,
4041 		      ndpi_str->callback_buffer_size_tcp_payload);
4042 
4043       memcpy(&ndpi_str->callback_buffer_tcp_payload[ndpi_str->callback_buffer_size_tcp_payload],
4044 	     &ndpi_str->callback_buffer[a], sizeof(struct ndpi_call_function_struct));
4045       ndpi_str->callback_buffer_size_tcp_payload++;
4046 
4047       if((ndpi_str->callback_buffer[a].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) ==
4048 	 0) {
4049 	if(_ndpi_debug_callbacks)
4050 	  NDPI_LOG_DBG2(
4051                         ndpi_str,
4052                         "\tcallback_buffer_tcp_no_payload, additional adding buffer %u to no_payload process\n", a);
4053 
4054 	memcpy(&ndpi_str->callback_buffer_tcp_no_payload[ndpi_str->callback_buffer_size_tcp_no_payload],
4055 	       &ndpi_str->callback_buffer[a], sizeof(struct ndpi_call_function_struct));
4056 	ndpi_str->callback_buffer_size_tcp_no_payload++;
4057       }
4058     }
4059   }
4060 
4061   ndpi_str->callback_buffer_size_udp = 0;
4062   for(a = 0; a < ndpi_str->callback_buffer_size; a++) {
4063     if((ndpi_str->callback_buffer[a].ndpi_selection_bitmask &
4064 	(NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP |
4065 	 NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC)) != 0) {
4066       if(_ndpi_debug_callbacks)
4067 	NDPI_LOG_DBG2(ndpi_str, "callback_buffer_size_udp: adding buffer : %u as entry %u\n", a,
4068 		      ndpi_str->callback_buffer_size_udp);
4069 
4070       memcpy(&ndpi_str->callback_buffer_udp[ndpi_str->callback_buffer_size_udp], &ndpi_str->callback_buffer[a],
4071 	     sizeof(struct ndpi_call_function_struct));
4072       ndpi_str->callback_buffer_size_udp++;
4073     }
4074   }
4075 
4076   ndpi_str->callback_buffer_size_non_tcp_udp = 0;
4077   for(a = 0; a < ndpi_str->callback_buffer_size; a++) {
4078     if((ndpi_str->callback_buffer[a].ndpi_selection_bitmask &
4079 	(NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP |
4080 	 NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP)) == 0 ||
4081        (ndpi_str->callback_buffer[a].ndpi_selection_bitmask & NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC) !=
4082        0) {
4083       if(_ndpi_debug_callbacks)
4084 	NDPI_LOG_DBG2(ndpi_str, "callback_buffer_non_tcp_udp: adding buffer : %u as entry %u\n", a,
4085 		      ndpi_str->callback_buffer_size_non_tcp_udp);
4086 
4087       memcpy(&ndpi_str->callback_buffer_non_tcp_udp[ndpi_str->callback_buffer_size_non_tcp_udp],
4088 	     &ndpi_str->callback_buffer[a], sizeof(struct ndpi_call_function_struct));
4089       ndpi_str->callback_buffer_size_non_tcp_udp++;
4090     }
4091   }
4092 }
4093 
4094 /* handle extension headers in IPv6 packets
4095  * arguments:
4096  * 	l4ptr: pointer to the byte following the initial IPv6 header
4097  * 	l4len: the length of the IPv6 packet excluding the IPv6 header
4098  * 	nxt_hdr: next header value from the IPv6 header
4099  * result:
4100  * 	l4ptr: pointer to the start of the actual packet payload
4101  * 	l4len: length of the actual payload
4102  * 	nxt_hdr: protocol of the actual payload
4103  * returns 0 upon success and 1 upon failure
4104  */
ndpi_handle_ipv6_extension_headers(struct ndpi_detection_module_struct * ndpi_str,const u_int8_t ** l4ptr,u_int16_t * l4len,u_int8_t * nxt_hdr)4105 int ndpi_handle_ipv6_extension_headers(struct ndpi_detection_module_struct *ndpi_str, const u_int8_t **l4ptr,
4106                                        u_int16_t *l4len, u_int8_t *nxt_hdr) {
4107   while((*nxt_hdr == 0 || *nxt_hdr == 43 || *nxt_hdr == 44 || *nxt_hdr == 60 || *nxt_hdr == 135 || *nxt_hdr == 59)) {
4108     u_int16_t ehdr_len;
4109 
4110     // no next header
4111     if(*nxt_hdr == 59) {
4112       return(1);
4113     }
4114 
4115     // fragment extension header has fixed size of 8 bytes and the first byte is the next header type
4116     if(*nxt_hdr == 44) {
4117       if(*l4len < 8) {
4118 	return(1);
4119       }
4120 
4121       *nxt_hdr = (*l4ptr)[0];
4122       *l4len -= 8;
4123       (*l4ptr) += 8;
4124       continue;
4125     }
4126 
4127     // the other extension headers have one byte for the next header type
4128     // and one byte for the extension header length in 8 byte steps minus the first 8 bytes
4129     if(*l4len < 2) {
4130       return(1);
4131     }
4132 
4133     ehdr_len = (*l4ptr)[1];
4134     ehdr_len *= 8;
4135     ehdr_len += 8;
4136 
4137     if(*l4len < ehdr_len) {
4138       return(1);
4139     }
4140 
4141     *nxt_hdr = (*l4ptr)[0];
4142 
4143     if(*l4len < ehdr_len)
4144       return(1);
4145 
4146     *l4len -= ehdr_len;
4147     (*l4ptr) += ehdr_len;
4148   }
4149 
4150   return(0);
4151 }
4152 
ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr * iph,const u_int16_t ipsize)4153 static u_int8_t ndpi_iph_is_valid_and_not_fragmented(const struct ndpi_iphdr *iph, const u_int16_t ipsize) {
4154   /*
4155     returned value:
4156     0: fragmented
4157     1: not fragmented
4158   */
4159   //#ifdef REQUIRE_FULL_PACKETS
4160   if(ipsize < iph->ihl * 4 || ipsize < ntohs(iph->tot_len) || ntohs(iph->tot_len) < iph->ihl * 4 ||
4161      (iph->frag_off & htons(0x1FFF)) != 0) {
4162     return(0);
4163   }
4164   //#endif
4165 
4166   return(1);
4167 }
4168 
4169 /*
4170   extract the l4 payload, if available
4171   returned value:
4172   0: ok, extracted
4173   1: packet too small
4174   2,3: fragmented, ....
4175   else
4176   0: ok, extracted
4177   1: error or not available
4178 */
ndpi_detection_get_l4_internal(struct ndpi_detection_module_struct * ndpi_str,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)4179 static u_int8_t ndpi_detection_get_l4_internal(struct ndpi_detection_module_struct *ndpi_str, const u_int8_t *l3,
4180                                                u_int16_t l3_len, const u_int8_t **l4_return, u_int16_t *l4_len_return,
4181                                                u_int8_t *l4_protocol_return, u_int32_t flags) {
4182   const struct ndpi_iphdr *iph = NULL;
4183   const struct ndpi_ipv6hdr *iph_v6 = NULL;
4184   u_int16_t l4len = 0;
4185   const u_int8_t *l4ptr = NULL;
4186   u_int8_t l4protocol = 0;
4187 
4188   if(l3 == NULL || l3_len < sizeof(struct ndpi_iphdr))
4189     return(1);
4190 
4191   if((iph = (const struct ndpi_iphdr *) l3) == NULL)
4192     return(1);
4193 
4194   if(iph->version == IPVERSION && iph->ihl >= 5) {
4195     NDPI_LOG_DBG2(ndpi_str, "ipv4 header\n");
4196   }
4197   else if(iph->version == 6 && l3_len >= sizeof(struct ndpi_ipv6hdr)) {
4198     NDPI_LOG_DBG2(ndpi_str, "ipv6 header\n");
4199     iph_v6 = (const struct ndpi_ipv6hdr *) l3;
4200     iph = NULL;
4201   } else {
4202     return(1);
4203   }
4204 
4205   if((flags & NDPI_DETECTION_ONLY_IPV6) && iph != NULL) {
4206     NDPI_LOG_DBG2(ndpi_str, "ipv4 header found but excluded by flag\n");
4207     return(1);
4208   } else if((flags & NDPI_DETECTION_ONLY_IPV4) && iph_v6 != NULL) {
4209     NDPI_LOG_DBG2(ndpi_str, "ipv6 header found but excluded by flag\n");
4210     return(1);
4211   }
4212 
4213   /* 0: fragmented; 1: not fragmented */
4214   if(iph != NULL && ndpi_iph_is_valid_and_not_fragmented(iph, l3_len)) {
4215     u_int16_t len = ntohs(iph->tot_len);
4216     u_int16_t hlen = (iph->ihl * 4);
4217 
4218     l4ptr = (((const u_int8_t *) iph) + iph->ihl * 4);
4219 
4220     if(len == 0)
4221       len = l3_len;
4222 
4223     l4len = (len > hlen) ? (len - hlen) : 0;
4224     l4protocol = iph->protocol;
4225   }
4226 
4227   else if(iph_v6 != NULL && (l3_len - sizeof(struct ndpi_ipv6hdr)) >= ntohs(iph_v6->ip6_hdr.ip6_un1_plen)) {
4228     l4ptr = (((const u_int8_t *) iph_v6) + sizeof(struct ndpi_ipv6hdr));
4229     l4len = ntohs(iph_v6->ip6_hdr.ip6_un1_plen);
4230     l4protocol = iph_v6->ip6_hdr.ip6_un1_nxt;
4231 
4232     // we need to handle IPv6 extension headers if present
4233     if(ndpi_handle_ipv6_extension_headers(ndpi_str, &l4ptr, &l4len, &l4protocol) != 0) {
4234       return(1);
4235     }
4236 
4237   } else {
4238     return(1);
4239   }
4240 
4241   if(l4_return != NULL) {
4242     *l4_return = l4ptr;
4243   }
4244 
4245   if(l4_len_return != NULL) {
4246     *l4_len_return = l4len;
4247   }
4248 
4249   if(l4_protocol_return != NULL) {
4250     *l4_protocol_return = l4protocol;
4251   }
4252 
4253   return(0);
4254 }
4255 
4256 /* ************************************************ */
4257 
ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct * flow,struct ndpi_packet_struct * packet)4258 void ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct *flow, struct ndpi_packet_struct *packet) {
4259   memcpy(&packet->detected_protocol_stack, &flow->detected_protocol_stack, sizeof(packet->detected_protocol_stack));
4260   memcpy(&packet->protocol_stack_info, &flow->protocol_stack_info, sizeof(packet->protocol_stack_info));
4261 }
4262 
4263 /* ****************************************************** */
4264 
ndpi_free_flow_data(struct ndpi_flow_struct * flow)4265 void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
4266   if(flow) {
4267     if(flow->http.url)
4268       ndpi_free(flow->http.url);
4269 
4270     if(flow->http.content_type)
4271       ndpi_free(flow->http.content_type);
4272 
4273     if(flow->http.request_content_type)
4274       ndpi_free(flow->http.request_content_type);
4275 
4276     if(flow->http.user_agent)
4277       ndpi_free(flow->http.user_agent);
4278 
4279     if(flow->kerberos_buf.pktbuf)
4280       ndpi_free(flow->kerberos_buf.pktbuf);
4281 
4282     if(flow_is_proto(flow, NDPI_PROTOCOL_QUIC) ||
4283        flow_is_proto(flow, NDPI_PROTOCOL_TLS) ||
4284        flow_is_proto(flow, NDPI_PROTOCOL_DTLS) ||
4285        flow_is_proto(flow, NDPI_PROTOCOL_MAIL_SMTPS) ||
4286        flow_is_proto(flow, NDPI_PROTOCOL_MAIL_POPS) ||
4287        flow_is_proto(flow, NDPI_PROTOCOL_MAIL_IMAPS)) {
4288       if(flow->protos.tls_quic_stun.tls_quic.server_names)
4289 	ndpi_free(flow->protos.tls_quic_stun.tls_quic.server_names);
4290 
4291       if(flow->protos.tls_quic_stun.tls_quic.alpn)
4292 	ndpi_free(flow->protos.tls_quic_stun.tls_quic.alpn);
4293 
4294       if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions)
4295 	ndpi_free(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions);
4296 
4297       if(flow->protos.tls_quic_stun.tls_quic.issuerDN)
4298 	ndpi_free(flow->protos.tls_quic_stun.tls_quic.issuerDN);
4299 
4300       if(flow->protos.tls_quic_stun.tls_quic.subjectDN)
4301 	ndpi_free(flow->protos.tls_quic_stun.tls_quic.subjectDN);
4302 
4303       if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni)
4304 	ndpi_free(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni);
4305     }
4306 
4307     if(flow->l4_proto == IPPROTO_TCP) {
4308       if(flow->l4.tcp.tls.message.buffer)
4309 	ndpi_free(flow->l4.tcp.tls.message.buffer);
4310     }
4311 
4312     if(flow->l4_proto == IPPROTO_UDP) {
4313       if(flow->l4.udp.quic_reasm_buf)
4314 	ndpi_free(flow->l4.udp.quic_reasm_buf);
4315     }
4316   }
4317 }
4318 
4319 /* ************************************************ */
4320 
ndpi_init_packet_header(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,unsigned short packetlen)4321 static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str,
4322 				   struct ndpi_flow_struct *flow,
4323                                    unsigned short packetlen) {
4324   const struct ndpi_iphdr *decaps_iph = NULL;
4325   u_int16_t l3len;
4326   u_int16_t l4len;
4327   const u_int8_t *l4ptr;
4328   u_int8_t l4protocol;
4329   u_int8_t l4_result;
4330 
4331   if(!flow)
4332     return(1);
4333 
4334   /* reset payload_packet_len, will be set if ipv4 tcp or udp */
4335   flow->packet.payload_packet_len = 0;
4336   flow->packet.l4_packet_len = 0;
4337   flow->packet.l3_packet_len = packetlen;
4338 
4339   flow->packet.tcp = NULL, flow->packet.udp = NULL;
4340   flow->packet.generic_l4_ptr = NULL;
4341   flow->packet.iphv6 = NULL;
4342 
4343   ndpi_apply_flow_protocol_to_packet(flow, &flow->packet);
4344 
4345   l3len = flow->packet.l3_packet_len;
4346 
4347   if(flow->packet.iph != NULL)
4348     decaps_iph = flow->packet.iph;
4349 
4350   if(decaps_iph && decaps_iph->version == IPVERSION && decaps_iph->ihl >= 5) {
4351     NDPI_LOG_DBG2(ndpi_str, "ipv4 header\n");
4352   } else if(decaps_iph && decaps_iph->version == 6 && l3len >= sizeof(struct ndpi_ipv6hdr) &&
4353 	    (ndpi_str->ip_version_limit & NDPI_DETECTION_ONLY_IPV4) == 0) {
4354     NDPI_LOG_DBG2(ndpi_str, "ipv6 header\n");
4355     flow->packet.iphv6 = (struct ndpi_ipv6hdr *) flow->packet.iph;
4356     flow->packet.iph = NULL;
4357   } else {
4358     flow->packet.iph = NULL;
4359     return(1);
4360   }
4361 
4362   /* needed:
4363    *  - unfragmented packets
4364    *  - ip header <= packet len
4365    *  - ip total length >= packet len
4366    */
4367 
4368   l4ptr = NULL;
4369   l4len = 0;
4370   l4protocol = 0;
4371 
4372   l4_result =
4373     ndpi_detection_get_l4_internal(ndpi_str, (const u_int8_t *) decaps_iph, l3len, &l4ptr, &l4len, &l4protocol, 0);
4374 
4375   if(l4_result != 0) {
4376     return(1);
4377   }
4378 
4379   flow->packet.l4_protocol = l4protocol;
4380   flow->packet.l4_packet_len = l4len;
4381   flow->l4_proto = l4protocol;
4382 
4383   /* TCP / UDP detection */
4384   if(l4protocol == IPPROTO_TCP && flow->packet.l4_packet_len >= 20 /* min size of tcp */) {
4385     /* tcp */
4386     flow->packet.tcp = (struct ndpi_tcphdr *) l4ptr;
4387     if(flow->packet.l4_packet_len >= flow->packet.tcp->doff * 4) {
4388       flow->packet.payload_packet_len = flow->packet.l4_packet_len - flow->packet.tcp->doff * 4;
4389       flow->packet.actual_payload_len = flow->packet.payload_packet_len;
4390       flow->packet.payload = ((u_int8_t *) flow->packet.tcp) + (flow->packet.tcp->doff * 4);
4391 
4392       /* check for new tcp syn packets, here
4393        * idea: reset detection state if a connection is unknown
4394        */
4395       if(flow->packet.tcp->syn != 0 && flow->packet.tcp->ack == 0 && flow->init_finished != 0 &&
4396 	 flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
4397 
4398 	u_int16_t guessed_protocol_id, guessed_host_protocol_id;
4399 	u_int16_t packet_direction_counter[2];
4400         u_int8_t num_processed_pkts;
4401 	struct packet_save {
4402 	  const struct ndpi_iphdr *iph;
4403 	  const struct ndpi_ipv6hdr *iphv6;
4404 	  const u_int8_t *payload;
4405 	  u_int64_t current_time_ms;
4406 	  u_int16_t l3_packet_len;
4407 	  u_int16_t l4_packet_len;
4408 	  u_int16_t payload_packet_len;
4409 	  u_int16_t actual_payload_len;
4410 	  u_int8_t l4_protocol;
4411 	} packet;
4412 
4413 #define flow_save(a) a = flow->a
4414 #define flow_restore(a) flow->a = a
4415 
4416 	flow_save(packet_direction_counter[0]);
4417 	flow_save(packet_direction_counter[1]);
4418 	flow_save(num_processed_pkts);
4419 	flow_save(guessed_protocol_id);
4420 	flow_save(guessed_host_protocol_id);
4421 	flow_save(packet.iph);
4422 	flow_save(packet.iphv6);
4423 	flow_save(packet.payload);
4424 	flow_save(packet.current_time_ms);
4425 	flow_save(packet.l3_packet_len);
4426 	flow_save(packet.l4_packet_len);
4427 	flow_save(packet.payload_packet_len);
4428 	flow_save(packet.actual_payload_len);
4429 	flow_save(packet.l4_protocol);
4430 
4431         ndpi_free_flow_data(flow);
4432         memset(flow, 0, sizeof(*(flow)));
4433 
4434         /* Restore pointers */
4435         flow->packet.tcp = (struct ndpi_tcphdr *) l4ptr;
4436         flow->l4_proto = IPPROTO_TCP;
4437 
4438 	flow_restore(packet_direction_counter[0]);
4439 	flow_restore(packet_direction_counter[1]);
4440 	flow_restore(num_processed_pkts);
4441 	flow_restore(guessed_protocol_id);
4442 	flow_restore(guessed_host_protocol_id);
4443 	flow_restore(packet.iph);
4444 	flow_restore(packet.iphv6);
4445 	flow_restore(packet.payload);
4446 	flow_restore(packet.current_time_ms);
4447 	flow_restore(packet.l3_packet_len);
4448 	flow_restore(packet.l4_packet_len);
4449 	flow_restore(packet.payload_packet_len);
4450 	flow_restore(packet.actual_payload_len);
4451 	flow_restore(packet.l4_protocol);
4452 
4453 #undef flow_save
4454 #undef flow_restore
4455 
4456         NDPI_LOG_DBG(ndpi_str, "tcp syn packet for unknown protocol, reset detection state\n");
4457       }
4458     } else {
4459       /* tcp header not complete */
4460       flow->packet.tcp = NULL;
4461     }
4462   } else if(l4protocol == IPPROTO_UDP && flow->packet.l4_packet_len >= 8 /* size of udp */) {
4463     flow->packet.udp = (struct ndpi_udphdr *) l4ptr;
4464     flow->packet.payload_packet_len = flow->packet.l4_packet_len - 8;
4465     flow->packet.payload = ((u_int8_t *) flow->packet.udp) + 8;
4466   } else if((l4protocol == IPPROTO_ICMP && flow->packet.l4_packet_len >= sizeof(struct ndpi_icmphdr))
4467 	    || (l4protocol == IPPROTO_ICMPV6 && flow->packet.l4_packet_len >= sizeof(struct ndpi_icmp6hdr))) {
4468     flow->packet.payload = ((u_int8_t *) l4ptr);
4469     flow->packet.payload_packet_len = flow->packet.l4_packet_len;
4470   } else {
4471     flow->packet.generic_l4_ptr = l4ptr;
4472   }
4473 
4474   return(0);
4475 }
4476 
4477 /* ************************************************ */
4478 
4479 
ndpi_connection_tracking(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow)4480 void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
4481 			      struct ndpi_flow_struct *flow) {
4482   if(!flow) {
4483     return;
4484   } else {
4485     /* const for gcc code optimization and cleaner code */
4486     struct ndpi_packet_struct *packet = &flow->packet;
4487     const struct ndpi_iphdr *iph = packet->iph;
4488     const struct ndpi_ipv6hdr *iphv6 = packet->iphv6;
4489     const struct ndpi_tcphdr *tcph = packet->tcp;
4490     const struct ndpi_udphdr *udph = packet->udp;
4491 
4492     packet->tcp_retransmission = 0, packet->packet_direction = 0;
4493 
4494     if(ndpi_str->direction_detect_disable) {
4495       packet->packet_direction = flow->packet_direction;
4496     } else {
4497       if(iph != NULL && ntohl(iph->saddr) < ntohl(iph->daddr))
4498 	packet->packet_direction = 1;
4499 
4500       if((iphv6 != NULL)
4501 	 && NDPI_COMPARE_IPV6_ADDRESS_STRUCTS(&iphv6->ip6_src, &iphv6->ip6_dst) != 0)
4502 	packet->packet_direction = 1;
4503     }
4504 
4505     packet->packet_lines_parsed_complete = 0;
4506 
4507     if(flow->init_finished == 0) {
4508       flow->init_finished = 1;
4509       flow->setup_packet_direction = packet->packet_direction;
4510     }
4511 
4512     if(tcph != NULL) {
4513       /* reset retried bytes here before setting it */
4514       packet->num_retried_bytes = 0;
4515 
4516       if(!ndpi_str->direction_detect_disable)
4517 	packet->packet_direction = (ntohs(tcph->source) < ntohs(tcph->dest)) ? 1 : 0;
4518 
4519       if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0 &&
4520 	 flow->l4.tcp.seen_ack == 0) {
4521 	flow->l4.tcp.seen_syn = 1;
4522       } else
4523 	if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0 &&
4524 	   flow->l4.tcp.seen_ack == 0) {
4525 	  flow->l4.tcp.seen_syn_ack = 1;
4526 	} else
4527 	  if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 &&
4528 	     flow->l4.tcp.seen_ack == 0) {
4529 	    flow->l4.tcp.seen_ack = 1;
4530 	  }
4531 
4532       if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0) ||
4533 	 (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0)) {
4534 	/* initialize tcp sequence counters */
4535 	/* the ack flag needs to be set to get valid sequence numbers from the other
4536 	 * direction. Usually it will catch the second packet syn+ack but it works
4537 	 * also for asymmetric traffic where it will use the first data packet
4538 	 *
4539 	 * if the syn flag is set add one to the sequence number,
4540 	 * otherwise use the payload length.
4541 	 */
4542 	if(tcph->ack != 0) {
4543 	  flow->next_tcp_seq_nr[flow->packet.packet_direction] =
4544 	    ntohl(tcph->seq) + (tcph->syn ? 1 : packet->payload_packet_len);
4545 
4546 	  /*
4547 	    Check to avoid discrepancies in case we analyze a flow that does not start with SYN...
4548 	    but that is already started when nDPI being to process it. See also (***) below
4549 	  */
4550 	  if(flow->num_processed_pkts > 1)
4551 	    flow->next_tcp_seq_nr[1 - flow->packet.packet_direction] = ntohl(tcph->ack_seq);
4552 	}
4553       } else if(packet->payload_packet_len > 0) {
4554 	/* check tcp sequence counters */
4555 	if(((u_int32_t)(ntohl(tcph->seq) - flow->next_tcp_seq_nr[packet->packet_direction])) >
4556 	   ndpi_str->tcp_max_retransmission_window_size) {
4557 	  packet->tcp_retransmission = 1;
4558 
4559 	  /* CHECK IF PARTIAL RETRY IS HAPPENING */
4560 	  if((flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq) <
4561 	      packet->payload_packet_len)) {
4562 	    /* num_retried_bytes actual_payload_len hold info about the partial retry
4563 	       analyzer which require this info can make use of this info
4564 	       Other analyzer can use packet->payload_packet_len */
4565 	    packet->num_retried_bytes =
4566 	      (u_int16_t)(flow->next_tcp_seq_nr[packet->packet_direction] - ntohl(tcph->seq));
4567 	    packet->actual_payload_len = packet->payload_packet_len - packet->num_retried_bytes;
4568 
4569 	    if(flow->num_processed_pkts > 1) /* See also (***) above */
4570 	      flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
4571 	  }
4572 	}
4573 
4574 	/* normal path
4575 	   actual_payload_len is initialized to payload_packet_len during tcp header parsing itself.
4576 	   It will be changed only in case of retransmission */
4577 	else {
4578 	  packet->num_retried_bytes = 0;
4579 	  flow->next_tcp_seq_nr[packet->packet_direction] = ntohl(tcph->seq) + packet->payload_packet_len;
4580 	}
4581       }
4582 
4583       if(tcph->rst) {
4584 	flow->next_tcp_seq_nr[0] = 0;
4585 	flow->next_tcp_seq_nr[1] = 0;
4586       }
4587     } else if(udph != NULL) {
4588       if(!ndpi_str->direction_detect_disable)
4589 	packet->packet_direction = (htons(udph->source) < htons(udph->dest)) ? 1 : 0;
4590     }
4591 
4592     if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) {
4593       flow->packet_counter++;
4594     }
4595 
4596     if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER &&
4597        packet->payload_packet_len) {
4598       flow->packet_direction_counter[packet->packet_direction]++;
4599     }
4600 
4601     if(flow->byte_counter[packet->packet_direction] + packet->payload_packet_len >
4602        flow->byte_counter[packet->packet_direction]) {
4603       flow->byte_counter[packet->packet_direction] += packet->payload_packet_len;
4604     }
4605   }
4606 }
4607 
4608 /* ************************************************ */
4609 
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)4610 static u_int32_t check_ndpi_detection_func(struct ndpi_detection_module_struct * const ndpi_str,
4611 					   struct ndpi_flow_struct * const flow,
4612 					   NDPI_SELECTION_BITMASK_PROTOCOL_SIZE const ndpi_selection_packet,
4613 					   struct ndpi_call_function_struct const * const callback_buffer,
4614 					   uint32_t callback_buffer_size)
4615 {
4616   void *func = NULL;
4617   u_int8_t is_tcp_without_payload = (callback_buffer == ndpi_str->callback_buffer_tcp_no_payload);
4618   u_int32_t num_calls = (is_tcp_without_payload != 0 ? 1 : 0);
4619   u_int16_t proto_index = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoIdx;
4620   u_int16_t proto_id = ndpi_str->proto_defaults[flow->guessed_protocol_id].protoId;
4621   NDPI_PROTOCOL_BITMASK detection_bitmask;
4622 
4623   NDPI_SAVE_AS_BITMASK(detection_bitmask, flow->packet.detected_protocol_stack[0]);
4624 
4625   if ((proto_id != NDPI_PROTOCOL_UNKNOWN) &&
4626       NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
4627 			   ndpi_str->callback_buffer[proto_index].excluded_protocol_bitmask) == 0 &&
4628       NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[proto_index].detection_bitmask, detection_bitmask) != 0 &&
4629       (ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask & ndpi_selection_packet) ==
4630       ndpi_str->callback_buffer[proto_index].ndpi_selection_bitmask)
4631     {
4632       if ((flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
4633           (ndpi_str->proto_defaults[flow->guessed_protocol_id].func != NULL) &&
4634           (is_tcp_without_payload == 0 ||
4635            ((ndpi_str->callback_buffer[flow->guessed_protocol_id].ndpi_selection_bitmask &
4636 	     NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD) == 0)))
4637 	{
4638 	  ndpi_str->proto_defaults[flow->guessed_protocol_id].func(ndpi_str, flow);
4639 	  func = ndpi_str->proto_defaults[flow->guessed_protocol_id].func;
4640 	  num_calls++;
4641 	}
4642     }
4643 
4644   if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
4645     {
4646       for (u_int32_t a = 0; a < callback_buffer_size; a++) {
4647         if ((func != callback_buffer[a].func) &&
4648             (callback_buffer[a].ndpi_selection_bitmask & ndpi_selection_packet) ==
4649 	    callback_buffer[a].ndpi_selection_bitmask &&
4650             NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
4651                                  callback_buffer[a].excluded_protocol_bitmask) == 0 &&
4652             NDPI_BITMASK_COMPARE(callback_buffer[a].detection_bitmask,
4653                                  detection_bitmask) != 0)
4654 	  {
4655 	    callback_buffer[a].func(ndpi_str, flow);
4656 	    num_calls++;
4657 
4658 	    if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
4659 	      {
4660 		break; /* Stop after the first detected protocol. */
4661 	      }
4662 	  }
4663       }
4664     }
4665 
4666   /* Check for subprotocols. */
4667   for (u_int32_t a = 0; a < ndpi_str->proto_defaults[flow->detected_protocol_stack[0]].subprotocol_count; a++)
4668     {
4669       u_int16_t subproto_id = ndpi_str->proto_defaults[flow->detected_protocol_stack[0]].subprotocols[a];
4670       if (subproto_id == (uint16_t)NDPI_PROTOCOL_MATCHED_BY_CONTENT)
4671 	{
4672 	  continue;
4673 	}
4674 
4675       u_int16_t subproto_index = ndpi_str->proto_defaults[subproto_id].protoIdx;
4676       if ((func != ndpi_str->proto_defaults[subproto_id].func) &&
4677           (ndpi_str->callback_buffer[subproto_index].ndpi_selection_bitmask & ndpi_selection_packet) ==
4678 	  ndpi_str->callback_buffer[subproto_index].ndpi_selection_bitmask &&
4679           NDPI_BITMASK_COMPARE(flow->excluded_protocol_bitmask,
4680                                ndpi_str->callback_buffer[subproto_index].excluded_protocol_bitmask) == 0 &&
4681           NDPI_BITMASK_COMPARE(ndpi_str->callback_buffer[subproto_index].detection_bitmask,
4682                                detection_bitmask) != 0)
4683 	{
4684 	  ndpi_str->callback_buffer[subproto_index].func(ndpi_str, flow);
4685 	  num_calls++;
4686 	}
4687 
4688       if (flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
4689 	{
4690 	  break; /* Stop after the first detected subprotocol. */
4691 	}
4692     }
4693 
4694   return num_calls;
4695 }
4696 
4697 /* ************************************************ */
4698 
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)4699 u_int32_t check_ndpi_other_flow_func(struct ndpi_detection_module_struct *ndpi_str,
4700 				     struct ndpi_flow_struct *flow,
4701 				     NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
4702 {
4703   return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
4704 				   ndpi_str->callback_buffer_non_tcp_udp,
4705 				   ndpi_str->callback_buffer_size_non_tcp_udp);
4706 }
4707 
4708 /* ************************************************ */
4709 
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)4710 static u_int32_t check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
4711 					  struct ndpi_flow_struct *flow,
4712 					  NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
4713 {
4714   return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
4715 				   ndpi_str->callback_buffer_udp,
4716 				   ndpi_str->callback_buffer_size_udp);
4717 }
4718 
4719 /* ************************************************ */
4720 
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)4721 static u_int32_t check_ndpi_tcp_flow_func(struct ndpi_detection_module_struct *ndpi_str,
4722 					  struct ndpi_flow_struct *flow,
4723 					  NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet)
4724 {
4725   if (flow->packet.payload_packet_len != 0) {
4726     return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
4727 				     ndpi_str->callback_buffer_tcp_payload,
4728 				     ndpi_str->callback_buffer_size_tcp_payload);
4729   } else {
4730     /* no payload */
4731     return check_ndpi_detection_func(ndpi_str, flow, *ndpi_selection_packet,
4732 				     ndpi_str->callback_buffer_tcp_no_payload,
4733 				     ndpi_str->callback_buffer_size_tcp_no_payload);
4734   }
4735 }
4736 
4737 /* ********************************************************************************* */
4738 
ndpi_check_flow_func(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,NDPI_SELECTION_BITMASK_PROTOCOL_SIZE * ndpi_selection_packet)4739 u_int32_t ndpi_check_flow_func(struct ndpi_detection_module_struct *ndpi_str,
4740 			       struct ndpi_flow_struct *flow,
4741 			       NDPI_SELECTION_BITMASK_PROTOCOL_SIZE *ndpi_selection_packet) {
4742   if(!flow)
4743     return(0);
4744   else if(flow->packet.tcp != NULL)
4745     return(check_ndpi_tcp_flow_func(ndpi_str, flow, ndpi_selection_packet));
4746   else if(flow->packet.udp != NULL)
4747     return(check_ndpi_udp_flow_func(ndpi_str, flow, ndpi_selection_packet));
4748   else
4749     return(check_ndpi_other_flow_func(ndpi_str, flow, ndpi_selection_packet));
4750 }
4751 
4752 /* ********************************************************************************* */
4753 
ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow)4754 u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
4755 				      struct ndpi_flow_struct *flow) {
4756   u_int16_t ret = NDPI_PROTOCOL_UNKNOWN;
4757 
4758   if(flow->packet.iph) {
4759     struct in_addr addr;
4760     u_int16_t sport, dport;
4761 
4762     addr.s_addr = flow->packet.iph->saddr;
4763 
4764     if((flow->l4_proto == IPPROTO_TCP) && flow->packet.tcp)
4765       sport = flow->packet.tcp->source, dport = flow->packet.tcp->dest;
4766     else if((flow->l4_proto == IPPROTO_UDP) && flow->packet.udp)
4767       sport = flow->packet.udp->source, dport = flow->packet.udp->dest;
4768     else
4769       sport = dport = 0;
4770 
4771     /* guess host protocol */
4772     ret = ndpi_network_port_ptree_match(ndpi_str, &addr, sport);
4773 
4774     if(ret == NDPI_PROTOCOL_UNKNOWN) {
4775       addr.s_addr = flow->packet.iph->daddr;
4776       ret = ndpi_network_port_ptree_match(ndpi_str, &addr, dport);
4777     }
4778   }
4779 
4780   return(ret);
4781 }
4782 
4783 /* ********************************************************************************* */
4784 
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)4785 ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
4786 				    u_int8_t enable_guess, u_int8_t *protocol_was_guessed) {
4787   ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
4788 
4789   *protocol_was_guessed = 0;
4790 
4791   if(flow == NULL)
4792     return(ret);
4793 
4794   /* Init defaults */
4795   ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
4796   ret.category = flow->category;
4797 
4798   /* Ensure that we don't change our mind if detection is already complete */
4799   if((ret.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
4800     return(ret);
4801 
4802   if(ndpi_str->mining_cache && flow->packet.iph) {
4803     u_int16_t cached_proto;
4804     u_int32_t key = flow->packet.iph->saddr + flow->packet.iph->daddr;
4805 
4806     if(ndpi_lru_find_cache(ndpi_str->mining_cache, key,
4807 			   &cached_proto, 0 /* Don't remove it as it can be used for other connections */)) {
4808       ndpi_set_detected_protocol(ndpi_str, flow, cached_proto, NDPI_PROTOCOL_UNKNOWN);
4809       ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
4810       return(ret);
4811     }
4812   }
4813 
4814   /* TODO: add the remaining stage_XXXX protocols */
4815   if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
4816     u_int16_t guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN, guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
4817 
4818     if(flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)
4819       goto check_stun_export;
4820     else if((flow->guessed_protocol_id == NDPI_PROTOCOL_HANGOUT_DUO) ||
4821 	    (flow->guessed_protocol_id == NDPI_PROTOCOL_MESSENGER) ||
4822 	    (flow->guessed_protocol_id == NDPI_PROTOCOL_WHATSAPP_CALL)) {
4823       *protocol_was_guessed = 1;
4824       ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_protocol_id, NDPI_PROTOCOL_UNKNOWN);
4825     }
4826     else if((flow->l4.tcp.tls.hello_processed == 1) &&
4827 	    (flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0')) {
4828       *protocol_was_guessed = 1;
4829       ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_TLS, NDPI_PROTOCOL_UNKNOWN);
4830     } else if(enable_guess) {
4831       if((flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) && (flow->packet.l4_protocol == IPPROTO_TCP) &&
4832 	 flow->l4.tcp.tls.hello_processed)
4833 	flow->guessed_protocol_id = NDPI_PROTOCOL_TLS;
4834 
4835       guessed_protocol_id = flow->guessed_protocol_id, guessed_host_protocol_id = flow->guessed_host_protocol_id;
4836 
4837       if((guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
4838 	 ((flow->packet.l4_protocol == IPPROTO_UDP) &&
4839 	  NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_host_protocol_id) &&
4840 	  is_udp_guessable_protocol(guessed_host_protocol_id)))
4841 	flow->guessed_host_protocol_id = guessed_host_protocol_id = NDPI_PROTOCOL_UNKNOWN;
4842 
4843       /* Ignore guessed protocol if they have been discarded */
4844       if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)
4845 	 // && (guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN)
4846 	 && (flow->packet.l4_protocol == IPPROTO_UDP) &&
4847 	 NDPI_ISSET(&flow->excluded_protocol_bitmask, guessed_protocol_id) &&
4848 	 is_udp_guessable_protocol(guessed_protocol_id))
4849 	flow->guessed_protocol_id = guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN;
4850 
4851       if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) || (guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
4852 	if((guessed_protocol_id == 0) && (flow->protos.tls_quic_stun.stun.num_binding_requests > 0) &&
4853 	   (flow->protos.tls_quic_stun.stun.num_processed_pkts > 0))
4854 	  guessed_protocol_id = NDPI_PROTOCOL_STUN;
4855 
4856 	if(flow->host_server_name[0] != '\0') {
4857 	  ndpi_protocol_match_result ret_match;
4858 
4859 	  memset(&ret_match, 0, sizeof(ret_match));
4860 
4861 	  ndpi_match_host_subprotocol(ndpi_str, flow, (char *) flow->host_server_name,
4862 				      strlen((const char *) flow->host_server_name), &ret_match,
4863 				      NDPI_PROTOCOL_DNS);
4864 
4865 	  if(ret_match.protocol_id != NDPI_PROTOCOL_UNKNOWN)
4866 	    guessed_host_protocol_id = ret_match.protocol_id;
4867 	}
4868 
4869 	*protocol_was_guessed = 1;
4870 	ndpi_int_change_protocol(ndpi_str, flow, guessed_host_protocol_id, guessed_protocol_id);
4871       }
4872     }
4873   } else if(enable_guess) {
4874     if(flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
4875       *protocol_was_guessed = 1;
4876       flow->detected_protocol_stack[1] = flow->guessed_protocol_id;
4877     }
4878 
4879     if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
4880       *protocol_was_guessed = 1;
4881       flow->detected_protocol_stack[0] = flow->guessed_host_protocol_id;
4882     }
4883 
4884     if(flow->detected_protocol_stack[1] == flow->detected_protocol_stack[0]) {
4885       *protocol_was_guessed = 1;
4886       flow->detected_protocol_stack[1] = flow->guessed_host_protocol_id;
4887     }
4888   }
4889 
4890   if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) &&
4891      (flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)) {
4892   check_stun_export:
4893     /* if(flow->protos.tls_quic_stun.stun.num_processed_pkts || flow->protos.tls_quic_stun.stun.num_udp_pkts) */
4894     {
4895       // if(/* (flow->protos.tls_quic_stun.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */
4896       *protocol_was_guessed = 1;
4897       ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_STUN);
4898     }
4899   }
4900 
4901   ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
4902 
4903   if(ret.master_protocol == NDPI_PROTOCOL_STUN) {
4904     if(ret.app_protocol == NDPI_PROTOCOL_FACEBOOK)
4905       ret.app_protocol = NDPI_PROTOCOL_MESSENGER;
4906     else if(ret.app_protocol == NDPI_PROTOCOL_GOOGLE) {
4907       /*
4908 	As Google has recently introduced Duo,
4909 	we need to distinguish between it and hangout
4910 	thing that should be handled by the STUN dissector
4911       */
4912       ret.app_protocol = NDPI_PROTOCOL_HANGOUT_DUO;
4913     }
4914   }
4915 
4916   if(ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) {
4917     *protocol_was_guessed = 1;
4918     ndpi_fill_protocol_category(ndpi_str, flow, &ret);
4919   }
4920 
4921   return(ret);
4922 }
4923 
4924 /* ********************************************************************************* */
4925 
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)4926 void ndpi_process_extra_packet(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
4927 			       const unsigned char *packet, const unsigned short packetlen,
4928 			       const u_int64_t current_time_ms, struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
4929   if(flow == NULL)
4930     return;
4931 
4932   if(flow->server_id == NULL)
4933     flow->server_id = dst; /* Default */
4934 
4935   /* need at least 20 bytes for ip header */
4936   if(packetlen < 20) {
4937     return;
4938   }
4939 
4940   flow->packet.current_time_ms = current_time_ms;
4941 
4942   /* parse packet */
4943   flow->packet.iph = (struct ndpi_iphdr *) packet;
4944   /* we are interested in ipv4 packet */
4945 
4946   /* set up the packet headers for the extra packet function to use if it wants */
4947   if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
4948     return;
4949 
4950   /* detect traffic for tcp or udp only */
4951   flow->src = src, flow->dst = dst;
4952 
4953   ndpi_connection_tracking(ndpi_str, flow);
4954 
4955   /* call the extra packet function (which may add more data/info to flow) */
4956   if(flow->extra_packets_func) {
4957     if((flow->extra_packets_func(ndpi_str, flow)) == 0)
4958       flow->check_extra_packets = 0;
4959 
4960     if(++flow->num_extra_packets_checked == flow->max_extra_packets_to_check)
4961       flow->extra_packets_func = NULL; /* Enough packets detected */
4962   }
4963 }
4964 
4965 /* ********************************************************************************* */
4966 
ndpi_load_ip_category(struct ndpi_detection_module_struct * ndpi_str,const char * ip_address_and_mask,ndpi_protocol_category_t category)4967 int ndpi_load_ip_category(struct ndpi_detection_module_struct *ndpi_str, const char *ip_address_and_mask,
4968 			  ndpi_protocol_category_t category) {
4969   ndpi_patricia_node_t *node;
4970   struct in_addr pin;
4971   int bits = 32;
4972   char *ptr;
4973   char ipbuf[64];
4974 
4975   strncpy(ipbuf, ip_address_and_mask, sizeof(ipbuf));
4976   ipbuf[sizeof(ipbuf) - 1] = '\0';
4977 
4978   ptr = strrchr(ipbuf, '/');
4979 
4980   if(ptr) {
4981     *(ptr++) = '\0';
4982     if(atoi(ptr) >= 0 && atoi(ptr) <= 32)
4983       bits = atoi(ptr);
4984   }
4985 
4986   if(inet_pton(AF_INET, ipbuf, &pin) != 1) {
4987     NDPI_LOG_DBG2(ndpi_str, "Invalid ip/ip+netmask: %s\n", ip_address_and_mask);
4988     return(-1);
4989   }
4990 
4991   if((node = add_to_ptree(ndpi_str->custom_categories.ipAddresses_shadow, AF_INET, &pin, bits)) != NULL) {
4992     node->value.u.uv32.user_value = (u_int16_t)category, node->value.u.uv32.additional_user_value = 0;
4993   }
4994 
4995   return(0);
4996 }
4997 
4998 
4999 /* ********************************************************************************* */
5000 
ndpi_load_hostname_category(struct ndpi_detection_module_struct * ndpi_str,const char * name_to_add,ndpi_protocol_category_t category)5001 int ndpi_load_hostname_category(struct ndpi_detection_module_struct *ndpi_str, const char *name_to_add,
5002 				ndpi_protocol_category_t category) {
5003 
5004   if(ndpi_str->custom_categories.hostnames_shadow.ac_automa == NULL)
5005     return(-1);
5006 
5007   if(name_to_add == NULL)
5008     return(-1);
5009 
5010   return ndpi_string_to_automa(ndpi_str,(AC_AUTOMATA_t *)ndpi_str->custom_categories.hostnames_shadow.ac_automa,
5011 			       name_to_add,category,category, 0, 0, 1); /* at_end */
5012 }
5013 
5014 /* ********************************************************************************* */
5015 
5016 /* Loads an IP or name category */
ndpi_load_category(struct ndpi_detection_module_struct * ndpi_struct,const char * ip_or_name,ndpi_protocol_category_t category)5017 int ndpi_load_category(struct ndpi_detection_module_struct *ndpi_struct, const char *ip_or_name,
5018 		       ndpi_protocol_category_t category) {
5019   int rv;
5020 
5021   /* Try to load as IP address first */
5022   rv = ndpi_load_ip_category(ndpi_struct, ip_or_name, category);
5023 
5024   if(rv < 0) {
5025     /* IP load failed, load as hostname */
5026     rv = ndpi_load_hostname_category(ndpi_struct, ip_or_name, category);
5027   }
5028 
5029   return(rv);
5030 }
5031 
5032 /* ********************************************************************************* */
5033 
ndpi_enable_loaded_categories(struct ndpi_detection_module_struct * ndpi_str)5034 int ndpi_enable_loaded_categories(struct ndpi_detection_module_struct *ndpi_str) {
5035   int i;
5036 
5037   /* First add the nDPI known categories matches */
5038   for(i = 0; category_match[i].string_to_match != NULL; i++)
5039     ndpi_load_category(ndpi_str, category_match[i].string_to_match, category_match[i].protocol_category);
5040 
5041   /* Free */
5042   ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
5043 		      1 /* free patterns strings memory */);
5044 
5045   /* Finalize */
5046   ac_automata_finalize((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames_shadow.ac_automa);
5047 
5048   /* Swap */
5049   ndpi_str->custom_categories.hostnames.ac_automa = ndpi_str->custom_categories.hostnames_shadow.ac_automa;
5050 
5051   /* Realloc */
5052   ndpi_str->custom_categories.hostnames_shadow.ac_automa = ac_automata_init(ac_domain_match_handler);
5053   if(ndpi_str->custom_categories.hostnames_shadow.ac_automa) {
5054     ac_automata_feature(ndpi_str->custom_categories.hostnames_shadow.ac_automa,AC_FEATURE_LC);
5055     ac_automata_name(ndpi_str->custom_categories.hostnames_shadow.ac_automa,"ccat_sh",0);
5056   }
5057 
5058   if(ndpi_str->custom_categories.ipAddresses != NULL)
5059     ndpi_patricia_destroy((ndpi_patricia_tree_t *) ndpi_str->custom_categories.ipAddresses, free_ptree_data);
5060 
5061   ndpi_str->custom_categories.ipAddresses = ndpi_str->custom_categories.ipAddresses_shadow;
5062   ndpi_str->custom_categories.ipAddresses_shadow = ndpi_patricia_new(32 /* IPv4 */);
5063 
5064   ndpi_str->custom_categories.categories_loaded = 1;
5065 
5066   return(0);
5067 }
5068 
5069 /* ********************************************************************************* */
5070 
ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct * ndpi_str,u_int32_t saddr,u_int32_t daddr,ndpi_protocol * ret)5071 int ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct *ndpi_str, u_int32_t saddr, u_int32_t daddr,
5072 				   ndpi_protocol *ret) {
5073   if(ndpi_str->custom_categories.categories_loaded) {
5074     ndpi_prefix_t prefix;
5075     ndpi_patricia_node_t *node;
5076 
5077     if(saddr == 0)
5078       node = NULL;
5079     else {
5080       /* Make sure all in network byte order otherwise compares wont work */
5081       ndpi_fill_prefix_v4(&prefix, (struct in_addr *) &saddr, 32,
5082 			  ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
5083       node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
5084     }
5085 
5086     if(!node) {
5087       if(daddr != 0) {
5088 	ndpi_fill_prefix_v4(&prefix, (struct in_addr *) &daddr, 32,
5089 			    ((ndpi_patricia_tree_t *) ndpi_str->protocols_ptree)->maxbits);
5090 	node = ndpi_patricia_search_best(ndpi_str->custom_categories.ipAddresses, &prefix);
5091       }
5092     }
5093 
5094     if(node) {
5095       ret->category = (ndpi_protocol_category_t) node->value.u.uv32.user_value;
5096 
5097       return(1);
5098     }
5099   }
5100 
5101   ret->category = ndpi_get_proto_category(ndpi_str, *ret);
5102 
5103   return(0);
5104 }
5105 
5106 /* ********************************************************************************* */
5107 
ndpi_fill_protocol_category(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,ndpi_protocol * ret)5108 void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
5109 				 ndpi_protocol *ret) {
5110   if((ret->master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret->app_protocol == NDPI_PROTOCOL_UNKNOWN))
5111     return;
5112 
5113   if(ndpi_str->custom_categories.categories_loaded) {
5114     if(flow->guessed_header_category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) {
5115       flow->category = ret->category = flow->guessed_header_category;
5116       return;
5117     }
5118 
5119     if(flow->host_server_name[0] != '\0') {
5120       u_int32_t id;
5121       int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->host_server_name,
5122 					  strlen((char *) flow->host_server_name), &id);
5123 
5124       if(rc == 0) {
5125 	flow->category = ret->category = (ndpi_protocol_category_t) id;
5126 	return;
5127       }
5128     }
5129 
5130     if(flow->l4.tcp.tls.hello_processed == 1 &&
5131        flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') {
5132       u_int32_t id;
5133       int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.tls_quic_stun.tls_quic.client_requested_server_name,
5134 					  strlen(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), &id);
5135 
5136       if(rc == 0) {
5137 	flow->category = ret->category = (ndpi_protocol_category_t) id;
5138 	return;
5139       }
5140     }
5141   }
5142 
5143   flow->category = ret->category = ndpi_get_proto_category(ndpi_str, *ret);
5144 }
5145 
5146 /* ********************************************************************************* */
5147 
ndpi_reset_packet_line_info(struct ndpi_packet_struct * packet)5148 static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet) {
5149   packet->parsed_lines = 0, packet->empty_line_position_set = 0, packet->host_line.ptr = NULL,
5150     packet->host_line.len = 0, packet->referer_line.ptr = NULL, packet->referer_line.len = 0,
5151     packet->content_line.ptr = NULL, packet->content_line.len = 0, packet->accept_line.ptr = NULL,
5152     packet->accept_line.len = 0, packet->user_agent_line.ptr = NULL, packet->user_agent_line.len = 0,
5153     packet->http_url_name.ptr = NULL, packet->http_url_name.len = 0, packet->http_encoding.ptr = NULL,
5154     packet->http_encoding.len = 0, packet->http_transfer_encoding.ptr = NULL, packet->http_transfer_encoding.len = 0,
5155     packet->http_contentlen.ptr = NULL, packet->http_contentlen.len = 0, packet->content_disposition_line.ptr = NULL,
5156     packet->content_disposition_line.len = 0, packet->http_cookie.ptr = NULL,
5157     packet->http_cookie.len = 0, packet->http_origin.len = 0, packet->http_origin.ptr = NULL,
5158     packet->http_x_session_type.ptr = NULL, packet->http_x_session_type.len = 0, packet->server_line.ptr = NULL,
5159     packet->server_line.len = 0, packet->http_method.ptr = NULL, packet->http_method.len = 0,
5160     packet->http_response.ptr = NULL, packet->http_response.len = 0, packet->http_num_headers = 0,
5161     packet->forwarded_line.ptr = NULL, packet->forwarded_line.len = 0;
5162 }
5163 
5164 /* ********************************************************************************* */
5165 
ndpi_is_ntop_protocol(ndpi_protocol * ret)5166 static int ndpi_is_ntop_protocol(ndpi_protocol *ret) {
5167   if((ret->master_protocol == NDPI_PROTOCOL_HTTP) && (ret->app_protocol == NDPI_PROTOCOL_NTOP))
5168     return(1);
5169   else
5170     return(0);
5171 }
5172 
5173 /* ********************************************************************************* */
5174 
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)5175 static int ndpi_check_protocol_port_mismatch_exceptions(struct ndpi_detection_module_struct *ndpi_str,
5176 							struct ndpi_flow_struct *flow,
5177 							ndpi_default_ports_tree_node_t *expected_proto,
5178 							ndpi_protocol *returned_proto) {
5179   /*
5180     For TLS (and other protocols) it is not simple to guess the exact protocol so before
5181     triggering an alert we need to make sure what we have exhausted all the possible
5182     options available
5183   */
5184 
5185   if(ndpi_is_ntop_protocol(returned_proto)) return(1);
5186 
5187   if(returned_proto->master_protocol == NDPI_PROTOCOL_TLS) {
5188     switch(expected_proto->proto->protoId) {
5189     case NDPI_PROTOCOL_MAIL_IMAPS:
5190     case NDPI_PROTOCOL_MAIL_POPS:
5191     case NDPI_PROTOCOL_MAIL_SMTPS:
5192       return(1); /* This is a reasonable exception */
5193       break;
5194     }
5195   }
5196 
5197   return(0);
5198 }
5199 
5200 /* ********************************************************************************* */
5201 
ndpi_reconcile_protocols(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,ndpi_protocol * ret)5202 static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_str,
5203 				     struct ndpi_flow_struct *flow,
5204 				     ndpi_protocol *ret) {
5205 
5206 #if 0
5207   if(flow) {
5208     /* Do not go for DNS when there is an application protocol. Example DNS.Apple */
5209     if((flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
5210        && (flow->detected_protocol_stack[0] /* app */ != flow->detected_protocol_stack[1] /* major */))
5211       NDPI_CLR_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
5212   }
5213 #endif
5214 
5215   // printf("====>> %u.%u [%u]\n", ret->master_protocol, ret->app_protocol, flow->detected_protocol_stack[0]);
5216 
5217   switch(ret->app_protocol) {
5218     /*
5219       Skype for a host doing MS Teams means MS Teams
5220       (MS Teams uses Skype as transport protocol for voice/video)
5221     */
5222   case NDPI_PROTOCOL_MSTEAMS:
5223     if(flow->packet.iph && flow->packet.tcp) {
5224       // printf("====>> NDPI_PROTOCOL_MSTEAMS\n");
5225 
5226       if(ndpi_str->msteams_cache == NULL)
5227 	ndpi_str->msteams_cache = ndpi_lru_cache_init(1024);
5228 
5229       if(ndpi_str->msteams_cache)
5230 	ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
5231 			      flow->packet.iph->saddr,
5232 			      (flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
5233     }
5234     break;
5235 
5236   case NDPI_PROTOCOL_SKYPE_TEAMS:
5237   case NDPI_PROTOCOL_SKYPE_CALL:
5238     if(flow->packet.iph
5239        && flow->packet.udp
5240        && ndpi_str->msteams_cache) {
5241       u_int16_t when;
5242 
5243       if(ndpi_lru_find_cache(ndpi_str->msteams_cache, flow->packet.iph->saddr,
5244 			     &when, 0 /* Don't remove it as it can be used for other connections */)) {
5245 	u_int16_t tdiff = ((flow->packet.current_time_ms /1000) & 0xFFFF) - when;
5246 
5247 	if(tdiff < 60 /* sec */) {
5248 	  // printf("====>> NDPI_PROTOCOL_SKYPE(_CALL) -> NDPI_PROTOCOL_MSTEAMS [%u]\n", tdiff);
5249 	  ret->app_protocol = NDPI_PROTOCOL_MSTEAMS;
5250 
5251 	  /* Refresh cache */
5252 	  ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
5253 				flow->packet.iph->saddr,
5254 				(flow->packet.current_time_ms / 1000) & 0xFFFF /* 16 bit */);
5255 	}
5256       }
5257     }
5258     break;
5259 
5260   case NDPI_PROTOCOL_ANYDESK:
5261     if(flow->packet.tcp) /* TCP only */
5262       ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */
5263     break;
5264   } /* switch */
5265 
5266   if(flow) {
5267     switch(ndpi_get_proto_breed(ndpi_str, ret->app_protocol)) {
5268     case NDPI_PROTOCOL_UNSAFE:
5269     case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
5270     case NDPI_PROTOCOL_DANGEROUS:
5271       ndpi_set_risk(ndpi_str, flow, NDPI_UNSAFE_PROTOCOL);
5272       break;
5273     default:
5274       /* Nothing to do */
5275       break;
5276     }
5277   }
5278 
5279 }
5280 
5281 /* ****************************************************** */
5282 
ndpi_do_guess(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,ndpi_protocol * ret)5283 static int ndpi_do_guess(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, ndpi_protocol *ret) {
5284   ret->master_protocol = ret->app_protocol = NDPI_PROTOCOL_UNKNOWN, ret->category = 0;
5285 
5286   if(flow->packet.iphv6 || flow->packet.iph) {
5287     u_int16_t sport, dport;
5288     u_int8_t protocol;
5289     u_int8_t user_defined_proto;
5290 
5291     if(flow->packet.iphv6 != NULL) {
5292       protocol = flow->packet.iphv6->ip6_hdr.ip6_un1_nxt;
5293     } else
5294       protocol = flow->packet.iph->protocol;
5295 
5296     if(flow->packet.udp)
5297       sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest);
5298     else if(flow->packet.tcp)
5299       sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
5300     else
5301       sport = dport = 0;
5302 
5303     /* guess protocol */
5304     flow->guessed_protocol_id      = (int16_t) ndpi_guess_protocol_id(ndpi_str, flow, protocol, sport, dport, &user_defined_proto);
5305     flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
5306 
5307     if(ndpi_str->custom_categories.categories_loaded && flow->packet.iph) {
5308       if(ndpi_str->ndpi_num_custom_protocols != 0)
5309 	ndpi_fill_ip_protocol_category(ndpi_str, flow->packet.iph->saddr, flow->packet.iph->daddr, ret);
5310       flow->guessed_header_category = ret->category;
5311     } else
5312       flow->guessed_header_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;
5313 
5314     if(flow->guessed_protocol_id >= NDPI_MAX_SUPPORTED_PROTOCOLS) {
5315       /* This is a custom protocol and it has priority over everything else */
5316       ret->master_protocol = NDPI_PROTOCOL_UNKNOWN,
5317 	ret->app_protocol = flow->guessed_protocol_id ? flow->guessed_protocol_id : flow->guessed_host_protocol_id;
5318 
5319       // if(ndpi_str->ndpi_num_custom_protocols != 0)
5320       ndpi_fill_protocol_category(ndpi_str, flow, ret);
5321       return(-1);
5322     }
5323 
5324     if(user_defined_proto && flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
5325       if(flow->packet.iph) {
5326 	if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
5327 	  u_int8_t protocol_was_guessed;
5328 
5329 	  /* ret->master_protocol = flow->guessed_protocol_id , ret->app_protocol = flow->guessed_host_protocol_id; /\* ****** *\/ */
5330 	  *ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
5331 	}
5332 
5333 	// if(ndpi_str->ndpi_num_custom_protocols != 0)
5334 	ndpi_fill_protocol_category(ndpi_str, flow, ret);
5335 	return(-1);
5336       }
5337     } else {
5338       /* guess host protocol */
5339       if(flow->packet.iph) {
5340 	flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_str, flow);
5341 
5342 	/*
5343 	  We could implement a shortcut here skipping dissectors for
5344 	  protocols we have identified by other means such as with the IP
5345 
5346 	  However we do NOT stop here and skip invoking the dissectors
5347 	  because we want to dissect the flow (e.g. dissect the TLS)
5348 	  and extract metadata.
5349 	*/
5350 #if SKIP_INVOKING_THE_DISSECTORS
5351 	if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
5352 	  /*
5353 	    We have identified a protocol using the IP address so
5354 	    it is not worth to dissect the traffic as we already have
5355 	    the solution
5356 	  */
5357 	  ret->master_protocol = flow->guessed_protocol_id, ret->app_protocol = flow->guessed_host_protocol_id;
5358 	}
5359 #endif
5360       }
5361     }
5362   }
5363 
5364   if(flow->guessed_host_protocol_id >= NDPI_MAX_SUPPORTED_PROTOCOLS) {
5365     //u_int32_t num_calls;
5366     NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet = {0};
5367 
5368     /* This is a custom protocol and it has priority over everything else */
5369     ret->master_protocol = flow->guessed_protocol_id, ret->app_protocol = flow->guessed_host_protocol_id;
5370 
5371     //num_calls =
5372     ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
5373 
5374     //if(ndpi_str->ndpi_num_custom_protocols != 0)
5375     ndpi_fill_protocol_category(ndpi_str, flow, ret);
5376     return(-1);
5377   }
5378 
5379   return(0);
5380 }
5381 
5382 /* ********************************************************************************* */
5383 
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)5384 ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct *ndpi_str,
5385 					    struct ndpi_flow_struct *flow, const unsigned char *packet,
5386 					    const unsigned short packetlen, const u_int64_t current_time_ms,
5387 					    struct ndpi_id_struct *src, struct ndpi_id_struct *dst) {
5388   NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
5389   u_int32_t a, num_calls = 0;
5390   ndpi_protocol ret = { flow->detected_protocol_stack[1], flow->detected_protocol_stack[0], flow->category };
5391 
5392   if(ndpi_str->ndpi_log_level >= NDPI_LOG_TRACE)
5393     NDPI_LOG(flow ? flow->detected_protocol_stack[0] : NDPI_PROTOCOL_UNKNOWN, ndpi_str, NDPI_LOG_TRACE,
5394 	     "START packet processing\n");
5395 
5396   if(flow == NULL)
5397     return(ret);
5398   else
5399     ret.category = flow->category;
5400 
5401   if(flow->fail_with_unknown) {
5402     // printf("%s(): FAIL_WITH_UNKNOWN\n", __FUNCTION__);
5403     return(ret);
5404   }
5405 
5406   flow->num_processed_pkts++;
5407 
5408   /* Init default */
5409   ret.master_protocol = flow->detected_protocol_stack[1],
5410     ret.app_protocol = flow->detected_protocol_stack[0];
5411 
5412   if(flow->server_id == NULL)
5413     flow->server_id = dst; /* Default */
5414 
5415   if(flow->check_extra_packets) {
5416     ndpi_process_extra_packet(ndpi_str, flow, packet, packetlen, current_time_ms, src, dst);
5417     /* Update in case of new match */
5418     ret.master_protocol = flow->detected_protocol_stack[1],
5419       ret.app_protocol = flow->detected_protocol_stack[0],
5420       ret.category = flow->category;
5421     goto invalidate_ptr;
5422   } else if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
5423     goto ret_protocols;
5424 
5425   /* need at least 20 bytes for ip header */
5426   if(packetlen < 20) {
5427     /* reset protocol which is normally done in init_packet_header */
5428     ndpi_int_reset_packet_protocol(&flow->packet);
5429     goto invalidate_ptr;
5430   }
5431 
5432   flow->packet.current_time_ms = current_time_ms;
5433 
5434   /* parse packet */
5435   flow->packet.iph = (struct ndpi_iphdr *) packet;
5436   /* we are interested in ipv4 packet */
5437 
5438   if(ndpi_init_packet_header(ndpi_str, flow, packetlen) != 0)
5439     goto invalidate_ptr;
5440 
5441   /* detect traffic for tcp or udp only */
5442   flow->src = src, flow->dst = dst;
5443 
5444   ndpi_connection_tracking(ndpi_str, flow);
5445 
5446   /* build ndpi_selection packet bitmask */
5447   ndpi_selection_packet = NDPI_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
5448   if(flow->packet.iph != NULL)
5449     ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IP | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
5450 
5451   if(flow->packet.tcp != NULL)
5452     ndpi_selection_packet |=
5453       (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
5454 
5455   if(flow->packet.udp != NULL)
5456     ndpi_selection_packet |=
5457       (NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
5458 
5459   if(flow->packet.payload_packet_len != 0)
5460     ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
5461 
5462   if(flow->packet.tcp_retransmission == 0)
5463     ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION;
5464 
5465   if(flow->packet.iphv6 != NULL)
5466     ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
5467 
5468   if(!flow->protocol_id_already_guessed) {
5469     flow->protocol_id_already_guessed = 1;
5470 
5471     if(ndpi_do_guess(ndpi_str, flow, &ret) == -1)
5472       goto invalidate_ptr;
5473   }
5474 
5475   num_calls = ndpi_check_flow_func(ndpi_str, flow, &ndpi_selection_packet);
5476 
5477   a = flow->packet.detected_protocol_stack[0];
5478   if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_str->detection_bitmask, a) == 0)
5479     a = NDPI_PROTOCOL_UNKNOWN;
5480 
5481   if(a != NDPI_PROTOCOL_UNKNOWN) {
5482     int i;
5483 
5484     for(i = 0; i < sizeof(flow->host_server_name); i++) {
5485       if(flow->host_server_name[i] != '\0')
5486 	flow->host_server_name[i] = tolower(flow->host_server_name[i]);
5487       else {
5488 	flow->host_server_name[i] = '\0';
5489 	break;
5490       }
5491     }
5492   }
5493 
5494  ret_protocols:
5495   if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
5496     ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
5497 
5498     if(ret.app_protocol == ret.master_protocol)
5499       ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
5500   } else
5501     ret.app_protocol = flow->detected_protocol_stack[0];
5502 
5503   /* Don't overwrite the category if already set */
5504   if((flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
5505     ndpi_fill_protocol_category(ndpi_str, flow, &ret);
5506   else
5507     ret.category = flow->category;
5508 
5509   if((flow->num_processed_pkts == 1) && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) &&
5510      (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) && flow->packet.tcp && (flow->packet.tcp->syn == 0) &&
5511      (flow->guessed_protocol_id == 0)) {
5512     u_int8_t protocol_was_guessed;
5513 
5514     /*
5515       This is a TCP flow
5516       - whose first packet is NOT a SYN
5517       - no protocol has been detected
5518 
5519       We don't see how future packets can match anything
5520       hence we giveup here
5521     */
5522     ret = ndpi_detection_giveup(ndpi_str, flow, 0, &protocol_was_guessed);
5523   }
5524 
5525   if((ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) && (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) &&
5526      (flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
5527     ret.master_protocol = ret.app_protocol;
5528     ret.app_protocol = flow->guessed_host_protocol_id;
5529   }
5530 
5531   if((!flow->risk_checked)
5532      && ((ret.master_protocol != NDPI_PROTOCOL_UNKNOWN) || (ret.app_protocol != NDPI_PROTOCOL_UNKNOWN))
5533      ) {
5534     ndpi_default_ports_tree_node_t *found;
5535     u_int16_t *default_ports, sport, dport;
5536 
5537     if(flow->packet.udp)
5538       found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_UDP,
5539 					   sport = ntohs(flow->packet.udp->source),
5540 					   dport = ntohs(flow->packet.udp->dest)),
5541 	default_ports = ndpi_str->proto_defaults[ret.master_protocol ? ret.master_protocol : ret.app_protocol].udp_default_ports;
5542     else if(flow->packet.tcp)
5543       found = ndpi_get_guessed_protocol_id(ndpi_str, IPPROTO_TCP,
5544 					   sport = ntohs(flow->packet.tcp->source),
5545 					   dport = ntohs(flow->packet.tcp->dest)),
5546 	default_ports = ndpi_str->proto_defaults[ret.master_protocol ? ret.master_protocol : ret.app_protocol].tcp_default_ports;
5547     else
5548       found = NULL, default_ports = NULL, sport = dport = 0;
5549 
5550     if(found
5551        && (found->proto->protoId != NDPI_PROTOCOL_UNKNOWN)
5552        && (found->proto->protoId != ret.master_protocol)
5553        && (found->proto->protoId != ret.app_protocol)
5554        ) {
5555       // printf("******** %u / %u\n", found->proto->protoId, ret.master_protocol);
5556 
5557       if(!ndpi_check_protocol_port_mismatch_exceptions(ndpi_str, flow, found, &ret)) {
5558 	/*
5559 	  Before triggering the alert we need to make some extra checks
5560 	  - the protocol found is not running on the port we have found (i.e. two or more protools share the same default port)
5561 	*/
5562 	u_int8_t found = 0, i;
5563 
5564 	for(i=0; (i<MAX_DEFAULT_PORTS) && (default_ports[i] != 0); i++) {
5565 	  if(default_ports[i] == dport) {
5566 	    found = 1;
5567 	    break;
5568 	  }
5569 	} /* for */
5570 
5571 	if(!found)
5572 	  ndpi_set_risk(ndpi_str, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
5573       }
5574     } else if((!ndpi_is_ntop_protocol(&ret)) && default_ports && (default_ports[0] != 0)) {
5575       u_int8_t found = 0, i, num_loops = 0;
5576 
5577     check_default_ports:
5578       for(i=0; (i<MAX_DEFAULT_PORTS) && (default_ports[i] != 0); i++) {
5579 	if((default_ports[i] == sport) || (default_ports[i] == dport)) {
5580 	  found = 1;
5581 	  break;
5582 	}
5583       } /* for */
5584 
5585       if((num_loops == 0) && (!found)) {
5586 	if(flow->packet.udp)
5587 	  default_ports = ndpi_str->proto_defaults[ret.app_protocol].udp_default_ports;
5588 	else
5589 	  default_ports = ndpi_str->proto_defaults[ret.app_protocol].tcp_default_ports;
5590 
5591 	num_loops = 1;
5592 	goto check_default_ports;
5593       }
5594 
5595       if(!found) {
5596 	// printf("******** Invalid default port\n");
5597 	ndpi_set_risk(ndpi_str, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT);
5598       }
5599     }
5600 
5601     flow->risk_checked = 1;
5602   }
5603 
5604   ndpi_reconcile_protocols(ndpi_str, flow, &ret);
5605 
5606   if(num_calls == 0)
5607     flow->fail_with_unknown = 1;
5608 
5609  invalidate_ptr:
5610   /*
5611     Invalidate packet memory to avoid accessing the pointers below
5612     when the packet is no longer accessible
5613   */
5614   flow->packet.iph = NULL, flow->packet.tcp = NULL, flow->packet.udp = NULL, flow->packet.payload = NULL;
5615   ndpi_reset_packet_line_info(&flow->packet);
5616 
5617   return(ret);
5618 }
5619 
5620 /* ********************************************************************************* */
5621 
ndpi_bytestream_to_number(const u_int8_t * str,u_int16_t max_chars_to_read,u_int16_t * bytes_read)5622 u_int32_t ndpi_bytestream_to_number(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
5623   u_int32_t val;
5624   val = 0;
5625 
5626   // cancel if eof, ' ' or line end chars are reached
5627   while(*str >= '0' && *str <= '9' && max_chars_to_read > 0) {
5628     val *= 10;
5629     val += *str - '0';
5630     str++;
5631     max_chars_to_read = max_chars_to_read - 1;
5632     *bytes_read = *bytes_read + 1;
5633   }
5634 
5635   return(val);
5636 }
5637 
5638 /* ********************************************************************************* */
5639 
5640 #ifdef CODE_UNUSED
ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str,u_int16_t max_chars_to_read,u_int16_t * bytes_read)5641 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) {
5642   u_int32_t val;
5643   val = 0;
5644   if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
5645     return(ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read));
5646   } else {
5647     /*use base 16 system */
5648     str += 2;
5649     max_chars_to_read -= 2;
5650     *bytes_read = *bytes_read + 2;
5651 
5652     while(max_chars_to_read > 0) {
5653       if(*str >= '0' && *str <= '9') {
5654 	val *= 16;
5655 	val += *str - '0';
5656       } else if(*str >= 'a' && *str <= 'f') {
5657 	val *= 16;
5658 	val += *str + 10 - 'a';
5659       } else if(*str >= 'A' && *str <= 'F') {
5660 	val *= 16;
5661 	val += *str + 10 - 'A';
5662       } else {
5663 	break;
5664       }
5665       str++;
5666       max_chars_to_read = max_chars_to_read - 1;
5667       *bytes_read = *bytes_read + 1;
5668     }
5669   }
5670 
5671   return(val);
5672 }
5673 
5674 #endif
5675 
5676 /* ********************************************************************************* */
5677 
ndpi_bytestream_to_number64(const u_int8_t * str,u_int16_t max_chars_to_read,u_int16_t * bytes_read)5678 u_int64_t ndpi_bytestream_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
5679   u_int64_t val;
5680   val = 0;
5681   // cancel if eof, ' ' or line end chars are reached
5682   while(max_chars_to_read > 0 && *str >= '0' && *str <= '9') {
5683     val *= 10;
5684     val += *str - '0';
5685     str++;
5686     max_chars_to_read = max_chars_to_read - 1;
5687     *bytes_read = *bytes_read + 1;
5688   }
5689   return(val);
5690 }
5691 
5692 /* ********************************************************************************* */
5693 
ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str,u_int16_t max_chars_to_read,u_int16_t * bytes_read)5694 u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t *str, u_int16_t max_chars_to_read,
5695 						 u_int16_t *bytes_read) {
5696   u_int64_t val;
5697   val = 0;
5698   if(max_chars_to_read <= 2 || str[0] != '0' || str[1] != 'x') {
5699     return(ndpi_bytestream_to_number64(str, max_chars_to_read, bytes_read));
5700   } else {
5701     /*use base 16 system */
5702     str += 2;
5703     max_chars_to_read -= 2;
5704     *bytes_read = *bytes_read + 2;
5705     while(max_chars_to_read > 0) {
5706       if(*str >= '0' && *str <= '9') {
5707 	val *= 16;
5708 	val += *str - '0';
5709       } else if(*str >= 'a' && *str <= 'f') {
5710 	val *= 16;
5711 	val += *str + 10 - 'a';
5712       } else if(*str >= 'A' && *str <= 'F') {
5713 	val *= 16;
5714 	val += *str + 10 - 'A';
5715       } else {
5716 	break;
5717       }
5718       str++;
5719       max_chars_to_read = max_chars_to_read - 1;
5720       *bytes_read = *bytes_read + 1;
5721     }
5722   }
5723   return(val);
5724 }
5725 
5726 /* ********************************************************************************* */
5727 
ndpi_bytestream_to_ipv4(const u_int8_t * str,u_int16_t max_chars_to_read,u_int16_t * bytes_read)5728 u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t *str, u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
5729   u_int32_t val;
5730   u_int16_t read = 0;
5731   u_int16_t oldread;
5732   u_int32_t c;
5733 
5734   /* ip address must be X.X.X.X with each X between 0 and 255 */
5735   oldread = read;
5736   c = ndpi_bytestream_to_number(str, max_chars_to_read, &read);
5737   if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
5738     return(0);
5739 
5740   read++;
5741   val = c << 24;
5742   oldread = read;
5743   c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
5744   if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
5745     return(0);
5746 
5747   read++;
5748   val = val + (c << 16);
5749   oldread = read;
5750   c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
5751   if(c > 255 || oldread == read || max_chars_to_read == read || str[read] != '.')
5752     return(0);
5753 
5754   read++;
5755   val = val + (c << 8);
5756   oldread = read;
5757   c = ndpi_bytestream_to_number(&str[read], max_chars_to_read - read, &read);
5758   if(c > 255 || oldread == read || max_chars_to_read == read)
5759     return(0);
5760 
5761   val = val + c;
5762 
5763   *bytes_read = *bytes_read + read;
5764 
5765   return(htonl(val));
5766 }
5767 
5768 /* ********************************************************************************* */
5769 
5770 /* internal function for every detection to parse one packet and to increase the info buffer */
ndpi_parse_packet_line_info(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow)5771 void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
5772   u_int32_t a;
5773   struct ndpi_packet_struct *packet = &flow->packet;
5774 
5775   if((packet->payload_packet_len < 3) || (packet->payload == NULL))
5776     return;
5777 
5778   if(packet->packet_lines_parsed_complete != 0)
5779     return;
5780 
5781   packet->packet_lines_parsed_complete = 1;
5782   ndpi_reset_packet_line_info(packet);
5783 
5784   packet->line[packet->parsed_lines].ptr = packet->payload;
5785   packet->line[packet->parsed_lines].len = 0;
5786 
5787   for(a = 0; ((a+1) < packet->payload_packet_len) && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET); a++) {
5788     if((packet->payload[a] == 0x0d) && (packet->payload[a+1] == 0x0a)) {
5789       /* If end of line char sequence CR+NL "\r\n", process line */
5790 
5791       if(((a + 3) < packet->payload_packet_len)
5792 	 && (packet->payload[a+2] == 0x0d)
5793 	 && (packet->payload[a+3] == 0x0a)) {
5794 	/* \r\n\r\n */
5795 	int diff; /* No unsigned ! */
5796 	u_int32_t a1 = a + 4;
5797 
5798 	diff = packet->payload_packet_len - a1;
5799 
5800 	if(diff > 0) {
5801 	  diff = ndpi_min(diff, sizeof(flow->initial_binary_bytes));
5802 	  memcpy(&flow->initial_binary_bytes, &packet->payload[a1], diff);
5803 	  flow->initial_binary_bytes_len = diff;
5804 	}
5805       }
5806 
5807       packet->line[packet->parsed_lines].len =
5808 	(u_int16_t)(((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
5809 
5810       /* First line of a HTTP response parsing. Expected a "HTTP/1.? ???" */
5811       if(packet->parsed_lines == 0 && packet->line[0].len >= NDPI_STATICSTRING_LEN("HTTP/1.X 200 ") &&
5812 	 strncasecmp((const char *) packet->line[0].ptr, "HTTP/1.", NDPI_STATICSTRING_LEN("HTTP/1.")) == 0 &&
5813 	 packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] > '0' && /* response code between 000 and 699 */
5814 	 packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.X ")] < '6') {
5815 	packet->http_response.ptr = &packet->line[0].ptr[NDPI_STATICSTRING_LEN("HTTP/1.1 ")];
5816 	packet->http_response.len = packet->line[0].len - NDPI_STATICSTRING_LEN("HTTP/1.1 ");
5817 	packet->http_num_headers++;
5818 
5819 	/* Set server HTTP response code */
5820 	if(packet->payload_packet_len >= 12) {
5821 	  char buf[4];
5822 
5823 	  /* Set server HTTP response code */
5824 	  strncpy(buf, (char *) &packet->payload[9], 3);
5825 	  buf[3] = '\0';
5826 
5827 	  flow->http.response_status_code = atoi(buf);
5828 	  /* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */
5829 	  if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509))
5830 	    flow->http.response_status_code = 0; /* Out of range */
5831 	}
5832       }
5833 
5834       /* "Server:" header line in HTTP response */
5835       if(packet->line[packet->parsed_lines].len > NDPI_STATICSTRING_LEN("Server:") + 1 &&
5836 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
5837 		     "Server:", NDPI_STATICSTRING_LEN("Server:")) == 0) {
5838 	// some stupid clients omit a space and place the servername directly after the colon
5839 	if(packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")] == ' ') {
5840 	  packet->server_line.ptr =
5841 	    &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:") + 1];
5842 	  packet->server_line.len =
5843 	    packet->line[packet->parsed_lines].len - (NDPI_STATICSTRING_LEN("Server:") + 1);
5844 	} else {
5845 	  packet->server_line.ptr = &packet->line[packet->parsed_lines].ptr[NDPI_STATICSTRING_LEN("Server:")];
5846 	  packet->server_line.len = packet->line[packet->parsed_lines].len - NDPI_STATICSTRING_LEN("Server:");
5847 	}
5848 	packet->http_num_headers++;
5849       }
5850       /* "Host:" header line in HTTP request */
5851       if(packet->line[packet->parsed_lines].len > 6 &&
5852 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Host:", 5) == 0) {
5853 	// some stupid clients omit a space and place the hostname directly after the colon
5854 	if(packet->line[packet->parsed_lines].ptr[5] == ' ') {
5855 	  packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[6];
5856 	  packet->host_line.len = packet->line[packet->parsed_lines].len - 6;
5857 	} else {
5858 	  packet->host_line.ptr = &packet->line[packet->parsed_lines].ptr[5];
5859 	  packet->host_line.len = packet->line[packet->parsed_lines].len - 5;
5860 	}
5861 	packet->http_num_headers++;
5862       }
5863       /* "X-Forwarded-For:" header line in HTTP request. Commonly used for HTTP proxies. */
5864       if(packet->line[packet->parsed_lines].len > 17 &&
5865 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Forwarded-For:", 16) == 0) {
5866 	// some stupid clients omit a space and place the hostname directly after the colon
5867 	if(packet->line[packet->parsed_lines].ptr[16] == ' ') {
5868 	  packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[17];
5869 	  packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 17;
5870 	} else {
5871 	  packet->forwarded_line.ptr = &packet->line[packet->parsed_lines].ptr[16];
5872 	  packet->forwarded_line.len = packet->line[packet->parsed_lines].len - 16;
5873 	}
5874 	packet->http_num_headers++;
5875       }
5876       /* "Content-Type:" header line in HTTP. */
5877       if(packet->line[packet->parsed_lines].len > 14 &&
5878 	 (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Type: ", 14) == 0 ||
5879 	  strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-type: ", 14) == 0)) {
5880 	packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[14];
5881 	packet->content_line.len = packet->line[packet->parsed_lines].len - 14;
5882 
5883 	while((packet->content_line.len > 0) && (packet->content_line.ptr[0] == ' '))
5884 	  packet->content_line.len--, packet->content_line.ptr++;
5885 
5886 	packet->http_num_headers++;
5887       }
5888       /* "Content-Type:" header line in HTTP AGAIN. Probably a bogus response without space after ":" */
5889       if((packet->content_line.len == 0) && (packet->line[packet->parsed_lines].len > 13) &&
5890 	 (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-type:", 13) == 0)) {
5891 	packet->content_line.ptr = &packet->line[packet->parsed_lines].ptr[13];
5892 	packet->content_line.len = packet->line[packet->parsed_lines].len - 13;
5893 	packet->http_num_headers++;
5894       }
5895 
5896       if(packet->content_line.len > 0) {
5897 	/* application/json; charset=utf-8 */
5898 	char separator[] = {';', '\r', '\0'};
5899 	int i;
5900 
5901 	for(i = 0; separator[i] != '\0'; i++) {
5902 	  char *c = memchr((char *) packet->content_line.ptr, separator[i], packet->content_line.len);
5903 
5904 	  if(c != NULL)
5905 	    packet->content_line.len = c - (char *) packet->content_line.ptr;
5906 	}
5907       }
5908 
5909       /* "Accept:" header line in HTTP request. */
5910       if(packet->line[packet->parsed_lines].len > 8 &&
5911 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept: ", 8) == 0) {
5912 	packet->accept_line.ptr = &packet->line[packet->parsed_lines].ptr[8];
5913 	packet->accept_line.len = packet->line[packet->parsed_lines].len - 8;
5914 	packet->http_num_headers++;
5915       }
5916       /* "Referer:" header line in HTTP request. */
5917       if(packet->line[packet->parsed_lines].len > 9 &&
5918 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Referer: ", 9) == 0) {
5919 	packet->referer_line.ptr = &packet->line[packet->parsed_lines].ptr[9];
5920 	packet->referer_line.len = packet->line[packet->parsed_lines].len - 9;
5921 	packet->http_num_headers++;
5922       }
5923       /* "User-Agent:" header line in HTTP request. */
5924       if(packet->line[packet->parsed_lines].len > 12 &&
5925 	 (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-Agent: ", 12) == 0 ||
5926 	  strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "User-agent: ", 12) == 0)) {
5927 	packet->user_agent_line.ptr = &packet->line[packet->parsed_lines].ptr[12];
5928 	packet->user_agent_line.len = packet->line[packet->parsed_lines].len - 12;
5929 	packet->http_num_headers++;
5930       }
5931       /* "Content-Encoding:" header line in HTTP response (and request?). */
5932       if(packet->line[packet->parsed_lines].len > 18 &&
5933 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Encoding: ", 18) == 0) {
5934 	packet->http_encoding.ptr = &packet->line[packet->parsed_lines].ptr[18];
5935 	packet->http_encoding.len = packet->line[packet->parsed_lines].len - 18;
5936 	packet->http_num_headers++;
5937       }
5938       /* "Transfer-Encoding:" header line in HTTP. */
5939       if(packet->line[packet->parsed_lines].len > 19 &&
5940 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Transfer-Encoding: ", 19) == 0) {
5941 	packet->http_transfer_encoding.ptr = &packet->line[packet->parsed_lines].ptr[19];
5942 	packet->http_transfer_encoding.len = packet->line[packet->parsed_lines].len - 19;
5943 	packet->http_num_headers++;
5944       }
5945       /* "Content-Length:" header line in HTTP. */
5946       if(packet->line[packet->parsed_lines].len > 16 &&
5947 	 ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Length: ", 16) == 0) ||
5948 	  (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "content-length: ", 16) == 0))) {
5949 	packet->http_contentlen.ptr = &packet->line[packet->parsed_lines].ptr[16];
5950 	packet->http_contentlen.len = packet->line[packet->parsed_lines].len - 16;
5951 	packet->http_num_headers++;
5952       }
5953       /* "Content-Disposition"*/
5954       if(packet->line[packet->parsed_lines].len > 21 &&
5955 	 ((strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Content-Disposition: ", 21) == 0))) {
5956 	packet->content_disposition_line.ptr = &packet->line[packet->parsed_lines].ptr[21];
5957 	packet->content_disposition_line.len = packet->line[packet->parsed_lines].len - 21;
5958 	packet->http_num_headers++;
5959       }
5960       /* "Cookie:" header line in HTTP. */
5961       if(packet->line[packet->parsed_lines].len > 8 &&
5962 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Cookie: ", 8) == 0) {
5963 	packet->http_cookie.ptr = &packet->line[packet->parsed_lines].ptr[8];
5964 	packet->http_cookie.len = packet->line[packet->parsed_lines].len - 8;
5965 	packet->http_num_headers++;
5966       }
5967       /* "Origin:" header line in HTTP. */
5968       if(packet->line[packet->parsed_lines].len > 8 &&
5969 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Origin: ", 8) == 0) {
5970 	packet->http_origin.ptr = &packet->line[packet->parsed_lines].ptr[8];
5971 	packet->http_origin.len = packet->line[packet->parsed_lines].len - 8;
5972 	packet->http_num_headers++;
5973       }
5974       /* "X-Session-Type:" header line in HTTP. */
5975       if(packet->line[packet->parsed_lines].len > 16 &&
5976 	 strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "X-Session-Type: ", 16) == 0) {
5977 	packet->http_x_session_type.ptr = &packet->line[packet->parsed_lines].ptr[16];
5978 	packet->http_x_session_type.len = packet->line[packet->parsed_lines].len - 16;
5979 	packet->http_num_headers++;
5980       }
5981       /* Identification and counting of other HTTP headers.
5982        * We consider the most common headers, but there are many others,
5983        * which can be seen at references below:
5984        * - https://tools.ietf.org/html/rfc7230
5985        * - https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
5986        */
5987       if((packet->line[packet->parsed_lines].len > 6 &&
5988 	  (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Date: ", 6) == 0 ||
5989 	   strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Vary: ", 6) == 0 ||
5990 	   strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "ETag: ", 6) == 0)) ||
5991 	 (packet->line[packet->parsed_lines].len > 8 &&
5992 	  strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Pragma: ", 8) == 0) ||
5993 	 (packet->line[packet->parsed_lines].len > 9 &&
5994 	  strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Expires: ", 9) == 0) ||
5995 	 (packet->line[packet->parsed_lines].len > 12 &&
5996 	  (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Set-Cookie: ", 12) == 0 ||
5997 	   strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Keep-Alive: ", 12) == 0 ||
5998 	   strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Connection: ", 12) == 0)) ||
5999 	 (packet->line[packet->parsed_lines].len > 15 &&
6000 	  (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Last-Modified: ", 15) == 0 ||
6001 	   strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Ranges: ", 15) == 0)) ||
6002 	 (packet->line[packet->parsed_lines].len > 17 &&
6003 	  (strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Language: ", 17) == 0 ||
6004 	   strncasecmp((const char *) packet->line[packet->parsed_lines].ptr, "Accept-Encoding: ", 17) == 0)) ||
6005 	 (packet->line[packet->parsed_lines].len > 27 &&
6006 	  strncasecmp((const char *) packet->line[packet->parsed_lines].ptr,
6007 		      "Upgrade-Insecure-Requests: ", 27) == 0)) {
6008 	/* Just count. In the future, if needed, this if can be splited to parse these headers */
6009 	packet->http_num_headers++;
6010       }
6011 
6012       if(packet->line[packet->parsed_lines].len == 0) {
6013 	packet->empty_line_position = a;
6014 	packet->empty_line_position_set = 1;
6015       }
6016 
6017       if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
6018 	return;
6019 
6020       packet->parsed_lines++;
6021       packet->line[packet->parsed_lines].ptr = &packet->payload[a + 2];
6022       packet->line[packet->parsed_lines].len = 0;
6023 
6024       a++; /* next char in the payload */
6025     }
6026   }
6027 
6028   if(packet->parsed_lines >= 1) {
6029     packet->line[packet->parsed_lines].len =
6030       (u_int16_t)(((size_t) &packet->payload[packet->payload_packet_len]) -
6031 		  ((size_t) packet->line[packet->parsed_lines].ptr));
6032     packet->parsed_lines++;
6033   }
6034 }
6035 
6036 /* ********************************************************************************* */
6037 
ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow)6038 void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
6039   struct ndpi_packet_struct *packet = &flow->packet;
6040   u_int32_t a;
6041   u_int16_t end = packet->payload_packet_len;
6042 
6043   if(packet->packet_lines_parsed_complete != 0)
6044     return;
6045 
6046   packet->packet_lines_parsed_complete = 1;
6047   packet->parsed_lines = 0;
6048 
6049   if(packet->payload_packet_len == 0)
6050     return;
6051 
6052   packet->line[packet->parsed_lines].ptr = packet->payload;
6053   packet->line[packet->parsed_lines].len = 0;
6054 
6055   for(a = 0; a < end; a++) {
6056     if(packet->payload[a] == 0x0a) {
6057       packet->line[packet->parsed_lines].len = (u_int16_t)(
6058 							   ((size_t) &packet->payload[a]) - ((size_t) packet->line[packet->parsed_lines].ptr));
6059 
6060       if(a > 0 && packet->payload[a - 1] == 0x0d)
6061 	packet->line[packet->parsed_lines].len--;
6062 
6063       if(packet->parsed_lines >= (NDPI_MAX_PARSE_LINES_PER_PACKET - 1))
6064 	break;
6065 
6066       packet->parsed_lines++;
6067       packet->line[packet->parsed_lines].ptr = &packet->payload[a + 1];
6068       packet->line[packet->parsed_lines].len = 0;
6069 
6070       if((a + 1) >= packet->payload_packet_len)
6071 	break;
6072 
6073       //a++;
6074     }
6075   }
6076 }
6077 
6078 /* ********************************************************************************* */
6079 
ndpi_check_for_email_address(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,u_int16_t counter)6080 u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
6081 				       u_int16_t counter) {
6082   struct ndpi_packet_struct *packet = &flow->packet;
6083 
6084   NDPI_LOG_DBG2(ndpi_str, "called ndpi_check_for_email_address\n");
6085 
6086   if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
6087 					      (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
6088 					      (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
6089 					      packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
6090     NDPI_LOG_DBG2(ndpi_str, "first letter\n");
6091     counter++;
6092     while(packet->payload_packet_len > counter &&
6093 	  ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
6094 	   (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
6095 	   (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
6096 	   packet->payload[counter] == '-' || packet->payload[counter] == '_' ||
6097 	   packet->payload[counter] == '.')) {
6098       NDPI_LOG_DBG2(ndpi_str, "further letter\n");
6099       counter++;
6100       if(packet->payload_packet_len > counter && packet->payload[counter] == '@') {
6101 	NDPI_LOG_DBG2(ndpi_str, "@\n");
6102 	counter++;
6103 	while(packet->payload_packet_len > counter &&
6104 	      ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
6105 	       (packet->payload[counter] >= 'A' && packet->payload[counter] <= 'Z') ||
6106 	       (packet->payload[counter] >= '0' && packet->payload[counter] <= '9') ||
6107 	       packet->payload[counter] == '-' || packet->payload[counter] == '_')) {
6108 	  NDPI_LOG_DBG2(ndpi_str, "letter\n");
6109 	  counter++;
6110 	  if(packet->payload_packet_len > counter && packet->payload[counter] == '.') {
6111 	    NDPI_LOG_DBG2(ndpi_str, ".\n");
6112 	    counter++;
6113 	    if(packet->payload_packet_len > counter + 1 &&
6114 	       ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') &&
6115 		(packet->payload[counter + 1] >= 'a' && packet->payload[counter + 1] <= 'z'))) {
6116 	      NDPI_LOG_DBG2(ndpi_str, "two letters\n");
6117 	      counter += 2;
6118 	      if(packet->payload_packet_len > counter &&
6119 		 (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
6120 		NDPI_LOG_DBG2(ndpi_str, "whitespace1\n");
6121 		return(counter);
6122 	      } else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
6123 			packet->payload[counter] <= 'z') {
6124 		NDPI_LOG_DBG2(ndpi_str, "one letter\n");
6125 		counter++;
6126 		if(packet->payload_packet_len > counter &&
6127 		   (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
6128 		  NDPI_LOG_DBG2(ndpi_str, "whitespace2\n");
6129 		  return(counter);
6130 		} else if(packet->payload_packet_len > counter && packet->payload[counter] >= 'a' &&
6131 			  packet->payload[counter] <= 'z') {
6132 		  counter++;
6133 		  if(packet->payload_packet_len > counter &&
6134 		     (packet->payload[counter] == ' ' || packet->payload[counter] == ';')) {
6135 		    NDPI_LOG_DBG2(ndpi_str, "whitespace3\n");
6136 		    return(counter);
6137 		  } else {
6138 		    return(0);
6139 		  }
6140 		} else {
6141 		  return(0);
6142 		}
6143 	      } else {
6144 		return(0);
6145 	      }
6146 	    } else {
6147 	      return(0);
6148 	    }
6149 	  }
6150 	}
6151 	return(0);
6152       }
6153     }
6154   }
6155   return(0);
6156 }
6157 
6158 #ifdef NDPI_ENABLE_DEBUG_MESSAGES
6159 /* ********************************************************************************* */
6160 
ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct * ndpi_str,const char ** file,const char ** func,u_int32_t * line)6161 void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_str, const char **file,
6162 					   const char **func, u_int32_t *line) {
6163   *file = "";
6164   *func = "";
6165 
6166   if(ndpi_str->ndpi_debug_print_file != NULL)
6167     *file = ndpi_str->ndpi_debug_print_file;
6168 
6169   if(ndpi_str->ndpi_debug_print_function != NULL)
6170     *func = ndpi_str->ndpi_debug_print_function;
6171 
6172   *line = ndpi_str->ndpi_debug_print_line;
6173 }
6174 #endif
6175 
6176 /* ********************************************************************************* */
6177 
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)6178 u_int8_t ndpi_detection_get_l4(const u_int8_t *l3, u_int16_t l3_len, const u_int8_t **l4_return,
6179 			       u_int16_t *l4_len_return, u_int8_t *l4_protocol_return, u_int32_t flags) {
6180   return(ndpi_detection_get_l4_internal(NULL, l3, l3_len, l4_return, l4_len_return, l4_protocol_return, flags));
6181 }
6182 
6183 /* ********************************************************************************* */
6184 
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)6185 void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
6186 				u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
6187   struct ndpi_id_struct *src = flow->src, *dst = flow->dst;
6188 
6189   ndpi_int_change_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
6190 
6191   if(src != NULL) {
6192     NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, upper_detected_protocol);
6193 
6194     if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
6195       NDPI_ADD_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, lower_detected_protocol);
6196   }
6197 
6198   if(dst != NULL) {
6199     NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, upper_detected_protocol);
6200 
6201     if(lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN)
6202       NDPI_ADD_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, lower_detected_protocol);
6203   }
6204 }
6205 
6206 /* ********************************************************************************* */
6207 
ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow)6208 u_int16_t ndpi_get_flow_masterprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) {
6209   return(flow->detected_protocol_stack[1]);
6210 }
6211 
6212 /* ********************************************************************************* */
6213 
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)6214 void ndpi_int_change_flow_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
6215 				   u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
6216   if(!flow)
6217     return;
6218 
6219   flow->detected_protocol_stack[0] = upper_detected_protocol,
6220     flow->detected_protocol_stack[1] = lower_detected_protocol;
6221 }
6222 
6223 /* ********************************************************************************* */
6224 
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)6225 void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
6226 				     u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
6227   struct ndpi_packet_struct *packet = &flow->packet;
6228   /* NOTE: everything below is identically to change_flow_protocol
6229    *        except flow->packet If you want to change something here,
6230    *        don't! Change it for the flow function and apply it here
6231    *        as well */
6232 
6233   if(!packet)
6234     return;
6235 
6236   packet->detected_protocol_stack[0] = upper_detected_protocol,
6237     packet->detected_protocol_stack[1] = lower_detected_protocol;
6238 }
6239 
6240 /* ********************************************************************************* */
6241 
6242 /* generic function for changing the protocol
6243  *
6244  * what it does is:
6245  * 1.update the flow protocol stack with the new protocol
6246  * 2.update the packet protocol stack with the new protocol
6247  */
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)6248 void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
6249 			      u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol) {
6250   if((upper_detected_protocol == NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol != NDPI_PROTOCOL_UNKNOWN))
6251     upper_detected_protocol = lower_detected_protocol;
6252 
6253   if(upper_detected_protocol == lower_detected_protocol)
6254     lower_detected_protocol = NDPI_PROTOCOL_UNKNOWN;
6255 
6256   if((upper_detected_protocol != NDPI_PROTOCOL_UNKNOWN) && (lower_detected_protocol == NDPI_PROTOCOL_UNKNOWN)) {
6257     if((flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
6258        (upper_detected_protocol != flow->guessed_host_protocol_id)) {
6259       if(ndpi_str->proto_defaults[upper_detected_protocol].subprotocol_count > 0) {
6260 	lower_detected_protocol = upper_detected_protocol;
6261 	upper_detected_protocol = flow->guessed_host_protocol_id;
6262       }
6263     }
6264   }
6265 
6266   ndpi_int_change_flow_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
6267   ndpi_int_change_packet_protocol(ndpi_str, flow, upper_detected_protocol, lower_detected_protocol);
6268 }
6269 
6270 /* ********************************************************************************* */
6271 
ndpi_int_change_category(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,ndpi_protocol_category_t protocol_category)6272 void ndpi_int_change_category(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow,
6273 			      ndpi_protocol_category_t protocol_category) {
6274   flow->category = protocol_category;
6275 }
6276 
6277 /* ********************************************************************************* */
6278 
6279 /* turns a packet back to unknown */
ndpi_int_reset_packet_protocol(struct ndpi_packet_struct * packet)6280 void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet) {
6281   int a;
6282 
6283   for(a = 0; a < NDPI_PROTOCOL_SIZE; a++)
6284     packet->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
6285 }
6286 
6287 /* ********************************************************************************* */
6288 
ndpi_int_reset_protocol(struct ndpi_flow_struct * flow)6289 void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow) {
6290   if(flow) {
6291     int a;
6292 
6293     for(a = 0; a < NDPI_PROTOCOL_SIZE; a++)
6294       flow->detected_protocol_stack[a] = NDPI_PROTOCOL_UNKNOWN;
6295   }
6296 }
6297 
6298 /* ********************************************************************************* */
6299 
NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t * ip)6300 void NDPI_PROTOCOL_IP_clear(ndpi_ip_addr_t *ip) {
6301   memset(ip, 0, sizeof(ndpi_ip_addr_t));
6302 }
6303 
6304 /* ********************************************************************************* */
6305 
6306 #ifdef CODE_UNUSED
6307 /* NTOP */
NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t * ip)6308 int NDPI_PROTOCOL_IP_is_set(const ndpi_ip_addr_t *ip) {
6309   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);
6310 }
6311 #endif
6312 
6313 /* ********************************************************************************* */
6314 
6315 /* check if the source ip address in packet and ip are equal */
6316 /* NTOP */
ndpi_packet_src_ip_eql(const struct ndpi_packet_struct * packet,const ndpi_ip_addr_t * ip)6317 int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
6318   /* IPv6 */
6319   if(packet->iphv6 != NULL) {
6320     if(packet->iphv6->ip6_src.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
6321        packet->iphv6->ip6_src.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
6322        packet->iphv6->ip6_src.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
6323        packet->iphv6->ip6_src.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
6324       return(1);
6325     //else
6326     return(0);
6327   }
6328 
6329   /* IPv4 */
6330   if(packet->iph->saddr == ip->ipv4)
6331     return(1);
6332   return(0);
6333 }
6334 
6335 /* ********************************************************************************* */
6336 
6337 /* check if the destination ip address in packet and ip are equal */
ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct * packet,const ndpi_ip_addr_t * ip)6338 int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t *ip) {
6339   /* IPv6 */
6340   if(packet->iphv6 != NULL) {
6341     if(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0] == ip->ipv6.u6_addr.u6_addr32[0] &&
6342        packet->iphv6->ip6_dst.u6_addr.u6_addr32[1] == ip->ipv6.u6_addr.u6_addr32[1] &&
6343        packet->iphv6->ip6_dst.u6_addr.u6_addr32[2] == ip->ipv6.u6_addr.u6_addr32[2] &&
6344        packet->iphv6->ip6_dst.u6_addr.u6_addr32[3] == ip->ipv6.u6_addr.u6_addr32[3])
6345       return(1);
6346     //else
6347     return(0);
6348   }
6349 
6350   /* IPv4 */
6351   if(packet->iph->saddr == ip->ipv4)
6352     return(1);
6353 
6354   return(0);
6355 }
6356 
6357 /* ********************************************************************************* */
6358 
6359 /* get the source ip address from packet and put it into ip */
6360 /* NTOP */
ndpi_packet_src_ip_get(const struct ndpi_packet_struct * packet,ndpi_ip_addr_t * ip)6361 void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
6362   NDPI_PROTOCOL_IP_clear(ip);
6363 
6364   /* IPv6 */
6365   if(packet->iphv6 != NULL) {
6366     ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_src.u6_addr.u6_addr32[0];
6367     ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_src.u6_addr.u6_addr32[1];
6368     ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_src.u6_addr.u6_addr32[2];
6369     ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_src.u6_addr.u6_addr32[3];
6370   } else {
6371     /* IPv4 */
6372     ip->ipv4 = packet->iph->saddr;
6373   }
6374 }
6375 
6376 /* ********************************************************************************* */
6377 
6378 /* get the destination ip address from packet and put it into ip */
6379 /* NTOP */
ndpi_packet_dst_ip_get(const struct ndpi_packet_struct * packet,ndpi_ip_addr_t * ip)6380 void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t *ip) {
6381   NDPI_PROTOCOL_IP_clear(ip);
6382 
6383   if(packet->iphv6 != NULL) {
6384     ip->ipv6.u6_addr.u6_addr32[0] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[0];
6385     ip->ipv6.u6_addr.u6_addr32[1] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[1];
6386     ip->ipv6.u6_addr.u6_addr32[2] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[2];
6387     ip->ipv6.u6_addr.u6_addr32[3] = packet->iphv6->ip6_dst.u6_addr.u6_addr32[3];
6388 
6389   } else
6390     ip->ipv4 = packet->iph->daddr;
6391 }
6392 
6393 /* ********************************************************************************* */
6394 
ndpi_is_ipv6(const ndpi_ip_addr_t * ip)6395 u_int8_t ndpi_is_ipv6(const ndpi_ip_addr_t *ip) {
6396   return(ip->ipv6.u6_addr.u6_addr32[1] != 0 || ip->ipv6.u6_addr.u6_addr32[2] != 0 ||
6397 	 ip->ipv6.u6_addr.u6_addr32[3] != 0);
6398 }
6399 
6400 /* ********************************************************************************* */
6401 
ndpi_get_ip_string(const ndpi_ip_addr_t * ip,char * buf,u_int buf_len)6402 char *ndpi_get_ip_string(const ndpi_ip_addr_t *ip, char *buf, u_int buf_len) {
6403   const u_int8_t *a = (const u_int8_t *) &ip->ipv4;
6404 
6405   if(ndpi_is_ipv6(ip)) {
6406     if(inet_ntop(AF_INET6, &ip->ipv6.u6_addr, buf, buf_len) == NULL)
6407       buf[0] = '\0';
6408 
6409     return(buf);
6410   }
6411 
6412   snprintf(buf, buf_len, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
6413 
6414   return(buf);
6415 }
6416 
6417 /* ****************************************************** */
6418 
6419 /* Returns -1 on failutre, otherwise fills parsed_ip and returns the IP version */
ndpi_parse_ip_string(const char * ip_str,ndpi_ip_addr_t * parsed_ip)6420 int ndpi_parse_ip_string(const char *ip_str, ndpi_ip_addr_t *parsed_ip) {
6421   int rv = -1;
6422   memset(parsed_ip, 0, sizeof(*parsed_ip));
6423 
6424   if(strchr(ip_str, '.')) {
6425     if(inet_pton(AF_INET, ip_str, &parsed_ip->ipv4) > 0)
6426       rv = 4;
6427   } else {
6428     if(inet_pton(AF_INET6, ip_str, &parsed_ip->ipv6) > 0)
6429       rv = 6;
6430   }
6431 
6432   return(rv);
6433 }
6434 
6435 /* ****************************************************** */
6436 
ntohs_ndpi_bytestream_to_number(const u_int8_t * str,u_int16_t max_chars_to_read,u_int16_t * bytes_read)6437 u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t *str,
6438 					  u_int16_t max_chars_to_read, u_int16_t *bytes_read) {
6439   u_int16_t val = ndpi_bytestream_to_number(str, max_chars_to_read, bytes_read);
6440   return(ntohs(val));
6441 }
6442 
6443 /* ****************************************************** */
6444 
ndpi_is_proto(ndpi_protocol proto,u_int16_t p)6445 u_int8_t ndpi_is_proto(ndpi_protocol proto, u_int16_t p) {
6446   return(((proto.app_protocol == p) || (proto.master_protocol == p)) ? 1 : 0);
6447 }
6448 
6449 /* ****************************************************** */
6450 
ndpi_get_lower_proto(ndpi_protocol proto)6451 u_int16_t ndpi_get_lower_proto(ndpi_protocol proto) {
6452   return((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.master_protocol : proto.app_protocol);
6453 }
6454 
6455 /* ****************************************************** */
6456 
ndpi_get_upper_proto(ndpi_protocol proto)6457 u_int16_t ndpi_get_upper_proto(ndpi_protocol proto) {
6458   return((proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.app_protocol : proto.master_protocol);
6459 }
6460 
6461 /* ****************************************************** */
6462 
ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,u_int8_t proto,u_int32_t shost,u_int16_t sport,u_int32_t dhost,u_int16_t dport)6463 ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct *ndpi_str,
6464 					     struct ndpi_flow_struct *flow, u_int8_t proto,
6465 					     u_int32_t shost /* host byte order */, u_int16_t sport,
6466 					     u_int32_t dhost /* host byte order */, u_int16_t dport) {
6467   u_int32_t rc;
6468   struct in_addr addr;
6469   ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED};
6470   u_int8_t user_defined_proto;
6471 
6472   if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
6473     rc = ndpi_search_tcp_or_udp_raw(ndpi_str, flow, proto, shost, dhost, sport, dport);
6474 
6475     if(rc != NDPI_PROTOCOL_UNKNOWN) {
6476       if(flow && (proto == IPPROTO_UDP) &&
6477 	 NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
6478 	;
6479       else {
6480 	ret.app_protocol = rc,
6481 	  ret.master_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
6482 
6483 	if(ret.app_protocol == ret.master_protocol)
6484 	  ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
6485 
6486 	ret.category = ndpi_get_proto_category(ndpi_str, ret);
6487 	return(ret);
6488       }
6489     }
6490 
6491     rc = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
6492     if(rc != NDPI_PROTOCOL_UNKNOWN) {
6493       if(flow && (proto == IPPROTO_UDP) &&
6494 	 NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc) && is_udp_guessable_protocol(rc))
6495 	;
6496       else {
6497 	ret.app_protocol = rc;
6498 
6499 	if(rc == NDPI_PROTOCOL_TLS)
6500 	  goto check_guessed_skype;
6501 	else {
6502 	  ret.category = ndpi_get_proto_category(ndpi_str, ret);
6503 	  return(ret);
6504 	}
6505       }
6506     }
6507 
6508   check_guessed_skype:
6509     addr.s_addr = htonl(shost);
6510     if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE_TEAMS) {
6511       ret.app_protocol = NDPI_PROTOCOL_SKYPE_TEAMS;
6512     } else {
6513       addr.s_addr = htonl(dhost);
6514       if(ndpi_network_ptree_match(ndpi_str, &addr) == NDPI_PROTOCOL_SKYPE_TEAMS)
6515 	ret.app_protocol = NDPI_PROTOCOL_SKYPE_TEAMS;
6516     }
6517   } else
6518     ret.app_protocol = ndpi_guess_protocol_id(ndpi_str, flow, proto, sport, dport, &user_defined_proto);
6519 
6520   ret.category = ndpi_get_proto_category(ndpi_str, ret);
6521   return(ret);
6522 }
6523 
6524 /* ****************************************************** */
6525 
ndpi_protocol2id(struct ndpi_detection_module_struct * ndpi_str,ndpi_protocol proto,char * buf,u_int buf_len)6526 char *ndpi_protocol2id(struct ndpi_detection_module_struct *ndpi_str,
6527 		       ndpi_protocol proto, char *buf, u_int buf_len) {
6528   if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
6529     if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
6530       snprintf(buf, buf_len, "%u.%u", proto.master_protocol, proto.app_protocol);
6531     else
6532       snprintf(buf, buf_len, "%u", proto.master_protocol);
6533   } else
6534     snprintf(buf, buf_len, "%u", proto.app_protocol);
6535 
6536   return(buf);
6537 }
6538 
6539 /* ****************************************************** */
6540 
ndpi_protocol2name(struct ndpi_detection_module_struct * ndpi_str,ndpi_protocol proto,char * buf,u_int buf_len)6541 char *ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_str,
6542 			 ndpi_protocol proto, char *buf, u_int buf_len) {
6543   if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) {
6544     if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)
6545       snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol),
6546 	       ndpi_get_proto_name(ndpi_str, proto.app_protocol));
6547     else
6548       snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol));
6549   } else
6550     snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.app_protocol));
6551 
6552   return(buf);
6553 }
6554 
6555 /* ****************************************************** */
6556 
ndpi_is_custom_category(ndpi_protocol_category_t category)6557 int ndpi_is_custom_category(ndpi_protocol_category_t category) {
6558   switch(category) {
6559   case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
6560   case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
6561   case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
6562   case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
6563   case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
6564     return(1);
6565     break;
6566 
6567   default:
6568     return(0);
6569     break;
6570   }
6571 }
6572 
6573 /* ****************************************************** */
6574 
ndpi_category_set_name(struct ndpi_detection_module_struct * ndpi_str,ndpi_protocol_category_t category,char * name)6575 void ndpi_category_set_name(struct ndpi_detection_module_struct *ndpi_str,
6576 			    ndpi_protocol_category_t category,
6577 			    char *name) {
6578   if(!name)
6579     return;
6580 
6581   switch(category) {
6582   case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
6583     snprintf(ndpi_str->custom_category_labels[0], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
6584     break;
6585 
6586   case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
6587     snprintf(ndpi_str->custom_category_labels[1], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
6588     break;
6589 
6590   case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
6591     snprintf(ndpi_str->custom_category_labels[2], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
6592     break;
6593 
6594   case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
6595     snprintf(ndpi_str->custom_category_labels[3], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
6596     break;
6597 
6598   case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
6599     snprintf(ndpi_str->custom_category_labels[4], CUSTOM_CATEGORY_LABEL_LEN, "%s", name);
6600     break;
6601 
6602   default:
6603     break;
6604   }
6605 }
6606 
6607 /* ****************************************************** */
6608 
ndpi_category_get_name(struct ndpi_detection_module_struct * ndpi_str,ndpi_protocol_category_t category)6609 const char *ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_str,
6610 				   ndpi_protocol_category_t category) {
6611   if((!ndpi_str) || (category >= NDPI_PROTOCOL_NUM_CATEGORIES)) {
6612     static char b[24];
6613 
6614     if(!ndpi_str)
6615       snprintf(b, sizeof(b), "NULL nDPI");
6616     else
6617       snprintf(b, sizeof(b), "Invalid category %d", (int) category);
6618     return(b);
6619   }
6620 
6621   if((category >= NDPI_PROTOCOL_CATEGORY_CUSTOM_1) && (category <= NDPI_PROTOCOL_CATEGORY_CUSTOM_5)) {
6622     switch(category) {
6623     case NDPI_PROTOCOL_CATEGORY_CUSTOM_1:
6624       return(ndpi_str->custom_category_labels[0]);
6625     case NDPI_PROTOCOL_CATEGORY_CUSTOM_2:
6626       return(ndpi_str->custom_category_labels[1]);
6627     case NDPI_PROTOCOL_CATEGORY_CUSTOM_3:
6628       return(ndpi_str->custom_category_labels[2]);
6629     case NDPI_PROTOCOL_CATEGORY_CUSTOM_4:
6630       return(ndpi_str->custom_category_labels[3]);
6631     case NDPI_PROTOCOL_CATEGORY_CUSTOM_5:
6632       return(ndpi_str->custom_category_labels[4]);
6633     case NDPI_PROTOCOL_NUM_CATEGORIES:
6634       return("Code should not use this internal constant");
6635     default:
6636       return("Unspecified");
6637     }
6638   } else
6639     return(categories[category]);
6640 }
6641 
6642 /* ****************************************************** */
6643 
ndpi_get_proto_category(struct ndpi_detection_module_struct * ndpi_str,ndpi_protocol proto)6644 ndpi_protocol_category_t ndpi_get_proto_category(struct ndpi_detection_module_struct *ndpi_str,
6645 						 ndpi_protocol proto) {
6646   if(proto.category != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
6647     return(proto.category);
6648 
6649   /* simple rule: sub protocol first, master after */
6650   else if((proto.master_protocol == NDPI_PROTOCOL_UNKNOWN) ||
6651 	  (ndpi_str->proto_defaults[proto.app_protocol].protoCategory != NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)) {
6652     if(ndpi_is_valid_protoId(proto.app_protocol))
6653       return(ndpi_str->proto_defaults[proto.app_protocol].protoCategory);
6654   } else if(ndpi_is_valid_protoId(proto.master_protocol))
6655     return(ndpi_str->proto_defaults[proto.master_protocol].protoCategory);
6656 
6657   return(NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
6658 }
6659 
6660 /* ****************************************************** */
6661 
ndpi_get_proto_name(struct ndpi_detection_module_struct * ndpi_str,u_int16_t proto_id)6662 char *ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_str,
6663 			  u_int16_t proto_id) {
6664   if((proto_id >= ndpi_str->ndpi_num_supported_protocols)
6665      || (!ndpi_is_valid_protoId(proto_id))
6666      || (ndpi_str->proto_defaults[proto_id].protoName == NULL))
6667     proto_id = NDPI_PROTOCOL_UNKNOWN;
6668 
6669   return(ndpi_str->proto_defaults[proto_id].protoName);
6670 }
6671 
6672 /* ****************************************************** */
6673 
ndpi_get_proto_breed(struct ndpi_detection_module_struct * ndpi_str,u_int16_t proto_id)6674 ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_str,
6675 					   u_int16_t proto_id) {
6676   if((proto_id >= ndpi_str->ndpi_num_supported_protocols) ||
6677      (!ndpi_is_valid_protoId(proto_id)) ||
6678      (ndpi_str->proto_defaults[proto_id].protoName == NULL))
6679     proto_id = NDPI_PROTOCOL_UNKNOWN;
6680 
6681   return(ndpi_str->proto_defaults[proto_id].protoBreed);
6682 }
6683 
6684 /* ****************************************************** */
6685 
ndpi_get_proto_breed_name(struct ndpi_detection_module_struct * ndpi_str,ndpi_protocol_breed_t breed_id)6686 char *ndpi_get_proto_breed_name(struct ndpi_detection_module_struct *ndpi_str,
6687 				ndpi_protocol_breed_t breed_id) {
6688   switch(breed_id) {
6689   case NDPI_PROTOCOL_SAFE:
6690     return("Safe");
6691     break;
6692   case NDPI_PROTOCOL_ACCEPTABLE:
6693     return("Acceptable");
6694     break;
6695   case NDPI_PROTOCOL_FUN:
6696     return("Fun");
6697     break;
6698   case NDPI_PROTOCOL_UNSAFE:
6699     return("Unsafe");
6700     break;
6701   case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS:
6702     return("Potentially Dangerous");
6703     break;
6704   case NDPI_PROTOCOL_TRACKER_ADS:
6705     return("Tracker/Ads");
6706     break;
6707   case NDPI_PROTOCOL_DANGEROUS:
6708     return("Dangerous");
6709     break;
6710   case NDPI_PROTOCOL_UNRATED:
6711     return("Unrated");
6712     break;
6713   default:
6714     return("???");
6715     break;
6716   }
6717 }
6718 
6719 /* ****************************************************** */
6720 
ndpi_get_protocol_id(struct ndpi_detection_module_struct * ndpi_str,char * proto)6721 int ndpi_get_protocol_id(struct ndpi_detection_module_struct *ndpi_str, char *proto) {
6722   int i;
6723 
6724   for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
6725     if(strcasecmp(proto, ndpi_str->proto_defaults[i].protoName) == 0)
6726       return(i);
6727 
6728   return(-1);
6729 }
6730 
6731 /* ****************************************************** */
6732 
ndpi_get_category_id(struct ndpi_detection_module_struct * ndpi_str,char * cat)6733 int ndpi_get_category_id(struct ndpi_detection_module_struct *ndpi_str, char *cat) {
6734   int i;
6735 
6736   for(i = 0; i < NDPI_PROTOCOL_NUM_CATEGORIES; i++) {
6737     const char *name = ndpi_category_get_name(ndpi_str, i);
6738 
6739     if(strcasecmp(cat, name) == 0)
6740       return(i);
6741   }
6742 
6743   return(-1);
6744 }
6745 
6746 /* ****************************************************** */
6747 
ndpi_dump_protocols(struct ndpi_detection_module_struct * ndpi_str)6748 void ndpi_dump_protocols(struct ndpi_detection_module_struct *ndpi_str) {
6749   int i;
6750 
6751   for(i = 0; i < (int) ndpi_str->ndpi_num_supported_protocols; i++)
6752     printf("%3d %-22s %-8s %-12s %s\n", i, ndpi_str->proto_defaults[i].protoName,
6753 	   ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_str, i)),
6754 	   ndpi_get_proto_breed_name(ndpi_str, ndpi_str->proto_defaults[i].protoBreed),
6755 	   ndpi_category_get_name(ndpi_str, ndpi_str->proto_defaults[i].protoCategory));
6756 }
6757 
6758 /* ****************************************************** */
6759 
ndpi_dump_risks_score()6760 void ndpi_dump_risks_score() {
6761   u_int i;
6762 
6763   printf("%3s %-48s %-8s %s %-8s %-8s\n",
6764 	 "Id", "Risk", "Severity", "Score", "CliScore", "SrvScore");
6765 
6766   for(i = 1; i < NDPI_MAX_RISK; i++) {
6767     ndpi_risk_enum r = (ndpi_risk_enum)i;
6768     ndpi_risk risk   = 2 << (r-1);
6769     ndpi_risk_info* info = ndpi_risk2severity(r);
6770     ndpi_risk_severity s =info->severity;
6771     u_int16_t client_score, server_score;
6772     u_int16_t score = ndpi_risk2score(risk, &client_score, &server_score);
6773 
6774     printf("%3d %-48s %-8s %-8u %-8u %-8u\n",
6775 	   i, ndpi_risk2str(r),
6776 	   ndpi_severity2str(s),
6777 	   score,
6778 	   client_score, server_score);
6779   }
6780 }
6781 
6782 /* ****************************************************** */
6783 
6784 /*
6785  * Find the first occurrence of find in s, where the search is limited to the
6786  * first slen characters of s.
6787  */
ndpi_strnstr(const char * s,const char * find,size_t slen)6788 char *ndpi_strnstr(const char *s, const char *find, size_t slen) {
6789   char c;
6790   size_t len;
6791 
6792   if((c = *find++) != '\0') {
6793     len = strnlen(find, slen);
6794     do {
6795       char sc;
6796 
6797       do {
6798 	if(slen-- < 1 || (sc = *s++) == '\0')
6799 	  return(NULL);
6800       } while(sc != c);
6801       if(len > slen)
6802 	return(NULL);
6803     } while(strncmp(s, find, len) != 0);
6804     s--;
6805   }
6806 
6807   return((char *) s);
6808 }
6809 
6810 /* ****************************************************** */
6811 
6812 /*
6813  * Same as ndpi_strnstr but case-insensitive
6814  */
ndpi_strncasestr(const char * str1,const char * str2,size_t len)6815 const char * ndpi_strncasestr(const char *str1, const char *str2, size_t len) {
6816   size_t str1_len = strnlen(str1, len);
6817   size_t str2_len = strlen(str2);
6818   size_t i;
6819 
6820   for(i = 0; i < (str1_len - str2_len + 1); i++){
6821     if(str1[0] == '\0')
6822       return NULL;
6823     else if(strncasecmp(str1, str2, str2_len) == 0)
6824       return(str1);
6825 
6826     str1++;
6827   }
6828 
6829   return NULL;
6830 }
6831 
6832 /* ****************************************************** */
6833 
ndpi_match_prefix(const u_int8_t * payload,size_t payload_len,const char * str,size_t str_len)6834 int ndpi_match_prefix(const u_int8_t *payload,
6835 		      size_t payload_len, const char *str, size_t str_len) {
6836   int rc = str_len <= payload_len ? memcmp(payload, str, str_len) == 0 : 0;
6837 
6838   return(rc);
6839 }
6840 
6841 /* ****************************************************** */
6842 
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)6843 int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str, char *string_to_match,
6844 				  u_int string_to_match_len, ndpi_protocol_match_result *ret_match,
6845 				  u_int8_t is_host_match) {
6846   ndpi_automa *automa = is_host_match ? &ndpi_str->host_automa : &ndpi_str->content_automa;
6847   int rc;
6848 
6849   if((automa->ac_automa == NULL) || (string_to_match_len == 0))
6850     return(NDPI_PROTOCOL_UNKNOWN);
6851 
6852   rc = ndpi_match_string_common(((AC_AUTOMATA_t *) automa->ac_automa),
6853 				string_to_match,string_to_match_len, &ret_match->protocol_id,
6854 				&ret_match->protocol_category, &ret_match->protocol_breed);
6855   return rc < 0 ? rc : ret_match->protocol_id;
6856 }
6857 
6858 /* **************************************** */
6859 
ndpi_is_more_generic_protocol(u_int16_t previous_proto,u_int16_t new_proto)6860 static u_int8_t ndpi_is_more_generic_protocol(u_int16_t previous_proto, u_int16_t new_proto) {
6861   /* Sometimes certificates are more generic than previously identified protocols */
6862 
6863   if((previous_proto == NDPI_PROTOCOL_UNKNOWN) || (previous_proto == new_proto))
6864     return(0);
6865 
6866   switch(previous_proto) {
6867   case NDPI_PROTOCOL_WHATSAPP_CALL:
6868   case NDPI_PROTOCOL_WHATSAPP_FILES:
6869     if(new_proto == NDPI_PROTOCOL_WHATSAPP)
6870       return(1);
6871   }
6872 
6873   return(0);
6874 }
6875 
6876 /* ****************************************************** */
6877 
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)6878 static u_int16_t ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
6879 						      struct ndpi_flow_struct *flow, char *string_to_match,
6880 						      u_int string_to_match_len, u_int16_t master_protocol_id,
6881 						      ndpi_protocol_match_result *ret_match, u_int8_t is_host_match) {
6882   int matching_protocol_id;
6883   struct ndpi_packet_struct *packet = &flow->packet;
6884 
6885   matching_protocol_id =
6886     ndpi_match_string_subprotocol(ndpi_str, string_to_match, string_to_match_len, ret_match, is_host_match);
6887 
6888   if(matching_protocol_id < 0)
6889     return NDPI_PROTOCOL_UNKNOWN;
6890 
6891 #ifdef DEBUG
6892   {
6893     char m[256];
6894     int len = ndpi_min(sizeof(m), string_to_match_len);
6895 
6896     strncpy(m, string_to_match, len);
6897     m[len] = '\0';
6898 
6899     NDPI_LOG_DBG2(ndpi_str, "[NDPI] ndpi_match_host_subprotocol(%s): %s\n", m,
6900 		  ndpi_str->proto_defaults[matching_protocol_id].protoName);
6901   }
6902 #endif
6903 
6904   if((matching_protocol_id != NDPI_PROTOCOL_UNKNOWN) &&
6905      (!ndpi_is_more_generic_protocol(packet->detected_protocol_stack[0], matching_protocol_id))) {
6906     /* Move the protocol on slot 0 down one position */
6907     packet->detected_protocol_stack[1] = master_protocol_id,
6908       packet->detected_protocol_stack[0] = matching_protocol_id;
6909 
6910     flow->detected_protocol_stack[0] = packet->detected_protocol_stack[0],
6911       flow->detected_protocol_stack[1] = packet->detected_protocol_stack[1];
6912 
6913     if(flow->category == NDPI_PROTOCOL_CATEGORY_UNSPECIFIED)
6914       flow->category = ret_match->protocol_category;
6915 
6916     return(packet->detected_protocol_stack[0]);
6917   }
6918 
6919 #ifdef DEBUG
6920   string_to_match[string_to_match_len] = '\0';
6921   NDPI_LOG_DBG2(ndpi_str, "[NTOP] Unable to find a match for '%s'\n", string_to_match);
6922 #endif
6923 
6924   ret_match->protocol_id = NDPI_PROTOCOL_UNKNOWN, ret_match->protocol_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
6925     ret_match->protocol_breed = NDPI_PROTOCOL_UNRATED;
6926 
6927   return(NDPI_PROTOCOL_UNKNOWN);
6928 }
6929 
6930 /* ****************************************************** */
6931 
ndpi_check_subprotocol_risk(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,u_int16_t subprotocol_id)6932 void ndpi_check_subprotocol_risk(struct ndpi_detection_module_struct *ndpi_str,
6933 				 struct ndpi_flow_struct *flow, u_int16_t subprotocol_id) {
6934   switch(subprotocol_id) {
6935   case NDPI_PROTOCOL_ANYDESK:
6936     ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */
6937     break;
6938   }
6939 }
6940 
6941 /* ****************************************************** */
6942 
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)6943 u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
6944 				      struct ndpi_flow_struct *flow,
6945 				      char *string_to_match, u_int string_to_match_len,
6946 				      ndpi_protocol_match_result *ret_match,
6947 				      u_int16_t master_protocol_id) {
6948   u_int16_t rc;
6949   ndpi_protocol_category_t id;
6950 
6951   rc = ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
6952 					    master_protocol_id, ret_match, 1);
6953   id = ret_match->protocol_category;
6954 
6955   if(ndpi_get_custom_category_match(ndpi_str, string_to_match, string_to_match_len, &id) != -1) {
6956     /* if(id != -1) */ {
6957       flow->category = ret_match->protocol_category = id;
6958       rc = master_protocol_id;
6959     }
6960   }
6961 
6962   if(ndpi_str->risky_domain_automa.ac_automa != NULL) {
6963     u_int32_t proto_id;
6964     u_int16_t rc1 = ndpi_match_string_common(ndpi_str->risky_domain_automa.ac_automa,
6965 					     string_to_match,string_to_match_len,
6966 					     &proto_id, NULL, NULL);
6967     if(rc1 > 0)
6968       ndpi_set_risk(ndpi_str, flow, NDPI_RISKY_DOMAIN);
6969   }
6970 
6971   return(rc);
6972 }
6973 
6974 /* **************************************** */
6975 
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)6976 int ndpi_match_hostname_protocol(struct ndpi_detection_module_struct *ndpi_struct,
6977 				 struct ndpi_flow_struct *flow,
6978 				 u_int16_t master_protocol, char *name, u_int name_len) {
6979   ndpi_protocol_match_result ret_match;
6980   u_int16_t subproto, what_len;
6981   char *what;
6982 
6983   if((name_len > 2) && (name[0] == '*') && (name[1] == '.'))
6984     what = &name[1], what_len = name_len - 1;
6985   else
6986     what = name, what_len = name_len;
6987 
6988   subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, what, what_len,
6989 					 &ret_match, master_protocol);
6990 
6991   if(subproto != NDPI_PROTOCOL_UNKNOWN) {
6992     ndpi_set_detected_protocol(ndpi_struct, flow, subproto, master_protocol);
6993     ndpi_int_change_category(ndpi_struct, flow, ret_match.protocol_category);
6994     return(1);
6995   } else
6996     return(0);
6997 }
6998 
6999 /* ****************************************************** */
7000 
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)7001 u_int16_t ndpi_match_content_subprotocol(struct ndpi_detection_module_struct *ndpi_str,
7002 					 struct ndpi_flow_struct *flow,
7003 					 char *string_to_match, u_int string_to_match_len,
7004 					 ndpi_protocol_match_result *ret_match,
7005 					 u_int16_t master_protocol_id) {
7006   return(ndpi_automa_match_string_subprotocol(ndpi_str, flow, string_to_match, string_to_match_len,
7007 					      master_protocol_id, ret_match, 0));
7008 }
7009 
7010 /* ****************************************************** */
7011 
ndpi_match_xgram(unsigned int * map,int l,const char * str)7012 static inline int ndpi_match_xgram(unsigned int *map,int l,const char *str) {
7013   unsigned int i,c;
7014   for(i=0,c=0; *str && i < l; i++) {
7015     unsigned char a = (unsigned char)(*str++);
7016     if(a < 'a' || a > 'z') return 0;
7017     c *= XGRAMS_C;
7018     c += a-'a';
7019   }
7020   return (map[c >> 5] & (1u << (c & 0x1f))) != 0;
7021 }
ndpi_match_bigram(const char * str)7022 int ndpi_match_bigram(const char *str) {
7023   return ndpi_match_xgram(bigrams_bitmap, 2, str);
7024 }
7025 
ndpi_match_impossible_bigram(const char * str)7026 int ndpi_match_impossible_bigram(const char *str) {
7027   return ndpi_match_xgram(imposible_bigrams_bitmap, 2, str);
7028 }
7029 
7030 /* ****************************************************** */
7031 
ndpi_match_trigram(const char * str)7032 int ndpi_match_trigram(const char *str) {
7033   return ndpi_match_xgram(trigrams_bitmap, 3, str);
7034 }
7035 
7036 
7037 /* ****************************************************** */
7038 
ndpi_free_flow(struct ndpi_flow_struct * flow)7039 void ndpi_free_flow(struct ndpi_flow_struct *flow) {
7040   if(flow) {
7041     ndpi_free_flow_data(flow);
7042     ndpi_free(flow);
7043   }
7044 }
7045 
7046 /* ****************************************************** */
7047 
ndpi_revision()7048 char *ndpi_revision() {
7049   return(NDPI_GIT_RELEASE);
7050 }
7051 
7052 /* ****************************************************** */
7053 
7054 #ifdef WIN32
7055 
7056 /* https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */
gettimeofday(struct timeval * tp,struct timezone * tzp)7057 int gettimeofday(struct timeval *tp, struct timezone *tzp) {
7058   // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
7059   // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
7060   // until 00:00:00 January 1, 1970
7061   static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
7062 
7063   SYSTEMTIME system_time;
7064   FILETIME file_time;
7065   uint64_t time;
7066 
7067   GetSystemTime(&system_time);
7068   SystemTimeToFileTime(&system_time, &file_time);
7069   time = ((uint64_t) file_time.dwLowDateTime);
7070   time += ((uint64_t) file_time.dwHighDateTime) << 32;
7071 
7072   tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
7073   tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
7074   return(0);
7075 }
7076 #endif
7077 
NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a,NDPI_PROTOCOL_BITMASK b)7078 int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
7079   int i;
7080 
7081   for(i = 0; i < NDPI_NUM_FDS_BITS; i++) {
7082     if(a.fds_bits[i] & b.fds_bits[i])
7083       return(1);
7084   }
7085 
7086   return(0);
7087 }
7088 
7089 #ifdef CODE_UNUSED
NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a)7090 int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) {
7091   int i;
7092 
7093   for(i = 0; i < NDPI_NUM_FDS_BITS; i++)
7094     if(a.fds_bits[i] != 0)
7095       return(0);
7096 
7097   return(1);
7098 }
7099 
NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a)7100 void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) {
7101   int i;
7102 
7103   for(i = 0; i < NDPI_NUM_FDS_BITS; i++)
7104     printf("[%d=%u]", i, a.fds_bits[i]);
7105 
7106   printf("\n");
7107 }
7108 #endif
7109 
ndpi_get_api_version()7110 u_int16_t ndpi_get_api_version() {
7111   return(NDPI_API_VERSION);
7112 }
7113 
ndpi_get_gcrypt_version(void)7114 const char *ndpi_get_gcrypt_version(void) {
7115 #ifdef HAVE_LIBGCRYPT
7116   return gcry_check_version(NULL);
7117 #endif
7118   return NULL;
7119 }
7120 
ndpi_get_proto_defaults(struct ndpi_detection_module_struct * ndpi_str)7121 ndpi_proto_defaults_t *ndpi_get_proto_defaults(struct ndpi_detection_module_struct *ndpi_str) {
7122   return(ndpi_str->proto_defaults);
7123 }
7124 
ndpi_get_ndpi_num_supported_protocols(struct ndpi_detection_module_struct * ndpi_str)7125 u_int ndpi_get_ndpi_num_supported_protocols(struct ndpi_detection_module_struct *ndpi_str) {
7126   return(ndpi_str->ndpi_num_supported_protocols);
7127 }
7128 
ndpi_get_ndpi_num_custom_protocols(struct ndpi_detection_module_struct * ndpi_str)7129 u_int ndpi_get_ndpi_num_custom_protocols(struct ndpi_detection_module_struct *ndpi_str) {
7130   return(ndpi_str->ndpi_num_custom_protocols);
7131 }
7132 
ndpi_get_ndpi_detection_module_size()7133 u_int ndpi_get_ndpi_detection_module_size() {
7134   return(sizeof(struct ndpi_detection_module_struct));
7135 }
7136 
ndpi_set_debug_bitmask(struct ndpi_detection_module_struct * ndpi_str,NDPI_PROTOCOL_BITMASK debug_bitmask)7137 void ndpi_set_debug_bitmask(struct ndpi_detection_module_struct *ndpi_str, NDPI_PROTOCOL_BITMASK debug_bitmask) {
7138 #ifdef NDPI_ENABLE_DEBUG_MESSAGES
7139   ndpi_str->debug_bitmask = debug_bitmask;
7140 #endif
7141 }
7142 
ndpi_set_log_level(struct ndpi_detection_module_struct * ndpi_str,u_int l)7143 void ndpi_set_log_level(struct ndpi_detection_module_struct *ndpi_str, u_int l){
7144   ndpi_str->ndpi_log_level = l;
7145 }
7146 
7147 /* ******************************************************************** */
7148 
7149 /* LRU cache */
ndpi_lru_cache_init(u_int32_t num_entries)7150 struct ndpi_lru_cache *ndpi_lru_cache_init(u_int32_t num_entries) {
7151   struct ndpi_lru_cache *c = (struct ndpi_lru_cache *) ndpi_malloc(sizeof(struct ndpi_lru_cache));
7152 
7153   if(!c)
7154     return(NULL);
7155 
7156   c->entries = (struct ndpi_lru_cache_entry *) ndpi_calloc(num_entries, sizeof(struct ndpi_lru_cache_entry));
7157 
7158   if(!c->entries) {
7159     ndpi_free(c);
7160     return(NULL);
7161   } else
7162     c->num_entries = num_entries;
7163 
7164   return(c);
7165 }
7166 
ndpi_lru_free_cache(struct ndpi_lru_cache * c)7167 void ndpi_lru_free_cache(struct ndpi_lru_cache *c) {
7168   ndpi_free(c->entries);
7169   ndpi_free(c);
7170 }
7171 
ndpi_lru_find_cache(struct ndpi_lru_cache * c,u_int32_t key,u_int16_t * value,u_int8_t clean_key_when_found)7172 u_int8_t ndpi_lru_find_cache(struct ndpi_lru_cache *c, u_int32_t key,
7173 			     u_int16_t *value, u_int8_t clean_key_when_found) {
7174   u_int32_t slot = key % c->num_entries;
7175 
7176   if(c->entries[slot].is_full && c->entries[slot].key == key) {
7177     *value = c->entries[slot].value;
7178     if(clean_key_when_found)
7179       c->entries[slot].is_full = 0;
7180     return(1);
7181   } else
7182     return(0);
7183 }
7184 
ndpi_lru_add_to_cache(struct ndpi_lru_cache * c,u_int32_t key,u_int16_t value)7185 void ndpi_lru_add_to_cache(struct ndpi_lru_cache *c, u_int32_t key, u_int16_t value) {
7186   u_int32_t slot = key % c->num_entries;
7187 
7188   c->entries[slot].is_full = 1, c->entries[slot].key = key, c->entries[slot].value = value;
7189 }
7190 
7191 /* ******************************************************************** */
7192 
7193 /*
7194   This function tells if it's possible to further dissect a given flow
7195   0 - All possible dissection has been completed
7196   1 - Additional dissection is possible
7197 */
ndpi_extra_dissection_possible(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow)7198 u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndpi_str,
7199 					struct ndpi_flow_struct *flow) {
7200   u_int16_t proto =
7201     flow->detected_protocol_stack[1] ? flow->detected_protocol_stack[1] : flow->detected_protocol_stack[0];
7202 
7203 #if 0
7204   printf("[DEBUG] %s(%u.%u): %u\n", __FUNCTION__,
7205 	 flow->detected_protocol_stack[0],
7206 	 flow->detected_protocol_stack[1],
7207 	 proto);
7208 #endif
7209 
7210   switch(proto) {
7211   case NDPI_PROTOCOL_TLS:
7212   case NDPI_PROTOCOL_DTLS:
7213     if(flow->l4.tcp.tls.certificate_processed) return(0);
7214 
7215     if(flow->l4.tcp.tls.num_tls_blocks <= ndpi_str->num_tls_blocks_to_follow) {
7216       // printf("*** %u/%u\n", flow->l4.tcp.tls.num_tls_blocks, ndpi_str->num_tls_blocks_to_follow);
7217       return(1);
7218     }
7219     break;
7220 
7221   case NDPI_PROTOCOL_HTTP:
7222     if((flow->host_server_name[0] == '\0') || (flow->http.response_status_code == 0))
7223       return(1);
7224     break;
7225 
7226   case NDPI_PROTOCOL_DNS:
7227   case NDPI_PROTOCOL_MDNS:
7228     if(flow->protos.dns.num_answers == 0)
7229       return(1);
7230     break;
7231 
7232   case NDPI_PROTOCOL_FTP_CONTROL:
7233   case NDPI_PROTOCOL_MAIL_POP:
7234   case NDPI_PROTOCOL_MAIL_IMAP:
7235   case NDPI_PROTOCOL_MAIL_SMTP:
7236     if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0')
7237       return(1);
7238     break;
7239 
7240   case NDPI_PROTOCOL_SSH:
7241     if((flow->protos.ssh.hassh_client[0] == '\0') || (flow->protos.ssh.hassh_server[0] == '\0'))
7242       return(1);
7243     break;
7244 
7245   case NDPI_PROTOCOL_TELNET:
7246     if(!flow->protos.telnet.password_detected)
7247       return(1);
7248     break;
7249 
7250   case NDPI_PROTOCOL_SKYPE_TEAMS:
7251     if(flow->extra_packets_func)
7252       return(1);
7253     break;
7254 
7255   case NDPI_PROTOCOL_QUIC:
7256     if(flow->extra_packets_func)
7257       return(1);
7258     break;
7259   }
7260 
7261   return(0);
7262 }
7263 
7264 /* ******************************************************************** */
7265 
ndpi_get_l4_proto_name(ndpi_l4_proto_info proto)7266 const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {
7267   switch(proto) {
7268   case ndpi_l4_proto_unknown:
7269     return("");
7270     break;
7271 
7272   case ndpi_l4_proto_tcp_only:
7273     return("TCP");
7274     break;
7275 
7276   case ndpi_l4_proto_udp_only:
7277     return("UDP");
7278     break;
7279 
7280   case ndpi_l4_proto_tcp_and_udp:
7281     return("TCP/UDP");
7282     break;
7283   }
7284 
7285   return("");
7286 }
7287 
7288 /* ******************************************************************** */
7289 
ndpi_get_l4_proto_info(struct ndpi_detection_module_struct * ndpi_struct,u_int16_t ndpi_proto_id)7290 ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
7291 					  u_int16_t ndpi_proto_id) {
7292   if(ndpi_proto_id < ndpi_struct->ndpi_num_supported_protocols) {
7293     u_int16_t idx = ndpi_struct->proto_defaults[ndpi_proto_id].protoIdx;
7294     NDPI_SELECTION_BITMASK_PROTOCOL_SIZE bm = ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask;
7295 
7296     if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP)
7297       return(ndpi_l4_proto_tcp_only);
7298     else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_UDP)
7299       return(ndpi_l4_proto_udp_only);
7300     else if(bm & NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP)
7301       return(ndpi_l4_proto_tcp_and_udp);
7302   }
7303 
7304   return(ndpi_l4_proto_unknown); /* default */
7305 }
7306 
7307 /* ******************************************************************** */
7308 
ndpi_ptree_create(void)7309 ndpi_ptree_t *ndpi_ptree_create(void) {
7310   ndpi_ptree_t *tree = (ndpi_ptree_t *) ndpi_malloc(sizeof(ndpi_ptree_t));
7311 
7312   if(tree) {
7313     tree->v4 = ndpi_patricia_new(32);
7314     tree->v6 = ndpi_patricia_new(128);
7315 
7316     if((!tree->v4) || (!tree->v6)) {
7317       ndpi_ptree_destroy(tree);
7318       return(NULL);
7319     }
7320   }
7321 
7322   return(tree);
7323 }
7324 
7325 /* ******************************************************************** */
7326 
ndpi_ptree_destroy(ndpi_ptree_t * tree)7327 void ndpi_ptree_destroy(ndpi_ptree_t *tree) {
7328   if(tree) {
7329     if(tree->v4)
7330       ndpi_patricia_destroy(tree->v4, free_ptree_data);
7331     if(tree->v6)
7332       ndpi_patricia_destroy(tree->v6, free_ptree_data);
7333 
7334     ndpi_free(tree);
7335   }
7336 }
7337 
7338 /* ******************************************************************** */
7339 
ndpi_ptree_insert(ndpi_ptree_t * tree,const ndpi_ip_addr_t * addr,u_int8_t bits,u_int64_t user_data)7340 int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr,
7341 		      u_int8_t bits, u_int64_t user_data) {
7342   u_int8_t is_v6 = ndpi_is_ipv6(addr);
7343   ndpi_patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
7344   ndpi_prefix_t prefix;
7345   ndpi_patricia_node_t *node;
7346 
7347   if(bits > ptree->maxbits)
7348     return(-1);
7349 
7350   if(is_v6)
7351     ndpi_fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
7352   else
7353     ndpi_fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
7354 
7355   /* Verify that the node does not already exist */
7356   node = ndpi_patricia_search_best(ptree, &prefix);
7357 
7358   if(node && (node->prefix->bitlen == bits))
7359     return(-2);
7360 
7361   node = ndpi_patricia_lookup(ptree, &prefix);
7362 
7363   if(node != NULL) {
7364     node->value.u.uv64 = user_data;
7365 
7366     return(0);
7367   }
7368 
7369   return(-3);
7370 }
7371 
7372 /* ******************************************************************** */
7373 
ndpi_ptree_match_addr(ndpi_ptree_t * tree,const ndpi_ip_addr_t * addr,u_int64_t * user_data)7374 int ndpi_ptree_match_addr(ndpi_ptree_t *tree,
7375 			  const ndpi_ip_addr_t *addr, u_int64_t *user_data) {
7376   u_int8_t is_v6 = ndpi_is_ipv6(addr);
7377   ndpi_patricia_tree_t *ptree = is_v6 ? tree->v6 : tree->v4;
7378   ndpi_prefix_t prefix;
7379   ndpi_patricia_node_t *node;
7380   int bits = ptree->maxbits;
7381 
7382   if(is_v6)
7383     ndpi_fill_prefix_v6(&prefix, (const struct in6_addr *) &addr->ipv6, bits, ptree->maxbits);
7384   else
7385     ndpi_fill_prefix_v4(&prefix, (const struct in_addr *) &addr->ipv4, bits, ptree->maxbits);
7386 
7387   node = ndpi_patricia_search_best(ptree, &prefix);
7388 
7389   if(node) {
7390     *user_data = node->value.u.uv64;
7391 
7392     return(0);
7393   }
7394 
7395   return(-1);
7396 }
7397 
7398 /* ******************************************************************** */
7399 
7400 /* Based on djb2 hash - http://www.cse.yorku.ca/~oz/hash.html */
ndpi_quick_hash(unsigned char * str,u_int str_len)7401 u_int32_t ndpi_quick_hash(unsigned char *str, u_int str_len) {
7402   u_int32_t hash = 5381, i;
7403 
7404   for(i=0; i<str_len; i++)
7405     hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */
7406 
7407   return hash;
7408 }
7409 
7410 /* ******************************************************************** */
7411 
ndpi_md5(const u_char * data,size_t data_len,u_char hash[16])7412 void ndpi_md5(const u_char *data, size_t data_len, u_char hash[16]) {
7413   ndpi_MD5_CTX ctx;
7414 
7415   ndpi_MD5Init(&ctx);
7416   ndpi_MD5Update(&ctx, data, data_len);
7417   ndpi_MD5Final(hash, &ctx);
7418 }
7419 
7420 /* ******************************************************************** */
7421 
enough(int a,int b)7422 static int enough(int a, int b) {
7423   u_int8_t percentage = 20;
7424 
7425   if(b <= 1) return(0);
7426   if(a == 0) return(1);
7427 
7428   if(b > (((a+1)*percentage)/100)) return(1);
7429 
7430   return(0);
7431 }
7432 
7433 /* ******************************************************************** */
7434 
endsWith(char * str,char * ends,u_int8_t ends_len)7435 static u_int8_t endsWith(char *str, char *ends, u_int8_t ends_len) {
7436   u_int str_len = str ? strlen(str) : 0;
7437   u_int8_t rc;
7438 
7439   if(str_len < ends_len) return(0);
7440 
7441   rc = (strncmp(&str[str_len-ends_len], ends, ends_len) != 0) ? 0 : 1;
7442 
7443 #ifdef DGA_DEBUG
7444   printf("[DGA] %s / %s [rc: %u]\n", str, ends, rc);
7445 #endif
7446 
7447   return(rc);
7448 }
7449 
7450 /* ******************************************************************** */
7451 
ndpi_is_trigram_char(char c)7452 static int ndpi_is_trigram_char(char c) {
7453   if(isdigit(c) || (c == '.') || (c == '-'))
7454     return(0);
7455   else
7456     return(1);
7457 }
7458 
7459 /* ******************************************************************** */
7460 
ndpi_is_vowel(char c)7461 static int ndpi_is_vowel(char c) {
7462   switch(c) {
7463   case 'a':
7464   case 'e':
7465   case 'i':
7466   case 'o':
7467   case 'u':
7468   case 'y': // Not a real vowel...
7469   case 'x': // Not a real vowel...
7470     return(1);
7471     break;
7472 
7473   default:
7474     return(0);
7475   }
7476 }
7477 
7478 /* ******************************************************************** */
7479 
ndpi_check_dga_name(struct ndpi_detection_module_struct * ndpi_str,struct ndpi_flow_struct * flow,char * name,u_int8_t is_hostname)7480 int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
7481 			struct ndpi_flow_struct *flow,
7482 			char *name, u_int8_t is_hostname) {
7483   if(ndpi_dga_function != NULL) {
7484     /* A custom DGA function is defined */
7485     int rc = ndpi_dga_function(name, is_hostname);
7486 
7487     if(rc) {
7488       if(flow)
7489 	ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
7490     }
7491 
7492     return(rc);
7493   } else {
7494     int len, rc = 0, trigram_char_skip = 0;
7495     u_int8_t max_num_char_repetitions = 0, last_char = 0, num_char_repetitions = 0, num_dots = 0, num_trigram_dots = 0;
7496     u_int8_t max_domain_element_len = 0, curr_domain_element_len = 0, first_element_is_numeric = 1;
7497 
7498     if((!name)
7499        || (strchr(name, '_') != NULL)
7500        || (endsWith(name, "in-addr.arpa", 12))
7501        || (endsWith(name, "ip6.arpa", 8))
7502        /* Ignore TLD .local .lan and .home */
7503        || (endsWith(name, ".local", 6))
7504        || (endsWith(name, ".lan", 4))
7505        || (endsWith(name, ".home", 5))
7506        )
7507       return(0);
7508 
7509     if(flow && (flow->packet.detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN))
7510       return(0); /* Ignore DGA check for protocols already fully detected */
7511 
7512     if(strncmp(name, "www.", 4) == 0)
7513       name = &name[4];
7514 
7515     if(ndpi_verbose_dga_detection)
7516       printf("[DGA check] %s\n", name);
7517 
7518     len = strlen(name);
7519 
7520     if(len >= 5) {
7521       int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0,
7522 	num_trigram_found = 0, num_trigram_checked = 0, num_dash = 0,
7523 	num_digits = 0, num_vowels = 0, num_trigram_vowels = 0, num_words = 0, skip_next_bigram = 0;
7524       char tmp[128], *word, *tok_tmp;
7525       u_int max_tmp_len = sizeof(tmp)-1;
7526 
7527       len = snprintf(tmp, max_tmp_len, "%s", name);
7528       if(len < 0) {
7529 
7530 	if(ndpi_verbose_dga_detection)
7531 	  printf("[DGA] Too short");
7532 
7533 	return(0);
7534       } else
7535 	tmp[len < max_tmp_len ? len : max_tmp_len] = '\0';
7536 
7537       for(i=0, j=0; (i<len) && (j<max_tmp_len); i++) {
7538 	tmp[j] = tolower(name[i]);
7539 
7540 	if(tmp[j] == '.') {
7541 	  num_dots++;
7542 	} else if(num_dots == 0) {
7543 	  if(!isdigit(tmp[j]))
7544 	    first_element_is_numeric = 0;
7545 	}
7546 
7547 	if(ndpi_is_vowel(tmp[j]))
7548 	  num_vowels++;
7549 
7550 	if(last_char == tmp[j]) {
7551 	  if(++num_char_repetitions > max_num_char_repetitions)
7552 	    max_num_char_repetitions = num_char_repetitions;
7553 	} else
7554 	  num_char_repetitions = 1, last_char = tmp[j];
7555 
7556 	if(isdigit(tmp[j])) {
7557 	  num_digits++;
7558 
7559 	  if(((j+2)<len) && isdigit(tmp[j+1]) && (tmp[j+2] == '.')) {
7560 	    /* Check if there are too many digits */
7561 	    if(num_digits < 4)
7562 	      return(0); /* Double digits */
7563 	  }
7564 	}
7565 
7566 	switch(tmp[j]) {
7567 	case '.':
7568 	case '-':
7569 	case '_':
7570 	case '/':
7571 	case ')':
7572 	case '(':
7573 	case ';':
7574 	case ':':
7575 	case '[':
7576 	case ']':
7577 	case ' ':
7578 	  /*
7579 	    Domain/word separator chars
7580 
7581 	    NOTE:
7582 	    this function is used also to detect other type of issues
7583 	    such as invalid/suspiciuous user agent
7584 	  */
7585 	  if(curr_domain_element_len > max_domain_element_len)
7586 	    max_domain_element_len = curr_domain_element_len;
7587 
7588 	  curr_domain_element_len = 0;
7589 	  break;
7590 
7591 	default:
7592 	  curr_domain_element_len++;
7593 	  break;
7594 	}
7595 
7596 	j++;
7597       }
7598 
7599       if(num_dots == 0) /* Doesn't look like a domain name */
7600 	return(0);
7601 
7602       if(curr_domain_element_len > max_domain_element_len)
7603 	max_domain_element_len = curr_domain_element_len;
7604 
7605       if(ndpi_verbose_dga_detection)
7606 	printf("[DGA] [max_num_char_repetitions: %u][max_domain_element_len: %u]\n",
7607 	       max_num_char_repetitions, max_domain_element_len);
7608 
7609       if(
7610 	 (is_hostname
7611 	  && (num_dots > 5)
7612 	  && (!first_element_is_numeric)
7613 	  )
7614 	 || (max_num_char_repetitions > 5 /* num or consecutive repeated chars */)
7615 	 /*
7616 	   In case of a name with too many consecutive chars an alert is triggered
7617 	   This is the case for instance of the wildcard DNS query used by NetBIOS
7618 	   (ckaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) and that can be exploited
7619 	   for reflection attacks
7620 	   - https://www.akamai.com/uk/en/multimedia/documents/state-of-the-internet/ddos-reflection-netbios-name-server-rpc-portmap-sentinel-udp-threat-advisory.pdf
7621 	   - http://ubiqx.org/cifs/NetBIOS.html
7622 	 */
7623 	 || ((max_domain_element_len >= 19 /* word too long. Example bbcbedxhgjmdobdprmen.com */) && ((num_char_repetitions > 1) || (num_digits > 1)))
7624 	 ) {
7625 	if(flow) ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
7626 
7627 	if(ndpi_verbose_dga_detection)
7628 	  printf("[DGA] Found!");
7629 
7630 	return(1);
7631       }
7632 
7633       tmp[j] = '\0';
7634       len = j;
7635 
7636       for(word = strtok_r(tmp, ".", &tok_tmp); ; word = strtok_r(NULL, ".", &tok_tmp)) {
7637 	if(!word) break;
7638 
7639 	num_words++;
7640 
7641 	if(strlen(word) < 3) continue;
7642 
7643 	if(ndpi_verbose_dga_detection)
7644 	  printf("-> word(%s) [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
7645 
7646 	trigram_char_skip = 0;
7647 
7648 	for(i = 0; word[i+1] != '\0'; i++) {
7649 	  switch(word[i]) {
7650 	  case '-':
7651 	    num_dash++;
7652 	    /*
7653 	      Let's check for double+consecutive --
7654 	      that are usually ok
7655 	      r2---sn-uxaxpu5ap5-2n5e.gvt1.com
7656 	    */
7657 	    if(word[i+1] == '-')
7658 	      return(0); /* Double dash */
7659 
7660 	  case '_':
7661 	  case ':':
7662 	    continue;
7663 	    break;
7664 
7665 	  case '.':
7666 	    continue;
7667 	    break;
7668 	  }
7669 	  num_bigram_checks++;
7670 
7671 	  if(ndpi_verbose_dga_detection)
7672 	    printf("-> Checking %c%c\n", word[i], word[i+1]);
7673 
7674 	  if(ndpi_match_impossible_bigram(&word[i])) {
7675 	    if(ndpi_verbose_dga_detection)
7676 	      printf("IMPOSSIBLE %s\n", &word[i]);
7677 
7678 	    num_impossible++;
7679 	  } else {
7680 	    if(!skip_next_bigram) {
7681 	      if(ndpi_match_bigram(&word[i])) {
7682 		num_found++, skip_next_bigram = 1;
7683 	      }
7684 	    } else
7685 	      skip_next_bigram = 0;
7686 	  }
7687 
7688 	  if((num_trigram_dots < 2) && (word[i+2] != '\0')) {
7689 	    if(ndpi_verbose_dga_detection)
7690 	      printf("***> %s [trigram_char_skip: %u]\n", &word[i], trigram_char_skip);
7691 
7692 	    if(ndpi_is_trigram_char(word[i]) && ndpi_is_trigram_char(word[i+1]) && ndpi_is_trigram_char(word[i+2])) {
7693 	      if(trigram_char_skip) {
7694 		trigram_char_skip--;
7695 	      } else {
7696 		num_trigram_checked++;
7697 
7698 		if(ndpi_match_trigram(&word[i]))
7699 		  num_trigram_found++, trigram_char_skip = 2 /* 1 char overlap */;
7700 		else if(ndpi_verbose_dga_detection)
7701 		  printf("[NDPI] NO Trigram %c%c%c\n", word[i], word[i+1], word[i+2]);
7702 
7703 		/* Count vowels */
7704 		num_trigram_vowels += ndpi_is_vowel(word[i]) + ndpi_is_vowel(word[i+1]) + ndpi_is_vowel(word[i+2]);
7705 	      }
7706 	    } else {
7707 	      if(word[i] == '.')
7708 		num_trigram_dots++;
7709 
7710 	      trigram_char_skip = 0;
7711 	    }
7712 	  }
7713 	} /* for */
7714       } /* for */
7715 
7716       if(ndpi_verbose_dga_detection)
7717 	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",
7718 	       name, num_found, num_impossible, num_digits, num_bigram_checks, num_vowels, len, num_trigram_vowels,
7719 	       num_trigram_checked, num_trigram_found, num_vowels, rc);
7720 
7721       if((len > 16) && (num_dots < 3) && ((num_vowels*4) < (len-num_dots))) {
7722 	if((num_trigram_checked > 2) && (num_trigram_vowels >= (num_trigram_found-1)))
7723 	  ; /* skip me */
7724 	else
7725 	  rc = 1;
7726       }
7727 
7728       if(num_bigram_checks
7729 	 && (num_dots > 0)
7730 	 && ((num_found == 0) || ((num_digits > 5) && (num_words <= 3))
7731 	     || enough(num_found, num_impossible)
7732 	     || ((num_trigram_checked > 2)
7733 		 && ((num_trigram_found < (num_trigram_checked/2))
7734 		     || ((num_trigram_vowels < (num_trigram_found-1)) && (num_dash == 0) && (num_dots > 1) && (num_impossible > 0)))
7735 		 )
7736 	     )
7737 	 )
7738 	rc = 1;
7739 
7740       if((num_trigram_checked > 2) && (num_vowels == 0))
7741 	rc = 1;
7742 
7743       if(num_dash > 2)
7744 	rc = 0;
7745 
7746       if(ndpi_verbose_dga_detection) {
7747 	if(rc)
7748 	  printf("DGA %s [num_found: %u][num_impossible: %u]\n",
7749 		 name, num_found, num_impossible);
7750       }
7751     }
7752 
7753     if(ndpi_verbose_dga_detection)
7754       printf("[DGA] Result: %u\n", rc);
7755 
7756     if(rc && flow)
7757       ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN);
7758 
7759     return(rc);
7760   }
7761 }
7762 
7763 /* ******************************************************************** */
7764 
ndpi_risk2severity(ndpi_risk_enum risk)7765 ndpi_risk_info* ndpi_risk2severity(ndpi_risk_enum risk) {
7766   return(&ndpi_known_risks[risk]);
7767 }
7768