diff options
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 Binary files differnew file mode 100644 index 000000000..7d2a815ad --- /dev/null +++ b/tests/pcap/bt_search.pcap diff --git a/tests/pcap/quic.pcap b/tests/pcap/quic.pcap Binary files differnew file mode 100644 index 000000000..5de878c1a --- /dev/null +++ b/tests/pcap/quic.pcap diff --git a/tests/pcap/skype.pcap b/tests/pcap/skype.pcap Binary files differnew file mode 100644 index 000000000..d8c85f508 --- /dev/null +++ b/tests/pcap/skype.pcap diff --git a/tests/pcap/skype_no_unknown.pcap b/tests/pcap/skype_no_unknown.pcap Binary files differnew file mode 100644 index 000000000..5266bca6f --- /dev/null +++ b/tests/pcap/skype_no_unknown.pcap 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 |