aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore37
-rw-r--r--.travis.yml4
-rwxr-xr-xautogen.sh31
-rw-r--r--configure.ac40
-rw-r--r--example/Win32/pcapExample/pcapExample.vcxproj3
-rw-r--r--example/Win32/pcapExample/pcapExample.vcxproj.filters5
-rw-r--r--example/ndpiReader.c94
-rw-r--r--src/include/ndpi_protocol_ids.h5
-rw-r--r--src/include/ndpi_protocols.h1
-rw-r--r--src/include/ndpi_typedefs.h54
-rw-r--r--src/lib/Makefile.am5
-rw-r--r--src/lib/ndpi_content_match.c.inc7
-rw-r--r--src/lib/ndpi_main.c26
-rw-r--r--src/lib/protocols/bittorrent.c73
-rw-r--r--src/lib/protocols/dns.c2
-rw-r--r--src/lib/protocols/quic.c157
-rw-r--r--src/lib/protocols/redis_net.c (renamed from src/lib/protocols/redis.c)0
-rw-r--r--src/lib/protocols/warcraft3.c2
-rw-r--r--src/lib/protocols/zeromq.c (renamed from src/lib/protocols/zmq.c)0
-rw-r--r--src/lib/third_party/include/ndpi_patricia.h (renamed from src/lib/third_party/include/patricia.h)22
-rw-r--r--src/lib/third_party/src/ndpi_patricia.c (renamed from src/lib/third_party/src/patricia.c)39
-rwxr-xr-xtests/do.sh39
-rw-r--r--tests/pcap/README.txt1
-rw-r--r--tests/pcap/bt_search.pcapbin0 -> 378 bytes
-rw-r--r--tests/pcap/quic.pcapbin0 -> 261506 bytes
-rw-r--r--tests/pcap/skype.pcapbin0 -> 699646 bytes
-rw-r--r--tests/pcap/skype_no_unknown.pcapbin0 -> 526100 bytes
-rw-r--r--tests/result/README.txt5
-rw-r--r--tests/result/bt_search.pcap.out1
-rw-r--r--tests/result/quic.pcap.out1
-rw-r--r--tests/result/skype.pcap.out13
-rw-r--r--tests/result/skype_no_unknown.pcap.out11
32 files changed, 529 insertions, 149 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..a7fbae6f5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,37 @@
+*.[oa]
+*~
+*o.cmd
+*.lo
+*.obj
+*o.cmd
+*.ko
+*.swp
+*.in
+*.la
+.libs
+.dirstamp
+stamp-h1
+/configure
+/config.guess
+/config.h
+/config.h.in
+/config.sub
+/config.log
+/config.status
+/depcomp
+/install-sh
+/ltmain.sh
+/missing
+/Makefile
+/libndpi.pc
+/libtool
+/src/lib/Makefile
+/src/include/Makefile
+/example/ndpiReader
+/example/Makefile
+/aclocal.m4
+/m4/libtool.m4
+/m4/ltoptions.m4
+/m4/ltsugar.m4
+/m4/ltversion.m4
+/m4/lt~obsolete.m4
diff --git a/.travis.yml b/.travis.yml
index 4f6b549e4..b3142db9a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,4 +15,8 @@ before_script:
script:
- ./configure
- make
+
+after_script:
+ - cd tests
+ - ./do.sh
\ No newline at end of file
diff --git a/autogen.sh b/autogen.sh
index 9853e65ef..a1a7b8817 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,7 +1,32 @@
#!/bin/sh
-#
-# 1.5.1 r8171 06/09/2014
-#
+
+/bin/rm -f configure config.h config.h.in src/lib/Makefile.in
+
+AUTOCONF=$(which autoconf)
+AUTOMAKE=$(which automake)
+LIBTOOL=$(which libtool)
+AUTORECONF=$(which autoreconf)
+
+if test -z $AUTOCONF; then
+ echo "autoconf is missing: please install it and try again"
+ exit
+fi
+
+if test -z $AUTOMAKE; then
+ echo "automake is missing: please install it and try again"
+ exit
+fi
+
+if test -z $LIBTOOL; then
+ echo "libtool is missing: please install it and try again"
+ exit
+fi
+
+if test -z $AUTORECONF; then
+ echo "autoreconf is missing: please install it and try again"
+ exit
+fi
+
autoreconf -ivf
./configure
diff --git a/configure.ac b/configure.ac
index 7c80bdf06..7152f2aa9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,32 +10,33 @@ AC_PROG_CC
AX_PTHREAD
if test -d ".git"; then :
-GIT_TAG=`git rev-parse HEAD`
-GIT_DATE=`date +%Y%m%d`
-GIT_RELEASE="${PACKAGE_VERSION} (${GIT_TAG}:${GIT_DATE})"
+ GIT_TAG=`git log -1 --format=%h`
+ GIT_DATE=`git log -1 --format=%cd`
+ GIT_NUM=`git rev-list HEAD --count`
+ GIT_BRANCH=`git rev-parse --abbrev-ref HEAD`
+ GIT_RELEASE="${PACKAGE_VERSION}-${GIT_BRANCH}-${GIT_NUM}-${GIT_TAG}"
else
-GIT_RELEASE="${PACKAGE_VERSION}"
-SVN_DATE=`date`
+ GIT_RELEASE="${PACKAGE_VERSION}"
+ GIT_DATE=`date`
fi
-AC_DEFINE_UNQUOTED(NDPI_GIT_RELEASE, "r${GIT_RELEASE}", [SVN Release])
-AC_DEFINE_UNQUOTED(NDPI_SVN_DATE, "${SVN_DATE}", [Last SVN change])
+AC_DEFINE_UNQUOTED(NDPI_GIT_RELEASE, "${GIT_RELEASE}", [GIT Release])
+AC_DEFINE_UNQUOTED(NDPI_GIT_DATE, "${GIT_DATE}", [Last GIT change])
AC_CHECK_HEADERS([netinet/in.h stdint.h stdlib.h string.h unistd.h])
PCAP_HOME=$HOME/PF_RING/userland
if test -d $PCAP_HOME; then :
- echo -n ""
+ echo -n ""
else
- PCAP_HOME=`pwd`/../../PF_RING/userland
+ PCAP_HOME=`pwd`/../../PF_RING/userland
fi
-
SHORT_MACHINE=`uname -m | cut -b1-3`
if test $SHORT_MACHINE = "arm"; then
-LIBNUMA=""
+ LIBNUMA=""
else
-LIBNUMA="-lnuma"
+ LIBNUMA="-lnuma"
fi
if test -f $PCAP_HOME/libpcap/libpcap.a; then :
@@ -56,12 +57,16 @@ else
fi
fi
+PKG_CONFIG=$(which pkg-config)
+
if test -d /usr/local/include/json-c/; then :
- CFLAGS="$CFLAGS -I/usr/local/include/json-c/"
- LDFLAGS="$LDFLAGS -L/usr/local/lib -ljson-c"
+ CFLAGS="$CFLAGS -I/usr/local/include/json-c/"
+ LDFLAGS="$LDFLAGS -L/usr/local/lib -ljson-c"
else
- CFLAGS="$CFLAGS $(pkg-config --cflags json-c)"
- LDFLAGS="$LDFLAGS $(pkg-config --libs json-c)"
+ if ! test -z "$PKG_CONFIG"; then :
+ CFLAGS="$CFLAGS $(pkg-config --cflags json-c)"
+ LDFLAGS="$LDFLAGS $(pkg-config --libs json-c)"
+ fi
fi
OLD_LIBS=$LIBS
@@ -74,6 +79,8 @@ LIBS=$OLD_LIBS
AC_CHECK_LIB(json-c, json_object_new_object, AC_DEFINE_UNQUOTED(HAVE_JSON_C, 1, [The JSON-C library is present]))
+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_HEADERS(config.h)
AC_SUBST(GIT_RELEASE)
@@ -81,5 +88,6 @@ AC_SUBST(SVN_DATE)
AC_SUBST(JSON_C_LIB)
AC_SUBST(PCAP_INC)
AC_SUBST(PCAP_LIB)
+AC_SUBST(HAVE_PTHREAD_SETAFFINITY_NP)
AC_OUTPUT
diff --git a/example/Win32/pcapExample/pcapExample.vcxproj b/example/Win32/pcapExample/pcapExample.vcxproj
index 2b86797bd..87c8e360b 100644
--- a/example/Win32/pcapExample/pcapExample.vcxproj
+++ b/example/Win32/pcapExample/pcapExample.vcxproj
@@ -153,6 +153,7 @@
<ClCompile Include="..\..\..\src\lib\protocols\pptp.c" />
<ClCompile Include="..\..\..\src\lib\protocols\qq.c" />
<ClCompile Include="..\..\..\src\lib\protocols\quake.c" />
+ <ClCompile Include="..\..\..\src\lib\protocols\quic.c" />
<ClCompile Include="..\..\..\src\lib\protocols\radius.c" />
<ClCompile Include="..\..\..\src\lib\protocols\rdp.c" />
<ClCompile Include="..\..\..\src\lib\protocols\rsync.c" />
@@ -227,4 +228,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/example/Win32/pcapExample/pcapExample.vcxproj.filters b/example/Win32/pcapExample/pcapExample.vcxproj.filters
index 394d9dc7a..a5b3f919e 100644
--- a/example/Win32/pcapExample/pcapExample.vcxproj.filters
+++ b/example/Win32/pcapExample/pcapExample.vcxproj.filters
@@ -252,6 +252,9 @@
<ClCompile Include="..\..\..\src\lib\protocols\quake.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\src\lib\protocols\quic.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\src\lib\protocols\radius.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -459,4 +462,4 @@
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 41a4b42ed..d7293f626 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -66,6 +66,8 @@ static void setupDetection(u_int16_t thread_id);
*/
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;
+static char *results_path = NULL;
static char *_bpf_filter = NULL; /**< bpf filter */
static char *_protoFilePath = NULL; /**< Protocol file path */
#ifdef HAVE_JSON_C
@@ -82,7 +84,7 @@ static u_int8_t undetected_flows_deleted = 0;
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;
+ 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
@@ -158,7 +160,7 @@ static u_int32_t size_id_struct = 0; //< ID tracking structure size
#endif
// flow tracking
-typedef struct ndpi_flow {
+typedef struct ndpi_flow {
u_int32_t lower_ip;
u_int32_t upper_ip;
u_int16_t lower_port;
@@ -190,8 +192,8 @@ static u_int32_t size_flow_struct = 0;
static void help(u_int long_help) {
printf("ndpiReader -i <file|device> [-f <filter>][-s <duration>]\n"
- " [-p <protos>][-l <loops>[-d][-h][-t][-v <level>]\n"
- " [-n <threads>] [-j <file>]\n\n"
+ " [-p <protos>][-l <loops> [-q][-d][-h][-t][-v <level>]\n"
+ " [-n <threads>] [-w <file>] [-j <file>]\n\n"
"Usage:\n"
" -i <file.pcap|device> | Specify a pcap file/playlist to read packets from or a device for live capture (comma-separated list)\n"
" -f <BPF filter> | Specify a BPF filter for filtering selected traffic\n"
@@ -204,7 +206,11 @@ static void help(u_int long_help) {
" -g <id:id...> | Thread affinity mask (one core id per thread)\n"
#endif
" -d | Disable protocol guess and use only DPI\n"
+ " -q | Quiet mode\n"
" -t | Dissect GTP tunnels\n"
+ " -r | Print nDPI version and git revision\n"
+ " -w <path> | Write test output on the specified file. This is useful for\n"
+ " | testing purposes in order to compare results across runs\n"
" -h | This help\n"
" -v <1|2> | Verbose 'unknown protocol' packet print. 1=verbose, 2=very verbose\n");
@@ -224,10 +230,10 @@ static void parseOptions(int argc, char **argv) {
char *__pcap_file = NULL, *bind_mask = NULL;
int thread_id, opt;
#ifdef linux
- u_int num_cores = sysconf( _SC_NPROCESSORS_ONLN );
+ u_int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
#endif
- while ((opt = getopt(argc, argv, "df:g:i:hp:l:s:tv:V:n:j:")) != EOF) {
+ while ((opt = getopt(argc, argv, "df:g:i:hp:l:s:tv:V:n:j:rp:w:q")) != EOF) {
switch (opt) {
case 'd':
enable_protocol_guess = 0;
@@ -266,6 +272,10 @@ static void parseOptions(int argc, char **argv) {
decode_tunnels = 1;
break;
+ case 'r':
+ printf("ndpiReader - nDPI (%s)\n", ndpi_revision());
+ exit(0);
+
case 'v':
verbose = atoi(optarg);
break;
@@ -288,11 +298,23 @@ static void parseOptions(int argc, char **argv) {
#endif
break;
- default:
- help(0);
+ case 'w':
+ results_path = strdup(optarg);
+ if((results_file = fopen(results_path, "w")) == NULL) {
+ printf("Unable to write in file %s: quitting\n", results_path);
+ return;
+ }
break;
- }
- }
+
+ case 'q':
+ quiet_mode = 1;
+ break;
+
+ default:
+ help(0);
+ break;
+ }
+}
// check parameters
if(_pcap_file[0] == NULL || strcmp(_pcap_file[0], "") == 0) {
@@ -620,7 +642,7 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth,
if (flow->detected_protocol == 0 /* UNKNOWN */ && !undetected_flows_deleted)
undetected_flows_deleted = 1;
-
+
free_ndpi_flow(flow);
ndpi_thread_info[thread_id].stats.ndpi_flow_count--;
@@ -849,7 +871,7 @@ static struct ndpi_flow *get_ndpi_flow6(u_int16_t thread_id,
if(iph.protocol == 0x3C /* IPv6 destination option */) {
u_int8_t *options = (u_int8_t*)iph6 + sizeof(const struct ndpi_ip6_hdr);
-
+
iph.protocol = options[0];
}
@@ -867,7 +889,7 @@ static void setupDetection(u_int16_t thread_id) {
memset(&ndpi_thread_info[thread_id], 0, sizeof(ndpi_thread_info[thread_id]));
// init global detection structure
- ndpi_thread_info[thread_id].ndpi_struct = ndpi_init_detection_module(detection_tick_resolution,
+ 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");
@@ -961,14 +983,14 @@ static unsigned int packet_processing(u_int16_t thread_id,
}
if((
- (flow->detected_protocol == NDPI_PROTOCOL_HTTP)
+ (flow->detected_protocol == NDPI_PROTOCOL_HTTP)
|| (flow->detected_protocol == NDPI_SERVICE_FACEBOOK)
)
&& full_http_dissection) {
char *method;
printf("[URL] %s\n", ndpi_get_http_url(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow));
- printf("[Content-Type] %s\n", ndpi_get_http_content_type(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow));
+ printf("[Content-Type] %s\n", ndpi_get_http_content_type(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow));
switch(ndpi_get_http_method(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow)) {
case HTTP_METHOD_OPTIONS: method = "HTTP_METHOD_OPTIONS"; break;
@@ -1151,6 +1173,7 @@ static void printResults(u_int64_t tot_usec) {
cumulative_stats.max_packet_len += ndpi_thread_info[thread_id].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)));
@@ -1203,6 +1226,7 @@ static void printResults(u_int64_t tot_usec) {
if(enable_protocol_guess)
printf("\tGuessed flow protos: %-13u\n", cumulative_stats.guessed_flow_protocols);
+ }
} else {
#ifdef HAVE_JSON_C
if((json_fp = fopen(_jsonFilePath,"w")) == NULL) {
@@ -1240,14 +1264,21 @@ static void printResults(u_int64_t tot_usec) {
#endif
}
- if(!json_flag) printf("\n\nDetected protocols:\n");
+ 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);
if(cumulative_stats.protocol_counter[i] > 0) {
breed_stats[breed] += (long long unsigned int)cumulative_stats.protocol_counter_bytes[i];
- if(!json_flag) {
+ 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),
+ (long long unsigned int)cumulative_stats.protocol_counter[i],
+ (long long unsigned int)cumulative_stats.protocol_counter_bytes[i],
+ cumulative_stats.protocol_flows[i]);
+
+ 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),
@@ -1272,7 +1303,7 @@ static void printResults(u_int64_t tot_usec) {
}
}
- if(!json_flag) {
+ if((!json_flag) && (!quiet_mode)) {
printf("\n\nProtocol statistics:\n");
for(i=0; i < NUM_BREEDS; i++) {
@@ -1426,21 +1457,21 @@ static void openPcapFileOrDevice(u_int16_t thread_id) {
printf("ERROR: could not open pcap file or playlist: %s\n", ndpi_thread_info[thread_id]._pcap_error_buffer);
exit(-1);
} else {
- if(!json_flag) 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[thread_id]);
}
} else {
- if(!json_flag) 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[thread_id]);
}
} else {
live_capture = 1;
- if(!json_flag) 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[thread_id]);
}
configurePcapHandle(thread_id);
if(capture_for > 0) {
- if(!json_flag) printf("Capturing traffic up to %u seconds\n", (unsigned int)capture_for);
+ if((!json_flag) && (!quiet_mode)) printf("Capturing traffic up to %u seconds\n", (unsigned int)capture_for);
#ifndef WIN32
alarm(capture_for);
@@ -1539,7 +1570,7 @@ static void pcap_packet_callback(u_char *args, const struct pcap_pkthdr *header,
static u_int8_t cap_warning_used = 0;
if(cap_warning_used == 0) {
- if(!json_flag) printf("\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n");
+ 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;
}
}
@@ -1554,7 +1585,7 @@ static void pcap_packet_callback(u_char *args, const struct pcap_pkthdr *header,
ndpi_thread_info[thread_id].stats.fragmented_count++;
if(ipv4_frags_warning_used == 0) {
- if(!json_flag) printf("\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n");
+ 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;
}
@@ -1568,7 +1599,7 @@ static void pcap_packet_callback(u_char *args, const struct pcap_pkthdr *header,
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);
}
@@ -1579,7 +1610,7 @@ static void pcap_packet_callback(u_char *args, const struct pcap_pkthdr *header,
v4_warning:
if(ipv4_warning_used == 0) {
- if(!json_flag) 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");
+ 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;
}
@@ -1631,7 +1662,7 @@ static void runPcapLoop(u_int16_t thread_id) {
void *processing_thread(void *_thread_id) {
long thread_id = (long) _thread_id;
-#ifdef linux
+#if defined(linux) && defined(HAVE_PTHREAD_SETAFFINITY_NP)
if(core_affinity[thread_id] >= 0) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
@@ -1640,11 +1671,11 @@ void *processing_thread(void *_thread_id) {
if(pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) != 0)
fprintf(stderr, "Error while binding thread %ld to core %d\n", thread_id, core_affinity[thread_id]);
else {
- if(!json_flag) printf("Running thread %ld on core %d...\n", thread_id, core_affinity[thread_id]);
+ if((!json_flag) && (!quiet_mode)) printf("Running thread %ld on core %d...\n", thread_id, core_affinity[thread_id]);
}
} else
#endif
- if(!json_flag) printf("Running thread %ld...\n", thread_id);
+ if((!json_flag) && (!quiet_mode)) printf("Running thread %ld...\n", thread_id);
pcap_loop:
runPcapLoop(thread_id);
@@ -1711,7 +1742,7 @@ int main(int argc, char **argv) {
parseOptions(argc, argv);
- if(!json_flag) {
+ if((!json_flag) && (!quiet_mode)) {
printf("\n-----------------------------------------------------------\n"
"* NOTE: This is demo app to show *some* nDPI features.\n"
"* In this demo we have implemented only some basic features\n"
@@ -1727,6 +1758,9 @@ int main(int argc, char **argv) {
for(i=0; i<num_loops; i++)
test_lib();
+ if(results_path) free(results_path);
+ if(results_file) fclose(results_file);
+
return 0;
}
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h
index efa4f6d7d..db2179897 100644
--- a/src/include/ndpi_protocol_ids.h
+++ b/src/include/ndpi_protocol_ids.h
@@ -197,6 +197,7 @@
#define NDPI_PROTOCOL_PANDO 183 /* Tomasz Bujlow <tomasz@skatnet.dk> */
#define NDPI_PROTOCOL_VHUA 184
#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_CONTENT_AVI 39
@@ -235,8 +236,8 @@
#define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow <tomasz@skatnet.dk> */
#define NDPI_SERVICE_PANDORA 187
-/* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE (NDPI_SERVICE_PANDORA) */
-#define NDPI_LAST_IMPLEMENTED_PROTOCOL 187
+/* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE (NDPI_PROTOCOL_QUIC) */
+#define NDPI_LAST_IMPLEMENTED_PROTOCOL 188
#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 5ab0da83a..4fc0516d8 100644
--- a/src/include/ndpi_protocols.h
+++ b/src/include/ndpi_protocols.h
@@ -177,5 +177,6 @@ void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct nd
void ndpi_search_twitter(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
void ndpi_search_telegram(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
+void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
#endif /* __NDPI_PROTOCOLS_INCLUDE_FILE__ */
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 5bdd5a6e6..1afca2138 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -32,8 +32,8 @@ typedef enum {
} ndpi_log_level_t;
typedef void (*ndpi_debug_function_ptr) (u_int32_t protocol,
- void *module_struct, ndpi_log_level_t log_level,
- const char *format, ...);
+ void *module_struct, ndpi_log_level_t log_level,
+ const char *format, ...);
#define BT_ANNOUNCE
typedef enum {
@@ -102,43 +102,43 @@ typedef union {
#ifdef NDPI_PROTOCOL_BITTORRENT
#ifndef __KERNEL__
typedef struct spinlock {
- volatile int val;
+ volatile int val;
} spinlock_t;
typedef struct atomic {
- volatile int counter;
+ volatile int counter;
} atomic_t;
#endif
struct hash_ip4p_node {
- struct hash_ip4p_node *next,*prev;
- time_t lchg;
- u_int16_t port,count:12,flag:4;
- u_int32_t ip;
- // + 12 bytes for ipv6
+ struct hash_ip4p_node *next,*prev;
+ time_t lchg;
+ u_int16_t port,count:12,flag:4;
+ u_int32_t ip;
+ // + 12 bytes for ipv6
};
struct hash_ip4p {
- struct hash_ip4p_node *top;
- spinlock_t lock;
- size_t len;
+ struct hash_ip4p_node *top;
+ spinlock_t lock;
+ size_t len;
};
struct hash_ip4p_table {
- size_t size;
- int ipv6;
- spinlock_t lock;
- atomic_t count;
- struct hash_ip4p tbl[0];
+ size_t size;
+ int ipv6;
+ spinlock_t lock;
+ atomic_t count;
+ struct hash_ip4p tbl;
};
struct bt_announce { // 192 bytes
- u_int32_t hash[5];
- u_int32_t ip[4];
- u_int32_t time;
- u_int16_t port;
- u_int8_t name_len,
- name[192 - 4*10 - 2 - 1]; // 149 bytes
+ u_int32_t hash[5];
+ u_int32_t ip[4];
+ u_int32_t time;
+ u_int16_t port;
+ u_int8_t name_len,
+ name[192 - 4*10 - 2 - 1]; // 149 bytes
};
#endif
@@ -174,7 +174,7 @@ typedef struct ndpi_id_struct {
u_int32_t yahoo_video_lan_timer;
#endif
#endif
-/* NDPI_PROTOCOL_IRC_MAXPORT % 2 must be 0 */
+ /* NDPI_PROTOCOL_IRC_MAXPORT % 2 must be 0 */
#ifdef NDPI_PROTOCOL_IRC
#define NDPI_PROTOCOL_IRC_MAXPORT 8
u_int16_t irc_port[NDPI_PROTOCOL_IRC_MAXPORT];
@@ -518,8 +518,8 @@ typedef struct ndpi_packet_struct {
u_int8_t ssl_certificate_detected:4, ssl_certificate_num_checks:4;
u_int8_t packet_lines_parsed_complete:1,
- packet_direction:1,
- empty_line_position_set:1;
+ packet_direction:1,
+ empty_line_position_set:1;
} ndpi_packet_struct_t;
struct ndpi_detection_module_struct;
@@ -710,7 +710,7 @@ typedef struct ndpi_flow_struct {
Pointer to src or dst
that identifies the
server of this connection
- */
+ */
#ifndef __KERNEL__
u_char host_server_name[256]; /* HTTP host or DNS query */
#else
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 2ecf1e2ac..86aeb6c68 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -93,9 +93,10 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/pptp.c \
protocols/qq.c \
protocols/quake.c \
+ protocols/quic.c \
protocols/radius.c \
protocols/rdp.c \
- protocols/redis.c \
+ protocols/redis_net.c \
protocols/rsync.c \
protocols/rtcp.c \
protocols/rtmp.c \
@@ -148,7 +149,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \
protocols/xdmcp.c \
protocols/yahoo.c \
protocols/zattoo.c \
- protocols/zmq.c \
+ protocols/zeromq.c \
third_party/include/actypes.h \
third_party/include/ahocorasick.h \
third_party/include/node.h \
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index 3b4693fc3..1a7f8eef6 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -72,12 +72,14 @@ static ndpi_network host_protocol_list[] = {
{ 0x6CA0A000 /* 108.160.160.0 */, 20, NDPI_PROTOCOL_DROPBOX },
/*
- Skype
+ Skype (Microsoft CDN)
157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15
+ 111.221.64.0 - 111.221.127.255
*/
{ 0x9D380000 /* 157.56.0.0 */, 14, NDPI_PROTOCOL_SKYPE },
{ 0x9D3C0000 /* 157.60.0.0 */, 16, NDPI_PROTOCOL_SKYPE },
- { 0x9D360000 /* 157.54.0.0/ */, 15, NDPI_PROTOCOL_SKYPE },
+ { 0x9D360000 /* 157.54.0.0 */, 15, NDPI_PROTOCOL_SKYPE },
+ { 0x6FDD4000 /* 111.221.64.0 */, 18, NDPI_PROTOCOL_SKYPE },
/*
Google
@@ -258,6 +260,7 @@ static ndpi_network host_protocol_list[] = {
{ 0xD820F200, 24, NDPI_PROTOCOL_SKYPE },
{ 0xD821F000, 22, NDPI_PROTOCOL_SKYPE },
{ 0xD4A10800, 24, NDPI_PROTOCOL_SKYPE },
+
{ 0x012A1231, 32, NDPI_PROTOCOL_TOR },
{ 0x01E69FA1, 32, NDPI_PROTOCOL_TOR },
{ 0x020DE985, 32, NDPI_PROTOCOL_TOR },
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 379cd034b..d8047825b 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -49,8 +49,8 @@
#endif
#include "ndpi_content_match.c.inc"
-#include "third_party/include/patricia.h"
-#include "third_party/src/patricia.c"
+#include "third_party/include/ndpi_patricia.h"
+#include "third_party/src/ndpi_patricia.c"
#ifdef WIN32
/* http://social.msdn.microsoft.com/Forums/uk/vcgeneral/thread/963aac07-da1a-4612-be4a-faac3f1d65ca */
@@ -946,7 +946,7 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
no_master,
no_master, "BitTorrent",
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_b, 6771, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EPP,
no_master,
no_master, "EPP",
@@ -1456,6 +1456,11 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
no_master, "Telegram",
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_QUIC,
+ no_master,
+ 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 */);
custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN;
custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN;
@@ -1677,6 +1682,7 @@ static int fill_prefix_v4(prefix_t *p, struct in_addr *a, int b, int mb) {
if(b < 0 || b > mb)
return(-1);
+ memset(p, 0, sizeof(prefix_t));
memcpy(&p->add.sin, a, (mb+7)/8);
p->family = AF_INET;
p->bitlen = b;
@@ -1692,6 +1698,7 @@ u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_str
prefix_t prefix;
patricia_node_t *node;
+ pin->s_addr = ntohl(pin->s_addr); /* Make sure all in network byte order otherwise compares wont work */
fill_prefix_v4(&prefix, pin, 32, ((patricia_tree_t*)ndpi_struct->protocols_ptree)->maxbits);
node = ndpi_patricia_search_best(ndpi_struct->protocols_ptree, &prefix);
@@ -1755,7 +1762,7 @@ static void ndpi_init_ptree_ipv4(struct ndpi_detection_module_struct *ndpi_str,
struct in_addr pin;
patricia_node_t *node;
- pin.s_addr = host_list[i].network;
+ pin.s_addr = ntohl(host_list[i].network);
if((node = add_to_ptree(ptree, AF_INET, &pin, host_list[i].cidr /* bits */)) != NULL)
node->value.user_value = host_list[i].value;
}
@@ -3516,6 +3523,15 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n
ADD_TO_DETECTION_BITMASK);
#endif
+#ifdef NDPI_PROTOCOL_QUIC
+ ndpi_set_bitmask_protocol_detection("QUIC", ndpi_struct, detection_bitmask, a++,
+ NDPI_PROTOCOL_QUIC,
+ ndpi_search_quic,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+#endif
+
ndpi_struct->callback_buffer_size = a;
NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
@@ -4212,7 +4228,7 @@ unsigned int ndpi_detection_process_packet(struct ndpi_detection_module_struct *
flow->packet.tick_timestamp = d;
}
#else
- flow->packet.tick_timestamp = current_tick_l/1000;
+ flow->packet.tick_timestamp = (u_int32_t)current_tick_l/1000;
#endif
/* parse packet */
diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c
index 4be42548f..5fe371a33 100644
--- a/src/lib/protocols/bittorrent.c
+++ b/src/lib/protocols/bittorrent.c
@@ -384,6 +384,8 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st
ndpi_int_search_bittorrent_tcp(ndpi_struct, flow);
}
else if(packet->udp != NULL) {
+ char *bt_search = "BT-SEARCH * HTTP/1.1\r\n";
+
if((ntohs(packet->udp->source) < 1024)
|| (ntohs(packet->udp->dest) < 1024) /* High ports only */)
return;
@@ -395,44 +397,51 @@ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, st
*/
if(packet->payload_packet_len >= 23 /* min header size */) {
- /* Check if this is protocol v0 */
- u_int8_t v0_extension = packet->payload[17];
- u_int8_t v0_flags = packet->payload[18];
-
- /* Check if this is protocol v1 */
- u_int8_t v1_version = packet->payload[0];
- u_int8_t v1_extension = packet->payload[1];
- u_int32_t v1_window_size = *((u_int32_t*)&packet->payload[12]);
-
- if((packet->payload[0]== 0x60)
- && (packet->payload[1]== 0x0)
- && (packet->payload[2]== 0x0)
- && (packet->payload[3]== 0x0)
- && (packet->payload[4]== 0x0)) {
- /* Heuristic */
- goto bittorrent_found;
- } else if(((v1_version & 0x0f) == 1)
- && ((v1_version >> 4) < 5 /* ST_NUM_STATES */)
- && (v1_extension < 3 /* EXT_NUM_EXT */)
- && (v1_window_size < 32768 /* 32k */)
- ) {
- goto bittorrent_found;
- } else if((v0_flags < 6 /* ST_NUM_STATES */)
- && (v0_extension < 3 /* EXT_NUM_EXT */)) {
- u_int32_t ts = ntohl(*((u_int32_t*)&(packet->payload[4])));
- u_int32_t now;
+ if(strncmp((const char*)packet->payload, bt_search, strlen(bt_search)) == 0) {
+ ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
+ NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
+ NDPI_REAL_PROTOCOL);
+ return;
+ } else {
+ /* Check if this is protocol v0 */
+ u_int8_t v0_extension = packet->payload[17];
+ u_int8_t v0_flags = packet->payload[18];
+
+ /* Check if this is protocol v1 */
+ u_int8_t v1_version = packet->payload[0];
+ u_int8_t v1_extension = packet->payload[1];
+ u_int32_t v1_window_size = *((u_int32_t*)&packet->payload[12]);
+
+ if((packet->payload[0]== 0x60)
+ && (packet->payload[1]== 0x0)
+ && (packet->payload[2]== 0x0)
+ && (packet->payload[3]== 0x0)
+ && (packet->payload[4]== 0x0)) {
+ /* Heuristic */
+ goto bittorrent_found;
+ } else if(((v1_version & 0x0f) == 1)
+ && ((v1_version >> 4) < 5 /* ST_NUM_STATES */)
+ && (v1_extension < 3 /* EXT_NUM_EXT */)
+ && (v1_window_size < 32768 /* 32k */)
+ ) {
+ goto bittorrent_found;
+ } else if((v0_flags < 6 /* ST_NUM_STATES */)
+ && (v0_extension < 3 /* EXT_NUM_EXT */)) {
+ u_int32_t ts = ntohl(*((u_int32_t*)&(packet->payload[4])));
+ u_int32_t now;
#ifndef __KERNEL__
- now = (u_int32_t)time(NULL);
+ now = (u_int32_t)time(NULL);
#else
- struct timespec t;
+ struct timespec t;
- getnstimeofday(&t);
- now = t.tv_sec;
+ getnstimeofday(&t);
+ now = t.tv_sec;
#endif
- if((ts < (now+86400)) && (ts > (now-86400))) {
- goto bittorrent_found;
+ if((ts < (now+86400)) && (ts > (now-86400))) {
+ goto bittorrent_found;
+ }
}
}
}
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 071039340..631514afd 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -246,7 +246,7 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
j++, i++;
}
- if(a_record != 0) {
+ if(a_record[0] != 0) {
char a_buf[32];
int i;
diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c
new file mode 100644
index 000000000..ca4b12fab
--- /dev/null
+++ b/src/lib/protocols/quic.c
@@ -0,0 +1,157 @@
+/*
+ * quic.c
+ *
+ * Andrea Buscarinu - <andrea.buscarinu@gmail.com>
+ * Michele Campus - <michelecampus5@gmail.com>
+ * 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
+ * (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"
+
+#define QUIC_NO_V_RES_RSV 0xC3
+
+#define QUIC_CID_MASK 0x0C
+#define QUIC_VER_MASK 0x01
+#define QUIC_SEQ_MASK 0x30
+
+#define CID_LEN_8 0x0C
+#define CID_LEN_4 0x08
+#define CID_LEN_1 0x04
+#define CID_LEN_0 0x00
+
+#define SEQ_LEN_6 0x30
+#define SEQ_LEN_4 0x20
+#define SEQ_LEN_2 0x10
+#define SEQ_LEN_1 0x00
+
+#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)
+{
+ ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_REAL_PROTOCOL);
+}
+
+static int connect_id(const unsigned char pflags)
+{
+ u_int cid_len;
+
+ 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 cid_len + 1;
+}
+
+static int sequence(const unsigned char *payload)
+{
+ unsigned char conv[6] = {0};
+ u_int seq_value = -1;
+ int seq_lens;
+ int cid_offs;
+ int i;
+
+ 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;
+ }
+
+ cid_offs = connect_id(payload[0]);
+
+ if (cid_offs != -1 && seq_lens > 0)
+ {
+ for (i = 0; i < seq_lens; i++)
+ conv[i] = payload[cid_offs + i];
+
+ seq_value = SEQ_CONV(conv);
+ }
+
+ return seq_value;
+}
+
+void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &flow->packet;
+ unsigned char *vers;
+ 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(((packet->payload[0] & 0xC2) != 0) || (!(sport == 80 || dport == 80 || sport == 443 || dport == 443)))
+ goto exclude_quic;
+
+ /* Quic without version. First check if PUBLIC FLAGS & SEQ bytes are 0x0, SEQ must be greater than zero */
+ 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_int_quic_add_connection(ndpi_struct, flow);
+ }
+
+ else if (packet->payload[0] & QUIC_VER_MASK)
+ {
+ ver_offs = connect_id(packet->payload[0]);
+
+ if (ver_offs != -1){
+ vers = (unsigned char*)(packet->payload + ver_offs);
+
+ 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);
+ }
+ }
+ } else
+ {
+ exclude_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);
+ }
+ }
+}
+#endif
diff --git a/src/lib/protocols/redis.c b/src/lib/protocols/redis_net.c
index a47778b48..a47778b48 100644
--- a/src/lib/protocols/redis.c
+++ b/src/lib/protocols/redis_net.c
diff --git a/src/lib/protocols/warcraft3.c b/src/lib/protocols/warcraft3.c
index 7780dbf6e..39c93378e 100644
--- a/src/lib/protocols/warcraft3.c
+++ b/src/lib/protocols/warcraft3.c
@@ -43,7 +43,7 @@ void ndpi_search_warcraft3(struct ndpi_detection_module_struct
// struct ndpi_id_struct *src=ndpi_struct->src;
// struct ndpi_id_struct *dst=ndpi_struct->dst;
- u_int32_t l; /*
+ u_int16_t l; /*
Leave it as u_int32_t because otherwise 'u_int16_t temp'
might overflood it and thus generate an infinite loop
*/
diff --git a/src/lib/protocols/zmq.c b/src/lib/protocols/zeromq.c
index 12548a2ed..12548a2ed 100644
--- a/src/lib/protocols/zmq.c
+++ b/src/lib/protocols/zeromq.c
diff --git a/src/lib/third_party/include/patricia.h b/src/lib/third_party/include/ndpi_patricia.h
index be8476e85..651e52fc9 100644
--- a/src/lib/third_party/include/patricia.h
+++ b/src/lib/third_party/include/ndpi_patricia.h
@@ -1,5 +1,5 @@
/*
- * $Id: patricia.h,v 1.6 2005/12/07 20:53:01 dplonka Exp $
+ * $Id: ndpi_patricia.h,v 1.6 2005/12/07 20:53:01 dplonka Exp $
* Dave Plonka <plonka@doit.wisc.edu>
*
* This product includes software developed by the University of Michigan,
@@ -7,7 +7,7 @@
*
* This file had been called "radix.h" in the MRT sources.
*
- * I renamed it to "patricia.h" since it's not an implementation of a general
+ * I renamed it to "ndpi_patricia.h" since it's not an implementation of a general
* radix trie. Also, pulled in various requirements from "mrt.h" and added
* some other things it could be used as a standalone API.
@@ -38,10 +38,14 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _PATRICIA_H
-#define _PATRICIA_H
+#ifndef _NDPI_PATRICIA_H
+#define _NDPI_PATRICIA_H
-#define HAVE_IPV6
+#ifndef WIN32
+#define PATRICIA_IPV6 HAVE_IPV6
+#else
+#undef PATRICIA_IPV6
+#endif
/* typedef unsigned int u_int; */
/* { from defs.h */
@@ -94,7 +98,7 @@ typedef struct the_prefix_t {
int ref_count; /* reference count */
union {
struct in_addr sin;
-#ifdef HAVE_IPV6
+#ifdef PATRICIA_IPV6
struct in6_addr sin6;
#endif /* IPV6 */
} add;
@@ -138,7 +142,11 @@ void ndpi_Clear_Patricia (patricia_tree_t *patricia, void_fn_t func);
void ndpi_Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func);
void ndpi_patricia_process (patricia_tree_t *patricia, void_fn2_t func);
+#ifdef WIN32
+#define PATRICIA_MAXBITS 128
+#else
#define PATRICIA_MAXBITS (sizeof(struct in6_addr) * 8)
+#endif
#define PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f))
#define PATRICIA_NBYTE(x) ((x) >> 3)
@@ -185,7 +193,7 @@ void ndpi_patricia_process (patricia_tree_t *patricia, void_fn2_t func);
} \
} while (0)
-#endif /* _PATRICIA_H */
+#endif /* _NDPI_PATRICIA_H */
/*************************
diff --git a/src/lib/third_party/src/patricia.c b/src/lib/third_party/src/ndpi_patricia.c
index b7b4c2010..59d17e556 100644
--- a/src/lib/third_party/src/patricia.c
+++ b/src/lib/third_party/src/ndpi_patricia.c
@@ -58,7 +58,8 @@
#define assert(a) ;
#endif /* __KERNEL__ */
-#include "patricia.h"
+#include "ndpi_patricia.h"
+
#ifdef __KERNEL__
@@ -125,12 +126,12 @@ inet_pton (int af, const char *src, void *dst)
}
}
#ifdef NT
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
else if(af == AF_INET6) {
struct in6_addr Address;
return (inet6_addr(src, &Address));
}
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
#endif /* NT */
#ifndef NT
else {
@@ -174,10 +175,10 @@ ndpi_my_inet_pton (int af, const char *src, void *dst)
}
memcpy (dst, xp, sizeof(struct in_addr));
return (1);
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
} else if(af == AF_INET6) {
return (inet_pton (af, src, dst));
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
} else {
#ifndef NT
#ifndef __KERNEL__
@@ -195,7 +196,7 @@ ndpi_my_inet_pton (int af, const char *src, void *dst)
* thread safe and (almost) re-entrant implementation
*/
char *
-ndpi_ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
+ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
{
if(prefix == NULL)
return ((char*)"(Null)");
@@ -235,7 +236,7 @@ ndpi_ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
}
return (buff);
}
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
else if(prefix->family == AF_INET6) {
char *r;
r = (char *) inet_ntop (AF_INET6, &prefix->add.sin6, buff, 48 /* a guess value */ );
@@ -245,7 +246,7 @@ ndpi_ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
}
return (buff);
}
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
else
return (NULL);
}
@@ -256,7 +257,7 @@ ndpi_ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
char *
ndpi_prefix_toa2 (prefix_t *prefix, char *buff)
{
- return (ndpi_ndpi_prefix_toa2x (prefix, buff, 0));
+ return (ndpi_prefix_toa2x (prefix, buff, 0));
}
/* ndpi_prefix_toa
@@ -273,7 +274,7 @@ ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
int dynamic_allocated = 0;
int default_bitlen = sizeof(struct in_addr) * 8;
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
if(family == AF_INET6) {
default_bitlen = sizeof(struct in6_addr) * 8;
if(prefix == NULL) {
@@ -283,7 +284,7 @@ ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
memcpy (&prefix->add.sin6, dest, sizeof(struct in6_addr));
}
else
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
if(family == AF_INET) {
if(prefix == NULL) {
#ifndef NT
@@ -327,9 +328,9 @@ ndpi_ascii2prefix (int family, char *string)
long maxbitlen = 0;
char *cp;
struct in_addr sin;
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
struct in6_addr sin6;
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
char save[MAXLINE];
if(string == NULL)
@@ -338,19 +339,19 @@ ndpi_ascii2prefix (int family, char *string)
/* easy way to handle both families */
if(family == 0) {
family = AF_INET;
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
if(strchr (string, ':')) family = AF_INET6;
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
}
if(family == AF_INET) {
maxbitlen = sizeof(struct in_addr) * 8;
}
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
else if(family == AF_INET6) {
maxbitlen = sizeof(struct in6_addr) * 8;
}
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
if((cp = strchr (string, '/')) != NULL) {
bitlen = atol (cp + 1);
@@ -372,7 +373,7 @@ ndpi_ascii2prefix (int family, char *string)
return (ndpi_New_Prefix (AF_INET, &sin, bitlen));
}
-#if defined(HAVE_IPV6) && (!defined(__KERNEL__))
+#if defined(PATRICIA_IPV6) && (!defined(__KERNEL__))
else if(family == AF_INET6) {
// Get rid of this with next IPv6 upgrade
#if defined(NT) && !defined(HAVE_INET_NTOP)
@@ -384,7 +385,7 @@ ndpi_ascii2prefix (int family, char *string)
#endif /* NT */
return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen));
}
-#endif /* HAVE_IPV6 */
+#endif /* PATRICIA_IPV6 */
else
return (NULL);
}
diff --git a/tests/do.sh b/tests/do.sh
new file mode 100755
index 000000000..2af667551
--- /dev/null
+++ b/tests/do.sh
@@ -0,0 +1,39 @@
+
+READER=../example/ndpiReader
+
+RC=0
+PCAPS=`cd pcap; /bin/ls *.pcap`
+
+build_results() {
+ for f in $PCAPS; do
+ #echo $f
+ # create result files if not present
+ [ ! -f result/$f.out ] && $READER -q -i pcap/$f -w result/$f.out
+ done
+}
+
+check_results() {
+ for f in $PCAPS; do
+ if [ -f result/$f.out ]; then
+ CMD="$READER -q -i pcap/$f -w /tmp/reader.out"
+ $CMD
+ NUM_DIFF=`diff result/$f.out /tmp/reader.out | wc -l`
+
+ if [ $NUM_DIFF -eq 0 ]; then
+ echo "$f\t OK"
+ else
+ echo "$f\t ERROR"
+ echo "$CMD"
+ diff result/$f.out /tmp/reader.out
+ RC=1
+ fi
+
+ /bin/rm /tmp/reader.out
+ fi
+ done
+}
+
+build_results
+check_results
+
+exit $RC \ No newline at end of file
diff --git a/tests/pcap/README.txt b/tests/pcap/README.txt
new file mode 100644
index 000000000..2505fe9c2
--- /dev/null
+++ b/tests/pcap/README.txt
@@ -0,0 +1 @@
+Place here test pcaps used for regressions testing
diff --git a/tests/pcap/bt_search.pcap b/tests/pcap/bt_search.pcap
new file mode 100644
index 000000000..7d2a815ad
--- /dev/null
+++ b/tests/pcap/bt_search.pcap
Binary files differ
diff --git a/tests/pcap/quic.pcap b/tests/pcap/quic.pcap
new file mode 100644
index 000000000..5de878c1a
--- /dev/null
+++ b/tests/pcap/quic.pcap
Binary files differ
diff --git a/tests/pcap/skype.pcap b/tests/pcap/skype.pcap
new file mode 100644
index 000000000..d8c85f508
--- /dev/null
+++ b/tests/pcap/skype.pcap
Binary files differ
diff --git a/tests/pcap/skype_no_unknown.pcap b/tests/pcap/skype_no_unknown.pcap
new file mode 100644
index 000000000..5266bca6f
--- /dev/null
+++ b/tests/pcap/skype_no_unknown.pcap
Binary files differ
diff --git a/tests/result/README.txt b/tests/result/README.txt
new file mode 100644
index 000000000..08992145b
--- /dev/null
+++ b/tests/result/README.txt
@@ -0,0 +1,5 @@
+Place here test results for pcaps used for regressions testing
+
+Example
+
+for pcap/myprotocol.pcap add result/myprotocol.result
diff --git a/tests/result/bt_search.pcap.out b/tests/result/bt_search.pcap.out
new file mode 100644
index 000000000..6cf54c85a
--- /dev/null
+++ b/tests/result/bt_search.pcap.out
@@ -0,0 +1 @@
+BitTorrent 2 322 1
diff --git a/tests/result/quic.pcap.out b/tests/result/quic.pcap.out
new file mode 100644
index 000000000..900864e4d
--- /dev/null
+++ b/tests/result/quic.pcap.out
@@ -0,0 +1 @@
+Quic 413 254874 1
diff --git a/tests/result/skype.pcap.out b/tests/result/skype.pcap.out
new file mode 100644
index 000000000..404442549
--- /dev/null
+++ b/tests/result/skype.pcap.out
@@ -0,0 +1,13 @@
+Unknown 409 49221 18
+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 20 1516 1
+DropBox 38 17948 5
+Skype 2362 501011 246
+Apple 15 2045 2
+AppleiCloud 88 20520 2
+Spotify 5 430 1
diff --git a/tests/result/skype_no_unknown.pcap.out b/tests/result/skype_no_unknown.pcap.out
new file mode 100644
index 000000000..2b6435897
--- /dev/null
+++ b/tests/result/skype_no_unknown.pcap.out
@@ -0,0 +1,11 @@
+Unknown 241 60170 16
+DNS 6 627 3
+MDNS 3 400 2
+NetBIOS 22 3106 7
+SSDP 40 14100 3
+ICMP 4 328 1
+IGMP 4 226 4
+SSL 22 1444 3
+DropBox 16 7342 5
+Skype 1637 379382 221
+Apple 84 20699 2