aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--README.md13
-rw-r--r--README.protocols2
-rw-r--r--configure.ac4
-rw-r--r--example/Makefile.am2
-rw-r--r--example/ndpiReader.c1381
-rw-r--r--example/ndpi_util.c867
-rw-r--r--example/ndpi_util.h151
-rw-r--r--libndpi.sym11
-rw-r--r--packages/homebrew/ndpi.rb11
-rw-r--r--src/include/ndpi_api.h114
-rw-r--r--src/include/ndpi_define.h27
-rw-r--r--src/include/ndpi_includes.h3
-rw-r--r--src/include/ndpi_main.h131
-rw-r--r--src/include/ndpi_protocol_ids.h53
-rw-r--r--src/include/ndpi_protocols.h14
-rw-r--r--src/include/ndpi_typedefs.h28
-rw-r--r--src/include/ndpi_unix.h3
-rw-r--r--src/include/ndpi_win32.h3
-rw-r--r--src/lib/Makefile.am11
-rw-r--r--src/lib/ndpi_content_match.c.inc79
-rw-r--r--src/lib/ndpi_main.c371
-rw-r--r--src/lib/protocols/bgp.c30
-rw-r--r--src/lib/protocols/bittorrent.c10
-rw-r--r--src/lib/protocols/coap.c38
-rw-r--r--src/lib/protocols/dcerpc.c4
-rw-r--r--src/lib/protocols/dhcp.c25
-rw-r--r--src/lib/protocols/dns.c198
-rw-r--r--src/lib/protocols/drda.c106
-rw-r--r--src/lib/protocols/dropbox.c3
-rw-r--r--src/lib/protocols/ftp_control.c456
-rw-r--r--src/lib/protocols/ftp_data.c40
-rw-r--r--src/lib/protocols/git.c83
-rw-r--r--src/lib/protocols/gnutella.c2
-rw-r--r--src/lib/protocols/gtp.c1
-rw-r--r--src/lib/protocols/h323.c8
-rw-r--r--src/lib/protocols/hangout.c105
-rw-r--r--src/lib/protocols/kakaotalk_voice.c2
-rw-r--r--src/lib/protocols/mail_imap.c22
-rw-r--r--src/lib/protocols/mqtt.c2
-rw-r--r--src/lib/protocols/msn.c12
-rw-r--r--src/lib/protocols/netbios.c2
-rw-r--r--src/lib/protocols/ntp.c62
-rw-r--r--src/lib/protocols/openvpn.c145
-rw-r--r--src/lib/protocols/oscar.c41
-rw-r--r--src/lib/protocols/pando.c10
-rw-r--r--src/lib/protocols/pplive.c14
-rw-r--r--src/lib/protocols/quic.c229
-rw-r--r--src/lib/protocols/radius.c3
-rw-r--r--src/lib/protocols/rtcp.c8
-rw-r--r--src/lib/protocols/rtp.c2
-rw-r--r--src/lib/protocols/rx.c234
-rw-r--r--src/lib/protocols/spotify.c2
-rw-r--r--src/lib/protocols/ssl.c272
-rw-r--r--src/lib/protocols/starcraft.c5
-rw-r--r--src/lib/protocols/steam.c22
-rw-r--r--src/lib/protocols/teredo.c2
-rw-r--r--src/lib/protocols/tor.c9
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/pcap/Meu.pcapbin671593 -> 0 bytes
-rw-r--r--tests/pcap/Torcedor.pcapbin70496 -> 0 bytes
-rwxr-xr-xtests/pcap/drda_db2.pcapbin0 -> 7323 bytes
-rw-r--r--tests/pcap/facebook.pcapbin0 -> 31495 bytes
-rw-r--r--tests/pcap/git.pcapbin0 -> 77264 bytes
-rw-r--r--tests/pcap/hangout.pcapbin0 -> 3102 bytes
-rw-r--r--tests/pcap/openvpn.pcapbin0 -> 61903 bytes
-rw-r--r--tests/pcap/quic.pcapbin261506 -> 356878 bytes
-rw-r--r--tests/pcap/rx.pcapbin0 -> 31116 bytes
-rw-r--r--tests/pcap/tor.pcapbin0 -> 3155084 bytes
-rw-r--r--tests/pcap/weibo.pcapbin0 -> 275547 bytes
-rw-r--r--tests/result/Instagram.pcap.out38
-rw-r--r--tests/result/Meu.pcap.out28
-rw-r--r--tests/result/NTPv3.pcap.out4
-rw-r--r--tests/result/Torcedor.pcap.out10
-rw-r--r--tests/result/Viber_session.pcap.out4
-rw-r--r--tests/result/coap_mqtt.pcap.out19
-rw-r--r--tests/result/drda_db2.pcap.out3
-rw-r--r--tests/result/dropbox.pcap.out35
-rw-r--r--tests/result/facebook.pcap.out4
-rw-r--r--tests/result/git.pcap.out3
-rw-r--r--tests/result/hangout.pcap.out3
-rw-r--r--tests/result/http_ipv6.pcap.out7
-rw-r--r--tests/result/ocs.pcap.out14
-rw-r--r--tests/result/openvpn.pcap.out5
-rw-r--r--tests/result/quic.pcap.out20
-rw-r--r--tests/result/rx.pcap.out7
-rw-r--r--tests/result/skype.pcap.out183
-rw-r--r--tests/result/skype_no_unknown.pcap.out17
-rw-r--r--tests/result/starcraft_battle.pcap.out16
-rw-r--r--tests/result/teredo.pcap.out10
-rw-r--r--tests/result/tor.pcap.out17
-rw-r--r--tests/result/viber_mobile.pcap.out4
-rw-r--r--tests/result/waze.pcap.out21
-rw-r--r--tests/result/weibo.pcap.out51
-rw-r--r--tests/result/whatsapp_login_call.pcap.out4
-rw-r--r--tests/result/whatsapp_login_chat.pcap.out4
96 files changed, 3693 insertions, 2331 deletions
diff --git a/Makefile.am b/Makefile.am
index 80258e773..17c674812 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = src/lib example
+SUBDIRS = src/lib example tests
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libndpi.pc
diff --git a/README.md b/README.md
index 0542ff474..b1feb5a98 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
![ntop][ntopng_logo] ![ntop][ntop_logo]
# nDPI
-[![Build Status](https://travis-ci.org/ntop/nDPI.png?branch=master)](https://travis-ci.org/ntop/nDPI)
+[![Build Status](https://travis-ci.org/ntop/nDPI.png?branch=dev)](https://travis-ci.org/ntop/nDPI)
## What is nDPI ?
@@ -15,6 +15,10 @@ In order to compile this library do
- ./configure
- make
+To run tests do additionally:
+
+- make check
+
Please note that the pre-requisites for compilation include:
- GNU tools (autogen, automake, autoconf, libtool)
- GNU C compiler (gcc)
@@ -23,7 +27,7 @@ Please note that the pre-requisites for compilation include:
The entire procedure of adding new protocols in detail:
-1. Add new protocol together with its unique ID to: src/include/ndpi_protocols_osdpi.h
+1. Add new protocol together with its unique ID to: src/include/ndpi_protocol_ids.h
2. Create a new protocol in: src/lib/protocols/
3. Variables to be kept for the duration of the entire flow (as state variables) needs to be placed in: /include/ndpi_structs.h in ndpi_flow_tcp_struct (for TCP only), ndpi_flow_udp_struct (for UDP only), or ndpi_flow_struct (for both).
4. Add a new entry for the search function for the new protocol in: src/include/ndpi_protocols.h
@@ -34,6 +38,7 @@ The entire procedure of adding new protocols in detail:
9. ./autogen.sh
10. ./configure
11. make
+12. make check
### Creating A Source File Tar Ball
@@ -41,6 +46,10 @@ If you want to distribute a source tar file of nDPI do:
- make dist
+To ensure that a tar file includes all necessary files and to run tests on distribution do:
+
+- make distcheck
+
[ntopng_logo]: https://camo.githubusercontent.com/0f789abcef232035c05e0d2e82afa3cc3be46485/687474703a2f2f7777772e6e746f702e6f72672f77702d636f6e74656e742f75706c6f6164732f323031312f30382f6e746f706e672d69636f6e2d313530783135302e706e67
[ntop_logo]: https://camo.githubusercontent.com/58e2a1ecfff62d8ecc9d74633bd1013f26e06cba/687474703a2f2f7777772e6e746f702e6f72672f77702d636f6e74656e742f75706c6f6164732f323031352f30352f6e746f702e706e67
diff --git a/README.protocols b/README.protocols
index 27d8c6408..1c77df15b 100644
--- a/README.protocols
+++ b/README.protocols
@@ -8,7 +8,7 @@ TCP 172.16.253.130:2021 <-> 75.147.140.249:443 [VLAN: 0][proto: 91/SSL][28 pkts/
TCP 172.16.253.130:2077 <-> 77.247.181.163:443 [VLAN: 0][proto: 91/SSL][136 pkts/94329 bytes][SSL client: www.fk4pprq42hsvl2wey.com]
It can be detected by analyzing the SSL client certificate and checking the name that does not match to a real host in
-addition of begin a bit weird. As doing DNS resolution is not a task for nDPI we let applications do and then recognize
+addition of being a bit weird. As doing DNS resolution is not a task for nDPI we let applications do and then recognize
SSL-tunnelled connections.
See http://www.netresec.com/?page=Blog&month=2013-04&post=Detecting-TOR-Communication-in-Network-Traffic
diff --git a/configure.ac b/configure.ac
index e65baea81..70e3f1888 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([libndpi], [1.7.1])
+AC_INIT([libndpi], [1.8.0])
AC_CONFIG_MACRO_DIR([m4])
@@ -87,7 +87,7 @@ LIBS=$OLD_LIBS
AC_CHECK_LIB(pthread, pthread_setaffinity_np, AC_DEFINE_UNQUOTED(HAVE_PTHREAD_SETAFFINITY_NP, 1, [libc has pthread_setaffinity_np]))
-AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile libndpi.pc])
+AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile tests/Makefile libndpi.pc])
AC_CONFIG_HEADERS(config.h)
AC_SUBST(GIT_RELEASE)
AC_SUBST(SVN_DATE)
diff --git a/example/Makefile.am b/example/Makefile.am
index f98bae9ae..a55212c92 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -6,7 +6,7 @@ AM_CFLAGS = @PTHREAD_CFLAGS@
LDADD = $(top_builddir)/src/lib/libndpi.la @JSON_C_LIB@ @PTHREAD_LIBS@ @PCAP_LIB@
AM_LDFLAGS = -static
-ndpiReader_SOURCES = ndpiReader.c
+ndpiReader_SOURCES = ndpiReader.c ndpi_util.c ndpi_util.h
ndpiReader.o: ndpiReader.c
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 52fac6a65..deb61b681 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -1,9 +1,7 @@
/*
* ndpiReader.c
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-2011 by ipoque GmbH
- * Copyright (C) 2014 - Matteo Bogo <matteo.bogo@gmail.com> (JSON support)
+ * Copyright (C) 2011-16 - ntop.org
*
* nDPI is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -43,7 +41,7 @@
#include <signal.h>
#include <pthread.h>
#include <sys/socket.h>
-
+#include <assert.h>
#include "../config.h"
#include "ndpi_api.h"
@@ -51,51 +49,9 @@
#include <json.h>
#endif
-#define MAX_NUM_READER_THREADS 16
-#define IDLE_SCAN_PERIOD 10 /* msec (use detection_tick_resolution = 1000) */
-#define MAX_IDLE_TIME 30000
-#define IDLE_SCAN_BUDGET 1024
-#define NUM_ROOTS 512
-#define GTP_U_V1_PORT 2152
-#define TZSP_PORT 37008
-#define MAX_NDPI_FLOWS 200000000
-
-#ifndef ETH_P_IP
-#define ETH_P_IP 0x0800 /* IPv4 */
-#endif
-
-#ifndef ETH_P_IPv6
-#define ETH_P_IPV6 0x86dd /* IPv6 */
-#endif
-
-#define SLARP 0x8035 /* Cisco Slarp */
-#define CISCO_D_PROTO 0x2000 /* Cisco Discovery Protocol */
-
-#define VLAN 0x8100
-#define MPLS_UNI 0x8847
-#define MPLS_MULTI 0x8848
-#define PPPoE 0x8864
-#define SNAP 0xaa
-
-/* mask for FCF */
-#define WIFI_DATA 0x2 /* 0000 0010 */
-#define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */
-#define FCF_SUBTYPE(fc) (((fc) >> 4) & 0xF) /* 0000 1111 = 0xF */
-#define FCF_TO_DS(fc) ((fc) & 0x0100)
-#define FCF_FROM_DS(fc) ((fc) & 0x0200)
-
-/* mask for Bad FCF presence */
-#define BAD_FCS 0x50 /* 0101 0000 */
-
-/**
- * @brief Set main components necessary to the detection
- * @details TODO
- */
-static void setupDetection(u_int16_t thread_id);
+#include "ndpi_util.h"
-/**
- * Client parameters
- */
+/** Client parameters **/
static char *_pcap_file[MAX_NUM_READER_THREADS]; /**< Ingress pcap file/interafaces */
static FILE *playlist_fp[MAX_NUM_READER_THREADS] = { NULL }; /**< Ingress playlist */
static FILE *results_file = NULL;
@@ -110,107 +66,59 @@ static json_object *jArray_known_flows, *jArray_unknown_flows;
#endif
static u_int8_t live_capture = 0;
static u_int8_t undetected_flows_deleted = 0;
-/**
- * User preferences
- */
+/** User preferences **/
static u_int8_t enable_protocol_guess = 1, verbose = 0, nDPI_traceLevel = 0, json_flag = 0;
static u_int16_t decode_tunnels = 0;
static u_int16_t num_loops = 1;
static u_int8_t shutdown_app = 0, quiet_mode = 0;
static u_int8_t num_threads = 1;
-static u_int32_t current_ndpi_memory = 0, max_ndpi_memory = 0;
#ifdef linux
static int core_affinity[MAX_NUM_READER_THREADS];
#endif
-
static struct timeval pcap_start, pcap_end;
-
-/**
- * Detection parameters
- */
-static u_int32_t detection_tick_resolution = 1000;
+/** Detection parameters **/
static time_t capture_for = 0;
static time_t capture_until = 0;
-
static u_int32_t num_flows;
-struct thread_stats {
- u_int32_t guessed_flow_protocols;
- u_int64_t raw_packet_count;
- u_int64_t ip_packet_count;
- u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes;
- u_int64_t protocol_counter[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1];
- u_int64_t protocol_counter_bytes[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1];
- u_int32_t protocol_flows[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1];
- u_int32_t ndpi_flow_count;
- u_int64_t tcp_count, udp_count;
- u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count;
- u_int64_t packet_len[6];
- u_int16_t max_packet_len;
-};
-
+// struct associated to a workflow for a thread
struct reader_thread {
- struct ndpi_detection_module_struct *ndpi_struct;
- void *ndpi_flows_root[NUM_ROOTS];
- char _pcap_error_buffer[PCAP_ERRBUF_SIZE];
- pcap_t *_pcap_handle;
- u_int64_t last_time;
+ struct ndpi_workflow * workflow;
+ pthread_t pthread;
u_int64_t last_idle_scan_time;
u_int32_t idle_scan_idx;
u_int32_t num_idle_flows;
- pthread_t pthread;
- int _pcap_datalink_type;
-
- /* TODO Add barrier */
- struct thread_stats stats;
-
- struct ndpi_flow *idle_flows[IDLE_SCAN_BUDGET];
+ struct ndpi_flow_info *idle_flows[IDLE_SCAN_BUDGET];
};
+// array for every thread created for a flow
static struct reader_thread ndpi_thread_info[MAX_NUM_READER_THREADS];
-/**
- * @brief ID tracking
- */
+// ID tracking
typedef struct ndpi_id {
- u_int8_t ip[4]; // Ip address
- struct ndpi_id_struct *ndpi_id; // nDpi worker structure
+ u_int8_t ip[4]; // Ip address
+ struct ndpi_id_struct *ndpi_id; // nDpi worker structure
} ndpi_id_t;
-static u_int32_t size_id_struct = 0; // ID tracking structure size
-
-// flow tracking
-typedef struct ndpi_flow {
- u_int32_t lower_ip;
- u_int32_t upper_ip;
- u_int16_t lower_port;
- u_int16_t upper_port;
- u_int8_t detection_completed, protocol;
- u_int16_t vlan_id;
- struct ndpi_flow_struct *ndpi_flow;
- char lower_name[48], upper_name[48];
- u_int8_t ip_version;
- u_int64_t last_seen;
- u_int64_t bytes;
- u_int32_t packets;
+// used memory counters
+u_int32_t current_ndpi_memory = 0, max_ndpi_memory = 0;
- // result only, not used for flow identification
- ndpi_protocol detected_protocol;
- char host_server_name[192];
- char bittorent_hash[41];
+/********************** FUNCTIONS ********************* */
- struct {
- char client_certificate[48], server_certificate[48];
- } ssl;
-
- void *src_id, *dst_id;
-} ndpi_flow_t;
+/**
+ * @brief Set main components necessary to the detection
+ */
+static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle);
-static u_int32_t size_flow_struct = 0;
+/**
+ * @brief Print help instructions
+ */
static void help(u_int long_help) {
+ printf("Welcome to nDPI %s\n\n", ndpi_revision());
+
printf("ndpiReader -i <file|device> [-f <filter>][-s <duration>]\n"
" [-p <protos>][-l <loops> [-q][-d][-h][-t][-v <level>]\n"
" [-n <threads>] [-w <file>] [-j <file>]\n\n"
@@ -237,16 +145,18 @@ static void help(u_int long_help) {
if(long_help) {
printf("\n\nSupported protocols:\n");
num_threads = 1;
- setupDetection(0);
- ndpi_dump_protocols(ndpi_thread_info[0].ndpi_struct);
+ setupDetection(0, NULL);
+ ndpi_dump_protocols(ndpi_thread_info[0].workflow->ndpi_struct);
}
-
exit(!long_help);
}
-/* ***************************************************** */
+/**
+ * @brief Option parser
+ */
static void parseOptions(int argc, char **argv) {
+
char *__pcap_file = NULL, *bind_mask = NULL;
int thread_id, opt;
#ifdef linux
@@ -342,7 +252,7 @@ static void parseOptions(int argc, char **argv) {
}
if(strchr(_pcap_file[0], ',')) { /* multiple ingress interfaces */
- num_threads = 0; /* setting number of threads = number of interfaces */
+ num_threads = 0; /* setting number of threads = number of interfaces */
__pcap_file = strtok(_pcap_file[0], ",");
while (__pcap_file != NULL && num_threads < MAX_NUM_READER_THREADS) {
_pcap_file[num_threads++] = __pcap_file;
@@ -369,63 +279,12 @@ static void parseOptions(int argc, char **argv) {
#endif
}
-/* ***************************************************** */
-
-static void debug_printf(u_int32_t protocol, void *id_struct,
- ndpi_log_level_t log_level,
- const char *format, ...) {
- va_list va_ap;
-#ifndef WIN32
- struct tm result;
-#endif
-
- if(log_level <= nDPI_traceLevel) {
- char buf[8192], out_buf[8192];
- char theDate[32];
- const char *extra_msg = "";
- time_t theTime = time(NULL);
-
- va_start (va_ap, format);
-
- if(log_level == NDPI_LOG_ERROR)
- extra_msg = "ERROR: ";
- else if(log_level == NDPI_LOG_TRACE)
- extra_msg = "TRACE: ";
- else
- extra_msg = "DEBUG: ";
-
- memset(buf, 0, sizeof(buf));
- strftime(theDate, 32, "%d/%b/%Y %H:%M:%S", localtime_r(&theTime,&result) );
- vsnprintf(buf, sizeof(buf)-1, format, va_ap);
-
- snprintf(out_buf, sizeof(out_buf), "%s %s%s", theDate, extra_msg, buf);
- printf("%s", out_buf);
- fflush(stdout);
- }
-
- va_end(va_ap);
-}
-
-/* ***************************************************** */
-
-static void *malloc_wrapper(size_t size) {
- current_ndpi_memory += size;
-
- if(current_ndpi_memory > max_ndpi_memory)
- max_ndpi_memory = current_ndpi_memory;
-
- return malloc(size);
-}
-
-/* ***************************************************** */
-
-static void free_wrapper(void *freeable) {
- free(freeable);
-}
-
-/* ***************************************************** */
+/**
+ * @brief From IPPROTO to string NAME
+ */
static char* ipProto2Name(u_short proto_id) {
+
static char proto[8];
switch(proto_id) {
@@ -453,12 +312,12 @@ static char* ipProto2Name(u_short proto_id) {
return(proto);
}
-/* ***************************************************** */
-/*
- * A faster replacement for inet_ntoa().
+/**
+ * @brief A faster replacement for inet_ntoa().
*/
char* intoaV4(unsigned int addr, char* buf, u_short bufLen) {
+
char *cp, *retStr;
uint byte;
int n;
@@ -487,9 +346,10 @@ char* intoaV4(unsigned int addr, char* buf, u_short bufLen) {
return(retStr);
}
-/* ***************************************************** */
-
-static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
+/**
+ * @brief Print the flow
+ */
+static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) {
#ifdef HAVE_JSON_C
json_object *jObj;
#endif
@@ -501,11 +361,11 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
fprintf(out, "\t%s %s%s%s:%u <-> %s%s%s:%u ",
ipProto2Name(flow->protocol),
(flow->ip_version == 6) ? "[" : "",
- flow->lower_name,
+ flow->lower_name,
(flow->ip_version == 6) ? "]" : "",
ntohs(flow->lower_port),
(flow->ip_version == 6) ? "[" : "",
- flow->upper_name,
+ flow->upper_name,
(flow->ip_version == 6) ? "]" : "",
ntohs(flow->upper_port));
@@ -516,12 +376,12 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
fprintf(out, "[proto: %u.%u/%s]",
flow->detected_protocol.master_protocol, flow->detected_protocol.protocol,
- ndpi_protocol2name(ndpi_thread_info[thread_id].ndpi_struct,
+ ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct,
flow->detected_protocol, buf, sizeof(buf)));
} else
fprintf(out, "[proto: %u/%s]",
flow->detected_protocol.protocol,
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol));
+ ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.protocol));
fprintf(out, "[%u pkts/%llu bytes]",
flow->packets, (long long unsigned int)flow->bytes);
@@ -551,14 +411,14 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
char tmp[256];
snprintf(tmp, sizeof(tmp), "%s.%s",
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.master_protocol),
- ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol));
+ ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.master_protocol),
+ ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.protocol));
json_object_object_add(jObj,"detected.protocol.name",
json_object_new_string(tmp));
} else
json_object_object_add(jObj,"detected.protocol.name",
- json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct,
+ json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct,
flow->detected_protocol.protocol)));
json_object_object_add(jObj,"packets",json_object_new_int(flow->packets));
@@ -579,7 +439,6 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
json_object_object_add(jObj, "ssl", sjObj);
}
- //flow->protos.ssl.client_certificate, flow->protos.ssl.server_certificate);
if(json_flag == 1)
json_object_array_add(jArray_known_flows,jObj);
else if(json_flag == 2)
@@ -588,28 +447,13 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) {
}
}
-/* ***************************************************** */
-
-static void free_ndpi_flow(struct ndpi_flow *flow) {
- if(flow->ndpi_flow) { ndpi_free_flow(flow->ndpi_flow); flow->ndpi_flow = NULL; }
- if(flow->src_id) { ndpi_free(flow->src_id); flow->src_id = NULL; }
- if(flow->dst_id) { ndpi_free(flow->dst_id); flow->dst_id = NULL; }
-
-}
-
-/* ***************************************************** */
-
-static void ndpi_flow_freer(void *node) {
- struct ndpi_flow *flow = (struct ndpi_flow*)node;
-
- free_ndpi_flow(flow);
- ndpi_free(flow);
-}
-
-/* ***************************************************** */
+/**
+ * @brief Unknown Proto Walker
+ */
static void node_print_unknown_proto_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) {
- struct ndpi_flow *flow = *(struct ndpi_flow**)node;
+
+ struct ndpi_flow_info *flow = *(struct ndpi_flow_info**)node;
u_int16_t thread_id = *((u_int16_t*)user_data);
if(flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN) return;
@@ -618,10 +462,12 @@ static void node_print_unknown_proto_walker(const void *node, ndpi_VISIT which,
printFlow(thread_id, flow);
}
-/* ***************************************************** */
-
+/**
+ * @brief Known Proto Walker
+ */
static void node_print_known_proto_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) {
- struct ndpi_flow *flow = *(struct ndpi_flow**)node;
+
+ struct ndpi_flow_info *flow = *(struct ndpi_flow_info**)node;
u_int16_t thread_id = *((u_int16_t*)user_data);
if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) return;
@@ -630,10 +476,13 @@ static void node_print_known_proto_walker(const void *node, ndpi_VISIT which, in
printFlow(thread_id, flow);
}
-/* ***************************************************** */
-static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi_flow *flow) {
- flow->detected_protocol = ndpi_guess_undetected_protocol(ndpi_thread_info[thread_id].ndpi_struct,
+/**
+ * @brief Guess Undetected Protocol
+ */
+static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi_flow_info *flow) {
+
+ flow->detected_protocol = ndpi_guess_undetected_protocol(ndpi_thread_info[thread_id].workflow->ndpi_struct,
flow->protocol,
ntohl(flow->lower_ip),
ntohs(flow->lower_port),
@@ -641,20 +490,23 @@ static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi
ntohs(flow->upper_port));
// printf("Guess state: %u\n", flow->detected_protocol);
if(flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN)
- ndpi_thread_info[thread_id].stats.guessed_flow_protocols++;
+ ndpi_thread_info[thread_id].workflow->stats.guessed_flow_protocols++;
return(flow->detected_protocol.protocol);
}
-/* ***************************************************** */
+/**
+ * @brief Proto Guess Walker
+ */
static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) {
- struct ndpi_flow *flow = *(struct ndpi_flow **) node;
+
+ struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node;
u_int16_t thread_id = *((u_int16_t *) user_data);
if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */
if((!flow->detection_completed) && flow->ndpi_flow)
- flow->detected_protocol = ndpi_detection_giveup(ndpi_thread_info[0].ndpi_struct, flow->ndpi_flow);
+ flow->detected_protocol = ndpi_detection_giveup(ndpi_thread_info[0].workflow->ndpi_struct, flow->ndpi_flow);
if(enable_protocol_guess) {
if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) {
@@ -663,23 +515,26 @@ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int dept
}
}
- ndpi_thread_info[thread_id].stats.protocol_counter[flow->detected_protocol.protocol] += flow->packets;
- ndpi_thread_info[thread_id].stats.protocol_counter_bytes[flow->detected_protocol.protocol] += flow->bytes;
- ndpi_thread_info[thread_id].stats.protocol_flows[flow->detected_protocol.protocol]++;
+ ndpi_thread_info[thread_id].workflow->stats.protocol_counter[flow->detected_protocol.protocol] += flow->packets;
+ ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes[flow->detected_protocol.protocol] += flow->bytes;
+ ndpi_thread_info[thread_id].workflow->stats.protocol_flows[flow->detected_protocol.protocol]++;
}
}
-/* ***************************************************** */
+/**
+ * @brief Idle Scan Walker
+ */
static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) {
- struct ndpi_flow *flow = *(struct ndpi_flow **) node;
+
+ struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node;
u_int16_t thread_id = *((u_int16_t *) user_data);
if(ndpi_thread_info[thread_id].num_idle_flows == IDLE_SCAN_BUDGET) /* TODO optimise with a budget-based walk */
return;
if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */
- if(flow->last_seen + MAX_IDLE_TIME < ndpi_thread_info[thread_id].last_time) {
+ if(flow->last_seen + MAX_IDLE_TIME < ndpi_thread_info[thread_id].workflow->last_time) {
/* update stats */
node_proto_guess_walker(node, which, depth, user_data);
@@ -687,8 +542,8 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth,
if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && !undetected_flows_deleted)
undetected_flows_deleted = 1;
- free_ndpi_flow(flow);
- ndpi_thread_info[thread_id].stats.ndpi_flow_count--;
+ ndpi_free_flow_info_half(flow);
+ ndpi_thread_info[thread_id].workflow->stats.ndpi_flow_count--;
/* adding to a queue (we can't delete it from the tree inline ) */
ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows++] = flow;
@@ -696,441 +551,121 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth,
}
}
-/* ***************************************************** */
-
-static int node_cmp(const void *a, const void *b) {
- struct ndpi_flow *fa = (struct ndpi_flow*)a;
- struct ndpi_flow *fb = (struct ndpi_flow*)b;
-
- if(fa->vlan_id < fb->vlan_id ) return(-1); else { if(fa->vlan_id > fb->vlan_id ) return(1); }
- if(fa->lower_ip < fb->lower_ip ) return(-1); else { if(fa->lower_ip > fb->lower_ip ) return(1); }
- if(fa->lower_port < fb->lower_port) return(-1); else { if(fa->lower_port > fb->lower_port) return(1); }
- if(fa->upper_ip < fb->upper_ip ) return(-1); else { if(fa->upper_ip > fb->upper_ip ) return(1); }
- if(fa->upper_port < fb->upper_port) return(-1); else { if(fa->upper_port > fb->upper_port) return(1); }
- if(fa->protocol < fb->protocol ) return(-1); else { if(fa->protocol > fb->protocol ) return(1); }
-
- return(0);
-}
-
-/* ***************************************************** */
-
-static struct ndpi_flow *get_ndpi_flow(u_int16_t thread_id,
- const u_int8_t version,
- u_int16_t vlan_id,
- const struct ndpi_iphdr *iph,
- const struct ndpi_ipv6hdr *iph6,
- u_int16_t ip_offset,
- u_int16_t ipsize,
- u_int16_t l4_packet_len,
- struct ndpi_tcphdr **tcph,
- struct ndpi_udphdr **udph,
- u_int16_t *sport, u_int16_t *dport,
- struct ndpi_id_struct **src,
- struct ndpi_id_struct **dst,
- u_int8_t *proto,
- u_int8_t **payload,
- u_int16_t *payload_len,
- u_int8_t *src_to_dst_direction) {
- u_int32_t idx, l4_offset;
- u_int32_t lower_ip;
- u_int32_t upper_ip;
- u_int16_t lower_port;
- u_int16_t upper_port;
- struct ndpi_flow flow;
- void *ret;
- u_int8_t *l3, *l4;
-
- /*
- Note: to keep things simple (ndpiReader is just a demo app)
- we handle IPv6 a-la-IPv4.
- */
- if(version == 4) {
- if(ipsize < 20)
- return NULL;
-
- if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len)
- || (iph->frag_off & htons(0x1FFF)) != 0)
- return NULL;
-
- l4_offset = iph->ihl * 4;
- l3 = (u_int8_t*)iph;
- } else {
- l4_offset = sizeof(struct ndpi_ipv6hdr);
- l3 = (u_int8_t*)iph6;
- }
-
- if(l4_packet_len < 64)
- ndpi_thread_info[thread_id].stats.packet_len[0]++;
- else if(l4_packet_len >= 64 && l4_packet_len < 128)
- ndpi_thread_info[thread_id].stats.packet_len[1]++;
- else if(l4_packet_len >= 128 && l4_packet_len < 256)
- ndpi_thread_info[thread_id].stats.packet_len[2]++;
- else if(l4_packet_len >= 256 && l4_packet_len < 1024)
- ndpi_thread_info[thread_id].stats.packet_len[3]++;
- else if(l4_packet_len >= 1024 && l4_packet_len < 1500)
- ndpi_thread_info[thread_id].stats.packet_len[4]++;
- else if(l4_packet_len >= 1500)
- ndpi_thread_info[thread_id].stats.packet_len[5]++;
-
- if(l4_packet_len > ndpi_thread_info[thread_id].stats.max_packet_len)
- ndpi_thread_info[thread_id].stats.max_packet_len = l4_packet_len;
-
- if(iph->saddr < iph->daddr) {
- lower_ip = iph->saddr;
- upper_ip = iph->daddr;
- } else {
- lower_ip = iph->daddr;
- upper_ip = iph->saddr;
- }
-
- *proto = iph->protocol;
- l4 = ((u_int8_t *) l3 + l4_offset);
- if(iph->protocol == 6 && l4_packet_len >= 20) {
- u_int tcp_len;
-
- ndpi_thread_info[thread_id].stats.tcp_count++;
-
- // tcp
- *tcph = (struct ndpi_tcphdr *)l4;
- *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest);
-
- if(iph->saddr < iph->daddr) {
- lower_port = (*tcph)->source, upper_port = (*tcph)->dest;
- *src_to_dst_direction = 1;
- } else {
- lower_port = (*tcph)->dest;
- upper_port = (*tcph)->source;
-
- *src_to_dst_direction = 0;
- if(iph->saddr == iph->daddr) {
- if(lower_port > upper_port) {
- u_int16_t p = lower_port;
+/**
+ * @brief On Protocol Discover - call node_guess_undetected_protocol() for protocol
+ */
+static void on_protocol_discovered(struct ndpi_workflow * workflow,
+ struct ndpi_flow_info * flow,
+ void * udata) {
+
+ const u_int16_t thread_id = (uintptr_t) udata;
- lower_port = upper_port;
- upper_port = p;
- }
+ if(verbose > 1){
+ if(enable_protocol_guess) {
+ if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) {
+ flow->detected_protocol.protocol = node_guess_undetected_protocol(thread_id, flow),
+ flow->detected_protocol.master_protocol = NDPI_PROTOCOL_UNKNOWN;
}
}
- tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len);
- *payload = &l4[tcp_len];
- *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff);
- } else if(iph->protocol == 17 && l4_packet_len >= 8) {
- // udp
- ndpi_thread_info[thread_id].stats.udp_count++;
-
- *udph = (struct ndpi_udphdr *)l4;
- *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest);
- *payload = &l4[sizeof(struct ndpi_udphdr)];
- *payload_len = ndpi_max(0, l4_packet_len-sizeof(struct ndpi_udphdr));
-
- if(iph->saddr < iph->daddr) {
- lower_port = (*udph)->source, upper_port = (*udph)->dest;
- *src_to_dst_direction = 1;
- } else {
- lower_port = (*udph)->dest, upper_port = (*udph)->source;
-
- *src_to_dst_direction = 0;
-
- if(iph->saddr == iph->daddr) {
- if(lower_port > upper_port) {
- u_int16_t p = lower_port;
-
- lower_port = upper_port;
- upper_port = p;
- }
- }
- }
-
- *sport = ntohs(lower_port), *dport = ntohs(upper_port);
- } else {
- // non tcp/udp protocols
- lower_port = 0;
- upper_port = 0;
+ printFlow(thread_id, flow);
}
+}
- flow.protocol = iph->protocol, flow.vlan_id = vlan_id;
- flow.lower_ip = lower_ip, flow.upper_ip = upper_ip;
- flow.lower_port = lower_port, flow.upper_port = upper_port;
-
- if(0)
- printf("[NDPI] [%u][%u:%u <-> %u:%u]\n",
- iph->protocol, lower_ip, ntohs(lower_port), upper_ip, ntohs(upper_port));
-
- idx = (vlan_id + lower_ip + upper_ip + iph->protocol + lower_port + upper_port) % NUM_ROOTS;
- ret = ndpi_tfind(&flow, &ndpi_thread_info[thread_id].ndpi_flows_root[idx], node_cmp);
-
- if(ret == NULL) {
- if(ndpi_thread_info[thread_id].stats.ndpi_flow_count == MAX_NDPI_FLOWS) {
- printf("ERROR: maximum flow count (%u) has been exceeded\n", MAX_NDPI_FLOWS);
- exit(-1);
- } else {
- struct ndpi_flow *newflow = (struct ndpi_flow*)malloc(sizeof(struct ndpi_flow));
-
- if(newflow == NULL) {
- printf("[NDPI] %s(1): not enough memory\n", __FUNCTION__);
- return(NULL);
- }
-
- memset(newflow, 0, sizeof(struct ndpi_flow));
- newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id;
- newflow->lower_ip = lower_ip, newflow->upper_ip = upper_ip;
- newflow->lower_port = lower_port, newflow->upper_port = upper_port;
- newflow->ip_version = version;
-
- if(version == 4) {
- inet_ntop(AF_INET, &lower_ip, newflow->lower_name, sizeof(newflow->lower_name));
- inet_ntop(AF_INET, &upper_ip, newflow->upper_name, sizeof(newflow->upper_name));
- } else {
- inet_ntop(AF_INET6, &iph6->ip6_src, newflow->lower_name, sizeof(newflow->lower_name));
- inet_ntop(AF_INET6, &iph6->ip6_dst, newflow->upper_name, sizeof(newflow->upper_name));
- }
-
- if((newflow->ndpi_flow = malloc_wrapper(size_flow_struct)) == NULL) {
- printf("[NDPI] %s(2): not enough memory\n", __FUNCTION__);
- free(newflow);
- return(NULL);
- } else
- memset(newflow->ndpi_flow, 0, size_flow_struct);
-
- if((newflow->src_id = malloc_wrapper(size_id_struct)) == NULL) {
- printf("[NDPI] %s(3): not enough memory\n", __FUNCTION__);
- free(newflow);
- return(NULL);
- } else
- memset(newflow->src_id, 0, size_id_struct);
- if((newflow->dst_id = malloc_wrapper(size_id_struct)) == NULL) {
- printf("[NDPI] %s(4): not enough memory\n", __FUNCTION__);
- free(newflow);
- return(NULL);
- } else
- memset(newflow->dst_id, 0, size_id_struct);
+/**
+ * @brief Print debug
+ */
+static void debug_printf(u_int32_t protocol, void *id_struct,
+ ndpi_log_level_t log_level,
+ const char *format, ...) {
- ndpi_tsearch(newflow, &ndpi_thread_info[thread_id].ndpi_flows_root[idx], node_cmp); /* Add */
- ndpi_thread_info[thread_id].stats.ndpi_flow_count++;
+ va_list va_ap;
+#ifndef WIN32
+ struct tm result;
+#endif
- *src = newflow->src_id, *dst = newflow->dst_id;
+ if(log_level <= nDPI_traceLevel) {
+ char buf[8192], out_buf[8192];
+ char theDate[32];
+ const char *extra_msg = "";
+ time_t theTime = time(NULL);
- // printFlow(thread_id, newflow);
- return newflow;
- }
- } else {
- struct ndpi_flow *flow = *(struct ndpi_flow**)ret;
+ va_start (va_ap, format);
- if(flow->lower_ip == lower_ip && flow->upper_ip == upper_ip
- && flow->lower_port == lower_port && flow->upper_port == upper_port)
- *src = flow->src_id, *dst = flow->dst_id;
+ if(log_level == NDPI_LOG_ERROR)
+ extra_msg = "ERROR: ";
+ else if(log_level == NDPI_LOG_TRACE)
+ extra_msg = "TRACE: ";
else
- *src = flow->dst_id, *dst = flow->src_id;
+ extra_msg = "DEBUG: ";
- return flow;
- }
-}
+ memset(buf, 0, sizeof(buf));
+ strftime(theDate, 32, "%d/%b/%Y %H:%M:%S", localtime_r(&theTime,&result) );
+ vsnprintf(buf, sizeof(buf)-1, format, va_ap);
-/* ***************************************************** */
-
-static struct ndpi_flow *get_ndpi_flow6(u_int16_t thread_id,
- u_int16_t vlan_id,
- const struct ndpi_ipv6hdr *iph6,
- u_int16_t ip_offset,
- struct ndpi_tcphdr **tcph,
- struct ndpi_udphdr **udph,
- u_int16_t *sport, u_int16_t *dport,
- struct ndpi_id_struct **src,
- struct ndpi_id_struct **dst,
- u_int8_t *proto,
- u_int8_t **payload,
- u_int16_t *payload_len,
- u_int8_t *src_to_dst_direction) {
- struct ndpi_iphdr iph;
-
- memset(&iph, 0, sizeof(iph));
- iph.version = 4;
- iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3];
- iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3];
- iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
-
- if(iph.protocol == 0x3C /* IPv6 destination option */) {
- u_int8_t *options = (u_int8_t*)iph6 + sizeof(const struct ndpi_ipv6hdr);
-
- iph.protocol = options[0];
+ snprintf(out_buf, sizeof(out_buf), "%s %s%s", theDate, extra_msg, buf);
+ printf("%s", out_buf);
+ fflush(stdout);
}
-
- return(get_ndpi_flow(thread_id, 6, vlan_id, &iph, iph6, ip_offset,
- sizeof(struct ndpi_ipv6hdr),
- ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen),
- tcph, udph, sport, dport,
- src, dst, proto, payload, payload_len, src_to_dst_direction));
+
+ va_end(va_ap);
}
-/* ***************************************************** */
-static void setupDetection(u_int16_t thread_id) {
+/**
+ * @brief Setup for detection begin
+ */
+static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
+
NDPI_PROTOCOL_BITMASK all;
+ struct ndpi_workflow_prefs prefs;
+
+ memset(&prefs, 0, sizeof(prefs));
+ prefs.decode_tunnels = decode_tunnels;
+ prefs.num_roots = NUM_ROOTS;
+ prefs.max_ndpi_flows = MAX_NDPI_FLOWS;
+ prefs.quiet_mode = quiet_mode;
memset(&ndpi_thread_info[thread_id], 0, sizeof(ndpi_thread_info[thread_id]));
+ ndpi_thread_info[thread_id].workflow = ndpi_workflow_init(&prefs, pcap_handle);
- // init global detection structure
- ndpi_thread_info[thread_id].ndpi_struct = ndpi_init_detection_module(detection_tick_resolution,
- malloc_wrapper, free_wrapper, debug_printf);
- if(ndpi_thread_info[thread_id].ndpi_struct == NULL) {
- printf("ERROR: global structure initialization failed\n");
- exit(-1);
- }
+ /* Preferences */
+ ndpi_thread_info[thread_id].workflow->ndpi_struct->http_dont_dissect_response = 0;
+ ndpi_thread_info[thread_id].workflow->ndpi_struct->dns_dissect_response = 0;
- /* ndpi_thread_info[thread_id].ndpi_struct->http_dont_dissect_response = 1; */
+ ndpi_workflow_set_flow_detected_callback(ndpi_thread_info[thread_id].workflow,
+ on_protocol_discovered, (void *)(uintptr_t)thread_id);
// enable all protocols
NDPI_BITMASK_SET_ALL(all);
- ndpi_set_protocol_detection_bitmask2(ndpi_thread_info[thread_id].ndpi_struct, &all);
-
- // allocate memory for id and flow tracking
- size_id_struct = sizeof(struct ndpi_id_struct);
- size_flow_struct = sizeof(struct ndpi_flow_struct);
+ ndpi_set_protocol_detection_bitmask2(ndpi_thread_info[thread_id].workflow->ndpi_struct, &all);
// clear memory for results
- memset(ndpi_thread_info[thread_id].stats.protocol_counter, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter));
- memset(ndpi_thread_info[thread_id].stats.protocol_counter_bytes, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter_bytes));
- memset(ndpi_thread_info[thread_id].stats.protocol_flows, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_flows));
+ memset(ndpi_thread_info[thread_id].workflow->stats.protocol_counter, 0, sizeof(ndpi_thread_info[thread_id].workflow->stats.protocol_counter));
+ memset(ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes, 0, sizeof(ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes));
+ memset(ndpi_thread_info[thread_id].workflow->stats.protocol_flows, 0, sizeof(ndpi_thread_info[thread_id].workflow->stats.protocol_flows));
if(_protoFilePath != NULL)
- ndpi_load_protocols_file(ndpi_thread_info[thread_id].ndpi_struct, _protoFilePath);
+ ndpi_load_protocols_file(ndpi_thread_info[thread_id].workflow->ndpi_struct, _protoFilePath);
}
-/* ***************************************************** */
+/**
+ * @brief End of detection and free flow
+ */
static void terminateDetection(u_int16_t thread_id) {
- int i;
-
- for(i=0; i<NUM_ROOTS; i++) {
- ndpi_tdestroy(ndpi_thread_info[thread_id].ndpi_flows_root[i], ndpi_flow_freer);
- ndpi_thread_info[thread_id].ndpi_flows_root[i] = NULL;
- }
-
- ndpi_exit_detection_module(ndpi_thread_info[thread_id].ndpi_struct, free_wrapper);
-}
-
-/* ***************************************************** */
-
-// ipsize = header->len - ip_offset ; rawsize = header->len
-static unsigned int packet_processing(u_int16_t thread_id,
- const u_int64_t time,
- u_int16_t vlan_id,
- const struct ndpi_iphdr *iph,
- struct ndpi_ipv6hdr *iph6,
- u_int16_t ip_offset,
- u_int16_t ipsize, u_int16_t rawsize) {
- struct ndpi_id_struct *src, *dst;
- struct ndpi_flow *flow;
- struct ndpi_flow_struct *ndpi_flow = NULL;
- u_int8_t proto;
- struct ndpi_tcphdr *tcph = NULL;
- struct ndpi_udphdr *udph = NULL;
- u_int16_t sport, dport, payload_len;
- u_int8_t *payload;
- u_int8_t src_to_dst_direction= 1;
-
- if(iph)
- flow = get_ndpi_flow(thread_id, 4, vlan_id, iph, NULL,
- ip_offset, ipsize,
- ntohs(iph->tot_len) - (iph->ihl * 4),
- &tcph, &udph, &sport, &dport,
- &src, &dst, &proto,
- &payload, &payload_len, &src_to_dst_direction);
- else
- flow = get_ndpi_flow6(thread_id, vlan_id, iph6, ip_offset,
- &tcph, &udph, &sport, &dport,
- &src, &dst, &proto,
- &payload, &payload_len, &src_to_dst_direction);
-
- if(flow != NULL) {
- ndpi_thread_info[thread_id].stats.ip_packet_count++;
- ndpi_thread_info[thread_id].stats.total_wire_bytes += rawsize + 24 /* CRC etc */, ndpi_thread_info[thread_id].stats.total_ip_bytes += rawsize;
- ndpi_flow = flow->ndpi_flow;
- flow->packets++, flow->bytes += rawsize;
- flow->last_seen = time;
- } else {
- return(0);
- }
-
- if(flow->detection_completed) return(0);
-
- flow->detected_protocol = ndpi_detection_process_packet(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow,
- iph ? (uint8_t *)iph : (uint8_t *)iph6,
- ipsize, time, src, dst);
- if((flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN)
- || ((proto == IPPROTO_UDP) && (flow->packets > 8))
- || ((proto == IPPROTO_TCP) && (flow->packets > 10))) {
- flow->detection_completed = 1;
-
- if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && (ndpi_flow->num_stun_udp_pkts > 0))
- ndpi_set_detected_protocol(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow, NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN);
-
- snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name);
-
- if(flow->detected_protocol.protocol == NDPI_PROTOCOL_BITTORRENT) {
- int i, j, n = 0;
-
- for(i=0, j = 0; i<20; i++) {
- sprintf(&flow->bittorent_hash[j], "%02x", flow->ndpi_flow->bittorent_hash[i]);
- j += 2, n += flow->ndpi_flow->bittorent_hash[i];
- }
-
- if(n == 0) flow->bittorent_hash[0] = '\0';
- }
-
- if((proto == IPPROTO_TCP) && (flow->detected_protocol.protocol != NDPI_PROTOCOL_DNS)) {
- snprintf(flow->ssl.client_certificate, sizeof(flow->ssl.client_certificate), "%s", flow->ndpi_flow->protos.ssl.client_certificate);
- snprintf(flow->ssl.server_certificate, sizeof(flow->ssl.server_certificate), "%s", flow->ndpi_flow->protos.ssl.server_certificate);
- }
-
- if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN)
- flow->detected_protocol = ndpi_detection_giveup(ndpi_thread_info[thread_id].ndpi_struct, flow->ndpi_flow);
-
- free_ndpi_flow(flow);
-
- if(verbose > 1) {
- if(enable_protocol_guess) {
- if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) {
- flow->detected_protocol.protocol = node_guess_undetected_protocol(thread_id, flow),
- flow->detected_protocol.master_protocol = NDPI_PROTOCOL_UNKNOWN;
- }
- }
-
- printFlow(thread_id, flow);
- }
- }
-
- if(live_capture) {
- if(ndpi_thread_info[thread_id].last_idle_scan_time + IDLE_SCAN_PERIOD < ndpi_thread_info[thread_id].last_time) {
- /* scan for idle flows */
- ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_idle_scan_walker, &thread_id);
-
- /* remove idle flows (unfortunately we cannot do this inline) */
- while (ndpi_thread_info[thread_id].num_idle_flows > 0) {
-
- /* search and delete the idle flow from the "ndpi_flow_root" (see struct reader thread) - here flows are the node of a b-tree */
- ndpi_tdelete(ndpi_thread_info[thread_id].idle_flows[--ndpi_thread_info[thread_id].num_idle_flows], &ndpi_thread_info[thread_id].ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_cmp);
-
- /* free the memory associated to idle flow in "idle_flows" - (see struct reader thread)*/
- free_ndpi_flow(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]);
- ndpi_free(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]);
- }
-
- if(++ndpi_thread_info[thread_id].idle_scan_idx == NUM_ROOTS) ndpi_thread_info[thread_id].idle_scan_idx = 0;
- ndpi_thread_info[thread_id].last_idle_scan_time = ndpi_thread_info[thread_id].last_time;
- }
- }
-
- return 0;
+ ndpi_workflow_free(ndpi_thread_info[thread_id].workflow);
}
-/* ****************************************************** */
+/**
+ * @brief Traffic stats format
+ */
char* formatTraffic(float numBits, int bits, char *buf) {
+
char unit;
if(bits)
@@ -1161,9 +696,12 @@ char* formatTraffic(float numBits, int bits, char *buf) {
return(buf);
}
-/* ***************************************************** */
+/**
+ * @brief Packets stats format
+ */
char* formatPackets(float numPkts, char *buf) {
+
if(numPkts < 1000) {
snprintf(buf, 32, "%.2f", numPkts);
} else if(numPkts < 1000000) {
@@ -1176,8 +714,10 @@ char* formatPackets(float numPkts, char *buf) {
return(buf);
}
-/* ***************************************************** */
+/**
+ * @brief JSON function init
+ */
#ifdef HAVE_JSON_C
static void json_init() {
jArray_known_flows = json_object_new_array();
@@ -1185,9 +725,12 @@ static void json_init() {
}
#endif
-/* ***************************************************** */
+/**
+ * @brief Bytes stats format
+ */
char* formatBytes(u_int32_t howMuch, char *buf, u_int buf_len) {
+
char unit = 'B';
if(howMuch < 1024) {
@@ -1209,13 +752,16 @@ char* formatBytes(u_int32_t howMuch, char *buf, u_int buf_len) {
return(buf);
}
-/* ***************************************************** */
+/**
+ * @brief Print result
+ */
static void printResults(u_int64_t tot_usec) {
+
u_int32_t i;
u_int64_t total_flow_bytes = 0;
u_int avg_pkt_size = 0;
- struct thread_stats cumulative_stats;
+ struct ndpi_stats cumulative_stats;
int thread_id;
char buf[32];
#ifdef HAVE_JSON_C
@@ -1227,41 +773,43 @@ static void printResults(u_int64_t tot_usec) {
memset(&cumulative_stats, 0, sizeof(cumulative_stats));
for(thread_id = 0; thread_id < num_threads; thread_id++) {
- if(ndpi_thread_info[thread_id].stats.total_wire_bytes == 0) continue;
+ if((ndpi_thread_info[thread_id].workflow->stats.total_wire_bytes == 0)
+ && (ndpi_thread_info[thread_id].workflow->stats.raw_packet_count == 0))
+ continue;
for(i=0; i<NUM_ROOTS; i++)
- ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_proto_guess_walker, &thread_id);
+ ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], node_proto_guess_walker, &thread_id);
/* Stats aggregation */
- cumulative_stats.guessed_flow_protocols += ndpi_thread_info[thread_id].stats.guessed_flow_protocols;
- cumulative_stats.raw_packet_count += ndpi_thread_info[thread_id].stats.raw_packet_count;
- cumulative_stats.ip_packet_count += ndpi_thread_info[thread_id].stats.ip_packet_count;
- cumulative_stats.total_wire_bytes += ndpi_thread_info[thread_id].stats.total_wire_bytes;
- cumulative_stats.total_ip_bytes += ndpi_thread_info[thread_id].stats.total_ip_bytes;
- cumulative_stats.total_discarded_bytes += ndpi_thread_info[thread_id].stats.total_discarded_bytes;
-
- for(i = 0; i < ndpi_get_num_supported_protocols(ndpi_thread_info[0].ndpi_struct); i++) {
- cumulative_stats.protocol_counter[i] += ndpi_thread_info[thread_id].stats.protocol_counter[i];
- cumulative_stats.protocol_counter_bytes[i] += ndpi_thread_info[thread_id].stats.protocol_counter_bytes[i];
- cumulative_stats.protocol_flows[i] += ndpi_thread_info[thread_id].stats.protocol_flows[i];
+ cumulative_stats.guessed_flow_protocols += ndpi_thread_info[thread_id].workflow->stats.guessed_flow_protocols;
+ cumulative_stats.raw_packet_count += ndpi_thread_info[thread_id].workflow->stats.raw_packet_count;
+ cumulative_stats.ip_packet_count += ndpi_thread_info[thread_id].workflow->stats.ip_packet_count;
+ cumulative_stats.total_wire_bytes += ndpi_thread_info[thread_id].workflow->stats.total_wire_bytes;
+ cumulative_stats.total_ip_bytes += ndpi_thread_info[thread_id].workflow->stats.total_ip_bytes;
+ cumulative_stats.total_discarded_bytes += ndpi_thread_info[thread_id].workflow->stats.total_discarded_bytes;
+
+ for(i = 0; i < ndpi_get_num_supported_protocols(ndpi_thread_info[0].workflow->ndpi_struct); i++) {
+ cumulative_stats.protocol_counter[i] += ndpi_thread_info[thread_id].workflow->stats.protocol_counter[i];
+ cumulative_stats.protocol_counter_bytes[i] += ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes[i];
+ cumulative_stats.protocol_flows[i] += ndpi_thread_info[thread_id].workflow->stats.protocol_flows[i];
}
- cumulative_stats.ndpi_flow_count += ndpi_thread_info[thread_id].stats.ndpi_flow_count;
- cumulative_stats.tcp_count += ndpi_thread_info[thread_id].stats.tcp_count;
- cumulative_stats.udp_count += ndpi_thread_info[thread_id].stats.udp_count;
- cumulative_stats.mpls_count += ndpi_thread_info[thread_id].stats.mpls_count;
- cumulative_stats.pppoe_count += ndpi_thread_info[thread_id].stats.pppoe_count;
- cumulative_stats.vlan_count += ndpi_thread_info[thread_id].stats.vlan_count;
- cumulative_stats.fragmented_count += ndpi_thread_info[thread_id].stats.fragmented_count;
+ cumulative_stats.ndpi_flow_count += ndpi_thread_info[thread_id].workflow->stats.ndpi_flow_count;
+ cumulative_stats.tcp_count += ndpi_thread_info[thread_id].workflow->stats.tcp_count;
+ cumulative_stats.udp_count += ndpi_thread_info[thread_id].workflow->stats.udp_count;
+ cumulative_stats.mpls_count += ndpi_thread_info[thread_id].workflow->stats.mpls_count;
+ cumulative_stats.pppoe_count += ndpi_thread_info[thread_id].workflow->stats.pppoe_count;
+ cumulative_stats.vlan_count += ndpi_thread_info[thread_id].workflow->stats.vlan_count;
+ cumulative_stats.fragmented_count += ndpi_thread_info[thread_id].workflow->stats.fragmented_count;
for(i = 0; i < 6; i++)
- cumulative_stats.packet_len[i] += ndpi_thread_info[thread_id].stats.packet_len[i];
- cumulative_stats.max_packet_len += ndpi_thread_info[thread_id].stats.max_packet_len;
+ cumulative_stats.packet_len[i] += ndpi_thread_info[thread_id].workflow->stats.packet_len[i];
+ cumulative_stats.max_packet_len += ndpi_thread_info[thread_id].workflow->stats.max_packet_len;
}
if(!quiet_mode) {
printf("\nnDPI Memory statistics:\n");
printf("\tnDPI Memory (once): %-13s\n", formatBytes(sizeof(struct ndpi_detection_module_struct), buf, sizeof(buf)));
- printf("\tFlow Memory (per flow): %-13s\n", formatBytes(size_flow_struct, buf, sizeof(buf)));
+ printf("\tFlow Memory (per flow): %-13s\n", formatBytes(sizeof(struct ndpi_flow_struct), buf, sizeof(buf)));
printf("\tActual Memory: %-13s\n", formatBytes(current_ndpi_memory, buf, sizeof(buf)));
printf("\tPeak Memory: %-13s\n", formatBytes(max_ndpi_memory, buf, sizeof(buf)));
@@ -1350,17 +898,17 @@ static void printResults(u_int64_t tot_usec) {
}
#endif
}
-
+
if((!json_flag) && (!quiet_mode)) printf("\n\nDetected protocols:\n");
- for(i = 0; i <= ndpi_get_num_supported_protocols(ndpi_thread_info[0].ndpi_struct); i++) {
- ndpi_protocol_breed_t breed = ndpi_get_proto_breed(ndpi_thread_info[0].ndpi_struct, i);
+ for(i = 0; i <= ndpi_get_num_supported_protocols(ndpi_thread_info[0].workflow->ndpi_struct); i++) {
+ ndpi_protocol_breed_t breed = ndpi_get_proto_breed(ndpi_thread_info[0].workflow->ndpi_struct, i);
if(cumulative_stats.protocol_counter[i] > 0) {
breed_stats[breed] += (long long unsigned int)cumulative_stats.protocol_counter_bytes[i];
if(results_file)
fprintf(results_file, "%s\t%llu\t%llu\t%u\n",
- ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i),
+ ndpi_get_proto_name(ndpi_thread_info[0].workflow->ndpi_struct, i),
(long long unsigned int)cumulative_stats.protocol_counter[i],
(long long unsigned int)cumulative_stats.protocol_counter_bytes[i],
cumulative_stats.protocol_flows[i]);
@@ -1368,7 +916,7 @@ static void printResults(u_int64_t tot_usec) {
if((!json_flag) && (!quiet_mode)) {
printf("\t%-20s packets: %-13llu bytes: %-13llu "
"flows: %-13u\n",
- ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i),
+ ndpi_get_proto_name(ndpi_thread_info[0].workflow->ndpi_struct, i),
(long long unsigned int)cumulative_stats.protocol_counter[i],
(long long unsigned int)cumulative_stats.protocol_counter_bytes[i],
cumulative_stats.protocol_flows[i]);
@@ -1377,8 +925,8 @@ static void printResults(u_int64_t tot_usec) {
if(json_fp) {
jObj = json_object_new_object();
- json_object_object_add(jObj,"name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i)));
- json_object_object_add(jObj,"breed",json_object_new_string(ndpi_get_proto_breed_name(ndpi_thread_info[0].ndpi_struct, breed)));
+ json_object_object_add(jObj,"name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[0].workflow->ndpi_struct, i)));
+ json_object_object_add(jObj,"breed",json_object_new_string(ndpi_get_proto_breed_name(ndpi_thread_info[0].workflow->ndpi_struct, breed)));
json_object_object_add(jObj,"packets",json_object_new_int64(cumulative_stats.protocol_counter[i]));
json_object_object_add(jObj,"bytes",json_object_new_int64(cumulative_stats.protocol_counter_bytes[i]));
json_object_object_add(jObj,"flows",json_object_new_int(cumulative_stats.protocol_flows[i]));
@@ -1398,7 +946,7 @@ static void printResults(u_int64_t tot_usec) {
for(i=0; i < NUM_BREEDS; i++) {
if(breed_stats[i] > 0) {
printf("\t%-20s %13llu bytes\n",
- ndpi_get_proto_breed_name(ndpi_thread_info[0].ndpi_struct, i),
+ ndpi_get_proto_breed_name(ndpi_thread_info[0].workflow->ndpi_struct, i),
breed_stats[i]);
}
}
@@ -1414,11 +962,11 @@ static void printResults(u_int64_t tot_usec) {
num_flows = 0;
for(thread_id = 0; thread_id < num_threads; thread_id++) {
for(i=0; i<NUM_ROOTS; i++)
- ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_print_known_proto_walker, &thread_id);
+ ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], node_print_known_proto_walker, &thread_id);
}
for(thread_id = 0; thread_id < num_threads; thread_id++) {
- if(ndpi_thread_info[thread_id].stats.protocol_counter[0 /* 0 = Unknown */] > 0) {
+ if(ndpi_thread_info[thread_id].workflow->stats.protocol_counter[0 /* 0 = Unknown */] > 0) {
if(!json_flag) {
FILE *out = results_file ? results_file : stdout;
@@ -1433,9 +981,9 @@ static void printResults(u_int64_t tot_usec) {
num_flows = 0;
for(thread_id = 0; thread_id < num_threads; thread_id++) {
- if(ndpi_thread_info[thread_id].stats.protocol_counter[0] > 0) {
+ if(ndpi_thread_info[thread_id].workflow->stats.protocol_counter[0] > 0) {
for(i=0; i<NUM_ROOTS; i++)
- ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_print_unknown_proto_walker, &thread_id);
+ ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], node_print_unknown_proto_walker, &thread_id);
}
}
}
@@ -1454,27 +1002,24 @@ static void printResults(u_int64_t tot_usec) {
}
}
-/* ***************************************************** */
-
-static void closePcapFile(u_int16_t thread_id) {
- if(ndpi_thread_info[thread_id]._pcap_handle != NULL) {
- pcap_close(ndpi_thread_info[thread_id]._pcap_handle);
-
- }
-}
-
-/* ***************************************************** */
+/**
+ * @brief Force a pcap_dispatch() or pcap_loop() call to return
+ */
static void breakPcapLoop(u_int16_t thread_id) {
- if(ndpi_thread_info[thread_id]._pcap_handle != NULL) {
- pcap_breakloop(ndpi_thread_info[thread_id]._pcap_handle);
+
+ if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL) {
+ pcap_breakloop(ndpi_thread_info[thread_id].workflow->pcap_handle);
}
}
-/* ***************************************************** */
-// executed for each packet in the pcap file
+
+/**
+ * @brief Sigproc is executed for each packet in the pcap file
+ */
void sigproc(int sig) {
+
static int called = 0;
int thread_id;
@@ -1485,8 +1030,10 @@ void sigproc(int sig) {
breakPcapLoop(thread_id);
}
-/* ***************************************************** */
+/**
+ * @brief Get the next pcap file from a passed playlist
+ */
static int getNextPcapFileFromPlaylist(u_int16_t thread_id, char filename[], u_int32_t filename_len) {
if(playlist_fp[thread_id] == NULL) {
@@ -1507,62 +1054,67 @@ static int getNextPcapFileFromPlaylist(u_int16_t thread_id, char filename[], u_i
}
}
-/* ***************************************************** */
-static void configurePcapHandle(u_int16_t thread_id) {
- ndpi_thread_info[thread_id]._pcap_datalink_type = pcap_datalink(ndpi_thread_info[thread_id]._pcap_handle);
+/**
+ * @brief Configure the pcap handle
+ */
+static void configurePcapHandle(pcap_t * pcap_handle) {
if(_bpf_filter != NULL) {
struct bpf_program fcode;
- if(pcap_compile(ndpi_thread_info[thread_id]._pcap_handle, &fcode, _bpf_filter, 1, 0xFFFFFF00) < 0) {
- printf("pcap_compile error: '%s'\n", pcap_geterr(ndpi_thread_info[thread_id]._pcap_handle));
+ if(pcap_compile(pcap_handle, &fcode, _bpf_filter, 1, 0xFFFFFF00) < 0) {
+ printf("pcap_compile error: '%s'\n", pcap_geterr(pcap_handle));
} else {
- if(pcap_setfilter(ndpi_thread_info[thread_id]._pcap_handle, &fcode) < 0) {
- printf("pcap_setfilter error: '%s'\n", pcap_geterr(ndpi_thread_info[thread_id]._pcap_handle));
+ if(pcap_setfilter(pcap_handle, &fcode) < 0) {
+ printf("pcap_setfilter error: '%s'\n", pcap_geterr(pcap_handle));
} else
printf("Successfully set BPF filter to '%s'\n", _bpf_filter);
}
}
}
-/* ***************************************************** */
-static void openPcapFileOrDevice(u_int16_t thread_id) {
+/**
+ * @brief Open a pcap file or a specified device - Always returns a valid pcap_t
+ */
+static pcap_t * openPcapFileOrDevice(u_int16_t thread_id, const u_char * pcap_file) {
+
u_int snaplen = 1536;
int promisc = 1;
- char errbuf[PCAP_ERRBUF_SIZE];
+ char pcap_error_buffer[PCAP_ERRBUF_SIZE];
+ pcap_t * pcap_handle = NULL;
/* trying to open a live interface */
- if((ndpi_thread_info[thread_id]._pcap_handle = pcap_open_live(_pcap_file[thread_id], snaplen, promisc, 500, errbuf)) == NULL) {
+ if((pcap_handle = pcap_open_live((char*)pcap_file, snaplen, promisc, 500, pcap_error_buffer)) == NULL) {
capture_for = capture_until = 0;
live_capture = 0;
num_threads = 1; /* Open pcap files in single threads mode */
/* trying to open a pcap file */
- if((ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(_pcap_file[thread_id], ndpi_thread_info[thread_id]._pcap_error_buffer)) == NULL) {
+ if((pcap_handle = pcap_open_offline((char*)pcap_file, pcap_error_buffer)) == NULL) {
char filename[256];
/* trying to open a pcap playlist */
if(getNextPcapFileFromPlaylist(thread_id, filename, sizeof(filename)) != 0 ||
- (ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(filename, ndpi_thread_info[thread_id]._pcap_error_buffer)) == NULL) {
+ (pcap_handle = pcap_open_offline(filename, pcap_error_buffer)) == NULL) {
- printf("ERROR: could not open pcap file or playlist: %s\n", ndpi_thread_info[thread_id]._pcap_error_buffer);
+ printf("ERROR: could not open pcap file or playlist: %s\n", pcap_error_buffer);
exit(-1);
} else {
- if((!json_flag) && (!quiet_mode)) printf("Reading packets from playlist %s...\n", _pcap_file[thread_id]);
+ if((!json_flag) && (!quiet_mode)) printf("Reading packets from playlist %s...\n", pcap_file);
}
} else {
- if((!json_flag) && (!quiet_mode)) printf("Reading packets from pcap file %s...\n", _pcap_file[thread_id]);
+ if((!json_flag) && (!quiet_mode)) printf("Reading packets from pcap file %s...\n", pcap_file);
}
} else {
live_capture = 1;
- if((!json_flag) && (!quiet_mode)) printf("Capturing live traffic from device %s...\n", _pcap_file[thread_id]);
+ if((!json_flag) && (!quiet_mode)) printf("Capturing live traffic from device %s...\n", pcap_file);
}
- configurePcapHandle(thread_id);
+ configurePcapHandle(pcap_handle);
if(capture_for > 0) {
if((!json_flag) && (!quiet_mode)) printf("Capturing traffic up to %u seconds\n", (unsigned int)capture_for);
@@ -1572,385 +1124,86 @@ static void openPcapFileOrDevice(u_int16_t thread_id) {
signal(SIGALRM, sigproc);
#endif
}
+
+ return pcap_handle;
}
-/* ***************************************************** */
-static void pcap_packet_callback(u_char *args,
+/**
+ * @brief Check pcap packet
+ */
+static void pcap_packet_callback_checked(u_char *args,
const struct pcap_pkthdr *header,
const u_char *packet) {
- /*
- * Declare pointers to packet headers
- */
-
- /* --- Ethernet header --- */
- const struct ndpi_ethhdr *ethernet;
- /* --- Ethernet II header --- */
- const struct ndpi_ethhdr *ethernet_2;
- /* --- LLC header --- */
- const struct ndpi_llc_header *llc;
-
- /* --- Cisco HDLC header --- */
- const struct ndpi_chdlc *chdlc;
- /* --- SLARP frame --- */
- struct ndpi_slarp *slarp;
- /* --- CDP --- */
- struct ndpi_cdp *cdp;
-
- /* --- Radio Tap header --- */
- const struct ndpi_radiotap_header *radiotap;
- /* --- Wifi header --- */
- const struct ndpi_wifi_header *wifi;
-
- /* --- MPLS header --- */
- struct ndpi_mpls_header *mpls;
-
- /** --- IP header --- **/
- struct ndpi_iphdr *iph;
- /** --- IPv6 header --- **/
- struct ndpi_ipv6hdr *iph6;
-
- /* lengths and offsets */
- u_int16_t eth_offset = 0;
- u_int16_t radio_len;
- u_int16_t fc;
- u_int16_t type;
- int wifi_len;
- int llc_off;
- int pyld_eth_len = 0;
- int check;
- char packet_copy[1600];
- u_int32_t fcs, packet_copy_len = sizeof(packet_copy);;
- u_int64_t time;
- u_int16_t ip_offset, ip_len, ip6_offset;
- u_int16_t frag_off = 0, vlan_id = 0;
- u_int8_t proto = 0;
- u_int32_t label;
-
u_int16_t thread_id = *((u_int16_t*)args);
- /* counters */
- u_int8_t malformed_pkts = 0, vlan_packet = 0;
- u_int8_t slarp_pkts = 0, cdp_pkts = 0;
-
- /* Increment raw packet counter */
- ndpi_thread_info[thread_id].stats.raw_packet_count++;
+ /* allocate an exact size buffer to check overflows */
+ uint8_t *packet_checked = malloc(header->caplen);
+ memcpy(packet_checked, packet, header->caplen);
+ ndpi_workflow_process_packet(ndpi_thread_info[thread_id].workflow, header, packet_checked);
if((capture_until != 0) && (header->ts.tv_sec >= capture_until)) {
- if(ndpi_thread_info[thread_id]._pcap_handle != NULL)
- pcap_breakloop(ndpi_thread_info[thread_id]._pcap_handle);
+ if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL)
+ pcap_breakloop(ndpi_thread_info[thread_id].workflow->pcap_handle);
return;
}
- if(header->caplen < packet_copy_len) packet_copy_len = header->caplen;
- memcpy(packet_copy, packet, packet_copy_len);
-
/* Check if capture is live or not */
if (!live_capture) {
if (!pcap_start.tv_sec) pcap_start.tv_sec = header->ts.tv_sec, pcap_start.tv_usec = header->ts.tv_usec;
pcap_end.tv_sec = header->ts.tv_sec, pcap_end.tv_usec = header->ts.tv_usec;
}
- /* setting time */
- time = ((uint64_t) header->ts.tv_sec) * detection_tick_resolution +
- header->ts.tv_usec / (1000000 / detection_tick_resolution);
-
- /* safety check */
- if(ndpi_thread_info[thread_id].last_time > time) {
- /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); */
- time = ndpi_thread_info[thread_id].last_time;
- }
- /* update last time value */
- ndpi_thread_info[thread_id].last_time = time;
-
- /*** check Data Link type ***/
- int datalink_type = ndpi_thread_info[thread_id]._pcap_datalink_type;
-
- datalink_check:
- switch(datalink_type) {
- case DLT_NULL :
- if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2)
- type = ETH_P_IP;
- else
- type = ETH_P_IPV6;
-
- ip_offset = 4 + eth_offset;
-
- /* Cisco PPP in HDLC-like framing - 50 */
- case DLT_PPP_SERIAL:
- chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
- ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
- type = ntohs(chdlc->proto_code);
- break;
-
- /* Cisco PPP with HDLC framing - 104 */
- case DLT_C_HDLC:
- chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
- ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
- type = ntohs(chdlc->proto_code);
- break;
-
- /* IEEE 802.3 Ethernet - 1 */
- case DLT_EN10MB :
- ethernet = (struct ndpi_ethhdr *) &packet[eth_offset];
- ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset;
- check = ntohs(ethernet->h_proto);
-
- if(check <= 1500)
- pyld_eth_len = check;
- else if (check >= 1536)
- type = check;
-
- if(pyld_eth_len != 0) {
- /* check for LLC layer with SNAP extension */
- if(packet[ip_offset] == SNAP) {
- llc = (struct ndpi_llc_header *)(&packet[ip_offset]);
- type = llc->snap.proto_ID;
- ip_offset += + 8;
- }
- }
- break;
-
- /* Linux Cooked Capture - 113 */
- case DLT_LINUX_SLL :
- type = (packet[eth_offset+14] << 8) + packet[eth_offset+15];
- ip_offset = 16 + eth_offset;
- break;
-
- /* Radiotap link-layer - 127 */
- case DLT_IEEE802_11_RADIO :
- radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset];
- radio_len = radiotap->len;
-
- /* Check Bad FCS presence */
- if((radiotap->flags & BAD_FCS) == BAD_FCS) {
- malformed_pkts += 1;
- ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len;
- return;
- }
-
- fcs = header->len - 4;
-
- /* Calculate 802.11 header length (variable) */
- wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len);
- fc = wifi->fc;
-
- /* check wifi data presence */
- if(FCF_TYPE(fc) == WIFI_DATA) {
- if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) ||
- (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc)))
- wifi_len = 26; /* + 4 byte fcs */
- } else /* no data frames */
- break;
-
- /* Check ether_type from LLC */
- llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len);
- if(llc->dsap == SNAP)
- type = ntohs(llc->snap.proto_ID);
-
- /* Set IP header offset */
- ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header) + eth_offset;
- break;
-
- case DLT_RAW:
- ip_offset = eth_offset = 0;
- break;
-
- default:
- /* printf("Unknown datalink %d\n", datalink_type); */
- return;
- }
-
- /* check ether type */
- if(type == VLAN) {
- vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
- type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
- ip_offset += 4;
- vlan_packet = 1;
- } else if(type == MPLS_UNI || type == MPLS_MULTI) {
- mpls = (struct ndpi_mpls_header *) &packet[ip_offset];
- label = ntohl(mpls->label);
- /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */
- ndpi_thread_info[thread_id].stats.mpls_count++;
- type = ETH_P_IP, ip_offset += 4;
-
- while((label & 0x100) != 0x100) {
- ip_offset += 4;
- label = ntohl(mpls->label);
- }
- }
- else if(type == SLARP) {
- slarp = (struct ndpi_slarp *) &packet[ip_offset];
- if(slarp->slarp_type == 0x02 || slarp->slarp_type == 0x00 || slarp->slarp_type == 0x01) {
- /* TODO if info are needed */
- }
- slarp_pkts++;
- }
- else if(type == CISCO_D_PROTO) {
- cdp = (struct ndpi_cdp *) &packet[ip_offset];
- cdp_pkts++;
- }
- else if(type == PPPoE) {
- ndpi_thread_info[thread_id].stats.pppoe_count++;
- type = ETH_P_IP;
- ip_offset += 8;
- }
-
- ndpi_thread_info[thread_id].stats.vlan_count += vlan_packet;
-
- iph_check:
- /* Check and set IP header size and total packet length */
- iph = (struct ndpi_iphdr *) &packet[ip_offset];
-
- /* just work on Ethernet packets that contain IP */
- if(type == ETH_P_IP && header->caplen >= ip_offset) {
- frag_off = ntohs(iph->frag_off);
-
- proto = iph->protocol;
- if(header->caplen < header->len) {
- static u_int8_t cap_warning_used = 0;
-
- if(cap_warning_used == 0) {
- if((!json_flag) && (!quiet_mode)) printf("\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n");
- cap_warning_used = 1;
- }
- }
- }
-
- if(iph->version == 4) {
- ip_len = ((u_short)iph->ihl * 4);
- iph6 = NULL;
+ /* Idle flows cleanup */
+ if(live_capture) {
+ if(ndpi_thread_info[thread_id].last_idle_scan_time + IDLE_SCAN_PERIOD < ndpi_thread_info[thread_id].workflow->last_time) {
+ /* scan for idle flows */
+ ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_idle_scan_walker, &thread_id);
- if(iph->protocol == 41) {
- ip_offset += ip_len;
- goto iph_check;
- }
+ /* remove idle flows (unfortunately we cannot do this inline) */
+ while (ndpi_thread_info[thread_id].num_idle_flows > 0) {
- if((frag_off & 0x3FFF) != 0) {
- static u_int8_t ipv4_frags_warning_used = 0;
- ndpi_thread_info[thread_id].stats.fragmented_count++;
+ /* search and delete the idle flow from the "ndpi_flow_root" (see struct reader thread) - here flows are the node of a b-tree */
+ ndpi_tdelete(ndpi_thread_info[thread_id].idle_flows[--ndpi_thread_info[thread_id].num_idle_flows],
+ &ndpi_thread_info[thread_id].workflow->ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx],
+ ndpi_workflow_node_cmp);
- if(ipv4_frags_warning_used == 0) {
- if((!json_flag) && (!quiet_mode)) printf("\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n");
- ipv4_frags_warning_used = 1;
+ /* free the memory associated to idle flow in "idle_flows" - (see struct reader thread)*/
+ ndpi_free_flow_info_half(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]);
+ ndpi_free(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]);
}
- ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len;
- return;
- }
- } else if(iph->version == 6) {
- iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
- proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
- ip_len = sizeof(struct ndpi_ipv6hdr);
-
- if(proto == 0x3C /* IPv6 destination option */) {
-
- u_int8_t *options = (u_int8_t*)&packet[ip_offset+ip_len];
- proto = options[0];
- ip_len += 8 * (options[1] + 1);
- }
- iph = NULL;
-
- } else {
- static u_int8_t ipv4_warning_used = 0;
-
- v4_warning:
- if(ipv4_warning_used == 0) {
- if((!json_flag) && (!quiet_mode))
- printf("\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI supports both IPv4 and IPv6), all other packets will be discarded\n\n");
- ipv4_warning_used = 1;
- }
- ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len;
- return;
- }
-
- if(decode_tunnels && (proto == IPPROTO_UDP)) {
- struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
- u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest);
-
- if((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) {
- /* Check if it's GTPv1 */
- u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
- u_int8_t flags = packet[offset];
- u_int8_t message_type = packet[offset+1];
-
- if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) &&
- (message_type == 0xFF /* T-PDU */)) {
-
- ip_offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr)+8; /* GTPv1 header len */
- if(flags & 0x04) ip_offset += 1; /* next_ext_header is present */
- if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */
- if(flags & 0x01) ip_offset += 1; /* pdu_number is present */
-
- iph = (struct ndpi_iphdr *) &packet[ip_offset];
-
- if(iph->version != 4) {
- // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)ndpi_thread_info[thread_id].stats.raw_packet_count);
- goto v4_warning;
- }
- }
- } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) {
- /* https://en.wikipedia.org/wiki/TZSP */
- u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
- u_int8_t version = packet[offset];
- u_int8_t type = packet[offset+1];
- u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2]));
-
- if((version == 1) && (type == 0) && (encapsulates == 1)) {
- u_int8_t stop = 0;
-
- offset += 4;
-
- while((!stop) && (offset < header->caplen)) {
- u_int8_t tag_type = packet[offset];
- u_int8_t tag_len;
-
- switch(tag_type) {
- case 0: /* PADDING Tag */
- tag_len = 1;
- break;
- case 1: /* END Tag */
- tag_len = 1, stop = 1;
- break;
- default:
- tag_len = packet[offset+1];
- break;
- }
-
- offset += tag_len;
-
- if(offset >= header->caplen)
- return; /* Invalid packet */
- else {
- eth_offset = offset;
- goto datalink_check;
- }
- }
- }
+ if(++ndpi_thread_info[thread_id].idle_scan_idx == ndpi_thread_info[thread_id].workflow->prefs.num_roots) ndpi_thread_info[thread_id].idle_scan_idx = 0;
+ ndpi_thread_info[thread_id].last_idle_scan_time = ndpi_thread_info[thread_id].workflow->last_time;
}
}
- /* process the packet */
- packet_processing(thread_id, time, vlan_id, iph, iph6,
- ip_offset, header->len - ip_offset, header->len);
-
- if(memcmp(packet_copy, packet, packet_copy_len) != 0)
+ /* check for buffer changes */
+ if(memcmp(packet, packet_checked, header->caplen) != 0)
printf("INTERNAL ERROR: ingress packet was nodified by nDPI: this should not happen [thread_id=%u, packetId=%lu]\n",
- thread_id, (unsigned long)ndpi_thread_info[thread_id].stats.raw_packet_count);
+ thread_id, (unsigned long)ndpi_thread_info[thread_id].workflow->stats.raw_packet_count);
+ free(packet_checked);
}
-/* ******************************************************************** */
+/**
+ * @brief Call pcap_loop() to process packets from a live capture or savefile
+ */
static void runPcapLoop(u_int16_t thread_id) {
- if((!shutdown_app) && (ndpi_thread_info[thread_id]._pcap_handle != NULL))
- pcap_loop(ndpi_thread_info[thread_id]._pcap_handle, -1, &pcap_packet_callback, (u_char*)&thread_id);
+
+ if((!shutdown_app) && (ndpi_thread_info[thread_id].workflow->pcap_handle != NULL))
+ pcap_loop(ndpi_thread_info[thread_id].workflow->pcap_handle, -1, &pcap_packet_callback_checked, (u_char*)&thread_id);
}
-/* ******************************************************************** */
-void *processing_thread(void *_thread_id) {
+/**
+ * @brief Process a running thread
+ */
+void * processing_thread(void *_thread_id) {
+
long thread_id = (long) _thread_id;
+ char pcap_error_buffer[PCAP_ERRBUF_SIZE];
#if defined(linux) && defined(HAVE_PTHREAD_SETAFFINITY_NP)
if(core_affinity[thread_id] >= 0) {
@@ -1974,18 +1227,21 @@ void *processing_thread(void *_thread_id) {
char filename[256];
if(getNextPcapFileFromPlaylist(thread_id, filename, sizeof(filename)) == 0 &&
- (ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(filename, ndpi_thread_info[thread_id]._pcap_error_buffer)) != NULL) {
- configurePcapHandle(thread_id);
+ (ndpi_thread_info[thread_id].workflow->pcap_handle = pcap_open_offline(filename, pcap_error_buffer)) != NULL) {
+ configurePcapHandle(ndpi_thread_info[thread_id].workflow->pcap_handle);
goto pcap_loop;
}
}
-
+
return NULL;
}
-/* ******************************************************************** */
+/**
+ * @brief Begin, process, end detection process
+ */
void test_lib() {
+
struct timeval begin, end;
u_int64_t tot_usec;
long thread_id;
@@ -1995,8 +1251,8 @@ void test_lib() {
#endif
for(thread_id = 0; thread_id < num_threads; thread_id++) {
- setupDetection(thread_id);
- openPcapFileOrDevice(thread_id);
+ pcap_t * cap = openPcapFileOrDevice(thread_id, (const u_char*)_pcap_file[thread_id]);
+ setupDetection(thread_id, cap);
}
gettimeofday(&begin, NULL);
@@ -2016,16 +1272,34 @@ void test_lib() {
printResults(tot_usec);
for(thread_id = 0; thread_id < num_threads; thread_id++) {
- closePcapFile(thread_id);
+ if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL) {
+ pcap_close(ndpi_thread_info[thread_id].workflow->pcap_handle);
+ }
terminateDetection(thread_id);
}
}
-/* ***************************************************** */
+void automataUnitTest() {
+ void *automa;
+
+ assert(automa = ndpi_init_automa());
+ assert(ndpi_add_string_to_automa(automa, "hello") == 0);
+ assert(ndpi_add_string_to_automa(automa, "world") == 0);
+ ndpi_finalize_automa(automa);
+ assert(ndpi_match_string(automa, "This is the wonderful world of nDPI") == 0);
+
+ ndpi_free_automa(automa);
+}
+/**
+ @brief MAIN FUNCTION
+ **/
int main(int argc, char **argv) {
+
int i;
+ automataUnitTest();
+
memset(ndpi_thread_info, 0, sizeof(ndpi_thread_info));
memset(&pcap_start, 0, sizeof(pcap_start));
memset(&pcap_end, 0, sizeof(pcap_end));
@@ -2054,7 +1328,6 @@ int main(int argc, char **argv) {
return 0;
}
-/* ****************************************************** */
#ifdef WIN32
#ifndef __GNUC__
@@ -2063,13 +1336,19 @@ int main(int argc, char **argv) {
#define EPOCHFILETIME (116444736000000000LL)
#endif
+
+/**
+ @brief Timezone
+ **/
struct timezone {
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
-/* ***************************************************** */
+/**
+ @brief Set time
+ **/
int gettimeofday(struct timeval *tv, struct timezone *tz) {
FILETIME ft;
LARGE_INTEGER li;
diff --git a/example/ndpi_util.c b/example/ndpi_util.c
new file mode 100644
index 000000000..405cac366
--- /dev/null
+++ b/example/ndpi_util.c
@@ -0,0 +1,867 @@
+/*
+ * ndpi_util.c
+ *
+ * Copyright (C) 2011-16 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+
+#ifdef WIN32
+#include <winsock2.h> /* winsock.h is included automatically */
+#include <process.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#include <netinet/in.h>
+#endif
+
+#ifndef ETH_P_IP
+#define ETH_P_IP 0x0800 /* IPv4 */
+#endif
+
+#ifndef ETH_P_IPv6
+#define ETH_P_IPV6 0x86dd /* IPv6 */
+#endif
+
+#define SLARP 0x8035 /* Cisco Slarp */
+#define CISCO_D_PROTO 0x2000 /* Cisco Discovery Protocol */
+
+#define VLAN 0x8100
+#define MPLS_UNI 0x8847
+#define MPLS_MULTI 0x8848
+#define PPPoE 0x8864
+#define SNAP 0xaa
+
+/* mask for FCF */
+#define WIFI_DATA 0x2 /* 0000 0010 */
+#define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */
+#define FCF_SUBTYPE(fc) (((fc) >> 4) & 0xF) /* 0000 1111 = 0xF */
+#define FCF_TO_DS(fc) ((fc) & 0x0100)
+#define FCF_FROM_DS(fc) ((fc) & 0x0200)
+
+/* mask for Bad FCF presence */
+#define BAD_FCS 0x50 /* 0101 0000 */
+
+#define GTP_U_V1_PORT 2152
+#define TZSP_PORT 37008
+
+#define SIZEOF_ID_STRUCT (sizeof(struct ndpi_id_struct))
+#define SIZEOF_FLOW_STRUCT (sizeof(struct ndpi_flow_struct))
+
+#include "ndpi_main.h"
+#include "ndpi_util.h"
+
+/* ***************************************************** */
+
+void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) {
+ if(flow->ndpi_flow) { ndpi_free_flow(flow->ndpi_flow); flow->ndpi_flow = NULL; }
+ if(flow->src_id) { ndpi_free(flow->src_id); flow->src_id = NULL; }
+ if(flow->dst_id) { ndpi_free(flow->dst_id); flow->dst_id = NULL; }
+
+}
+
+/* ***************************************************** */
+
+static const u_int8_t nDPI_traceLevel = 0;
+
+/* ***************************************************** */
+
+extern u_int32_t current_ndpi_memory, max_ndpi_memory;
+
+/**
+ * @brief malloc wrapper function
+ */
+static void *malloc_wrapper(size_t size) {
+ current_ndpi_memory += size;
+
+ if(current_ndpi_memory > max_ndpi_memory)
+ max_ndpi_memory = current_ndpi_memory;
+
+ return malloc(size);
+}
+
+/* ***************************************************** */
+
+/**
+ * @brief free wrapper function
+ */
+static void free_wrapper(void *freeable) {
+ free(freeable);
+}
+
+/* ***************************************************** */
+
+struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, pcap_t * pcap_handle) {
+
+ set_ndpi_malloc(malloc_wrapper), set_ndpi_free(free_wrapper);
+ /* TODO: just needed here to init ndpi malloc wrapper */
+ struct ndpi_detection_module_struct * module = ndpi_init_detection_module();
+
+ struct ndpi_workflow * workflow = ndpi_calloc(1, sizeof(struct ndpi_workflow));
+
+ workflow->pcap_handle = pcap_handle;
+ workflow->prefs = *prefs;
+ workflow->ndpi_struct = module;
+
+ if(workflow->ndpi_struct == NULL) {
+ NDPI_LOG(0, NULL, NDPI_LOG_ERROR, "global structure initialization failed\n");
+ exit(-1);
+ }
+
+ workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *));
+ return workflow;
+}
+
+/* ***************************************************** */
+
+static void ndpi_flow_info_freer(void *node) {
+ struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node;
+
+ ndpi_free_flow_info_half(flow);
+ ndpi_free(flow);
+}
+
+/* ***************************************************** */
+
+void ndpi_workflow_free(struct ndpi_workflow * workflow) {
+ int i;
+
+ for(i=0; i<workflow->prefs.num_roots; i++)
+ ndpi_tdestroy(workflow->ndpi_flows_root[i], ndpi_flow_info_freer);
+
+ ndpi_exit_detection_module(workflow->ndpi_struct);
+ free(workflow->ndpi_flows_root);
+ free(workflow);
+}
+
+/* ***************************************************** */
+
+int ndpi_workflow_node_cmp(const void *a, const void *b) {
+ struct ndpi_flow_info *fa = (struct ndpi_flow_info*)a;
+ struct ndpi_flow_info *fb = (struct ndpi_flow_info*)b;
+
+ if(fa->vlan_id < fb->vlan_id ) return(-1); else { if(fa->vlan_id > fb->vlan_id ) return(1); }
+ if(fa->lower_ip < fb->lower_ip ) return(-1); else { if(fa->lower_ip > fb->lower_ip ) return(1); }
+ if(fa->lower_port < fb->lower_port) return(-1); else { if(fa->lower_port > fb->lower_port) return(1); }
+ if(fa->upper_ip < fb->upper_ip ) return(-1); else { if(fa->upper_ip > fb->upper_ip ) return(1); }
+ if(fa->upper_port < fb->upper_port) return(-1); else { if(fa->upper_port > fb->upper_port) return(1); }
+ if(fa->protocol < fb->protocol ) return(-1); else { if(fa->protocol > fb->protocol ) return(1); }
+
+ return(0);
+}
+
+/* ***************************************************** */
+
+static void patchIPv6Address(char *str) {
+ int i = 0, j = 0;
+
+ while(str[i] != '\0') {
+ if((str[i] == ':')
+ && (str[i+1] == '0')
+ && (str[i+2] == ':')) {
+ str[j++] = ':';
+ str[j++] = ':';
+ i += 3;
+ } else
+ str[j++] = str[i++];
+ }
+ if(str[j] != '\0') str[j] = '\0';
+}
+
+/* ***************************************************** */
+
+static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow,
+ const u_int8_t version,
+ u_int16_t vlan_id,
+ const struct ndpi_iphdr *iph,
+ const struct ndpi_ipv6hdr *iph6,
+ u_int16_t ip_offset,
+ u_int16_t ipsize,
+ u_int16_t l4_packet_len,
+ struct ndpi_tcphdr **tcph,
+ struct ndpi_udphdr **udph,
+ u_int16_t *sport, u_int16_t *dport,
+ struct ndpi_id_struct **src,
+ struct ndpi_id_struct **dst,
+ u_int8_t *proto,
+ u_int8_t **payload,
+ u_int16_t *payload_len,
+ u_int8_t *src_to_dst_direction) {
+ u_int32_t idx, l4_offset;
+ u_int32_t lower_ip;
+ u_int32_t upper_ip;
+ u_int16_t lower_port;
+ u_int16_t upper_port;
+ struct ndpi_flow_info flow;
+ void *ret;
+ u_int8_t *l3, *l4;
+
+ /*
+ Note: to keep things simple (ndpiReader is just a demo app)
+ we handle IPv6 a-la-IPv4.
+ */
+ if(version == 4) {
+ if(ipsize < 20)
+ return NULL;
+
+ if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len)
+ || (iph->frag_off & htons(0x1FFF)) != 0)
+ return NULL;
+
+ l4_offset = iph->ihl * 4;
+ l3 = (u_int8_t*)iph;
+ } else {
+ l4_offset = sizeof(struct ndpi_ipv6hdr);
+ l3 = (u_int8_t*)iph6;
+ }
+
+ if(l4_packet_len < 64)
+ workflow->stats.packet_len[0]++;
+ else if(l4_packet_len >= 64 && l4_packet_len < 128)
+ workflow->stats.packet_len[1]++;
+ else if(l4_packet_len >= 128 && l4_packet_len < 256)
+ workflow->stats.packet_len[2]++;
+ else if(l4_packet_len >= 256 && l4_packet_len < 1024)
+ workflow->stats.packet_len[3]++;
+ else if(l4_packet_len >= 1024 && l4_packet_len < 1500)
+ workflow->stats.packet_len[4]++;
+ else if(l4_packet_len >= 1500)
+ workflow->stats.packet_len[5]++;
+
+ if(l4_packet_len > workflow->stats.max_packet_len)
+ workflow->stats.max_packet_len = l4_packet_len;
+
+ if(iph->saddr < iph->daddr) {
+ lower_ip = iph->saddr;
+ upper_ip = iph->daddr;
+ } else {
+ lower_ip = iph->daddr;
+ upper_ip = iph->saddr;
+ }
+
+ *proto = iph->protocol;
+ l4 = ((u_int8_t *) l3 + l4_offset);
+
+ if(iph->protocol == 6 && l4_packet_len >= 20) {
+ u_int tcp_len;
+
+ workflow->stats.tcp_count++;
+
+ // tcp
+ *tcph = (struct ndpi_tcphdr *)l4;
+ *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest);
+
+ if(iph->saddr < iph->daddr) {
+ lower_port = (*tcph)->source, upper_port = (*tcph)->dest;
+ *src_to_dst_direction = 1;
+ } else {
+ lower_port = (*tcph)->dest;
+ upper_port = (*tcph)->source;
+
+ *src_to_dst_direction = 0;
+ if(iph->saddr == iph->daddr) {
+ if(lower_port > upper_port) {
+ u_int16_t p = lower_port;
+
+ lower_port = upper_port;
+ upper_port = p;
+ }
+ }
+ }
+
+ tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len);
+ *payload = &l4[tcp_len];
+ *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff);
+ } else if(iph->protocol == 17 && l4_packet_len >= 8) {
+ // udp
+ workflow->stats.udp_count++;
+
+ *udph = (struct ndpi_udphdr *)l4;
+ *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest);
+ *payload = &l4[sizeof(struct ndpi_udphdr)];
+ *payload_len = ndpi_max(0, l4_packet_len-sizeof(struct ndpi_udphdr));
+
+ if(iph->saddr < iph->daddr) {
+ lower_port = (*udph)->source, upper_port = (*udph)->dest;
+ *src_to_dst_direction = 1;
+ } else {
+ lower_port = (*udph)->dest, upper_port = (*udph)->source;
+
+ *src_to_dst_direction = 0;
+
+ if(iph->saddr == iph->daddr) {
+ if(lower_port > upper_port) {
+ u_int16_t p = lower_port;
+
+ lower_port = upper_port;
+ upper_port = p;
+ }
+ }
+ }
+
+ *sport = ntohs(lower_port), *dport = ntohs(upper_port);
+ } else {
+ // non tcp/udp protocols
+ lower_port = 0;
+ upper_port = 0;
+ }
+
+ flow.protocol = iph->protocol, flow.vlan_id = vlan_id;
+ flow.lower_ip = lower_ip, flow.upper_ip = upper_ip;
+ flow.lower_port = lower_port, flow.upper_port = upper_port;
+
+ if(0)
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "[NDPI] [%u][%u:%u <-> %u:%u]\n",
+ iph->protocol, lower_ip, ntohs(lower_port), upper_ip, ntohs(upper_port));
+
+ idx = (vlan_id + lower_ip + upper_ip + iph->protocol + lower_port + upper_port) % workflow->prefs.num_roots;
+ ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
+
+ if(ret == NULL) {
+ if(workflow->stats.ndpi_flow_count == workflow->prefs.max_ndpi_flows) {
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "maximum flow count (%u) has been exceeded\n", workflow->prefs.max_ndpi_flows);
+ exit(-1);
+ } else {
+ struct ndpi_flow_info *newflow = (struct ndpi_flow_info*)malloc(sizeof(struct ndpi_flow_info));
+
+ if(newflow == NULL) {
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(1): not enough memory\n", __FUNCTION__);
+ return(NULL);
+ }
+
+ memset(newflow, 0, sizeof(struct ndpi_flow_info));
+ newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id;
+ newflow->lower_ip = lower_ip, newflow->upper_ip = upper_ip;
+ newflow->lower_port = lower_port, newflow->upper_port = upper_port;
+ newflow->ip_version = version;
+
+ if(version == 4) {
+ inet_ntop(AF_INET, &lower_ip, newflow->lower_name, sizeof(newflow->lower_name));
+ inet_ntop(AF_INET, &upper_ip, newflow->upper_name, sizeof(newflow->upper_name));
+ } else {
+ inet_ntop(AF_INET6, &iph6->ip6_src, newflow->lower_name, sizeof(newflow->lower_name));
+ inet_ntop(AF_INET6, &iph6->ip6_dst, newflow->upper_name, sizeof(newflow->upper_name));
+ /* For consistency across platfoms replace :0: with :: */
+ patchIPv6Address(newflow->lower_name), patchIPv6Address(newflow->upper_name);
+ }
+
+ if((newflow->ndpi_flow = ndpi_malloc(SIZEOF_FLOW_STRUCT)) == NULL) {
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(2): not enough memory\n", __FUNCTION__);
+ free(newflow);
+ return(NULL);
+ } else
+ memset(newflow->ndpi_flow, 0, SIZEOF_FLOW_STRUCT);
+
+ if((newflow->src_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) {
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(3): not enough memory\n", __FUNCTION__);
+ free(newflow);
+ return(NULL);
+ } else
+ memset(newflow->src_id, 0, SIZEOF_ID_STRUCT);
+
+ if((newflow->dst_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) {
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(4): not enough memory\n", __FUNCTION__);
+ free(newflow);
+ return(NULL);
+ } else
+ memset(newflow->dst_id, 0, SIZEOF_ID_STRUCT);
+
+ ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); /* Add */
+ workflow->stats.ndpi_flow_count++;
+
+ *src = newflow->src_id, *dst = newflow->dst_id;
+
+ return newflow;
+ }
+ } else {
+ struct ndpi_flow_info *flow = *(struct ndpi_flow_info**)ret;
+
+ if(flow->lower_ip == lower_ip && flow->upper_ip == upper_ip
+ && flow->lower_port == lower_port && flow->upper_port == upper_port)
+ *src = flow->src_id, *dst = flow->dst_id;
+ else
+ *src = flow->dst_id, *dst = flow->src_id;
+
+ return flow;
+ }
+}
+
+/* ****************************************************** */
+
+static struct ndpi_flow_info *get_ndpi_flow_info6(struct ndpi_workflow * workflow,
+ u_int16_t vlan_id,
+ const struct ndpi_ipv6hdr *iph6,
+ u_int16_t ip_offset,
+ struct ndpi_tcphdr **tcph,
+ struct ndpi_udphdr **udph,
+ u_int16_t *sport, u_int16_t *dport,
+ struct ndpi_id_struct **src,
+ struct ndpi_id_struct **dst,
+ u_int8_t *proto,
+ u_int8_t **payload,
+ u_int16_t *payload_len,
+ u_int8_t *src_to_dst_direction) {
+ struct ndpi_iphdr iph;
+
+ memset(&iph, 0, sizeof(iph));
+ iph.version = 4;
+ iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3];
+ iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3];
+ iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
+
+ if(iph.protocol == 0x3C /* IPv6 destination option */) {
+ u_int8_t *options = (u_int8_t*)iph6 + sizeof(const struct ndpi_ipv6hdr);
+
+ iph.protocol = options[0];
+ }
+
+ return(get_ndpi_flow_info(workflow, 6, vlan_id, &iph, iph6, ip_offset,
+ sizeof(struct ndpi_ipv6hdr),
+ ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen),
+ tcph, udph, sport, dport,
+ src, dst, proto, payload, payload_len, src_to_dst_direction));
+}
+
+/* ****************************************************** */
+
+// ipsize = header->len - ip_offset ; rawsize = header->len
+static unsigned int packet_processing(struct ndpi_workflow * workflow,
+ const u_int64_t time,
+ u_int16_t vlan_id,
+ const struct ndpi_iphdr *iph,
+ struct ndpi_ipv6hdr *iph6,
+ u_int16_t ip_offset,
+ u_int16_t ipsize, u_int16_t rawsize) {
+ struct ndpi_id_struct *src, *dst;
+ struct ndpi_flow_info *flow;
+ struct ndpi_flow_struct *ndpi_flow = NULL;
+ u_int8_t proto;
+ struct ndpi_tcphdr *tcph = NULL;
+ struct ndpi_udphdr *udph = NULL;
+ u_int16_t sport, dport, payload_len;
+ u_int8_t *payload;
+ u_int8_t src_to_dst_direction= 1;
+
+ if(iph)
+ flow = get_ndpi_flow_info(workflow, 4, vlan_id, iph, NULL,
+ ip_offset, ipsize,
+ ntohs(iph->tot_len) - (iph->ihl * 4),
+ &tcph, &udph, &sport, &dport,
+ &src, &dst, &proto,
+ &payload, &payload_len, &src_to_dst_direction);
+ else
+ flow = get_ndpi_flow_info6(workflow, vlan_id, iph6, ip_offset,
+ &tcph, &udph, &sport, &dport,
+ &src, &dst, &proto,
+ &payload, &payload_len, &src_to_dst_direction);
+
+ if(flow != NULL) {
+ workflow->stats.ip_packet_count++;
+ workflow->stats.total_wire_bytes += rawsize + 24 /* CRC etc */, workflow->stats.total_ip_bytes += rawsize;
+ ndpi_flow = flow->ndpi_flow;
+ flow->packets++, flow->bytes += rawsize;
+ flow->last_seen = time;
+ } else {
+ return(0);
+ }
+
+ /* Protocol already detected */
+ if(flow->detection_completed) return(0);
+
+ flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow,
+ iph ? (uint8_t *)iph : (uint8_t *)iph6,
+ ipsize, time, src, dst);
+
+ if((flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN)
+ || ((proto == IPPROTO_UDP) && (flow->packets > 8))
+ || ((proto == IPPROTO_TCP) && (flow->packets > 10))) {
+ /* New protocol detected or give up */
+ flow->detection_completed = 1;
+
+ if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && (ndpi_flow->num_stun_udp_pkts > 0))
+ ndpi_set_detected_protocol(workflow->ndpi_struct, ndpi_flow, NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN);
+
+ snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name);
+
+ if(flow->detected_protocol.protocol == NDPI_PROTOCOL_BITTORRENT) {
+ int i, j, n = 0;
+
+ for(i=0, j = 0; i<20; i++) {
+ sprintf(&flow->bittorent_hash[j], "%02x", flow->ndpi_flow->bittorent_hash[i]);
+ j += 2, n += flow->ndpi_flow->bittorent_hash[i];
+ }
+
+ if(n == 0) flow->bittorent_hash[0] = '\0';
+ }
+
+ if((proto == IPPROTO_TCP) && (flow->detected_protocol.protocol != NDPI_PROTOCOL_DNS)) {
+ snprintf(flow->ssl.client_certificate, sizeof(flow->ssl.client_certificate), "%s", flow->ndpi_flow->protos.ssl.client_certificate);
+ snprintf(flow->ssl.server_certificate, sizeof(flow->ssl.server_certificate), "%s", flow->ndpi_flow->protos.ssl.server_certificate);
+ }
+
+ if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) {
+ flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow);
+
+ if (workflow->__flow_giveup_callback != NULL)
+ workflow->__flow_giveup_callback(workflow, flow, workflow->__flow_giveup_udata);
+ } else {
+ if (workflow->__flow_detected_callback != NULL)
+ workflow->__flow_detected_callback(workflow, flow, workflow->__flow_detected_udata);
+ }
+
+ ndpi_free_flow_info_half(flow);
+ }
+
+ return 0;
+}
+
+/* ****************************************************** */
+void ndpi_workflow_process_packet (struct ndpi_workflow * workflow,
+ const struct pcap_pkthdr *header,
+ const u_char *packet) {
+ /*
+ * Declare pointers to packet headers
+ */
+
+ /* --- Ethernet header --- */
+ const struct ndpi_ethhdr *ethernet;
+ /* --- Ethernet II header --- */
+ const struct ndpi_ethhdr *ethernet_2;
+ /* --- LLC header --- */
+ const struct ndpi_llc_header *llc;
+
+ /* --- Cisco HDLC header --- */
+ const struct ndpi_chdlc *chdlc;
+ /* --- SLARP frame --- */
+ struct ndpi_slarp *slarp;
+ /* --- CDP --- */
+ struct ndpi_cdp *cdp;
+
+ /* --- Radio Tap header --- */
+ const struct ndpi_radiotap_header *radiotap;
+ /* --- Wifi header --- */
+ const struct ndpi_wifi_header *wifi;
+
+ /* --- MPLS header --- */
+ struct ndpi_mpls_header *mpls;
+
+ /** --- IP header --- **/
+ struct ndpi_iphdr *iph;
+ /** --- IPv6 header --- **/
+ struct ndpi_ipv6hdr *iph6;
+
+ /* lengths and offsets */
+ u_int16_t eth_offset = 0;
+ u_int16_t radio_len;
+ u_int16_t fc;
+ u_int16_t type;
+ int wifi_len = 0;
+ int llc_off;
+ int pyld_eth_len = 0;
+ int check;
+ u_int64_t time;
+ u_int16_t ip_offset, ip_len, ip6_offset;
+ u_int16_t frag_off = 0, vlan_id = 0;
+ u_int8_t proto = 0;
+ u_int32_t label;
+
+ /* counters */
+ u_int8_t vlan_packet = 0;
+
+ /* Increment raw packet counter */
+ workflow->stats.raw_packet_count++;
+
+ /* setting time */
+ time = ((uint64_t) header->ts.tv_sec) * TICK_RESOLUTION + header->ts.tv_usec / (1000000 / TICK_RESOLUTION);
+
+ /* safety check */
+ if(workflow->last_time > time) {
+ /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); */
+ time = workflow->last_time;
+ }
+ /* update last time value */
+ workflow->last_time = time;
+
+ /*** check Data Link type ***/
+ const int datalink_type = pcap_datalink(workflow->pcap_handle);
+
+ datalink_check:
+ switch(datalink_type) {
+ case DLT_NULL :
+ if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2)
+ type = ETH_P_IP;
+ else
+ type = ETH_P_IPV6;
+
+ ip_offset = 4 + eth_offset;
+ break;
+
+ /* Cisco PPP in HDLC-like framing - 50 */
+ case DLT_PPP_SERIAL:
+ chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
+ ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
+ type = ntohs(chdlc->proto_code);
+ break;
+
+ /* Cisco PPP with HDLC framing - 104 */
+ case DLT_C_HDLC:
+ chdlc = (struct ndpi_chdlc *) &packet[eth_offset];
+ ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */
+ type = ntohs(chdlc->proto_code);
+ break;
+
+ /* IEEE 802.3 Ethernet - 1 */
+ case DLT_EN10MB :
+ ethernet = (struct ndpi_ethhdr *) &packet[eth_offset];
+ ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset;
+ check = ntohs(ethernet->h_proto);
+
+ if(check <= 1500)
+ pyld_eth_len = check;
+ else if (check >= 1536)
+ type = check;
+
+ if(pyld_eth_len != 0) {
+ /* check for LLC layer with SNAP extension */
+ if(packet[ip_offset] == SNAP) {
+ llc = (struct ndpi_llc_header *)(&packet[ip_offset]);
+ type = llc->snap.proto_ID;
+ ip_offset += + 8;
+ }
+ }
+ break;
+
+ /* Linux Cooked Capture - 113 */
+ case DLT_LINUX_SLL :
+ type = (packet[eth_offset+14] << 8) + packet[eth_offset+15];
+ ip_offset = 16 + eth_offset;
+ break;
+
+ /* Radiotap link-layer - 127 */
+ case DLT_IEEE802_11_RADIO :
+ radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset];
+ radio_len = radiotap->len;
+
+ /* Check Bad FCS presence */
+ if((radiotap->flags & BAD_FCS) == BAD_FCS) {
+ workflow->stats.total_discarded_bytes += header->len;
+ return;
+ }
+
+ /* Calculate 802.11 header length (variable) */
+ wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len);
+ fc = wifi->fc;
+
+ /* check wifi data presence */
+ if(FCF_TYPE(fc) == WIFI_DATA) {
+ if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) ||
+ (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc)))
+ wifi_len = 26; /* + 4 byte fcs */
+ } else /* no data frames */
+ break;
+
+ /* Check ether_type from LLC */
+ llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len);
+ if(llc->dsap == SNAP)
+ type = ntohs(llc->snap.proto_ID);
+
+ /* Set IP header offset */
+ ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header) + eth_offset;
+ break;
+
+ case DLT_RAW:
+ ip_offset = eth_offset = 0;
+ break;
+
+ default:
+ /* printf("Unknown datalink %d\n", datalink_type); */
+ return;
+ }
+
+ /* check ether type */
+ switch(type) {
+ case VLAN:
+ vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF;
+ type = (packet[ip_offset+2] << 8) + packet[ip_offset+3];
+ ip_offset += 4;
+ vlan_packet = 1;
+ break;
+ case MPLS_UNI:
+ case MPLS_MULTI:
+ mpls = (struct ndpi_mpls_header *) &packet[ip_offset];
+ label = ntohl(mpls->label);
+ /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */
+ workflow->stats.mpls_count++;
+ type = ETH_P_IP, ip_offset += 4;
+
+ while((label & 0x100) != 0x100) {
+ ip_offset += 4;
+ label = ntohl(mpls->label);
+ }
+ break;
+ case PPPoE:
+ workflow->stats.pppoe_count++;
+ type = ETH_P_IP;
+ ip_offset += 8;
+ break;
+ default:
+ break;
+ }
+
+ workflow->stats.vlan_count += vlan_packet;
+
+ iph_check:
+ /* Check and set IP header size and total packet length */
+ iph = (struct ndpi_iphdr *) &packet[ip_offset];
+
+ /* just work on Ethernet packets that contain IP */
+ if(type == ETH_P_IP && header->caplen >= ip_offset) {
+ frag_off = ntohs(iph->frag_off);
+
+ proto = iph->protocol;
+ if(header->caplen < header->len) {
+ static u_int8_t cap_warning_used = 0;
+
+ if(cap_warning_used == 0) {
+ if(!workflow->prefs.quiet_mode)
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n");
+ cap_warning_used = 1;
+ }
+ }
+ }
+
+ if(iph->version == 4) {
+ ip_len = ((u_short)iph->ihl * 4);
+ iph6 = NULL;
+
+ if(iph->protocol == 41) {
+ ip_offset += ip_len;
+ goto iph_check;
+ }
+
+ if((frag_off & 0x1FFF) != 0) {
+ static u_int8_t ipv4_frags_warning_used = 0;
+ workflow->stats.fragmented_count++;
+
+ if(ipv4_frags_warning_used == 0) {
+ if(!workflow->prefs.quiet_mode)
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n");
+ ipv4_frags_warning_used = 1;
+ }
+
+ workflow->stats.total_discarded_bytes += header->len;
+ return;
+ }
+ } else if(iph->version == 6) {
+ iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset];
+ proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
+ ip_len = sizeof(struct ndpi_ipv6hdr);
+
+ if(proto == 0x3C /* IPv6 destination option */) {
+
+ u_int8_t *options = (u_int8_t*)&packet[ip_offset+ip_len];
+ proto = options[0];
+ ip_len += 8 * (options[1] + 1);
+ }
+ iph = NULL;
+
+ } else {
+ static u_int8_t ipv4_warning_used = 0;
+
+ v4_warning:
+ if(ipv4_warning_used == 0) {
+ if(!workflow->prefs.quiet_mode)
+ NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI supports both IPv4 and IPv6), all other packets will be discarded\n\n");
+ ipv4_warning_used = 1;
+ }
+ workflow->stats.total_discarded_bytes += header->len;
+ return;
+ }
+
+ if(workflow->prefs.decode_tunnels && (proto == IPPROTO_UDP)) {
+ struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len];
+ u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest);
+
+ if((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) {
+ /* Check if it's GTPv1 */
+ u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
+ u_int8_t flags = packet[offset];
+ u_int8_t message_type = packet[offset+1];
+
+ if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) &&
+ (message_type == 0xFF /* T-PDU */)) {
+
+ ip_offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr)+8; /* GTPv1 header len */
+ if(flags & 0x04) ip_offset += 1; /* next_ext_header is present */
+ if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */
+ if(flags & 0x01) ip_offset += 1; /* pdu_number is present */
+
+ iph = (struct ndpi_iphdr *) &packet[ip_offset];
+
+ if(iph->version != 4) {
+ // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count);
+ goto v4_warning;
+ }
+ }
+ } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) {
+ /* https://en.wikipedia.org/wiki/TZSP */
+ u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr);
+ u_int8_t version = packet[offset];
+ u_int8_t type = packet[offset+1];
+ u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2]));
+
+ if((version == 1) && (type == 0) && (encapsulates == 1)) {
+ u_int8_t stop = 0;
+
+ offset += 4;
+
+ while((!stop) && (offset < header->caplen)) {
+ u_int8_t tag_type = packet[offset];
+ u_int8_t tag_len;
+
+ switch(tag_type) {
+ case 0: /* PADDING Tag */
+ tag_len = 1;
+ break;
+ case 1: /* END Tag */
+ tag_len = 1, stop = 1;
+ break;
+ default:
+ tag_len = packet[offset+1];
+ break;
+ }
+
+ offset += tag_len;
+
+ if(offset >= header->caplen)
+ return; /* Invalid packet */
+ else {
+ eth_offset = offset;
+ goto datalink_check;
+ }
+ }
+ }
+ }
+ }
+
+ /* process the packet */
+ packet_processing(workflow, time, vlan_id, iph, iph6,
+ ip_offset, header->len - ip_offset, header->len);
+}
diff --git a/example/ndpi_util.h b/example/ndpi_util.h
new file mode 100644
index 000000000..7b1450774
--- /dev/null
+++ b/example/ndpi_util.h
@@ -0,0 +1,151 @@
+/*
+ * ndpi_util.h
+ *
+ * Copyright (C) 2011-16 - ntop.org
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * This module contains routines to help setup a simple nDPI program.
+ *
+ * If you concern about performance or have to integrate nDPI in your
+ * application, you could need to reimplement them yourself.
+ *
+ * WARNING: this API is unstable! Use it at your own risk!
+ */
+
+#ifndef __NDPI_UTIL_H__
+#define __NDPI_UTIL_H__
+
+#include <pcap.h>
+
+#define MAX_NUM_READER_THREADS 16
+#define IDLE_SCAN_PERIOD 10 /* msec (use TICK_RESOLUTION = 1000) */
+#define MAX_IDLE_TIME 30000
+#define IDLE_SCAN_BUDGET 1024
+#define NUM_ROOTS 512
+#define MAX_NDPI_FLOWS 200000000
+#define TICK_RESOLUTION 1000
+
+
+// flow tracking
+typedef struct ndpi_flow_info {
+ u_int32_t lower_ip;
+ u_int32_t upper_ip;
+ u_int16_t lower_port;
+ u_int16_t upper_port;
+ u_int8_t detection_completed, protocol;
+ u_int16_t vlan_id;
+ struct ndpi_flow_struct *ndpi_flow;
+ char lower_name[48], upper_name[48];
+ u_int8_t ip_version;
+ u_int64_t last_seen;
+ u_int64_t bytes;
+ u_int32_t packets;
+
+ // result only, not used for flow identification
+ ndpi_protocol detected_protocol;
+
+ char host_server_name[192];
+ char bittorent_hash[41];
+
+ struct {
+ char client_certificate[48], server_certificate[48];
+ } ssl;
+
+ void *src_id, *dst_id;
+} ndpi_flow_info_t;
+
+typedef struct ndpi_stats {
+ u_int32_t guessed_flow_protocols;
+ u_int64_t raw_packet_count;
+ u_int64_t ip_packet_count;
+ u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes;
+ u_int64_t protocol_counter[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1];
+ u_int64_t protocol_counter_bytes[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1];
+ u_int32_t protocol_flows[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1];
+ u_int32_t ndpi_flow_count;
+ u_int64_t tcp_count, udp_count;
+ u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count;
+ u_int64_t packet_len[6];
+ u_int16_t max_packet_len;
+} ndpi_stats_t;
+
+typedef struct ndpi_workflow_prefs {
+ u_int8_t decode_tunnels;
+ u_int8_t quiet_mode;
+ u_int32_t num_roots;
+ u_int32_t max_ndpi_flows;
+} ndpi_workflow_prefs_t;
+
+struct ndpi_workflow;
+/** workflow, flow, user data */
+typedef void (*ndpi_workflow_callback_ptr) (struct ndpi_workflow *, struct ndpi_flow_info *, void *);
+
+typedef struct ndpi_workflow {
+ u_int64_t last_time;
+
+ struct ndpi_workflow_prefs prefs;
+ struct ndpi_stats stats;
+
+ ndpi_workflow_callback_ptr __flow_detected_callback;
+ void * __flow_detected_udata;
+ ndpi_workflow_callback_ptr __flow_giveup_callback;
+ void * __flow_giveup_udata;
+
+ /* outside referencies */
+ pcap_t *pcap_handle;
+
+ /* allocated by prefs */
+ void **ndpi_flows_root;
+ struct ndpi_detection_module_struct *ndpi_struct;
+} ndpi_workflow_t;
+
+/* TODO: remove wrappers parameters and use ndpi global, when their initialization will be fixed... */
+struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, pcap_t * pcap_handle);
+
+void ndpi_workflow_free(struct ndpi_workflow * workflow);
+
+/** Free flow_info ndpi support structures but not the flow_info itself
+ *
+ * TODO remove! Half freeing things is bad!
+ */
+void ndpi_free_flow_info_half(struct ndpi_flow_info *flow);
+
+/** Process a @packet and update the @workflow. */
+void ndpi_workflow_process_packet (struct ndpi_workflow * workflow,
+ const struct pcap_pkthdr *header,
+ const u_char *packet);
+
+/* flow callbacks: ndpi_flow_info will be freed right after */
+static inline void ndpi_workflow_set_flow_detected_callback(struct ndpi_workflow * workflow,
+ ndpi_workflow_callback_ptr callback,
+ void * udata) {
+ workflow->__flow_detected_callback = callback;
+ workflow->__flow_detected_udata = udata;
+}
+
+static inline void ndpi_workflow_set_flow_giveup_callback(struct ndpi_workflow * workflow,
+ ndpi_workflow_callback_ptr callback,
+ void * udata) {
+ workflow->__flow_giveup_callback = callback;
+ workflow->__flow_giveup_udata = udata;
+}
+
+int ndpi_workflow_node_cmp(const void *a, const void *b);
+
+
+#endif
diff --git a/libndpi.sym b/libndpi.sym
index 7fd2f920d..da21e64fd 100644
--- a/libndpi.sym
+++ b/libndpi.sym
@@ -1,4 +1,6 @@
ndpi_dump_protocols
+ndpi_strnstr
+ndpi_detection_giveup
ndpi_get_proto_name
ndpi_free
ndpi_guess_undetected_protocol
@@ -27,6 +29,7 @@ ndpi_free_flow
ndpi_get_proto_breed
ndpi_get_proto_breed_name
ndpi_get_proto_by_id
+ndpi_get_proto_by_name
ndpi_get_protocol_id_master_proto
ndpi_guess_protocol_id
ndpi_protocol2name
@@ -36,3 +39,11 @@ ndpi_malloc
ndpi_calloc
ndpi_set_detected_protocol
ndpi_match_string_subprotocol
+ndpi_init_automa
+ndpi_free_automa
+ndpi_add_string_to_automa
+ndpi_finalize_automa
+ndpi_match_string
+set_ndpi_malloc
+set_ndpi_free
+set_ndpi_debug_function \ No newline at end of file
diff --git a/packages/homebrew/ndpi.rb b/packages/homebrew/ndpi.rb
index d7c17f500..a3ea00458 100644
--- a/packages/homebrew/ndpi.rb
+++ b/packages/homebrew/ndpi.rb
@@ -1,14 +1,15 @@
class Ndpi < Formula
desc "Deep Packet Inspection (DPI) library"
homepage "http://www.ntop.org/products/ndpi/"
- url "https://downloads.sourceforge.net/project/ntop/nDPI/nDPI-1.7.tar.gz"
- sha256 "714b745103a072462130b0e14cf31b2eb5270f580b7c839da5cf5ea75150262d"
+ url "https://downloads.sourceforge.net/project/ntop/nDPI/nDPI-1.8.tgz"
+ sha256 "f490137a7387b69d0d55e990f2150b86d7b5eaae870e5326e8c2f18c17412443"
bottle do
cellar :any
- sha256 "e9464d314479ba3e7a91422e0bc606cfd5f6e72e94d6441cc4fa30e9c925da5c" => :yosemite
- sha256 "1d6b1d860669b42766baa276ed948c342e2fa4fd28663ba64a90fd0e200ba9c4" => :mavericks
- sha256 "b814918b4fb9588de7126061ce4ac3eb41a5c3eee27c7432b669f6dc6921bfde" => :mountain_lion
+ sha256 "05053767fc3c70557745c348c7352e7c2716c040ca54c5cf8d5306167c878fcb" => :el_capitan
+ sha256 "34c0269039a0079820eeed862daa28158d9291f73f640a9415da60746d69a662" => :yosemite
+ sha256 "a2af4dc62c24313593b3a20e45ca9d2d49f8efc0ea5e52fd064001ea441b93e4" => :mavericks
+ sha256 "1bb200268a4d9df9bbe5d33bc773ee3bcf4b5d4fa00c76a040f16318438c284f" => :mountain_lion
end
depends_on "autoconf" => :build
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h
index a07c96e63..737e29cb9 100644
--- a/src/include/ndpi_api.h
+++ b/src/include/ndpi_api.h
@@ -115,22 +115,14 @@ extern "C" {
*
*/
void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_match *match);
-
/**
* Returns a new initialized detection module
*
- * @par ticks_per_second = the timestamp resolution per second (like 1000 for millisecond resolution)
- * @par __ndpi_malloc = function pointer to a nDPI memory allocator
- * @par ndpi_debug_printf = function pointer to a nDPI debug output function (use NULL in productive envionments)
* @return the initialized detection module
*
*/
- struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second,
- void* (*__ndpi_malloc)(size_t size),
- void (*__ndpi_free)(void *ptr),
- ndpi_debug_function_ptr ndpi_debug_printf);
-
+ struct ndpi_detection_module_struct *ndpi_init_detection_module();
/**
* Frees the memory allocated in the specified flow
@@ -157,10 +149,9 @@ extern "C" {
* Destroys the detection module
*
* @par ndpi_struct = the struct to clearing for the detection module
- * @par ndpi_free = function pointer to a nDPI memory free function
*
*/
- void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct, void (*ndpi_free) (void *ptr));
+ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct);
/**
@@ -233,6 +224,52 @@ extern "C" {
struct ndpi_id_struct *src,
struct ndpi_id_struct *dst);
+
+ /**
+ * Processes one packet of L4 and returns the ID of the detected protocol.
+ * L3 and L4 packet headers are passed in the arguments while payload
+ * points to the L4 body.
+ * This function mimics ndpi_detection_process_packet behaviour.
+ *
+ * @par ndpi_struct = the detection module
+ * @par flow = pointer to the connection state machine
+ * @par iph = IP packet header for IPv4 or NULL
+ * @par iph6 = IP packet header for IPv6 or NULL
+ * @par tcp = TCP packet header for TCP or NULL
+ * @par udp = UDP packet header for UDP or NULL
+ * @par src_to_dst_direction = order of src/dst state machines in a flow.
+ * @par l4_proto = L4 protocol of the packet.
+ * @par src = pointer to the source subscriber state machine
+ * @par dst = pointer to the destination subscriber state machine
+ * @par sport = source port of L4 packet, used for protocol guessing.
+ * @par dport = destination port of L4 packet, used for protocol guessing.
+ * @par current_tick_l = the current timestamp for the packet
+ * @par payload = unsigned char pointer to the Layer 4 (TCP/UDP body)
+ * @par payload_len = the length of the payload
+ * @return the detected ID of the protocol
+ *
+ * NOTE: in a current implementation flow->src and flow->dst are swapped with
+ * the src_to_dst_direction flag while ndpi_detection_process_packet does not swap
+ * these values.
+ *
+ */
+
+ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ const struct ndpi_iphdr *iph,
+ struct ndpi_ipv6hdr *iph6,
+ struct ndpi_tcphdr *tcp,
+ struct ndpi_udphdr *udp,
+ u_int8_t src_to_dst_direction,
+ u_int8_t l4_proto,
+ struct ndpi_id_struct *src,
+ u_int16_t sport,
+ struct ndpi_id_struct *dst,
+ u_int16_t dport,
+ const u_int64_t current_tick_l,
+ u_int8_t *payload, u_int16_t payload_len);
+
+
/**
* Get the main protocol of the passed flows for the detected module
@@ -544,6 +581,61 @@ extern "C" {
struct ndpi_flow_struct *flow, char *certificate);
#endif
+ /* Wrappers functions */
+ /**
+ * Init Aho-Corasick automata
+ *
+ * @return The requested automata, or NULL if an error occurred
+ *
+ */
+ void* ndpi_init_automa();
+
+
+ /**
+ * Free Aho-Corasick automata allocated with ndpi_init_automa();
+ *
+ * @par The automata initialized with ndpi_init_automa();
+ *
+ */
+ void ndpi_free_automa(void *_automa);
+
+
+ /**
+ * Add a string to match to an automata
+ *
+ * @par The automata initialized with ndpi_init_automa();
+ * @par The (sub)string to search
+ * @return 0 in case of no error, or -1 if an error occurred.
+ *
+ */
+ int ndpi_add_string_to_automa(void *_automa, char *str);
+
+
+ /**
+ * Finalize the automa (necessary before start searching)
+ *
+ * @par The automata initialized with ndpi_init_automa();
+ *
+ */
+ void ndpi_finalize_automa(void *_automa);
+
+
+ /**
+ * Add a string to match to an automata
+ *
+ * @par The automata initialized with ndpi_init_automa();
+ * @par The (sub)string to search
+ * @return 0 in case of match, or -1 if no match, or -2 if an error occurred.
+ *
+ */
+ int ndpi_match_string(void *_automa, char *string_to_match);
+
+
+ /* Utility functions to set ndpi malloc/free/print wrappers */
+ void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size));
+ void set_ndpi_free(void (*__ndpi_free)(void *ptr));
+ void set_ndpi_debug_function(ndpi_debug_function_ptr ndpi_debug_printf);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/include/ndpi_define.h b/src/include/ndpi_define.h
index 3fa0b34e6..cc237128a 100644
--- a/src/include/ndpi_define.h
+++ b/src/include/ndpi_define.h
@@ -1,7 +1,6 @@
/*
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -77,7 +76,7 @@
#endif
-#define NDPI_USE_ASYMMETRIC_DETECTION 0
+#define NDPI_USE_ASYMMETRIC_DETECTION 0
#define NDPI_SELECTION_BITMASK_PROTOCOL_SIZE u_int32_t
#define NDPI_SELECTION_BITMASK_PROTOCOL_IP (1<<0)
@@ -160,24 +159,24 @@
/* TODO: rebuild all memory areas to have a more aligned memory block here */
/* DEFINITION OF MAX LINE NUMBERS FOR line parse algorithm */
-#define NDPI_MAX_PARSE_LINES_PER_PACKET 64
+#define NDPI_MAX_PARSE_LINES_PER_PACKET 64
#define MAX_PACKET_COUNTER 65000
#define MAX_DEFAULT_PORTS 5
#define NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT 600
#define NDPI_IRC_CONNECTION_TIMEOUT 120
-#define NDPI_GNUTELLA_CONNECTION_TIMEOUT 60
-#define NDPI_BATTLEFIELD_CONNECTION_TIMEOUT 60
-#define NDPI_THUNDER_CONNECTION_TIMEOUT 30
-#define NDPI_RTSP_CONNECTION_TIMEOUT 5
-#define NDPI_TVANTS_CONNECTION_TIMEOUT 5
-#define NDPI_YAHOO_DETECT_HTTP_CONNECTIONS 1
-#define NDPI_YAHOO_LAN_VIDEO_TIMEOUT 30
+#define NDPI_GNUTELLA_CONNECTION_TIMEOUT 60
+#define NDPI_BATTLEFIELD_CONNECTION_TIMEOUT 60
+#define NDPI_THUNDER_CONNECTION_TIMEOUT 30
+#define NDPI_RTSP_CONNECTION_TIMEOUT 5
+#define NDPI_TVANTS_CONNECTION_TIMEOUT 5
+#define NDPI_YAHOO_DETECT_HTTP_CONNECTIONS 1
+#define NDPI_YAHOO_LAN_VIDEO_TIMEOUT 30
#define NDPI_ZATTOO_CONNECTION_TIMEOUT 120
-#define NDPI_ZATTOO_FLASH_TIMEOUT 5
-#define NDPI_JABBER_STUN_TIMEOUT 30
-#define NDPI_JABBER_FT_TIMEOUT 5
+#define NDPI_ZATTOO_FLASH_TIMEOUT 5
+#define NDPI_JABBER_STUN_TIMEOUT 30
+#define NDPI_JABBER_FT_TIMEOUT 5
#define NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT 600
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
diff --git a/src/include/ndpi_includes.h b/src/include/ndpi_includes.h
index ce36a25f9..f77f8cfc4 100644
--- a/src/include/ndpi_includes.h
+++ b/src/include/ndpi_includes.h
@@ -1,7 +1,7 @@
/*
* ndpi_includes.h
*
- * Copyright (C) 2011-15 - ntop.org
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -35,6 +35,7 @@
#ifdef WIN32
#include "ndpi_win32.h"
#else
+#include <sys/types.h>
#include <sys/param.h>
#include <pthread.h>
#include <arpa/inet.h>
diff --git a/src/include/ndpi_main.h b/src/include/ndpi_main.h
index a70f35c8d..43bd4e2bb 100644
--- a/src/include/ndpi_main.h
+++ b/src/include/ndpi_main.h
@@ -1,8 +1,7 @@
/*
* ndpi_main.h
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -32,79 +31,99 @@
#include "ndpi_protocols.h"
#include "ndpi_api.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
-void *ndpi_tdelete(const void * __restrict, void ** __restrict,
- int (*)(const void *, const void *));
-void *ndpi_tfind(const void *, void *, int (*)(const void *, const void *));
-void *ndpi_tsearch(const void *, void**, int (*)(const void *, const void *));
-void ndpi_twalk(const void *, void (*)(const void *, ndpi_VISIT, int, void*), void *user_data);
-void ndpi_tdestroy(void *vrootp, void (*freefct)(void *));
+ void *ndpi_tdelete(const void * __restrict, void ** __restrict,
+ int (*)(const void *, const void *));
+ void *ndpi_tfind(const void *, void *, int (*)(const void *, const void *));
+ void *ndpi_tsearch(const void *, void**, int (*)(const void *, const void *));
+ void ndpi_twalk(const void *, void (*)(const void *, ndpi_VISIT, int, void*), void *user_data);
+ void ndpi_tdestroy(void *vrootp, void (*freefct)(void *));
-int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b);
-int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a);
-void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a);
+ int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b);
+ int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a);
+ void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a);
-extern u_int8_t ndpi_net_match(u_int32_t ip_to_check,
- u_int32_t net,
- u_int32_t num_bits);
+ extern u_int8_t ndpi_net_match(u_int32_t ip_to_check,
+ u_int32_t net,
+ u_int32_t num_bits);
-extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst,
- u_int32_t net, u_int32_t num_bits);
+ extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst,
+ u_int32_t net, u_int32_t num_bits);
-u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
+ u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
-u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
-u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
-u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
-u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
-u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
+ u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
+ u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
+ u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
+ u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
+ u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read);
-void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol,
- u_int16_t lower_detected_protocol);
+ void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol,
+ u_int16_t lower_detected_protocol);
-extern void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
-extern void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+ extern void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+ extern void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
-extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t counter);
+ extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t counter);
-extern void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol,
- u_int16_t lower_detected_protocol);
-extern void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
- u_int16_t upper_detected_protocol,
- u_int16_t lower_detected_protocol);
-extern void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_breed_t protoBreed, u_int16_t protoId,
- u_int16_t tcp_alias_protoId[2], u_int16_t udp_alias_protoId[2], char *protoName,
- ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts);
+ extern void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol,
+ u_int16_t lower_detected_protocol);
+ extern void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
+ u_int16_t upper_detected_protocol,
+ u_int16_t lower_detected_protocol);
+ extern void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_breed_t protoBreed, u_int16_t protoId,
+ u_int16_t tcp_alias_protoId[2], u_int16_t udp_alias_protoId[2], char *protoName,
+ ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts);
-extern void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet);
-extern void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow);
+ extern void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet);
+ extern void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow);
-extern int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip);
-extern int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip);
-extern void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip);
-extern void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip);
+ extern int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip);
+ extern int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip);
+ extern void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip);
+ extern void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip);
-extern char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const ndpi_ip_addr_t * ip);
-extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const struct ndpi_packet_struct *packet);
-extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id);
+ extern char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const ndpi_ip_addr_t * ip);
+ extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const struct ndpi_packet_struct *packet);
+ extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id);
+ u_int16_t ndpi_get_proto_by_name(struct ndpi_detection_module_struct *ndpi_mod, const char *name);
-extern u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
- u_int8_t proto, u_int16_t sport, u_int16_t dport);
+ extern u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t proto, u_int16_t sport, u_int16_t dport,
+ u_int8_t *user_defined_proto);
-extern u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto);
+ extern u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto);
-extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p);
-extern int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t protocol_id,
- u_int16_t** tcp_master_proto,
- u_int16_t** udp_master_proto);
+ extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p);
+ extern int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t protocol_id,
+ u_int16_t** tcp_master_proto,
+ u_int16_t** udp_master_proto);
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
-void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_struct,
- const char **file, const char **func, u_int32_t * line);
+ void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_struct,
+ const char **file, const char **func, u_int32_t * line);
+#endif
+
+ /** Checks when the @p payload starts with the string literal @p str.
+ * When the string is larger than the payload, check fails.
+ * @return non-zero if check succeeded
+ */
+ int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len,
+ const char *str, size_t str_len);
+
+ /* version of ndpi_match_prefix with string literal */
+#define ndpi_match_strprefix(payload, payload_len, str) \
+ ndpi_match_prefix((payload), (payload_len), (str), (sizeof(str)-1))
+
+#ifdef __cplusplus
+}
#endif
#endif /* __NDPI_MAIN_H__ */
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h
index cfc0ad56d..e4d40e9bb 100644
--- a/src/include/ndpi_protocol_ids.h
+++ b/src/include/ndpi_protocol_ids.h
@@ -1,8 +1,7 @@
/*
* ndpi_protocol_ids.h
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-11 - ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -199,10 +198,10 @@
#define NDPI_PROTOCOL_TELEGRAM 185 /* Gianluca Costa <g.costa@xplico.org> */
#define NDPI_PROTOCOL_QUIC 188 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> - Michele Campus <michelecampus5@gmail.com> */
#define NDPI_PROTOCOL_WHATSAPP_VOICE 189
-#define NDPI_PROTOCOL_STARCRAFT 213 /* Matteo Bracci <matteobracci1@gmail.com> */
-#define NDPI_PROTOCOL_TEREDO 214
-#define NDPI_PROTOCOL_HEP 216 /* Sipcapture.org QXIP BV */
-#define NDPI_PROTOCOL_UBNTAC2 217 /* Ubiquity UBNT AirControl 2 - Thomas Fjellstrom <thomas+ndpi@fjellstrom.ca> */
+#define NDPI_PROTOCOL_STARCRAFT 211 /* Matteo Bracci <matteobracci1@gmail.com> */
+#define NDPI_PROTOCOL_TEREDO 212
+#define NDPI_PROTOCOL_HEP 213 /* Sipcapture.org QXIP BV */
+#define NDPI_PROTOCOL_UBNTAC2 214 /* Ubiquity UBNT AirControl 2 - Thomas Fjellstrom <thomas+ndpi@fjellstrom.ca> */
#define NDPI_PROTOCOL_MS_LYNC 173
@@ -243,36 +242,32 @@
#define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow <tomasz@skatnet.dk> */
#define NDPI_SERVICE_PANDORA 187
#define NDPI_PROTOCOL_EAQ 190
-#define NDPI_SERVICE_TIMMEU 191
-#define NDPI_SERVICE_TORCEDOR 192
+#define NDPI_PROTOCOL_GIT 191
+#define NDPI_PROTOCOL_DRDA 192
#define NDPI_SERVICE_KAKAOTALK 193 /* KakaoTalk Chat (no voice call) */
#define NDPI_SERVICE_KAKAOTALK_VOICE 194 /* KakaoTalk Voice */
#define NDPI_SERVICE_TWITCH 195 /* Edoardo Dominici <edoaramis@gmail.com> */
#define NDPI_SERVICE_QUICKPLAY 196 /* Streaming service used by various services such as hooq.tv */
-#define NDPI_SERVICE_TIM 197 /* Traffic for tim.com.br and tim.it */
+#define NDPI_SERVICE_OPENDNS 197
#define NDPI_PROTOCOL_MPEGTS 198
#define NDPI_SERVICE_SNAPCHAT 199
-#define NDPI_SERVICE_SIMET 200
-#define NDPI_SERVICE_OPENSIGNAL 201
-#define NDPI_SERVICE_99TAXI 202
-#define NDPI_SERVICE_EASYTAXI 203
-#define NDPI_SERVICE_GLOBOTV 204
-#define NDPI_SERVICE_TIMSOMDECHAMADA 205
-#define NDPI_SERVICE_TIMMENU 206
-#define NDPI_SERVICE_TIMPORTASABERTAS 207
-#define NDPI_SERVICE_TIMRECARGA 208
-#define NDPI_SERVICE_TIMBETA 209
-#define NDPI_SERVICE_DEEZER 210
-#define NDPI_SERVICE_INSTAGRAM 211 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> */
-#define NDPI_SERVICE_MICROSOFT 212
-#define NDPI_SERVICE_HOTSPOT_SHIELD 215
-#define NDPI_SERVICE_OCS 218
-#define NDPI_SERVICE_OFFICE_365 219
-#define NDPI_SERVICE_CLOUDFLARE 220
-#define NDPI_SERVICE_MS_ONE_DRIVE 221
-#define NDPI_PROTOCOL_MQTT 222
+#define NDPI_SERVICE_DEEZER 200
+#define NDPI_SERVICE_INSTAGRAM 201 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> */
+#define NDPI_SERVICE_MICROSOFT 202
+#define NDPI_SERVICE_HOTSPOT_SHIELD 203
+#define NDPI_SERVICE_OCS 204
+#define NDPI_SERVICE_OFFICE_365 205
+#define NDPI_SERVICE_CLOUDFLARE 206
+#define NDPI_SERVICE_MS_ONE_DRIVE 207
+#define NDPI_PROTOCOL_MQTT 208
+#define NDPI_PROTOCOL_RX 209
+#define NDPI_SERVICE_WEIBO 210
+#define NDPI_SERVICE_HANGOUT 215
+#define NDPI_SERVICE_SLACK 216
+#define NDPI_SERVICE_HOTMAIL 217
+
/* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE */
-#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_PROTOCOL_MQTT
+#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_SERVICE_HOTMAIL
#define NDPI_MAX_SUPPORTED_PROTOCOLS (NDPI_LAST_IMPLEMENTED_PROTOCOL + 1)
#define NDPI_MAX_NUM_CUSTOM_PROTOCOLS (NDPI_NUM_BITS-NDPI_LAST_IMPLEMENTED_PROTOCOL)
diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h
index b5df1c937..12f3a0dbd 100644
--- a/src/include/ndpi_protocols.h
+++ b/src/include/ndpi_protocols.h
@@ -1,8 +1,7 @@
/*
* ndpi_protocols.h
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -53,10 +52,6 @@ void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, st
/* Applications and other protocols. */
void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
-void ndpi_bittorrent_init(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t size,u_int32_t timeout);
-void ndpi_bittorrent_done(struct ndpi_detection_module_struct *ndpi_struct);
-int ndpi_bittorrent_gc(struct hash_ip4p_table *ht,int key,time_t now);
-
void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_fasttrack_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
@@ -198,6 +193,9 @@ void ndpi_search_starcraft(struct ndpi_detection_module_struct *ndpi_struct, str
void ndpi_search_ubntac2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_coap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+void ndpi_search_rx(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+void ndpi_search_git(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+void ndpi_search_drda(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
/* --- INIT FUNCTIONS --- */
void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_aimini_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
@@ -337,4 +335,8 @@ void init_stracraft_dissector(struct ndpi_detection_module_struct *ndpi_struct,
void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_coap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_mqtt_dissector (struct ndpi_detection_module_struct *ndpi_struct,u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
+void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
+void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
+void init_hangout_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
+void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
#endif /* __NDPI_PROTOCOLS_H__ */
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index ed74b9a07..9a50b65fd 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -1,8 +1,7 @@
/*
* ndpi_typedefs.h
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-11 - ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -555,7 +554,7 @@ struct ndpi_flow_tcp_struct {
u_int32_t mail_pop_stage:2;
#endif
#ifdef NDPI_PROTOCOL_MAIL_IMAP
- u_int32_t mail_imap_stage:3;
+ u_int32_t mail_imap_stage:3, mail_imap_starttls:2;
#endif
#ifdef NDPI_PROTOCOL_SKYPE
u_int8_t skype_packet_id;
@@ -622,6 +621,10 @@ struct ndpi_flow_udp_struct {
u_int8_t eaq_pkt_id;
u_int32_t eaq_sequence;
#endif
+#ifdef NDPI_PROTOCOL_RX
+ u_int32_t rx_conn_epoch;
+ u_int32_t rx_conn_id;
+#endif
}
#ifndef WIN32
__attribute__ ((__packed__))
@@ -734,6 +737,7 @@ typedef struct ndpi_proto_defaults {
typedef struct ndpi_default_ports_tree_node {
ndpi_proto_defaults_t *proto;
+ u_int8_t customUserProto;
u_int16_t default_port;
} ndpi_default_ports_tree_node_t;
@@ -749,7 +753,7 @@ typedef struct ndpi_proto {
#define NDPI_PROTOCOL_NULL { NDPI_PROTOCOL_UNKNOWN , NDPI_PROTOCOL_UNKNOWN }
struct ndpi_detection_module_struct {
-
+
NDPI_PROTOCOL_BITMASK detection_bitmask;
NDPI_PROTOCOL_BITMASK generic_http_packet_bitmask;
@@ -802,7 +806,7 @@ struct ndpi_detection_module_struct {
content_automa, /* Used for HTTP subprotocol_detection */
subprotocol_automa, /* Used for HTTP subprotocol_detection */
bigrams_automa, impossible_bigrams_automa; /* TOR */
-
+
/* IP-based protocol detection */
void *protocols_ptree;
@@ -846,8 +850,8 @@ struct ndpi_detection_module_struct {
ndpi_proto_defaults_t proto_defaults[NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS];
- u_int8_t http_dont_dissect_response:1;
- u_int8_t direction_detect_disable:1; /* disable internal detection of packet direction */
+ u_int8_t http_dont_dissect_response:1, dns_dissect_response:1,
+ direction_detect_disable:1; /* disable internal detection of packet direction */
};
struct ndpi_flow_struct {
@@ -908,10 +912,10 @@ struct ndpi_flow_struct {
/* the only fields useful for nDPI and ntopng */
struct {
- u_int8_t num_answers, ret_code;
- u_int16_t query_type;
+ u_int8_t num_queries, num_answers, reply_code;
+ u_int16_t query_type, query_class, rsp_type;
} dns;
-
+
struct {
u_int8_t request_code;
u_int8_t version;
@@ -1002,6 +1006,10 @@ struct ndpi_flow_struct {
#ifdef NDPI_PROTOCOL_STARCRAFT
u_int32_t starcraft_udp_stage : 3; // 0-7
#endif
+#ifdef NDPI_PROTOCOL_OPENVPN
+ u_int8_t ovpn_session_id[8];
+ u_int8_t ovpn_counter;
+#endif
/* internal structures to save functions calls */
struct ndpi_packet_struct packet;
diff --git a/src/include/ndpi_unix.h b/src/include/ndpi_unix.h
index b680d3c30..6e6987bfd 100644
--- a/src/include/ndpi_unix.h
+++ b/src/include/ndpi_unix.h
@@ -1,8 +1,7 @@
/*
* ndpi_unix.h
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
diff --git a/src/include/ndpi_win32.h b/src/include/ndpi_win32.h
index 645c022e5..876e59c05 100644
--- a/src/include/ndpi_win32.h
+++ b/src/include/ndpi_win32.h
@@ -1,8 +1,7 @@
/*
* ndpi_win32.h
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-2011 by ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index abda7ede1..b920d4d67 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -26,6 +26,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/bittorrent.c \
protocols/ciscovpn.c \
protocols/citrix.c \
+ protocols/coap.c \
protocols/collectd.c \
protocols/corba.c \
protocols/crossfire.c \
@@ -36,6 +37,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/directdownloadlink.c \
protocols/dns.c \
protocols/dofus.c \
+ protocols/drda.c \
protocols/dropbox.c \
protocols/eaq.c \
protocols/edonkey.c \
@@ -45,9 +47,11 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/florensia.c \
protocols/ftp_control.c \
protocols/ftp_data.c \
+ protocols/git.c \
protocols/gnutella.c \
protocols/gtp.c \
protocols/guildwars.c \
+ protocols/hangout.c \
protocols/h323.c \
protocols/halflife2_and_mods.c \
protocols/hep.c \
@@ -74,6 +78,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/mgcp.c \
protocols/mms.c \
protocols/mpegts.c \
+ protocols/mqtt.c \
protocols/msn.c \
protocols/mssql.c \
protocols/mysql.c \
@@ -104,6 +109,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/rtmp.c \
protocols/rtp.c \
protocols/rtsp.c \
+ protocols/rx.c \
protocols/sflow.c \
protocols/shoutcast.c \
protocols/sip.c \
@@ -152,12 +158,13 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/yahoo.c \
protocols/zattoo.c \
protocols/zeromq.c \
- protocols/coap.c \
- protocols/mqtt.c \
third_party/include/actypes.h \
third_party/include/ahocorasick.h \
+ third_party/include/ndpi_patricia.h \
third_party/include/node.h \
third_party/include/sort.h \
third_party/src/ahocorasick.c \
third_party/src/node.c \
third_party/src/sort.c
+
+EXTRA_DIST = third_party/src/ndpi_patricia.c
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index 915df390f..fc5c35029 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -1,7 +1,7 @@
/*
* ndpi_content_match.c
*
- * Copyright (C) 2011-15 - ntop.org
+ * Copyright (C) 2011-16 - ntop.org
*
* nDPI is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -22,7 +22,13 @@
static ndpi_network host_protocol_list[] = {
- /*
+ /*
+ OpenDNS
+ 208.67.216.0/21
+ */
+ { 0xD043D800 /* 208.67.216.0/21 */, 21, NDPI_SERVICE_OPENDNS },
+
+ /*
Microsoft Corporation (MS One Drive)
204.79.195.0/24
204.79.196.0/23
@@ -40,7 +46,6 @@ static ndpi_network host_protocol_list[] = {
{ 0x83FD1200 /* 131.253.18.0/24 */, 24, NDPI_SERVICE_MS_ONE_DRIVE },
{ 0x4136BF00 /* 65.54.191.0/24 */, 24, NDPI_SERVICE_MS_ONE_DRIVE },
-
/*
Amazon-EU-AWS Elastic Compute Cloud, EC2 (also used by Netflix)
46.137.128.0/18
@@ -149,17 +154,29 @@ static ndpi_network host_protocol_list[] = {
/*
Skype (Microsoft CDN)
- 157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15
+ 157.56.135.64/26, 157.56.185.0/26, 157.56.52.0/26,
+ 157.56.53.128/25, 157.56.198.0/26
+ 157.60.0.0/16, 157.54.0.0/15
+ 13.107.3.128/32
+ 13.107.3.129/32
111.221.64.0 - 111.221.127.255
91.190.216.0/21 (AS198015 Skype Communications Sarl)
40.126.129.109/32
+ 65.55.223.0/26
*/
- { 0x9D380000 /* 157.56.0.0 */, 14, NDPI_PROTOCOL_SKYPE },
+ { 0x9D388740 /* 157.56.135.64 */, 26, NDPI_PROTOCOL_SKYPE },
+ { 0x9D38B900 /* 157.56.185.0 */, 26, NDPI_PROTOCOL_SKYPE },
+ { 0x9D383400 /* 157.56.52.0 */, 26, NDPI_PROTOCOL_SKYPE },
+ { 0x9D383580 /* 157.56.53.128 */, 25, NDPI_PROTOCOL_SKYPE },
+ { 0x9D38C600 /* 157.56.198.0 */, 26, NDPI_PROTOCOL_SKYPE },
{ 0x9D3C0000 /* 157.60.0.0 */, 16, NDPI_PROTOCOL_SKYPE },
{ 0x9D360000 /* 157.54.0.0 */, 15, NDPI_PROTOCOL_SKYPE },
+ { 0x0D6B0380 /* 13.107.3.128 */, 32, NDPI_PROTOCOL_SKYPE },
+ { 0x0D6B0381 /* 13.107.3.129 */, 32, NDPI_PROTOCOL_SKYPE },
{ 0x6FDD4000 /* 111.221.64.0 */, 18, NDPI_PROTOCOL_SKYPE },
{ 0x5BBED800 /* 91.190.216.0 */, 21, NDPI_PROTOCOL_SKYPE },
{ 0x287F816D /* 40.126.129.109 */, 32, NDPI_PROTOCOL_SKYPE },
+ { 0x4237DF00 /* 65.55.223.0 */, 26, NDPI_PROTOCOL_SKYPE },
/*
@@ -7226,9 +7243,6 @@ static ndpi_network host_protocol_list[] = {
{ 0xC709F98C, 32, NDPI_SERVICE_TWITCH },
{ 0xC709F9C5, 32, NDPI_SERVICE_TWITCH },
- /* Simet - 200.160.4.0/24 */
- { 0xC8A00400, 24, NDPI_SERVICE_SIMET },
-
/*
AnchorFree (Hotspot Shield)
AnchorFree Inc. AFNETWORK-1 (NET-74-115-0-0-1) 74.115.0.0 - 74.115.7.255
@@ -7253,6 +7267,7 @@ ndpi_protocol_match host_match[] = {
{ "images-amazon.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
{ "amazonaws.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
{ "amazon-adsystem.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".cloudfront.net", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE },
{ ".apple.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE },
{ ".mzstatic.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE },
{ ".icloud.com", "AppleiCloud", NDPI_SERVICE_APPLE_ICLOUD, NDPI_PROTOCOL_ACCEPTABLE },
@@ -7268,10 +7283,11 @@ ndpi_protocol_match host_match[] = {
{ ".ebayrtm.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE },
{ ".ebaystratus.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE },
{ ".ebayimg.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE },
- { ".facebook.com", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN },
+ { "facebook.com", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN },
{ "fbstatic-a.akamaihd.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN },
{ ".fbcdn.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN },
- { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */
+ { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */
+ { ".facebook.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN },
{ ".google.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
{ ".gstatic.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
{ ".googlesyndication.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
@@ -7284,10 +7300,12 @@ ndpi_protocol_match host_match[] = {
{ "googleadservices.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
{ "googleapis.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
{ "ggpht.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "1e100.net", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE },
{ "maps.google.", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE },
{ "maps.gstatic.com", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE },
{ ".gmail.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE },
{ "mail.google.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE },
+ { "mail.outlook.com", "Hotmail", NDPI_SERVICE_HOTMAIL, NDPI_PROTOCOL_SAFE },
{ ".last.fm", "LastFM", NDPI_SERVICE_LASTFM, NDPI_PROTOCOL_FUN },
{ "msn.com", "MSN", NDPI_SERVICE_MSN, NDPI_PROTOCOL_FUN },
{ "netflix.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN },
@@ -7316,6 +7334,7 @@ ndpi_protocol_match host_match[] = {
{ ".yimg.com", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE },
{ "yahooapis.", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE },
{ "youtube.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
+ { "yt3.ggpht.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
{ ".googlevideo.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
{ ".ytimg.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
{ "youtube-nocookie.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN },
@@ -7323,16 +7342,18 @@ ndpi_protocol_match host_match[] = {
{ ".spotify.", "Spotify", NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_FUN },
{ ".pandora.com", "Pandora", NDPI_SERVICE_PANDORA, NDPI_PROTOCOL_FUN },
{ ".torproject.org", "Tor", NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS },
- { "appmeutim.tim.com.br", "TIM_Meu", NDPI_SERVICE_TIMMEU, NDPI_PROTOCOL_ACCEPTABLE },
- { ".timtorcedor.com.br", "Torcedor", NDPI_SERVICE_TORCEDOR, NDPI_PROTOCOL_ACCEPTABLE },
{ ".kakao.com", "KakaoTalk", NDPI_SERVICE_KAKAOTALK, NDPI_PROTOCOL_FUN },
{ "ttvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN },
{ "static-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN },
{ "www-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN },
{ "quickplay.com", "QuickPlay", NDPI_SERVICE_QUICKPLAY, NDPI_PROTOCOL_FUN },
- { "tim.com.br", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE },
- { "tim.it", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE },
{ ".qq.com", "QQ", NDPI_PROTOCOL_QQ, NDPI_PROTOCOL_FUN },
+ { ".weibo.com", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN },
+ { ".sinaimg.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN },
+ { ".sinajs.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN },
+ { ".sina.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN },
+ { ".sina.com.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN },
+
/* https://support.cipafilter.com/index.php?/Knowledgebase/Article/View/117/0/snapchat---how-to-block */
{ "feelinsonice.appspot.com", "Snapchat", NDPI_SERVICE_SNAPCHAT, NDPI_PROTOCOL_FUN },
@@ -7348,17 +7369,6 @@ ndpi_protocol_match host_match[] = {
{ "instagramstatic-", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN },
{ ".waze.com", "Waze", NDPI_SERVICE_WAZE, NDPI_PROTOCOL_ACCEPTABLE },
- { "simet-", "Simet", NDPI_SERVICE_SIMET, NDPI_PROTOCOL_ACCEPTABLE },
- { "opensignal.com", "OpenSignal", NDPI_SERVICE_OPENSIGNAL, NDPI_PROTOCOL_ACCEPTABLE },
- { "99taxis.com", "99Taxi", NDPI_SERVICE_99TAXI, NDPI_PROTOCOL_ACCEPTABLE },
- { "easytaxis.com", "EasyTaxi", NDPI_SERVICE_EASYTAXI, NDPI_PROTOCOL_ACCEPTABLE },
- { ".globo.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE },
- { ".glbimg.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE },
- { "timsomdechamada.com.br", "SomDeChamada", NDPI_SERVICE_TIMSOMDECHAMADA, NDPI_PROTOCOL_ACCEPTABLE },
- { ".tim.acotelbr.com.br", "TIM_Menu", NDPI_SERVICE_TIMMENU, NDPI_PROTOCOL_ACCEPTABLE },
- { ".timbeta.com.br", "TIM_Beta", NDPI_SERVICE_TIMBETA, NDPI_PROTOCOL_ACCEPTABLE },
- { "tim-geoportal.geoportal3d.com.br", "TIM_PortasAbertas", NDPI_SERVICE_TIMPORTASABERTAS, NDPI_PROTOCOL_ACCEPTABLE },
- { ".m4u.com.br", "TIM_Recarga", NDPI_SERVICE_TIMRECARGA, NDPI_PROTOCOL_ACCEPTABLE },
{ ".deezer.com", "Deezer", NDPI_SERVICE_DEEZER, NDPI_PROTOCOL_ACCEPTABLE },
{ ".microsoft.com", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE },
@@ -7368,6 +7378,7 @@ ndpi_protocol_match host_match[] = {
{ ".msecnd.net", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE },
{ ".visualstudio.com", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE },
{ "bn1301.storage.live.com", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "*.gateway.messenger.live.com", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE },
{ "skyapi.live.net", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE },
{ "d.docs.live.net", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE },
{ "update.microsoft.com", "WindowsUpdate", NDPI_SERVICE_WINDOWS_UPDATE, NDPI_PROTOCOL_ACCEPTABLE },
@@ -7386,7 +7397,7 @@ ndpi_protocol_match host_match[] = {
{ "evsecure-ocsp.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
{ "evsecure-aia.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
{ "evsecure-crl.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
- { ".omniroot.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".omniroot.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
{ ".verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
{ ".symcb.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
{ ".symcd.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE },
@@ -7400,7 +7411,20 @@ ndpi_protocol_match host_match[] = {
{ "coby.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE },
{ "amanda.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE },
+ { "d295hzzivaok4k.cloudfront.net", "OpenDNS", NDPI_SERVICE_OPENDNS, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".opendns.com", "OpenDNS", NDPI_SERVICE_OPENDNS, NDPI_PROTOCOL_ACCEPTABLE },
+ /* https://get.slack.help/hc/en-us/articles/205138367-Troubleshooting-Slack-connection-issues */
+ { "slack.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".slack-msgs.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "slack-files.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "slack-imgs.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".slack-edge.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+ { ".slack-core.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+ { "slack-redir.net", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+ /* Detected "slack-assets2.s3-us-west-2.amazonaws.com.". Omitted "*amazonaws.com" CDN, but no generic pattern to use on first part */
+ { "slack-assets2.s3-", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE },
+
{ NULL, 0 }
};
@@ -7525,7 +7549,7 @@ static const char *ndpi_en_bigrams[] = {
static const char *ndpi_en_impossible_bigrams[] = {
"bk", "bq", "bx", "cb", "cf", "cg", "cj", "cp", "cv", "cw", "cx", "dx", "fk", "fq", "fv", "fx", "ee",
"fz", "gq", "gv", "gx", "hh", "hk", "hv", "hx", "hz", "iy", "jb", "jc", "jd", "jf", "jg", "jh", "jk",
- "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx",
+ "jl", "jm", "jn", "jp", "jq", "jr", /* "js", */ "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx",
"kz", "lq", "lx", "mg", "mj", "mq", "mx", "mz", "pq", "pv", "px", "qb", "qc", "qd", "qe", "qf", "ii",
"qg", "qh", "qj", "qk", "ql", "qm", "qn", "qo", "qp", "qr", "qs", "qt", "qv", "qw", "qx", "qy", "uu",
"qz", "sx", "sz", "tq", "tx", "vb", "vc", "vd", "vf", "vg", "vh", "vj", "vk", "vm", "vn", "vp", "bw",
@@ -7533,3 +7557,4 @@ static const char *ndpi_en_impossible_bigrams[] = {
"yj", "yq", "yv", "yz", "yw", "zb", "zc", "zg", "zh", "zj", "zn", "zq", "zr", "zs", "zx", "wh", "wk",
"wb", "zk", "kp", "zk", "xy",
NULL };
+
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 845c56c63..4224dd2d6 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1,8 +1,7 @@
/*
* ndpi_main.c
*
- * Copyright (C) 2011-15 - ntop.org
- * Copyright (C) 2009-11 - ipoque GmbH
+ * Copyright (C) 2011-16 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -303,13 +302,17 @@ strncasecmp(s1, s2, n)
/* Forward */
static void addDefaultPort(ndpi_port_range *range,
- ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root);
+ ndpi_proto_defaults_t *def,
+ u_int8_t customUserProto,
+ ndpi_default_ports_tree_node_t **root);
+
static int removeDefaultPort(ndpi_port_range *range,
- ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root);
+ ndpi_proto_defaults_t *def,
+ ndpi_default_ports_tree_node_t **root);
/* ****************************************** */
-void* ndpi_malloc(size_t size) { return(_ndpi_malloc(size)); }
+void* ndpi_malloc(size_t size) { return(_ndpi_malloc ? _ndpi_malloc(size) : malloc(size)); }
/* ****************************************** */
@@ -325,7 +328,7 @@ void* ndpi_calloc(unsigned long count, size_t size) {
/* ****************************************** */
-void ndpi_free(void *ptr) { _ndpi_free(ptr); }
+void ndpi_free(void *ptr) { if(_ndpi_free) _ndpi_free(ptr); else free(ptr); }
/* ****************************************** */
@@ -374,6 +377,18 @@ char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int
return((id >= ndpi_mod->ndpi_num_supported_protocols) ? NULL : ndpi_mod->proto_defaults[id].protoName);
}
+/* ****************************************************** */
+
+u_int16_t ndpi_get_proto_by_name(struct ndpi_detection_module_struct *ndpi_mod, const char *name) {
+ u_int16_t i, num = ndpi_get_num_supported_protocols(ndpi_mod);
+
+ for(i = 0; i < num; i++)
+ if(strcasecmp(ndpi_get_proto_by_id(ndpi_mod, i), name) == 0)
+ return(i);
+
+ return(NDPI_PROTOCOL_UNKNOWN);
+}
+
/* ******************************************************************** */
ndpi_port_range* ndpi_build_default_ports_range(ndpi_port_range *ports,
@@ -446,8 +461,8 @@ void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod,
memcpy(&ndpi_mod->proto_defaults[protoId].master_udp_protoId, udp_master_protoId, 2*sizeof(u_int16_t));
for(j=0; j<MAX_DEFAULT_PORTS; j++) {
- if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->udpRoot);
- if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->tcpRoot);
+ if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], 0, &ndpi_mod->udpRoot);
+ if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], 0, &ndpi_mod->tcpRoot);
}
}
@@ -480,12 +495,12 @@ void ndpi_default_ports_tree_node_t_walker(const void *node, const ndpi_VISIT wh
/* ******************************************************************** */
static void addDefaultPort(ndpi_port_range *range,
- ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root) {
+ ndpi_proto_defaults_t *def,
+ u_int8_t customUserProto,
+ ndpi_default_ports_tree_node_t **root) {
ndpi_default_ports_tree_node_t *ret;
u_int16_t port;
- // printf("[NDPI] %s(%d)\n", __FUNCTION__, port);
-
for(port=range->port_low; port<=range->port_high; port++) {
ndpi_default_ports_tree_node_t *node = (ndpi_default_ports_tree_node_t*)ndpi_malloc(sizeof(ndpi_default_ports_tree_node_t));
@@ -494,11 +509,11 @@ static void addDefaultPort(ndpi_port_range *range,
break;
}
- node->proto = def, node->default_port = port;
+ node->proto = def, node->default_port = port, node->customUserProto = customUserProto;
ret = *(ndpi_default_ports_tree_node_t**)ndpi_tsearch(node, (void*)root, ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */
if(ret != node) {
- printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port);
+ /* printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port); */
ret->proto = def;
ndpi_free(node);
@@ -551,7 +566,11 @@ static int ndpi_string_to_automa(struct ndpi_detection_module_struct *ndpi_struc
if(automa->ac_automa == NULL) return(-2);
ac_pattern.astring = value;
ac_pattern.rep.number = protocol_id;
- ac_pattern.length = strlen(ac_pattern.astring);
+ if(value == NULL)
+ ac_pattern.length = 0;
+ else
+ ac_pattern.length = strlen(ac_pattern.astring);
+
ac_automata_add(((AC_AUTOMATA_t*)automa->ac_automa), &ac_pattern);
return(0);
@@ -1359,9 +1378,14 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_QUIC,
no_master,
- no_master, "Quic",
+ no_master, "QUIC",
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 443, 80, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DROPBOX,
+ no_master,
+ no_master, "Dropbox",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 17500, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EAQ,
no_master,
no_master, "EAQ",
@@ -1451,43 +1475,43 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHOIS_DAS,
no_master,
no_master, "Whois-DAS",
- ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_COLLECTD,
no_master,
no_master, "Collectd",
- ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS,
no_master,
no_master, "SOCKS",
- ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TFTP,
no_master,
no_master, "TFTP",
- ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 69, 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 69, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTMP,
no_master,
no_master, "RTMP",
- ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PANDO,
no_master,
no_master, "Pando_Media_Booster",
- ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEGACO,
no_master,
no_master, "Megaco",
- ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_REDIS,
no_master,
no_master, "Redis",
- ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0) /* TCP */,
- ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */);
+ ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZMQ,
no_master,
no_master, "ZeroMQ",
@@ -1506,13 +1530,13 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_UBNTAC2,
no_master,
no_master, "UBNTAC2",
- ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
- ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MS_LYNC,
no_master,
no_master, "Lync",
- ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
- ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VIBER,
no_master,
no_master, "Viber",
@@ -1523,11 +1547,32 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
no_master, "COAP",
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
ndpi_build_default_ports(ports_b, 5683, 5684, 0, 0, 0)); /* UDP */
- ndpi_set_proto_defaults(ndpi_mod,NDPI_PROTOCOL_ACCEPTABLE,NDPI_PROTOCOL_MQTT,
- no_master,
- no_master, "MQTT",
- ndpi_build_default_ports(ports_a, 1883, 8883, 0, 0, 0), /* TCP */
- ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MQTT,
+ no_master,
+ no_master, "MQTT",
+ ndpi_build_default_ports(ports_a, 1883, 8883, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RX,
+ no_master,
+ no_master, "RX",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_GIT,
+ no_master,
+ no_master, "Git",
+ ndpi_build_default_ports(ports_a, 9418, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DRDA,
+ no_master,
+ no_master, "DRDA",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_SERVICE_HANGOUT,
+ no_master,
+ no_master, "GoogleHangout",
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+
/* calling function for host and content matched protocols */
init_string_based_protocols(ndpi_mod);
@@ -1674,22 +1719,25 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp
#endif
-/* ******************************************************************** */
+void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size)) { _ndpi_malloc = __ndpi_malloc; }
-struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second,
- void* (*__ndpi_malloc)(size_t size),
- void (*__ndpi_free)(void *ptr),
- ndpi_debug_function_ptr ndpi_debug_printf)
-{
- struct ndpi_detection_module_struct *ndpi_str;
+void set_ndpi_free(void (*__ndpi_free)(void *ptr)) { _ndpi_free = __ndpi_free; }
- _ndpi_malloc = __ndpi_malloc;
- _ndpi_free = __ndpi_free;
+void set_ndpi_debug_function(ndpi_debug_function_ptr ndpi_debug_printf) {
+#ifdef NDPI_ENABLE_DEBUG_MESSAGES
+ ndpi_str->ndpi_debug_printf = ndpi_debug_printf;
+#endif
+}
+
+/* ******************************************************************** */
- ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct));
+struct ndpi_detection_module_struct *ndpi_init_detection_module() {
+ struct ndpi_detection_module_struct *ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct));
if(ndpi_str == NULL) {
+#ifdef NDPI_ENABLE_DEBUG_MESSAGES
ndpi_debug_printf(0, NULL, NDPI_LOG_DEBUG, "ndpi_init_detection_module initial malloc failed\n");
+#endif
return NULL;
}
memset(ndpi_str, 0, sizeof(struct ndpi_detection_module_struct));
@@ -1699,30 +1747,29 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_
NDPI_BITMASK_RESET(ndpi_str->detection_bitmask);
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
- ndpi_str->ndpi_debug_printf = ndpi_debug_printf;
ndpi_str->user_data = NULL;
#endif
- ndpi_str->ticks_per_second = ticks_per_second;
+ ndpi_str->ticks_per_second = 1000; /* ndpi_str->ticks_per_second */
ndpi_str->tcp_max_retransmission_window_size = NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE;
ndpi_str->directconnect_connection_ip_tick_timeout =
- NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second;
+ NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second;
- ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ticks_per_second;
- ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ticks_per_second;
- ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ticks_per_second;
- ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
+ ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
+ ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
+ ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
- ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
- ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ticks_per_second;
+ ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
ndpi_str->yahoo_detect_http_connections = NDPI_YAHOO_DETECT_HTTP_CONNECTIONS;
- ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ticks_per_second;
- ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ticks_per_second;
- ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ticks_per_second;
- ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ticks_per_second;
- ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second;
+ ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ndpi_str->ticks_per_second;
+ ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second;
+ ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ndpi_str->ticks_per_second;
+ ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ndpi_str->ticks_per_second;
+ ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second;
ndpi_str->ndpi_num_supported_protocols = NDPI_MAX_SUPPORTED_PROTOCOLS;
ndpi_str->ndpi_num_custom_protocols = 0;
@@ -1738,12 +1785,52 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_
/* *********************************************** */
+/* Wrappers */
+void* ndpi_init_automa() {
+ return(ac_automata_init(ac_match_handler));
+}
+
+int ndpi_add_string_to_automa(void *_automa, char *str) {
+ AC_PATTERN_t ac_pattern;
+ AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa;
+
+ if(automa == NULL) return(-1);
+
+ ac_pattern.astring = str;
+ ac_pattern.rep.number = 1; /* Dummy */
+ ac_pattern.length = strlen(ac_pattern.astring);
+ return(ac_automata_add(automa, &ac_pattern) == ACERR_SUCCESS ? 0 : -1);
+}
+
+void ndpi_free_automa(void *_automa) { ac_automata_release((AC_AUTOMATA_t*)_automa); }
+void ndpi_finalize_automa(void *_automa) { ac_automata_finalize((AC_AUTOMATA_t*)_automa); }
+
+/* ****************************************************** */
+
+int ndpi_match_string(void *_automa, char *string_to_match) {
+ int matching_protocol_id = NDPI_PROTOCOL_UNKNOWN;
+ AC_TEXT_t ac_input_text;
+ AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa;
+
+ if((automa == NULL)
+ || (string_to_match == NULL)
+ || (string_to_match[0] == '\0'))
+ return(-2);
+
+ ac_input_text.astring = string_to_match, ac_input_text.length = strlen(string_to_match);
+ ac_automata_search(automa, &ac_input_text, (void*)&matching_protocol_id);
+ ac_automata_reset(automa);
+
+ return(matching_protocol_id > 0 ? 0 : -1);
+}
+
+/* *********************************************** */
+
static void free_ptree_data(void *data) { ; }
/* ****************************************************** */
-void ndpi_exit_detection_module(struct ndpi_detection_module_struct
- *ndpi_struct, void (*ndpi_free) (void *ptr)) {
+void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct) {
if(ndpi_struct != NULL) {
int i;
@@ -1793,11 +1880,11 @@ int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_
/* ****************************************************** */
-u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
- u_int8_t proto, u_int16_t sport, u_int16_t dport) {
+static ndpi_default_ports_tree_node_t* ndpi_get_guessed_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t proto, u_int16_t sport, u_int16_t dport) {
const void *ret;
ndpi_default_ports_tree_node_t node;
-
+
if(sport && dport) {
int low = ndpi_min(sport, dport);
int high = ndpi_max(sport, dport);
@@ -1814,10 +1901,27 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struc
ndpi_default_ports_tree_node_t_cmp);
}
- if(ret != NULL) {
- ndpi_default_ports_tree_node_t *found = *(ndpi_default_ports_tree_node_t**)ret;
+ if(ret) return(*(ndpi_default_ports_tree_node_t**)ret);
+ }
- return(found->proto->protoId);
+ return(NULL);
+}
+
+/* ****************************************************** */
+
+u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int8_t proto, u_int16_t sport, u_int16_t dport,
+ u_int8_t *user_defined_proto) {
+ const void *ret;
+ ndpi_default_ports_tree_node_t node;
+
+ *user_defined_proto = 0; /* Default */
+ if(sport && dport) {
+ ndpi_default_ports_tree_node_t *found = ndpi_get_guessed_protocol_id(ndpi_struct, proto, sport, dport);
+
+ if(found != NULL) {
+ *user_defined_proto = found->customUserProto;
+ return(found->proto->protoId);
}
} else {
/* No TCP/UDP */
@@ -1871,13 +1975,13 @@ u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi
#ifdef WIN32
char * strsep(char **sp, char *sep)
{
- char *p, *s;
- if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL);
- s = *sp;
- p = s + strcspn(s, sep);
- if (*p != '\0') *p++ = '\0';
- *sp = p;
- return(s);
+ char *p, *s;
+ if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL);
+ s = *sp;
+ p = s + strcspn(s, sep);
+ if (*p != '\0') *p++ = '\0';
+ *sp = p;
+ return(s);
}
#endif
@@ -1970,7 +2074,7 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod, char* rule,
if(sscanf(value, "%u-%u", (unsigned int *)&range.port_low, (unsigned int *)&range.port_high) != 2)
range.port_low = range.port_high = atoi(&elem[4]);
if(do_add)
- addDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot);
+ addDefaultPort(&range, def, 1 /* Custom user proto */, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot);
else
removeDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot);
} else if(is_ip) {
@@ -2264,7 +2368,7 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
/* SSDP */
init_ssdp_dissector(ndpi_struct, &a, detection_bitmask);
-/* WORLD_OF_WARCRAFT */
+ /* WORLD_OF_WARCRAFT */
init_world_of_warcraft_dissector(ndpi_struct, &a, detection_bitmask);
/* POSTGRES */
@@ -2495,7 +2599,19 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
/* MQTT */
init_mqtt_dissector(ndpi_struct, &a, detection_bitmask);
- /* Put false-positive sensitive protocols at the end */
+ /* RX */
+ init_rx_dissector(ndpi_struct, &a, detection_bitmask);
+
+ /* GIT */
+ init_git_dissector(ndpi_struct, &a, detection_bitmask);
+
+ /* HANGOUT */
+ init_hangout_dissector(ndpi_struct, &a, detection_bitmask);
+
+ /* DRDA */
+ init_drda_dissector(ndpi_struct, &a, detection_bitmask);
+
+ /*** Put false-positive sensitive protocols at the end ***/
/* SKYPE */
init_skype_dissector(ndpi_struct, &a, detection_bitmask);
@@ -3154,18 +3270,35 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru
u_int8_t l4_proto,
struct ndpi_id_struct *src,
u_int16_t sport,
- struct ndpi_id_struct *dst,
+ struct ndpi_id_struct *dst,
u_int16_t dport,
+ const u_int64_t current_tick_l,
u_int8_t *payload, u_int16_t payload_len) {
NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet;
u_int32_t a;
ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN };
+ if(flow == NULL)
+ return(ret);
+
if(payload_len == 0) return(ret);
flow->packet.tcp = tcp, flow->packet.udp = udp;
flow->packet.payload = payload, flow->packet.payload_packet_len = payload_len;
+ flow->packet.tick_timestamp_l = current_tick_l;
+ flow->packet.tick_timestamp = (u_int32_t)current_tick_l/1000;
+
+ if(flow) {
+ ndpi_apply_flow_protocol_to_packet(flow, &flow->packet);
+ } else {
+ ndpi_int_reset_packet_protocol(&flow->packet);
+ }
+
+ if(flow->server_id == NULL) flow->server_id = dst; /* Default */
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ goto ret_protocols;
+
if(src_to_dst_direction)
flow->src = src, flow->dst = dst;
else
@@ -3179,6 +3312,8 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru
ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;
#endif /* NDPI_DETECTION_SUPPORT_IPV6 */
+ ndpi_connection_tracking(ndpi_struct, flow);
+
if(flow->packet.tcp != NULL)
ndpi_selection_packet |=
(NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
@@ -3196,6 +3331,28 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru
flow->packet.l4_protocol = l4_proto, flow->packet.packet_direction = src_to_dst_direction;
+ if((!flow->protocol_id_already_guessed)
+ && (
+#ifdef NDPI_DETECTION_SUPPORT_IPV6
+ flow->packet.iphv6 ||
+#endif
+ flow->packet.iph)) {
+ u_int8_t user_defined_proto;
+
+ flow->protocol_id_already_guessed = 1,
+ flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, l4_proto, sport, dport, &user_defined_proto);
+
+ if(user_defined_proto && (flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
+ ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.protocol = flow->guessed_protocol_id;
+ return(ret);
+ }
+
+ if(flow->packet.iph) {
+ if((flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN)
+ flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->daddr);
+ }
+ }
+
check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet);
a = flow->packet.detected_protocol_stack[0];
@@ -3329,6 +3486,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
u_int16_t sport, dport;
u_int8_t protocol;
u_int32_t saddr, daddr;
+ u_int8_t user_defined_proto;
flow->protocol_id_already_guessed = 1;
@@ -3339,15 +3497,18 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
#endif
{
protocol = flow->packet.iph->protocol;
- saddr = ntohl(flow->packet.iph->saddr);
- daddr = ntohl(flow->packet.iph->daddr);
}
if(flow->packet.udp) sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest);
else if(flow->packet.tcp) sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest);
else sport = dport = 0;
- flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport);
+ flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport, &user_defined_proto);
+
+ if(user_defined_proto && (flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)) {
+ ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.protocol = flow->guessed_protocol_id;
+ return(ret);
+ }
if(flow->packet.iph) {
if((flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN)
@@ -4182,12 +4343,14 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
unsigned int rc;
struct in_addr addr;
ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN };
+ u_int8_t user_defined_proto;
if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, proto, shost, dhost, sport, dport);
+
if(rc != NDPI_PROTOCOL_UNKNOWN) {
ret.protocol = rc,
- ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport);
+ ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto);
if(ret.protocol == ret.master_protocol)
ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
@@ -4195,7 +4358,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
return(ret);
}
- rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport);
+ rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto);
if(rc != NDPI_PROTOCOL_UNKNOWN) {
ret.protocol = rc;
@@ -4219,7 +4382,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
ret.protocol = NDPI_PROTOCOL_SKYPE;
}
} else
- ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport);
+ ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto);
return(ret);
}
@@ -4339,6 +4502,16 @@ char* ndpi_strnstr(const char *s, const char *find, size_t slen) {
/* ****************************************************** */
+int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len,
+ const char *str, size_t str_len)
+{
+ return str_len <= payload_len
+ ? memcmp(payload, str, str_len) == 0
+ : 0;
+}
+
+/* ****************************************************** */
+
int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
char *string_to_match, u_int string_to_match_len,
u_int8_t is_host_match) {
@@ -4369,7 +4542,6 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str
u_int8_t is_host_match) {
int matching_protocol_id = ndpi_match_string_subprotocol(ndpi_struct, string_to_match, string_to_match_len, is_host_match);
struct ndpi_packet_struct *packet = &flow->packet;
- AC_TEXT_t ac_input_text;
#ifdef DEBUG
{
@@ -4465,25 +4637,6 @@ char* ndpi_revision() { return(NDPI_GIT_RELEASE); }
#ifdef WIN32
-/*
- int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) {
- unused = NULL;
- *mutex = CreateMutex(NULL, FALSE, NULL);
- return *mutex == NULL ? -1 : 0;
- }
-
- int pthread_mutex_destroy(pthread_mutex_t *mutex) {
- return CloseHandle(*mutex) == 0 ? -1 : 0;
- }
-
- int pthread_mutex_lock(pthread_mutex_t *mutex) {
- return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
- }
-
- int pthread_mutex_unlock(pthread_mutex_t *mutex) {
- return ReleaseMutex(*mutex) == 0 ? -1 : 0;
- }
-*/
/* http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/port/gettimeofday.c;h=75a91993b74414c0a1c13a2a09ce739cb8aa8a08;hb=HEAD */
int gettimeofday(struct timeval * tp, struct timezone * tzp) {
/* FILETIME of Jan 1 1970 00:00:00. */
diff --git a/src/lib/protocols/bgp.c b/src/lib/protocols/bgp.c
index 8f293b611..e72fdee57 100644
--- a/src/lib/protocols/bgp.c
+++ b/src/lib/protocols/bgp.c
@@ -35,23 +35,23 @@ static void ndpi_int_bgp_add_connection(struct ndpi_detection_module_struct *ndp
/* this detection also works asymmetrically */
void ndpi_search_bgp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
- struct ndpi_packet_struct *packet = &flow->packet;
-
-// struct ndpi_id_struct *src=ndpi_struct->src;
-// struct ndpi_id_struct *dst=ndpi_struct->dst;
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t bgp_port = htons(179);
- if (packet->payload_packet_len > 18 &&
- get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL &&
- get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL &&
- ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len &&
- (packet->tcp->dest == htons(179) || packet->tcp->source == htons(179))
- && packet->payload[18] < 5) {
- NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n");
- ndpi_int_bgp_add_connection(ndpi_struct, flow);
- return;
- }
+ if(packet->tcp
+ && (packet->payload_packet_len > 18)
+ && (packet->payload[18] < 5)
+ && ((packet->tcp->dest == bgp_port) || (packet->tcp->source == bgp_port))
+ && (get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL)
+ && (get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL)
+ && (ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len)
+ ) {
+ NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n");
+ ndpi_int_bgp_add_connection(ndpi_struct, flow);
+ return;
+ }
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP);
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP);
}
diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c
index 8213d3b45..0eebe07ee 100644
--- a/src/lib/protocols/bittorrent.c
+++ b/src/lib/protocols/bittorrent.c
@@ -53,8 +53,7 @@ static u_int8_t is_utp_pkt(const u_int8_t *payload, u_int payload_len) {
static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
int bt_offset, int check_hash,
- const u_int8_t save_detection, const u_int8_t encrypted_connection/* , */
- /* ndpi_protocol_type_t protocol_type */)
+ const u_int8_t save_detection, const u_int8_t encrypted_connection)
{
if(check_hash) {
const char *bt_hash = NULL; /* 20 bytes long */
@@ -92,8 +91,7 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
ndpi_add_connection_as_bittorrent(ndpi_struct, flow, 19, 1,
- NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */
- /* NDPI_REAL_PROTOCOL */);
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION);
return 1;
}
}
@@ -125,8 +123,7 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct,
NDPI_LOG_TRACE, "BT: plain Bitcomet persistent seed protocol detected\n");
ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1,
- NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */
- /* NDPI_CORRELATED_PROTOCOL */);
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION);
return 1;
}
@@ -135,7 +132,6 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module
|| memcmp(packet->payload, "POST ", 5) == 0)) {
const u_int8_t *ptr = &packet->payload[4];
u_int16_t len = packet->payload_packet_len - 4;
- a = 0;
/* parse complete get packet here into line structure elements */
diff --git a/src/lib/protocols/coap.c b/src/lib/protocols/coap.c
index cddf31b7e..5f8e97863 100644
--- a/src/lib/protocols/coap.c
+++ b/src/lib/protocols/coap.c
@@ -72,7 +72,7 @@ struct ndpi_coap_hdr
[164] = "5.04 Gateway Timeout",
[165] = "5.05 Proxying Not Supported"
**/
-
+
/**
* Entry point when protocol is identified.
@@ -84,6 +84,20 @@ static void ndpi_int_coap_add_connection (struct ndpi_detection_module_struct *n
}
/**
+ * Check if the default port is acceptable
+ *
+ * UDP Port 5683 (mandatory)
+ * UDP Ports 61616-61631 compressed 6lowPAN
+ */
+static int isCoAPport(u_int16_t port) {
+ if((port == 5683)
+ || ((port >= 61616) && (port <= 61631)))
+ return(1);
+ else
+ return(0);
+}
+
+/**
* Dissector function that searches CoAP headers
*/
void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct,
@@ -91,22 +105,24 @@ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct,
{
struct ndpi_packet_struct *packet = &flow->packet;
struct ndpi_coap_hdr * h = (struct ndpi_coap_hdr*) packet->payload;
-
+
if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
return;
}
// search for udp packet
if(packet->udp != NULL) {
-
- // header too short
- if(packet->payload_packet_len < 4) {
-
+ u_int16_t s_port = ntohs(flow->packet.udp->source);
+ u_int16_t d_port = ntohs(flow->packet.udp->dest);
+
+ if((!isCoAPport(s_port) && !isCoAPport(s_port))
+ || (packet->payload_packet_len < 4) // header too short
+ ) {
NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "excluding Coap\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP);
return;
}
-
+
NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "calculating coap over udp.\n");
// check values in header
@@ -116,21 +132,21 @@ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct,
if((h->code >= 0 && h->code <= 5) || (h->code >= 65 && h->code <= 69) ||
(h->code >= 128 && h->code <= 134) || (h->code >= 140 && h->code <= 143) ||
(h->code >= 160 && h->code <= 165)) {
-
+
NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Coap found...\n");
ndpi_int_coap_add_connection(ndpi_struct,flow);
return;
}
}
}
- }
+ }
}
-
+
NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Coap ...\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP);
return;
-
}
+
/**
* Entry point for the ndpi library
*/
diff --git a/src/lib/protocols/dcerpc.c b/src/lib/protocols/dcerpc.c
index ec96d1287..7be8ac027 100644
--- a/src/lib/protocols/dcerpc.c
+++ b/src/lib/protocols/dcerpc.c
@@ -36,13 +36,11 @@ void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, struct
{
struct ndpi_packet_struct *packet = &flow->packet;
- u_int16_t len_packet = (packet->payload[9]<<8) | packet->payload[8];
-
if((packet->tcp != NULL)
&& (packet->payload_packet_len >= 64)
&& (packet->payload[0] == 0x05) /* version 5 */
&& (packet->payload[2] < 16) /* Packet type */
- && (len_packet == packet->payload_packet_len) /* Packet Length */
+ && (((packet->payload[9]<<8) | packet->payload[8]) == packet->payload_packet_len) /* Packet Length */
) {
NDPI_LOG(NDPI_PROTOCOL_DCERPC, ndpi_struct, NDPI_LOG_DEBUG, "DCERPC match\n");
ndpi_int_dcerpc_add_connection(ndpi_struct, flow);
diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c
index 8ffc04d51..e33a7c011 100644
--- a/src/lib/protocols/dhcp.c
+++ b/src/lib/protocols/dhcp.c
@@ -1,8 +1,7 @@
/*
* dhcp.c
*
- * Copyright (C) 2009-2011 by ipoque GmbH
- * Copyright (C) 2011-15 - ntop.org
+ * Copyright (C) 2016 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -43,16 +42,18 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru
/* this detection also works for asymmetric dhcp traffic */
/*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */
- if (packet->payload_packet_len >= 244 && (packet->udp->source == htons(67)
- || packet->udp->source == htons(68))
- && (packet->udp->dest == htons(67) || packet->udp->dest == htons(68))
- && get_u_int32_t(packet->payload, 236) == htonl(0x63825363)
- && get_u_int16_t(packet->payload, 240) == htons(0x3501)) {
-
- NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n");
-
- ndpi_int_dhcp_add_connection(ndpi_struct, flow);
- return;
+ if(packet->udp) {
+ if(packet->payload_packet_len >= 244 &&
+ (packet->udp->source == htons(67) || packet->udp->source == htons(68)) &&
+ (packet->udp->dest == htons(67) || packet->udp->dest == htons(68)) &&
+ get_u_int32_t(packet->payload, 236) == htonl(0x63825363) &&
+ get_u_int16_t(packet->payload, 240) == htons(0x3501)) {
+
+ NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n");
+
+ ndpi_int_dhcp_add_connection(ndpi_struct, flow);
+ return;
+ }
}
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCP);
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 503761137..5358cc8b7 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2012-16 - ntop.org
*
- * Michele Campus - <campus@ntop.org>
- *
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
*
@@ -29,37 +27,60 @@
#define FLAGS_MASK 0x8000
-void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
-{
+/* #define DNS_DEBUG 1 */
+
+/* *********************************************** */
+
+static u_int16_t get16(int *i, const u_int8_t *payload) {
+ u_int16_t v = *(u_int16_t*)&payload[*i];
+
+ (*i) += 2;
+
+ return(ntohs(v));
+}
+
+/* *********************************************** */
+
+static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) {
+ if(payload[i] == 0x00)
+ return(1);
+ else if(payload[i] == 0xC0)
+ return(2);
+ else {
+ u_int8_t len = payload[i];
+ u_int8_t off = len + 1;
+
+ if(off == 0) /* Bad packet */
+ return(0);
+ else
+ return(off + getNameLength(i+off, payload, payloadLen));
+ }
+}
+
+/* *********************************************** */
+void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
int x;
- u_int8_t is_query, ret_code;
- u_int16_t s_port = 0;
- u_int16_t d_port = 0;
+ u_int8_t is_query;
+ u_int16_t s_port = 0, d_port = 0;
NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n");
- if(flow->packet.udp != NULL)
- {
+ if(flow->packet.udp != NULL) {
s_port = ntohs(flow->packet.udp->source);
d_port = ntohs(flow->packet.udp->dest);
x = 0;
- }
- else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */
- {
+ } else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ {
s_port = ntohs(flow->packet.tcp->source);
d_port = ntohs(flow->packet.tcp->dest);
x = 2;
- }
- else
- {
+ } else {
NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
}
if((s_port == 53 || d_port == 53 || d_port == 5355)
- && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)))
- {
+ && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+x)) {
struct ndpi_dns_packet_header dns_header;
int invalid = 0;
@@ -70,12 +91,13 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
dns_header.num_answers = ntohs(dns_header.num_answers);
dns_header.authority_rrs = ntohs(dns_header.authority_rrs);
dns_header.additional_rrs = ntohs(dns_header.additional_rrs);
+ x += sizeof(struct ndpi_dns_packet_header);
/* 0x0000 QUERY */
if((dns_header.flags & FLAGS_MASK) == 0x0000)
is_query = 1;
/* 0x8000 RESPONSE */
- else if((dns_header.flags & FLAGS_MASK) != 0x8000)
+ else if((dns_header.flags & FLAGS_MASK) == 0x8000)
is_query = 0;
else
invalid = 1;
@@ -87,69 +109,129 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
&& (((dns_header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */)
|| ((dns_header.num_answers == 0) && (dns_header.authority_rrs == 0)))) {
/* This is a good query */
+
+ if(dns_header.num_queries > 0) {
+ while(x < flow->packet.payload_packet_len) {
+ if(flow->packet.payload[x] == '\0') {
+ x++;
+ flow->protos.dns.query_type = get16(&x, flow->packet.payload);
+#ifdef DNS_DEBUG
+ printf("[%s:%d] query_type=%2d\n", __FILE__, __LINE__, flow->protos.dns.query_type);
+#endif
+ break;
+ } else
+ x++;
+ }
+ }
} else
invalid = 1;
+
} else {
/* DNS Reply */
+
+ flow->protos.dns.reply_code = dns_header.flags & 0x0F;
+
if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */
&& (((dns_header.num_answers > 0) && (dns_header.num_answers <= NDPI_MAX_DNS_REQUESTS))
|| ((dns_header.authority_rrs > 0) && (dns_header.authority_rrs <= NDPI_MAX_DNS_REQUESTS))
|| ((dns_header.additional_rrs > 0) && (dns_header.additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
) {
/* This is a good reply */
- } else
- invalid = 1;
+ if(ndpi_struct->dns_dissect_response) {
+ x++;
+
+ if(flow->packet.payload[x] != '\0') {
+ while((x < flow->packet.payload_packet_len)
+ && (flow->packet.payload[x] != '\0')) {
+ x++;
+ }
+
+ x++;
+ }
+
+ x += 4;
+
+ if(dns_header.num_answers > 0) {
+ u_int16_t rsp_type;
+ u_int16_t num;
+
+ for(num = 0; num < dns_header.num_answers; num++) {
+ u_int16_t data_len;
+
+ if((x+6) >= flow->packet.payload_packet_len) {
+ break;
+ }
+
+ if((data_len = getNameLength(x, flow->packet.payload, flow->packet.payload_packet_len)) == 0) {
+ break;
+ } else
+ x += data_len;
+
+ rsp_type = get16(&x, flow->packet.payload);
+ flow->protos.dns.rsp_type = rsp_type;
+ break;
+ }
+ }
+ }
+ }
}
- }
- if(invalid) {
- NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
- return;
- }
+ if(invalid) {
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
+ return;
+ }
- /* extract host name server */
- ret_code = (is_query == 0) ? 0 : (dns_header.flags & 0x0F);
- int j = 0;
- int off = sizeof(struct ndpi_dns_packet_header) + 1;
- while((flow->packet.payload[off] != '\0'))
- {
- if(off < flow->packet.payload_packet_len)
- {
+ /* extract host name server */
+ int j = 0, max_len = sizeof(flow->host_server_name)-1, off = sizeof(struct ndpi_dns_packet_header) + 1;
+
+ while(off < flow->packet.payload_packet_len && flow->packet.payload[off] != '\0') {
flow->host_server_name[j] = flow->packet.payload[off];
- if(j < strlen(flow->host_server_name))
- {
+ if(j < max_len) {
if(flow->host_server_name[j] < ' ')
flow->host_server_name[j] = '.';
j++;
- }
+ } else
+ break;
+
off++;
}
- }
- flow->host_server_name[j] = '\0';
- flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs);
- flow->protos.dns.ret_code = ret_code;
+ flow->host_server_name[j] = '\0';
+
+ flow->protos.dns.num_queries = (u_int8_t)dns_header.num_queries,
+ flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs);
+
+ if(j > 0)
+ ndpi_match_host_subprotocol(ndpi_struct, flow,
+ (char *)flow->host_server_name,
+ strlen((const char*)flow->host_server_name),
+ NDPI_PROTOCOL_DNS);
- if(j > 0)
- ndpi_match_host_subprotocol(ndpi_struct, flow,
- (char *)flow->host_server_name,
- strlen((const char*)flow->host_server_name),
- NDPI_PROTOCOL_DNS);
+#ifdef DNS_DEBUG
+ printf("[%s:%d] [num_queries=%d][num_answers=%d][reply_code=%u][rsp_type=%u][host_server_name=%s]\n",
+ __FILE__, __LINE__,
+ flow->protos.dns.num_queries, flow->protos.dns.num_answers,
+ flow->protos.dns.reply_code, flow->protos.dns.rsp_type, flow->host_server_name
+ );
+#endif
- if(flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
- {
- /**
- Do not set the protocol with DNS if ndpi_match_host_subprotocol() has
- matched a subprotocol
- **/
- NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN);
- } else {
- NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
+ if(flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
+ if(is_query && ndpi_struct->dns_dissect_response)
+ return; /* The response will set the verdict */
+
+ /**
+ Do not set the protocol with DNS if ndpi_match_host_subprotocol() has
+ matched a subprotocol
+ **/
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN);
+ } else {
+ NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
+ }
}
- }
+ }
}
void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
diff --git a/src/lib/protocols/drda.c b/src/lib/protocols/drda.c
new file mode 100644
index 000000000..fe75379ff
--- /dev/null
+++ b/src/lib/protocols/drda.c
@@ -0,0 +1,106 @@
+/*
+ * drda.c
+ *
+ * Copyright (C) 2012-16 - ntop.org
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_DRDA
+
+#define DRDA_PORT 50000
+
+struct ndpi_drda_hdr {
+ u_int16_t length;
+ u_int8_t magic;
+ u_int8_t format;
+ u_int16_t correlID;
+ u_int16_t length2;
+ u_int16_t code_pnt;
+};
+
+
+void ndpi_search_drda(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct * packet = &flow->packet;
+ u_int16_t payload_len = packet->payload_packet_len;
+ u_int count = 0; // prevent integer overflow
+
+ if(packet->tcp != NULL) {
+
+ /* check port */
+ if((ntohs(packet->tcp->source) == DRDA_PORT ||
+ ntohs(packet->tcp->dest) == DRDA_PORT) &&
+ payload_len >= sizeof(struct ndpi_drda_hdr)) {
+
+ struct ndpi_drda_hdr * drda = (struct ndpi_drda_hdr *) packet->payload;
+
+ u_int16_t len = ntohs(drda->length);
+
+ /* check first header */
+ if(len != ntohs(drda->length2) + 6 ||
+ drda->magic != 0xd0)
+ goto no_drda;
+
+ /* check if there are more drda headers */
+ if(payload_len > len) {
+
+ count = len;
+
+ while(count + sizeof(struct ndpi_drda_hdr) < payload_len)
+ {
+ /* update info */
+ drda = (struct ndpi_drda_hdr *)(packet->payload + count);
+ len = ntohs(drda->length);
+
+ if(len != ntohs(drda->length2) + 6 ||
+ drda->magic != 0xd0)
+ goto no_drda;
+
+ count += len;
+ }
+ if(count != payload_len) goto no_drda;
+ }
+ NDPI_LOG(NDPI_PROTOCOL_DRDA, ndpi_struct, NDPI_LOG_DEBUG, "found DRDA.\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DRDA, NDPI_PROTOCOL_UNKNOWN);
+ return;
+ }
+ }
+
+ no_drda:
+ NDPI_LOG(NDPI_PROTOCOL_DRDA, ndpi_struct, NDPI_LOG_DEBUG, "exclude DRDA.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DRDA);
+}
+
+
+/* ***************************************************************** */
+
+
+void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id,
+ NDPI_PROTOCOL_BITMASK *detection_bitmask)
+{
+ ndpi_set_bitmask_protocol_detection("DRDA", ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_DRDA,
+ ndpi_search_drda,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ *id += 1;
+}
+
+#endif /* NDPI_PROTOCOL_DRDA */
diff --git a/src/lib/protocols/dropbox.c b/src/lib/protocols/dropbox.c
index f51de95d2..d8babfb1b 100644
--- a/src/lib/protocols/dropbox.c
+++ b/src/lib/protocols/dropbox.c
@@ -1,7 +1,7 @@
/*
* dropbox.c
*
- * Copyright (C) 2011-13 by ntop.org
+ * Copyright (C) 2012-16 by ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -44,7 +44,6 @@ static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t payload_len = packet->payload_packet_len;
if(packet->udp != NULL) {
-
u_int16_t dropbox_port = htons(DB_LSP_PORT);
if((packet->udp->source == dropbox_port)
diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c
index 8710096be..9bc2bf904 100644
--- a/src/lib/protocols/ftp_control.c
+++ b/src/lib/protocols/ftp_control.c
@@ -30,904 +30,904 @@ static void ndpi_int_ftp_control_add_connection(struct ndpi_detection_module_str
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FTP_CONTROL, NDPI_PROTOCOL_UNKNOWN);
}
-static int ndpi_ftp_control_check_request(const u_int8_t *payload) {
+static int ndpi_ftp_control_check_request(const u_int8_t *payload, size_t payload_len) {
- if (match_first_bytes(payload, "ABOR")) {
+ if (ndpi_match_strprefix(payload, payload_len, "ABOR")) {
return 1;
}
- if (match_first_bytes(payload, "ACCT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "ACCT")) {
return 1;
}
- if (match_first_bytes(payload, "ADAT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "ADAT")) {
return 1;
}
- if (match_first_bytes(payload, "ALLO")) {
+ if (ndpi_match_strprefix(payload, payload_len, "ALLO")) {
return 1;
}
- if (match_first_bytes(payload, "APPE")) {
+ if (ndpi_match_strprefix(payload, payload_len, "APPE")) {
return 1;
}
- if (match_first_bytes(payload, "AUTH")) {
+ if (ndpi_match_strprefix(payload, payload_len, "AUTH")) {
return 1;
}
- if (match_first_bytes(payload, "CCC")) {
+ if (ndpi_match_strprefix(payload, payload_len, "CCC")) {
return 1;
}
- if (match_first_bytes(payload, "CDUP")) {
+ if (ndpi_match_strprefix(payload, payload_len, "CDUP")) {
return 1;
}
- if (match_first_bytes(payload, "CONF")) {
+ if (ndpi_match_strprefix(payload, payload_len, "CONF")) {
return 1;
}
- if (match_first_bytes(payload, "CWD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "CWD")) {
return 1;
}
- if (match_first_bytes(payload, "DELE")) {
+ if (ndpi_match_strprefix(payload, payload_len, "DELE")) {
return 1;
}
- if (match_first_bytes(payload, "ENC")) {
+ if (ndpi_match_strprefix(payload, payload_len, "ENC")) {
return 1;
}
- if (match_first_bytes(payload, "EPRT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "EPRT")) {
return 1;
}
- if (match_first_bytes(payload, "EPSV")) {
+ if (ndpi_match_strprefix(payload, payload_len, "EPSV")) {
return 1;
}
- if (match_first_bytes(payload, "FEAT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "FEAT")) {
return 1;
}
- if (match_first_bytes(payload, "HELP")) {
+ if (ndpi_match_strprefix(payload, payload_len, "HELP")) {
return 1;
}
- if (match_first_bytes(payload, "LANG")) {
+ if (ndpi_match_strprefix(payload, payload_len, "LANG")) {
return 1;
}
- if (match_first_bytes(payload, "LIST")) {
+ if (ndpi_match_strprefix(payload, payload_len, "LIST")) {
return 1;
}
- if (match_first_bytes(payload, "LPRT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "LPRT")) {
return 1;
}
- if (match_first_bytes(payload, "LPSV")) {
+ if (ndpi_match_strprefix(payload, payload_len, "LPSV")) {
return 1;
}
- if (match_first_bytes(payload, "MDTM")) {
+ if (ndpi_match_strprefix(payload, payload_len, "MDTM")) {
return 1;
}
- if (match_first_bytes(payload, "MIC")) {
+ if (ndpi_match_strprefix(payload, payload_len, "MIC")) {
return 1;
}
- if (match_first_bytes(payload, "MKD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "MKD")) {
return 1;
}
- if (match_first_bytes(payload, "MLSD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "MLSD")) {
return 1;
}
- if (match_first_bytes(payload, "MLST")) {
+ if (ndpi_match_strprefix(payload, payload_len, "MLST")) {
return 1;
}
- if (match_first_bytes(payload, "MODE")) {
+ if (ndpi_match_strprefix(payload, payload_len, "MODE")) {
return 1;
}
- if (match_first_bytes(payload, "NLST")) {
+ if (ndpi_match_strprefix(payload, payload_len, "NLST")) {
return 1;
}
- if (match_first_bytes(payload, "NOOP")) {
+ if (ndpi_match_strprefix(payload, payload_len, "NOOP")) {
return 1;
}
- if (match_first_bytes(payload, "OPTS")) {
+ if (ndpi_match_strprefix(payload, payload_len, "OPTS")) {
return 1;
}
- if (match_first_bytes(payload, "PASS")) {
+ if (ndpi_match_strprefix(payload, payload_len, "PASS")) {
return 1;
}
- if (match_first_bytes(payload, "PASV")) {
+ if (ndpi_match_strprefix(payload, payload_len, "PASV")) {
return 1;
}
- if (match_first_bytes(payload, "PBSZ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "PBSZ")) {
return 1;
}
- if (match_first_bytes(payload, "PORT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "PORT")) {
return 1;
}
- if (match_first_bytes(payload, "PROT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "PROT")) {
return 1;
}
- if (match_first_bytes(payload, "PWD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "PWD")) {
return 1;
}
- if (match_first_bytes(payload, "QUIT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "QUIT")) {
return 1;
}
- if (match_first_bytes(payload, "REIN")) {
+ if (ndpi_match_strprefix(payload, payload_len, "REIN")) {
return 1;
}
- if (match_first_bytes(payload, "REST")) {
+ if (ndpi_match_strprefix(payload, payload_len, "REST")) {
return 1;
}
- if (match_first_bytes(payload, "RETR")) {
+ if (ndpi_match_strprefix(payload, payload_len, "RETR")) {
return 1;
}
- if (match_first_bytes(payload, "RMD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "RMD")) {
return 1;
}
- if (match_first_bytes(payload, "RNFR")) {
+ if (ndpi_match_strprefix(payload, payload_len, "RNFR")) {
return 1;
}
- if (match_first_bytes(payload, "RNTO")) {
+ if (ndpi_match_strprefix(payload, payload_len, "RNTO")) {
return 1;
}
- if (match_first_bytes(payload, "SITE")) {
+ if (ndpi_match_strprefix(payload, payload_len, "SITE")) {
return 1;
}
- if (match_first_bytes(payload, "SIZE")) {
+ if (ndpi_match_strprefix(payload, payload_len, "SIZE")) {
return 1;
}
- if (match_first_bytes(payload, "SMNT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "SMNT")) {
return 1;
}
- if (match_first_bytes(payload, "STAT")) {
+ if (ndpi_match_strprefix(payload, payload_len, "STAT")) {
return 1;
}
- if (match_first_bytes(payload, "STOR")) {
+ if (ndpi_match_strprefix(payload, payload_len, "STOR")) {
return 1;
}
- if (match_first_bytes(payload, "STOU")) {
+ if (ndpi_match_strprefix(payload, payload_len, "STOU")) {
return 1;
}
- if (match_first_bytes(payload, "STRU")) {
+ if (ndpi_match_strprefix(payload, payload_len, "STRU")) {
return 1;
}
- if (match_first_bytes(payload, "SYST")) {
+ if (ndpi_match_strprefix(payload, payload_len, "SYST")) {
return 1;
}
- if (match_first_bytes(payload, "TYPE")) {
+ if (ndpi_match_strprefix(payload, payload_len, "TYPE")) {
return 1;
}
- if (match_first_bytes(payload, "USER")) {
+ if (ndpi_match_strprefix(payload, payload_len, "USER")) {
return 1;
}
- if (match_first_bytes(payload, "XCUP")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XCUP")) {
return 1;
}
- if (match_first_bytes(payload, "XMKD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XMKD")) {
return 1;
}
- if (match_first_bytes(payload, "XPWD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XPWD")) {
return 1;
}
- if (match_first_bytes(payload, "XRCP")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XRCP")) {
return 1;
}
- if (match_first_bytes(payload, "XRMD")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XRMD")) {
return 1;
}
- if (match_first_bytes(payload, "XRSQ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XRSQ")) {
return 1;
}
- if (match_first_bytes(payload, "XSEM")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XSEM")) {
return 1;
}
- if (match_first_bytes(payload, "XSEN")) {
+ if (ndpi_match_strprefix(payload, payload_len, "XSEN")) {
return 1;
}
- if (match_first_bytes(payload, "HOST")) {
+ if (ndpi_match_strprefix(payload, payload_len, "HOST")) {
return 1;
}
- if (match_first_bytes(payload, "abor")) {
+ if (ndpi_match_strprefix(payload, payload_len, "abor")) {
return 1;
}
- if (match_first_bytes(payload, "acct")) {
+ if (ndpi_match_strprefix(payload, payload_len, "acct")) {
return 1;
}
- if (match_first_bytes(payload, "adat")) {
+ if (ndpi_match_strprefix(payload, payload_len, "adat")) {
return 1;
}
- if (match_first_bytes(payload, "allo")) {
+ if (ndpi_match_strprefix(payload, payload_len, "allo")) {
return 1;
}
- if (match_first_bytes(payload, "appe")) {
+ if (ndpi_match_strprefix(payload, payload_len, "appe")) {
return 1;
}
- if (match_first_bytes(payload, "auth")) {
+ if (ndpi_match_strprefix(payload, payload_len, "auth")) {
return 1;
}
- if (match_first_bytes(payload, "ccc")) {
+ if (ndpi_match_strprefix(payload, payload_len, "ccc")) {
return 1;
}
- if (match_first_bytes(payload, "cdup")) {
+ if (ndpi_match_strprefix(payload, payload_len, "cdup")) {
return 1;
}
- if (match_first_bytes(payload, "conf")) {
+ if (ndpi_match_strprefix(payload, payload_len, "conf")) {
return 1;
}
- if (match_first_bytes(payload, "cwd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "cwd")) {
return 1;
}
- if (match_first_bytes(payload, "dele")) {
+ if (ndpi_match_strprefix(payload, payload_len, "dele")) {
return 1;
}
- if (match_first_bytes(payload, "enc")) {
+ if (ndpi_match_strprefix(payload, payload_len, "enc")) {
return 1;
}
- if (match_first_bytes(payload, "eprt")) {
+ if (ndpi_match_strprefix(payload, payload_len, "eprt")) {
return 1;
}
- if (match_first_bytes(payload, "epsv")) {
+ if (ndpi_match_strprefix(payload, payload_len, "epsv")) {
return 1;
}
- if (match_first_bytes(payload, "feat")) {
+ if (ndpi_match_strprefix(payload, payload_len, "feat")) {
return 1;
}
- if (match_first_bytes(payload, "help")) {
+ if (ndpi_match_strprefix(payload, payload_len, "help")) {
return 1;
}
- if (match_first_bytes(payload, "lang")) {
+ if (ndpi_match_strprefix(payload, payload_len, "lang")) {
return 1;
}
- if (match_first_bytes(payload, "list")) {
+ if (ndpi_match_strprefix(payload, payload_len, "list")) {
return 1;
}
- if (match_first_bytes(payload, "lprt")) {
+ if (ndpi_match_strprefix(payload, payload_len, "lprt")) {
return 1;
}
- if (match_first_bytes(payload, "lpsv")) {
+ if (ndpi_match_strprefix(payload, payload_len, "lpsv")) {
return 1;
}
- if (match_first_bytes(payload, "mdtm")) {
+ if (ndpi_match_strprefix(payload, payload_len, "mdtm")) {
return 1;
}
- if (match_first_bytes(payload, "mic")) {
+ if (ndpi_match_strprefix(payload, payload_len, "mic")) {
return 1;
}
- if (match_first_bytes(payload, "mkd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "mkd")) {
return 1;
}
- if (match_first_bytes(payload, "mlsd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "mlsd")) {
return 1;
}
- if (match_first_bytes(payload, "mlst")) {
+ if (ndpi_match_strprefix(payload, payload_len, "mlst")) {
return 1;
}
- if (match_first_bytes(payload, "mode")) {
+ if (ndpi_match_strprefix(payload, payload_len, "mode")) {
return 1;
}
- if (match_first_bytes(payload, "nlst")) {
+ if (ndpi_match_strprefix(payload, payload_len, "nlst")) {
return 1;
}
- if (match_first_bytes(payload, "noop")) {
+ if (ndpi_match_strprefix(payload, payload_len, "noop")) {
return 1;
}
- if (match_first_bytes(payload, "opts")) {
+ if (ndpi_match_strprefix(payload, payload_len, "opts")) {
return 1;
}
- if (match_first_bytes(payload, "pass")) {
+ if (ndpi_match_strprefix(payload, payload_len, "pass")) {
return 1;
}
- if (match_first_bytes(payload, "pasv")) {
+ if (ndpi_match_strprefix(payload, payload_len, "pasv")) {
return 1;
}
- if (match_first_bytes(payload, "pbsz")) {
+ if (ndpi_match_strprefix(payload, payload_len, "pbsz")) {
return 1;
}
- if (match_first_bytes(payload, "port")) {
+ if (ndpi_match_strprefix(payload, payload_len, "port")) {
return 1;
}
- if (match_first_bytes(payload, "prot")) {
+ if (ndpi_match_strprefix(payload, payload_len, "prot")) {
return 1;
}
- if (match_first_bytes(payload, "pwd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "pwd")) {
return 1;
}
- if (match_first_bytes(payload, "quit")) {
+ if (ndpi_match_strprefix(payload, payload_len, "quit")) {
return 1;
}
- if (match_first_bytes(payload, "rein")) {
+ if (ndpi_match_strprefix(payload, payload_len, "rein")) {
return 1;
}
- if (match_first_bytes(payload, "rest")) {
+ if (ndpi_match_strprefix(payload, payload_len, "rest")) {
return 1;
}
- if (match_first_bytes(payload, "retr")) {
+ if (ndpi_match_strprefix(payload, payload_len, "retr")) {
return 1;
}
- if (match_first_bytes(payload, "rmd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "rmd")) {
return 1;
}
- if (match_first_bytes(payload, "rnfr")) {
+ if (ndpi_match_strprefix(payload, payload_len, "rnfr")) {
return 1;
}
- if (match_first_bytes(payload, "rnto")) {
+ if (ndpi_match_strprefix(payload, payload_len, "rnto")) {
return 1;
}
- if (match_first_bytes(payload, "site")) {
+ if (ndpi_match_strprefix(payload, payload_len, "site")) {
return 1;
}
- if (match_first_bytes(payload, "size")) {
+ if (ndpi_match_strprefix(payload, payload_len, "size")) {
return 1;
}
- if (match_first_bytes(payload, "smnt")) {
+ if (ndpi_match_strprefix(payload, payload_len, "smnt")) {
return 1;
}
- if (match_first_bytes(payload, "stat")) {
+ if (ndpi_match_strprefix(payload, payload_len, "stat")) {
return 1;
}
- if (match_first_bytes(payload, "stor")) {
+ if (ndpi_match_strprefix(payload, payload_len, "stor")) {
return 1;
}
- if (match_first_bytes(payload, "stou")) {
+ if (ndpi_match_strprefix(payload, payload_len, "stou")) {
return 1;
}
- if (match_first_bytes(payload, "stru")) {
+ if (ndpi_match_strprefix(payload, payload_len, "stru")) {
return 1;
}
- if (match_first_bytes(payload, "syst")) {
+ if (ndpi_match_strprefix(payload, payload_len, "syst")) {
return 1;
}
- if (match_first_bytes(payload, "type")) {
+ if (ndpi_match_strprefix(payload, payload_len, "type")) {
return 1;
}
- if (match_first_bytes(payload, "user")) {
+ if (ndpi_match_strprefix(payload, payload_len, "user")) {
return 1;
}
- if (match_first_bytes(payload, "xcup")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xcup")) {
return 1;
}
- if (match_first_bytes(payload, "xmkd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xmkd")) {
return 1;
}
- if (match_first_bytes(payload, "xpwd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xpwd")) {
return 1;
}
- if (match_first_bytes(payload, "xrcp")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xrcp")) {
return 1;
}
- if (match_first_bytes(payload, "xrmd")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xrmd")) {
return 1;
}
- if (match_first_bytes(payload, "xrsq")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xrsq")) {
return 1;
}
- if (match_first_bytes(payload, "xsem")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xsem")) {
return 1;
}
- if (match_first_bytes(payload, "xsen")) {
+ if (ndpi_match_strprefix(payload, payload_len, "xsen")) {
return 1;
}
- if (match_first_bytes(payload, "host")) {
+ if (ndpi_match_strprefix(payload, payload_len, "host")) {
return 1;
}
return 0;
}
-static int ndpi_ftp_control_check_response(const u_int8_t *payload) {
+static int ndpi_ftp_control_check_response(const u_int8_t *payload, size_t payload_len) {
- if (match_first_bytes(payload, "110-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "110-")) {
return 1;
}
- if (match_first_bytes(payload, "120-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "120-")) {
return 1;
}
- if (match_first_bytes(payload, "125-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "125-")) {
return 1;
}
- if (match_first_bytes(payload, "150-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "150-")) {
return 1;
}
- if (match_first_bytes(payload, "202-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "202-")) {
return 1;
}
- if (match_first_bytes(payload, "211-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "211-")) {
return 1;
}
- if (match_first_bytes(payload, "212-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "212-")) {
return 1;
}
- if (match_first_bytes(payload, "213-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "213-")) {
return 1;
}
- if (match_first_bytes(payload, "214-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "214-")) {
return 1;
}
- if (match_first_bytes(payload, "215-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "215-")) {
return 1;
}
- if (match_first_bytes(payload, "220-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "220-")) {
return 1;
}
- if (match_first_bytes(payload, "221-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "221-")) {
return 1;
}
- if (match_first_bytes(payload, "225-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "225-")) {
return 1;
}
- if (match_first_bytes(payload, "226-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "226-")) {
return 1;
}
- if (match_first_bytes(payload, "227-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "227-")) {
return 1;
}
- if (match_first_bytes(payload, "228-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "228-")) {
return 1;
}
- if (match_first_bytes(payload, "229-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "229-")) {
return 1;
}
- if (match_first_bytes(payload, "230-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "230-")) {
return 1;
}
- if (match_first_bytes(payload, "231-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "231-")) {
return 1;
}
- if (match_first_bytes(payload, "232-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "232-")) {
return 1;
}
- if (match_first_bytes(payload, "250-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "250-")) {
return 1;
}
- if (match_first_bytes(payload, "257-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "257-")) {
return 1;
}
- if (match_first_bytes(payload, "331-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "331-")) {
return 1;
}
- if (match_first_bytes(payload, "332-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "332-")) {
return 1;
}
- if (match_first_bytes(payload, "350-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "350-")) {
return 1;
}
- if (match_first_bytes(payload, "421-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "421-")) {
return 1;
}
- if (match_first_bytes(payload, "425-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "425-")) {
return 1;
}
- if (match_first_bytes(payload, "426-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "426-")) {
return 1;
}
- if (match_first_bytes(payload, "430-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "430-")) {
return 1;
}
- if (match_first_bytes(payload, "434-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "434-")) {
return 1;
}
- if (match_first_bytes(payload, "450-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "450-")) {
return 1;
}
- if (match_first_bytes(payload, "451-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "451-")) {
return 1;
}
- if (match_first_bytes(payload, "452-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "452-")) {
return 1;
}
- if (match_first_bytes(payload, "501-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "501-")) {
return 1;
}
- if (match_first_bytes(payload, "502-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "502-")) {
return 1;
}
- if (match_first_bytes(payload, "503-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "503-")) {
return 1;
}
- if (match_first_bytes(payload, "504-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "504-")) {
return 1;
}
- if (match_first_bytes(payload, "530-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "530-")) {
return 1;
}
- if (match_first_bytes(payload, "532-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "532-")) {
return 1;
}
- if (match_first_bytes(payload, "550-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "550-")) {
return 1;
}
- if (match_first_bytes(payload, "551-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "551-")) {
return 1;
}
- if (match_first_bytes(payload, "552-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "552-")) {
return 1;
}
- if (match_first_bytes(payload, "553-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "553-")) {
return 1;
}
- if (match_first_bytes(payload, "631-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "631-")) {
return 1;
}
- if (match_first_bytes(payload, "632-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "632-")) {
return 1;
}
- if (match_first_bytes(payload, "633-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "633-")) {
return 1;
}
- if (match_first_bytes(payload, "10054-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10054-")) {
return 1;
}
- if (match_first_bytes(payload, "10060-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10060-")) {
return 1;
}
- if (match_first_bytes(payload, "10061-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10061-")) {
return 1;
}
- if (match_first_bytes(payload, "10066-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10066-")) {
return 1;
}
- if (match_first_bytes(payload, "10068-")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10068-")) {
return 1;
}
- if (match_first_bytes(payload, "110 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "110 ")) {
return 1;
}
- if (match_first_bytes(payload, "120 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "120 ")) {
return 1;
}
- if (match_first_bytes(payload, "125 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "125 ")) {
return 1;
}
- if (match_first_bytes(payload, "150 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "150 ")) {
return 1;
}
- if (match_first_bytes(payload, "202 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "202 ")) {
return 1;
}
- if (match_first_bytes(payload, "211 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "211 ")) {
return 1;
}
- if (match_first_bytes(payload, "212 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "212 ")) {
return 1;
}
- if (match_first_bytes(payload, "213 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "213 ")) {
return 1;
}
- if (match_first_bytes(payload, "214 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "214 ")) {
return 1;
}
- if (match_first_bytes(payload, "215 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "215 ")) {
return 1;
}
- if (match_first_bytes(payload, "220 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "220 ")) {
return 1;
}
- if (match_first_bytes(payload, "221 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "221 ")) {
return 1;
}
- if (match_first_bytes(payload, "225 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "225 ")) {
return 1;
}
- if (match_first_bytes(payload, "226 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "226 ")) {
return 1;
}
- if (match_first_bytes(payload, "227 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "227 ")) {
return 1;
}
- if (match_first_bytes(payload, "228 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "228 ")) {
return 1;
}
- if (match_first_bytes(payload, "229 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "229 ")) {
return 1;
}
- if (match_first_bytes(payload, "230 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "230 ")) {
return 1;
}
- if (match_first_bytes(payload, "231 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "231 ")) {
return 1;
}
- if (match_first_bytes(payload, "232 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "232 ")) {
return 1;
}
- if (match_first_bytes(payload, "250 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "250 ")) {
return 1;
}
- if (match_first_bytes(payload, "257 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "257 ")) {
return 1;
}
- if (match_first_bytes(payload, "331 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "331 ")) {
return 1;
}
- if (match_first_bytes(payload, "332 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "332 ")) {
return 1;
}
- if (match_first_bytes(payload, "350 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "350 ")) {
return 1;
}
- if (match_first_bytes(payload, "421 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "421 ")) {
return 1;
}
- if (match_first_bytes(payload, "425 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "425 ")) {
return 1;
}
- if (match_first_bytes(payload, "426 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "426 ")) {
return 1;
}
- if (match_first_bytes(payload, "430 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "430 ")) {
return 1;
}
- if (match_first_bytes(payload, "434 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "434 ")) {
return 1;
}
- if (match_first_bytes(payload, "450 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "450 ")) {
return 1;
}
- if (match_first_bytes(payload, "451 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "451 ")) {
return 1;
}
- if (match_first_bytes(payload, "452 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "452 ")) {
return 1;
}
- if (match_first_bytes(payload, "501 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "501 ")) {
return 1;
}
- if (match_first_bytes(payload, "502 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "502 ")) {
return 1;
}
- if (match_first_bytes(payload, "503 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "503 ")) {
return 1;
}
- if (match_first_bytes(payload, "504 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "504 ")) {
return 1;
}
- if (match_first_bytes(payload, "530 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "530 ")) {
return 1;
}
- if (match_first_bytes(payload, "532 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "532 ")) {
return 1;
}
- if (match_first_bytes(payload, "550 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "550 ")) {
return 1;
}
- if (match_first_bytes(payload, "551 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "551 ")) {
return 1;
}
- if (match_first_bytes(payload, "552 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "552 ")) {
return 1;
}
- if (match_first_bytes(payload, "553 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "553 ")) {
return 1;
}
- if (match_first_bytes(payload, "631 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "631 ")) {
return 1;
}
- if (match_first_bytes(payload, "632 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "632 ")) {
return 1;
}
- if (match_first_bytes(payload, "633 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "633 ")) {
return 1;
}
- if (match_first_bytes(payload, "10054 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10054 ")) {
return 1;
}
- if (match_first_bytes(payload, "10060 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10060 ")) {
return 1;
}
- if (match_first_bytes(payload, "10061 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10061 ")) {
return 1;
}
- if (match_first_bytes(payload, "10066 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10066 ")) {
return 1;
}
- if (match_first_bytes(payload, "10068 ")) {
+ if (ndpi_match_strprefix(payload, payload_len, "10068 ")) {
return 1;
}
@@ -956,7 +956,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str
if (flow->ftp_control_stage == 0) {
NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL stage 0: \n");
- if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload)) {
+ if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload, payload_len)) {
NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Possible FTP_CONTROL request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -972,7 +972,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload)) {
+ if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload, payload_len)) {
NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Found FTP_CONTROL.\n");
ndpi_int_ftp_control_add_connection(ndpi_struct, flow);
} else {
diff --git a/src/lib/protocols/ftp_data.c b/src/lib/protocols/ftp_data.c
index e87b4402f..7daf9190d 100644
--- a/src/lib/protocols/ftp_data.c
+++ b/src/lib/protocols/ftp_data.c
@@ -60,13 +60,14 @@ static int ndpi_match_ftp_data_directory(struct ndpi_detection_module_struct *nd
static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
/* A FTP packet is pretty long so 256 is a bit consrvative but it should be OK */
if(packet->payload_packet_len < 256)
return 0;
/* RIFF is a meta-format for storing AVI and WAV files */
- if(match_first_bytes(packet->payload, "RIFF"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "RIFF"))
return 1;
/* MZ is a .exe file */
@@ -74,7 +75,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* Ogg files */
- if(match_first_bytes(packet->payload, "OggS"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "OggS"))
return 1;
/* ZIP files */
@@ -86,7 +87,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* RAR files */
- if(match_first_bytes(packet->payload, "Rar!"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "Rar!"))
return 1;
/* EBML */
@@ -98,7 +99,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* GIF */
- if(match_first_bytes(packet->payload, "GIF8"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "GIF8"))
return 1;
/* PHP scripts */
@@ -110,7 +111,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* PDFs */
- if(match_first_bytes(packet->payload, "%PDF"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "%PDF"))
return 1;
/* PNG */
@@ -118,7 +119,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* HTML */
- if(match_first_bytes(packet->payload, "<htm"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "<htm"))
return 1;
if((packet->payload[0] == 0x0a) && (packet->payload[1] == '<') && (packet->payload[2] == '!') && (packet->payload[3] == 'D'))
return 1;
@@ -132,17 +133,17 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* XML */
- if(match_first_bytes(packet->payload, "<!DO"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "<!DO"))
return 1;
/* FLAC */
- if(match_first_bytes(packet->payload, "fLaC"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "fLaC"))
return 1;
/* MP3 */
if((packet->payload[0] == 'I') && (packet->payload[1] == 'D') && (packet->payload[2] == '3') && (packet->payload[3] == 0x03))
return 1;
- if(match_first_bytes(packet->payload, "\xff\xfb\x90\xc0"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "\xff\xfb\x90\xc0"))
return 1;
/* RPM */
@@ -150,7 +151,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* Wz Patch */
- if(match_first_bytes(packet->payload, "WzPa"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "WzPa"))
return 1;
/* Flash Video */
@@ -158,7 +159,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* .BKF (Microsoft Tape Format) */
- if(match_first_bytes(packet->payload, "TAPE"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "TAPE"))
return 1;
/* MS Office Doc file - this is unpleasantly geeky */
@@ -174,23 +175,23 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
/* ar archive, typically .deb files */
- if(match_first_bytes(packet->payload, "!<ar"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "!<ar"))
return 1;
/* Raw XML (skip jabber-like traffic as this is not FTP but unencrypted jabber) */
- if((match_first_bytes(packet->payload, "<?xm"))
+ if((ndpi_match_strprefix(packet->payload, payload_len, "<?xm"))
&& (ndpi_strnstr((const char *)packet->payload, "jabber", packet->payload_packet_len) == NULL))
return 1;
- if(match_first_bytes(packet->payload, "<iq "))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "<iq "))
return 1;
/* SPF */
- if(match_first_bytes(packet->payload, "SPFI"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "SPFI"))
return 1;
/* ABIF - Applied Biosystems */
- if(match_first_bytes(packet->payload, "ABIF"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, "ABIF"))
return 1;
/* bzip2 - other digits are also possible instead of 9 */
@@ -203,11 +204,11 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru
return 1;
if((packet->payload[0] == '<') && (packet->payload[1] == 'C') && (packet->payload[2] == 'F'))
return 1;
- if(match_first_bytes(packet->payload, ".tem"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, ".tem"))
return 1;
- if(match_first_bytes(packet->payload, ".ite"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, ".ite"))
return 1;
- if(match_first_bytes(packet->payload, ".lef"))
+ if(ndpi_match_strprefix(packet->payload, payload_len, ".lef"))
return 1;
return 0;
@@ -229,7 +230,6 @@ static void ndpi_check_ftp_data(struct ndpi_detection_module_struct *ndpi_struct
}
void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &flow->packet;
/* Break after 20 packets. */
if(flow->packet_counter > 20) {
diff --git a/src/lib/protocols/git.c b/src/lib/protocols/git.c
new file mode 100644
index 000000000..e156b7913
--- /dev/null
+++ b/src/lib/protocols/git.c
@@ -0,0 +1,83 @@
+/*
+ * git.c
+ *
+ * Copyright (C) 2012-16 - ntop.org
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <stdlib.h>
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_GIT
+
+#define GIT_PORT 9418
+
+void ndpi_search_git(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct * packet = &flow->packet;
+
+ if((packet->tcp != NULL) && (packet->payload_packet_len > 4)) {
+ if((ntohs(packet->tcp->source) == GIT_PORT)
+ || (ntohs(packet->tcp->dest) == GIT_PORT)) {
+ const u_int8_t * pp = packet->payload;
+ u_int16_t payload_len = packet->payload_packet_len;
+ u_int8_t found_git = 1;
+ u_int16_t git_len = 0, offset = 0;
+
+ while((offset+4) < payload_len) {
+ char len[5];
+ u_int32_t git_pkt_len;
+
+ memcpy(&len, &pp[offset], 4), len[4] = 0;
+ git_pkt_len = atoi(len);
+
+ if((payload_len < git_pkt_len) || (git_pkt_len == 0 /* Bad */)) {
+ found_git = 0;
+ break;
+ } else
+ offset += git_pkt_len, payload_len -= git_pkt_len;
+ }
+
+ if(found_git) {
+ NDPI_LOG(NDPI_PROTOCOL_GIT, ndpi_struct, NDPI_LOG_DEBUG, "found Git.\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GIT, NDPI_PROTOCOL_UNKNOWN);
+ return;
+ }
+ }
+ }
+
+ NDPI_LOG(NDPI_PROTOCOL_GIT, ndpi_struct, NDPI_LOG_DEBUG, "exclude Git.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GIT);
+}
+
+
+/* ***************************************************************** */
+
+
+void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id,
+ NDPI_PROTOCOL_BITMASK *detection_bitmask)
+{
+ ndpi_set_bitmask_protocol_detection("Git", ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_GIT,
+ ndpi_search_git,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ *id += 1;
+}
+
+#endif /* NDPI_PROTOCOL_GIT */
diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c
index 09d4d0852..e45096391 100644
--- a/src/lib/protocols/gnutella.c
+++ b/src/lib/protocols/gnutella.c
@@ -294,7 +294,7 @@ void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, stru
return;
}
- if (memcmp(packet->payload, "GND", 3) == 0) {
+ if (packet->payload_packet_len >= 3 && memcmp(packet->payload, "GND", 3) == 0) {
if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0))
|| (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5)
== 0)) || (packet->payload_packet_len == 17
diff --git a/src/lib/protocols/gtp.c b/src/lib/protocols/gtp.c
index 97044f94e..88235f2a8 100644
--- a/src/lib/protocols/gtp.c
+++ b/src/lib/protocols/gtp.c
@@ -18,7 +18,6 @@
*
*/
-
#include "ndpi_api.h"
#ifdef NDPI_PROTOCOL_GTP
diff --git a/src/lib/protocols/h323.c b/src/lib/protocols/h323.c
index 1d503a747..31d578455 100644
--- a/src/lib/protocols/h323.c
+++ b/src/lib/protocols/h323.c
@@ -27,7 +27,8 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n
NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n");
/* H323 */
- if((packet->payload[0] == 0x03)
+ if(packet->payload_packet_len >= 3
+ && (packet->payload[0] == 0x03)
&& (packet->payload[1] == 0x00)
&& (packet->payload[2] == 0x00)) {
struct tpkt *t = (struct tpkt*)packet->payload;
@@ -63,7 +64,8 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n
sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over udp.\n");
- if(packet->payload[0] == 0x80 && packet->payload[1] == 0x08 && (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) &&
+ if(packet->payload_packet_len >= 6 && packet->payload[0] == 0x80 && packet->payload[1] == 0x08 &&
+ (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) &&
packet->payload[4] == 0x00 && packet->payload[5] == 0x00)
{
NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n");
@@ -79,7 +81,7 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN);
return;
}
- else if(packet->payload_packet_len >= 20 || packet->payload_packet_len <= 117)
+ else if(packet->payload_packet_len >= 20 && packet->payload_packet_len <= 117)
{
NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN);
diff --git a/src/lib/protocols/hangout.c b/src/lib/protocols/hangout.c
new file mode 100644
index 000000000..ca53a8814
--- /dev/null
+++ b/src/lib/protocols/hangout.c
@@ -0,0 +1,105 @@
+/*
+ * hangout.c
+ *
+ * Copyright (C) 2012-16 - ntop.org
+ *
+ * This module is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "ndpi_api.h"
+
+#ifdef NDPI_SERVICE_HANGOUT
+
+/* https://support.google.com/a/answer/1279090?hl=en */
+#define HANGOUT_UDP_LOW_PORT 19302
+#define HANGOUT_UDP_HIGH_PORT 19309
+#define HANGOUT_TCP_LOW_PORT 19305
+#define HANGOUT_TCP_HIGH_PORT 19309
+
+/* ***************************************************************** */
+
+static u_int8_t isHangoutUDPPort(u_int16_t port) {
+ if((port >= HANGOUT_UDP_LOW_PORT) && (port <= HANGOUT_UDP_HIGH_PORT))
+ return(1);
+ else
+ return(0);
+}
+
+/* ***************************************************************** */
+
+static u_int8_t isHangoutTCPPort(u_int16_t port) {
+ if((port >= HANGOUT_TCP_LOW_PORT) && (port <= HANGOUT_TCP_HIGH_PORT))
+ return(1);
+ else
+ return(0);
+}
+
+/* ******************************************* */
+
+static u_int8_t google_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin) {
+ return((ndpi_network_ptree_match(ndpi_struct, pin) == NDPI_SERVICE_GOOGLE) ? 1 : 0);
+}
+
+/* ******************************************* */
+
+static u_int8_t is_google_flow(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->iph) {
+ if(google_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->saddr)
+ || google_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->daddr)) {
+ return(1);
+ }
+ }
+
+ return(0);
+}
+
+/* ***************************************************************** */
+
+void ndpi_search_hangout(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct * packet = &flow->packet;
+
+ if((packet->payload_packet_len > 24) && is_google_flow(ndpi_struct, flow)) {
+ if(
+ ((packet->udp != NULL) && (isHangoutUDPPort(ntohs(packet->udp->source)) || isHangoutUDPPort(ntohs(packet->udp->dest))))
+ ||
+ ((packet->tcp != NULL) && (isHangoutTCPPort(ntohs(packet->tcp->source)) || isHangoutTCPPort(ntohs(packet->tcp->dest))))) {
+ NDPI_LOG(NDPI_SERVICE_HANGOUT, ndpi_struct, NDPI_LOG_DEBUG, "Found Hangout.\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_SERVICE_HANGOUT, NDPI_PROTOCOL_UNKNOWN);
+ return;
+ }
+ }
+
+ NDPI_LOG(NDPI_SERVICE_HANGOUT, ndpi_struct, NDPI_LOG_DEBUG, "No Hangout.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_SERVICE_HANGOUT);
+}
+
+/* ***************************************************************** */
+
+void init_hangout_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id,
+ NDPI_PROTOCOL_BITMASK *detection_bitmask) {
+ ndpi_set_bitmask_protocol_detection("GoogleHangout", ndpi_struct, detection_bitmask, *id,
+ NDPI_SERVICE_HANGOUT,
+ ndpi_search_hangout,
+ NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ *id += 1;
+}
+
+#endif /* NDPI_SERVICE_HANGOUT */
diff --git a/src/lib/protocols/kakaotalk_voice.c b/src/lib/protocols/kakaotalk_voice.c
index c6972c7a1..368532c5d 100644
--- a/src/lib/protocols/kakaotalk_voice.c
+++ b/src/lib/protocols/kakaotalk_voice.c
@@ -33,7 +33,7 @@ void ndpi_search_kakaotalk_voice(struct ndpi_detection_module_struct *ndpi_struc
if(packet->iph
&& packet->udp
- && (packet->payload_packet_len > 0)
+ && (packet->payload_packet_len >= 4)
) {
if((packet->payload[0] == 0x81)
|| (packet->payload[1] == 0xC8)
diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c
index c62c1d366..4e352583e 100644
--- a/src/lib/protocols/mail_imap.c
+++ b/src/lib/protocols/mail_imap.c
@@ -1,8 +1,7 @@
/*
* mail_imap.c
*
- * Copyright (C) 2009-2011 by ipoque GmbH
- * Copyright (C) 2011-15 - ntop.org
+ * Copyright (C) 2016 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -42,6 +41,15 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
/* const u_int8_t *command = 0; */
NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "search IMAP.\n");
+
+ if (flow->l4.tcp.mail_imap_starttls == 2) {
+#ifdef NDPI_PROTOCOL_SSL
+ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "starttls detected\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_IMAP);
+ NDPI_DEL_PROTOCOL_FROM_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL);
+ return;
+#endif
+ }
if (packet->payload_packet_len >= 4 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
// the DONE command appears without a tag
@@ -62,7 +70,7 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
}
if (!((packet->payload[i] >= 'a' && packet->payload[i] <= 'z') ||
(packet->payload[i] >= 'A' && packet->payload[i] <= 'Z') ||
- (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*')) {
+ (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*' || packet->payload[i] == '.')) {
goto imap_excluded;
}
i++;
@@ -99,6 +107,8 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
&& (packet->payload[command_start + 1] == 'K' || packet->payload[command_start + 1] == 'k')
&& packet->payload[command_start + 2] == ' ') {
flow->l4.tcp.mail_imap_stage += 1;
+ if (flow->l4.tcp.mail_imap_starttls == 1)
+ flow->l4.tcp.mail_imap_starttls = 2;
saw_command = 1;
} else if ((packet->payload[command_start] == 'U' || packet->payload[command_start] == 'u')
&& (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i')
@@ -131,8 +141,10 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
&& (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't')
&& (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l')
&& (packet->payload[command_start + 7] == 'S' || packet->payload[command_start + 7] == 's')) {
- flow->l4.tcp.mail_imap_stage += 1;
- saw_command = 1;
+ flow->l4.tcp.mail_imap_stage += 1;
+ flow->l4.tcp.mail_imap_starttls = 1;
+ flow->detected_protocol_stack[0] = NDPI_PROTOCOL_MAIL_IMAPS;
+ saw_command = 1;
}
}
if ((command_start + 5) < packet->payload_packet_len) {
diff --git a/src/lib/protocols/mqtt.c b/src/lib/protocols/mqtt.c
index 024fad8a7..37c469066 100644
--- a/src/lib/protocols/mqtt.c
+++ b/src/lib/protocols/mqtt.c
@@ -144,7 +144,7 @@ void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct,
NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Passed second stage of identification\n");
// third stage verification (payload)
if (pt == CONNECT) {
- if (memcmp(&(packet->payload[4]),"MQTT",4) == 0) {
+ if (packet->payload_packet_len >= 8 && memcmp(&(packet->payload[4]),"MQTT",4) == 0) {
NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found CONNECT\n");
ndpi_int_mqtt_add_connection(ndpi_struct,flow);
return;
diff --git a/src/lib/protocols/msn.c b/src/lib/protocols/msn.c
index af537d7ff..ff81a12b3 100644
--- a/src/lib/protocols/msn.c
+++ b/src/lib/protocols/msn.c
@@ -130,7 +130,7 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct
if (get_u_int8_t(packet->payload, packet->payload_packet_len - 2) == 0x0d
&& get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a) {
/* The MSNP string is used in XBOX clients. */
- if (memcmp(packet->payload, "VER ", 4) == 0) {
+ if (ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "VER ")) {
if (memcmp(&packet->payload[packet->payload_packet_len - 6], "CVR",
3) == 0 || memcmp(&packet->payload[packet->payload_packet_len - 8], "MSNP", 4) == 0) {
@@ -139,7 +139,7 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct
ndpi_int_msn_add_connection(ndpi_struct, flow);
return;
}
- if (memcmp(&packet->payload[4], "MSNFT", 5) == 0) {
+ if (ndpi_match_strprefix(&packet->payload[4], packet->payload_packet_len-4, "MSNFT")) {
NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE,
"found MSN FT by pattern VER MSNFT...0d0a.\n");
ndpi_int_msn_add_connection(ndpi_struct, flow);
@@ -153,8 +153,8 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct
#ifdef NDPI_PROTOCOL_HTTP
packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
#endif
- memcmp(packet->payload, "GET ", NDPI_STATICSTRING_LEN("GET ")) == 0 ||
- memcmp(packet->payload, "POST ", NDPI_STATICSTRING_LEN("POST ")) == 0) {
+ ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "GET ") ||
+ ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "POST ")) {
ndpi_parse_packet_line_info(ndpi_struct, flow);
if (packet->user_agent_line.ptr != NULL &&
packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Messenger/") &&
@@ -277,8 +277,8 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct
#ifdef NDPI_PROTOCOL_HTTP
packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP ||
#endif
- (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) ||
- (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0)
+ ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "HTTP/1.0 200 OK") ||
+ ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "HTTP/1.1 200 OK")
) {
ndpi_parse_packet_line_info(ndpi_struct, flow);
diff --git a/src/lib/protocols/netbios.c b/src/lib/protocols/netbios.c
index 9c2283a81..ca649782b 100644
--- a/src/lib/protocols/netbios.c
+++ b/src/lib/protocols/netbios.c
@@ -324,7 +324,7 @@ void ndpi_search_netbios(struct ndpi_detection_module_struct *ndpi_struct, struc
NDPI_LOG_DEBUG, "found netbios with checked ip-address.\n");
if(netbios_name_interpret((char*)&packet->payload[12], name, sizeof(name)) > 0)
- snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name), "%s", name);
+ snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name)-1, "%s", name);
ndpi_int_netbios_add_connection(ndpi_struct, flow);
return;
diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c
index a0fa92a20..6e355c9f8 100644
--- a/src/lib/protocols/ntp.c
+++ b/src/lib/protocols/ntp.c
@@ -22,54 +22,44 @@
*
*/
-
#include "ndpi_protocols.h"
+
#ifdef NDPI_PROTOCOL_NTP
+
static void ndpi_int_ntp_add_connection(struct ndpi_detection_module_struct
*ndpi_struct, struct ndpi_flow_struct *flow)
{
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NTP, NDPI_PROTOCOL_UNKNOWN);
}
-/* detection also works asymmetrically */
-
void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
- struct ndpi_packet_struct *packet = &flow->packet;
-
-// struct ndpi_id_struct *src=ndpi_struct->src;
-// struct ndpi_id_struct *dst=ndpi_struct->dst;
-
- if (!(packet->udp->dest == htons(123) || packet->udp->source == htons(123)))
- goto exclude_ntp;
-
- NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n");
-
- // It's not correct because packets could be bigger
- //if (packet->payload_packet_len != 48)
- // goto exclude_ntp;
-
- NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n");
-
-
- if ((((packet->payload[0] & 0x38) >> 3) <= 4)) {
- NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP.");
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if (!(packet->udp->dest == htons(123) || packet->udp->source == htons(123)))
+ goto exclude_ntp;
+
+ NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n");
+
+ NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n");
+
+
+ if ((((packet->payload[0] & 0x38) >> 3) <= 4)) {
+ NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP.");
- // 38 in binary representation is 00111000
- flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3;
-
- if (flow->protos.ntp.version == 2) {
- flow->protos.ntp.request_code = packet->payload[3];
- }
-
- ndpi_int_ntp_add_connection(ndpi_struct, flow);
- return;
- }
-
-
-
- exclude_ntp:
+ // 38 in binary representation is 00111000
+ flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3;
+
+ if (flow->protos.ntp.version == 2) {
+ flow->protos.ntp.request_code = packet->payload[3];
+ }
+
+ ndpi_int_ntp_add_connection(ndpi_struct, flow);
+ return;
+ }
+
+ exclude_ntp:
NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP excluded.\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NTP);
}
diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c
index 9005dc3ff..3e8412355 100644
--- a/src/lib/protocols/openvpn.c
+++ b/src/lib/protocols/openvpn.c
@@ -1,68 +1,113 @@
/*
- * h323.c
+ * openvpn.c
*
- * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
+ * Copyright (C) 2011-16 - ntop.org
+ *
+ * OpenVPN TCP / UDP Detection - 128/160 hmac
+ *
+ * Detection based upon these openvpn protocol properties:
+ * - opcode
+ * - packet ID
+ * - session ID
+ *
+ * Two (good) packets are needed to perform detection.
+ * - First packet from client: save session ID
+ * - Second packet from server: report saved session ID
+ *
+ * TODO
+ * - Support PSK only mode (instead of TLS)
+ * - Support PSK + TLS mode (PSK used for early authentication)
+ * - TLS certificate extraction
*
*/
#include "ndpi_api.h"
-
#ifdef NDPI_PROTOCOL_OPENVPN
+#define P_CONTROL_HARD_RESET_CLIENT_V1 (0x01 << 3)
+#define P_CONTROL_HARD_RESET_CLIENT_V2 (0x07 << 3)
+#define P_CONTROL_HARD_RESET_SERVER_V1 (0x02 << 3)
+#define P_CONTROL_HARD_RESET_SERVER_V2 (0x08 << 3)
+#define P_OPCODE_MASK 0xF8
+#define P_SHA1_HMAC_SIZE 20
+#define P_HMAC_128 16 // (RSA-)MD5, (RSA-)MD4, ..others
+#define P_HMAC_160 20 // (RSA-|DSA-)SHA(1), ..others, SHA1 is openvpn default
+#define P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) (9 + hmac_size)
+#define P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) (P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) + 8)
+#define P_HARD_RESET_CLIENT_MAX_COUNT 5
+
+static inline u_int32_t get_packet_id(const u_int8_t * payload, u_int8_t hms) {
+ return ntohl(*(u_int32_t*)(payload + P_HARD_RESET_PACKET_ID_OFFSET(hms)));
+}
+
+static inline int8_t check_pkid_and_detect_hmac_size(const u_int8_t * payload) {
+ // try to guess
+ if (get_packet_id(payload, P_HMAC_160) == 1)
+ return P_HMAC_160;
+ if (get_packet_id(payload, P_HMAC_128) == 1)
+ return P_HMAC_128;
+ return -1;
+}
+
void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct,
struct ndpi_flow_struct* flow) {
struct ndpi_packet_struct* packet = &flow->packet;
- u_int16_t dport = 0, sport = 0;
-
- if (packet->udp != NULL) {
-
- sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
-
- if ((packet->payload_packet_len >= 25) && (sport == 443 || dport == 443) &&
- (packet->payload[0] == 0x17 && packet->payload[1] == 0x01 &&
- packet->payload[2] == 0x00 && packet->payload[3] == 0x00)) {
- NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
- "found openvpn udp 443.\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN);
- return;
- }
-
- if ( ( (packet->payload_packet_len > 40) ||
- (packet->payload_packet_len <= 14) ) && // hard-reset
- (sport == 1194 || dport == 1194) &&
- (packet->payload[0] == 0x30 || packet->payload[0] == 0x31 ||
- packet->payload[0] == 0x32 || packet->payload[0] == 0x33 ||
- packet->payload[0] == 0x34 || packet->payload[0] == 0x35 ||
- packet->payload[0] == 0x36 || packet->payload[0] == 0x37 ||
- packet->payload[0] == 0x38 || packet->payload[0] == 0x39)) {
- NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
- "found openvpn broadcast udp STD.\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN);
- return;
- }
-
- }
-
- if (packet->tcp != NULL) {
-
- sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
-
- if ((packet->payload_packet_len >= 40) &&
- (sport == 1194 || dport == 1194) &&
- ((packet->payload[0] == 0x00) && (packet->payload[1] == 0x2a) &&
- (packet->payload[2] == 0x38))) {
- NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
- "found openvpn broadcast udp STD.\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN);
- return;
- }
+ const u_int8_t * ovpn_payload = packet->payload;
+ const u_int8_t * session_remote;
+ u_int8_t opcode;
+ u_int8_t alen;
+ int8_t hmac_size;
+ int8_t failed = 0;
+
+ if (packet->payload_packet_len >= 40) {
+ // skip openvpn TCP transport packet size
+ if (packet->tcp != NULL)
+ ovpn_payload += 2;
+
+ opcode = ovpn_payload[0] & P_OPCODE_MASK;
+
+ if (flow->ovpn_counter < P_HARD_RESET_CLIENT_MAX_COUNT && (opcode == P_CONTROL_HARD_RESET_CLIENT_V1 ||
+ opcode == P_CONTROL_HARD_RESET_CLIENT_V2)) {
+
+ if (check_pkid_and_detect_hmac_size(ovpn_payload) > 0) {
+ memcpy(flow->ovpn_session_id, ovpn_payload+1, 8);
+
+ NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
+ "session key: %02x%02x%02x%02x%02x%02x%02x%02x\n",
+ flow->ovpn_session_id[0], flow->ovpn_session_id[1], flow->ovpn_session_id[2], flow->ovpn_session_id[3],
+ flow->ovpn_session_id[4], flow->ovpn_session_id[5], flow->ovpn_session_id[6], flow->ovpn_session_id[7]);
+ }
+ } else if (flow->ovpn_counter >= 1 && flow->ovpn_counter <= P_HARD_RESET_CLIENT_MAX_COUNT &&
+ (opcode == P_CONTROL_HARD_RESET_SERVER_V1 || opcode == P_CONTROL_HARD_RESET_SERVER_V2)) {
+
+ hmac_size = check_pkid_and_detect_hmac_size(ovpn_payload);
+
+ if (hmac_size > 0) {
+ alen = ovpn_payload[P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size)];
+ session_remote = ovpn_payload + P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) + 1 + alen * 4;
+
+ if (memcmp(flow->ovpn_session_id, session_remote, 8) == 0)
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN);
+ else {
+ NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG,
+ "key mismatch: %02x%02x%02x%02x%02x%02x%02x%02x\n",
+ session_remote[0], session_remote[1], session_remote[2], session_remote[3],
+ session_remote[4], session_remote[5], session_remote[6], session_remote[7]);
+ failed = 1;
+ }
+ } else
+ failed = 1;
+ } else
+ failed = 1;
+
+ flow->ovpn_counter++;
+
+ if (failed)
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENVPN);
}
-
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENVPN);
}
-
void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
{
ndpi_set_bitmask_protocol_detection("OpenVPN", ndpi_struct, detection_bitmask, *id,
diff --git a/src/lib/protocols/oscar.c b/src/lib/protocols/oscar.c
index a43394a8d..869b36378 100644
--- a/src/lib/protocols/oscar.c
+++ b/src/lib/protocols/oscar.c
@@ -244,10 +244,19 @@ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct
*/
if (channel == DATA)
{
- family = get_u_int16_t(packet->payload, 6);
- type = get_u_int16_t(packet->payload, 8);
- flag = get_u_int16_t(packet->payload, 10);
- req_ID = get_u_int32_t(packet->payload, 12);
+ if (packet->payload_packet_len >= 8)
+ family = get_u_int16_t(packet->payload, 6);
+ else
+ family = 0;
+ if (packet->payload_packet_len >= 10)
+ type = get_u_int16_t(packet->payload, 8);
+ else
+ type = 0;
+ if (family == 0 || type == 0)
+ {
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR);
+ return;
+ }
/* Family 0x0001 */
if (family == htons(GE_SE_CTL))
@@ -561,16 +570,24 @@ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct
}
/* flag */
- if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001))
- {
- /* request ID */
- if((req_ID <= 4294967295))
+ if (packet->payload_packet_len >= 12)
+ {
+ flag = get_u_int16_t(packet->payload, 10);
+ if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001))
+ {
+ if (packet->payload_packet_len >= 16)
{
- NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n");
- ndpi_int_oscar_add_connection(ndpi_struct, flow);
- return;
+ /* request ID */
+ req_ID = get_u_int32_t(packet->payload, 12);
+ if((req_ID <= 4294967295))
+ {
+ NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n");
+ ndpi_int_oscar_add_connection(ndpi_struct, flow);
+ return;
+ }
}
- }
+ }
+ }
}
/*
ERROR -> FLAP__ERROR_CHANNEL_0x03
diff --git a/src/lib/protocols/pando.c b/src/lib/protocols/pando.c
index f3ed00783..b906e7ed9 100644
--- a/src/lib/protocols/pando.c
+++ b/src/lib/protocols/pando.c
@@ -34,7 +34,7 @@ static void ndpi_check_pando_tcp(struct ndpi_detection_module_struct *ndpi_struc
struct ndpi_packet_struct *packet = &flow->packet;
u_int32_t payload_len = packet->payload_packet_len;
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\x0ePan")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\x0ePan")) {
NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n");
ndpi_int_pando_add_connection(ndpi_struct, flow);
}
@@ -56,7 +56,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc
return;
}
- if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "UDPA")) {
NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -64,7 +64,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc
return;
}
- if ((payload_len > 0) && (match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE"))) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "UDPR") || ndpi_match_strprefix(packet->payload, payload_len, "UDPE")) {
NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -98,7 +98,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len == 0) || match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE")) {
+ if ((payload_len == 0) || (ndpi_match_strprefix(packet->payload, payload_len, "UDPR") || ndpi_match_strprefix(packet->payload, payload_len, "UDPE"))) {
NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n");
ndpi_int_pando_add_connection(ndpi_struct, flow);
} else {
@@ -115,7 +115,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "UDPA")) {
NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n");
ndpi_int_pando_add_connection(ndpi_struct, flow);
} else {
diff --git a/src/lib/protocols/pplive.c b/src/lib/protocols/pplive.c
index cf9260f17..2e4747159 100644
--- a/src/lib/protocols/pplive.c
+++ b/src/lib/protocols/pplive.c
@@ -39,7 +39,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str
if (flow->pplive_stage1 == 0) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n");
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -47,7 +47,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str
return;
}
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x42\x01")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x42\x01")) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -55,7 +55,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str
return;
}
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\x1c\x1c\x32\x01")) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -72,7 +72,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len > 0) && (match_first_bytes(packet->payload, "\xe9\x03\x42\x01") || match_first_bytes(packet->payload, "\xe9\x03\x41\x01"))) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x42\x01") || ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
ndpi_int_pplive_add_connection(ndpi_struct, flow);
} else {
@@ -89,7 +89,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
ndpi_int_pplive_add_connection(ndpi_struct, flow);
} else {
@@ -105,7 +105,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\x1c\x1c\x32\x01")) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n");
ndpi_int_pplive_add_connection(ndpi_struct, flow);
} else {
@@ -124,7 +124,7 @@ static void ndpi_check_pplive_udp2(struct ndpi_detection_module_struct *ndpi_str
if (flow->pplive_stage2 == 0) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n");
- if ((payload_len == 57) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) {
+ if ((payload_len == 57) && ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) {
NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c
index 2bece25a7..8050a9b61 100644
--- a/src/lib/protocols/quic.c
+++ b/src/lib/protocols/quic.c
@@ -1,11 +1,12 @@
/*
* quic.c
*
+ * Copyright (C) 2012-16 - ntop.org
+ *
+ * Based on code of:
* Andrea Buscarinu - <andrea.buscarinu@gmail.com>
* Michele Campus - <campus@ntop.org>
*
- * Copyright (C) 2012-15 - ntop.org
- *
* This module is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -21,164 +22,122 @@
*
*/
-
#include "ndpi_api.h"
-#define QUIC_NO_V_RES_RSV 0xC3 // 1100 0011
-
-#define QUIC_CID_MASK 0x0C // 0000 1100
-#define QUIC_VER_MASK 0x01 // 0000 0001
-#define QUIC_SEQ_MASK 0x30 // 0011 0000
-
-#define CID_LEN_8 0x0C // 0000 1100
-#define CID_LEN_4 0x08 // 0000 1000
-#define CID_LEN_1 0x04 // 0000 0100
-#define CID_LEN_0 0x00 // 0000 0000
-
-#define SEQ_LEN_6 0x30 // 0011 0000
-#define SEQ_LEN_4 0x20 // 0010 0000
-#define SEQ_LEN_2 0x10 // 0001 0000
-#define SEQ_LEN_1 0x00 // 0000 0000
-
-#define SEQ_CONV(ARR) (ARR[0] | ARR[1] | ARR[2] | ARR[3] | ARR[4] | ARR[5] << 8)
-
-
#ifdef NDPI_PROTOCOL_QUIC
-static void ndpi_int_quic_add_connection(struct ndpi_detection_module_struct
- *ndpi_struct, struct ndpi_flow_struct *flow)
+
+static int quic_ports(u_int16_t sport, u_int16_t dport)
{
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN);
+ if ((sport == 443 || dport == 443 || sport == 80 || dport == 80) &&
+ (sport != 123 && dport != 123))
+ return 1;
+
+ return 0;
}
-static int connect_id(const unsigned char pflags)
-{
- u_int cid_len;
-
- // Check CID length.
- switch (pflags & QUIC_CID_MASK)
- {
- case CID_LEN_8: cid_len = 8; break;
- case CID_LEN_4: cid_len = 4; break;
- case CID_LEN_1: cid_len = 1; break;
- case CID_LEN_0: cid_len = 0; break;
- default:
- return -1;
-
- }
- // Return offset.
- return cid_len + 1;
+/* ***************************************************************** */
+
+static int quic_len(u_int8_t l) {
+ switch(l) {
+ case 0:
+ return(1);
+ break;
+ case 1:
+ return(2);
+ break;
+ case 2:
+ return(4);
+ break;
+ case 3:
+ return(8);
+ break;
+ }
+
+ return(0); /* NOTREACHED */
}
-static int sequence(const unsigned char *payload)
+/* ***************************************************************** */
+
+void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
{
- unsigned char conv[6] = {0};
- u_int seq_value = -1;
- int seq_lens;
- int cid_offs;
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t udp_len = packet->payload_packet_len;
+ u_int version_len = ((packet->payload[0] & 0x01) == 0) ? 0 : 4;
+ u_int cid_len = quic_len((packet->payload[0] & 0x0C) >> 2);
+ u_int seq_len = quic_len((packet->payload[0] & 0x30) >> 4);
+ u_int quic_hlen = 1 /* flags */ + version_len + seq_len + cid_len;
+
+ if(packet->udp != NULL
+ && (udp_len > (quic_hlen+4 /* QXXX */))
+ && ((packet->payload[0] & 0xC2) == 0x00)
+ && (quic_ports(ntohs(packet->udp->source), ntohs(packet->udp->dest)))
+ ) {
+ char *begin;
int i;
- // Search SEQ bytes length.
- switch (payload[0] & QUIC_SEQ_MASK)
- {
- case SEQ_LEN_6: seq_lens = 6; break;
- case SEQ_LEN_4: seq_lens = 4; break;
- case SEQ_LEN_2: seq_lens = 2; break;
- case SEQ_LEN_1: seq_lens = 1; break;
- default:
- return -1;
- }
- // Retrieve SEQ offset.
- cid_offs = connect_id(payload[0]);
-
- if (cid_offs >= 0 && seq_lens > 0)
- {
- for (i = 0; i < seq_lens; i++)
- conv[i] = payload[cid_offs + i];
-
- seq_value = SEQ_CONV(conv);
- }
-
- // Return SEQ dec value;
- return seq_value;
-}
+ if((version_len > 0) && (packet->payload[1+cid_len] != 'Q'))
+ goto no_quic;
-void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
-{
- struct ndpi_packet_struct *packet = &flow->packet;
- int ver_offs;
-
- if(packet->udp != NULL) {
-
- u_int16_t sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
-
- NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "calculating quic over udp.\n");
-
- if((((sport == 80) || (dport == 80) || (sport == 443) || (dport == 443))))
- {
- NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n");
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC);
-
-
- // Settings without version. First check if PUBLIC FLAGS & SEQ bytes are 0x0. SEQ must be 1 at least.
- if ((packet->payload[0] == 0x00 && packet->payload[1] != 0x00) || ((packet->payload[0] & QUIC_NO_V_RES_RSV) == 0))
- {
- if (sequence(packet->payload) < 1)
- {
-
- NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n");
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC);
- }
+ NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found QUIC.\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN);
- NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n");
- ndpi_int_quic_add_connection(ndpi_struct, flow);
- }
+ if(udp_len > quic_hlen + 17 + 4 &&
+ !strncmp((char*)&packet->payload[quic_hlen+17], "CHLO" /* Client Hello */, 4)) {
+ /* Check if SNI (Server Name Identification) is present */
+ for(i=quic_hlen+12; i<udp_len-3; i++) {
+ if((packet->payload[i] == 'S')
+ && (packet->payload[i+1] == 'N')
+ && (packet->payload[i+2] == 'I')
+ && (packet->payload[i+3] == 0)) {
+ u_int32_t offset = *((u_int32_t*)&packet->payload[i+4]);
+ u_int32_t prev_offset = *((u_int32_t*)&packet->payload[i-4]);
+ int len = offset-prev_offset;
+ int sni_offset = i+prev_offset+1;
+
+ while((sni_offset < udp_len) && (packet->payload[sni_offset] == '-'))
+ sni_offset++;
- // Check if version, than the CID length.
- else if (packet->payload[0] & QUIC_VER_MASK)
- {
- // Skip CID length.
- ver_offs = connect_id(packet->payload[0]);
-
- if (ver_offs >= 0)
- {
- unsigned char vers[] = {packet->payload[ver_offs], packet->payload[ver_offs + 1],
- packet->payload[ver_offs + 2], packet->payload[ver_offs + 3]};
-
- // Version Match.
- if ((vers[0] == 'Q' && vers[1] == '0') &&
- ((vers[2] == '2' && (vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' ||
- vers[3] == '1' || vers[3] == '0')) ||
- (vers[2] == '1' && (vers[3] == '9' || vers[3] == '8' || vers[3] == '7' || vers[3] == '6' ||
- vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' ||
- vers[3] == '1' || vers[3] == '0')) ||
- (vers[2] == '0' && vers[3] == '9')))
-
- {
- NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n");
- ndpi_int_quic_add_connection(ndpi_struct, flow);
+ if((sni_offset+len) < udp_len) {
+ int max_len = sizeof(flow->host_server_name)-1, j = 0;
+
+ if(len > max_len) len = max_len;
+
+ while((len > 0) && (sni_offset < udp_len)) {
+ flow->host_server_name[j++] = packet->payload[sni_offset];
+ sni_offset++, len--;
}
+
+ ndpi_match_host_subprotocol(ndpi_struct, flow,
+ (char *)flow->host_server_name,
+ strlen((const char*)flow->host_server_name),
+ NDPI_PROTOCOL_QUIC);
+
}
+
+ break;
}
- }
- else
- {
- NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n");
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC);
}
}
+ return;
+ }
+
+ no_quic:
+ NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude QUIC.\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC);
}
+/* ***************************************************************** */
-void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
+void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id,
+ NDPI_PROTOCOL_BITMASK *detection_bitmask)
{
- ndpi_set_bitmask_protocol_detection("Quic", ndpi_struct, detection_bitmask, *id,
- NDPI_PROTOCOL_QUIC,
- ndpi_search_quic,
+ ndpi_set_bitmask_protocol_detection("QUIC", ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_QUIC, ndpi_search_quic,
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
- SAVE_DETECTION_BITMASK_AS_UNKNOWN,
- ADD_TO_DETECTION_BITMASK);
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK);
*id += 1;
}
-#endif
+#endif /* NDPI_PROTOCOL_QUIC */
diff --git a/src/lib/protocols/radius.c b/src/lib/protocols/radius.c
index 625dc4108..308049522 100644
--- a/src/lib/protocols/radius.c
+++ b/src/lib/protocols/radius.c
@@ -37,12 +37,11 @@ static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct,
if(packet->udp != NULL) {
struct radius_header *h = (struct radius_header*)packet->payload;
- u_int len = ntohs(h->len);
if((payload_len > sizeof(struct radius_header))
&& (h->code > 0)
&& (h->code <= 5)
- && (len == payload_len)) {
+ && (ntohs(h->len) == payload_len)) {
NDPI_LOG(NDPI_PROTOCOL_RADIUS, ndpi_struct, NDPI_LOG_DEBUG, "Found radius.\n");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RADIUS, NDPI_PROTOCOL_UNKNOWN);
diff --git a/src/lib/protocols/rtcp.c b/src/lib/protocols/rtcp.c
index c8fc90953..cc6265220 100644
--- a/src/lib/protocols/rtcp.c
+++ b/src/lib/protocols/rtcp.c
@@ -38,7 +38,7 @@ void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct n
/* Let's check first the RTCP packet length */
u_int16_t len, offset = 0, rtcp_section_len;
- while(offset < packet->payload_packet_len) {
+ while(offset + 3 < packet->payload_packet_len) {
len = packet->payload[2+offset] * 256 + packet->payload[2+offset+1];
rtcp_section_len = (len + 1) * 4;
@@ -48,11 +48,11 @@ void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct n
offset += rtcp_section_len;
}
- sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n");
- if(((packet->payload_packet_len >= 28 || packet->payload_packet_len <= 1200) &&
+ /* TODO changed a pair of length condition to the && from ||. Is it correct? */
+ if(((packet->payload_packet_len >= 28 && packet->payload_packet_len <= 1200) &&
((packet->payload[0] == 0x80) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) && (packet->payload[2] == 0x00)))
- || (((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9))
+ || (packet->payload_packet_len >= 3 && ((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9))
&& (packet->payload[2] == 0x00)))) {
NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "found rtcp.\n");
ndpi_int_rtcp_add_connection(ndpi_struct, flow);
diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c
index 17744ed95..9bcaec941 100644
--- a/src/lib/protocols/rtp.c
+++ b/src/lib/protocols/rtp.c
@@ -73,6 +73,8 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
const u_int8_t * payload, const u_int16_t payload_len)
{
+ if (payload_len < 2)
+ return;
//struct ndpi_packet_struct *packet = &flow->packet;
u_int8_t payloadType, payload_type = payload[1] & 0x7F;
u_int32_t *ssid = (u_int32_t*)&payload[8];
diff --git a/src/lib/protocols/rx.c b/src/lib/protocols/rx.c
new file mode 100644
index 000000000..9d27d5e18
--- /dev/null
+++ b/src/lib/protocols/rx.c
@@ -0,0 +1,234 @@
+/*
+ * rx.c
+ *
+ * Copyright (C) 2012-16 - ntop.org
+ *
+ * Giovanni Mascellani <gio@debian.org>
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_api.h"
+
+#ifdef NDPI_PROTOCOL_RX
+
+/* See http://web.mit.edu/kolya/afs/rx/rx-spec for procotol description. */
+
+/* The should be no need for explicit packing, but just in case... */
+PACK_ON
+struct ndpi_rx_header {
+ u_int32_t conn_epoch;
+ u_int32_t conn_id;
+ u_int32_t call_number;
+ u_int32_t sequence_number;
+ u_int32_t serial_number;
+ u_int8_t type;
+ u_int8_t flags;
+ u_int8_t status;
+ u_int8_t security;
+ u_int16_t checksum;
+ u_int16_t service_id;
+} PACK_OFF;
+
+/* Type values */
+#define DATA 1
+#define ACK 2
+#define BUSY 3
+#define ABORT 4
+#define ACKALL 5
+#define CHALLENGE 6
+#define RESPONSE 7
+#define DEBUG 8
+#define PARAM_1 9
+#define PARAM_2 10
+#define PARAM_3 11
+#define PARAMS_4 12
+#define VERSION 13
+
+/* Flags values */
+#define EMPTY 0
+#define CLIENT_INIT_1 1
+#define REQ_ACK 2
+#define PLUS_0 3
+#define LAST_PKT 4
+#define PLUS_1 5
+#define PLUS_2 6
+#define MORE_1 9
+#define CLIENT_INIT_2 33
+
+
+
+void ndpi_check_rx(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ u_int32_t payload_len = packet->payload_packet_len;
+ int found = 0;
+
+
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "RX: pck: %d, dir[0]: %d, dir[1]: %d\n",
+ flow->packet_counter, flow->packet_direction_counter[0], flow->packet_direction_counter[1]);
+
+ /* Check that packet is long enough */
+ if (payload_len < sizeof(struct ndpi_rx_header)) {
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX);
+ return;
+ }
+
+ struct ndpi_rx_header *header = (struct ndpi_rx_header*) packet->payload;
+
+ /**
+ * Useless check: a session could be detected also after it starts
+ * and this check limit the correct detection for -d option (disable guess)
+ * TODO - maybe to improve
+ **/
+ /* Check whether the packet has counters beginning from one; the
+ Sequence Number can be zero if the packet is just an ACK. */
+ /* if ((ntohl(header->sequence_number) | 1) != 1 || ntohl(header->serial_number) != 1) */
+
+
+ /**
+ * Check the TYPE and FLAGS fields of an RX packet header.
+ * This check is necessary because we could detect an RX session already begun
+ **/
+
+ /* TYPE field */
+ if((header->type < DATA) || (header->type > VERSION)) {
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX);
+ return;
+ }
+
+ /* FLAGS fields */
+ if(header->flags == EMPTY || header->flags == LAST_PKT ||
+ header->flags == PLUS_0 || header->flags == PLUS_1 ||
+ header->flags == PLUS_2 || header->flags == REQ_ACK ||
+ header->flags == MORE_1 || header->flags == CLIENT_INIT_1 ||
+ header->flags == CLIENT_INIT_2) {
+
+ /* TYPE and FLAGS combo */
+ switch(header->type)
+ {
+ case DATA:
+ if(header->flags == LAST_PKT || header->flags == EMPTY ||
+ header->flags == PLUS_0 || header->flags == PLUS_1 ||
+ header->flags == PLUS_2 || header->flags == REQ_ACK ||
+ header->flags == MORE_1)
+ goto security;
+ case ACK:
+ if(header->flags == CLIENT_INIT_1 || header->flags == CLIENT_INIT_2 ||
+ header->flags == EMPTY)
+ goto security;
+ case CHALLENGE:
+ if(header->flags == EMPTY || header->call_number == 0)
+ goto security;
+ case RESPONSE:
+ if(header->flags == EMPTY || header->call_number == 0)
+ goto security;
+ case ACKALL:
+ if(header->flags == EMPTY)
+ goto security;
+ case BUSY:
+ goto security;
+ case ABORT:
+ goto security;
+ case DEBUG:
+ goto security;
+ case PARAM_1:
+ goto security;
+ case PARAM_2:
+ goto security;
+ case PARAM_3:
+ goto security;
+ case VERSION:
+ goto security;
+ default:
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX);
+ return;
+ } // switch
+ } else { // FLAG
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX);
+ return;
+ }
+
+ security:
+ /* SECURITY field */
+ if(header->security > 3)
+ {
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX);
+ return;
+ }
+
+ /* If we have already seen one packet in the other direction, then
+ the two must have matching connection numbers. Otherwise store
+ them. */
+ if(flow->packet_direction_counter[!packet->packet_direction] != 0)
+ {
+ if (flow->l4.udp.rx_conn_epoch == header->conn_epoch &&
+ flow->l4.udp.rx_conn_id == header->conn_id)
+ {
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "found RX\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RX, NDPI_PROTOCOL_UNKNOWN);
+ }
+ /* https://www.central.org/frameless/numbers/rxservice.html. */
+ else
+ {
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n");
+ NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX);
+ return;
+ }
+ } else {
+ flow->l4.udp.rx_conn_epoch = header->conn_epoch;
+ flow->l4.udp.rx_conn_id = header->conn_id;
+ {
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "found RX\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RX, NDPI_PROTOCOL_UNKNOWN);
+ }
+ }
+}
+
+void ndpi_search_rx(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "entering RX search\n");
+ if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_RX) {
+ ndpi_check_rx(ndpi_struct, flow);
+ }
+}
+
+void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id,
+ NDPI_PROTOCOL_BITMASK *detection_bitmask)
+{
+ ndpi_set_bitmask_protocol_detection("RX", ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_RX,
+ ndpi_search_rx,
+ NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ *id += 1;
+}
+
+#endif
diff --git a/src/lib/protocols/spotify.c b/src/lib/protocols/spotify.c
index 274312163..e7dac5d66 100644
--- a/src/lib/protocols/spotify.c
+++ b/src/lib/protocols/spotify.c
@@ -54,7 +54,7 @@ static void ndpi_check_spotify(struct ndpi_detection_module_struct *ndpi_struct,
}
} else if(packet->tcp != NULL) {
- if(packet->payload[0] == 0x00 && packet->payload[1] == 0x04 &&
+ if(payload_len >= 8 && packet->payload[0] == 0x00 && packet->payload[1] == 0x04 &&
packet->payload[2] == 0x00 && packet->payload[3] == 0x00&&
packet->payload[6] == 0x52 && packet->payload[7] == 0x0e &&
packet->payload[8] == 0x50 ) {
diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c
index 2269ae782..5632741e5 100644
--- a/src/lib/protocols/ssl.c
+++ b/src/lib/protocols/ssl.c
@@ -1,8 +1,7 @@
/*
* ssl.c
*
- * Copyright (C) 2009-2011 by ipoque GmbH
- * Copyright (C) 2011-15 - ntop.org
+ * Copyright (C) 2016 - ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -35,6 +34,52 @@
extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow);
+static u_int32_t ndpi_ssl_refine_master_protocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow, u_int32_t protocol)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if((flow->protos.ssl.client_certificate[0] != '\0')
+ || (flow->protos.ssl.server_certificate[0] != '\0')
+ || (flow->host_server_name[0] != '\0'))
+ protocol = NDPI_PROTOCOL_SSL;
+ else
+ protocol = NDPI_PROTOCOL_SSL_NO_CERT;
+
+ if(packet->tcp != NULL) {
+ switch(protocol) {
+
+ case NDPI_PROTOCOL_SSL:
+ case NDPI_PROTOCOL_SSL_NO_CERT:
+ {
+ /*
+ In case of SSL there are probably sub-protocols
+ such as IMAPS that can be otherwise detected
+ */
+ u_int16_t sport = ntohs(packet->tcp->source);
+ u_int16_t dport = ntohs(packet->tcp->dest);
+
+ if((sport == 465) || (dport == 465))
+ protocol = NDPI_PROTOCOL_MAIL_SMTPS;
+ else if((sport == 993) || (dport == 993)
+#ifdef NDPI_PROTOCOL_MAIL_IMAP
+ || (flow->l4.tcp.mail_imap_starttls)
+#endif
+ ) protocol = NDPI_PROTOCOL_MAIL_IMAPS;
+ else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS;
+ }
+ break;
+ }
+
+ if((protocol == NDPI_PROTOCOL_SSL_NO_CERT)
+ && is_skype_flow(ndpi_struct, flow)) {
+ protocol = NDPI_PROTOCOL_SKYPE;
+ }
+ }
+
+ return protocol;
+}
+
static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow, u_int32_t protocol)
{
@@ -42,40 +87,7 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp
&& (protocol != NDPI_PROTOCOL_SSL_NO_CERT)) {
ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN);
} else {
- struct ndpi_packet_struct *packet = &flow->packet;
-
- if((flow->protos.ssl.client_certificate[0] != '\0')
- || (flow->protos.ssl.server_certificate[0] != '\0')
- || (flow->host_server_name[0] != '\0'))
- protocol = NDPI_PROTOCOL_SSL;
- else
- protocol = NDPI_PROTOCOL_SSL_NO_CERT;
-
- if(packet->tcp != NULL) {
- switch(protocol) {
- case NDPI_PROTOCOL_SSL:
- case NDPI_PROTOCOL_SSL_NO_CERT:
- {
- /*
- In case of SSL there are probably sub-protocols
- such as IMAPS that can be otherwise detected
- */
- u_int16_t sport = ntohs(packet->tcp->source);
- u_int16_t dport = ntohs(packet->tcp->dest);
-
- if((sport == 465) || (dport == 465)) protocol = NDPI_PROTOCOL_MAIL_SMTPS;
- else if((sport == 993) || (dport == 993)) protocol = NDPI_PROTOCOL_MAIL_IMAPS;
- else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS;
- }
- break;
- }
-
- if((protocol == NDPI_PROTOCOL_SSL_NO_CERT)
- && is_skype_flow(ndpi_struct, flow)) {
- protocol = NDPI_PROTOCOL_SKYPE;
- }
- }
-
+ protocol = ndpi_ssl_refine_master_protocol(ndpi_struct, flow, protocol);
ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN);
}
}
@@ -86,20 +98,20 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp
#define ndpi_isdigit(ch) ((ch) >= '0' && (ch) <= '9')
#define ndpi_isspace(ch) (((ch) >= '\t' && (ch) <= '\r') || ((ch) == ' '))
#define ndpi_isprint(ch) ((ch) >= 0x20 && (ch) <= 0x7e)
-#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \
- ((ch) >= ':' && (ch) <= '@') || \
- ((ch) >= '[' && (ch) <= '`') || \
- ((ch) >= '{' && (ch) <= '~'))
+#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \
+ ((ch) >= ':' && (ch) <= '@') || \
+ ((ch) >= '[' && (ch) <= '`') || \
+ ((ch) >= '{' && (ch) <= '~'))
static void stripCertificateTrailer(char *buffer, int buffer_len) {
-
+
int i, is_puny;
-
+
// printf("->%s<-\n", buffer);
-
+
for(i = 0; i < buffer_len; i++) {
// printf("%c [%d]\n", buffer[i], buffer[i]);
-
+
if((buffer[i] != '.')
&& (buffer[i] != '-')
&& (buffer[i] != '*')
@@ -153,7 +165,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
/*
Nothing matched so far: let's decode the certificate with some heuristics
Patches courtesy of Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
- */
+ */
if(packet->payload[0] == 0x16 /* Handshake */) {
u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */;
u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */
@@ -162,7 +174,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
/* Truncate total len, search at least in incomplete packet */
if(total_len > packet->payload_packet_len)
- total_len = packet->payload_packet_len;
+ total_len = packet->payload_packet_len;
/* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */
if(total_len > 4) {
@@ -223,69 +235,74 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
}
} else if(handshake_protocol == 0x01 /* Client Hello */) {
u_int offset, base_offset = 43;
- u_int16_t session_id_len = packet->payload[base_offset];
+ if (base_offset + 2 <= packet->payload_packet_len)
+ {
+ u_int16_t session_id_len = packet->payload[base_offset];
- if((session_id_len+base_offset+2) <= total_len) {
- u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
- offset = base_offset + session_id_len + cypher_len + 2;
+ if((session_id_len+base_offset+2) <= total_len) {
+ u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
+ offset = base_offset + session_id_len + cypher_len + 2;
- flow->l4.tcp.ssl_seen_client_cert = 1;
+ flow->l4.tcp.ssl_seen_client_cert = 1;
- if(offset < total_len) {
- u_int16_t compression_len;
- u_int16_t extensions_len;
+ if(offset < total_len) {
+ u_int16_t compression_len;
+ u_int16_t extensions_len;
- compression_len = packet->payload[offset+1];
- offset += compression_len + 3;
+ compression_len = packet->payload[offset+1];
+ offset += compression_len + 3;
- if(offset < total_len) {
- extensions_len = packet->payload[offset];
+ if(offset < total_len) {
+ extensions_len = packet->payload[offset];
- if((extensions_len+offset) < total_len) {
- u_int16_t extension_offset = 1; /* Move to the first extension */
+ if((extensions_len+offset) < total_len) {
+ /* Move to the first extension
+ Type is u_int to avoid possible overflow on extension_len addition */
+ u_int extension_offset = 1;
- while(extension_offset < extensions_len) {
- u_int16_t extension_id, extension_len;
+ while(extension_offset < extensions_len) {
+ u_int16_t extension_id, extension_len;
- memcpy(&extension_id, &packet->payload[offset+extension_offset], 2);
- extension_offset += 2;
+ memcpy(&extension_id, &packet->payload[offset+extension_offset], 2);
+ extension_offset += 2;
- memcpy(&extension_len, &packet->payload[offset+extension_offset], 2);
- extension_offset += 2;
+ memcpy(&extension_len, &packet->payload[offset+extension_offset], 2);
+ extension_offset += 2;
- extension_id = ntohs(extension_id), extension_len = ntohs(extension_len);
+ extension_id = ntohs(extension_id), extension_len = ntohs(extension_len);
- if(extension_id == 0) {
- u_int begin = 0,len;
- char *server_name = (char*)&packet->payload[offset+extension_offset];
+ if(extension_id == 0) {
+ u_int begin = 0,len;
+ char *server_name = (char*)&packet->payload[offset+extension_offset];
- while(begin < extension_len) {
- if((!ndpi_isprint(server_name[begin]))
- || ndpi_ispunct(server_name[begin])
- || ndpi_isspace(server_name[begin]))
- begin++;
- else
- break;
- }
+ while(begin < extension_len) {
+ if((!ndpi_isprint(server_name[begin]))
+ || ndpi_ispunct(server_name[begin])
+ || ndpi_isspace(server_name[begin]))
+ begin++;
+ else
+ break;
+ }
- len = (u_int)ndpi_min(extension_len-begin, buffer_len-1);
- strncpy(buffer, &server_name[begin], len);
- buffer[len] = '\0';
- stripCertificateTrailer(buffer, buffer_len);
+ len = (u_int)ndpi_min(extension_len-begin, buffer_len-1);
+ strncpy(buffer, &server_name[begin], len);
+ buffer[len] = '\0';
+ stripCertificateTrailer(buffer, buffer_len);
- snprintf(flow->protos.ssl.client_certificate,
- sizeof(flow->protos.ssl.client_certificate), "%s", buffer);
+ snprintf(flow->protos.ssl.client_certificate,
+ sizeof(flow->protos.ssl.client_certificate), "%s", buffer);
- /* We're happy now */
- return(2 /* Client Certificate */);
- }
+ /* We're happy now */
+ return(2 /* Client Certificate */);
+ }
- extension_offset += extension_len;
+ extension_offset += extension_len;
+ }
+ }
}
}
}
}
- }
}
}
}
@@ -312,11 +329,14 @@ int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_s
#ifdef CERTIFICATE_DEBUG
printf("***** [SSL] %s\n", certificate);
#endif
-
- if(ndpi_match_host_subprotocol(ndpi_struct, flow, certificate,
- strlen(certificate),
- NDPI_PROTOCOL_SSL) != NDPI_PROTOCOL_UNKNOWN)
+ u_int32_t subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, certificate,
+ strlen(certificate), NDPI_PROTOCOL_SSL);
+
+ if(subproto != NDPI_PROTOCOL_UNKNOWN) {
+ ndpi_set_detected_protocol(ndpi_struct, flow, subproto,
+ ndpi_ssl_refine_master_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSL));
return(rc); /* Fix courtesy of Gianluca Costa <g.costa@xplico.org> */
+ }
#ifdef NDPI_PROTOCOL_TOR
if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0)
@@ -366,7 +386,7 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct
if(memcmp(&packet->payload[a], "talk.google.com", 15) == 0) {
NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n");
if(NDPI_COMPARE_PROTOCOL_TO_BITMASK
- (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) {
+ (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) {
ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER);
return;
}
@@ -375,18 +395,18 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct
#endif
#ifdef NDPI_PROTOCOL_OSCAR
if(packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c'
- || packet->payload[a] == 'h') {
+ || packet->payload[a] == 'h') {
if(((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0)
- // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 )
- // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0)
- || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0)
- || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0)
- || ((a + 41) < packet->payload_packet_len
- && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0)
- || ((a + 28) < packet->payload_packet_len
- && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0)
- || ((a + 32) < packet->payload_packet_len
- && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) {
+ // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 )
+ // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0)
+ || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0)
+ || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0)
+ || ((a + 41) < packet->payload_packet_len
+ && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0)
+ || ((a + 28) < packet->payload_packet_len
+ && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0)
+ || ((a + 32) < packet->payload_packet_len
+ && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) {
NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n");
if(flow->dst != NULL && packet->payload_packet_len > 75) {
@@ -402,8 +422,8 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct
if(packet->payload[a] == 'm' || packet->payload[a] == 's') {
if((a + 21) < packet->payload_packet_len &&
- (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0
- || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) {
+ (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0
+ || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) {
NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n");
ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR);
return;
@@ -438,13 +458,13 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct
if((packet->payload_packet_len >= 5)
- && (packet->payload[0] == 0x16)
- && (packet->payload[1] == 0x03)
- && ((packet->payload[2] == 0x00)
- || (packet->payload[2] == 0x01)
- || (packet->payload[2] == 0x02)
- || (packet->payload[2] == 0x03)
- )) {
+ && (packet->payload[0] == 0x16)
+ && (packet->payload[1] == 0x03)
+ && ((packet->payload[2] == 0x00)
+ || (packet->payload[2] == 0x01)
+ || (packet->payload[2] == 0x02)
+ || (packet->payload[2] == 0x03)
+ )) {
u_int32_t temp;
NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n");
// SSLv3 Record
@@ -454,7 +474,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct
temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5;
NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
if(packet->payload_packet_len == temp
- || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) {
+ || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) {
return 1;
}
@@ -499,7 +519,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct
if(packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16)
- && packet->payload[temp + 1] == 0x03) {
+ && packet->payload[temp + 1] == 0x03) {
u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
return 1;
@@ -510,7 +530,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct
return 1;
}
if(packet->payload_packet_len >= temp + 5 &&
- packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
+ packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
return 1;
@@ -521,7 +541,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct
return 1;
}
if(packet->payload_packet_len >= temp + 5 &&
- packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
+ packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
return 1;
@@ -590,16 +610,16 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc
NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n");
// SSLv2 Record
if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03
- && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
- && (packet->payload_packet_len - packet->payload[1] == 2)) {
+ && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
+ && (packet->payload_packet_len - packet->payload[1] == 2)) {
NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n");
flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
return;
}
if(packet->payload[0] == 0x16 && packet->payload[1] == 0x03
- && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02)
- && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) {
+ && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02)
+ && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) {
// SSLv3 Record
NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n");
flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
@@ -608,8 +628,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc
}
if(packet->payload_packet_len > 40 &&
- flow->l4.tcp.ssl_stage == 1 + packet->packet_direction
- && flow->packet_direction_counter[packet->packet_direction] < 5) {
+ flow->l4.tcp.ssl_stage == 1 + packet->packet_direction
+ && flow->packet_direction_counter[packet->packet_direction] < 5) {
return;
}
@@ -617,8 +637,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc
NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n");
// SSLv2 Record
if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03
- && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
- && (packet->payload_packet_len - 2) >= packet->payload[1]) {
+ && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
+ && (packet->payload_packet_len - 2) >= packet->payload[1]) {
NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n");
ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
return;
diff --git a/src/lib/protocols/starcraft.c b/src/lib/protocols/starcraft.c
index f96853f23..760578563 100644
--- a/src/lib/protocols/starcraft.c
+++ b/src/lib/protocols/starcraft.c
@@ -49,9 +49,8 @@ u_int8_t ndpi_check_starcraft_tcp(struct ndpi_detection_module_struct* ndpi_stru
{
if (sc2_match_logon_ip(&flow->packet)
&& flow->packet.tcp->dest == htons(1119) //bnetgame port
- && flow->packet.payload_packet_len >= 10
- && (match_first_bytes(flow->packet.payload, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66")
- || match_first_bytes(flow->packet.payload, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66")))
+ && (ndpi_match_strprefix(flow->packet.payload, flow->packet.payload_packet_len, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66")
+ || ndpi_match_strprefix(flow->packet.payload, flow->packet.payload_packet_len, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66")))
return 1;
else
return -1;
diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c
index 7ed0eae29..d12a0cb4b 100644
--- a/src/lib/protocols/steam.c
+++ b/src/lib/protocols/steam.c
@@ -50,7 +50,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc
if (flow->steam_stage == 0) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n");
- if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) {
+ if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -58,7 +58,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc
return;
}
- if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) {
+ if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -74,7 +74,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc
}
/* This is a packet in another direction. Check if we find the proper response. */
- if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) {
+ if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
ndpi_int_steam_add_connection(ndpi_struct, flow);
} else {
@@ -90,7 +90,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc
}
/* This is a packet in another direction. Check if we find the proper response. */
- if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) {
+ if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
ndpi_int_steam_add_connection(ndpi_struct, flow);
} else {
@@ -104,7 +104,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru
struct ndpi_packet_struct *packet = &flow->packet;
u_int32_t payload_len = packet->payload_packet_len;
- if ((payload_len > 0) && match_first_bytes(packet->payload, "VS01")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "VS01")) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
ndpi_int_steam_add_connection(ndpi_struct, flow);
return;
@@ -114,7 +114,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru
if (flow->steam_stage1 == 0) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n");
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -122,7 +122,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru
return;
}
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -139,7 +139,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
ndpi_int_steam_add_connection(ndpi_struct, flow);
} else {
@@ -156,7 +156,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) {
+ if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
ndpi_int_steam_add_connection(ndpi_struct, flow);
} else {
@@ -175,7 +175,7 @@ static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_stru
if (flow->steam_stage2 == 0) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n");
- if ((payload_len == 25) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ if ((payload_len == 25) && ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n");
/* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
@@ -191,7 +191,7 @@ static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_stru
}
/* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len == 0) || match_first_bytes(packet->payload, "\xff\xff\xff\xff")) {
+ if ((payload_len == 0) || ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n");
ndpi_int_steam_add_connection(ndpi_struct, flow);
} else {
diff --git a/src/lib/protocols/teredo.c b/src/lib/protocols/teredo.c
index 9fb2c6483..079d1fbcd 100644
--- a/src/lib/protocols/teredo.c
+++ b/src/lib/protocols/teredo.c
@@ -29,6 +29,8 @@ void ndpi_search_teredo(struct ndpi_detection_module_struct *ndpi_struct, struct
struct ndpi_packet_struct *packet = &flow->packet;
if(packet->udp
+ && packet->iph
+ && ((ntohl(packet->iph->daddr) & 0xF0000000) == 0xE0000000 /* A multicast address */)
&& ((ntohs(packet->udp->source) == 3544) || (ntohs(packet->udp->dest) == 3544))
&& (packet->payload_packet_len >= 40 /* IPv6 header */))
ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEREDO, NDPI_PROTOCOL_UNKNOWN);
diff --git a/src/lib/protocols/tor.c b/src/lib/protocols/tor.c
index 7903bf511..2152da328 100644
--- a/src/lib/protocols/tor.c
+++ b/src/lib/protocols/tor.c
@@ -1,7 +1,7 @@
/*
* tor.c
*
- * Copyright (C) 2015 ntop.org
+ * Copyright (C) 2016 ntop.org
* Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr>
*
*/
@@ -24,7 +24,7 @@ int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct,
if((certificate == NULL)
|| (strlen(certificate) < 6)
- || !(strncmp(certificate, "www.", 4)))
+ || (strncmp(certificate, "www.", 4)))
return(0);
// printf("***** [SSL] %s(): %s\n", __FUNCTION__, certificate);
@@ -39,10 +39,11 @@ int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct,
len = strlen(name);
- if(len > 6) {
+ if(len >= 5) {
for(i = 0; name[i+1] != '\0'; i++) {
+ // printf("***** [SSL] %s(): [%d][%c]", __FUNCTION__, i, name[i]);
+
if((name[i] >= '0') && (name[i] <= '9')) {
-
if(prev_num != 1) {
numbers_found++;
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 000000000..a8a127088
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,3 @@
+TESTS = do.sh
+
+EXTRA_DIST = do.sh pcap result
diff --git a/tests/pcap/Meu.pcap b/tests/pcap/Meu.pcap
deleted file mode 100644
index 9c724928a..000000000
--- a/tests/pcap/Meu.pcap
+++ /dev/null
Binary files differ
diff --git a/tests/pcap/Torcedor.pcap b/tests/pcap/Torcedor.pcap
deleted file mode 100644
index 7d7f03a1d..000000000
--- a/tests/pcap/Torcedor.pcap
+++ /dev/null
Binary files differ
diff --git a/tests/pcap/drda_db2.pcap b/tests/pcap/drda_db2.pcap
new file mode 100755
index 000000000..e91629e04
--- /dev/null
+++ b/tests/pcap/drda_db2.pcap
Binary files differ
diff --git a/tests/pcap/facebook.pcap b/tests/pcap/facebook.pcap
new file mode 100644
index 000000000..153d497a3
--- /dev/null
+++ b/tests/pcap/facebook.pcap
Binary files differ
diff --git a/tests/pcap/git.pcap b/tests/pcap/git.pcap
new file mode 100644
index 000000000..b32a255ef
--- /dev/null
+++ b/tests/pcap/git.pcap
Binary files differ
diff --git a/tests/pcap/hangout.pcap b/tests/pcap/hangout.pcap
new file mode 100644
index 000000000..9f3482679
--- /dev/null
+++ b/tests/pcap/hangout.pcap
Binary files differ
diff --git a/tests/pcap/openvpn.pcap b/tests/pcap/openvpn.pcap
new file mode 100644
index 000000000..9ae8351a1
--- /dev/null
+++ b/tests/pcap/openvpn.pcap
Binary files differ
diff --git a/tests/pcap/quic.pcap b/tests/pcap/quic.pcap
index 5de878c1a..1b1994a70 100644
--- a/tests/pcap/quic.pcap
+++ b/tests/pcap/quic.pcap
Binary files differ
diff --git a/tests/pcap/rx.pcap b/tests/pcap/rx.pcap
new file mode 100644
index 000000000..68fd825ac
--- /dev/null
+++ b/tests/pcap/rx.pcap
Binary files differ
diff --git a/tests/pcap/tor.pcap b/tests/pcap/tor.pcap
new file mode 100644
index 000000000..bf5b43649
--- /dev/null
+++ b/tests/pcap/tor.pcap
Binary files differ
diff --git a/tests/pcap/weibo.pcap b/tests/pcap/weibo.pcap
new file mode 100644
index 000000000..44ab450c9
--- /dev/null
+++ b/tests/pcap/weibo.pcap
Binary files differ
diff --git a/tests/result/Instagram.pcap.out b/tests/result/Instagram.pcap.out
index 3e349a331..a715b8f7f 100644
--- a/tests/result/Instagram.pcap.out
+++ b/tests/result/Instagram.pcap.out
@@ -2,40 +2,40 @@ Unknown 1 66 1
HTTP 266 245342 7
ICMP 5 510 1
SSL 103 62597 5
-DropBox 5 725 2
+Dropbox 5 725 2
Instagram 363 255094 16
- 1 UDP 192.168.0.106:17500 <-> 192.168.0.255:17500 [proto: 121/DropBox][1 pkts/145 bytes]
- 2 UDP 8.8.8.8:53 <-> 192.168.0.103:26540 [proto: 5.211/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-g-a.akamaihd.net]
- 3 UDP 8.8.8.8:53 <-> 192.168.0.103:27124 [proto: 5.211/DNS.Instagram][1 pkts/85 bytes][Host: photos-b.ak.instagram.com]
+ 1 UDP 192.168.0.106:17500 <-> 192.168.0.255:17500 [proto: 121/Dropbox][1 pkts/145 bytes]
+ 2 UDP 8.8.8.8:53 <-> 192.168.0.103:26540 [proto: 5.201/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-g-a.akamaihd.net]
+ 3 UDP 8.8.8.8:53 <-> 192.168.0.103:27124 [proto: 5.201/DNS.Instagram][1 pkts/85 bytes][Host: photos-b.ak.instagram.com]
4 TCP 31.13.93.52:443 <-> 192.168.0.103:33763 [proto: 91/SSL][11 pkts/5397 bytes]
5 TCP 31.13.93.52:443 <-> 192.168.0.103:33935 [proto: 91/SSL][10 pkts/5299 bytes]
6 TCP 2.22.236.51:80 <-> 192.168.0.103:44151 [proto: 7/HTTP][49 pkts/38684 bytes]
- 7 TCP 192.168.0.103:38816 <-> 46.33.70.160:80 [proto: 7.211/HTTP.Instagram][52 pkts/58994 bytes][Host: photos-h.ak.instagram.com]
+ 7 TCP 192.168.0.103:38816 <-> 46.33.70.160:80 [proto: 7.201/HTTP.Instagram][52 pkts/58994 bytes][Host: photos-h.ak.instagram.com]
8 TCP 77.67.29.17:80 <-> 192.168.0.103:33976 [proto: 7/HTTP][34 pkts/29039 bytes]
- 9 TCP 192.168.0.103:37350 <-> 82.85.26.153:80 [proto: 7.211/HTTP.Instagram][1 pkts/324 bytes][Host: photos-a.ak.instagram.com]
- 10 TCP 192.168.0.103:41181 <-> 82.85.26.154:443 [proto: 91.211/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net]
+ 9 TCP 192.168.0.103:37350 <-> 82.85.26.153:80 [proto: 7.201/HTTP.Instagram][1 pkts/324 bytes][Host: photos-a.ak.instagram.com]
+ 10 TCP 192.168.0.103:41181 <-> 82.85.26.154:443 [proto: 91.201/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net]
11 TCP 31.13.86.52:80 <-> 192.168.0.103:58216 [proto: 7/HTTP][150 pkts/153558 bytes]
- 12 TCP 192.168.0.103:57936 <-> 82.85.26.162:80 [proto: 7.211/HTTP.Instagram][58 pkts/50220 bytes][Host: photos-g.ak.instagram.com]
+ 12 TCP 192.168.0.103:57936 <-> 82.85.26.162:80 [proto: 7.201/HTTP.Instagram][58 pkts/50220 bytes][Host: photos-g.ak.instagram.com]
13 TCP 192.168.0.103:57966 <-> 82.85.26.185:80 [proto: 7/HTTP][3 pkts/198 bytes]
- 14 TCP 192.168.0.103:58052 <-> 82.85.26.162:80 [proto: 7.211/HTTP.Instagram][75 pkts/57239 bytes][Host: photos-g.ak.instagram.com]
- 15 TCP 173.252.107.4:443 <-> 192.168.0.103:56382 [proto: 91.211/SSL.Instagram][17 pkts/2647 bytes][SSL client: telegraph-ash.instagram.com]
- 16 UDP 192.168.0.106:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][4 pkts/580 bytes]
- 17 UDP 8.8.8.8:53 <-> 192.168.0.103:33603 [proto: 5.211/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-a-a.akamaihd.net]
+ 14 TCP 192.168.0.103:58052 <-> 82.85.26.162:80 [proto: 7.201/HTTP.Instagram][75 pkts/57239 bytes][Host: photos-g.ak.instagram.com]
+ 15 TCP 173.252.107.4:443 <-> 192.168.0.103:56382 [proto: 91.201/SSL.Instagram][17 pkts/2647 bytes][SSL client: telegraph-ash.instagram.com]
+ 16 UDP 192.168.0.106:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][4 pkts/580 bytes]
+ 17 UDP 8.8.8.8:53 <-> 192.168.0.103:33603 [proto: 5.201/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-a-a.akamaihd.net]
18 TCP 31.13.93.52:443 <-> 192.168.0.103:33936 [proto: 91/SSL][68 pkts/45688 bytes]
19 TCP 31.13.93.52:443 <-> 192.168.0.103:33934 [proto: 91/SSL][12 pkts/6044 bytes]
20 ICMP 192.168.0.103:0 <-> 192.168.0.103:0 [proto: 81/ICMP][5 pkts/510 bytes]
21 TCP 192.168.0.103:38817 <-> 46.33.70.160:80 [proto: 7/HTTP][3 pkts/198 bytes]
22 TCP 192.168.0.103:40855 <-> 46.33.70.150:80 [proto: 7/HTTP][2 pkts/140 bytes]
- 23 UDP 8.8.8.8:53 <-> 192.168.0.103:51219 [proto: 5.211/DNS.Instagram][2 pkts/394 bytes][Host: igcdn-photos-h-a.akamaihd.net]
- 24 TCP 192.168.0.103:44558 <-> 46.33.70.174:443 [proto: 91.211/SSL.Instagram][17 pkts/6369 bytes][SSL client: igcdn-photos-h-a.akamaihd.net]
- 25 TCP 192.168.0.103:41182 <-> 82.85.26.154:443 [proto: 91.211/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net]
+ 23 UDP 8.8.8.8:53 <-> 192.168.0.103:51219 [proto: 5.201/DNS.Instagram][2 pkts/394 bytes][Host: igcdn-photos-h-a.akamaihd.net]
+ 24 TCP 192.168.0.103:44558 <-> 46.33.70.174:443 [proto: 91.201/SSL.Instagram][17 pkts/6369 bytes][SSL client: igcdn-photos-h-a.akamaihd.net]
+ 25 TCP 192.168.0.103:41182 <-> 82.85.26.154:443 [proto: 91.201/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net]
26 TCP 192.168.0.103:41562 <-> 92.122.48.138:80 [proto: 7/HTTP][25 pkts/23525 bytes]
- 27 TCP 192.168.0.103:44379 <-> 82.85.26.186:80 [proto: 7.211/HTTP.Instagram][81 pkts/53416 bytes][Host: photos-e.ak.instagram.com]
+ 27 TCP 192.168.0.103:44379 <-> 82.85.26.186:80 [proto: 7.201/HTTP.Instagram][81 pkts/53416 bytes][Host: photos-e.ak.instagram.com]
28 TCP 192.168.0.103:58690 <-> 46.33.70.159:443 [proto: 91/SSL][2 pkts/169 bytes]
- 29 TCP 192.168.0.103:60908 <-> 46.33.70.136:443 [proto: 91.211/SSL.Instagram][19 pkts/9340 bytes][SSL client: igcdn-photos-g-a.akamaihd.net]
- 30 TCP 192.168.0.103:57965 <-> 82.85.26.185:80 [proto: 7.211/HTTP.Instagram][7 pkts/4015 bytes][Host: photos-f.ak.instagram.com]
- 31 TCP 192.168.0.103:58053 <-> 82.85.26.162:80 [proto: 7.211/HTTP.Instagram][1 pkts/321 bytes][Host: photos-g.ak.instagram.com]
+ 29 TCP 192.168.0.103:60908 <-> 46.33.70.136:443 [proto: 91.201/SSL.Instagram][19 pkts/9340 bytes][SSL client: igcdn-photos-g-a.akamaihd.net]
+ 30 TCP 192.168.0.103:57965 <-> 82.85.26.185:80 [proto: 7.201/HTTP.Instagram][7 pkts/4015 bytes][Host: photos-f.ak.instagram.com]
+ 31 TCP 192.168.0.103:58053 <-> 82.85.26.162:80 [proto: 7.201/HTTP.Instagram][1 pkts/321 bytes][Host: photos-g.ak.instagram.com]
Undetected flows:
diff --git a/tests/result/Meu.pcap.out b/tests/result/Meu.pcap.out
deleted file mode 100644
index 788681ba2..000000000
--- a/tests/result/Meu.pcap.out
+++ /dev/null
@@ -1,28 +0,0 @@
-TIM_Meu 814 658545 26
-
- 1 TCP 10.8.0.1:55226 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][62 pkts/31584 bytes][SSL client: appmeutim.tim.com.br]
- 2 TCP 10.8.0.1:55230 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][27 pkts/11642 bytes][SSL client: appmeutim.tim.com.br]
- 3 TCP 10.8.0.1:55232 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][37 pkts/37269 bytes][SSL client: appmeutim.tim.com.br]
- 4 TCP 10.8.0.1:55234 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][21 pkts/9350 bytes][SSL client: appmeutim.tim.com.br]
- 5 TCP 10.8.0.1:55236 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][13 pkts/1181 bytes][SSL client: appmeutim.tim.com.br]
- 6 TCP 10.8.0.1:55238 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][13 pkts/1181 bytes][SSL client: appmeutim.tim.com.br]
- 7 TCP 10.8.0.1:55250 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][22 pkts/9903 bytes][SSL client: appmeutim.tim.com.br]
- 8 TCP 10.8.0.1:55252 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][34 pkts/20796 bytes][SSL client: appmeutim.tim.com.br]
- 9 TCP 10.8.0.1:55254 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][27 pkts/8864 bytes][SSL client: appmeutim.tim.com.br]
- 10 TCP 10.8.0.1:55262 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br]
- 11 TCP 10.8.0.1:55264 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br]
- 12 TCP 10.8.0.1:55268 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][26 pkts/6969 bytes][SSL client: appmeutim.tim.com.br]
- 13 TCP 10.8.0.1:55270 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][56 pkts/36838 bytes][SSL client: appmeutim.tim.com.br]
- 14 TCP 10.8.0.1:55272 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][53 pkts/142338 bytes][SSL client: appmeutim.tim.com.br]
- 15 TCP 10.8.0.1:55276 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][20 pkts/7059 bytes][SSL client: appmeutim.tim.com.br]
- 16 TCP 10.8.0.1:55227 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][41 pkts/19844 bytes][SSL client: appmeutim.tim.com.br]
- 17 TCP 10.8.0.1:55231 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][33 pkts/14083 bytes][SSL client: appmeutim.tim.com.br]
- 18 TCP 10.8.0.1:55233 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][96 pkts/137364 bytes][SSL client: appmeutim.tim.com.br]
- 19 TCP 10.8.0.1:55235 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][19 pkts/5178 bytes][SSL client: appmeutim.tim.com.br]
- 20 TCP 10.8.0.1:55237 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][13 pkts/1181 bytes][SSL client: appmeutim.tim.com.br]
- 21 TCP 10.8.0.1:55239 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][85 pkts/122532 bytes][SSL client: appmeutim.tim.com.br]
- 22 TCP 10.8.0.1:55251 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][20 pkts/6243 bytes][SSL client: appmeutim.tim.com.br]
- 23 TCP 10.8.0.1:55253 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br]
- 24 TCP 10.8.0.1:55255 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][17 pkts/4594 bytes][SSL client: appmeutim.tim.com.br]
- 25 TCP 10.8.0.1:55263 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br]
- 26 TCP 10.8.0.1:55273 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][19 pkts/4608 bytes][SSL client: appmeutim.tim.com.br]
diff --git a/tests/result/NTPv3.pcap.out b/tests/result/NTPv3.pcap.out
index dcf9eafda..91d817e5e 100644
--- a/tests/result/NTPv3.pcap.out
+++ b/tests/result/NTPv3.pcap.out
@@ -1,3 +1,3 @@
-Quic 1 90 1
+NTP 1 90 1
- 1 UDP 78.46.76.2:80 <-> 175.144.140.29:123 [proto: 188/Quic][1 pkts/90 bytes]
+ 1 UDP 78.46.76.2:80 <-> 175.144.140.29:123 [proto: 9/NTP][1 pkts/90 bytes]
diff --git a/tests/result/Torcedor.pcap.out b/tests/result/Torcedor.pcap.out
deleted file mode 100644
index 17528c48c..000000000
--- a/tests/result/Torcedor.pcap.out
+++ /dev/null
@@ -1,10 +0,0 @@
-HTTP 4 216 1
-SSL 26 1558 2
-Torcedor 55 67338 3
-
- 1 TCP 10.8.0.1:55944 <-> 52.25.136.177:80 [proto: 7.192/HTTP.Torcedor][7 pkts/1118 bytes][Host: usuario.timtorcedor.com.br]
- 2 TCP 10.8.0.1:53114 <-> 31.13.85.8:443 [proto: 91/SSL][4 pkts/216 bytes]
- 3 TCP 10.8.0.1:56117 <-> 52.25.136.177:80 [proto: 7.192/HTTP.Torcedor][23 pkts/33056 bytes][Host: usuario.timtorcedor.com.br]
- 4 TCP 10.8.0.1:40016 <-> 158.85.58.105:443 [proto: 91/SSL][22 pkts/1342 bytes]
- 5 TCP 10.8.0.1:33415 <-> 187.109.32.201:80 [proto: 7/HTTP][4 pkts/216 bytes]
- 6 TCP 10.8.0.1:39422 <-> 54.149.207.220:80 [proto: 7.192/HTTP.Torcedor][25 pkts/33164 bytes][Host: usuario.timtorcedor.com.br]
diff --git a/tests/result/Viber_session.pcap.out b/tests/result/Viber_session.pcap.out
index 89bdd3a92..e73acc6f4 100644
--- a/tests/result/Viber_session.pcap.out
+++ b/tests/result/Viber_session.pcap.out
@@ -3,7 +3,7 @@ HTTP 14 862 8
SSL_No_Cert 34 4141 1
ICMP 2 196 1
SSL 109 11647 10
-DropBox 1 97 1
+Dropbox 1 97 1
GMail 21 1891 1
Google 50 4084 5
Viber 4163 392492 4
@@ -37,7 +37,7 @@ Viber 4163 392492 4
27 UDP 54.169.63.186:7987 <-> 192.168.200.222:48564 [proto: 144/Viber][2 pkts/138 bytes]
28 UDP 54.169.63.186:7985 <-> 192.168.200.222:48564 [proto: 144/Viber][4143 pkts/390781 bytes]
29 TCP 93.184.221.200:80 <-> 192.168.200.222:50854 [proto: 7/HTTP][1 pkts/60 bytes]
- 30 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.DropBox][1 pkts/97 bytes]
+ 30 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.Dropbox][1 pkts/97 bytes]
31 TCP 107.22.192.179:443 <-> 192.168.200.222:52269 [proto: 91/SSL][16 pkts/1419 bytes][SSL client: settings.crashlytics.com]
diff --git a/tests/result/coap_mqtt.pcap.out b/tests/result/coap_mqtt.pcap.out
index 2e6f7abc9..a9bd983e1 100644
--- a/tests/result/coap_mqtt.pcap.out
+++ b/tests/result/coap_mqtt.pcap.out
@@ -1,19 +1,20 @@
-COAP 819 82290 12
+COAP 19 1614 8
+Dropbox 800 80676 4
MQTT 7695 668291 4
1 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61043 [proto: 27/COAP][1 pkts/86 bytes]
2 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61045 [proto: 27/COAP][1 pkts/86 bytes]
3 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61047 [proto: 27/COAP][1 pkts/90 bytes]
- 4 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20220 bytes]
- 5 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20194 bytes]
- 6 TCP 192.168.56.1:53523 <-> 192.168.56.101:17501 [proto: 222/MQTT][1926 pkts/167126 bytes]
+ 4 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20220 bytes]
+ 5 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20194 bytes]
+ 6 TCP 192.168.56.1:53523 <-> 192.168.56.101:17501 [proto: 208/MQTT][1926 pkts/167126 bytes]
7 UDP [bbbb::1]:33499 <-> [bbbb::3]:5683 [proto: 27/COAP][4 pkts/404 bytes]
8 UDP [bbbb::1]:46819 <-> [bbbb::3]:5683 [proto: 27/COAP][6 pkts/467 bytes]
9 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61044 [proto: 27/COAP][1 pkts/86 bytes]
10 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61046 [proto: 27/COAP][1 pkts/86 bytes]
- 11 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20120 bytes]
- 12 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20142 bytes]
- 13 TCP 192.168.56.1:53522 <-> 192.168.56.101:17501 [proto: 222/MQTT][1922 pkts/166928 bytes]
- 14 TCP 192.168.56.1:53528 <-> 192.168.56.101:17501 [proto: 222/MQTT][1928 pkts/167509 bytes]
- 15 TCP 192.168.56.1:53524 <-> 192.168.56.101:17501 [proto: 222/MQTT][1919 pkts/166728 bytes]
+ 11 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20120 bytes]
+ 12 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20142 bytes]
+ 13 TCP 192.168.56.1:53522 <-> 192.168.56.101:17501 [proto: 208/MQTT][1922 pkts/166928 bytes]
+ 14 TCP 192.168.56.1:53528 <-> 192.168.56.101:17501 [proto: 208/MQTT][1928 pkts/167509 bytes]
+ 15 TCP 192.168.56.1:53524 <-> 192.168.56.101:17501 [proto: 208/MQTT][1919 pkts/166728 bytes]
16 UDP [bbbb::1]:50250 <-> [bbbb::3]:5683 [proto: 27/COAP][4 pkts/309 bytes]
diff --git a/tests/result/drda_db2.pcap.out b/tests/result/drda_db2.pcap.out
new file mode 100644
index 000000000..2543776b2
--- /dev/null
+++ b/tests/result/drda_db2.pcap.out
@@ -0,0 +1,3 @@
+DRDA 38 6691 1
+
+ 1 TCP 192.168.106.1:4847 <-> 192.168.106.128:50000 [proto: 192/DRDA][38 pkts/6691 bytes]
diff --git a/tests/result/dropbox.pcap.out b/tests/result/dropbox.pcap.out
index 343ba0ad5..c8b862513 100644
--- a/tests/result/dropbox.pcap.out
+++ b/tests/result/dropbox.pcap.out
@@ -1,17 +1,16 @@
MDNS 16 1648 1
SSDP 140 61108 22
-COAP 800 80676 4
-DropBox 304 165446 12
+Dropbox 1104 246122 16
- 1 UDP 192.168.1.105:33189 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/744 bytes][Host: notify.dropbox.com]
- 2 UDP 192.168.1.105:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][6 pkts/1422 bytes]
- 3 TCP 192.168.1.105:59975 <-> 108.160.172.204:443 [proto: 91.121/SSL.DropBox][34 pkts/18026 bytes][SSL client: client.dropbox.com]
- 4 UDP 192.168.1.105:36173 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][8 pkts/1390 bytes][Host: log.getdropbox.com]
- 5 TCP 192.168.1.105:46394 <-> 162.125.17.131:443 [proto: 91.121/SSL.DropBox][22 pkts/11392 bytes][SSL client: notify.dropbox.com]
- 6 UDP 192.168.1.105:50789 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/792 bytes][Host: d.dropbox.com]
- 7 UDP 192.168.1.105:55407 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/822 bytes][Host: client.dropbox.com]
- 8 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20220 bytes]
- 9 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20194 bytes]
+ 1 UDP 192.168.1.105:33189 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/744 bytes][Host: notify.dropbox.com]
+ 2 UDP 192.168.1.105:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][6 pkts/1422 bytes]
+ 3 TCP 192.168.1.105:59975 <-> 108.160.172.204:443 [proto: 91.121/SSL.Dropbox][34 pkts/18026 bytes][SSL client: client.dropbox.com]
+ 4 UDP 192.168.1.105:36173 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][8 pkts/1390 bytes][Host: log.getdropbox.com]
+ 5 TCP 192.168.1.105:46394 <-> 162.125.17.131:443 [proto: 91.121/SSL.Dropbox][22 pkts/11392 bytes][SSL client: notify.dropbox.com]
+ 6 UDP 192.168.1.105:50789 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/792 bytes][Host: d.dropbox.com]
+ 7 UDP 192.168.1.105:55407 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/822 bytes][Host: client.dropbox.com]
+ 8 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20220 bytes]
+ 9 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20194 bytes]
10 UDP 192.168.1.101:1280 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes]
11 UDP 192.168.1.101:1346 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes]
12 UDP 192.168.1.101:1650 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes]
@@ -20,14 +19,14 @@ DropBox 304 165446 12
15 UDP 192.168.1.101:2604 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes]
16 UDP 192.168.1.101:3412 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes]
17 UDP 192.168.1.101:4974 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes]
- 18 UDP 192.168.1.105:49112 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/774 bytes][Host: client-cf.dropbox.com]
- 19 UDP 192.168.1.105:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][6 pkts/1422 bytes]
+ 18 UDP 192.168.1.105:49112 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/774 bytes][Host: client-cf.dropbox.com]
+ 19 UDP 192.168.1.105:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][6 pkts/1422 bytes]
20 UDP 239.255.255.250:1900 <-> 192.168.1.254:50828 [proto: 12/SSDP][44 pkts/19936 bytes]
- 21 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20120 bytes]
- 22 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20142 bytes]
+ 21 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20120 bytes]
+ 22 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20142 bytes]
23 UDP 192.168.1.106:57268 <-> 239.255.255.250:1900 [proto: 12/SSDP][16 pkts/2632 bytes]
- 24 TCP 54.240.174.31:443 <-> 192.168.1.105:44949 [proto: 91.121/SSL.DropBox][138 pkts/97302 bytes][SSL client: client-cf.dropbox.com]
- 25 TCP 192.168.1.105:36226 <-> 108.160.172.195:80 [proto: 7.121/HTTP.DropBox][20 pkts/3928 bytes][Host: log.getdropbox.com]
+ 24 TCP 54.240.174.31:443 <-> 192.168.1.105:44949 [proto: 91.121/SSL.Dropbox][138 pkts/97302 bytes][SSL client: client-cf.dropbox.com]
+ 25 TCP 192.168.1.105:36226 <-> 108.160.172.195:80 [proto: 7.121/HTTP.Dropbox][20 pkts/3928 bytes][Host: log.getdropbox.com]
26 UDP 192.168.1.101:2169 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes]
27 UDP 192.168.1.101:2141 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes]
28 UDP 192.168.1.101:2159 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes]
@@ -41,4 +40,4 @@ DropBox 304 165446 12
36 UDP 192.168.1.101:4169 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes]
37 UDP 192.168.1.106:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][16 pkts/1648 bytes]
38 UDP 192.168.1.101:4625 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes]
- 39 TCP 192.168.1.105:47747 <-> 108.160.172.225:443 [proto: 91.121/SSL.DropBox][54 pkts/27432 bytes][SSL client: d.dropbox.com]
+ 39 TCP 192.168.1.105:47747 <-> 108.160.172.225:443 [proto: 91.121/SSL.Dropbox][54 pkts/27432 bytes][SSL client: d.dropbox.com]
diff --git a/tests/result/facebook.pcap.out b/tests/result/facebook.pcap.out
new file mode 100644
index 000000000..ad3cbdaad
--- /dev/null
+++ b/tests/result/facebook.pcap.out
@@ -0,0 +1,4 @@
+Facebook 60 30511 2
+
+ 1 TCP 192.168.43.18:52066 <-> 66.220.156.68:443 [proto: 91.119/SSL.Facebook][19 pkts/5745 bytes][SSL client: facebook.com]
+ 2 TCP 192.168.43.18:44614 <-> 31.13.86.36:443 [proto: 91.119/SSL.Facebook][41 pkts/24766 bytes][SSL client: www.facebook.com]
diff --git a/tests/result/git.pcap.out b/tests/result/git.pcap.out
new file mode 100644
index 000000000..1df4f5da9
--- /dev/null
+++ b/tests/result/git.pcap.out
@@ -0,0 +1,3 @@
+Git 90 74005 1
+
+ 1 TCP 5.153.231.21:9418 <-> 192.168.0.77:47991 [proto: 191/Git][90 pkts/74005 bytes]
diff --git a/tests/result/hangout.pcap.out b/tests/result/hangout.pcap.out
new file mode 100644
index 000000000..481ddfe3c
--- /dev/null
+++ b/tests/result/hangout.pcap.out
@@ -0,0 +1,3 @@
+GoogleHangout 19 2774 1
+
+ 1 UDP 10.89.61.13:56406 <-> 74.125.134.127:19305 [proto: 215/GoogleHangout][19 pkts/2774 bytes]
diff --git a/tests/result/http_ipv6.pcap.out b/tests/result/http_ipv6.pcap.out
index 77bc0d9db..8117cef8e 100644
--- a/tests/result/http_ipv6.pcap.out
+++ b/tests/result/http_ipv6.pcap.out
@@ -1,6 +1,7 @@
SSL 106 39646 11
Facebook 22 10202 2
-Quic 65 16479 2
+Google 62 15977 1
+QUIC 3 502 1
1 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:33062 <-> [2a00:1450:400b:c02::9a]:443 [proto: 91/SSL][2 pkts/172 bytes]
2 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a03:b0c0:3:d0::70:1001]:37486 [proto: 91/SSL][19 pkts/7014 bytes][SSL client: www.ntop.org]
@@ -15,5 +16,5 @@ Quic 65 16479 2
11 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a00:1450:4001:803::1012]:59690 [proto: 91/SSL][2 pkts/172 bytes]
12 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:60124 <-> [2a02:26f0:ad:1a1::eed]:443 [proto: 91/SSL][2 pkts/172 bytes]
13 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:40308 <-> [2a03:2880:1010:3f20:face:b00c::25de]:443 [proto: 91/SSL][2 pkts/172 bytes]
- 14 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a00:1450:4001:803::1017]:45931 [proto: 188/Quic][62 pkts/15977 bytes]
- 15 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:55145 <-> [2a00:1450:400b:c02::5f]:443 [proto: 188/Quic][3 pkts/502 bytes]
+ 14 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a00:1450:4001:803::1017]:45931 [proto: 188.126/QUIC.Google][62 pkts/15977 bytes][Host: www.google.it]
+ 15 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:55145 <-> [2a00:1450:400b:c02::5f]:443 [proto: 188/QUIC][3 pkts/502 bytes]
diff --git a/tests/result/ocs.pcap.out b/tests/result/ocs.pcap.out
index 253583c88..e65f45829 100644
--- a/tests/result/ocs.pcap.out
+++ b/tests/result/ocs.pcap.out
@@ -5,21 +5,21 @@ SSL 45 5771 3
Google 14 2349 3
OCS 863 57552 7
- 1 TCP 192.168.180.2:42590 <-> 178.248.208.210:80 [proto: 7.218/HTTP.OCS][83 pkts/5408 bytes][Host: www.ocs.fr]
- 2 TCP 192.168.180.2:48250 <-> 178.248.208.54:80 [proto: 7.218/HTTP.OCS][6 pkts/1092 bytes][Host: ocu03.labgency.ws]
+ 1 TCP 192.168.180.2:42590 <-> 178.248.208.210:80 [proto: 7.204/HTTP.OCS][83 pkts/5408 bytes][Host: www.ocs.fr]
+ 2 TCP 192.168.180.2:48250 <-> 178.248.208.54:80 [proto: 7.204/HTTP.OCS][6 pkts/1092 bytes][Host: ocu03.labgency.ws]
3 TCP 192.168.180.2:41223 <-> 216.58.208.46:443 [proto: 91/SSL][13 pkts/1448 bytes]
- 4 UDP 192.168.180.2:38472 <-> 8.8.8.8:53 [proto: 5.218/DNS.OCS][1 pkts/63 bytes][Host: ocu03.labgency.ws]
+ 4 UDP 192.168.180.2:38472 <-> 8.8.8.8:53 [proto: 5.204/DNS.OCS][1 pkts/63 bytes][Host: ocu03.labgency.ws]
5 TCP 192.168.180.2:39263 <-> 23.21.230.199:443 [proto: 91/SSL][20 pkts/2715 bytes][SSL client: settings.crashlytics.com]
6 UDP 192.168.180.2:48770 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][1 pkts/72 bytes][Host: android.clients.google.com]
7 TCP 192.168.180.2:47803 <-> 64.233.166.95:443 [proto: 91/SSL][12 pkts/1608 bytes]
8 UDP 192.168.180.2:1291 <-> 8.8.8.8:53 [proto: 5/DNS][1 pkts/67 bytes][Host: api.eu01.capptain.com]
- 9 UDP 192.168.180.2:2589 <-> 8.8.8.8:53 [proto: 5.218/DNS.OCS][1 pkts/61 bytes][Host: ocs.labgency.ws]
+ 9 UDP 192.168.180.2:2589 <-> 8.8.8.8:53 [proto: 5.204/DNS.OCS][1 pkts/61 bytes][Host: ocs.labgency.ws]
10 UDP 192.168.180.2:3621 <-> 8.8.8.8:53 [proto: 5/DNS][1 pkts/77 bytes][Host: xmpp.device06.eu01.capptain.com]
11 UDP 192.168.180.2:11793 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][1 pkts/65 bytes][Host: play.googleapis.com]
- 12 TCP 192.168.180.2:36680 <-> 178.248.208.54:443 [proto: 91.218/SSL.OCS][20 pkts/6089 bytes][SSL client: ocs.labgency.ws]
+ 12 TCP 192.168.180.2:36680 <-> 178.248.208.54:443 [proto: 91.204/SSL.OCS][20 pkts/6089 bytes][SSL client: ocs.labgency.ws]
13 TCP 192.168.180.2:53356 <-> 137.135.129.206:80 [proto: 7/HTTP][6 pkts/479 bytes]
- 14 UDP 192.168.180.2:24245 <-> 8.8.8.8:53 [proto: 5.218/DNS.OCS][1 pkts/56 bytes][Host: www.ocs.fr]
- 15 TCP 192.168.180.2:49881 <-> 178.248.208.54:80 [proto: 7.218/HTTP.OCS][751 pkts/44783 bytes][Host: ocu03.labgency.ws]
+ 14 UDP 192.168.180.2:24245 <-> 8.8.8.8:53 [proto: 5.204/DNS.OCS][1 pkts/56 bytes][Host: www.ocs.fr]
+ 15 TCP 192.168.180.2:49881 <-> 178.248.208.54:80 [proto: 7.204/HTTP.OCS][751 pkts/44783 bytes][Host: ocu03.labgency.ws]
16 UDP 192.168.180.2:40097 <-> 8.8.8.8:53 [proto: 5/DNS][1 pkts/70 bytes][Host: settings.crashlytics.com]
17 TCP 192.168.180.2:32946 <-> 64.233.184.188:443 [proto: 91.126/SSL.Google][12 pkts/2212 bytes][SSL client: mtalk.google.com]
18 TCP 192.168.180.2:44959 <-> 137.135.129.206:80 [proto: 7/HTTP][7 pkts/540 bytes]
diff --git a/tests/result/openvpn.pcap.out b/tests/result/openvpn.pcap.out
new file mode 100644
index 000000000..81d959dc1
--- /dev/null
+++ b/tests/result/openvpn.pcap.out
@@ -0,0 +1,5 @@
+OpenVPN 298 57111 3
+
+ 1 UDP 192.168.43.12:41507 <-> 139.59.151.137:13680 [proto: 159/OpenVPN][83 pkts/13559 bytes]
+ 2 UDP 192.168.43.18:13680 <-> 139.59.151.137:13680 [proto: 159/OpenVPN][120 pkts/28172 bytes]
+ 3 TCP 192.168.1.77:60140 <-> 46.101.231.218:443 [proto: 159/OpenVPN][95 pkts/15380 bytes]
diff --git a/tests/result/quic.pcap.out b/tests/result/quic.pcap.out
index 082d4b328..b79529833 100644
--- a/tests/result/quic.pcap.out
+++ b/tests/result/quic.pcap.out
@@ -1,3 +1,19 @@
-Quic 413 254874 1
+Unknown 6 7072 1
+GMail 413 254874 1
+YouTube 85 76193 5
+Google 11 10063 2
+QUIC 3 364 1
- 1 UDP 216.58.212.101:443 <-> 192.168.1.109:57833 [proto: 188/Quic][413 pkts/254874 bytes]
+ 1 UDP 192.168.1.105:48445 <-> 216.58.214.110:443 [proto: 188.124/QUIC.YouTube][3 pkts/2863 bytes][Host: i.ytimg.com]
+ 2 UDP 192.168.1.105:53817 <-> 216.58.210.225:443 [proto: 188.124/QUIC.YouTube][2 pkts/2784 bytes][Host: yt3.ggpht.com]
+ 3 UDP 216.58.212.101:443 <-> 192.168.1.109:57833 [proto: 188.122/QUIC.GMail][413 pkts/254874 bytes][Host: mail.google.com]
+ 4 UDP 172.217.16.3:443 <-> 192.168.1.105:40461 [proto: 188/QUIC][3 pkts/364 bytes]
+ 5 UDP 172.217.16.4:443 <-> 192.168.1.105:45669 [proto: 188.126/QUIC.Google][5 pkts/4334 bytes][Host: www.google.com]
+ 6 UDP 192.168.1.105:34438 <-> 216.58.210.238:443 [proto: 188.124/QUIC.YouTube][7 pkts/6545 bytes][Host: www.youtube.com]
+ 7 UDP 192.168.1.109:35236 <-> 216.58.210.206:443 [proto: 188.124/QUIC.YouTube][69 pkts/58433 bytes][Host: www.youtube.com]
+ 8 UDP 192.168.1.105:40030 <-> 216.58.201.227:443 [proto: 188.126/QUIC.Google][6 pkts/5729 bytes][Host: fonts.gstatic.com]
+ 9 UDP 192.168.1.105:55934 <-> 216.58.201.238:443 [proto: 188.124/QUIC.YouTube][4 pkts/5568 bytes][Host: s.ytimg.com]
+
+
+Undetected flows:
+ 1 UDP 10.0.0.3:6121 <-> 10.0.0.4:40134 [proto: 0/Unknown][6 pkts/7072 bytes]
diff --git a/tests/result/rx.pcap.out b/tests/result/rx.pcap.out
new file mode 100644
index 000000000..f38fc982d
--- /dev/null
+++ b/tests/result/rx.pcap.out
@@ -0,0 +1,7 @@
+RX 132 26475 5
+
+ 1 UDP 192.167.206.124:7002 <-> 131.114.219.168:38331 [proto: 209/RX][3 pkts/519 bytes]
+ 2 UDP 192.167.206.124:7002 <-> 131.114.219.168:41559 [proto: 209/RX][3 pkts/519 bytes]
+ 3 UDP 192.167.206.124:7003 <-> 131.114.219.168:7001 [proto: 209/RX][27 pkts/9919 bytes]
+ 4 UDP 131.114.219.168:7001 <-> 192.167.206.241:7000 [proto: 209/RX][79 pkts/12376 bytes]
+ 5 UDP 192.167.206.124:7000 <-> 131.114.219.168:7001 [proto: 209/RX][20 pkts/3142 bytes]
diff --git a/tests/result/skype.pcap.out b/tests/result/skype.pcap.out
index abcece480..316399879 100644
--- a/tests/result/skype.pcap.out
+++ b/tests/result/skype.pcap.out
@@ -1,16 +1,17 @@
-Unknown 396 52104 15
+Unknown 404 52712 16
DNS 8 807 4
MDNS 8 1736 2
NTP 2 180 1
SSDP 101 38156 6
ICMP 8 656 1
IGMP 5 258 4
-SSL 88 8268 6
-DropBox 38 17948 5
-Skype 2307 491376 244
+SSL 96 8876 7
+Dropbox 38 17948 5
+Skype 1904 292070 241
Apple 15 2045 2
AppleiCloud 88 20520 2
Spotify 5 430 1
+MS_OneDrive 387 198090 1
1 TCP 192.168.1.34:50114 <-> 5.248.186.221:31010 [proto: 125/Skype][18 pkts/1402 bytes]
2 UDP 111.221.74.15:40024 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes]
@@ -33,8 +34,8 @@ Spotify 5 430 1
19 UDP 192.168.1.34:13021 <-> 111.221.77.176:40020 [proto: 125/Skype][1 pkts/73 bytes]
20 TCP 192.168.1.34:50110 <-> 91.190.216.125:12350 [proto: 125/Skype][6 pkts/377 bytes]
21 TCP 91.190.216.23:12350 <-> 192.168.1.34:50126 [proto: 125/Skype][20 pkts/5160 bytes]
- 22 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][6 pkts/3264 bytes]
- 23 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][5 pkts/2720 bytes]
+ 22 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][6 pkts/3264 bytes]
+ 23 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][5 pkts/2720 bytes]
24 TCP 192.168.1.34:50113 <-> 71.238.7.203:18767 [proto: 125/Skype][14 pkts/1152 bytes]
25 TCP 192.168.1.34:50116 <-> 81.83.77.141:17639 [proto: 125/Skype][19 pkts/1510 bytes]
26 UDP 157.56.52.18:33033 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/71 bytes]
@@ -169,7 +170,7 @@ Spotify 5 430 1
155 UDP 192.168.1.34:13021 <-> 157.55.130.146:33033 [proto: 125/Skype][1 pkts/69 bytes]
156 UDP 192.168.1.34:13021 <-> 157.55.56.146:33033 [proto: 125/Skype][1 pkts/70 bytes]
157 TCP 76.167.161.6:20274 <-> 192.168.1.34:50112 [proto: 125/Skype][15 pkts/1254 bytes]
- 158 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 125/Skype][387 pkts/198090 bytes]
+ 158 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 91.207/SSL.MS_OneDrive][387 pkts/198090 bytes][SSL server: *.gateway.messenger.live.com]
159 TCP 192.168.1.34:50036 <-> 157.56.52.44:443 [proto: 125/Skype][14 pkts/1328 bytes]
160 TCP 192.168.1.34:50037 <-> 157.55.56.170:443 [proto: 125/Skype][15 pkts/1569 bytes]
161 TCP 192.168.1.34:50045 <-> 157.55.130.167:443 [proto: 125/Skype][15 pkts/1411 bytes]
@@ -179,7 +180,7 @@ Spotify 5 430 1
165 TCP 192.168.1.34:50081 <-> 157.55.130.176:443 [proto: 125/Skype][15 pkts/1513 bytes]
166 TCP 192.168.1.34:50091 <-> 157.55.235.146:443 [proto: 125/Skype][16 pkts/1754 bytes]
167 TCP 192.168.1.34:50101 <-> 157.55.235.176:443 [proto: 125/Skype][15 pkts/1590 bytes]
- 168 TCP 192.168.1.34:50146 <-> 157.56.53.51:443 [proto: 91.125/SSL.Skype][8 pkts/608 bytes]
+ 168 TCP 192.168.1.34:50146 <-> 157.56.53.51:443 [proto: 91/SSL][8 pkts/608 bytes]
169 UDP 192.168.1.34:13021 <-> 157.55.130.160:40029 [proto: 125/Skype][1 pkts/67 bytes]
170 UDP 192.168.1.34:13021 <-> 157.55.130.154:40005 [proto: 125/Skype][1 pkts/79 bytes]
171 UDP 192.168.1.34:13021 <-> 157.56.52.45:40012 [proto: 125/Skype][1 pkts/67 bytes]
@@ -209,87 +210,86 @@ Spotify 5 430 1
195 TCP 149.13.32.15:13392 <-> 192.168.1.34:50132 [proto: 125/Skype][18 pkts/1412 bytes]
196 UDP 192.168.1.92:57621 <-> 192.168.1.255:57621 [proto: 156/Spotify][5 pkts/430 bytes]
197 UDP 192.168.1.1:53 <-> 192.168.1.34:49990 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net]
- 198 TCP 192.168.1.34:50145 <-> 157.56.53.51:12350 [proto: 125/Skype][8 pkts/608 bytes]
- 199 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][6 pkts/3264 bytes]
- 200 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][5 pkts/2720 bytes]
- 201 UDP 192.168.1.34:13021 <-> 213.199.179.146:33033 [proto: 125/Skype][1 pkts/67 bytes]
- 202 UDP 192.168.1.1:53 <-> 192.168.1.34:51802 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com]
- 203 UDP 192.168.1.1:53 <-> 192.168.1.34:52714 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com]
- 204 UDP 192.168.1.1:53 <-> 192.168.1.34:52850 [proto: 5.125/DNS.Skype][8 pkts/648 bytes][Host: conn.skype.akadns.net]
- 205 UDP 192.168.1.1:53 <-> 192.168.1.34:52742 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst5.r.skype.net]
- 206 TCP 192.168.1.34:50039 <-> 213.199.179.175:443 [proto: 91/SSL][16 pkts/1592 bytes]
- 207 TCP 192.168.1.34:50079 <-> 213.199.179.142:443 [proto: 91/SSL][16 pkts/1376 bytes]
- 208 UDP 192.168.1.1:53 <-> 192.168.1.34:54396 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com]
- 209 TCP 192.168.1.34:50099 <-> 64.4.23.166:40022 [proto: 125/Skype][16 pkts/1355 bytes]
- 210 TCP 65.55.223.33:40002 <-> 192.168.1.34:50026 [proto: 125/Skype][17 pkts/1370 bytes]
- 211 TCP 65.55.223.12:40031 <-> 192.168.1.34:50065 [proto: 125/Skype][17 pkts/1401 bytes]
- 212 TCP 65.55.223.15:40026 <-> 192.168.1.34:50098 [proto: 125/Skype][17 pkts/1381 bytes]
- 213 UDP 192.168.1.1:53 <-> 192.168.1.34:57288 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net]
- 214 UDP 192.168.1.1:53 <-> 192.168.1.34:57406 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com]
- 215 UDP 192.168.1.1:53 <-> 192.168.1.34:57726 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net]
- 216 UDP 192.168.1.34:13021 <-> 213.199.179.165:40007 [proto: 125/Skype][1 pkts/74 bytes]
- 217 UDP 192.168.1.34:13021 <-> 213.199.179.141:40015 [proto: 125/Skype][1 pkts/75 bytes]
- 218 UDP 192.168.1.34:13021 <-> 213.199.179.162:40029 [proto: 125/Skype][1 pkts/70 bytes]
- 219 UDP 192.168.1.34:13021 <-> 213.199.179.152:40023 [proto: 125/Skype][1 pkts/64 bytes]
- 220 UDP 192.168.1.34:13021 <-> 213.199.179.145:40027 [proto: 125/Skype][1 pkts/66 bytes]
- 221 UDP 192.168.1.34:13021 <-> 213.199.179.170:40011 [proto: 125/Skype][1 pkts/71 bytes]
- 222 UDP 192.168.1.1:53 <-> 192.168.1.34:58458 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net]
- 223 UDP 192.168.1.1:53 <-> 192.168.1.34:58368 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst13.r.skype.net]
- 224 UDP 192.168.1.1:53 <-> 192.168.1.34:60288 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net]
- 225 ICMP 192.168.1.1:0 <-> 192.168.1.34:0 [proto: 81/ICMP][8 pkts/656 bytes]
- 226 UDP 192.168.1.1:53 <-> 192.168.1.34:62454 [proto: 5.143/DNS.AppleiCloud][2 pkts/234 bytes][Host: p05-keyvalueservice.icloud.com.akadns.net]
- 227 UDP 192.168.1.1:53 <-> 192.168.1.34:63108 [proto: 5.125/DNS.Skype][7 pkts/651 bytes][Host: a.config.skype.trafficmanager.net]
- 228 UDP 192.168.1.92:50084 <-> 239.255.255.250:1900 [proto: 12/SSDP][14 pkts/7281 bytes]
- 229 UDP 192.168.1.34:51066 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes]
- 230 UDP 192.168.1.1:53 <-> 192.168.1.34:65426 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com]
- 231 TCP 192.168.1.34:50130 <-> 212.161.8.36:13392 [proto: 125/Skype][17 pkts/1380 bytes]
- 232 TCP 192.168.1.34:50059 <-> 111.221.74.38:40015 [proto: 125/Skype][16 pkts/1236 bytes]
- 233 TCP 192.168.1.34:50029 <-> 23.206.33.166:443 [proto: 91.125/SSL.Skype][17 pkts/3535 bytes][SSL client: apps.skype.com]
- 234 IGMP 224.0.0.1:0 <-> 192.168.0.254:0 [proto: 82/IGMP][2 pkts/92 bytes]
- 235 IGMP 224.0.0.1:0 <-> 192.168.1.1:0 [proto: 82/IGMP][1 pkts/60 bytes]
- 236 IGMP 192.168.1.92:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/60 bytes]
- 237 IGMP 192.168.1.34:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/46 bytes]
- 238 UDP 192.168.1.34:56886 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes]
- 239 TCP 192.168.1.34:50033 <-> 157.55.56.170:40015 [proto: 125/Skype][17 pkts/1361 bytes]
- 240 TCP 157.56.52.28:40009 <-> 192.168.1.34:50108 [proto: 125/Skype][472 pkts/164627 bytes]
- 241 TCP 192.168.1.34:50049 <-> 157.55.130.166:40021 [proto: 125/Skype][16 pkts/1278 bytes]
- 242 TCP 192.168.1.34:50067 <-> 157.55.56.160:40027 [proto: 125/Skype][17 pkts/1305 bytes]
- 243 TCP 192.168.1.34:50070 <-> 157.55.130.170:40018 [proto: 125/Skype][17 pkts/1312 bytes]
- 244 TCP 192.168.1.34:50076 <-> 157.55.235.156:40014 [proto: 125/Skype][18 pkts/1442 bytes]
- 245 TCP 192.168.1.34:50092 <-> 157.55.130.155:40020 [proto: 125/Skype][17 pkts/1387 bytes]
- 246 UDP 192.168.1.34:64560 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes]
- 247 UDP 192.168.1.34:13021 <-> 64.4.23.146:33033 [proto: 125/Skype][1 pkts/66 bytes]
- 248 TCP 86.31.35.30:59621 <-> 192.168.1.34:50115 [proto: 125/Skype][17 pkts/1386 bytes]
- 249 TCP 192.168.1.34:50103 <-> 64.4.23.166:443 [proto: 91/SSL][12 pkts/1147 bytes]
- 250 TCP 65.55.223.33:443 <-> 192.168.1.34:50030 [proto: 91/SSL][15 pkts/1311 bytes]
- 251 TCP 65.55.223.12:443 <-> 192.168.1.34:50066 [proto: 91/SSL][15 pkts/1452 bytes]
- 252 TCP 65.55.223.15:443 <-> 192.168.1.34:50102 [proto: 91/SSL][14 pkts/1390 bytes]
- 253 UDP 239.255.255.250:1900 <-> 192.168.0.254:1025 [proto: 12/SSDP][79 pkts/29479 bytes]
- 254 UDP 192.168.1.34:13021 <-> 71.62.0.85:33647 [proto: 125/Skype][1 pkts/60 bytes]
- 255 UDP 192.168.1.92:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][4 pkts/828 bytes]
- 256 UDP 192.168.1.34:13021 <-> 64.4.23.159:40009 [proto: 125/Skype][1 pkts/70 bytes]
- 257 UDP 192.168.1.34:13021 <-> 64.4.23.151:40029 [proto: 125/Skype][1 pkts/72 bytes]
- 258 UDP 192.168.1.34:13021 <-> 64.4.23.170:40011 [proto: 125/Skype][1 pkts/68 bytes]
- 259 UDP 192.168.1.34:13021 <-> 64.4.23.173:40017 [proto: 125/Skype][1 pkts/66 bytes]
- 260 UDP 65.55.223.15:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/66 bytes]
- 261 UDP 192.168.1.34:13021 <-> 65.55.223.43:40002 [proto: 125/Skype][1 pkts/76 bytes]
- 262 UDP 65.55.223.17:40022 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/70 bytes]
- 263 UDP 65.55.223.25:40028 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/76 bytes]
- 264 UDP 65.55.223.24:40032 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/67 bytes]
- 265 UDP 65.55.223.28:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/74 bytes]
- 266 UDP 65.55.223.26:40004 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/79 bytes]
- 267 UDP 65.55.223.29:40010 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes]
- 268 UDP 192.168.1.34:13021 <-> 65.55.223.45:40012 [proto: 125/Skype][1 pkts/71 bytes]
- 269 UDP 192.168.1.34:123 <-> 17.253.48.245:123 [proto: 9/NTP][2 pkts/180 bytes]
- 270 TCP 192.168.1.34:50111 <-> 91.190.216.125:443 [proto: 125/Skype][20 pkts/1516 bytes]
- 271 TCP 192.168.1.34:50123 <-> 80.14.46.121:4415 [proto: 125/Skype][18 pkts/1506 bytes]
- 272 TCP 192.168.1.34:50141 <-> 80.14.46.121:4415 [proto: 125/Skype][15 pkts/1237 bytes]
- 273 TCP 192.168.1.34:49445 <-> 108.160.170.46:443 [proto: 91.121/SSL.DropBox][16 pkts/5980 bytes]
- 274 TCP 192.168.1.34:50058 <-> 111.221.74.47:443 [proto: 125/Skype][14 pkts/1208 bytes]
- 275 TCP 192.168.1.34:50100 <-> 111.221.74.46:443 [proto: 125/Skype][13 pkts/1109 bytes]
- 276 TCP 192.168.1.34:50035 <-> 213.199.179.175:40021 [proto: 125/Skype][17 pkts/1304 bytes]
- 277 TCP 192.168.1.34:50075 <-> 213.199.179.142:40003 [proto: 125/Skype][19 pkts/1495 bytes]
- 278 UDP [fe80::c62c:3ff:fe06:49fe]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][4 pkts/908 bytes]
+ 198 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][6 pkts/3264 bytes]
+ 199 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][5 pkts/2720 bytes]
+ 200 UDP 192.168.1.34:13021 <-> 213.199.179.146:33033 [proto: 125/Skype][1 pkts/67 bytes]
+ 201 UDP 192.168.1.1:53 <-> 192.168.1.34:51802 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com]
+ 202 UDP 192.168.1.1:53 <-> 192.168.1.34:52714 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com]
+ 203 UDP 192.168.1.1:53 <-> 192.168.1.34:52850 [proto: 5.125/DNS.Skype][8 pkts/648 bytes][Host: conn.skype.akadns.net]
+ 204 UDP 192.168.1.1:53 <-> 192.168.1.34:52742 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst5.r.skype.net]
+ 205 TCP 192.168.1.34:50039 <-> 213.199.179.175:443 [proto: 91/SSL][16 pkts/1592 bytes]
+ 206 TCP 192.168.1.34:50079 <-> 213.199.179.142:443 [proto: 91/SSL][16 pkts/1376 bytes]
+ 207 UDP 192.168.1.1:53 <-> 192.168.1.34:54396 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com]
+ 208 TCP 192.168.1.34:50099 <-> 64.4.23.166:40022 [proto: 125/Skype][16 pkts/1355 bytes]
+ 209 TCP 65.55.223.33:40002 <-> 192.168.1.34:50026 [proto: 125/Skype][17 pkts/1370 bytes]
+ 210 TCP 65.55.223.12:40031 <-> 192.168.1.34:50065 [proto: 125/Skype][17 pkts/1401 bytes]
+ 211 TCP 65.55.223.15:40026 <-> 192.168.1.34:50098 [proto: 125/Skype][17 pkts/1381 bytes]
+ 212 UDP 192.168.1.1:53 <-> 192.168.1.34:57288 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net]
+ 213 UDP 192.168.1.1:53 <-> 192.168.1.34:57406 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com]
+ 214 UDP 192.168.1.1:53 <-> 192.168.1.34:57726 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net]
+ 215 UDP 192.168.1.34:13021 <-> 213.199.179.165:40007 [proto: 125/Skype][1 pkts/74 bytes]
+ 216 UDP 192.168.1.34:13021 <-> 213.199.179.141:40015 [proto: 125/Skype][1 pkts/75 bytes]
+ 217 UDP 192.168.1.34:13021 <-> 213.199.179.162:40029 [proto: 125/Skype][1 pkts/70 bytes]
+ 218 UDP 192.168.1.34:13021 <-> 213.199.179.152:40023 [proto: 125/Skype][1 pkts/64 bytes]
+ 219 UDP 192.168.1.34:13021 <-> 213.199.179.145:40027 [proto: 125/Skype][1 pkts/66 bytes]
+ 220 UDP 192.168.1.34:13021 <-> 213.199.179.170:40011 [proto: 125/Skype][1 pkts/71 bytes]
+ 221 UDP 192.168.1.1:53 <-> 192.168.1.34:58458 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net]
+ 222 UDP 192.168.1.1:53 <-> 192.168.1.34:58368 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst13.r.skype.net]
+ 223 UDP 192.168.1.1:53 <-> 192.168.1.34:60288 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net]
+ 224 ICMP 192.168.1.1:0 <-> 192.168.1.34:0 [proto: 81/ICMP][8 pkts/656 bytes]
+ 225 UDP 192.168.1.1:53 <-> 192.168.1.34:62454 [proto: 5.143/DNS.AppleiCloud][2 pkts/234 bytes][Host: p05-keyvalueservice.icloud.com.akadns.net]
+ 226 UDP 192.168.1.1:53 <-> 192.168.1.34:63108 [proto: 5.125/DNS.Skype][7 pkts/651 bytes][Host: a.config.skype.trafficmanager.net]
+ 227 UDP 192.168.1.92:50084 <-> 239.255.255.250:1900 [proto: 12/SSDP][14 pkts/7281 bytes]
+ 228 UDP 192.168.1.34:51066 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes]
+ 229 UDP 192.168.1.1:53 <-> 192.168.1.34:65426 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com]
+ 230 TCP 192.168.1.34:50130 <-> 212.161.8.36:13392 [proto: 125/Skype][17 pkts/1380 bytes]
+ 231 TCP 192.168.1.34:50059 <-> 111.221.74.38:40015 [proto: 125/Skype][16 pkts/1236 bytes]
+ 232 TCP 192.168.1.34:50029 <-> 23.206.33.166:443 [proto: 91.125/SSL.Skype][17 pkts/3535 bytes][SSL client: apps.skype.com]
+ 233 IGMP 224.0.0.1:0 <-> 192.168.0.254:0 [proto: 82/IGMP][2 pkts/92 bytes]
+ 234 IGMP 224.0.0.1:0 <-> 192.168.1.1:0 [proto: 82/IGMP][1 pkts/60 bytes]
+ 235 IGMP 192.168.1.92:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/60 bytes]
+ 236 IGMP 192.168.1.34:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/46 bytes]
+ 237 UDP 192.168.1.34:56886 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes]
+ 238 TCP 192.168.1.34:50033 <-> 157.55.56.170:40015 [proto: 125/Skype][17 pkts/1361 bytes]
+ 239 TCP 157.56.52.28:40009 <-> 192.168.1.34:50108 [proto: 125/Skype][472 pkts/164627 bytes]
+ 240 TCP 192.168.1.34:50049 <-> 157.55.130.166:40021 [proto: 125/Skype][16 pkts/1278 bytes]
+ 241 TCP 192.168.1.34:50067 <-> 157.55.56.160:40027 [proto: 125/Skype][17 pkts/1305 bytes]
+ 242 TCP 192.168.1.34:50070 <-> 157.55.130.170:40018 [proto: 125/Skype][17 pkts/1312 bytes]
+ 243 TCP 192.168.1.34:50076 <-> 157.55.235.156:40014 [proto: 125/Skype][18 pkts/1442 bytes]
+ 244 TCP 192.168.1.34:50092 <-> 157.55.130.155:40020 [proto: 125/Skype][17 pkts/1387 bytes]
+ 245 UDP 192.168.1.34:64560 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes]
+ 246 UDP 192.168.1.34:13021 <-> 64.4.23.146:33033 [proto: 125/Skype][1 pkts/66 bytes]
+ 247 TCP 86.31.35.30:59621 <-> 192.168.1.34:50115 [proto: 125/Skype][17 pkts/1386 bytes]
+ 248 TCP 192.168.1.34:50103 <-> 64.4.23.166:443 [proto: 91/SSL][12 pkts/1147 bytes]
+ 249 TCP 65.55.223.33:443 <-> 192.168.1.34:50030 [proto: 91/SSL][15 pkts/1311 bytes]
+ 250 TCP 65.55.223.12:443 <-> 192.168.1.34:50066 [proto: 91/SSL][15 pkts/1452 bytes]
+ 251 TCP 65.55.223.15:443 <-> 192.168.1.34:50102 [proto: 91/SSL][14 pkts/1390 bytes]
+ 252 UDP 239.255.255.250:1900 <-> 192.168.0.254:1025 [proto: 12/SSDP][79 pkts/29479 bytes]
+ 253 UDP 192.168.1.34:13021 <-> 71.62.0.85:33647 [proto: 125/Skype][1 pkts/60 bytes]
+ 254 UDP 192.168.1.92:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][4 pkts/828 bytes]
+ 255 UDP 192.168.1.34:13021 <-> 64.4.23.159:40009 [proto: 125/Skype][1 pkts/70 bytes]
+ 256 UDP 192.168.1.34:13021 <-> 64.4.23.151:40029 [proto: 125/Skype][1 pkts/72 bytes]
+ 257 UDP 192.168.1.34:13021 <-> 64.4.23.170:40011 [proto: 125/Skype][1 pkts/68 bytes]
+ 258 UDP 192.168.1.34:13021 <-> 64.4.23.173:40017 [proto: 125/Skype][1 pkts/66 bytes]
+ 259 UDP 65.55.223.15:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/66 bytes]
+ 260 UDP 192.168.1.34:13021 <-> 65.55.223.43:40002 [proto: 125/Skype][1 pkts/76 bytes]
+ 261 UDP 65.55.223.17:40022 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/70 bytes]
+ 262 UDP 65.55.223.25:40028 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/76 bytes]
+ 263 UDP 65.55.223.24:40032 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/67 bytes]
+ 264 UDP 65.55.223.28:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/74 bytes]
+ 265 UDP 65.55.223.26:40004 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/79 bytes]
+ 266 UDP 65.55.223.29:40010 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes]
+ 267 UDP 192.168.1.34:13021 <-> 65.55.223.45:40012 [proto: 125/Skype][1 pkts/71 bytes]
+ 268 UDP 192.168.1.34:123 <-> 17.253.48.245:123 [proto: 9/NTP][2 pkts/180 bytes]
+ 269 TCP 192.168.1.34:50111 <-> 91.190.216.125:443 [proto: 125/Skype][20 pkts/1516 bytes]
+ 270 TCP 192.168.1.34:50123 <-> 80.14.46.121:4415 [proto: 125/Skype][18 pkts/1506 bytes]
+ 271 TCP 192.168.1.34:50141 <-> 80.14.46.121:4415 [proto: 125/Skype][15 pkts/1237 bytes]
+ 272 TCP 192.168.1.34:49445 <-> 108.160.170.46:443 [proto: 91.121/SSL.Dropbox][16 pkts/5980 bytes]
+ 273 TCP 192.168.1.34:50058 <-> 111.221.74.47:443 [proto: 125/Skype][14 pkts/1208 bytes]
+ 274 TCP 192.168.1.34:50100 <-> 111.221.74.46:443 [proto: 125/Skype][13 pkts/1109 bytes]
+ 275 TCP 192.168.1.34:50035 <-> 213.199.179.175:40021 [proto: 125/Skype][17 pkts/1304 bytes]
+ 276 TCP 192.168.1.34:50075 <-> 213.199.179.142:40003 [proto: 125/Skype][19 pkts/1495 bytes]
+ 277 UDP [fe80::c62c:3ff:fe06:49fe]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][4 pkts/908 bytes]
Undetected flows:
@@ -306,5 +306,6 @@ Undetected flows:
11 TCP 192.168.1.34:50121 <-> 81.83.77.141:17639 [proto: 0/Unknown][40 pkts/5609 bytes]
12 TCP 76.167.161.6:20274 <-> 192.168.1.34:50140 [proto: 0/Unknown][3 pkts/206 bytes]
13 TCP 192.168.1.34:50144 <-> 78.202.226.115:29059 [proto: 0/Unknown][14 pkts/1139 bytes]
- 14 TCP 86.31.35.30:59621 <-> 192.168.1.34:50119 [proto: 0/Unknown][100 pkts/12266 bytes]
- 15 TCP 192.168.1.34:50127 <-> 80.14.46.121:4415 [proto: 0/Unknown][27 pkts/2098 bytes]
+ 14 TCP 192.168.1.34:50145 <-> 157.56.53.51:12350 [proto: 0/Unknown][8 pkts/608 bytes]
+ 15 TCP 86.31.35.30:59621 <-> 192.168.1.34:50119 [proto: 0/Unknown][100 pkts/12266 bytes]
+ 16 TCP 192.168.1.34:50127 <-> 80.14.46.121:4415 [proto: 0/Unknown][27 pkts/2098 bytes]
diff --git a/tests/result/skype_no_unknown.pcap.out b/tests/result/skype_no_unknown.pcap.out
index c307ca471..b3be14eb1 100644
--- a/tests/result/skype_no_unknown.pcap.out
+++ b/tests/result/skype_no_unknown.pcap.out
@@ -6,9 +6,10 @@ SSDP 40 14100 3
ICMP 4 328 1
IGMP 4 226 4
SSL 79 7742 6
-DropBox 16 7342 5
-Skype 1585 362654 220
+Dropbox 16 7342 5
+Skype 1237 180967 219
Apple 84 20699 2
+MS_OneDrive 348 181687 1
1 UDP 192.168.1.34:13021 <-> 189.138.161.88:19521 [proto: 125/Skype][1 pkts/60 bytes]
2 TCP 192.168.1.34:51290 <-> 5.248.186.221:31010 [proto: 125/Skype][18 pkts/1490 bytes]
@@ -23,9 +24,9 @@ Apple 84 20699 2
11 UDP 192.168.1.34:13021 <-> 111.221.77.149:40016 [proto: 125/Skype][1 pkts/75 bytes]
12 UDP 192.168.1.34:13021 <-> 111.221.77.171:40030 [proto: 125/Skype][1 pkts/64 bytes]
13 UDP 192.168.1.34:13021 <-> 111.221.77.173:40012 [proto: 125/Skype][1 pkts/79 bytes]
- 14 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes]
+ 14 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes]
15 TCP 192.168.1.34:51284 <-> 91.190.218.125:12350 [proto: 125/Skype][6 pkts/423 bytes]
- 16 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes]
+ 16 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes]
17 TCP 192.168.1.34:51296 <-> 91.190.216.125:12350 [proto: 125/Skype][6 pkts/479 bytes]
18 TCP 192.168.1.34:51289 <-> 71.238.7.203:18767 [proto: 125/Skype][17 pkts/1369 bytes]
19 UDP 157.56.52.18:33033 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes]
@@ -123,7 +124,7 @@ Apple 84 20699 2
111 TCP 192.168.1.34:51302 <-> 91.190.216.125:443 [proto: 125/Skype][10 pkts/599 bytes]
112 UDP 192.168.1.34:13021 <-> 111.221.77.146:33033 [proto: 125/Skype][1 pkts/70 bytes]
113 UDP 111.221.74.18:33033 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/67 bytes]
- 114 TCP 192.168.1.34:51222 <-> 108.160.163.108:443 [proto: 91.121/SSL.DropBox][8 pkts/2990 bytes]
+ 114 TCP 192.168.1.34:51222 <-> 108.160.163.108:443 [proto: 91.121/SSL.Dropbox][8 pkts/2990 bytes]
115 TCP 192.168.1.34:51259 <-> 111.221.77.142:443 [proto: 125/Skype][14 pkts/1253 bytes]
116 TCP 192.168.1.34:51283 <-> 111.221.74.48:443 [proto: 91.125/SSL.Skype][3 pkts/206 bytes]
117 TCP 192.168.1.34:51258 <-> 213.199.179.176:40021 [proto: 125/Skype][19 pkts/1496 bytes]
@@ -150,7 +151,7 @@ Apple 84 20699 2
138 UDP 192.168.1.34:13021 <-> 157.55.130.146:33033 [proto: 125/Skype][1 pkts/69 bytes]
139 TCP 192.168.1.34:51291 <-> 81.83.77.141:17639 [proto: 125/Skype][15 pkts/1226 bytes]
140 TCP 76.167.161.6:20274 <-> 192.168.1.34:51288 [proto: 125/Skype][15 pkts/1258 bytes]
- 141 TCP 192.168.1.34:51230 <-> 157.56.126.211:443 [proto: 125/Skype][348 pkts/181687 bytes]
+ 141 TCP 192.168.1.34:51230 <-> 157.56.126.211:443 [proto: 91.207/SSL.MS_OneDrive][348 pkts/181687 bytes][SSL server: *.gateway.messenger.live.com]
142 TCP 157.56.52.28:443 <-> 192.168.1.34:51232 [proto: 125/Skype][13 pkts/1157 bytes]
143 TCP 192.168.1.34:51241 <-> 157.55.130.176:443 [proto: 125/Skype][15 pkts/1584 bytes]
144 TCP 192.168.1.34:51261 <-> 157.55.235.170:443 [proto: 125/Skype][15 pkts/1569 bytes]
@@ -188,8 +189,8 @@ Apple 84 20699 2
176 UDP 192.168.1.34:13021 <-> 157.55.235.175:40023 [proto: 125/Skype][1 pkts/74 bytes]
177 UDP 192.168.1.1:53 <-> 192.168.1.34:49864 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com]
178 TCP 149.13.32.15:13392 <-> 192.168.1.34:51316 [proto: 125/Skype][14 pkts/1176 bytes]
- 179 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes]
- 180 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes]
+ 179 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes]
+ 180 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes]
181 UDP 192.168.1.34:13021 <-> 213.199.179.146:33033 [proto: 125/Skype][1 pkts/75 bytes]
182 UDP 192.168.1.1:53 <-> 192.168.1.34:53372 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst11.r.skype.net]
183 UDP 192.168.1.92:53826 <-> 192.168.1.255:137 [proto: 10/NetBIOS][1 pkts/92 bytes]
diff --git a/tests/result/starcraft_battle.pcap.out b/tests/result/starcraft_battle.pcap.out
index e221e9ab6..c094ab4ed 100644
--- a/tests/result/starcraft_battle.pcap.out
+++ b/tests/result/starcraft_battle.pcap.out
@@ -7,7 +7,7 @@ WorldOfWarcraft 9 880 1
IGMP 2 120 1
SSL 41 2782 12
Google 14 1588 3
-Quic 6 475 1
+QUIC 6 475 1
Starcraft 236 51494 6
1 TCP 80.239.186.21:80 <-> 192.168.1.100:3516 [proto: 7/HTTP][12 pkts/3680 bytes][Host: eu.launcher.battle.net]
@@ -15,14 +15,14 @@ Starcraft 236 51494 6
3 TCP 80.239.186.21:80 <-> 192.168.1.100:3522 [proto: 7/HTTP][11 pkts/3620 bytes][Host: eu.launcher.battle.net]
4 TCP 80.239.186.26:80 <-> 192.168.1.100:3524 [proto: 7/HTTP][10 pkts/1214 bytes][Host: nydus.battle.net]
5 TCP 80.239.186.40:80 <-> 192.168.1.100:3526 [proto: 7/HTTP][11 pkts/3686 bytes][Host: eu.battle.net]
- 6 TCP 192.168.1.100:3427 <-> 80.239.208.193:1119 [proto: 213/Starcraft][13 pkts/902 bytes]
+ 6 TCP 192.168.1.100:3427 <-> 80.239.208.193:1119 [proto: 211/Starcraft][13 pkts/902 bytes]
7 UDP 239.255.255.250:1900 <-> 192.168.1.254:38605 [proto: 12/SSDP][11 pkts/4984 bytes]
8 UDP 192.168.1.100:53145 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/336 bytes][Host: nydus.battle.net]
9 UDP 192.168.1.100:58831 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/417 bytes][Host: 254.1.168.192.in-addr.arpa]
10 UDP 192.168.1.100:58851 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/455 bytes][Host: 22.40.194.173.in-addr.arpa]
11 TCP 192.168.1.100:3484 <-> 173.194.113.224:443 [proto: 91.126/SSL.Google][3 pkts/168 bytes]
12 TCP 192.168.1.100:3486 <-> 199.38.164.156:443 [proto: 91/SSL][4 pkts/228 bytes]
- 13 UDP 192.168.1.100:53146 <-> 5.42.180.154:1119 [proto: 213/Starcraft][2 pkts/104 bytes]
+ 13 UDP 192.168.1.100:53146 <-> 5.42.180.154:1119 [proto: 211/Starcraft][2 pkts/104 bytes]
14 TCP 192.168.1.100:3052 <-> 216.58.212.110:443 [proto: 91.126/SSL.Google][2 pkts/121 bytes]
15 TCP 192.168.1.100:3528 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25105 bytes][Host: bnetcmsus-a.akamaihd.net]
16 TCP 192.168.1.100:3530 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25102 bytes][Host: bnetcmsus-a.akamaihd.net]
@@ -40,7 +40,7 @@ Starcraft 236 51494 6
28 TCP 80.239.186.26:443 <-> 192.168.1.100:3476 [proto: 91/SSL][1 pkts/60 bytes]
29 TCP 80.239.186.40:443 <-> 192.168.1.100:3478 [proto: 91/SSL][1 pkts/60 bytes]
30 TCP 192.168.1.100:3508 <-> 87.248.221.254:80 [proto: 7.60/HTTP.HTTPDownload][179 pkts/134204 bytes][Host: llnw.blizzard.com]
- 31 UDP 173.194.40.22:443 <-> 192.168.1.100:53568 [proto: 188/Quic][6 pkts/475 bytes]
+ 31 UDP 173.194.40.22:443 <-> 192.168.1.100:53568 [proto: 188/QUIC][6 pkts/475 bytes]
32 UDP 192.168.1.100:55468 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/556 bytes][Host: bnetcmsus-a.akamaihd.net]
33 UDP 192.168.1.100:58818 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/432 bytes][Host: 91.252.30.192.in-addr.arpa]
34 UDP 192.168.1.100:58844 <-> 192.168.1.254:53 [proto: 5/DNS][2 pkts/210 bytes][Host: 40.186.239.80.in-addr.arpa]
@@ -48,9 +48,9 @@ Starcraft 236 51494 6
36 TCP 192.168.1.100:3506 <-> 173.194.113.224:80 [proto: 7.126/HTTP.Google][9 pkts/1299 bytes][Host: www.google-analytics.com]
37 TCP 192.30.252.91:443 <-> 192.168.1.100:3213 [proto: 91/SSL][3 pkts/234 bytes]
38 IGMP 224.0.0.22:0 <-> 192.168.1.107:0 [proto: 82/IGMP][2 pkts/120 bytes]
- 39 TCP 192.168.1.100:3517 <-> 213.248.127.130:1119 [proto: 213/Starcraft][215 pkts/50178 bytes]
- 40 UDP 192.168.1.100:6113 <-> 213.248.127.212:1119 [proto: 213/Starcraft][2 pkts/103 bytes]
- 41 UDP 192.168.1.100:6113 <-> 213.248.127.166:1119 [proto: 213/Starcraft][2 pkts/103 bytes]
+ 39 TCP 192.168.1.100:3517 <-> 213.248.127.130:1119 [proto: 211/Starcraft][215 pkts/50178 bytes]
+ 40 UDP 192.168.1.100:6113 <-> 213.248.127.212:1119 [proto: 211/Starcraft][2 pkts/103 bytes]
+ 41 UDP 192.168.1.100:6113 <-> 213.248.127.166:1119 [proto: 211/Starcraft][2 pkts/103 bytes]
42 TCP 192.168.1.100:3527 <-> 2.228.46.112:80 [proto: 7/HTTP][41 pkts/37433 bytes][Host: bnetcmsus-a.akamaihd.net]
43 TCP 192.168.1.100:3529 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25102 bytes][Host: bnetcmsus-a.akamaihd.net]
44 TCP 192.168.1.100:3531 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25102 bytes][Host: bnetcmsus-a.akamaihd.net]
@@ -60,7 +60,7 @@ Starcraft 236 51494 6
48 TCP 192.168.1.100:3482 <-> 2.228.46.114:443 [proto: 91/SSL][4 pkts/275 bytes]
49 TCP 192.168.1.100:3480 <-> 2.228.46.114:443 [proto: 91/SSL][4 pkts/275 bytes]
50 TCP 12.129.222.54:80 <-> 192.168.1.100:3512 [proto: 7.76/HTTP.WorldOfWarcraft][9 pkts/880 bytes][Host: us.scan.worldofwarcraft.com]
- 51 UDP 62.115.246.51:1119 <-> 192.168.1.100:53146 [proto: 213/Starcraft][2 pkts/104 bytes]
+ 51 UDP 62.115.246.51:1119 <-> 192.168.1.100:53146 [proto: 211/Starcraft][2 pkts/104 bytes]
Undetected flows:
diff --git a/tests/result/teredo.pcap.out b/tests/result/teredo.pcap.out
index 6c65bc313..c0c37a425 100644
--- a/tests/result/teredo.pcap.out
+++ b/tests/result/teredo.pcap.out
@@ -1,7 +1,7 @@
Teredo 24 2574 5
- 1 UDP 194.136.28.76:3544 <-> 10.112.16.106:52513 [proto: 214/Teredo][4 pkts/508 bytes]
- 2 UDP 194.136.28.76:3544 <-> 10.112.16.89:60381 [proto: 214/Teredo][2 pkts/254 bytes]
- 3 UDP 10.112.16.67:51812 <-> 194.136.28.76:3544 [proto: 214/Teredo][14 pkts/1304 bytes]
- 4 UDP 10.112.16.64:56154 <-> 194.136.28.76:3544 [proto: 214/Teredo][2 pkts/254 bytes]
- 5 UDP 194.136.28.76:3544 <-> 10.112.16.92:63448 [proto: 214/Teredo][2 pkts/254 bytes]
+ 1 UDP 194.136.28.76:3544 <-> 10.112.16.106:52513 [proto: 212/Teredo][4 pkts/508 bytes]
+ 2 UDP 194.136.28.76:3544 <-> 10.112.16.89:60381 [proto: 212/Teredo][2 pkts/254 bytes]
+ 3 UDP 10.112.16.67:51812 <-> 194.136.28.76:3544 [proto: 212/Teredo][14 pkts/1304 bytes]
+ 4 UDP 10.112.16.64:56154 <-> 194.136.28.76:3544 [proto: 212/Teredo][2 pkts/254 bytes]
+ 5 UDP 194.136.28.76:3544 <-> 10.112.16.92:63448 [proto: 212/Teredo][2 pkts/254 bytes]
diff --git a/tests/result/tor.pcap.out b/tests/result/tor.pcap.out
new file mode 100644
index 000000000..4fb9eb1d4
--- /dev/null
+++ b/tests/result/tor.pcap.out
@@ -0,0 +1,17 @@
+NetBIOS 1 252 1
+SSL 1 60 1
+DHCPV6 6 906 1
+Dropbox 10 1860 1
+Tor 3676 3014362 7
+
+ 1 UDP 192.168.1.1:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][10 pkts/1860 bytes]
+ 2 UDP [fe80::c583:1972:5728:7323]:547 <-> [ff02::1:2]:546 [proto: 103/DHCPV6][6 pkts/906 bytes]
+ 3 TCP 212.83.155.250:443 <-> 192.168.1.252:51174 [proto: 163/Tor][32 pkts/10431 bytes][SSL client: www.t3i3ru.com]
+ 4 TCP 46.59.52.31:443 <-> 192.168.1.252:51111 [proto: 163/Tor][34 pkts/11142 bytes][SSL client: www.e6r5p57kbafwrxj3plz.com]
+ 5 TCP 91.143.93.242:443 <-> 192.168.1.252:51175 [proto: 163/Tor][38 pkts/12520 bytes][SSL client: www.gfu7hbxpfp.com]
+ 6 TCP 157.56.30.46:443 <-> 192.168.1.252:51104 [proto: 91/SSL][1 pkts/60 bytes]
+ 7 UDP 192.168.1.252:138 <-> 192.168.1.255:138 [proto: 10/NetBIOS][1 pkts/252 bytes]
+ 8 TCP 38.229.70.53:443 <-> 192.168.1.252:51112 [proto: 163/Tor][1576 pkts/1388792 bytes][SSL client: www.q4cyamnc6mtokjurvdclt.com]
+ 9 TCP 38.229.70.53:443 <-> 192.168.1.252:51176 [proto: 163/Tor][1826 pkts/1513278 bytes][SSL client: www.jmts2id.com]
+ 10 TCP 62.210.137.230:443 <-> 192.168.1.252:51185 [proto: 163/Tor][29 pkts/9661 bytes][SSL client: www.6gyip7tqim7sieb.com]
+ 11 TCP 91.143.93.242:443 <-> 192.168.1.252:51110 [proto: 163/Tor][141 pkts/68538 bytes][SSL client: www.ct7ctrgb6cr7.com]
diff --git a/tests/result/viber_mobile.pcap.out b/tests/result/viber_mobile.pcap.out
index df601dd7d..e08572565 100644
--- a/tests/result/viber_mobile.pcap.out
+++ b/tests/result/viber_mobile.pcap.out
@@ -6,7 +6,7 @@ SSL_No_Cert 36 5874 1
ICMP 4 518 3
SSL 90 22731 8
Facebook 39 16382 2
-DropBox 2 163 1
+Dropbox 2 163 1
GMail 35 14773 2
Google 75 17027 7
WhatsApp 31 6224 2
@@ -82,7 +82,7 @@ Viber 10081 1413446 4
68 TCP 93.184.221.200:80 <-> 192.168.200.222:50854 [proto: 7/HTTP][5 pkts/300 bytes]
69 UDP 192.168.200.222:39413 <-> 81.192.42.247:15057 [proto: 37/BitTorrent][1 pkts/146 bytes]
70 UDP 92.245.59.202:12998 <-> 192.168.200.222:39413 [proto: 37/BitTorrent][2 pkts/505 bytes]
- 71 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.DropBox][2 pkts/163 bytes]
+ 71 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.Dropbox][2 pkts/163 bytes]
72 TCP 107.22.192.179:443 <-> 192.168.200.222:52269 [proto: 91/SSL][26 pkts/10057 bytes][SSL client: settings.crashlytics.com]
diff --git a/tests/result/waze.pcap.out b/tests/result/waze.pcap.out
index 0429e66a0..65169ea40 100644
--- a/tests/result/waze.pcap.out
+++ b/tests/result/waze.pcap.out
@@ -1,21 +1,22 @@
Unknown 10 786 1
+HTTP 28 1572 7
NTP 2 180 1
HTTPDownload 37 63205 1
SSL_No_Cert 13 2142 1
+SSL 8 432 2
Waze 484 289335 19
WhatsApp 15 1341 1
-Simet 36 2004 9
1 TCP 10.8.0.1:50828 <-> 108.168.176.228:443 [proto: 142/WhatsApp][15 pkts/1341 bytes]
2 TCP 10.8.0.1:36312 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][32 pkts/44619 bytes][SSL server: *.world.waze.com]
3 TCP 10.8.0.1:36314 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][20 pkts/5673 bytes][SSL server: *.world.waze.com]
4 TCP 10.8.0.1:36316 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][28 pkts/27886 bytes][SSL server: *.world.waze.com]
- 5 TCP 200.160.4.49:80 <-> 10.16.37.157:41823 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes]
- 6 TCP 200.160.4.31:80 <-> 10.16.37.157:43991 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes]
+ 5 TCP 200.160.4.49:80 <-> 10.16.37.157:41823 [proto: 7/HTTP][4 pkts/228 bytes]
+ 6 TCP 200.160.4.31:80 <-> 10.16.37.157:43991 [proto: 7/HTTP][4 pkts/228 bytes]
7 TCP 10.8.0.1:51050 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][18 pkts/5553 bytes][SSL server: *.waze.com]
- 8 TCP 10.8.0.1:45169 <-> 200.160.4.198:80 [proto: 7.200/HTTP.Simet][4 pkts/216 bytes]
- 9 TCP 200.160.4.49:80 <-> 10.16.37.157:46473 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes]
- 10 TCP 200.160.4.49:80 <-> 10.16.37.157:52953 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes]
+ 8 TCP 10.8.0.1:45169 <-> 200.160.4.198:80 [proto: 7/HTTP][4 pkts/216 bytes]
+ 9 TCP 200.160.4.49:80 <-> 10.16.37.157:46473 [proto: 7/HTTP][4 pkts/228 bytes]
+ 10 TCP 200.160.4.49:80 <-> 10.16.37.157:52953 [proto: 7/HTTP][4 pkts/228 bytes]
11 TCP 10.8.0.1:36100 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][107 pkts/85712 bytes][SSL server: *.world.waze.com]
12 TCP 10.8.0.1:36102 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][37 pkts/11984 bytes][SSL server: *.world.waze.com]
13 TCP 10.8.0.1:36134 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][24 pkts/6585 bytes][SSL server: *.world.waze.com]
@@ -28,13 +29,13 @@ Simet 36 2004 9
20 TCP 10.8.0.1:45554 <-> 54.230.227.172:80 [proto: 7.135/HTTP.Waze][14 pkts/1319 bytes][Host: cres.waze.com]
21 TCP 10.8.0.1:54915 <-> 65.39.128.135:80 [proto: 7.60/HTTP.HTTPDownload][37 pkts/63205 bytes][Host: xtra1.gpsonextra.net]
22 TCP 10.8.0.1:36585 <-> 173.194.118.48:443 [proto: 64/SSL_No_Cert][13 pkts/2142 bytes]
- 23 TCP 10.8.0.1:43089 <-> 200.160.4.198:443 [proto: 91.200/SSL.Simet][4 pkts/216 bytes]
+ 23 TCP 10.8.0.1:43089 <-> 200.160.4.198:443 [proto: 91/SSL][4 pkts/216 bytes]
24 TCP 10.8.0.1:51049 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][23 pkts/7823 bytes][SSL server: *.waze.com]
25 TCP 10.8.0.1:51051 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][21 pkts/7715 bytes][SSL server: *.waze.com]
26 UDP 10.8.0.1:46214 <-> 200.89.75.198:123 [proto: 9/NTP][2 pkts/180 bytes]
- 27 TCP 200.160.4.49:80 <-> 10.16.37.157:52746 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes]
- 28 TCP 10.8.0.1:60574 <-> 200.160.4.49:80 [proto: 7.200/HTTP.Simet][4 pkts/216 bytes]
- 29 TCP 10.8.0.1:60479 <-> 200.160.4.49:443 [proto: 91.200/SSL.Simet][4 pkts/216 bytes]
+ 27 TCP 200.160.4.49:80 <-> 10.16.37.157:52746 [proto: 7/HTTP][4 pkts/228 bytes]
+ 28 TCP 10.8.0.1:60574 <-> 200.160.4.49:80 [proto: 7/HTTP][4 pkts/216 bytes]
+ 29 TCP 10.8.0.1:60479 <-> 200.160.4.49:443 [proto: 91/SSL][4 pkts/216 bytes]
30 TCP 10.8.0.1:36137 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][23 pkts/5742 bytes][SSL server: *.world.waze.com]
31 TCP 10.8.0.1:39021 <-> 52.17.114.219:443 [proto: 91.135/SSL.Waze][33 pkts/58896 bytes][SSL server: *.world.waze.com]
32 TCP 10.8.0.1:45529 <-> 54.230.227.172:80 [proto: 7.135/HTTP.Waze][17 pkts/4015 bytes][Host: roadshields.waze.com]
diff --git a/tests/result/weibo.pcap.out b/tests/result/weibo.pcap.out
new file mode 100644
index 000000000..2be5bb816
--- /dev/null
+++ b/tests/result/weibo.pcap.out
@@ -0,0 +1,51 @@
+DNS 11 1129 6
+HTTP 19 2275 5
+SSL 17 1366 11
+Google 10 660 5
+QUIC 23 4118 2
+Weibo 418 258007 15
+
+ 1 TCP 140.205.174.1:443 <-> 192.168.1.105:48352 [proto: 91/SSL][1 pkts/74 bytes]
+ 2 TCP 140.205.174.1:443 <-> 192.168.1.105:48356 [proto: 91/SSL][1 pkts/74 bytes]
+ 3 TCP 192.168.1.105:59120 <-> 114.134.80.162:80 [proto: 7/HTTP][3 pkts/194 bytes]
+ 4 TCP 216.58.212.65:443 <-> 192.168.1.105:34699 [proto: 91.126/SSL.Google][2 pkts/132 bytes]
+ 5 TCP 222.73.28.96:80 <-> 192.168.1.105:42275 [proto: 7.210/HTTP.Weibo][4 pkts/676 bytes][Host: u1.img.mobile.sina.cn]
+ 6 UDP 192.168.1.1:53 <-> 192.168.1.105:50533 [proto: 5.210/DNS.Weibo][1 pkts/74 bytes][Host: data.weibo.com]
+ 7 UDP 192.168.1.1:53 <-> 192.168.1.105:53543 [proto: 5.210/DNS.Weibo][2 pkts/266 bytes][Host: img.t.sinajs.cn]
+ 8 UDP 216.58.210.14:443 <-> 192.168.1.105:49361 [proto: 188/QUIC][9 pkts/1944 bytes]
+ 9 TCP 216.58.214.78:443 <-> 192.168.1.105:58481 [proto: 91.126/SSL.Google][2 pkts/132 bytes]
+ 10 UDP 192.168.1.1:53 <-> 192.168.1.105:7148 [proto: 5.210/DNS.Weibo][2 pkts/215 bytes][Host: www.weibo.com]
+ 11 TCP 192.168.1.105:35803 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][106 pkts/76903 bytes][Host: img.t.sinajs.cn]
+ 12 TCP 192.168.1.105:35805 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][41 pkts/23245 bytes][Host: img.t.sinajs.cn]
+ 13 TCP 192.168.1.105:35807 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][53 pkts/36468 bytes][Host: img.t.sinajs.cn]
+ 14 TCP 192.168.1.105:35809 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][35 pkts/22361 bytes][Host: img.t.sinajs.cn]
+ 15 TCP 192.168.1.105:35811 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][5 pkts/744 bytes][Host: js.t.sinajs.cn]
+ 16 TCP 192.168.1.105:50827 <-> 47.89.65.229:443 [proto: 91/SSL][4 pkts/448 bytes][SSL client: g.alicdn.com]
+ 17 TCP 192.168.1.105:50831 <-> 47.89.65.229:443 [proto: 91/SSL][3 pkts/194 bytes]
+ 18 TCP 42.156.184.19:443 <-> 192.168.1.105:52272 [proto: 91/SSL][1 pkts/74 bytes]
+ 19 TCP 42.156.184.19:443 <-> 192.168.1.105:52274 [proto: 91/SSL][1 pkts/74 bytes]
+ 20 UDP 192.168.1.1:53 <-> 192.168.1.105:11798 [proto: 5.210/DNS.Weibo][1 pkts/77 bytes][Host: account.weibo.com]
+ 21 UDP 192.168.1.1:53 <-> 192.168.1.105:16804 [proto: 5/DNS][1 pkts/70 bytes][Host: c.weibo.cn]
+ 22 TCP 140.205.170.63:443 <-> 192.168.1.105:47721 [proto: 91/SSL][1 pkts/74 bytes]
+ 23 TCP 140.205.170.63:443 <-> 192.168.1.105:47723 [proto: 91/SSL][1 pkts/74 bytes]
+ 24 TCP 140.205.174.1:443 <-> 192.168.1.105:48353 [proto: 91/SSL][1 pkts/74 bytes]
+ 25 UDP 192.168.1.1:53 <-> 192.168.1.105:33822 [proto: 5/DNS][2 pkts/242 bytes][Host: login.taobao.com]
+ 26 TCP 192.168.1.105:59119 <-> 114.134.80.162:80 [proto: 7/HTTP][9 pkts/1599 bytes][Host: weibo.com]
+ 27 TCP 192.168.1.105:59121 <-> 114.134.80.162:80 [proto: 7/HTTP][3 pkts/194 bytes]
+ 28 TCP 192.168.1.105:35154 <-> 216.58.210.206:443 [proto: 91.126/SSL.Google][2 pkts/132 bytes]
+ 29 TCP 216.58.212.69:443 <-> 192.168.1.105:37802 [proto: 91.126/SSL.Google][2 pkts/132 bytes]
+ 30 UDP 192.168.1.1:53 <-> 192.168.1.105:41352 [proto: 5.210/DNS.Weibo][2 pkts/264 bytes][Host: js.t.sinajs.cn]
+ 31 TCP 222.73.28.96:80 <-> 192.168.1.105:42280 [proto: 7/HTTP][1 pkts/74 bytes]
+ 32 UDP 192.168.1.1:53 <-> 192.168.1.105:50640 [proto: 5/DNS][2 pkts/234 bytes][Host: acjstb.aliyun.com]
+ 33 UDP 192.168.1.1:53 <-> 192.168.1.105:51440 [proto: 5/DNS][2 pkts/243 bytes][Host: g.alicdn.com]
+ 34 UDP 192.168.1.1:53 <-> 192.168.1.105:53466 [proto: 5/DNS][2 pkts/186 bytes][Host: log.mmstat.com]
+ 35 UDP 192.168.1.1:53 <-> 192.168.1.105:54988 [proto: 5/DNS][2 pkts/154 bytes][Host: weibo.com]
+ 36 UDP 192.168.1.105:53656 <-> 216.58.210.227:443 [proto: 188/QUIC][14 pkts/2174 bytes]
+ 37 TCP 216.58.214.78:443 <-> 192.168.1.105:58480 [proto: 91.126/SSL.Google][2 pkts/132 bytes]
+ 38 TCP 192.168.1.105:40440 <-> 54.225.163.210:443 [proto: 91/SSL][2 pkts/132 bytes]
+ 39 TCP 192.168.1.105:35804 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][72 pkts/54281 bytes][Host: img.t.sinajs.cn]
+ 40 TCP 192.168.1.105:35806 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][13 pkts/4701 bytes][Host: img.t.sinajs.cn]
+ 41 TCP 192.168.1.105:35808 <-> 93.188.134.246:80 [proto: 7/HTTP][3 pkts/214 bytes]
+ 42 TCP 42.156.184.19:443 <-> 192.168.1.105:52271 [proto: 91/SSL][1 pkts/74 bytes]
+ 43 UDP 192.168.1.1:53 <-> 192.168.1.105:18035 [proto: 5.210/DNS.Weibo][2 pkts/240 bytes][Host: u1.img.mobile.sina.cn]
+ 44 TCP 192.168.1.105:51698 <-> 93.188.134.137:80 [proto: 7.210/HTTP.Weibo][79 pkts/37492 bytes][Host: www.weibo.com]
diff --git a/tests/result/whatsapp_login_call.pcap.out b/tests/result/whatsapp_login_call.pcap.out
index fd2edb823..41ec89cdf 100644
--- a/tests/result/whatsapp_login_call.pcap.out
+++ b/tests/result/whatsapp_login_call.pcap.out
@@ -4,7 +4,7 @@ DHCP 10 3420 1
STUN 97 11786 16
ICMP 10 700 1
SSL 8 589 2
-DropBox 4 2176 1
+Dropbox 4 2176 1
Apple 127 28102 20
WhatsApp 182 25154 2
AppleiTunes 85 28087 2
@@ -12,7 +12,7 @@ Spotify 3 258 1
WhatsAppVoice 706 91156 4
1 UDP [fe80::da30:62ff:fe56:1c]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][2 pkts/258 bytes]
- 2 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/DropBox][4 pkts/2176 bytes]
+ 2 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/Dropbox][4 pkts/2176 bytes]
3 ICMP 192.168.2.4:0 <-> 91.253.176.65:0 [proto: 81/ICMP][10 pkts/700 bytes]
4 UDP 192.168.2.4:52794 <-> 91.253.176.65:9665 [proto: 189/WhatsAppVoice][198 pkts/30418 bytes]
5 UDP 173.252.114.1:3478 <-> 192.168.2.4:52794 [proto: 78/STUN][5 pkts/676 bytes]
diff --git a/tests/result/whatsapp_login_chat.pcap.out b/tests/result/whatsapp_login_chat.pcap.out
index 0a904dd54..13c56555a 100644
--- a/tests/result/whatsapp_login_chat.pcap.out
+++ b/tests/result/whatsapp_login_chat.pcap.out
@@ -1,11 +1,11 @@
MDNS 2 202 2
DHCP 6 2052 1
-DropBox 2 1088 1
+Dropbox 2 1088 1
Apple 50 23466 2
WhatsApp 32 3243 2
Spotify 1 86 1
- 1 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes]
+ 1 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes]
2 UDP [fe80::189c:c31b:1298:224]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][1 pkts/111 bytes]
3 UDP 192.168.2.1:53 <-> 192.168.2.4:61697 [proto: 5.142/DNS.WhatsApp][2 pkts/280 bytes][Host: e12.whatsapp.net]
4 TCP 192.168.2.4:49205 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][44 pkts/21371 bytes]