diff options
96 files changed, 3693 insertions, 2331 deletions
diff --git a/Makefile.am b/Makefile.am index 80258e773..17c674812 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src/lib example +SUBDIRS = src/lib example tests pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libndpi.pc @@ -1,7 +1,7 @@ ![ntop][ntopng_logo] ![ntop][ntop_logo] # nDPI -[](https://travis-ci.org/ntop/nDPI) +[](https://travis-ci.org/ntop/nDPI) ## What is nDPI ? @@ -15,6 +15,10 @@ In order to compile this library do - ./configure - make +To run tests do additionally: + +- make check + Please note that the pre-requisites for compilation include: - GNU tools (autogen, automake, autoconf, libtool) - GNU C compiler (gcc) @@ -23,7 +27,7 @@ Please note that the pre-requisites for compilation include: The entire procedure of adding new protocols in detail: -1. Add new protocol together with its unique ID to: src/include/ndpi_protocols_osdpi.h +1. Add new protocol together with its unique ID to: src/include/ndpi_protocol_ids.h 2. Create a new protocol in: src/lib/protocols/ 3. Variables to be kept for the duration of the entire flow (as state variables) needs to be placed in: /include/ndpi_structs.h in ndpi_flow_tcp_struct (for TCP only), ndpi_flow_udp_struct (for UDP only), or ndpi_flow_struct (for both). 4. Add a new entry for the search function for the new protocol in: src/include/ndpi_protocols.h @@ -34,6 +38,7 @@ The entire procedure of adding new protocols in detail: 9. ./autogen.sh 10. ./configure 11. make +12. make check ### Creating A Source File Tar Ball @@ -41,6 +46,10 @@ If you want to distribute a source tar file of nDPI do: - make dist +To ensure that a tar file includes all necessary files and to run tests on distribution do: + +- make distcheck + [ntopng_logo]: https://camo.githubusercontent.com/0f789abcef232035c05e0d2e82afa3cc3be46485/687474703a2f2f7777772e6e746f702e6f72672f77702d636f6e74656e742f75706c6f6164732f323031312f30382f6e746f706e672d69636f6e2d313530783135302e706e67 [ntop_logo]: https://camo.githubusercontent.com/58e2a1ecfff62d8ecc9d74633bd1013f26e06cba/687474703a2f2f7777772e6e746f702e6f72672f77702d636f6e74656e742f75706c6f6164732f323031352f30352f6e746f702e706e67 diff --git a/README.protocols b/README.protocols index 27d8c6408..1c77df15b 100644 --- a/README.protocols +++ b/README.protocols @@ -8,7 +8,7 @@ TCP 172.16.253.130:2021 <-> 75.147.140.249:443 [VLAN: 0][proto: 91/SSL][28 pkts/ TCP 172.16.253.130:2077 <-> 77.247.181.163:443 [VLAN: 0][proto: 91/SSL][136 pkts/94329 bytes][SSL client: www.fk4pprq42hsvl2wey.com] It can be detected by analyzing the SSL client certificate and checking the name that does not match to a real host in -addition of begin a bit weird. As doing DNS resolution is not a task for nDPI we let applications do and then recognize +addition of being a bit weird. As doing DNS resolution is not a task for nDPI we let applications do and then recognize SSL-tunnelled connections. See http://www.netresec.com/?page=Blog&month=2013-04&post=Detecting-TOR-Communication-in-Network-Traffic diff --git a/configure.ac b/configure.ac index e65baea81..70e3f1888 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([libndpi], [1.7.1]) +AC_INIT([libndpi], [1.8.0]) AC_CONFIG_MACRO_DIR([m4]) @@ -87,7 +87,7 @@ LIBS=$OLD_LIBS AC_CHECK_LIB(pthread, pthread_setaffinity_np, AC_DEFINE_UNQUOTED(HAVE_PTHREAD_SETAFFINITY_NP, 1, [libc has pthread_setaffinity_np])) -AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile libndpi.pc]) +AC_CONFIG_FILES([Makefile src/lib/Makefile example/Makefile tests/Makefile libndpi.pc]) AC_CONFIG_HEADERS(config.h) AC_SUBST(GIT_RELEASE) AC_SUBST(SVN_DATE) diff --git a/example/Makefile.am b/example/Makefile.am index f98bae9ae..a55212c92 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -6,7 +6,7 @@ AM_CFLAGS = @PTHREAD_CFLAGS@ LDADD = $(top_builddir)/src/lib/libndpi.la @JSON_C_LIB@ @PTHREAD_LIBS@ @PCAP_LIB@ AM_LDFLAGS = -static -ndpiReader_SOURCES = ndpiReader.c +ndpiReader_SOURCES = ndpiReader.c ndpi_util.c ndpi_util.h ndpiReader.o: ndpiReader.c diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 52fac6a65..deb61b681 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1,9 +1,7 @@ /* * ndpiReader.c * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2014 - Matteo Bogo <matteo.bogo@gmail.com> (JSON support) + * Copyright (C) 2011-16 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -43,7 +41,7 @@ #include <signal.h> #include <pthread.h> #include <sys/socket.h> - +#include <assert.h> #include "../config.h" #include "ndpi_api.h" @@ -51,51 +49,9 @@ #include <json.h> #endif -#define MAX_NUM_READER_THREADS 16 -#define IDLE_SCAN_PERIOD 10 /* msec (use detection_tick_resolution = 1000) */ -#define MAX_IDLE_TIME 30000 -#define IDLE_SCAN_BUDGET 1024 -#define NUM_ROOTS 512 -#define GTP_U_V1_PORT 2152 -#define TZSP_PORT 37008 -#define MAX_NDPI_FLOWS 200000000 - -#ifndef ETH_P_IP -#define ETH_P_IP 0x0800 /* IPv4 */ -#endif - -#ifndef ETH_P_IPv6 -#define ETH_P_IPV6 0x86dd /* IPv6 */ -#endif - -#define SLARP 0x8035 /* Cisco Slarp */ -#define CISCO_D_PROTO 0x2000 /* Cisco Discovery Protocol */ - -#define VLAN 0x8100 -#define MPLS_UNI 0x8847 -#define MPLS_MULTI 0x8848 -#define PPPoE 0x8864 -#define SNAP 0xaa - -/* mask for FCF */ -#define WIFI_DATA 0x2 /* 0000 0010 */ -#define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */ -#define FCF_SUBTYPE(fc) (((fc) >> 4) & 0xF) /* 0000 1111 = 0xF */ -#define FCF_TO_DS(fc) ((fc) & 0x0100) -#define FCF_FROM_DS(fc) ((fc) & 0x0200) - -/* mask for Bad FCF presence */ -#define BAD_FCS 0x50 /* 0101 0000 */ - -/** - * @brief Set main components necessary to the detection - * @details TODO - */ -static void setupDetection(u_int16_t thread_id); +#include "ndpi_util.h" -/** - * Client parameters - */ +/** Client parameters **/ static char *_pcap_file[MAX_NUM_READER_THREADS]; /**< Ingress pcap file/interafaces */ static FILE *playlist_fp[MAX_NUM_READER_THREADS] = { NULL }; /**< Ingress playlist */ static FILE *results_file = NULL; @@ -110,107 +66,59 @@ static json_object *jArray_known_flows, *jArray_unknown_flows; #endif static u_int8_t live_capture = 0; static u_int8_t undetected_flows_deleted = 0; -/** - * User preferences - */ +/** User preferences **/ static u_int8_t enable_protocol_guess = 1, verbose = 0, nDPI_traceLevel = 0, json_flag = 0; static u_int16_t decode_tunnels = 0; static u_int16_t num_loops = 1; static u_int8_t shutdown_app = 0, quiet_mode = 0; static u_int8_t num_threads = 1; -static u_int32_t current_ndpi_memory = 0, max_ndpi_memory = 0; #ifdef linux static int core_affinity[MAX_NUM_READER_THREADS]; #endif - static struct timeval pcap_start, pcap_end; - -/** - * Detection parameters - */ -static u_int32_t detection_tick_resolution = 1000; +/** Detection parameters **/ static time_t capture_for = 0; static time_t capture_until = 0; - static u_int32_t num_flows; -struct thread_stats { - u_int32_t guessed_flow_protocols; - u_int64_t raw_packet_count; - u_int64_t ip_packet_count; - u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes; - u_int64_t protocol_counter[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; - u_int64_t protocol_counter_bytes[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; - u_int32_t protocol_flows[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; - u_int32_t ndpi_flow_count; - u_int64_t tcp_count, udp_count; - u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count; - u_int64_t packet_len[6]; - u_int16_t max_packet_len; -}; - +// struct associated to a workflow for a thread struct reader_thread { - struct ndpi_detection_module_struct *ndpi_struct; - void *ndpi_flows_root[NUM_ROOTS]; - char _pcap_error_buffer[PCAP_ERRBUF_SIZE]; - pcap_t *_pcap_handle; - u_int64_t last_time; + struct ndpi_workflow * workflow; + pthread_t pthread; u_int64_t last_idle_scan_time; u_int32_t idle_scan_idx; u_int32_t num_idle_flows; - pthread_t pthread; - int _pcap_datalink_type; - - /* TODO Add barrier */ - struct thread_stats stats; - - struct ndpi_flow *idle_flows[IDLE_SCAN_BUDGET]; + struct ndpi_flow_info *idle_flows[IDLE_SCAN_BUDGET]; }; +// array for every thread created for a flow static struct reader_thread ndpi_thread_info[MAX_NUM_READER_THREADS]; -/** - * @brief ID tracking - */ +// ID tracking typedef struct ndpi_id { - u_int8_t ip[4]; // Ip address - struct ndpi_id_struct *ndpi_id; // nDpi worker structure + u_int8_t ip[4]; // Ip address + struct ndpi_id_struct *ndpi_id; // nDpi worker structure } ndpi_id_t; -static u_int32_t size_id_struct = 0; // ID tracking structure size - -// flow tracking -typedef struct ndpi_flow { - u_int32_t lower_ip; - u_int32_t upper_ip; - u_int16_t lower_port; - u_int16_t upper_port; - u_int8_t detection_completed, protocol; - u_int16_t vlan_id; - struct ndpi_flow_struct *ndpi_flow; - char lower_name[48], upper_name[48]; - u_int8_t ip_version; - u_int64_t last_seen; - u_int64_t bytes; - u_int32_t packets; +// used memory counters +u_int32_t current_ndpi_memory = 0, max_ndpi_memory = 0; - // result only, not used for flow identification - ndpi_protocol detected_protocol; - char host_server_name[192]; - char bittorent_hash[41]; +/********************** FUNCTIONS ********************* */ - struct { - char client_certificate[48], server_certificate[48]; - } ssl; - - void *src_id, *dst_id; -} ndpi_flow_t; +/** + * @brief Set main components necessary to the detection + */ +static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle); -static u_int32_t size_flow_struct = 0; +/** + * @brief Print help instructions + */ static void help(u_int long_help) { + printf("Welcome to nDPI %s\n\n", ndpi_revision()); + printf("ndpiReader -i <file|device> [-f <filter>][-s <duration>]\n" " [-p <protos>][-l <loops> [-q][-d][-h][-t][-v <level>]\n" " [-n <threads>] [-w <file>] [-j <file>]\n\n" @@ -237,16 +145,18 @@ static void help(u_int long_help) { if(long_help) { printf("\n\nSupported protocols:\n"); num_threads = 1; - setupDetection(0); - ndpi_dump_protocols(ndpi_thread_info[0].ndpi_struct); + setupDetection(0, NULL); + ndpi_dump_protocols(ndpi_thread_info[0].workflow->ndpi_struct); } - exit(!long_help); } -/* ***************************************************** */ +/** + * @brief Option parser + */ static void parseOptions(int argc, char **argv) { + char *__pcap_file = NULL, *bind_mask = NULL; int thread_id, opt; #ifdef linux @@ -342,7 +252,7 @@ static void parseOptions(int argc, char **argv) { } if(strchr(_pcap_file[0], ',')) { /* multiple ingress interfaces */ - num_threads = 0; /* setting number of threads = number of interfaces */ + num_threads = 0; /* setting number of threads = number of interfaces */ __pcap_file = strtok(_pcap_file[0], ","); while (__pcap_file != NULL && num_threads < MAX_NUM_READER_THREADS) { _pcap_file[num_threads++] = __pcap_file; @@ -369,63 +279,12 @@ static void parseOptions(int argc, char **argv) { #endif } -/* ***************************************************** */ - -static void debug_printf(u_int32_t protocol, void *id_struct, - ndpi_log_level_t log_level, - const char *format, ...) { - va_list va_ap; -#ifndef WIN32 - struct tm result; -#endif - - if(log_level <= nDPI_traceLevel) { - char buf[8192], out_buf[8192]; - char theDate[32]; - const char *extra_msg = ""; - time_t theTime = time(NULL); - - va_start (va_ap, format); - - if(log_level == NDPI_LOG_ERROR) - extra_msg = "ERROR: "; - else if(log_level == NDPI_LOG_TRACE) - extra_msg = "TRACE: "; - else - extra_msg = "DEBUG: "; - - memset(buf, 0, sizeof(buf)); - strftime(theDate, 32, "%d/%b/%Y %H:%M:%S", localtime_r(&theTime,&result) ); - vsnprintf(buf, sizeof(buf)-1, format, va_ap); - - snprintf(out_buf, sizeof(out_buf), "%s %s%s", theDate, extra_msg, buf); - printf("%s", out_buf); - fflush(stdout); - } - - va_end(va_ap); -} - -/* ***************************************************** */ - -static void *malloc_wrapper(size_t size) { - current_ndpi_memory += size; - - if(current_ndpi_memory > max_ndpi_memory) - max_ndpi_memory = current_ndpi_memory; - - return malloc(size); -} - -/* ***************************************************** */ - -static void free_wrapper(void *freeable) { - free(freeable); -} - -/* ***************************************************** */ +/** + * @brief From IPPROTO to string NAME + */ static char* ipProto2Name(u_short proto_id) { + static char proto[8]; switch(proto_id) { @@ -453,12 +312,12 @@ static char* ipProto2Name(u_short proto_id) { return(proto); } -/* ***************************************************** */ -/* - * A faster replacement for inet_ntoa(). +/** + * @brief A faster replacement for inet_ntoa(). */ char* intoaV4(unsigned int addr, char* buf, u_short bufLen) { + char *cp, *retStr; uint byte; int n; @@ -487,9 +346,10 @@ char* intoaV4(unsigned int addr, char* buf, u_short bufLen) { return(retStr); } -/* ***************************************************** */ - -static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) { +/** + * @brief Print the flow + */ +static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { #ifdef HAVE_JSON_C json_object *jObj; #endif @@ -501,11 +361,11 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) { fprintf(out, "\t%s %s%s%s:%u <-> %s%s%s:%u ", ipProto2Name(flow->protocol), (flow->ip_version == 6) ? "[" : "", - flow->lower_name, + flow->lower_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->lower_port), (flow->ip_version == 6) ? "[" : "", - flow->upper_name, + flow->upper_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->upper_port)); @@ -516,12 +376,12 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) { fprintf(out, "[proto: %u.%u/%s]", flow->detected_protocol.master_protocol, flow->detected_protocol.protocol, - ndpi_protocol2name(ndpi_thread_info[thread_id].ndpi_struct, + ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol, buf, sizeof(buf))); } else fprintf(out, "[proto: %u/%s]", flow->detected_protocol.protocol, - ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol)); + ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.protocol)); fprintf(out, "[%u pkts/%llu bytes]", flow->packets, (long long unsigned int)flow->bytes); @@ -551,14 +411,14 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) { char tmp[256]; snprintf(tmp, sizeof(tmp), "%s.%s", - ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.master_protocol), - ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, flow->detected_protocol.protocol)); + ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.master_protocol), + ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.protocol)); json_object_object_add(jObj,"detected.protocol.name", json_object_new_string(tmp)); } else json_object_object_add(jObj,"detected.protocol.name", - json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[thread_id].ndpi_struct, + json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.protocol))); json_object_object_add(jObj,"packets",json_object_new_int(flow->packets)); @@ -579,7 +439,6 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) { json_object_object_add(jObj, "ssl", sjObj); } - //flow->protos.ssl.client_certificate, flow->protos.ssl.server_certificate); if(json_flag == 1) json_object_array_add(jArray_known_flows,jObj); else if(json_flag == 2) @@ -588,28 +447,13 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow *flow) { } } -/* ***************************************************** */ - -static void free_ndpi_flow(struct ndpi_flow *flow) { - if(flow->ndpi_flow) { ndpi_free_flow(flow->ndpi_flow); flow->ndpi_flow = NULL; } - if(flow->src_id) { ndpi_free(flow->src_id); flow->src_id = NULL; } - if(flow->dst_id) { ndpi_free(flow->dst_id); flow->dst_id = NULL; } - -} - -/* ***************************************************** */ - -static void ndpi_flow_freer(void *node) { - struct ndpi_flow *flow = (struct ndpi_flow*)node; - - free_ndpi_flow(flow); - ndpi_free(flow); -} - -/* ***************************************************** */ +/** + * @brief Unknown Proto Walker + */ static void node_print_unknown_proto_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { - struct ndpi_flow *flow = *(struct ndpi_flow**)node; + + struct ndpi_flow_info *flow = *(struct ndpi_flow_info**)node; u_int16_t thread_id = *((u_int16_t*)user_data); if(flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN) return; @@ -618,10 +462,12 @@ static void node_print_unknown_proto_walker(const void *node, ndpi_VISIT which, printFlow(thread_id, flow); } -/* ***************************************************** */ - +/** + * @brief Known Proto Walker + */ static void node_print_known_proto_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { - struct ndpi_flow *flow = *(struct ndpi_flow**)node; + + struct ndpi_flow_info *flow = *(struct ndpi_flow_info**)node; u_int16_t thread_id = *((u_int16_t*)user_data); if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) return; @@ -630,10 +476,13 @@ static void node_print_known_proto_walker(const void *node, ndpi_VISIT which, in printFlow(thread_id, flow); } -/* ***************************************************** */ -static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi_flow *flow) { - flow->detected_protocol = ndpi_guess_undetected_protocol(ndpi_thread_info[thread_id].ndpi_struct, +/** + * @brief Guess Undetected Protocol + */ +static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi_flow_info *flow) { + + flow->detected_protocol = ndpi_guess_undetected_protocol(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->protocol, ntohl(flow->lower_ip), ntohs(flow->lower_port), @@ -641,20 +490,23 @@ static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi ntohs(flow->upper_port)); // printf("Guess state: %u\n", flow->detected_protocol); if(flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN) - ndpi_thread_info[thread_id].stats.guessed_flow_protocols++; + ndpi_thread_info[thread_id].workflow->stats.guessed_flow_protocols++; return(flow->detected_protocol.protocol); } -/* ***************************************************** */ +/** + * @brief Proto Guess Walker + */ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { - struct ndpi_flow *flow = *(struct ndpi_flow **) node; + + struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node; u_int16_t thread_id = *((u_int16_t *) user_data); if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ if((!flow->detection_completed) && flow->ndpi_flow) - flow->detected_protocol = ndpi_detection_giveup(ndpi_thread_info[0].ndpi_struct, flow->ndpi_flow); + flow->detected_protocol = ndpi_detection_giveup(ndpi_thread_info[0].workflow->ndpi_struct, flow->ndpi_flow); if(enable_protocol_guess) { if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) { @@ -663,23 +515,26 @@ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int dept } } - ndpi_thread_info[thread_id].stats.protocol_counter[flow->detected_protocol.protocol] += flow->packets; - ndpi_thread_info[thread_id].stats.protocol_counter_bytes[flow->detected_protocol.protocol] += flow->bytes; - ndpi_thread_info[thread_id].stats.protocol_flows[flow->detected_protocol.protocol]++; + ndpi_thread_info[thread_id].workflow->stats.protocol_counter[flow->detected_protocol.protocol] += flow->packets; + ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes[flow->detected_protocol.protocol] += flow->bytes; + ndpi_thread_info[thread_id].workflow->stats.protocol_flows[flow->detected_protocol.protocol]++; } } -/* ***************************************************** */ +/** + * @brief Idle Scan Walker + */ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { - struct ndpi_flow *flow = *(struct ndpi_flow **) node; + + struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node; u_int16_t thread_id = *((u_int16_t *) user_data); if(ndpi_thread_info[thread_id].num_idle_flows == IDLE_SCAN_BUDGET) /* TODO optimise with a budget-based walk */ return; if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ - if(flow->last_seen + MAX_IDLE_TIME < ndpi_thread_info[thread_id].last_time) { + if(flow->last_seen + MAX_IDLE_TIME < ndpi_thread_info[thread_id].workflow->last_time) { /* update stats */ node_proto_guess_walker(node, which, depth, user_data); @@ -687,8 +542,8 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth, if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && !undetected_flows_deleted) undetected_flows_deleted = 1; - free_ndpi_flow(flow); - ndpi_thread_info[thread_id].stats.ndpi_flow_count--; + ndpi_free_flow_info_half(flow); + ndpi_thread_info[thread_id].workflow->stats.ndpi_flow_count--; /* adding to a queue (we can't delete it from the tree inline ) */ ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows++] = flow; @@ -696,441 +551,121 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth, } } -/* ***************************************************** */ - -static int node_cmp(const void *a, const void *b) { - struct ndpi_flow *fa = (struct ndpi_flow*)a; - struct ndpi_flow *fb = (struct ndpi_flow*)b; - - if(fa->vlan_id < fb->vlan_id ) return(-1); else { if(fa->vlan_id > fb->vlan_id ) return(1); } - if(fa->lower_ip < fb->lower_ip ) return(-1); else { if(fa->lower_ip > fb->lower_ip ) return(1); } - if(fa->lower_port < fb->lower_port) return(-1); else { if(fa->lower_port > fb->lower_port) return(1); } - if(fa->upper_ip < fb->upper_ip ) return(-1); else { if(fa->upper_ip > fb->upper_ip ) return(1); } - if(fa->upper_port < fb->upper_port) return(-1); else { if(fa->upper_port > fb->upper_port) return(1); } - if(fa->protocol < fb->protocol ) return(-1); else { if(fa->protocol > fb->protocol ) return(1); } - - return(0); -} - -/* ***************************************************** */ - -static struct ndpi_flow *get_ndpi_flow(u_int16_t thread_id, - const u_int8_t version, - u_int16_t vlan_id, - const struct ndpi_iphdr *iph, - const struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - u_int16_t ipsize, - u_int16_t l4_packet_len, - struct ndpi_tcphdr **tcph, - struct ndpi_udphdr **udph, - u_int16_t *sport, u_int16_t *dport, - struct ndpi_id_struct **src, - struct ndpi_id_struct **dst, - u_int8_t *proto, - u_int8_t **payload, - u_int16_t *payload_len, - u_int8_t *src_to_dst_direction) { - u_int32_t idx, l4_offset; - u_int32_t lower_ip; - u_int32_t upper_ip; - u_int16_t lower_port; - u_int16_t upper_port; - struct ndpi_flow flow; - void *ret; - u_int8_t *l3, *l4; - - /* - Note: to keep things simple (ndpiReader is just a demo app) - we handle IPv6 a-la-IPv4. - */ - if(version == 4) { - if(ipsize < 20) - return NULL; - - if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len) - || (iph->frag_off & htons(0x1FFF)) != 0) - return NULL; - - l4_offset = iph->ihl * 4; - l3 = (u_int8_t*)iph; - } else { - l4_offset = sizeof(struct ndpi_ipv6hdr); - l3 = (u_int8_t*)iph6; - } - - if(l4_packet_len < 64) - ndpi_thread_info[thread_id].stats.packet_len[0]++; - else if(l4_packet_len >= 64 && l4_packet_len < 128) - ndpi_thread_info[thread_id].stats.packet_len[1]++; - else if(l4_packet_len >= 128 && l4_packet_len < 256) - ndpi_thread_info[thread_id].stats.packet_len[2]++; - else if(l4_packet_len >= 256 && l4_packet_len < 1024) - ndpi_thread_info[thread_id].stats.packet_len[3]++; - else if(l4_packet_len >= 1024 && l4_packet_len < 1500) - ndpi_thread_info[thread_id].stats.packet_len[4]++; - else if(l4_packet_len >= 1500) - ndpi_thread_info[thread_id].stats.packet_len[5]++; - - if(l4_packet_len > ndpi_thread_info[thread_id].stats.max_packet_len) - ndpi_thread_info[thread_id].stats.max_packet_len = l4_packet_len; - - if(iph->saddr < iph->daddr) { - lower_ip = iph->saddr; - upper_ip = iph->daddr; - } else { - lower_ip = iph->daddr; - upper_ip = iph->saddr; - } - - *proto = iph->protocol; - l4 = ((u_int8_t *) l3 + l4_offset); - if(iph->protocol == 6 && l4_packet_len >= 20) { - u_int tcp_len; - - ndpi_thread_info[thread_id].stats.tcp_count++; - - // tcp - *tcph = (struct ndpi_tcphdr *)l4; - *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest); - - if(iph->saddr < iph->daddr) { - lower_port = (*tcph)->source, upper_port = (*tcph)->dest; - *src_to_dst_direction = 1; - } else { - lower_port = (*tcph)->dest; - upper_port = (*tcph)->source; - - *src_to_dst_direction = 0; - if(iph->saddr == iph->daddr) { - if(lower_port > upper_port) { - u_int16_t p = lower_port; +/** + * @brief On Protocol Discover - call node_guess_undetected_protocol() for protocol + */ +static void on_protocol_discovered(struct ndpi_workflow * workflow, + struct ndpi_flow_info * flow, + void * udata) { + + const u_int16_t thread_id = (uintptr_t) udata; - lower_port = upper_port; - upper_port = p; - } + if(verbose > 1){ + if(enable_protocol_guess) { + if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) { + flow->detected_protocol.protocol = node_guess_undetected_protocol(thread_id, flow), + flow->detected_protocol.master_protocol = NDPI_PROTOCOL_UNKNOWN; } } - tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len); - *payload = &l4[tcp_len]; - *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff); - } else if(iph->protocol == 17 && l4_packet_len >= 8) { - // udp - ndpi_thread_info[thread_id].stats.udp_count++; - - *udph = (struct ndpi_udphdr *)l4; - *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest); - *payload = &l4[sizeof(struct ndpi_udphdr)]; - *payload_len = ndpi_max(0, l4_packet_len-sizeof(struct ndpi_udphdr)); - - if(iph->saddr < iph->daddr) { - lower_port = (*udph)->source, upper_port = (*udph)->dest; - *src_to_dst_direction = 1; - } else { - lower_port = (*udph)->dest, upper_port = (*udph)->source; - - *src_to_dst_direction = 0; - - if(iph->saddr == iph->daddr) { - if(lower_port > upper_port) { - u_int16_t p = lower_port; - - lower_port = upper_port; - upper_port = p; - } - } - } - - *sport = ntohs(lower_port), *dport = ntohs(upper_port); - } else { - // non tcp/udp protocols - lower_port = 0; - upper_port = 0; + printFlow(thread_id, flow); } +} - flow.protocol = iph->protocol, flow.vlan_id = vlan_id; - flow.lower_ip = lower_ip, flow.upper_ip = upper_ip; - flow.lower_port = lower_port, flow.upper_port = upper_port; - - if(0) - printf("[NDPI] [%u][%u:%u <-> %u:%u]\n", - iph->protocol, lower_ip, ntohs(lower_port), upper_ip, ntohs(upper_port)); - - idx = (vlan_id + lower_ip + upper_ip + iph->protocol + lower_port + upper_port) % NUM_ROOTS; - ret = ndpi_tfind(&flow, &ndpi_thread_info[thread_id].ndpi_flows_root[idx], node_cmp); - - if(ret == NULL) { - if(ndpi_thread_info[thread_id].stats.ndpi_flow_count == MAX_NDPI_FLOWS) { - printf("ERROR: maximum flow count (%u) has been exceeded\n", MAX_NDPI_FLOWS); - exit(-1); - } else { - struct ndpi_flow *newflow = (struct ndpi_flow*)malloc(sizeof(struct ndpi_flow)); - - if(newflow == NULL) { - printf("[NDPI] %s(1): not enough memory\n", __FUNCTION__); - return(NULL); - } - - memset(newflow, 0, sizeof(struct ndpi_flow)); - newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id; - newflow->lower_ip = lower_ip, newflow->upper_ip = upper_ip; - newflow->lower_port = lower_port, newflow->upper_port = upper_port; - newflow->ip_version = version; - - if(version == 4) { - inet_ntop(AF_INET, &lower_ip, newflow->lower_name, sizeof(newflow->lower_name)); - inet_ntop(AF_INET, &upper_ip, newflow->upper_name, sizeof(newflow->upper_name)); - } else { - inet_ntop(AF_INET6, &iph6->ip6_src, newflow->lower_name, sizeof(newflow->lower_name)); - inet_ntop(AF_INET6, &iph6->ip6_dst, newflow->upper_name, sizeof(newflow->upper_name)); - } - - if((newflow->ndpi_flow = malloc_wrapper(size_flow_struct)) == NULL) { - printf("[NDPI] %s(2): not enough memory\n", __FUNCTION__); - free(newflow); - return(NULL); - } else - memset(newflow->ndpi_flow, 0, size_flow_struct); - - if((newflow->src_id = malloc_wrapper(size_id_struct)) == NULL) { - printf("[NDPI] %s(3): not enough memory\n", __FUNCTION__); - free(newflow); - return(NULL); - } else - memset(newflow->src_id, 0, size_id_struct); - if((newflow->dst_id = malloc_wrapper(size_id_struct)) == NULL) { - printf("[NDPI] %s(4): not enough memory\n", __FUNCTION__); - free(newflow); - return(NULL); - } else - memset(newflow->dst_id, 0, size_id_struct); +/** + * @brief Print debug + */ +static void debug_printf(u_int32_t protocol, void *id_struct, + ndpi_log_level_t log_level, + const char *format, ...) { - ndpi_tsearch(newflow, &ndpi_thread_info[thread_id].ndpi_flows_root[idx], node_cmp); /* Add */ - ndpi_thread_info[thread_id].stats.ndpi_flow_count++; + va_list va_ap; +#ifndef WIN32 + struct tm result; +#endif - *src = newflow->src_id, *dst = newflow->dst_id; + if(log_level <= nDPI_traceLevel) { + char buf[8192], out_buf[8192]; + char theDate[32]; + const char *extra_msg = ""; + time_t theTime = time(NULL); - // printFlow(thread_id, newflow); - return newflow; - } - } else { - struct ndpi_flow *flow = *(struct ndpi_flow**)ret; + va_start (va_ap, format); - if(flow->lower_ip == lower_ip && flow->upper_ip == upper_ip - && flow->lower_port == lower_port && flow->upper_port == upper_port) - *src = flow->src_id, *dst = flow->dst_id; + if(log_level == NDPI_LOG_ERROR) + extra_msg = "ERROR: "; + else if(log_level == NDPI_LOG_TRACE) + extra_msg = "TRACE: "; else - *src = flow->dst_id, *dst = flow->src_id; + extra_msg = "DEBUG: "; - return flow; - } -} + memset(buf, 0, sizeof(buf)); + strftime(theDate, 32, "%d/%b/%Y %H:%M:%S", localtime_r(&theTime,&result) ); + vsnprintf(buf, sizeof(buf)-1, format, va_ap); -/* ***************************************************** */ - -static struct ndpi_flow *get_ndpi_flow6(u_int16_t thread_id, - u_int16_t vlan_id, - const struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - struct ndpi_tcphdr **tcph, - struct ndpi_udphdr **udph, - u_int16_t *sport, u_int16_t *dport, - struct ndpi_id_struct **src, - struct ndpi_id_struct **dst, - u_int8_t *proto, - u_int8_t **payload, - u_int16_t *payload_len, - u_int8_t *src_to_dst_direction) { - struct ndpi_iphdr iph; - - memset(&iph, 0, sizeof(iph)); - iph.version = 4; - iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3]; - iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3]; - iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; - - if(iph.protocol == 0x3C /* IPv6 destination option */) { - u_int8_t *options = (u_int8_t*)iph6 + sizeof(const struct ndpi_ipv6hdr); - - iph.protocol = options[0]; + snprintf(out_buf, sizeof(out_buf), "%s %s%s", theDate, extra_msg, buf); + printf("%s", out_buf); + fflush(stdout); } - - return(get_ndpi_flow(thread_id, 6, vlan_id, &iph, iph6, ip_offset, - sizeof(struct ndpi_ipv6hdr), - ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), - tcph, udph, sport, dport, - src, dst, proto, payload, payload_len, src_to_dst_direction)); + + va_end(va_ap); } -/* ***************************************************** */ -static void setupDetection(u_int16_t thread_id) { +/** + * @brief Setup for detection begin + */ +static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) { + NDPI_PROTOCOL_BITMASK all; + struct ndpi_workflow_prefs prefs; + + memset(&prefs, 0, sizeof(prefs)); + prefs.decode_tunnels = decode_tunnels; + prefs.num_roots = NUM_ROOTS; + prefs.max_ndpi_flows = MAX_NDPI_FLOWS; + prefs.quiet_mode = quiet_mode; memset(&ndpi_thread_info[thread_id], 0, sizeof(ndpi_thread_info[thread_id])); + ndpi_thread_info[thread_id].workflow = ndpi_workflow_init(&prefs, pcap_handle); - // init global detection structure - ndpi_thread_info[thread_id].ndpi_struct = ndpi_init_detection_module(detection_tick_resolution, - malloc_wrapper, free_wrapper, debug_printf); - if(ndpi_thread_info[thread_id].ndpi_struct == NULL) { - printf("ERROR: global structure initialization failed\n"); - exit(-1); - } + /* Preferences */ + ndpi_thread_info[thread_id].workflow->ndpi_struct->http_dont_dissect_response = 0; + ndpi_thread_info[thread_id].workflow->ndpi_struct->dns_dissect_response = 0; - /* ndpi_thread_info[thread_id].ndpi_struct->http_dont_dissect_response = 1; */ + ndpi_workflow_set_flow_detected_callback(ndpi_thread_info[thread_id].workflow, + on_protocol_discovered, (void *)(uintptr_t)thread_id); // enable all protocols NDPI_BITMASK_SET_ALL(all); - ndpi_set_protocol_detection_bitmask2(ndpi_thread_info[thread_id].ndpi_struct, &all); - - // allocate memory for id and flow tracking - size_id_struct = sizeof(struct ndpi_id_struct); - size_flow_struct = sizeof(struct ndpi_flow_struct); + ndpi_set_protocol_detection_bitmask2(ndpi_thread_info[thread_id].workflow->ndpi_struct, &all); // clear memory for results - memset(ndpi_thread_info[thread_id].stats.protocol_counter, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter)); - memset(ndpi_thread_info[thread_id].stats.protocol_counter_bytes, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_counter_bytes)); - memset(ndpi_thread_info[thread_id].stats.protocol_flows, 0, sizeof(ndpi_thread_info[thread_id].stats.protocol_flows)); + memset(ndpi_thread_info[thread_id].workflow->stats.protocol_counter, 0, sizeof(ndpi_thread_info[thread_id].workflow->stats.protocol_counter)); + memset(ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes, 0, sizeof(ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes)); + memset(ndpi_thread_info[thread_id].workflow->stats.protocol_flows, 0, sizeof(ndpi_thread_info[thread_id].workflow->stats.protocol_flows)); if(_protoFilePath != NULL) - ndpi_load_protocols_file(ndpi_thread_info[thread_id].ndpi_struct, _protoFilePath); + ndpi_load_protocols_file(ndpi_thread_info[thread_id].workflow->ndpi_struct, _protoFilePath); } -/* ***************************************************** */ +/** + * @brief End of detection and free flow + */ static void terminateDetection(u_int16_t thread_id) { - int i; - - for(i=0; i<NUM_ROOTS; i++) { - ndpi_tdestroy(ndpi_thread_info[thread_id].ndpi_flows_root[i], ndpi_flow_freer); - ndpi_thread_info[thread_id].ndpi_flows_root[i] = NULL; - } - - ndpi_exit_detection_module(ndpi_thread_info[thread_id].ndpi_struct, free_wrapper); -} - -/* ***************************************************** */ - -// ipsize = header->len - ip_offset ; rawsize = header->len -static unsigned int packet_processing(u_int16_t thread_id, - const u_int64_t time, - u_int16_t vlan_id, - const struct ndpi_iphdr *iph, - struct ndpi_ipv6hdr *iph6, - u_int16_t ip_offset, - u_int16_t ipsize, u_int16_t rawsize) { - struct ndpi_id_struct *src, *dst; - struct ndpi_flow *flow; - struct ndpi_flow_struct *ndpi_flow = NULL; - u_int8_t proto; - struct ndpi_tcphdr *tcph = NULL; - struct ndpi_udphdr *udph = NULL; - u_int16_t sport, dport, payload_len; - u_int8_t *payload; - u_int8_t src_to_dst_direction= 1; - - if(iph) - flow = get_ndpi_flow(thread_id, 4, vlan_id, iph, NULL, - ip_offset, ipsize, - ntohs(iph->tot_len) - (iph->ihl * 4), - &tcph, &udph, &sport, &dport, - &src, &dst, &proto, - &payload, &payload_len, &src_to_dst_direction); - else - flow = get_ndpi_flow6(thread_id, vlan_id, iph6, ip_offset, - &tcph, &udph, &sport, &dport, - &src, &dst, &proto, - &payload, &payload_len, &src_to_dst_direction); - - if(flow != NULL) { - ndpi_thread_info[thread_id].stats.ip_packet_count++; - ndpi_thread_info[thread_id].stats.total_wire_bytes += rawsize + 24 /* CRC etc */, ndpi_thread_info[thread_id].stats.total_ip_bytes += rawsize; - ndpi_flow = flow->ndpi_flow; - flow->packets++, flow->bytes += rawsize; - flow->last_seen = time; - } else { - return(0); - } - - if(flow->detection_completed) return(0); - - flow->detected_protocol = ndpi_detection_process_packet(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow, - iph ? (uint8_t *)iph : (uint8_t *)iph6, - ipsize, time, src, dst); - if((flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN) - || ((proto == IPPROTO_UDP) && (flow->packets > 8)) - || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { - flow->detection_completed = 1; - - if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && (ndpi_flow->num_stun_udp_pkts > 0)) - ndpi_set_detected_protocol(ndpi_thread_info[thread_id].ndpi_struct, ndpi_flow, NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN); - - snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); - - if(flow->detected_protocol.protocol == NDPI_PROTOCOL_BITTORRENT) { - int i, j, n = 0; - - for(i=0, j = 0; i<20; i++) { - sprintf(&flow->bittorent_hash[j], "%02x", flow->ndpi_flow->bittorent_hash[i]); - j += 2, n += flow->ndpi_flow->bittorent_hash[i]; - } - - if(n == 0) flow->bittorent_hash[0] = '\0'; - } - - if((proto == IPPROTO_TCP) && (flow->detected_protocol.protocol != NDPI_PROTOCOL_DNS)) { - snprintf(flow->ssl.client_certificate, sizeof(flow->ssl.client_certificate), "%s", flow->ndpi_flow->protos.ssl.client_certificate); - snprintf(flow->ssl.server_certificate, sizeof(flow->ssl.server_certificate), "%s", flow->ndpi_flow->protos.ssl.server_certificate); - } - - if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) - flow->detected_protocol = ndpi_detection_giveup(ndpi_thread_info[thread_id].ndpi_struct, flow->ndpi_flow); - - free_ndpi_flow(flow); - - if(verbose > 1) { - if(enable_protocol_guess) { - if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) { - flow->detected_protocol.protocol = node_guess_undetected_protocol(thread_id, flow), - flow->detected_protocol.master_protocol = NDPI_PROTOCOL_UNKNOWN; - } - } - - printFlow(thread_id, flow); - } - } - - if(live_capture) { - if(ndpi_thread_info[thread_id].last_idle_scan_time + IDLE_SCAN_PERIOD < ndpi_thread_info[thread_id].last_time) { - /* scan for idle flows */ - ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_idle_scan_walker, &thread_id); - - /* remove idle flows (unfortunately we cannot do this inline) */ - while (ndpi_thread_info[thread_id].num_idle_flows > 0) { - - /* search and delete the idle flow from the "ndpi_flow_root" (see struct reader thread) - here flows are the node of a b-tree */ - ndpi_tdelete(ndpi_thread_info[thread_id].idle_flows[--ndpi_thread_info[thread_id].num_idle_flows], &ndpi_thread_info[thread_id].ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_cmp); - - /* free the memory associated to idle flow in "idle_flows" - (see struct reader thread)*/ - free_ndpi_flow(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]); - ndpi_free(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]); - } - - if(++ndpi_thread_info[thread_id].idle_scan_idx == NUM_ROOTS) ndpi_thread_info[thread_id].idle_scan_idx = 0; - ndpi_thread_info[thread_id].last_idle_scan_time = ndpi_thread_info[thread_id].last_time; - } - } - - return 0; + ndpi_workflow_free(ndpi_thread_info[thread_id].workflow); } -/* ****************************************************** */ +/** + * @brief Traffic stats format + */ char* formatTraffic(float numBits, int bits, char *buf) { + char unit; if(bits) @@ -1161,9 +696,12 @@ char* formatTraffic(float numBits, int bits, char *buf) { return(buf); } -/* ***************************************************** */ +/** + * @brief Packets stats format + */ char* formatPackets(float numPkts, char *buf) { + if(numPkts < 1000) { snprintf(buf, 32, "%.2f", numPkts); } else if(numPkts < 1000000) { @@ -1176,8 +714,10 @@ char* formatPackets(float numPkts, char *buf) { return(buf); } -/* ***************************************************** */ +/** + * @brief JSON function init + */ #ifdef HAVE_JSON_C static void json_init() { jArray_known_flows = json_object_new_array(); @@ -1185,9 +725,12 @@ static void json_init() { } #endif -/* ***************************************************** */ +/** + * @brief Bytes stats format + */ char* formatBytes(u_int32_t howMuch, char *buf, u_int buf_len) { + char unit = 'B'; if(howMuch < 1024) { @@ -1209,13 +752,16 @@ char* formatBytes(u_int32_t howMuch, char *buf, u_int buf_len) { return(buf); } -/* ***************************************************** */ +/** + * @brief Print result + */ static void printResults(u_int64_t tot_usec) { + u_int32_t i; u_int64_t total_flow_bytes = 0; u_int avg_pkt_size = 0; - struct thread_stats cumulative_stats; + struct ndpi_stats cumulative_stats; int thread_id; char buf[32]; #ifdef HAVE_JSON_C @@ -1227,41 +773,43 @@ static void printResults(u_int64_t tot_usec) { memset(&cumulative_stats, 0, sizeof(cumulative_stats)); for(thread_id = 0; thread_id < num_threads; thread_id++) { - if(ndpi_thread_info[thread_id].stats.total_wire_bytes == 0) continue; + if((ndpi_thread_info[thread_id].workflow->stats.total_wire_bytes == 0) + && (ndpi_thread_info[thread_id].workflow->stats.raw_packet_count == 0)) + continue; for(i=0; i<NUM_ROOTS; i++) - ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_proto_guess_walker, &thread_id); + ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], node_proto_guess_walker, &thread_id); /* Stats aggregation */ - cumulative_stats.guessed_flow_protocols += ndpi_thread_info[thread_id].stats.guessed_flow_protocols; - cumulative_stats.raw_packet_count += ndpi_thread_info[thread_id].stats.raw_packet_count; - cumulative_stats.ip_packet_count += ndpi_thread_info[thread_id].stats.ip_packet_count; - cumulative_stats.total_wire_bytes += ndpi_thread_info[thread_id].stats.total_wire_bytes; - cumulative_stats.total_ip_bytes += ndpi_thread_info[thread_id].stats.total_ip_bytes; - cumulative_stats.total_discarded_bytes += ndpi_thread_info[thread_id].stats.total_discarded_bytes; - - for(i = 0; i < ndpi_get_num_supported_protocols(ndpi_thread_info[0].ndpi_struct); i++) { - cumulative_stats.protocol_counter[i] += ndpi_thread_info[thread_id].stats.protocol_counter[i]; - cumulative_stats.protocol_counter_bytes[i] += ndpi_thread_info[thread_id].stats.protocol_counter_bytes[i]; - cumulative_stats.protocol_flows[i] += ndpi_thread_info[thread_id].stats.protocol_flows[i]; + cumulative_stats.guessed_flow_protocols += ndpi_thread_info[thread_id].workflow->stats.guessed_flow_protocols; + cumulative_stats.raw_packet_count += ndpi_thread_info[thread_id].workflow->stats.raw_packet_count; + cumulative_stats.ip_packet_count += ndpi_thread_info[thread_id].workflow->stats.ip_packet_count; + cumulative_stats.total_wire_bytes += ndpi_thread_info[thread_id].workflow->stats.total_wire_bytes; + cumulative_stats.total_ip_bytes += ndpi_thread_info[thread_id].workflow->stats.total_ip_bytes; + cumulative_stats.total_discarded_bytes += ndpi_thread_info[thread_id].workflow->stats.total_discarded_bytes; + + for(i = 0; i < ndpi_get_num_supported_protocols(ndpi_thread_info[0].workflow->ndpi_struct); i++) { + cumulative_stats.protocol_counter[i] += ndpi_thread_info[thread_id].workflow->stats.protocol_counter[i]; + cumulative_stats.protocol_counter_bytes[i] += ndpi_thread_info[thread_id].workflow->stats.protocol_counter_bytes[i]; + cumulative_stats.protocol_flows[i] += ndpi_thread_info[thread_id].workflow->stats.protocol_flows[i]; } - cumulative_stats.ndpi_flow_count += ndpi_thread_info[thread_id].stats.ndpi_flow_count; - cumulative_stats.tcp_count += ndpi_thread_info[thread_id].stats.tcp_count; - cumulative_stats.udp_count += ndpi_thread_info[thread_id].stats.udp_count; - cumulative_stats.mpls_count += ndpi_thread_info[thread_id].stats.mpls_count; - cumulative_stats.pppoe_count += ndpi_thread_info[thread_id].stats.pppoe_count; - cumulative_stats.vlan_count += ndpi_thread_info[thread_id].stats.vlan_count; - cumulative_stats.fragmented_count += ndpi_thread_info[thread_id].stats.fragmented_count; + cumulative_stats.ndpi_flow_count += ndpi_thread_info[thread_id].workflow->stats.ndpi_flow_count; + cumulative_stats.tcp_count += ndpi_thread_info[thread_id].workflow->stats.tcp_count; + cumulative_stats.udp_count += ndpi_thread_info[thread_id].workflow->stats.udp_count; + cumulative_stats.mpls_count += ndpi_thread_info[thread_id].workflow->stats.mpls_count; + cumulative_stats.pppoe_count += ndpi_thread_info[thread_id].workflow->stats.pppoe_count; + cumulative_stats.vlan_count += ndpi_thread_info[thread_id].workflow->stats.vlan_count; + cumulative_stats.fragmented_count += ndpi_thread_info[thread_id].workflow->stats.fragmented_count; for(i = 0; i < 6; i++) - cumulative_stats.packet_len[i] += ndpi_thread_info[thread_id].stats.packet_len[i]; - cumulative_stats.max_packet_len += ndpi_thread_info[thread_id].stats.max_packet_len; + cumulative_stats.packet_len[i] += ndpi_thread_info[thread_id].workflow->stats.packet_len[i]; + cumulative_stats.max_packet_len += ndpi_thread_info[thread_id].workflow->stats.max_packet_len; } if(!quiet_mode) { printf("\nnDPI Memory statistics:\n"); printf("\tnDPI Memory (once): %-13s\n", formatBytes(sizeof(struct ndpi_detection_module_struct), buf, sizeof(buf))); - printf("\tFlow Memory (per flow): %-13s\n", formatBytes(size_flow_struct, buf, sizeof(buf))); + printf("\tFlow Memory (per flow): %-13s\n", formatBytes(sizeof(struct ndpi_flow_struct), buf, sizeof(buf))); printf("\tActual Memory: %-13s\n", formatBytes(current_ndpi_memory, buf, sizeof(buf))); printf("\tPeak Memory: %-13s\n", formatBytes(max_ndpi_memory, buf, sizeof(buf))); @@ -1350,17 +898,17 @@ static void printResults(u_int64_t tot_usec) { } #endif } - + if((!json_flag) && (!quiet_mode)) printf("\n\nDetected protocols:\n"); - for(i = 0; i <= ndpi_get_num_supported_protocols(ndpi_thread_info[0].ndpi_struct); i++) { - ndpi_protocol_breed_t breed = ndpi_get_proto_breed(ndpi_thread_info[0].ndpi_struct, i); + for(i = 0; i <= ndpi_get_num_supported_protocols(ndpi_thread_info[0].workflow->ndpi_struct); i++) { + ndpi_protocol_breed_t breed = ndpi_get_proto_breed(ndpi_thread_info[0].workflow->ndpi_struct, i); if(cumulative_stats.protocol_counter[i] > 0) { breed_stats[breed] += (long long unsigned int)cumulative_stats.protocol_counter_bytes[i]; if(results_file) fprintf(results_file, "%s\t%llu\t%llu\t%u\n", - ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i), + ndpi_get_proto_name(ndpi_thread_info[0].workflow->ndpi_struct, i), (long long unsigned int)cumulative_stats.protocol_counter[i], (long long unsigned int)cumulative_stats.protocol_counter_bytes[i], cumulative_stats.protocol_flows[i]); @@ -1368,7 +916,7 @@ static void printResults(u_int64_t tot_usec) { if((!json_flag) && (!quiet_mode)) { printf("\t%-20s packets: %-13llu bytes: %-13llu " "flows: %-13u\n", - ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i), + ndpi_get_proto_name(ndpi_thread_info[0].workflow->ndpi_struct, i), (long long unsigned int)cumulative_stats.protocol_counter[i], (long long unsigned int)cumulative_stats.protocol_counter_bytes[i], cumulative_stats.protocol_flows[i]); @@ -1377,8 +925,8 @@ static void printResults(u_int64_t tot_usec) { if(json_fp) { jObj = json_object_new_object(); - json_object_object_add(jObj,"name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[0].ndpi_struct, i))); - json_object_object_add(jObj,"breed",json_object_new_string(ndpi_get_proto_breed_name(ndpi_thread_info[0].ndpi_struct, breed))); + json_object_object_add(jObj,"name",json_object_new_string(ndpi_get_proto_name(ndpi_thread_info[0].workflow->ndpi_struct, i))); + json_object_object_add(jObj,"breed",json_object_new_string(ndpi_get_proto_breed_name(ndpi_thread_info[0].workflow->ndpi_struct, breed))); json_object_object_add(jObj,"packets",json_object_new_int64(cumulative_stats.protocol_counter[i])); json_object_object_add(jObj,"bytes",json_object_new_int64(cumulative_stats.protocol_counter_bytes[i])); json_object_object_add(jObj,"flows",json_object_new_int(cumulative_stats.protocol_flows[i])); @@ -1398,7 +946,7 @@ static void printResults(u_int64_t tot_usec) { for(i=0; i < NUM_BREEDS; i++) { if(breed_stats[i] > 0) { printf("\t%-20s %13llu bytes\n", - ndpi_get_proto_breed_name(ndpi_thread_info[0].ndpi_struct, i), + ndpi_get_proto_breed_name(ndpi_thread_info[0].workflow->ndpi_struct, i), breed_stats[i]); } } @@ -1414,11 +962,11 @@ static void printResults(u_int64_t tot_usec) { num_flows = 0; for(thread_id = 0; thread_id < num_threads; thread_id++) { for(i=0; i<NUM_ROOTS; i++) - ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_print_known_proto_walker, &thread_id); + ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], node_print_known_proto_walker, &thread_id); } for(thread_id = 0; thread_id < num_threads; thread_id++) { - if(ndpi_thread_info[thread_id].stats.protocol_counter[0 /* 0 = Unknown */] > 0) { + if(ndpi_thread_info[thread_id].workflow->stats.protocol_counter[0 /* 0 = Unknown */] > 0) { if(!json_flag) { FILE *out = results_file ? results_file : stdout; @@ -1433,9 +981,9 @@ static void printResults(u_int64_t tot_usec) { num_flows = 0; for(thread_id = 0; thread_id < num_threads; thread_id++) { - if(ndpi_thread_info[thread_id].stats.protocol_counter[0] > 0) { + if(ndpi_thread_info[thread_id].workflow->stats.protocol_counter[0] > 0) { for(i=0; i<NUM_ROOTS; i++) - ndpi_twalk(ndpi_thread_info[thread_id].ndpi_flows_root[i], node_print_unknown_proto_walker, &thread_id); + ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], node_print_unknown_proto_walker, &thread_id); } } } @@ -1454,27 +1002,24 @@ static void printResults(u_int64_t tot_usec) { } } -/* ***************************************************** */ - -static void closePcapFile(u_int16_t thread_id) { - if(ndpi_thread_info[thread_id]._pcap_handle != NULL) { - pcap_close(ndpi_thread_info[thread_id]._pcap_handle); - - } -} - -/* ***************************************************** */ +/** + * @brief Force a pcap_dispatch() or pcap_loop() call to return + */ static void breakPcapLoop(u_int16_t thread_id) { - if(ndpi_thread_info[thread_id]._pcap_handle != NULL) { - pcap_breakloop(ndpi_thread_info[thread_id]._pcap_handle); + + if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL) { + pcap_breakloop(ndpi_thread_info[thread_id].workflow->pcap_handle); } } -/* ***************************************************** */ -// executed for each packet in the pcap file + +/** + * @brief Sigproc is executed for each packet in the pcap file + */ void sigproc(int sig) { + static int called = 0; int thread_id; @@ -1485,8 +1030,10 @@ void sigproc(int sig) { breakPcapLoop(thread_id); } -/* ***************************************************** */ +/** + * @brief Get the next pcap file from a passed playlist + */ static int getNextPcapFileFromPlaylist(u_int16_t thread_id, char filename[], u_int32_t filename_len) { if(playlist_fp[thread_id] == NULL) { @@ -1507,62 +1054,67 @@ static int getNextPcapFileFromPlaylist(u_int16_t thread_id, char filename[], u_i } } -/* ***************************************************** */ -static void configurePcapHandle(u_int16_t thread_id) { - ndpi_thread_info[thread_id]._pcap_datalink_type = pcap_datalink(ndpi_thread_info[thread_id]._pcap_handle); +/** + * @brief Configure the pcap handle + */ +static void configurePcapHandle(pcap_t * pcap_handle) { if(_bpf_filter != NULL) { struct bpf_program fcode; - if(pcap_compile(ndpi_thread_info[thread_id]._pcap_handle, &fcode, _bpf_filter, 1, 0xFFFFFF00) < 0) { - printf("pcap_compile error: '%s'\n", pcap_geterr(ndpi_thread_info[thread_id]._pcap_handle)); + if(pcap_compile(pcap_handle, &fcode, _bpf_filter, 1, 0xFFFFFF00) < 0) { + printf("pcap_compile error: '%s'\n", pcap_geterr(pcap_handle)); } else { - if(pcap_setfilter(ndpi_thread_info[thread_id]._pcap_handle, &fcode) < 0) { - printf("pcap_setfilter error: '%s'\n", pcap_geterr(ndpi_thread_info[thread_id]._pcap_handle)); + if(pcap_setfilter(pcap_handle, &fcode) < 0) { + printf("pcap_setfilter error: '%s'\n", pcap_geterr(pcap_handle)); } else printf("Successfully set BPF filter to '%s'\n", _bpf_filter); } } } -/* ***************************************************** */ -static void openPcapFileOrDevice(u_int16_t thread_id) { +/** + * @brief Open a pcap file or a specified device - Always returns a valid pcap_t + */ +static pcap_t * openPcapFileOrDevice(u_int16_t thread_id, const u_char * pcap_file) { + u_int snaplen = 1536; int promisc = 1; - char errbuf[PCAP_ERRBUF_SIZE]; + char pcap_error_buffer[PCAP_ERRBUF_SIZE]; + pcap_t * pcap_handle = NULL; /* trying to open a live interface */ - if((ndpi_thread_info[thread_id]._pcap_handle = pcap_open_live(_pcap_file[thread_id], snaplen, promisc, 500, errbuf)) == NULL) { + if((pcap_handle = pcap_open_live((char*)pcap_file, snaplen, promisc, 500, pcap_error_buffer)) == NULL) { capture_for = capture_until = 0; live_capture = 0; num_threads = 1; /* Open pcap files in single threads mode */ /* trying to open a pcap file */ - if((ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(_pcap_file[thread_id], ndpi_thread_info[thread_id]._pcap_error_buffer)) == NULL) { + if((pcap_handle = pcap_open_offline((char*)pcap_file, pcap_error_buffer)) == NULL) { char filename[256]; /* trying to open a pcap playlist */ if(getNextPcapFileFromPlaylist(thread_id, filename, sizeof(filename)) != 0 || - (ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(filename, ndpi_thread_info[thread_id]._pcap_error_buffer)) == NULL) { + (pcap_handle = pcap_open_offline(filename, pcap_error_buffer)) == NULL) { - printf("ERROR: could not open pcap file or playlist: %s\n", ndpi_thread_info[thread_id]._pcap_error_buffer); + printf("ERROR: could not open pcap file or playlist: %s\n", pcap_error_buffer); exit(-1); } else { - if((!json_flag) && (!quiet_mode)) printf("Reading packets from playlist %s...\n", _pcap_file[thread_id]); + if((!json_flag) && (!quiet_mode)) printf("Reading packets from playlist %s...\n", pcap_file); } } else { - if((!json_flag) && (!quiet_mode)) printf("Reading packets from pcap file %s...\n", _pcap_file[thread_id]); + if((!json_flag) && (!quiet_mode)) printf("Reading packets from pcap file %s...\n", pcap_file); } } else { live_capture = 1; - if((!json_flag) && (!quiet_mode)) printf("Capturing live traffic from device %s...\n", _pcap_file[thread_id]); + if((!json_flag) && (!quiet_mode)) printf("Capturing live traffic from device %s...\n", pcap_file); } - configurePcapHandle(thread_id); + configurePcapHandle(pcap_handle); if(capture_for > 0) { if((!json_flag) && (!quiet_mode)) printf("Capturing traffic up to %u seconds\n", (unsigned int)capture_for); @@ -1572,385 +1124,86 @@ static void openPcapFileOrDevice(u_int16_t thread_id) { signal(SIGALRM, sigproc); #endif } + + return pcap_handle; } -/* ***************************************************** */ -static void pcap_packet_callback(u_char *args, +/** + * @brief Check pcap packet + */ +static void pcap_packet_callback_checked(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { - /* - * Declare pointers to packet headers - */ - - /* --- Ethernet header --- */ - const struct ndpi_ethhdr *ethernet; - /* --- Ethernet II header --- */ - const struct ndpi_ethhdr *ethernet_2; - /* --- LLC header --- */ - const struct ndpi_llc_header *llc; - - /* --- Cisco HDLC header --- */ - const struct ndpi_chdlc *chdlc; - /* --- SLARP frame --- */ - struct ndpi_slarp *slarp; - /* --- CDP --- */ - struct ndpi_cdp *cdp; - - /* --- Radio Tap header --- */ - const struct ndpi_radiotap_header *radiotap; - /* --- Wifi header --- */ - const struct ndpi_wifi_header *wifi; - - /* --- MPLS header --- */ - struct ndpi_mpls_header *mpls; - - /** --- IP header --- **/ - struct ndpi_iphdr *iph; - /** --- IPv6 header --- **/ - struct ndpi_ipv6hdr *iph6; - - /* lengths and offsets */ - u_int16_t eth_offset = 0; - u_int16_t radio_len; - u_int16_t fc; - u_int16_t type; - int wifi_len; - int llc_off; - int pyld_eth_len = 0; - int check; - char packet_copy[1600]; - u_int32_t fcs, packet_copy_len = sizeof(packet_copy);; - u_int64_t time; - u_int16_t ip_offset, ip_len, ip6_offset; - u_int16_t frag_off = 0, vlan_id = 0; - u_int8_t proto = 0; - u_int32_t label; - u_int16_t thread_id = *((u_int16_t*)args); - /* counters */ - u_int8_t malformed_pkts = 0, vlan_packet = 0; - u_int8_t slarp_pkts = 0, cdp_pkts = 0; - - /* Increment raw packet counter */ - ndpi_thread_info[thread_id].stats.raw_packet_count++; + /* allocate an exact size buffer to check overflows */ + uint8_t *packet_checked = malloc(header->caplen); + memcpy(packet_checked, packet, header->caplen); + ndpi_workflow_process_packet(ndpi_thread_info[thread_id].workflow, header, packet_checked); if((capture_until != 0) && (header->ts.tv_sec >= capture_until)) { - if(ndpi_thread_info[thread_id]._pcap_handle != NULL) - pcap_breakloop(ndpi_thread_info[thread_id]._pcap_handle); + if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL) + pcap_breakloop(ndpi_thread_info[thread_id].workflow->pcap_handle); return; } - if(header->caplen < packet_copy_len) packet_copy_len = header->caplen; - memcpy(packet_copy, packet, packet_copy_len); - /* Check if capture is live or not */ if (!live_capture) { if (!pcap_start.tv_sec) pcap_start.tv_sec = header->ts.tv_sec, pcap_start.tv_usec = header->ts.tv_usec; pcap_end.tv_sec = header->ts.tv_sec, pcap_end.tv_usec = header->ts.tv_usec; } - /* setting time */ - time = ((uint64_t) header->ts.tv_sec) * detection_tick_resolution + - header->ts.tv_usec / (1000000 / detection_tick_resolution); - - /* safety check */ - if(ndpi_thread_info[thread_id].last_time > time) { - /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); */ - time = ndpi_thread_info[thread_id].last_time; - } - /* update last time value */ - ndpi_thread_info[thread_id].last_time = time; - - /*** check Data Link type ***/ - int datalink_type = ndpi_thread_info[thread_id]._pcap_datalink_type; - - datalink_check: - switch(datalink_type) { - case DLT_NULL : - if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2) - type = ETH_P_IP; - else - type = ETH_P_IPV6; - - ip_offset = 4 + eth_offset; - - /* Cisco PPP in HDLC-like framing - 50 */ - case DLT_PPP_SERIAL: - chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ - type = ntohs(chdlc->proto_code); - break; - - /* Cisco PPP with HDLC framing - 104 */ - case DLT_C_HDLC: - chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ - type = ntohs(chdlc->proto_code); - break; - - /* IEEE 802.3 Ethernet - 1 */ - case DLT_EN10MB : - ethernet = (struct ndpi_ethhdr *) &packet[eth_offset]; - ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset; - check = ntohs(ethernet->h_proto); - - if(check <= 1500) - pyld_eth_len = check; - else if (check >= 1536) - type = check; - - if(pyld_eth_len != 0) { - /* check for LLC layer with SNAP extension */ - if(packet[ip_offset] == SNAP) { - llc = (struct ndpi_llc_header *)(&packet[ip_offset]); - type = llc->snap.proto_ID; - ip_offset += + 8; - } - } - break; - - /* Linux Cooked Capture - 113 */ - case DLT_LINUX_SLL : - type = (packet[eth_offset+14] << 8) + packet[eth_offset+15]; - ip_offset = 16 + eth_offset; - break; - - /* Radiotap link-layer - 127 */ - case DLT_IEEE802_11_RADIO : - radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset]; - radio_len = radiotap->len; - - /* Check Bad FCS presence */ - if((radiotap->flags & BAD_FCS) == BAD_FCS) { - malformed_pkts += 1; - ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len; - return; - } - - fcs = header->len - 4; - - /* Calculate 802.11 header length (variable) */ - wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len); - fc = wifi->fc; - - /* check wifi data presence */ - if(FCF_TYPE(fc) == WIFI_DATA) { - if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) || - (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc))) - wifi_len = 26; /* + 4 byte fcs */ - } else /* no data frames */ - break; - - /* Check ether_type from LLC */ - llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len); - if(llc->dsap == SNAP) - type = ntohs(llc->snap.proto_ID); - - /* Set IP header offset */ - ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header) + eth_offset; - break; - - case DLT_RAW: - ip_offset = eth_offset = 0; - break; - - default: - /* printf("Unknown datalink %d\n", datalink_type); */ - return; - } - - /* check ether type */ - if(type == VLAN) { - vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF; - type = (packet[ip_offset+2] << 8) + packet[ip_offset+3]; - ip_offset += 4; - vlan_packet = 1; - } else if(type == MPLS_UNI || type == MPLS_MULTI) { - mpls = (struct ndpi_mpls_header *) &packet[ip_offset]; - label = ntohl(mpls->label); - /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */ - ndpi_thread_info[thread_id].stats.mpls_count++; - type = ETH_P_IP, ip_offset += 4; - - while((label & 0x100) != 0x100) { - ip_offset += 4; - label = ntohl(mpls->label); - } - } - else if(type == SLARP) { - slarp = (struct ndpi_slarp *) &packet[ip_offset]; - if(slarp->slarp_type == 0x02 || slarp->slarp_type == 0x00 || slarp->slarp_type == 0x01) { - /* TODO if info are needed */ - } - slarp_pkts++; - } - else if(type == CISCO_D_PROTO) { - cdp = (struct ndpi_cdp *) &packet[ip_offset]; - cdp_pkts++; - } - else if(type == PPPoE) { - ndpi_thread_info[thread_id].stats.pppoe_count++; - type = ETH_P_IP; - ip_offset += 8; - } - - ndpi_thread_info[thread_id].stats.vlan_count += vlan_packet; - - iph_check: - /* Check and set IP header size and total packet length */ - iph = (struct ndpi_iphdr *) &packet[ip_offset]; - - /* just work on Ethernet packets that contain IP */ - if(type == ETH_P_IP && header->caplen >= ip_offset) { - frag_off = ntohs(iph->frag_off); - - proto = iph->protocol; - if(header->caplen < header->len) { - static u_int8_t cap_warning_used = 0; - - if(cap_warning_used == 0) { - if((!json_flag) && (!quiet_mode)) printf("\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n"); - cap_warning_used = 1; - } - } - } - - if(iph->version == 4) { - ip_len = ((u_short)iph->ihl * 4); - iph6 = NULL; + /* Idle flows cleanup */ + if(live_capture) { + if(ndpi_thread_info[thread_id].last_idle_scan_time + IDLE_SCAN_PERIOD < ndpi_thread_info[thread_id].workflow->last_time) { + /* scan for idle flows */ + ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], node_idle_scan_walker, &thread_id); - if(iph->protocol == 41) { - ip_offset += ip_len; - goto iph_check; - } + /* remove idle flows (unfortunately we cannot do this inline) */ + while (ndpi_thread_info[thread_id].num_idle_flows > 0) { - if((frag_off & 0x3FFF) != 0) { - static u_int8_t ipv4_frags_warning_used = 0; - ndpi_thread_info[thread_id].stats.fragmented_count++; + /* search and delete the idle flow from the "ndpi_flow_root" (see struct reader thread) - here flows are the node of a b-tree */ + ndpi_tdelete(ndpi_thread_info[thread_id].idle_flows[--ndpi_thread_info[thread_id].num_idle_flows], + &ndpi_thread_info[thread_id].workflow->ndpi_flows_root[ndpi_thread_info[thread_id].idle_scan_idx], + ndpi_workflow_node_cmp); - if(ipv4_frags_warning_used == 0) { - if((!json_flag) && (!quiet_mode)) printf("\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n"); - ipv4_frags_warning_used = 1; + /* free the memory associated to idle flow in "idle_flows" - (see struct reader thread)*/ + ndpi_free_flow_info_half(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]); + ndpi_free(ndpi_thread_info[thread_id].idle_flows[ndpi_thread_info[thread_id].num_idle_flows]); } - ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len; - return; - } - } else if(iph->version == 6) { - iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset]; - proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; - ip_len = sizeof(struct ndpi_ipv6hdr); - - if(proto == 0x3C /* IPv6 destination option */) { - - u_int8_t *options = (u_int8_t*)&packet[ip_offset+ip_len]; - proto = options[0]; - ip_len += 8 * (options[1] + 1); - } - iph = NULL; - - } else { - static u_int8_t ipv4_warning_used = 0; - - v4_warning: - if(ipv4_warning_used == 0) { - if((!json_flag) && (!quiet_mode)) - printf("\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI supports both IPv4 and IPv6), all other packets will be discarded\n\n"); - ipv4_warning_used = 1; - } - ndpi_thread_info[thread_id].stats.total_discarded_bytes += header->len; - return; - } - - if(decode_tunnels && (proto == IPPROTO_UDP)) { - struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len]; - u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest); - - if((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) { - /* Check if it's GTPv1 */ - u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); - u_int8_t flags = packet[offset]; - u_int8_t message_type = packet[offset+1]; - - if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) && - (message_type == 0xFF /* T-PDU */)) { - - ip_offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr)+8; /* GTPv1 header len */ - if(flags & 0x04) ip_offset += 1; /* next_ext_header is present */ - if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */ - if(flags & 0x01) ip_offset += 1; /* pdu_number is present */ - - iph = (struct ndpi_iphdr *) &packet[ip_offset]; - - if(iph->version != 4) { - // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)ndpi_thread_info[thread_id].stats.raw_packet_count); - goto v4_warning; - } - } - } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) { - /* https://en.wikipedia.org/wiki/TZSP */ - u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); - u_int8_t version = packet[offset]; - u_int8_t type = packet[offset+1]; - u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2])); - - if((version == 1) && (type == 0) && (encapsulates == 1)) { - u_int8_t stop = 0; - - offset += 4; - - while((!stop) && (offset < header->caplen)) { - u_int8_t tag_type = packet[offset]; - u_int8_t tag_len; - - switch(tag_type) { - case 0: /* PADDING Tag */ - tag_len = 1; - break; - case 1: /* END Tag */ - tag_len = 1, stop = 1; - break; - default: - tag_len = packet[offset+1]; - break; - } - - offset += tag_len; - - if(offset >= header->caplen) - return; /* Invalid packet */ - else { - eth_offset = offset; - goto datalink_check; - } - } - } + if(++ndpi_thread_info[thread_id].idle_scan_idx == ndpi_thread_info[thread_id].workflow->prefs.num_roots) ndpi_thread_info[thread_id].idle_scan_idx = 0; + ndpi_thread_info[thread_id].last_idle_scan_time = ndpi_thread_info[thread_id].workflow->last_time; } } - /* process the packet */ - packet_processing(thread_id, time, vlan_id, iph, iph6, - ip_offset, header->len - ip_offset, header->len); - - if(memcmp(packet_copy, packet, packet_copy_len) != 0) + /* check for buffer changes */ + if(memcmp(packet, packet_checked, header->caplen) != 0) printf("INTERNAL ERROR: ingress packet was nodified by nDPI: this should not happen [thread_id=%u, packetId=%lu]\n", - thread_id, (unsigned long)ndpi_thread_info[thread_id].stats.raw_packet_count); + thread_id, (unsigned long)ndpi_thread_info[thread_id].workflow->stats.raw_packet_count); + free(packet_checked); } -/* ******************************************************************** */ +/** + * @brief Call pcap_loop() to process packets from a live capture or savefile + */ static void runPcapLoop(u_int16_t thread_id) { - if((!shutdown_app) && (ndpi_thread_info[thread_id]._pcap_handle != NULL)) - pcap_loop(ndpi_thread_info[thread_id]._pcap_handle, -1, &pcap_packet_callback, (u_char*)&thread_id); + + if((!shutdown_app) && (ndpi_thread_info[thread_id].workflow->pcap_handle != NULL)) + pcap_loop(ndpi_thread_info[thread_id].workflow->pcap_handle, -1, &pcap_packet_callback_checked, (u_char*)&thread_id); } -/* ******************************************************************** */ -void *processing_thread(void *_thread_id) { +/** + * @brief Process a running thread + */ +void * processing_thread(void *_thread_id) { + long thread_id = (long) _thread_id; + char pcap_error_buffer[PCAP_ERRBUF_SIZE]; #if defined(linux) && defined(HAVE_PTHREAD_SETAFFINITY_NP) if(core_affinity[thread_id] >= 0) { @@ -1974,18 +1227,21 @@ void *processing_thread(void *_thread_id) { char filename[256]; if(getNextPcapFileFromPlaylist(thread_id, filename, sizeof(filename)) == 0 && - (ndpi_thread_info[thread_id]._pcap_handle = pcap_open_offline(filename, ndpi_thread_info[thread_id]._pcap_error_buffer)) != NULL) { - configurePcapHandle(thread_id); + (ndpi_thread_info[thread_id].workflow->pcap_handle = pcap_open_offline(filename, pcap_error_buffer)) != NULL) { + configurePcapHandle(ndpi_thread_info[thread_id].workflow->pcap_handle); goto pcap_loop; } } - + return NULL; } -/* ******************************************************************** */ +/** + * @brief Begin, process, end detection process + */ void test_lib() { + struct timeval begin, end; u_int64_t tot_usec; long thread_id; @@ -1995,8 +1251,8 @@ void test_lib() { #endif for(thread_id = 0; thread_id < num_threads; thread_id++) { - setupDetection(thread_id); - openPcapFileOrDevice(thread_id); + pcap_t * cap = openPcapFileOrDevice(thread_id, (const u_char*)_pcap_file[thread_id]); + setupDetection(thread_id, cap); } gettimeofday(&begin, NULL); @@ -2016,16 +1272,34 @@ void test_lib() { printResults(tot_usec); for(thread_id = 0; thread_id < num_threads; thread_id++) { - closePcapFile(thread_id); + if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL) { + pcap_close(ndpi_thread_info[thread_id].workflow->pcap_handle); + } terminateDetection(thread_id); } } -/* ***************************************************** */ +void automataUnitTest() { + void *automa; + + assert(automa = ndpi_init_automa()); + assert(ndpi_add_string_to_automa(automa, "hello") == 0); + assert(ndpi_add_string_to_automa(automa, "world") == 0); + ndpi_finalize_automa(automa); + assert(ndpi_match_string(automa, "This is the wonderful world of nDPI") == 0); + + ndpi_free_automa(automa); +} +/** + @brief MAIN FUNCTION + **/ int main(int argc, char **argv) { + int i; + automataUnitTest(); + memset(ndpi_thread_info, 0, sizeof(ndpi_thread_info)); memset(&pcap_start, 0, sizeof(pcap_start)); memset(&pcap_end, 0, sizeof(pcap_end)); @@ -2054,7 +1328,6 @@ int main(int argc, char **argv) { return 0; } -/* ****************************************************** */ #ifdef WIN32 #ifndef __GNUC__ @@ -2063,13 +1336,19 @@ int main(int argc, char **argv) { #define EPOCHFILETIME (116444736000000000LL) #endif + +/** + @brief Timezone + **/ struct timezone { int tz_minuteswest; /* minutes W of Greenwich */ int tz_dsttime; /* type of dst correction */ }; -/* ***************************************************** */ +/** + @brief Set time + **/ int gettimeofday(struct timeval *tv, struct timezone *tz) { FILETIME ft; LARGE_INTEGER li; diff --git a/example/ndpi_util.c b/example/ndpi_util.c new file mode 100644 index 000000000..405cac366 --- /dev/null +++ b/example/ndpi_util.c @@ -0,0 +1,867 @@ +/* + * ndpi_util.c + * + * Copyright (C) 2011-16 - ntop.org + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> + +#ifdef WIN32 +#include <winsock2.h> /* winsock.h is included automatically */ +#include <process.h> +#include <io.h> +#else +#include <unistd.h> +#include <netinet/in.h> +#endif + +#ifndef ETH_P_IP +#define ETH_P_IP 0x0800 /* IPv4 */ +#endif + +#ifndef ETH_P_IPv6 +#define ETH_P_IPV6 0x86dd /* IPv6 */ +#endif + +#define SLARP 0x8035 /* Cisco Slarp */ +#define CISCO_D_PROTO 0x2000 /* Cisco Discovery Protocol */ + +#define VLAN 0x8100 +#define MPLS_UNI 0x8847 +#define MPLS_MULTI 0x8848 +#define PPPoE 0x8864 +#define SNAP 0xaa + +/* mask for FCF */ +#define WIFI_DATA 0x2 /* 0000 0010 */ +#define FCF_TYPE(fc) (((fc) >> 2) & 0x3) /* 0000 0011 = 0x3 */ +#define FCF_SUBTYPE(fc) (((fc) >> 4) & 0xF) /* 0000 1111 = 0xF */ +#define FCF_TO_DS(fc) ((fc) & 0x0100) +#define FCF_FROM_DS(fc) ((fc) & 0x0200) + +/* mask for Bad FCF presence */ +#define BAD_FCS 0x50 /* 0101 0000 */ + +#define GTP_U_V1_PORT 2152 +#define TZSP_PORT 37008 + +#define SIZEOF_ID_STRUCT (sizeof(struct ndpi_id_struct)) +#define SIZEOF_FLOW_STRUCT (sizeof(struct ndpi_flow_struct)) + +#include "ndpi_main.h" +#include "ndpi_util.h" + +/* ***************************************************** */ + +void ndpi_free_flow_info_half(struct ndpi_flow_info *flow) { + if(flow->ndpi_flow) { ndpi_free_flow(flow->ndpi_flow); flow->ndpi_flow = NULL; } + if(flow->src_id) { ndpi_free(flow->src_id); flow->src_id = NULL; } + if(flow->dst_id) { ndpi_free(flow->dst_id); flow->dst_id = NULL; } + +} + +/* ***************************************************** */ + +static const u_int8_t nDPI_traceLevel = 0; + +/* ***************************************************** */ + +extern u_int32_t current_ndpi_memory, max_ndpi_memory; + +/** + * @brief malloc wrapper function + */ +static void *malloc_wrapper(size_t size) { + current_ndpi_memory += size; + + if(current_ndpi_memory > max_ndpi_memory) + max_ndpi_memory = current_ndpi_memory; + + return malloc(size); +} + +/* ***************************************************** */ + +/** + * @brief free wrapper function + */ +static void free_wrapper(void *freeable) { + free(freeable); +} + +/* ***************************************************** */ + +struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, pcap_t * pcap_handle) { + + set_ndpi_malloc(malloc_wrapper), set_ndpi_free(free_wrapper); + /* TODO: just needed here to init ndpi malloc wrapper */ + struct ndpi_detection_module_struct * module = ndpi_init_detection_module(); + + struct ndpi_workflow * workflow = ndpi_calloc(1, sizeof(struct ndpi_workflow)); + + workflow->pcap_handle = pcap_handle; + workflow->prefs = *prefs; + workflow->ndpi_struct = module; + + if(workflow->ndpi_struct == NULL) { + NDPI_LOG(0, NULL, NDPI_LOG_ERROR, "global structure initialization failed\n"); + exit(-1); + } + + workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *)); + return workflow; +} + +/* ***************************************************** */ + +static void ndpi_flow_info_freer(void *node) { + struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node; + + ndpi_free_flow_info_half(flow); + ndpi_free(flow); +} + +/* ***************************************************** */ + +void ndpi_workflow_free(struct ndpi_workflow * workflow) { + int i; + + for(i=0; i<workflow->prefs.num_roots; i++) + ndpi_tdestroy(workflow->ndpi_flows_root[i], ndpi_flow_info_freer); + + ndpi_exit_detection_module(workflow->ndpi_struct); + free(workflow->ndpi_flows_root); + free(workflow); +} + +/* ***************************************************** */ + +int ndpi_workflow_node_cmp(const void *a, const void *b) { + struct ndpi_flow_info *fa = (struct ndpi_flow_info*)a; + struct ndpi_flow_info *fb = (struct ndpi_flow_info*)b; + + if(fa->vlan_id < fb->vlan_id ) return(-1); else { if(fa->vlan_id > fb->vlan_id ) return(1); } + if(fa->lower_ip < fb->lower_ip ) return(-1); else { if(fa->lower_ip > fb->lower_ip ) return(1); } + if(fa->lower_port < fb->lower_port) return(-1); else { if(fa->lower_port > fb->lower_port) return(1); } + if(fa->upper_ip < fb->upper_ip ) return(-1); else { if(fa->upper_ip > fb->upper_ip ) return(1); } + if(fa->upper_port < fb->upper_port) return(-1); else { if(fa->upper_port > fb->upper_port) return(1); } + if(fa->protocol < fb->protocol ) return(-1); else { if(fa->protocol > fb->protocol ) return(1); } + + return(0); +} + +/* ***************************************************** */ + +static void patchIPv6Address(char *str) { + int i = 0, j = 0; + + while(str[i] != '\0') { + if((str[i] == ':') + && (str[i+1] == '0') + && (str[i+2] == ':')) { + str[j++] = ':'; + str[j++] = ':'; + i += 3; + } else + str[j++] = str[i++]; + } + if(str[j] != '\0') str[j] = '\0'; +} + +/* ***************************************************** */ + +static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow, + const u_int8_t version, + u_int16_t vlan_id, + const struct ndpi_iphdr *iph, + const struct ndpi_ipv6hdr *iph6, + u_int16_t ip_offset, + u_int16_t ipsize, + u_int16_t l4_packet_len, + struct ndpi_tcphdr **tcph, + struct ndpi_udphdr **udph, + u_int16_t *sport, u_int16_t *dport, + struct ndpi_id_struct **src, + struct ndpi_id_struct **dst, + u_int8_t *proto, + u_int8_t **payload, + u_int16_t *payload_len, + u_int8_t *src_to_dst_direction) { + u_int32_t idx, l4_offset; + u_int32_t lower_ip; + u_int32_t upper_ip; + u_int16_t lower_port; + u_int16_t upper_port; + struct ndpi_flow_info flow; + void *ret; + u_int8_t *l3, *l4; + + /* + Note: to keep things simple (ndpiReader is just a demo app) + we handle IPv6 a-la-IPv4. + */ + if(version == 4) { + if(ipsize < 20) + return NULL; + + if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len) + || (iph->frag_off & htons(0x1FFF)) != 0) + return NULL; + + l4_offset = iph->ihl * 4; + l3 = (u_int8_t*)iph; + } else { + l4_offset = sizeof(struct ndpi_ipv6hdr); + l3 = (u_int8_t*)iph6; + } + + if(l4_packet_len < 64) + workflow->stats.packet_len[0]++; + else if(l4_packet_len >= 64 && l4_packet_len < 128) + workflow->stats.packet_len[1]++; + else if(l4_packet_len >= 128 && l4_packet_len < 256) + workflow->stats.packet_len[2]++; + else if(l4_packet_len >= 256 && l4_packet_len < 1024) + workflow->stats.packet_len[3]++; + else if(l4_packet_len >= 1024 && l4_packet_len < 1500) + workflow->stats.packet_len[4]++; + else if(l4_packet_len >= 1500) + workflow->stats.packet_len[5]++; + + if(l4_packet_len > workflow->stats.max_packet_len) + workflow->stats.max_packet_len = l4_packet_len; + + if(iph->saddr < iph->daddr) { + lower_ip = iph->saddr; + upper_ip = iph->daddr; + } else { + lower_ip = iph->daddr; + upper_ip = iph->saddr; + } + + *proto = iph->protocol; + l4 = ((u_int8_t *) l3 + l4_offset); + + if(iph->protocol == 6 && l4_packet_len >= 20) { + u_int tcp_len; + + workflow->stats.tcp_count++; + + // tcp + *tcph = (struct ndpi_tcphdr *)l4; + *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest); + + if(iph->saddr < iph->daddr) { + lower_port = (*tcph)->source, upper_port = (*tcph)->dest; + *src_to_dst_direction = 1; + } else { + lower_port = (*tcph)->dest; + upper_port = (*tcph)->source; + + *src_to_dst_direction = 0; + if(iph->saddr == iph->daddr) { + if(lower_port > upper_port) { + u_int16_t p = lower_port; + + lower_port = upper_port; + upper_port = p; + } + } + } + + tcp_len = ndpi_min(4*(*tcph)->doff, l4_packet_len); + *payload = &l4[tcp_len]; + *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff); + } else if(iph->protocol == 17 && l4_packet_len >= 8) { + // udp + workflow->stats.udp_count++; + + *udph = (struct ndpi_udphdr *)l4; + *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest); + *payload = &l4[sizeof(struct ndpi_udphdr)]; + *payload_len = ndpi_max(0, l4_packet_len-sizeof(struct ndpi_udphdr)); + + if(iph->saddr < iph->daddr) { + lower_port = (*udph)->source, upper_port = (*udph)->dest; + *src_to_dst_direction = 1; + } else { + lower_port = (*udph)->dest, upper_port = (*udph)->source; + + *src_to_dst_direction = 0; + + if(iph->saddr == iph->daddr) { + if(lower_port > upper_port) { + u_int16_t p = lower_port; + + lower_port = upper_port; + upper_port = p; + } + } + } + + *sport = ntohs(lower_port), *dport = ntohs(upper_port); + } else { + // non tcp/udp protocols + lower_port = 0; + upper_port = 0; + } + + flow.protocol = iph->protocol, flow.vlan_id = vlan_id; + flow.lower_ip = lower_ip, flow.upper_ip = upper_ip; + flow.lower_port = lower_port, flow.upper_port = upper_port; + + if(0) + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "[NDPI] [%u][%u:%u <-> %u:%u]\n", + iph->protocol, lower_ip, ntohs(lower_port), upper_ip, ntohs(upper_port)); + + idx = (vlan_id + lower_ip + upper_ip + iph->protocol + lower_port + upper_port) % workflow->prefs.num_roots; + ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); + + if(ret == NULL) { + if(workflow->stats.ndpi_flow_count == workflow->prefs.max_ndpi_flows) { + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "maximum flow count (%u) has been exceeded\n", workflow->prefs.max_ndpi_flows); + exit(-1); + } else { + struct ndpi_flow_info *newflow = (struct ndpi_flow_info*)malloc(sizeof(struct ndpi_flow_info)); + + if(newflow == NULL) { + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(1): not enough memory\n", __FUNCTION__); + return(NULL); + } + + memset(newflow, 0, sizeof(struct ndpi_flow_info)); + newflow->protocol = iph->protocol, newflow->vlan_id = vlan_id; + newflow->lower_ip = lower_ip, newflow->upper_ip = upper_ip; + newflow->lower_port = lower_port, newflow->upper_port = upper_port; + newflow->ip_version = version; + + if(version == 4) { + inet_ntop(AF_INET, &lower_ip, newflow->lower_name, sizeof(newflow->lower_name)); + inet_ntop(AF_INET, &upper_ip, newflow->upper_name, sizeof(newflow->upper_name)); + } else { + inet_ntop(AF_INET6, &iph6->ip6_src, newflow->lower_name, sizeof(newflow->lower_name)); + inet_ntop(AF_INET6, &iph6->ip6_dst, newflow->upper_name, sizeof(newflow->upper_name)); + /* For consistency across platfoms replace :0: with :: */ + patchIPv6Address(newflow->lower_name), patchIPv6Address(newflow->upper_name); + } + + if((newflow->ndpi_flow = ndpi_malloc(SIZEOF_FLOW_STRUCT)) == NULL) { + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(2): not enough memory\n", __FUNCTION__); + free(newflow); + return(NULL); + } else + memset(newflow->ndpi_flow, 0, SIZEOF_FLOW_STRUCT); + + if((newflow->src_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) { + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(3): not enough memory\n", __FUNCTION__); + free(newflow); + return(NULL); + } else + memset(newflow->src_id, 0, SIZEOF_ID_STRUCT); + + if((newflow->dst_id = ndpi_malloc(SIZEOF_ID_STRUCT)) == NULL) { + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_ERROR, "[NDPI] %s(4): not enough memory\n", __FUNCTION__); + free(newflow); + return(NULL); + } else + memset(newflow->dst_id, 0, SIZEOF_ID_STRUCT); + + ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); /* Add */ + workflow->stats.ndpi_flow_count++; + + *src = newflow->src_id, *dst = newflow->dst_id; + + return newflow; + } + } else { + struct ndpi_flow_info *flow = *(struct ndpi_flow_info**)ret; + + if(flow->lower_ip == lower_ip && flow->upper_ip == upper_ip + && flow->lower_port == lower_port && flow->upper_port == upper_port) + *src = flow->src_id, *dst = flow->dst_id; + else + *src = flow->dst_id, *dst = flow->src_id; + + return flow; + } +} + +/* ****************************************************** */ + +static struct ndpi_flow_info *get_ndpi_flow_info6(struct ndpi_workflow * workflow, + u_int16_t vlan_id, + const struct ndpi_ipv6hdr *iph6, + u_int16_t ip_offset, + struct ndpi_tcphdr **tcph, + struct ndpi_udphdr **udph, + u_int16_t *sport, u_int16_t *dport, + struct ndpi_id_struct **src, + struct ndpi_id_struct **dst, + u_int8_t *proto, + u_int8_t **payload, + u_int16_t *payload_len, + u_int8_t *src_to_dst_direction) { + struct ndpi_iphdr iph; + + memset(&iph, 0, sizeof(iph)); + iph.version = 4; + iph.saddr = iph6->ip6_src.u6_addr.u6_addr32[2] + iph6->ip6_src.u6_addr.u6_addr32[3]; + iph.daddr = iph6->ip6_dst.u6_addr.u6_addr32[2] + iph6->ip6_dst.u6_addr.u6_addr32[3]; + iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; + + if(iph.protocol == 0x3C /* IPv6 destination option */) { + u_int8_t *options = (u_int8_t*)iph6 + sizeof(const struct ndpi_ipv6hdr); + + iph.protocol = options[0]; + } + + return(get_ndpi_flow_info(workflow, 6, vlan_id, &iph, iph6, ip_offset, + sizeof(struct ndpi_ipv6hdr), + ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), + tcph, udph, sport, dport, + src, dst, proto, payload, payload_len, src_to_dst_direction)); +} + +/* ****************************************************** */ + +// ipsize = header->len - ip_offset ; rawsize = header->len +static unsigned int packet_processing(struct ndpi_workflow * workflow, + const u_int64_t time, + u_int16_t vlan_id, + const struct ndpi_iphdr *iph, + struct ndpi_ipv6hdr *iph6, + u_int16_t ip_offset, + u_int16_t ipsize, u_int16_t rawsize) { + struct ndpi_id_struct *src, *dst; + struct ndpi_flow_info *flow; + struct ndpi_flow_struct *ndpi_flow = NULL; + u_int8_t proto; + struct ndpi_tcphdr *tcph = NULL; + struct ndpi_udphdr *udph = NULL; + u_int16_t sport, dport, payload_len; + u_int8_t *payload; + u_int8_t src_to_dst_direction= 1; + + if(iph) + flow = get_ndpi_flow_info(workflow, 4, vlan_id, iph, NULL, + ip_offset, ipsize, + ntohs(iph->tot_len) - (iph->ihl * 4), + &tcph, &udph, &sport, &dport, + &src, &dst, &proto, + &payload, &payload_len, &src_to_dst_direction); + else + flow = get_ndpi_flow_info6(workflow, vlan_id, iph6, ip_offset, + &tcph, &udph, &sport, &dport, + &src, &dst, &proto, + &payload, &payload_len, &src_to_dst_direction); + + if(flow != NULL) { + workflow->stats.ip_packet_count++; + workflow->stats.total_wire_bytes += rawsize + 24 /* CRC etc */, workflow->stats.total_ip_bytes += rawsize; + ndpi_flow = flow->ndpi_flow; + flow->packets++, flow->bytes += rawsize; + flow->last_seen = time; + } else { + return(0); + } + + /* Protocol already detected */ + if(flow->detection_completed) return(0); + + flow->detected_protocol = ndpi_detection_process_packet(workflow->ndpi_struct, ndpi_flow, + iph ? (uint8_t *)iph : (uint8_t *)iph6, + ipsize, time, src, dst); + + if((flow->detected_protocol.protocol != NDPI_PROTOCOL_UNKNOWN) + || ((proto == IPPROTO_UDP) && (flow->packets > 8)) + || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { + /* New protocol detected or give up */ + flow->detection_completed = 1; + + if((flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) && (ndpi_flow->num_stun_udp_pkts > 0)) + ndpi_set_detected_protocol(workflow->ndpi_struct, ndpi_flow, NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN); + + snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); + + if(flow->detected_protocol.protocol == NDPI_PROTOCOL_BITTORRENT) { + int i, j, n = 0; + + for(i=0, j = 0; i<20; i++) { + sprintf(&flow->bittorent_hash[j], "%02x", flow->ndpi_flow->bittorent_hash[i]); + j += 2, n += flow->ndpi_flow->bittorent_hash[i]; + } + + if(n == 0) flow->bittorent_hash[0] = '\0'; + } + + if((proto == IPPROTO_TCP) && (flow->detected_protocol.protocol != NDPI_PROTOCOL_DNS)) { + snprintf(flow->ssl.client_certificate, sizeof(flow->ssl.client_certificate), "%s", flow->ndpi_flow->protos.ssl.client_certificate); + snprintf(flow->ssl.server_certificate, sizeof(flow->ssl.server_certificate), "%s", flow->ndpi_flow->protos.ssl.server_certificate); + } + + if(flow->detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN) { + flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow); + + if (workflow->__flow_giveup_callback != NULL) + workflow->__flow_giveup_callback(workflow, flow, workflow->__flow_giveup_udata); + } else { + if (workflow->__flow_detected_callback != NULL) + workflow->__flow_detected_callback(workflow, flow, workflow->__flow_detected_udata); + } + + ndpi_free_flow_info_half(flow); + } + + return 0; +} + +/* ****************************************************** */ +void ndpi_workflow_process_packet (struct ndpi_workflow * workflow, + const struct pcap_pkthdr *header, + const u_char *packet) { + /* + * Declare pointers to packet headers + */ + + /* --- Ethernet header --- */ + const struct ndpi_ethhdr *ethernet; + /* --- Ethernet II header --- */ + const struct ndpi_ethhdr *ethernet_2; + /* --- LLC header --- */ + const struct ndpi_llc_header *llc; + + /* --- Cisco HDLC header --- */ + const struct ndpi_chdlc *chdlc; + /* --- SLARP frame --- */ + struct ndpi_slarp *slarp; + /* --- CDP --- */ + struct ndpi_cdp *cdp; + + /* --- Radio Tap header --- */ + const struct ndpi_radiotap_header *radiotap; + /* --- Wifi header --- */ + const struct ndpi_wifi_header *wifi; + + /* --- MPLS header --- */ + struct ndpi_mpls_header *mpls; + + /** --- IP header --- **/ + struct ndpi_iphdr *iph; + /** --- IPv6 header --- **/ + struct ndpi_ipv6hdr *iph6; + + /* lengths and offsets */ + u_int16_t eth_offset = 0; + u_int16_t radio_len; + u_int16_t fc; + u_int16_t type; + int wifi_len = 0; + int llc_off; + int pyld_eth_len = 0; + int check; + u_int64_t time; + u_int16_t ip_offset, ip_len, ip6_offset; + u_int16_t frag_off = 0, vlan_id = 0; + u_int8_t proto = 0; + u_int32_t label; + + /* counters */ + u_int8_t vlan_packet = 0; + + /* Increment raw packet counter */ + workflow->stats.raw_packet_count++; + + /* setting time */ + time = ((uint64_t) header->ts.tv_sec) * TICK_RESOLUTION + header->ts.tv_usec / (1000000 / TICK_RESOLUTION); + + /* safety check */ + if(workflow->last_time > time) { + /* printf("\nWARNING: timestamp bug in the pcap file (ts delta: %llu, repairing)\n", ndpi_thread_info[thread_id].last_time - time); */ + time = workflow->last_time; + } + /* update last time value */ + workflow->last_time = time; + + /*** check Data Link type ***/ + const int datalink_type = pcap_datalink(workflow->pcap_handle); + + datalink_check: + switch(datalink_type) { + case DLT_NULL : + if(ntohl(*((u_int32_t*)&packet[eth_offset])) == 2) + type = ETH_P_IP; + else + type = ETH_P_IPV6; + + ip_offset = 4 + eth_offset; + break; + + /* Cisco PPP in HDLC-like framing - 50 */ + case DLT_PPP_SERIAL: + chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; + ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ + type = ntohs(chdlc->proto_code); + break; + + /* Cisco PPP with HDLC framing - 104 */ + case DLT_C_HDLC: + chdlc = (struct ndpi_chdlc *) &packet[eth_offset]; + ip_offset = sizeof(struct ndpi_chdlc); /* CHDLC_OFF = 4 */ + type = ntohs(chdlc->proto_code); + break; + + /* IEEE 802.3 Ethernet - 1 */ + case DLT_EN10MB : + ethernet = (struct ndpi_ethhdr *) &packet[eth_offset]; + ip_offset = sizeof(struct ndpi_ethhdr) + eth_offset; + check = ntohs(ethernet->h_proto); + + if(check <= 1500) + pyld_eth_len = check; + else if (check >= 1536) + type = check; + + if(pyld_eth_len != 0) { + /* check for LLC layer with SNAP extension */ + if(packet[ip_offset] == SNAP) { + llc = (struct ndpi_llc_header *)(&packet[ip_offset]); + type = llc->snap.proto_ID; + ip_offset += + 8; + } + } + break; + + /* Linux Cooked Capture - 113 */ + case DLT_LINUX_SLL : + type = (packet[eth_offset+14] << 8) + packet[eth_offset+15]; + ip_offset = 16 + eth_offset; + break; + + /* Radiotap link-layer - 127 */ + case DLT_IEEE802_11_RADIO : + radiotap = (struct ndpi_radiotap_header *) &packet[eth_offset]; + radio_len = radiotap->len; + + /* Check Bad FCS presence */ + if((radiotap->flags & BAD_FCS) == BAD_FCS) { + workflow->stats.total_discarded_bytes += header->len; + return; + } + + /* Calculate 802.11 header length (variable) */ + wifi = (struct ndpi_wifi_header*)( packet + eth_offset + radio_len); + fc = wifi->fc; + + /* check wifi data presence */ + if(FCF_TYPE(fc) == WIFI_DATA) { + if((FCF_TO_DS(fc) && FCF_FROM_DS(fc) == 0x0) || + (FCF_TO_DS(fc) == 0x0 && FCF_FROM_DS(fc))) + wifi_len = 26; /* + 4 byte fcs */ + } else /* no data frames */ + break; + + /* Check ether_type from LLC */ + llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len); + if(llc->dsap == SNAP) + type = ntohs(llc->snap.proto_ID); + + /* Set IP header offset */ + ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header) + eth_offset; + break; + + case DLT_RAW: + ip_offset = eth_offset = 0; + break; + + default: + /* printf("Unknown datalink %d\n", datalink_type); */ + return; + } + + /* check ether type */ + switch(type) { + case VLAN: + vlan_id = ((packet[ip_offset] << 8) + packet[ip_offset+1]) & 0xFFF; + type = (packet[ip_offset+2] << 8) + packet[ip_offset+3]; + ip_offset += 4; + vlan_packet = 1; + break; + case MPLS_UNI: + case MPLS_MULTI: + mpls = (struct ndpi_mpls_header *) &packet[ip_offset]; + label = ntohl(mpls->label); + /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */ + workflow->stats.mpls_count++; + type = ETH_P_IP, ip_offset += 4; + + while((label & 0x100) != 0x100) { + ip_offset += 4; + label = ntohl(mpls->label); + } + break; + case PPPoE: + workflow->stats.pppoe_count++; + type = ETH_P_IP; + ip_offset += 8; + break; + default: + break; + } + + workflow->stats.vlan_count += vlan_packet; + + iph_check: + /* Check and set IP header size and total packet length */ + iph = (struct ndpi_iphdr *) &packet[ip_offset]; + + /* just work on Ethernet packets that contain IP */ + if(type == ETH_P_IP && header->caplen >= ip_offset) { + frag_off = ntohs(iph->frag_off); + + proto = iph->protocol; + if(header->caplen < header->len) { + static u_int8_t cap_warning_used = 0; + + if(cap_warning_used == 0) { + if(!workflow->prefs.quiet_mode) + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: packet capture size is smaller than packet size, DETECTION MIGHT NOT WORK CORRECTLY\n\n"); + cap_warning_used = 1; + } + } + } + + if(iph->version == 4) { + ip_len = ((u_short)iph->ihl * 4); + iph6 = NULL; + + if(iph->protocol == 41) { + ip_offset += ip_len; + goto iph_check; + } + + if((frag_off & 0x1FFF) != 0) { + static u_int8_t ipv4_frags_warning_used = 0; + workflow->stats.fragmented_count++; + + if(ipv4_frags_warning_used == 0) { + if(!workflow->prefs.quiet_mode) + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: IPv4 fragments are not handled by this demo (nDPI supports them)\n"); + ipv4_frags_warning_used = 1; + } + + workflow->stats.total_discarded_bytes += header->len; + return; + } + } else if(iph->version == 6) { + iph6 = (struct ndpi_ipv6hdr *)&packet[ip_offset]; + proto = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; + ip_len = sizeof(struct ndpi_ipv6hdr); + + if(proto == 0x3C /* IPv6 destination option */) { + + u_int8_t *options = (u_int8_t*)&packet[ip_offset+ip_len]; + proto = options[0]; + ip_len += 8 * (options[1] + 1); + } + iph = NULL; + + } else { + static u_int8_t ipv4_warning_used = 0; + + v4_warning: + if(ipv4_warning_used == 0) { + if(!workflow->prefs.quiet_mode) + NDPI_LOG(0, workflow.ndpi_struct, NDPI_LOG_DEBUG, "\n\nWARNING: only IPv4/IPv6 packets are supported in this demo (nDPI supports both IPv4 and IPv6), all other packets will be discarded\n\n"); + ipv4_warning_used = 1; + } + workflow->stats.total_discarded_bytes += header->len; + return; + } + + if(workflow->prefs.decode_tunnels && (proto == IPPROTO_UDP)) { + struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len]; + u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest); + + if((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) { + /* Check if it's GTPv1 */ + u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); + u_int8_t flags = packet[offset]; + u_int8_t message_type = packet[offset+1]; + + if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) && + (message_type == 0xFF /* T-PDU */)) { + + ip_offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr)+8; /* GTPv1 header len */ + if(flags & 0x04) ip_offset += 1; /* next_ext_header is present */ + if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */ + if(flags & 0x01) ip_offset += 1; /* pdu_number is present */ + + iph = (struct ndpi_iphdr *) &packet[ip_offset]; + + if(iph->version != 4) { + // printf("WARNING: not good (packet_id=%u)!\n", (unsigned int)workflow->stats.raw_packet_count); + goto v4_warning; + } + } + } else if((sport == TZSP_PORT) || (dport == TZSP_PORT)) { + /* https://en.wikipedia.org/wiki/TZSP */ + u_int offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr); + u_int8_t version = packet[offset]; + u_int8_t type = packet[offset+1]; + u_int16_t encapsulates = ntohs(*((u_int16_t*)&packet[offset+2])); + + if((version == 1) && (type == 0) && (encapsulates == 1)) { + u_int8_t stop = 0; + + offset += 4; + + while((!stop) && (offset < header->caplen)) { + u_int8_t tag_type = packet[offset]; + u_int8_t tag_len; + + switch(tag_type) { + case 0: /* PADDING Tag */ + tag_len = 1; + break; + case 1: /* END Tag */ + tag_len = 1, stop = 1; + break; + default: + tag_len = packet[offset+1]; + break; + } + + offset += tag_len; + + if(offset >= header->caplen) + return; /* Invalid packet */ + else { + eth_offset = offset; + goto datalink_check; + } + } + } + } + } + + /* process the packet */ + packet_processing(workflow, time, vlan_id, iph, iph6, + ip_offset, header->len - ip_offset, header->len); +} diff --git a/example/ndpi_util.h b/example/ndpi_util.h new file mode 100644 index 000000000..7b1450774 --- /dev/null +++ b/example/ndpi_util.h @@ -0,0 +1,151 @@ +/* + * ndpi_util.h + * + * Copyright (C) 2011-16 - ntop.org + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/** + * This module contains routines to help setup a simple nDPI program. + * + * If you concern about performance or have to integrate nDPI in your + * application, you could need to reimplement them yourself. + * + * WARNING: this API is unstable! Use it at your own risk! + */ + +#ifndef __NDPI_UTIL_H__ +#define __NDPI_UTIL_H__ + +#include <pcap.h> + +#define MAX_NUM_READER_THREADS 16 +#define IDLE_SCAN_PERIOD 10 /* msec (use TICK_RESOLUTION = 1000) */ +#define MAX_IDLE_TIME 30000 +#define IDLE_SCAN_BUDGET 1024 +#define NUM_ROOTS 512 +#define MAX_NDPI_FLOWS 200000000 +#define TICK_RESOLUTION 1000 + + +// flow tracking +typedef struct ndpi_flow_info { + u_int32_t lower_ip; + u_int32_t upper_ip; + u_int16_t lower_port; + u_int16_t upper_port; + u_int8_t detection_completed, protocol; + u_int16_t vlan_id; + struct ndpi_flow_struct *ndpi_flow; + char lower_name[48], upper_name[48]; + u_int8_t ip_version; + u_int64_t last_seen; + u_int64_t bytes; + u_int32_t packets; + + // result only, not used for flow identification + ndpi_protocol detected_protocol; + + char host_server_name[192]; + char bittorent_hash[41]; + + struct { + char client_certificate[48], server_certificate[48]; + } ssl; + + void *src_id, *dst_id; +} ndpi_flow_info_t; + +typedef struct ndpi_stats { + u_int32_t guessed_flow_protocols; + u_int64_t raw_packet_count; + u_int64_t ip_packet_count; + u_int64_t total_wire_bytes, total_ip_bytes, total_discarded_bytes; + u_int64_t protocol_counter[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int64_t protocol_counter_bytes[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int32_t protocol_flows[NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1]; + u_int32_t ndpi_flow_count; + u_int64_t tcp_count, udp_count; + u_int64_t mpls_count, pppoe_count, vlan_count, fragmented_count; + u_int64_t packet_len[6]; + u_int16_t max_packet_len; +} ndpi_stats_t; + +typedef struct ndpi_workflow_prefs { + u_int8_t decode_tunnels; + u_int8_t quiet_mode; + u_int32_t num_roots; + u_int32_t max_ndpi_flows; +} ndpi_workflow_prefs_t; + +struct ndpi_workflow; +/** workflow, flow, user data */ +typedef void (*ndpi_workflow_callback_ptr) (struct ndpi_workflow *, struct ndpi_flow_info *, void *); + +typedef struct ndpi_workflow { + u_int64_t last_time; + + struct ndpi_workflow_prefs prefs; + struct ndpi_stats stats; + + ndpi_workflow_callback_ptr __flow_detected_callback; + void * __flow_detected_udata; + ndpi_workflow_callback_ptr __flow_giveup_callback; + void * __flow_giveup_udata; + + /* outside referencies */ + pcap_t *pcap_handle; + + /* allocated by prefs */ + void **ndpi_flows_root; + struct ndpi_detection_module_struct *ndpi_struct; +} ndpi_workflow_t; + +/* TODO: remove wrappers parameters and use ndpi global, when their initialization will be fixed... */ +struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * prefs, pcap_t * pcap_handle); + +void ndpi_workflow_free(struct ndpi_workflow * workflow); + +/** Free flow_info ndpi support structures but not the flow_info itself + * + * TODO remove! Half freeing things is bad! + */ +void ndpi_free_flow_info_half(struct ndpi_flow_info *flow); + +/** Process a @packet and update the @workflow. */ +void ndpi_workflow_process_packet (struct ndpi_workflow * workflow, + const struct pcap_pkthdr *header, + const u_char *packet); + +/* flow callbacks: ndpi_flow_info will be freed right after */ +static inline void ndpi_workflow_set_flow_detected_callback(struct ndpi_workflow * workflow, + ndpi_workflow_callback_ptr callback, + void * udata) { + workflow->__flow_detected_callback = callback; + workflow->__flow_detected_udata = udata; +} + +static inline void ndpi_workflow_set_flow_giveup_callback(struct ndpi_workflow * workflow, + ndpi_workflow_callback_ptr callback, + void * udata) { + workflow->__flow_giveup_callback = callback; + workflow->__flow_giveup_udata = udata; +} + +int ndpi_workflow_node_cmp(const void *a, const void *b); + + +#endif diff --git a/libndpi.sym b/libndpi.sym index 7fd2f920d..da21e64fd 100644 --- a/libndpi.sym +++ b/libndpi.sym @@ -1,4 +1,6 @@ ndpi_dump_protocols +ndpi_strnstr +ndpi_detection_giveup ndpi_get_proto_name ndpi_free ndpi_guess_undetected_protocol @@ -27,6 +29,7 @@ ndpi_free_flow ndpi_get_proto_breed ndpi_get_proto_breed_name ndpi_get_proto_by_id +ndpi_get_proto_by_name ndpi_get_protocol_id_master_proto ndpi_guess_protocol_id ndpi_protocol2name @@ -36,3 +39,11 @@ ndpi_malloc ndpi_calloc ndpi_set_detected_protocol ndpi_match_string_subprotocol +ndpi_init_automa +ndpi_free_automa +ndpi_add_string_to_automa +ndpi_finalize_automa +ndpi_match_string +set_ndpi_malloc +set_ndpi_free +set_ndpi_debug_function
\ No newline at end of file diff --git a/packages/homebrew/ndpi.rb b/packages/homebrew/ndpi.rb index d7c17f500..a3ea00458 100644 --- a/packages/homebrew/ndpi.rb +++ b/packages/homebrew/ndpi.rb @@ -1,14 +1,15 @@ class Ndpi < Formula desc "Deep Packet Inspection (DPI) library" homepage "http://www.ntop.org/products/ndpi/" - url "https://downloads.sourceforge.net/project/ntop/nDPI/nDPI-1.7.tar.gz" - sha256 "714b745103a072462130b0e14cf31b2eb5270f580b7c839da5cf5ea75150262d" + url "https://downloads.sourceforge.net/project/ntop/nDPI/nDPI-1.8.tgz" + sha256 "f490137a7387b69d0d55e990f2150b86d7b5eaae870e5326e8c2f18c17412443" bottle do cellar :any - sha256 "e9464d314479ba3e7a91422e0bc606cfd5f6e72e94d6441cc4fa30e9c925da5c" => :yosemite - sha256 "1d6b1d860669b42766baa276ed948c342e2fa4fd28663ba64a90fd0e200ba9c4" => :mavericks - sha256 "b814918b4fb9588de7126061ce4ac3eb41a5c3eee27c7432b669f6dc6921bfde" => :mountain_lion + sha256 "05053767fc3c70557745c348c7352e7c2716c040ca54c5cf8d5306167c878fcb" => :el_capitan + sha256 "34c0269039a0079820eeed862daa28158d9291f73f640a9415da60746d69a662" => :yosemite + sha256 "a2af4dc62c24313593b3a20e45ca9d2d49f8efc0ea5e52fd064001ea441b93e4" => :mavericks + sha256 "1bb200268a4d9df9bbe5d33bc773ee3bcf4b5d4fa00c76a040f16318438c284f" => :mountain_lion end depends_on "autoconf" => :build diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index a07c96e63..737e29cb9 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -115,22 +115,14 @@ extern "C" { * */ void ndpi_init_protocol_match(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_match *match); - /** * Returns a new initialized detection module * - * @par ticks_per_second = the timestamp resolution per second (like 1000 for millisecond resolution) - * @par __ndpi_malloc = function pointer to a nDPI memory allocator - * @par ndpi_debug_printf = function pointer to a nDPI debug output function (use NULL in productive envionments) * @return the initialized detection module * */ - struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second, - void* (*__ndpi_malloc)(size_t size), - void (*__ndpi_free)(void *ptr), - ndpi_debug_function_ptr ndpi_debug_printf); - + struct ndpi_detection_module_struct *ndpi_init_detection_module(); /** * Frees the memory allocated in the specified flow @@ -157,10 +149,9 @@ extern "C" { * Destroys the detection module * * @par ndpi_struct = the struct to clearing for the detection module - * @par ndpi_free = function pointer to a nDPI memory free function * */ - void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct, void (*ndpi_free) (void *ptr)); + void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct); /** @@ -233,6 +224,52 @@ extern "C" { struct ndpi_id_struct *src, struct ndpi_id_struct *dst); + + /** + * Processes one packet of L4 and returns the ID of the detected protocol. + * L3 and L4 packet headers are passed in the arguments while payload + * points to the L4 body. + * This function mimics ndpi_detection_process_packet behaviour. + * + * @par ndpi_struct = the detection module + * @par flow = pointer to the connection state machine + * @par iph = IP packet header for IPv4 or NULL + * @par iph6 = IP packet header for IPv6 or NULL + * @par tcp = TCP packet header for TCP or NULL + * @par udp = UDP packet header for UDP or NULL + * @par src_to_dst_direction = order of src/dst state machines in a flow. + * @par l4_proto = L4 protocol of the packet. + * @par src = pointer to the source subscriber state machine + * @par dst = pointer to the destination subscriber state machine + * @par sport = source port of L4 packet, used for protocol guessing. + * @par dport = destination port of L4 packet, used for protocol guessing. + * @par current_tick_l = the current timestamp for the packet + * @par payload = unsigned char pointer to the Layer 4 (TCP/UDP body) + * @par payload_len = the length of the payload + * @return the detected ID of the protocol + * + * NOTE: in a current implementation flow->src and flow->dst are swapped with + * the src_to_dst_direction flag while ndpi_detection_process_packet does not swap + * these values. + * + */ + +ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + const struct ndpi_iphdr *iph, + struct ndpi_ipv6hdr *iph6, + struct ndpi_tcphdr *tcp, + struct ndpi_udphdr *udp, + u_int8_t src_to_dst_direction, + u_int8_t l4_proto, + struct ndpi_id_struct *src, + u_int16_t sport, + struct ndpi_id_struct *dst, + u_int16_t dport, + const u_int64_t current_tick_l, + u_int8_t *payload, u_int16_t payload_len); + + /** * Get the main protocol of the passed flows for the detected module @@ -544,6 +581,61 @@ extern "C" { struct ndpi_flow_struct *flow, char *certificate); #endif + /* Wrappers functions */ + /** + * Init Aho-Corasick automata + * + * @return The requested automata, or NULL if an error occurred + * + */ + void* ndpi_init_automa(); + + + /** + * Free Aho-Corasick automata allocated with ndpi_init_automa(); + * + * @par The automata initialized with ndpi_init_automa(); + * + */ + void ndpi_free_automa(void *_automa); + + + /** + * Add a string to match to an automata + * + * @par The automata initialized with ndpi_init_automa(); + * @par The (sub)string to search + * @return 0 in case of no error, or -1 if an error occurred. + * + */ + int ndpi_add_string_to_automa(void *_automa, char *str); + + + /** + * Finalize the automa (necessary before start searching) + * + * @par The automata initialized with ndpi_init_automa(); + * + */ + void ndpi_finalize_automa(void *_automa); + + + /** + * Add a string to match to an automata + * + * @par The automata initialized with ndpi_init_automa(); + * @par The (sub)string to search + * @return 0 in case of match, or -1 if no match, or -2 if an error occurred. + * + */ + int ndpi_match_string(void *_automa, char *string_to_match); + + + /* Utility functions to set ndpi malloc/free/print wrappers */ + void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size)); + void set_ndpi_free(void (*__ndpi_free)(void *ptr)); + void set_ndpi_debug_function(ndpi_debug_function_ptr ndpi_debug_printf); + #ifdef __cplusplus } #endif diff --git a/src/include/ndpi_define.h b/src/include/ndpi_define.h index 3fa0b34e6..cc237128a 100644 --- a/src/include/ndpi_define.h +++ b/src/include/ndpi_define.h @@ -1,7 +1,6 @@ /* * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -77,7 +76,7 @@ #endif -#define NDPI_USE_ASYMMETRIC_DETECTION 0 +#define NDPI_USE_ASYMMETRIC_DETECTION 0 #define NDPI_SELECTION_BITMASK_PROTOCOL_SIZE u_int32_t #define NDPI_SELECTION_BITMASK_PROTOCOL_IP (1<<0) @@ -160,24 +159,24 @@ /* TODO: rebuild all memory areas to have a more aligned memory block here */ /* DEFINITION OF MAX LINE NUMBERS FOR line parse algorithm */ -#define NDPI_MAX_PARSE_LINES_PER_PACKET 64 +#define NDPI_MAX_PARSE_LINES_PER_PACKET 64 #define MAX_PACKET_COUNTER 65000 #define MAX_DEFAULT_PORTS 5 #define NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT 600 #define NDPI_IRC_CONNECTION_TIMEOUT 120 -#define NDPI_GNUTELLA_CONNECTION_TIMEOUT 60 -#define NDPI_BATTLEFIELD_CONNECTION_TIMEOUT 60 -#define NDPI_THUNDER_CONNECTION_TIMEOUT 30 -#define NDPI_RTSP_CONNECTION_TIMEOUT 5 -#define NDPI_TVANTS_CONNECTION_TIMEOUT 5 -#define NDPI_YAHOO_DETECT_HTTP_CONNECTIONS 1 -#define NDPI_YAHOO_LAN_VIDEO_TIMEOUT 30 +#define NDPI_GNUTELLA_CONNECTION_TIMEOUT 60 +#define NDPI_BATTLEFIELD_CONNECTION_TIMEOUT 60 +#define NDPI_THUNDER_CONNECTION_TIMEOUT 30 +#define NDPI_RTSP_CONNECTION_TIMEOUT 5 +#define NDPI_TVANTS_CONNECTION_TIMEOUT 5 +#define NDPI_YAHOO_DETECT_HTTP_CONNECTIONS 1 +#define NDPI_YAHOO_LAN_VIDEO_TIMEOUT 30 #define NDPI_ZATTOO_CONNECTION_TIMEOUT 120 -#define NDPI_ZATTOO_FLASH_TIMEOUT 5 -#define NDPI_JABBER_STUN_TIMEOUT 30 -#define NDPI_JABBER_FT_TIMEOUT 5 +#define NDPI_ZATTOO_FLASH_TIMEOUT 5 +#define NDPI_JABBER_STUN_TIMEOUT 30 +#define NDPI_JABBER_FT_TIMEOUT 5 #define NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT 600 #ifdef NDPI_ENABLE_DEBUG_MESSAGES diff --git a/src/include/ndpi_includes.h b/src/include/ndpi_includes.h index ce36a25f9..f77f8cfc4 100644 --- a/src/include/ndpi_includes.h +++ b/src/include/ndpi_includes.h @@ -1,7 +1,7 @@ /* * ndpi_includes.h * - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -35,6 +35,7 @@ #ifdef WIN32 #include "ndpi_win32.h" #else +#include <sys/types.h> #include <sys/param.h> #include <pthread.h> #include <arpa/inet.h> diff --git a/src/include/ndpi_main.h b/src/include/ndpi_main.h index a70f35c8d..43bd4e2bb 100644 --- a/src/include/ndpi_main.h +++ b/src/include/ndpi_main.h @@ -1,8 +1,7 @@ /* * ndpi_main.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -32,79 +31,99 @@ #include "ndpi_protocols.h" #include "ndpi_api.h" +#ifdef __cplusplus +extern "C" { +#endif -void *ndpi_tdelete(const void * __restrict, void ** __restrict, - int (*)(const void *, const void *)); -void *ndpi_tfind(const void *, void *, int (*)(const void *, const void *)); -void *ndpi_tsearch(const void *, void**, int (*)(const void *, const void *)); -void ndpi_twalk(const void *, void (*)(const void *, ndpi_VISIT, int, void*), void *user_data); -void ndpi_tdestroy(void *vrootp, void (*freefct)(void *)); + void *ndpi_tdelete(const void * __restrict, void ** __restrict, + int (*)(const void *, const void *)); + void *ndpi_tfind(const void *, void *, int (*)(const void *, const void *)); + void *ndpi_tsearch(const void *, void**, int (*)(const void *, const void *)); + void ndpi_twalk(const void *, void (*)(const void *, ndpi_VISIT, int, void*), void *user_data); + void ndpi_tdestroy(void *vrootp, void (*freefct)(void *)); -int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b); -int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a); -void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a); + int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b); + int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a); + void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a); -extern u_int8_t ndpi_net_match(u_int32_t ip_to_check, - u_int32_t net, - u_int32_t num_bits); + extern u_int8_t ndpi_net_match(u_int32_t ip_to_check, + u_int32_t net, + u_int32_t num_bits); -extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst, - u_int32_t net, u_int32_t num_bits); + extern u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst, + u_int32_t net, u_int32_t num_bits); -u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int16_t ntohs_ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int32_t ndpi_bytestream_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int64_t ndpi_bytestream_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int32_t ndpi_bytestream_dec_or_hex_to_number(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int64_t ndpi_bytestream_dec_or_hex_to_number64(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); + u_int32_t ndpi_bytestream_to_ipv4(const u_int8_t * str, u_int16_t max_chars_to_read, u_int16_t * bytes_read); -void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - u_int16_t upper_detected_protocol, - u_int16_t lower_detected_protocol); + void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t upper_detected_protocol, + u_int16_t lower_detected_protocol); -extern void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); -extern void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + extern void ndpi_parse_packet_line_info(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); + extern void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); -extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t counter); + extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int16_t counter); -extern void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int16_t upper_detected_protocol, - u_int16_t lower_detected_protocol); -extern void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int16_t upper_detected_protocol, - u_int16_t lower_detected_protocol); -extern void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_breed_t protoBreed, u_int16_t protoId, - u_int16_t tcp_alias_protoId[2], u_int16_t udp_alias_protoId[2], char *protoName, - ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts); + extern void ndpi_int_change_packet_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + u_int16_t upper_detected_protocol, + u_int16_t lower_detected_protocol); + extern void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, + u_int16_t upper_detected_protocol, + u_int16_t lower_detected_protocol); + extern void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_breed_t protoBreed, u_int16_t protoId, + u_int16_t tcp_alias_protoId[2], u_int16_t udp_alias_protoId[2], char *protoName, + ndpi_port_range *tcpDefPorts, ndpi_port_range *udpDefPorts); -extern void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet); -extern void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow); + extern void ndpi_int_reset_packet_protocol(struct ndpi_packet_struct *packet); + extern void ndpi_int_reset_protocol(struct ndpi_flow_struct *flow); -extern int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); -extern int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); -extern void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); -extern void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); + extern int ndpi_packet_src_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); + extern int ndpi_packet_dst_ip_eql(const struct ndpi_packet_struct *packet, const ndpi_ip_addr_t * ip); + extern void ndpi_packet_src_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); + extern void ndpi_packet_dst_ip_get(const struct ndpi_packet_struct *packet, ndpi_ip_addr_t * ip); -extern char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const ndpi_ip_addr_t * ip); -extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const struct ndpi_packet_struct *packet); -extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id); + extern char *ndpi_get_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const ndpi_ip_addr_t * ip); + extern char *ndpi_get_packet_src_ip_string(struct ndpi_detection_module_struct *ndpi_struct, const struct ndpi_packet_struct *packet); + extern char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int id); + u_int16_t ndpi_get_proto_by_name(struct ndpi_detection_module_struct *ndpi_mod, const char *name); -extern u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, - u_int8_t proto, u_int16_t sport, u_int16_t dport); + extern u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int16_t sport, u_int16_t dport, + u_int8_t *user_defined_proto); -extern u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto); + extern u_int8_t ndpi_is_proto(ndpi_protocol p, u_int16_t proto); -extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p); -extern int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t protocol_id, - u_int16_t** tcp_master_proto, - u_int16_t** udp_master_proto); + extern u_int16_t ndpi_get_lower_proto(ndpi_protocol p); + extern int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t protocol_id, + u_int16_t** tcp_master_proto, + u_int16_t** udp_master_proto); #ifdef NDPI_ENABLE_DEBUG_MESSAGES -void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_struct, - const char **file, const char **func, u_int32_t * line); + void ndpi_debug_get_last_log_function_line(struct ndpi_detection_module_struct *ndpi_struct, + const char **file, const char **func, u_int32_t * line); +#endif + + /** Checks when the @p payload starts with the string literal @p str. + * When the string is larger than the payload, check fails. + * @return non-zero if check succeeded + */ + int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len, + const char *str, size_t str_len); + + /* version of ndpi_match_prefix with string literal */ +#define ndpi_match_strprefix(payload, payload_len, str) \ + ndpi_match_prefix((payload), (payload_len), (str), (sizeof(str)-1)) + +#ifdef __cplusplus +} #endif #endif /* __NDPI_MAIN_H__ */ diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h index cfc0ad56d..e4d40e9bb 100644 --- a/src/include/ndpi_protocol_ids.h +++ b/src/include/ndpi_protocol_ids.h @@ -1,8 +1,7 @@ /* * ndpi_protocol_ids.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-11 - ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -199,10 +198,10 @@ #define NDPI_PROTOCOL_TELEGRAM 185 /* Gianluca Costa <g.costa@xplico.org> */ #define NDPI_PROTOCOL_QUIC 188 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> - Michele Campus <michelecampus5@gmail.com> */ #define NDPI_PROTOCOL_WHATSAPP_VOICE 189 -#define NDPI_PROTOCOL_STARCRAFT 213 /* Matteo Bracci <matteobracci1@gmail.com> */ -#define NDPI_PROTOCOL_TEREDO 214 -#define NDPI_PROTOCOL_HEP 216 /* Sipcapture.org QXIP BV */ -#define NDPI_PROTOCOL_UBNTAC2 217 /* Ubiquity UBNT AirControl 2 - Thomas Fjellstrom <thomas+ndpi@fjellstrom.ca> */ +#define NDPI_PROTOCOL_STARCRAFT 211 /* Matteo Bracci <matteobracci1@gmail.com> */ +#define NDPI_PROTOCOL_TEREDO 212 +#define NDPI_PROTOCOL_HEP 213 /* Sipcapture.org QXIP BV */ +#define NDPI_PROTOCOL_UBNTAC2 214 /* Ubiquity UBNT AirControl 2 - Thomas Fjellstrom <thomas+ndpi@fjellstrom.ca> */ #define NDPI_PROTOCOL_MS_LYNC 173 @@ -243,36 +242,32 @@ #define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow <tomasz@skatnet.dk> */ #define NDPI_SERVICE_PANDORA 187 #define NDPI_PROTOCOL_EAQ 190 -#define NDPI_SERVICE_TIMMEU 191 -#define NDPI_SERVICE_TORCEDOR 192 +#define NDPI_PROTOCOL_GIT 191 +#define NDPI_PROTOCOL_DRDA 192 #define NDPI_SERVICE_KAKAOTALK 193 /* KakaoTalk Chat (no voice call) */ #define NDPI_SERVICE_KAKAOTALK_VOICE 194 /* KakaoTalk Voice */ #define NDPI_SERVICE_TWITCH 195 /* Edoardo Dominici <edoaramis@gmail.com> */ #define NDPI_SERVICE_QUICKPLAY 196 /* Streaming service used by various services such as hooq.tv */ -#define NDPI_SERVICE_TIM 197 /* Traffic for tim.com.br and tim.it */ +#define NDPI_SERVICE_OPENDNS 197 #define NDPI_PROTOCOL_MPEGTS 198 #define NDPI_SERVICE_SNAPCHAT 199 -#define NDPI_SERVICE_SIMET 200 -#define NDPI_SERVICE_OPENSIGNAL 201 -#define NDPI_SERVICE_99TAXI 202 -#define NDPI_SERVICE_EASYTAXI 203 -#define NDPI_SERVICE_GLOBOTV 204 -#define NDPI_SERVICE_TIMSOMDECHAMADA 205 -#define NDPI_SERVICE_TIMMENU 206 -#define NDPI_SERVICE_TIMPORTASABERTAS 207 -#define NDPI_SERVICE_TIMRECARGA 208 -#define NDPI_SERVICE_TIMBETA 209 -#define NDPI_SERVICE_DEEZER 210 -#define NDPI_SERVICE_INSTAGRAM 211 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> */ -#define NDPI_SERVICE_MICROSOFT 212 -#define NDPI_SERVICE_HOTSPOT_SHIELD 215 -#define NDPI_SERVICE_OCS 218 -#define NDPI_SERVICE_OFFICE_365 219 -#define NDPI_SERVICE_CLOUDFLARE 220 -#define NDPI_SERVICE_MS_ONE_DRIVE 221 -#define NDPI_PROTOCOL_MQTT 222 +#define NDPI_SERVICE_DEEZER 200 +#define NDPI_SERVICE_INSTAGRAM 201 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> */ +#define NDPI_SERVICE_MICROSOFT 202 +#define NDPI_SERVICE_HOTSPOT_SHIELD 203 +#define NDPI_SERVICE_OCS 204 +#define NDPI_SERVICE_OFFICE_365 205 +#define NDPI_SERVICE_CLOUDFLARE 206 +#define NDPI_SERVICE_MS_ONE_DRIVE 207 +#define NDPI_PROTOCOL_MQTT 208 +#define NDPI_PROTOCOL_RX 209 +#define NDPI_SERVICE_WEIBO 210 +#define NDPI_SERVICE_HANGOUT 215 +#define NDPI_SERVICE_SLACK 216 +#define NDPI_SERVICE_HOTMAIL 217 + /* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE */ -#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_PROTOCOL_MQTT +#define NDPI_LAST_IMPLEMENTED_PROTOCOL NDPI_SERVICE_HOTMAIL #define NDPI_MAX_SUPPORTED_PROTOCOLS (NDPI_LAST_IMPLEMENTED_PROTOCOL + 1) #define NDPI_MAX_NUM_CUSTOM_PROTOCOLS (NDPI_NUM_BITS-NDPI_LAST_IMPLEMENTED_PROTOCOL) diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h index b5df1c937..12f3a0dbd 100644 --- a/src/include/ndpi_protocols.h +++ b/src/include/ndpi_protocols.h @@ -1,8 +1,7 @@ /* * ndpi_protocols.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -53,10 +52,6 @@ void ndpi_search_tcp_or_udp(struct ndpi_detection_module_struct *ndpi_struct, st /* Applications and other protocols. */ void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); -void ndpi_bittorrent_init(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t size,u_int32_t timeout); -void ndpi_bittorrent_done(struct ndpi_detection_module_struct *ndpi_struct); -int ndpi_bittorrent_gc(struct hash_ip4p_table *ht,int key,time_t now); - void ndpi_search_edonkey(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_fasttrack_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); @@ -198,6 +193,9 @@ void ndpi_search_starcraft(struct ndpi_detection_module_struct *ndpi_struct, str void ndpi_search_ubntac2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_coap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_rx(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_git(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_drda(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); /* --- INIT FUNCTIONS --- */ void init_afp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_aimini_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); @@ -337,4 +335,8 @@ void init_stracraft_dissector(struct ndpi_detection_module_struct *ndpi_struct, void init_ubntac2_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_coap_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mqtt_dissector (struct ndpi_detection_module_struct *ndpi_struct,u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_hangout_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); +void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); #endif /* __NDPI_PROTOCOLS_H__ */ diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index ed74b9a07..9a50b65fd 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1,8 +1,7 @@ /* * ndpi_typedefs.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-11 - ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -555,7 +554,7 @@ struct ndpi_flow_tcp_struct { u_int32_t mail_pop_stage:2; #endif #ifdef NDPI_PROTOCOL_MAIL_IMAP - u_int32_t mail_imap_stage:3; + u_int32_t mail_imap_stage:3, mail_imap_starttls:2; #endif #ifdef NDPI_PROTOCOL_SKYPE u_int8_t skype_packet_id; @@ -622,6 +621,10 @@ struct ndpi_flow_udp_struct { u_int8_t eaq_pkt_id; u_int32_t eaq_sequence; #endif +#ifdef NDPI_PROTOCOL_RX + u_int32_t rx_conn_epoch; + u_int32_t rx_conn_id; +#endif } #ifndef WIN32 __attribute__ ((__packed__)) @@ -734,6 +737,7 @@ typedef struct ndpi_proto_defaults { typedef struct ndpi_default_ports_tree_node { ndpi_proto_defaults_t *proto; + u_int8_t customUserProto; u_int16_t default_port; } ndpi_default_ports_tree_node_t; @@ -749,7 +753,7 @@ typedef struct ndpi_proto { #define NDPI_PROTOCOL_NULL { NDPI_PROTOCOL_UNKNOWN , NDPI_PROTOCOL_UNKNOWN } struct ndpi_detection_module_struct { - + NDPI_PROTOCOL_BITMASK detection_bitmask; NDPI_PROTOCOL_BITMASK generic_http_packet_bitmask; @@ -802,7 +806,7 @@ struct ndpi_detection_module_struct { content_automa, /* Used for HTTP subprotocol_detection */ subprotocol_automa, /* Used for HTTP subprotocol_detection */ bigrams_automa, impossible_bigrams_automa; /* TOR */ - + /* IP-based protocol detection */ void *protocols_ptree; @@ -846,8 +850,8 @@ struct ndpi_detection_module_struct { ndpi_proto_defaults_t proto_defaults[NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS]; - u_int8_t http_dont_dissect_response:1; - u_int8_t direction_detect_disable:1; /* disable internal detection of packet direction */ + u_int8_t http_dont_dissect_response:1, dns_dissect_response:1, + direction_detect_disable:1; /* disable internal detection of packet direction */ }; struct ndpi_flow_struct { @@ -908,10 +912,10 @@ struct ndpi_flow_struct { /* the only fields useful for nDPI and ntopng */ struct { - u_int8_t num_answers, ret_code; - u_int16_t query_type; + u_int8_t num_queries, num_answers, reply_code; + u_int16_t query_type, query_class, rsp_type; } dns; - + struct { u_int8_t request_code; u_int8_t version; @@ -1002,6 +1006,10 @@ struct ndpi_flow_struct { #ifdef NDPI_PROTOCOL_STARCRAFT u_int32_t starcraft_udp_stage : 3; // 0-7 #endif +#ifdef NDPI_PROTOCOL_OPENVPN + u_int8_t ovpn_session_id[8]; + u_int8_t ovpn_counter; +#endif /* internal structures to save functions calls */ struct ndpi_packet_struct packet; diff --git a/src/include/ndpi_unix.h b/src/include/ndpi_unix.h index b680d3c30..6e6987bfd 100644 --- a/src/include/ndpi_unix.h +++ b/src/include/ndpi_unix.h @@ -1,8 +1,7 @@ /* * ndpi_unix.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH diff --git a/src/include/ndpi_win32.h b/src/include/ndpi_win32.h index 645c022e5..876e59c05 100644 --- a/src/include/ndpi_win32.h +++ b/src/include/ndpi_win32.h @@ -1,8 +1,7 @@ /* * ndpi_win32.h * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-2011 by ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index abda7ede1..b920d4d67 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -26,6 +26,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/bittorrent.c \ protocols/ciscovpn.c \ protocols/citrix.c \ + protocols/coap.c \ protocols/collectd.c \ protocols/corba.c \ protocols/crossfire.c \ @@ -36,6 +37,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/directdownloadlink.c \ protocols/dns.c \ protocols/dofus.c \ + protocols/drda.c \ protocols/dropbox.c \ protocols/eaq.c \ protocols/edonkey.c \ @@ -45,9 +47,11 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/florensia.c \ protocols/ftp_control.c \ protocols/ftp_data.c \ + protocols/git.c \ protocols/gnutella.c \ protocols/gtp.c \ protocols/guildwars.c \ + protocols/hangout.c \ protocols/h323.c \ protocols/halflife2_and_mods.c \ protocols/hep.c \ @@ -74,6 +78,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/mgcp.c \ protocols/mms.c \ protocols/mpegts.c \ + protocols/mqtt.c \ protocols/msn.c \ protocols/mssql.c \ protocols/mysql.c \ @@ -104,6 +109,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/rtmp.c \ protocols/rtp.c \ protocols/rtsp.c \ + protocols/rx.c \ protocols/sflow.c \ protocols/shoutcast.c \ protocols/sip.c \ @@ -152,12 +158,13 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/yahoo.c \ protocols/zattoo.c \ protocols/zeromq.c \ - protocols/coap.c \ - protocols/mqtt.c \ third_party/include/actypes.h \ third_party/include/ahocorasick.h \ + third_party/include/ndpi_patricia.h \ third_party/include/node.h \ third_party/include/sort.h \ third_party/src/ahocorasick.c \ third_party/src/node.c \ third_party/src/sort.c + +EXTRA_DIST = third_party/src/ndpi_patricia.c diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc index 915df390f..fc5c35029 100644 --- a/src/lib/ndpi_content_match.c.inc +++ b/src/lib/ndpi_content_match.c.inc @@ -1,7 +1,7 @@ /* * ndpi_content_match.c * - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2011-16 - ntop.org * * nDPI is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -22,7 +22,13 @@ static ndpi_network host_protocol_list[] = { - /* + /* + OpenDNS + 208.67.216.0/21 + */ + { 0xD043D800 /* 208.67.216.0/21 */, 21, NDPI_SERVICE_OPENDNS }, + + /* Microsoft Corporation (MS One Drive) 204.79.195.0/24 204.79.196.0/23 @@ -40,7 +46,6 @@ static ndpi_network host_protocol_list[] = { { 0x83FD1200 /* 131.253.18.0/24 */, 24, NDPI_SERVICE_MS_ONE_DRIVE }, { 0x4136BF00 /* 65.54.191.0/24 */, 24, NDPI_SERVICE_MS_ONE_DRIVE }, - /* Amazon-EU-AWS Elastic Compute Cloud, EC2 (also used by Netflix) 46.137.128.0/18 @@ -149,17 +154,29 @@ static ndpi_network host_protocol_list[] = { /* Skype (Microsoft CDN) - 157.56.0.0/14, 157.60.0.0/16, 157.54.0.0/15 + 157.56.135.64/26, 157.56.185.0/26, 157.56.52.0/26, + 157.56.53.128/25, 157.56.198.0/26 + 157.60.0.0/16, 157.54.0.0/15 + 13.107.3.128/32 + 13.107.3.129/32 111.221.64.0 - 111.221.127.255 91.190.216.0/21 (AS198015 Skype Communications Sarl) 40.126.129.109/32 + 65.55.223.0/26 */ - { 0x9D380000 /* 157.56.0.0 */, 14, NDPI_PROTOCOL_SKYPE }, + { 0x9D388740 /* 157.56.135.64 */, 26, NDPI_PROTOCOL_SKYPE }, + { 0x9D38B900 /* 157.56.185.0 */, 26, NDPI_PROTOCOL_SKYPE }, + { 0x9D383400 /* 157.56.52.0 */, 26, NDPI_PROTOCOL_SKYPE }, + { 0x9D383580 /* 157.56.53.128 */, 25, NDPI_PROTOCOL_SKYPE }, + { 0x9D38C600 /* 157.56.198.0 */, 26, NDPI_PROTOCOL_SKYPE }, { 0x9D3C0000 /* 157.60.0.0 */, 16, NDPI_PROTOCOL_SKYPE }, { 0x9D360000 /* 157.54.0.0 */, 15, NDPI_PROTOCOL_SKYPE }, + { 0x0D6B0380 /* 13.107.3.128 */, 32, NDPI_PROTOCOL_SKYPE }, + { 0x0D6B0381 /* 13.107.3.129 */, 32, NDPI_PROTOCOL_SKYPE }, { 0x6FDD4000 /* 111.221.64.0 */, 18, NDPI_PROTOCOL_SKYPE }, { 0x5BBED800 /* 91.190.216.0 */, 21, NDPI_PROTOCOL_SKYPE }, { 0x287F816D /* 40.126.129.109 */, 32, NDPI_PROTOCOL_SKYPE }, + { 0x4237DF00 /* 65.55.223.0 */, 26, NDPI_PROTOCOL_SKYPE }, /* @@ -7226,9 +7243,6 @@ static ndpi_network host_protocol_list[] = { { 0xC709F98C, 32, NDPI_SERVICE_TWITCH }, { 0xC709F9C5, 32, NDPI_SERVICE_TWITCH }, - /* Simet - 200.160.4.0/24 */ - { 0xC8A00400, 24, NDPI_SERVICE_SIMET }, - /* AnchorFree (Hotspot Shield) AnchorFree Inc. AFNETWORK-1 (NET-74-115-0-0-1) 74.115.0.0 - 74.115.7.255 @@ -7253,6 +7267,7 @@ ndpi_protocol_match host_match[] = { { "images-amazon.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, { "amazonaws.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, { "amazon-adsystem.com", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, + { ".cloudfront.net", "Amazon", NDPI_SERVICE_AMAZON, NDPI_PROTOCOL_ACCEPTABLE }, { ".apple.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".mzstatic.com", "Apple", NDPI_SERVICE_APPLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".icloud.com", "AppleiCloud", NDPI_SERVICE_APPLE_ICLOUD, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7268,10 +7283,11 @@ ndpi_protocol_match host_match[] = { { ".ebayrtm.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, { ".ebaystratus.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, { ".ebayimg.com", "eBay", NDPI_SERVICE_EBAY, NDPI_PROTOCOL_ACCEPTABLE }, - { ".facebook.com", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, + { "facebook.com", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, { "fbstatic-a.akamaihd.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, { ".fbcdn.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, - { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */ + { "fbcdn-", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, /* fbcdn-video-a-akamaihd.net */ + { ".facebook.net", "Facebook", NDPI_SERVICE_FACEBOOK, NDPI_PROTOCOL_FUN }, { ".google.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".gstatic.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { ".googlesyndication.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7284,10 +7300,12 @@ ndpi_protocol_match host_match[] = { { "googleadservices.", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { "googleapis.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { "ggpht.com", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, + { "1e100.net", "Google", NDPI_SERVICE_GOOGLE, NDPI_PROTOCOL_ACCEPTABLE }, { "maps.google.", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE }, { "maps.gstatic.com", "GoogleMaps", NDPI_SERVICE_GOOGLE_MAPS, NDPI_PROTOCOL_ACCEPTABLE }, { ".gmail.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE }, { "mail.google.", "GMail", NDPI_SERVICE_GMAIL, NDPI_PROTOCOL_SAFE }, + { "mail.outlook.com", "Hotmail", NDPI_SERVICE_HOTMAIL, NDPI_PROTOCOL_SAFE }, { ".last.fm", "LastFM", NDPI_SERVICE_LASTFM, NDPI_PROTOCOL_FUN }, { "msn.com", "MSN", NDPI_SERVICE_MSN, NDPI_PROTOCOL_FUN }, { "netflix.com", "NetFlix", NDPI_SERVICE_NETFLIX, NDPI_PROTOCOL_FUN }, @@ -7316,6 +7334,7 @@ ndpi_protocol_match host_match[] = { { ".yimg.com", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE }, { "yahooapis.", "Yahoo", NDPI_SERVICE_YAHOO, NDPI_PROTOCOL_ACCEPTABLE }, { "youtube.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, + { "yt3.ggpht.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, { ".googlevideo.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, { ".ytimg.com", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, { "youtube-nocookie.", "YouTube", NDPI_SERVICE_YOUTUBE, NDPI_PROTOCOL_FUN }, @@ -7323,16 +7342,18 @@ ndpi_protocol_match host_match[] = { { ".spotify.", "Spotify", NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_FUN }, { ".pandora.com", "Pandora", NDPI_SERVICE_PANDORA, NDPI_PROTOCOL_FUN }, { ".torproject.org", "Tor", NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_POTENTIALLY_DANGEROUS }, - { "appmeutim.tim.com.br", "TIM_Meu", NDPI_SERVICE_TIMMEU, NDPI_PROTOCOL_ACCEPTABLE }, - { ".timtorcedor.com.br", "Torcedor", NDPI_SERVICE_TORCEDOR, NDPI_PROTOCOL_ACCEPTABLE }, { ".kakao.com", "KakaoTalk", NDPI_SERVICE_KAKAOTALK, NDPI_PROTOCOL_FUN }, { "ttvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "static-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "www-cdn.jtvnw.net", "Twitch", NDPI_SERVICE_TWITCH, NDPI_PROTOCOL_FUN }, { "quickplay.com", "QuickPlay", NDPI_SERVICE_QUICKPLAY, NDPI_PROTOCOL_FUN }, - { "tim.com.br", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE }, - { "tim.it", "TIM", NDPI_SERVICE_TIM, NDPI_PROTOCOL_ACCEPTABLE }, { ".qq.com", "QQ", NDPI_PROTOCOL_QQ, NDPI_PROTOCOL_FUN }, + { ".weibo.com", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sinaimg.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sinajs.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sina.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + { ".sina.com.cn", "Weibo", NDPI_SERVICE_WEIBO, NDPI_PROTOCOL_FUN }, + /* https://support.cipafilter.com/index.php?/Knowledgebase/Article/View/117/0/snapchat---how-to-block */ { "feelinsonice.appspot.com", "Snapchat", NDPI_SERVICE_SNAPCHAT, NDPI_PROTOCOL_FUN }, @@ -7348,17 +7369,6 @@ ndpi_protocol_match host_match[] = { { "instagramstatic-", "Instagram", NDPI_SERVICE_INSTAGRAM, NDPI_PROTOCOL_FUN }, { ".waze.com", "Waze", NDPI_SERVICE_WAZE, NDPI_PROTOCOL_ACCEPTABLE }, - { "simet-", "Simet", NDPI_SERVICE_SIMET, NDPI_PROTOCOL_ACCEPTABLE }, - { "opensignal.com", "OpenSignal", NDPI_SERVICE_OPENSIGNAL, NDPI_PROTOCOL_ACCEPTABLE }, - { "99taxis.com", "99Taxi", NDPI_SERVICE_99TAXI, NDPI_PROTOCOL_ACCEPTABLE }, - { "easytaxis.com", "EasyTaxi", NDPI_SERVICE_EASYTAXI, NDPI_PROTOCOL_ACCEPTABLE }, - { ".globo.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE }, - { ".glbimg.com", "GloboTV", NDPI_SERVICE_GLOBOTV, NDPI_PROTOCOL_ACCEPTABLE }, - { "timsomdechamada.com.br", "SomDeChamada", NDPI_SERVICE_TIMSOMDECHAMADA, NDPI_PROTOCOL_ACCEPTABLE }, - { ".tim.acotelbr.com.br", "TIM_Menu", NDPI_SERVICE_TIMMENU, NDPI_PROTOCOL_ACCEPTABLE }, - { ".timbeta.com.br", "TIM_Beta", NDPI_SERVICE_TIMBETA, NDPI_PROTOCOL_ACCEPTABLE }, - { "tim-geoportal.geoportal3d.com.br", "TIM_PortasAbertas", NDPI_SERVICE_TIMPORTASABERTAS, NDPI_PROTOCOL_ACCEPTABLE }, - { ".m4u.com.br", "TIM_Recarga", NDPI_SERVICE_TIMRECARGA, NDPI_PROTOCOL_ACCEPTABLE }, { ".deezer.com", "Deezer", NDPI_SERVICE_DEEZER, NDPI_PROTOCOL_ACCEPTABLE }, { ".microsoft.com", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7368,6 +7378,7 @@ ndpi_protocol_match host_match[] = { { ".msecnd.net", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE }, { ".visualstudio.com", "Microsoft", NDPI_SERVICE_MICROSOFT, NDPI_PROTOCOL_ACCEPTABLE }, { "bn1301.storage.live.com", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, + { "*.gateway.messenger.live.com", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, { "skyapi.live.net", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, { "d.docs.live.net", "MS_OneDrive", NDPI_SERVICE_MS_ONE_DRIVE, NDPI_PROTOCOL_ACCEPTABLE }, { "update.microsoft.com", "WindowsUpdate", NDPI_SERVICE_WINDOWS_UPDATE, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7386,7 +7397,7 @@ ndpi_protocol_match host_match[] = { { "evsecure-ocsp.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, { "evsecure-aia.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, { "evsecure-crl.verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, - { ".omniroot.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, + { ".omniroot.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, { ".verisign.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, { ".symcb.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, { ".symcd.com", "Office365", NDPI_SERVICE_OFFICE_365, NDPI_PROTOCOL_ACCEPTABLE }, @@ -7400,7 +7411,20 @@ ndpi_protocol_match host_match[] = { { "coby.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE }, { "amanda.ns.cloudflare.com", "Cloudflare", NDPI_SERVICE_CLOUDFLARE, NDPI_PROTOCOL_ACCEPTABLE }, + { "d295hzzivaok4k.cloudfront.net", "OpenDNS", NDPI_SERVICE_OPENDNS, NDPI_PROTOCOL_ACCEPTABLE }, + { ".opendns.com", "OpenDNS", NDPI_SERVICE_OPENDNS, NDPI_PROTOCOL_ACCEPTABLE }, + /* https://get.slack.help/hc/en-us/articles/205138367-Troubleshooting-Slack-connection-issues */ + { "slack.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { ".slack-msgs.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { "slack-files.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { "slack-imgs.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { ".slack-edge.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { ".slack-core.com", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { "slack-redir.net", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + /* Detected "slack-assets2.s3-us-west-2.amazonaws.com.". Omitted "*amazonaws.com" CDN, but no generic pattern to use on first part */ + { "slack-assets2.s3-", "Slack", NDPI_SERVICE_SLACK, NDPI_PROTOCOL_ACCEPTABLE }, + { NULL, 0 } }; @@ -7525,7 +7549,7 @@ static const char *ndpi_en_bigrams[] = { static const char *ndpi_en_impossible_bigrams[] = { "bk", "bq", "bx", "cb", "cf", "cg", "cj", "cp", "cv", "cw", "cx", "dx", "fk", "fq", "fv", "fx", "ee", "fz", "gq", "gv", "gx", "hh", "hk", "hv", "hx", "hz", "iy", "jb", "jc", "jd", "jf", "jg", "jh", "jk", - "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx", + "jl", "jm", "jn", "jp", "jq", "jr", /* "js", */ "jt", "jv", "jw", "jx", "jy", "jz", "kg", "kq", "kv", "kx", "kz", "lq", "lx", "mg", "mj", "mq", "mx", "mz", "pq", "pv", "px", "qb", "qc", "qd", "qe", "qf", "ii", "qg", "qh", "qj", "qk", "ql", "qm", "qn", "qo", "qp", "qr", "qs", "qt", "qv", "qw", "qx", "qy", "uu", "qz", "sx", "sz", "tq", "tx", "vb", "vc", "vd", "vf", "vg", "vh", "vj", "vk", "vm", "vn", "vp", "bw", @@ -7533,3 +7557,4 @@ static const char *ndpi_en_impossible_bigrams[] = { "yj", "yq", "yv", "yz", "yw", "zb", "zc", "zg", "zh", "zj", "zn", "zq", "zr", "zs", "zx", "wh", "wk", "wb", "zk", "kp", "zk", "xy", NULL }; + diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 845c56c63..4224dd2d6 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -1,8 +1,7 @@ /* * ndpi_main.c * - * Copyright (C) 2011-15 - ntop.org - * Copyright (C) 2009-11 - ipoque GmbH + * Copyright (C) 2011-16 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -303,13 +302,17 @@ strncasecmp(s1, s2, n) /* Forward */ static void addDefaultPort(ndpi_port_range *range, - ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root); + ndpi_proto_defaults_t *def, + u_int8_t customUserProto, + ndpi_default_ports_tree_node_t **root); + static int removeDefaultPort(ndpi_port_range *range, - ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root); + ndpi_proto_defaults_t *def, + ndpi_default_ports_tree_node_t **root); /* ****************************************** */ -void* ndpi_malloc(size_t size) { return(_ndpi_malloc(size)); } +void* ndpi_malloc(size_t size) { return(_ndpi_malloc ? _ndpi_malloc(size) : malloc(size)); } /* ****************************************** */ @@ -325,7 +328,7 @@ void* ndpi_calloc(unsigned long count, size_t size) { /* ****************************************** */ -void ndpi_free(void *ptr) { _ndpi_free(ptr); } +void ndpi_free(void *ptr) { if(_ndpi_free) _ndpi_free(ptr); else free(ptr); } /* ****************************************** */ @@ -374,6 +377,18 @@ char* ndpi_get_proto_by_id(struct ndpi_detection_module_struct *ndpi_mod, u_int return((id >= ndpi_mod->ndpi_num_supported_protocols) ? NULL : ndpi_mod->proto_defaults[id].protoName); } +/* ****************************************************** */ + +u_int16_t ndpi_get_proto_by_name(struct ndpi_detection_module_struct *ndpi_mod, const char *name) { + u_int16_t i, num = ndpi_get_num_supported_protocols(ndpi_mod); + + for(i = 0; i < num; i++) + if(strcasecmp(ndpi_get_proto_by_id(ndpi_mod, i), name) == 0) + return(i); + + return(NDPI_PROTOCOL_UNKNOWN); +} + /* ******************************************************************** */ ndpi_port_range* ndpi_build_default_ports_range(ndpi_port_range *ports, @@ -446,8 +461,8 @@ void ndpi_set_proto_defaults(struct ndpi_detection_module_struct *ndpi_mod, memcpy(&ndpi_mod->proto_defaults[protoId].master_udp_protoId, udp_master_protoId, 2*sizeof(u_int16_t)); for(j=0; j<MAX_DEFAULT_PORTS; j++) { - if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->udpRoot); - if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], &ndpi_mod->tcpRoot); + if(udpDefPorts[j].port_low != 0) addDefaultPort(&udpDefPorts[j], &ndpi_mod->proto_defaults[protoId], 0, &ndpi_mod->udpRoot); + if(tcpDefPorts[j].port_low != 0) addDefaultPort(&tcpDefPorts[j], &ndpi_mod->proto_defaults[protoId], 0, &ndpi_mod->tcpRoot); } } @@ -480,12 +495,12 @@ void ndpi_default_ports_tree_node_t_walker(const void *node, const ndpi_VISIT wh /* ******************************************************************** */ static void addDefaultPort(ndpi_port_range *range, - ndpi_proto_defaults_t *def, ndpi_default_ports_tree_node_t **root) { + ndpi_proto_defaults_t *def, + u_int8_t customUserProto, + ndpi_default_ports_tree_node_t **root) { ndpi_default_ports_tree_node_t *ret; u_int16_t port; - // printf("[NDPI] %s(%d)\n", __FUNCTION__, port); - for(port=range->port_low; port<=range->port_high; port++) { ndpi_default_ports_tree_node_t *node = (ndpi_default_ports_tree_node_t*)ndpi_malloc(sizeof(ndpi_default_ports_tree_node_t)); @@ -494,11 +509,11 @@ static void addDefaultPort(ndpi_port_range *range, break; } - node->proto = def, node->default_port = port; + node->proto = def, node->default_port = port, node->customUserProto = customUserProto; ret = *(ndpi_default_ports_tree_node_t**)ndpi_tsearch(node, (void*)root, ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */ if(ret != node) { - printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port); + /* printf("[NDPI] %s(): found duplicate for port %u: overwriting it with new value\n", __FUNCTION__, port); */ ret->proto = def; ndpi_free(node); @@ -551,7 +566,11 @@ static int ndpi_string_to_automa(struct ndpi_detection_module_struct *ndpi_struc if(automa->ac_automa == NULL) return(-2); ac_pattern.astring = value; ac_pattern.rep.number = protocol_id; - ac_pattern.length = strlen(ac_pattern.astring); + if(value == NULL) + ac_pattern.length = 0; + else + ac_pattern.length = strlen(ac_pattern.astring); + ac_automata_add(((AC_AUTOMATA_t*)automa->ac_automa), &ac_pattern); return(0); @@ -1359,9 +1378,14 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_QUIC, no_master, - no_master, "Quic", + no_master, "QUIC", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 443, 80, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DROPBOX, + no_master, + no_master, "Dropbox", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 17500, 0, 0, 0, 0) /* UDP */); ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_EAQ, no_master, no_master, "EAQ", @@ -1451,43 +1475,43 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHOIS_DAS, no_master, no_master, "Whois-DAS", - ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 43, 4343, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_COLLECTD, no_master, no_master, "Collectd", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 25826, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SOCKS, no_master, no_master, "SOCKS", - ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 1080, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 1080, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_TFTP, no_master, no_master, "TFTP", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 69, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 69, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RTMP, no_master, no_master, "RTMP", - ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 1935, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_PANDO, no_master, no_master, "Pando_Media_Booster", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MEGACO, no_master, no_master, "Megaco", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 2944 , 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_REDIS, no_master, no_master, "Redis", - ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0) /* TCP */, - ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0) /* UDP */); + ndpi_build_default_ports(ports_a, 6379, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0 , 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ZMQ, no_master, no_master, "ZeroMQ", @@ -1506,13 +1530,13 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_UBNTAC2, no_master, no_master, "UBNTAC2", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ - ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */ + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 10001, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_MS_LYNC, no_master, no_master, "Lync", - ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_VIBER, no_master, no_master, "Viber", @@ -1523,11 +1547,32 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp no_master, "COAP", ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ ndpi_build_default_ports(ports_b, 5683, 5684, 0, 0, 0)); /* UDP */ - ndpi_set_proto_defaults(ndpi_mod,NDPI_PROTOCOL_ACCEPTABLE,NDPI_PROTOCOL_MQTT, - no_master, - no_master, "MQTT", - ndpi_build_default_ports(ports_a, 1883, 8883, 0, 0, 0), /* TCP */ - ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_MQTT, + no_master, + no_master, "MQTT", + ndpi_build_default_ports(ports_a, 1883, 8883, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_RX, + no_master, + no_master, "RX", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_GIT, + no_master, + no_master, "Git", + ndpi_build_default_ports(ports_a, 9418, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DRDA, + no_master, + no_master, "DRDA", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0), /* TCP */ + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0)); /* UDP */ + ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_SERVICE_HANGOUT, + no_master, + no_master, "GoogleHangout", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + /* calling function for host and content matched protocols */ init_string_based_protocols(ndpi_mod); @@ -1674,22 +1719,25 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp #endif -/* ******************************************************************** */ +void set_ndpi_malloc(void* (*__ndpi_malloc)(size_t size)) { _ndpi_malloc = __ndpi_malloc; } -struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_per_second, - void* (*__ndpi_malloc)(size_t size), - void (*__ndpi_free)(void *ptr), - ndpi_debug_function_ptr ndpi_debug_printf) -{ - struct ndpi_detection_module_struct *ndpi_str; +void set_ndpi_free(void (*__ndpi_free)(void *ptr)) { _ndpi_free = __ndpi_free; } - _ndpi_malloc = __ndpi_malloc; - _ndpi_free = __ndpi_free; +void set_ndpi_debug_function(ndpi_debug_function_ptr ndpi_debug_printf) { +#ifdef NDPI_ENABLE_DEBUG_MESSAGES + ndpi_str->ndpi_debug_printf = ndpi_debug_printf; +#endif +} + +/* ******************************************************************** */ - ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct)); +struct ndpi_detection_module_struct *ndpi_init_detection_module() { + struct ndpi_detection_module_struct *ndpi_str = ndpi_malloc(sizeof(struct ndpi_detection_module_struct)); if(ndpi_str == NULL) { +#ifdef NDPI_ENABLE_DEBUG_MESSAGES ndpi_debug_printf(0, NULL, NDPI_LOG_DEBUG, "ndpi_init_detection_module initial malloc failed\n"); +#endif return NULL; } memset(ndpi_str, 0, sizeof(struct ndpi_detection_module_struct)); @@ -1699,30 +1747,29 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_ NDPI_BITMASK_RESET(ndpi_str->detection_bitmask); #ifdef NDPI_ENABLE_DEBUG_MESSAGES - ndpi_str->ndpi_debug_printf = ndpi_debug_printf; ndpi_str->user_data = NULL; #endif - ndpi_str->ticks_per_second = ticks_per_second; + ndpi_str->ticks_per_second = 1000; /* ndpi_str->ticks_per_second */ ndpi_str->tcp_max_retransmission_window_size = NDPI_DEFAULT_MAX_TCP_RETRANSMISSION_WINDOW_SIZE; ndpi_str->directconnect_connection_ip_tick_timeout = - NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second; + NDPI_DIRECTCONNECT_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second; - ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->rtsp_connection_timeout = NDPI_RTSP_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->tvants_connection_timeout = NDPI_TVANTS_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->irc_timeout = NDPI_IRC_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->gnutella_timeout = NDPI_GNUTELLA_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; - ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->battlefield_timeout = NDPI_BATTLEFIELD_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; - ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ticks_per_second; + ndpi_str->thunder_timeout = NDPI_THUNDER_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; ndpi_str->yahoo_detect_http_connections = NDPI_YAHOO_DETECT_HTTP_CONNECTIONS; - ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ticks_per_second; - ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ticks_per_second; - ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ticks_per_second; - ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ticks_per_second; - ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ticks_per_second; + ndpi_str->yahoo_lan_video_timeout = NDPI_YAHOO_LAN_VIDEO_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->zattoo_connection_timeout = NDPI_ZATTOO_CONNECTION_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->jabber_stun_timeout = NDPI_JABBER_STUN_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->jabber_file_transfer_timeout = NDPI_JABBER_FT_TIMEOUT * ndpi_str->ticks_per_second; + ndpi_str->soulseek_connection_ip_tick_timeout = NDPI_SOULSEEK_CONNECTION_IP_TICK_TIMEOUT * ndpi_str->ticks_per_second; ndpi_str->ndpi_num_supported_protocols = NDPI_MAX_SUPPORTED_PROTOCOLS; ndpi_str->ndpi_num_custom_protocols = 0; @@ -1738,12 +1785,52 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(u_int32_t ticks_ /* *********************************************** */ +/* Wrappers */ +void* ndpi_init_automa() { + return(ac_automata_init(ac_match_handler)); +} + +int ndpi_add_string_to_automa(void *_automa, char *str) { + AC_PATTERN_t ac_pattern; + AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa; + + if(automa == NULL) return(-1); + + ac_pattern.astring = str; + ac_pattern.rep.number = 1; /* Dummy */ + ac_pattern.length = strlen(ac_pattern.astring); + return(ac_automata_add(automa, &ac_pattern) == ACERR_SUCCESS ? 0 : -1); +} + +void ndpi_free_automa(void *_automa) { ac_automata_release((AC_AUTOMATA_t*)_automa); } +void ndpi_finalize_automa(void *_automa) { ac_automata_finalize((AC_AUTOMATA_t*)_automa); } + +/* ****************************************************** */ + +int ndpi_match_string(void *_automa, char *string_to_match) { + int matching_protocol_id = NDPI_PROTOCOL_UNKNOWN; + AC_TEXT_t ac_input_text; + AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa; + + if((automa == NULL) + || (string_to_match == NULL) + || (string_to_match[0] == '\0')) + return(-2); + + ac_input_text.astring = string_to_match, ac_input_text.length = strlen(string_to_match); + ac_automata_search(automa, &ac_input_text, (void*)&matching_protocol_id); + ac_automata_reset(automa); + + return(matching_protocol_id > 0 ? 0 : -1); +} + +/* *********************************************** */ + static void free_ptree_data(void *data) { ; } /* ****************************************************** */ -void ndpi_exit_detection_module(struct ndpi_detection_module_struct - *ndpi_struct, void (*ndpi_free) (void *ptr)) { +void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_struct) { if(ndpi_struct != NULL) { int i; @@ -1793,11 +1880,11 @@ int ndpi_get_protocol_id_master_proto(struct ndpi_detection_module_struct *ndpi_ /* ****************************************************** */ -u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, - u_int8_t proto, u_int16_t sport, u_int16_t dport) { +static ndpi_default_ports_tree_node_t* ndpi_get_guessed_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int16_t sport, u_int16_t dport) { const void *ret; ndpi_default_ports_tree_node_t node; - + if(sport && dport) { int low = ndpi_min(sport, dport); int high = ndpi_max(sport, dport); @@ -1814,10 +1901,27 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struc ndpi_default_ports_tree_node_t_cmp); } - if(ret != NULL) { - ndpi_default_ports_tree_node_t *found = *(ndpi_default_ports_tree_node_t**)ret; + if(ret) return(*(ndpi_default_ports_tree_node_t**)ret); + } - return(found->proto->protoId); + return(NULL); +} + +/* ****************************************************** */ + +u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_struct, + u_int8_t proto, u_int16_t sport, u_int16_t dport, + u_int8_t *user_defined_proto) { + const void *ret; + ndpi_default_ports_tree_node_t node; + + *user_defined_proto = 0; /* Default */ + if(sport && dport) { + ndpi_default_ports_tree_node_t *found = ndpi_get_guessed_protocol_id(ndpi_struct, proto, sport, dport); + + if(found != NULL) { + *user_defined_proto = found->customUserProto; + return(found->proto->protoId); } } else { /* No TCP/UDP */ @@ -1871,13 +1975,13 @@ u_int ndpi_get_num_supported_protocols(struct ndpi_detection_module_struct *ndpi #ifdef WIN32 char * strsep(char **sp, char *sep) { - char *p, *s; - if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL); - s = *sp; - p = s + strcspn(s, sep); - if (*p != '\0') *p++ = '\0'; - *sp = p; - return(s); + char *p, *s; + if (sp == NULL || *sp == NULL || **sp == '\0') return(NULL); + s = *sp; + p = s + strcspn(s, sep); + if (*p != '\0') *p++ = '\0'; + *sp = p; + return(s); } #endif @@ -1970,7 +2074,7 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_mod, char* rule, if(sscanf(value, "%u-%u", (unsigned int *)&range.port_low, (unsigned int *)&range.port_high) != 2) range.port_low = range.port_high = atoi(&elem[4]); if(do_add) - addDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); + addDefaultPort(&range, def, 1 /* Custom user proto */, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); else removeDefaultPort(&range, def, is_tcp ? &ndpi_mod->tcpRoot : &ndpi_mod->udpRoot); } else if(is_ip) { @@ -2264,7 +2368,7 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n /* SSDP */ init_ssdp_dissector(ndpi_struct, &a, detection_bitmask); -/* WORLD_OF_WARCRAFT */ + /* WORLD_OF_WARCRAFT */ init_world_of_warcraft_dissector(ndpi_struct, &a, detection_bitmask); /* POSTGRES */ @@ -2495,7 +2599,19 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n /* MQTT */ init_mqtt_dissector(ndpi_struct, &a, detection_bitmask); - /* Put false-positive sensitive protocols at the end */ + /* RX */ + init_rx_dissector(ndpi_struct, &a, detection_bitmask); + + /* GIT */ + init_git_dissector(ndpi_struct, &a, detection_bitmask); + + /* HANGOUT */ + init_hangout_dissector(ndpi_struct, &a, detection_bitmask); + + /* DRDA */ + init_drda_dissector(ndpi_struct, &a, detection_bitmask); + + /*** Put false-positive sensitive protocols at the end ***/ /* SKYPE */ init_skype_dissector(ndpi_struct, &a, detection_bitmask); @@ -3154,18 +3270,35 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru u_int8_t l4_proto, struct ndpi_id_struct *src, u_int16_t sport, - struct ndpi_id_struct *dst, + struct ndpi_id_struct *dst, u_int16_t dport, + const u_int64_t current_tick_l, u_int8_t *payload, u_int16_t payload_len) { NDPI_SELECTION_BITMASK_PROTOCOL_SIZE ndpi_selection_packet; u_int32_t a; ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; + if(flow == NULL) + return(ret); + if(payload_len == 0) return(ret); flow->packet.tcp = tcp, flow->packet.udp = udp; flow->packet.payload = payload, flow->packet.payload_packet_len = payload_len; + flow->packet.tick_timestamp_l = current_tick_l; + flow->packet.tick_timestamp = (u_int32_t)current_tick_l/1000; + + if(flow) { + ndpi_apply_flow_protocol_to_packet(flow, &flow->packet); + } else { + ndpi_int_reset_packet_protocol(&flow->packet); + } + + if(flow->server_id == NULL) flow->server_id = dst; /* Default */ + if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) + goto ret_protocols; + if(src_to_dst_direction) flow->src = src, flow->dst = dst; else @@ -3179,6 +3312,8 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru ndpi_selection_packet |= NDPI_SELECTION_BITMASK_PROTOCOL_IPV6 | NDPI_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6; #endif /* NDPI_DETECTION_SUPPORT_IPV6 */ + ndpi_connection_tracking(ndpi_struct, flow); + if(flow->packet.tcp != NULL) ndpi_selection_packet |= (NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP | NDPI_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP); @@ -3196,6 +3331,28 @@ ndpi_protocol ndpi_l4_detection_process_packet(struct ndpi_detection_module_stru flow->packet.l4_protocol = l4_proto, flow->packet.packet_direction = src_to_dst_direction; + if((!flow->protocol_id_already_guessed) + && ( +#ifdef NDPI_DETECTION_SUPPORT_IPV6 + flow->packet.iphv6 || +#endif + flow->packet.iph)) { + u_int8_t user_defined_proto; + + flow->protocol_id_already_guessed = 1, + flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, l4_proto, sport, dport, &user_defined_proto); + + if(user_defined_proto && (flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)) { + ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.protocol = flow->guessed_protocol_id; + return(ret); + } + + if(flow->packet.iph) { + if((flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN) + flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->daddr); + } + } + check_ndpi_flow_func(ndpi_struct, flow, &ndpi_selection_packet); a = flow->packet.detected_protocol_stack[0]; @@ -3329,6 +3486,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct u_int16_t sport, dport; u_int8_t protocol; u_int32_t saddr, daddr; + u_int8_t user_defined_proto; flow->protocol_id_already_guessed = 1; @@ -3339,15 +3497,18 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct #endif { protocol = flow->packet.iph->protocol; - saddr = ntohl(flow->packet.iph->saddr); - daddr = ntohl(flow->packet.iph->daddr); } if(flow->packet.udp) sport = ntohs(flow->packet.udp->source), dport = ntohs(flow->packet.udp->dest); else if(flow->packet.tcp) sport = ntohs(flow->packet.tcp->source), dport = ntohs(flow->packet.tcp->dest); else sport = dport = 0; - flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport); + flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, protocol, sport, dport, &user_defined_proto); + + if(user_defined_proto && (flow->guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN)) { + ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.protocol = flow->guessed_protocol_id; + return(ret); + } if(flow->packet.iph) { if((flow->guessed_host_protocol_id = ndpi_network_ptree_match(ndpi_struct, (struct in_addr *)&flow->packet.iph->saddr)) == NDPI_PROTOCOL_UNKNOWN) @@ -4182,12 +4343,14 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct unsigned int rc; struct in_addr addr; ndpi_protocol ret = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; + u_int8_t user_defined_proto; if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) { rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, proto, shost, dhost, sport, dport); + if(rc != NDPI_PROTOCOL_UNKNOWN) { ret.protocol = rc, - ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); + ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto); if(ret.protocol == ret.master_protocol) ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; @@ -4195,7 +4358,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct return(ret); } - rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); + rc = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto); if(rc != NDPI_PROTOCOL_UNKNOWN) { ret.protocol = rc; @@ -4219,7 +4382,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct ret.protocol = NDPI_PROTOCOL_SKYPE; } } else - ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport); + ret.protocol = ndpi_guess_protocol_id(ndpi_struct, proto, sport, dport, &user_defined_proto); return(ret); } @@ -4339,6 +4502,16 @@ char* ndpi_strnstr(const char *s, const char *find, size_t slen) { /* ****************************************************** */ +int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len, + const char *str, size_t str_len) +{ + return str_len <= payload_len + ? memcmp(payload, str, str_len) == 0 + : 0; +} + +/* ****************************************************** */ + int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_struct, char *string_to_match, u_int string_to_match_len, u_int8_t is_host_match) { @@ -4369,7 +4542,6 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str u_int8_t is_host_match) { int matching_protocol_id = ndpi_match_string_subprotocol(ndpi_struct, string_to_match, string_to_match_len, is_host_match); struct ndpi_packet_struct *packet = &flow->packet; - AC_TEXT_t ac_input_text; #ifdef DEBUG { @@ -4465,25 +4637,6 @@ char* ndpi_revision() { return(NDPI_GIT_RELEASE); } #ifdef WIN32 -/* - int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) { - unused = NULL; - *mutex = CreateMutex(NULL, FALSE, NULL); - return *mutex == NULL ? -1 : 0; - } - - int pthread_mutex_destroy(pthread_mutex_t *mutex) { - return CloseHandle(*mutex) == 0 ? -1 : 0; - } - - int pthread_mutex_lock(pthread_mutex_t *mutex) { - return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; - } - - int pthread_mutex_unlock(pthread_mutex_t *mutex) { - return ReleaseMutex(*mutex) == 0 ? -1 : 0; - } -*/ /* http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/port/gettimeofday.c;h=75a91993b74414c0a1c13a2a09ce739cb8aa8a08;hb=HEAD */ int gettimeofday(struct timeval * tp, struct timezone * tzp) { /* FILETIME of Jan 1 1970 00:00:00. */ diff --git a/src/lib/protocols/bgp.c b/src/lib/protocols/bgp.c index 8f293b611..e72fdee57 100644 --- a/src/lib/protocols/bgp.c +++ b/src/lib/protocols/bgp.c @@ -35,23 +35,23 @@ static void ndpi_int_bgp_add_connection(struct ndpi_detection_module_struct *ndp /* this detection also works asymmetrically */ void ndpi_search_bgp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; - -// struct ndpi_id_struct *src=ndpi_struct->src; -// struct ndpi_id_struct *dst=ndpi_struct->dst; + struct ndpi_packet_struct *packet = &flow->packet; + u_int16_t bgp_port = htons(179); - if (packet->payload_packet_len > 18 && - get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL && - get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL && - ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len && - (packet->tcp->dest == htons(179) || packet->tcp->source == htons(179)) - && packet->payload[18] < 5) { - NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n"); - ndpi_int_bgp_add_connection(ndpi_struct, flow); - return; - } + if(packet->tcp + && (packet->payload_packet_len > 18) + && (packet->payload[18] < 5) + && ((packet->tcp->dest == bgp_port) || (packet->tcp->source == bgp_port)) + && (get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL) + && (get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL) + && (ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len) + ) { + NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n"); + ndpi_int_bgp_add_connection(ndpi_struct, flow); + return; + } - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP); } diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c index 8213d3b45..0eebe07ee 100644 --- a/src/lib/protocols/bittorrent.c +++ b/src/lib/protocols/bittorrent.c @@ -53,8 +53,7 @@ static u_int8_t is_utp_pkt(const u_int8_t *payload, u_int payload_len) { static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, int bt_offset, int check_hash, - const u_int8_t save_detection, const u_int8_t encrypted_connection/* , */ - /* ndpi_protocol_type_t protocol_type */) + const u_int8_t save_detection, const u_int8_t encrypted_connection) { if(check_hash) { const char *bt_hash = NULL; /* 20 bytes long */ @@ -92,8 +91,7 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, 19, 1, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION/* , */ - /* NDPI_REAL_PROTOCOL */); + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return 1; } } @@ -125,8 +123,7 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module NDPI_LOG(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain Bitcomet persistent seed protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 1, - NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION/* , */ - /* NDPI_CORRELATED_PROTOCOL */); + NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION); return 1; } @@ -135,7 +132,6 @@ static u_int8_t ndpi_int_search_bittorrent_tcp_zero(struct ndpi_detection_module || memcmp(packet->payload, "POST ", 5) == 0)) { const u_int8_t *ptr = &packet->payload[4]; u_int16_t len = packet->payload_packet_len - 4; - a = 0; /* parse complete get packet here into line structure elements */ diff --git a/src/lib/protocols/coap.c b/src/lib/protocols/coap.c index cddf31b7e..5f8e97863 100644 --- a/src/lib/protocols/coap.c +++ b/src/lib/protocols/coap.c @@ -72,7 +72,7 @@ struct ndpi_coap_hdr [164] = "5.04 Gateway Timeout", [165] = "5.05 Proxying Not Supported" **/ - + /** * Entry point when protocol is identified. @@ -84,6 +84,20 @@ static void ndpi_int_coap_add_connection (struct ndpi_detection_module_struct *n } /** + * Check if the default port is acceptable + * + * UDP Port 5683 (mandatory) + * UDP Ports 61616-61631 compressed 6lowPAN + */ +static int isCoAPport(u_int16_t port) { + if((port == 5683) + || ((port >= 61616) && (port <= 61631))) + return(1); + else + return(0); +} + +/** * Dissector function that searches CoAP headers */ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct, @@ -91,22 +105,24 @@ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct, { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_coap_hdr * h = (struct ndpi_coap_hdr*) packet->payload; - + if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { return; } // search for udp packet if(packet->udp != NULL) { - - // header too short - if(packet->payload_packet_len < 4) { - + u_int16_t s_port = ntohs(flow->packet.udp->source); + u_int16_t d_port = ntohs(flow->packet.udp->dest); + + if((!isCoAPport(s_port) && !isCoAPport(s_port)) + || (packet->payload_packet_len < 4) // header too short + ) { NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "excluding Coap\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP); return; } - + NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "calculating coap over udp.\n"); // check values in header @@ -116,21 +132,21 @@ void ndpi_search_coap (struct ndpi_detection_module_struct *ndpi_struct, if((h->code >= 0 && h->code <= 5) || (h->code >= 65 && h->code <= 69) || (h->code >= 128 && h->code <= 134) || (h->code >= 140 && h->code <= 143) || (h->code >= 160 && h->code <= 165)) { - + NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Coap found...\n"); ndpi_int_coap_add_connection(ndpi_struct,flow); return; } } } - } + } } - + NDPI_LOG(NDPI_PROTOCOL_COAP, ndpi_struct, NDPI_LOG_DEBUG, "Excluding Coap ...\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_COAP); return; - } + /** * Entry point for the ndpi library */ diff --git a/src/lib/protocols/dcerpc.c b/src/lib/protocols/dcerpc.c index ec96d1287..7be8ac027 100644 --- a/src/lib/protocols/dcerpc.c +++ b/src/lib/protocols/dcerpc.c @@ -36,13 +36,11 @@ void ndpi_search_dcerpc(struct ndpi_detection_module_struct *ndpi_struct, struct { struct ndpi_packet_struct *packet = &flow->packet; - u_int16_t len_packet = (packet->payload[9]<<8) | packet->payload[8]; - if((packet->tcp != NULL) && (packet->payload_packet_len >= 64) && (packet->payload[0] == 0x05) /* version 5 */ && (packet->payload[2] < 16) /* Packet type */ - && (len_packet == packet->payload_packet_len) /* Packet Length */ + && (((packet->payload[9]<<8) | packet->payload[8]) == packet->payload_packet_len) /* Packet Length */ ) { NDPI_LOG(NDPI_PROTOCOL_DCERPC, ndpi_struct, NDPI_LOG_DEBUG, "DCERPC match\n"); ndpi_int_dcerpc_add_connection(ndpi_struct, flow); diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c index 8ffc04d51..e33a7c011 100644 --- a/src/lib/protocols/dhcp.c +++ b/src/lib/protocols/dhcp.c @@ -1,8 +1,7 @@ /* * dhcp.c * - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2016 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -43,16 +42,18 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru /* this detection also works for asymmetric dhcp traffic */ /*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */ - if (packet->payload_packet_len >= 244 && (packet->udp->source == htons(67) - || packet->udp->source == htons(68)) - && (packet->udp->dest == htons(67) || packet->udp->dest == htons(68)) - && get_u_int32_t(packet->payload, 236) == htonl(0x63825363) - && get_u_int16_t(packet->payload, 240) == htons(0x3501)) { - - NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n"); - - ndpi_int_dhcp_add_connection(ndpi_struct, flow); - return; + if(packet->udp) { + if(packet->payload_packet_len >= 244 && + (packet->udp->source == htons(67) || packet->udp->source == htons(68)) && + (packet->udp->dest == htons(67) || packet->udp->dest == htons(68)) && + get_u_int32_t(packet->payload, 236) == htonl(0x63825363) && + get_u_int16_t(packet->payload, 240) == htons(0x3501)) { + + NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n"); + + ndpi_int_dhcp_add_connection(ndpi_struct, flow); + return; + } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCP); diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 503761137..5358cc8b7 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -3,8 +3,6 @@ * * Copyright (C) 2012-16 - ntop.org * - * Michele Campus - <campus@ntop.org> - * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH * @@ -29,37 +27,60 @@ #define FLAGS_MASK 0x8000 -void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ +/* #define DNS_DEBUG 1 */ + +/* *********************************************** */ + +static u_int16_t get16(int *i, const u_int8_t *payload) { + u_int16_t v = *(u_int16_t*)&payload[*i]; + + (*i) += 2; + + return(ntohs(v)); +} + +/* *********************************************** */ + +static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) { + if(payload[i] == 0x00) + return(1); + else if(payload[i] == 0xC0) + return(2); + else { + u_int8_t len = payload[i]; + u_int8_t off = len + 1; + + if(off == 0) /* Bad packet */ + return(0); + else + return(off + getNameLength(i+off, payload, payloadLen)); + } +} + +/* *********************************************** */ +void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { int x; - u_int8_t is_query, ret_code; - u_int16_t s_port = 0; - u_int16_t d_port = 0; + u_int8_t is_query; + u_int16_t s_port = 0, d_port = 0; NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n"); - if(flow->packet.udp != NULL) - { + if(flow->packet.udp != NULL) { s_port = ntohs(flow->packet.udp->source); d_port = ntohs(flow->packet.udp->dest); x = 0; - } - else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ - { + } else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ { s_port = ntohs(flow->packet.tcp->source); d_port = ntohs(flow->packet.tcp->dest); x = 2; - } - else - { + } else { NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); } if((s_port == 53 || d_port == 53 || d_port == 5355) - && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header))) - { + && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+x)) { struct ndpi_dns_packet_header dns_header; int invalid = 0; @@ -70,12 +91,13 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd dns_header.num_answers = ntohs(dns_header.num_answers); dns_header.authority_rrs = ntohs(dns_header.authority_rrs); dns_header.additional_rrs = ntohs(dns_header.additional_rrs); + x += sizeof(struct ndpi_dns_packet_header); /* 0x0000 QUERY */ if((dns_header.flags & FLAGS_MASK) == 0x0000) is_query = 1; /* 0x8000 RESPONSE */ - else if((dns_header.flags & FLAGS_MASK) != 0x8000) + else if((dns_header.flags & FLAGS_MASK) == 0x8000) is_query = 0; else invalid = 1; @@ -87,69 +109,129 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd && (((dns_header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */) || ((dns_header.num_answers == 0) && (dns_header.authority_rrs == 0)))) { /* This is a good query */ + + if(dns_header.num_queries > 0) { + while(x < flow->packet.payload_packet_len) { + if(flow->packet.payload[x] == '\0') { + x++; + flow->protos.dns.query_type = get16(&x, flow->packet.payload); +#ifdef DNS_DEBUG + printf("[%s:%d] query_type=%2d\n", __FILE__, __LINE__, flow->protos.dns.query_type); +#endif + break; + } else + x++; + } + } } else invalid = 1; + } else { /* DNS Reply */ + + flow->protos.dns.reply_code = dns_header.flags & 0x0F; + if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */ && (((dns_header.num_answers > 0) && (dns_header.num_answers <= NDPI_MAX_DNS_REQUESTS)) || ((dns_header.authority_rrs > 0) && (dns_header.authority_rrs <= NDPI_MAX_DNS_REQUESTS)) || ((dns_header.additional_rrs > 0) && (dns_header.additional_rrs <= NDPI_MAX_DNS_REQUESTS))) ) { /* This is a good reply */ - } else - invalid = 1; + if(ndpi_struct->dns_dissect_response) { + x++; + + if(flow->packet.payload[x] != '\0') { + while((x < flow->packet.payload_packet_len) + && (flow->packet.payload[x] != '\0')) { + x++; + } + + x++; + } + + x += 4; + + if(dns_header.num_answers > 0) { + u_int16_t rsp_type; + u_int16_t num; + + for(num = 0; num < dns_header.num_answers; num++) { + u_int16_t data_len; + + if((x+6) >= flow->packet.payload_packet_len) { + break; + } + + if((data_len = getNameLength(x, flow->packet.payload, flow->packet.payload_packet_len)) == 0) { + break; + } else + x += data_len; + + rsp_type = get16(&x, flow->packet.payload); + flow->protos.dns.rsp_type = rsp_type; + break; + } + } + } + } } - } - if(invalid) { - NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); - return; - } + if(invalid) { + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); + return; + } - /* extract host name server */ - ret_code = (is_query == 0) ? 0 : (dns_header.flags & 0x0F); - int j = 0; - int off = sizeof(struct ndpi_dns_packet_header) + 1; - while((flow->packet.payload[off] != '\0')) - { - if(off < flow->packet.payload_packet_len) - { + /* extract host name server */ + int j = 0, max_len = sizeof(flow->host_server_name)-1, off = sizeof(struct ndpi_dns_packet_header) + 1; + + while(off < flow->packet.payload_packet_len && flow->packet.payload[off] != '\0') { flow->host_server_name[j] = flow->packet.payload[off]; - if(j < strlen(flow->host_server_name)) - { + if(j < max_len) { if(flow->host_server_name[j] < ' ') flow->host_server_name[j] = '.'; j++; - } + } else + break; + off++; } - } - flow->host_server_name[j] = '\0'; - flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs); - flow->protos.dns.ret_code = ret_code; + flow->host_server_name[j] = '\0'; + + flow->protos.dns.num_queries = (u_int8_t)dns_header.num_queries, + flow->protos.dns.num_answers = (u_int8_t) (dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs); + + if(j > 0) + ndpi_match_host_subprotocol(ndpi_struct, flow, + (char *)flow->host_server_name, + strlen((const char*)flow->host_server_name), + NDPI_PROTOCOL_DNS); - if(j > 0) - ndpi_match_host_subprotocol(ndpi_struct, flow, - (char *)flow->host_server_name, - strlen((const char*)flow->host_server_name), - NDPI_PROTOCOL_DNS); +#ifdef DNS_DEBUG + printf("[%s:%d] [num_queries=%d][num_answers=%d][reply_code=%u][rsp_type=%u][host_server_name=%s]\n", + __FILE__, __LINE__, + flow->protos.dns.num_queries, flow->protos.dns.num_answers, + flow->protos.dns.reply_code, flow->protos.dns.rsp_type, flow->host_server_name + ); +#endif - if(flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) - { - /** - Do not set the protocol with DNS if ndpi_match_host_subprotocol() has - matched a subprotocol - **/ - NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); - } else { - NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); + if(flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { + if(is_query && ndpi_struct->dns_dissect_response) + return; /* The response will set the verdict */ + + /** + Do not set the protocol with DNS if ndpi_match_host_subprotocol() has + matched a subprotocol + **/ + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN); + } else { + NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS); + } } - } + } } void init_dns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) diff --git a/src/lib/protocols/drda.c b/src/lib/protocols/drda.c new file mode 100644 index 000000000..fe75379ff --- /dev/null +++ b/src/lib/protocols/drda.c @@ -0,0 +1,106 @@ +/* + * drda.c + * + * Copyright (C) 2012-16 - ntop.org + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_DRDA + +#define DRDA_PORT 50000 + +struct ndpi_drda_hdr { + u_int16_t length; + u_int8_t magic; + u_int8_t format; + u_int16_t correlID; + u_int16_t length2; + u_int16_t code_pnt; +}; + + +void ndpi_search_drda(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct * packet = &flow->packet; + u_int16_t payload_len = packet->payload_packet_len; + u_int count = 0; // prevent integer overflow + + if(packet->tcp != NULL) { + + /* check port */ + if((ntohs(packet->tcp->source) == DRDA_PORT || + ntohs(packet->tcp->dest) == DRDA_PORT) && + payload_len >= sizeof(struct ndpi_drda_hdr)) { + + struct ndpi_drda_hdr * drda = (struct ndpi_drda_hdr *) packet->payload; + + u_int16_t len = ntohs(drda->length); + + /* check first header */ + if(len != ntohs(drda->length2) + 6 || + drda->magic != 0xd0) + goto no_drda; + + /* check if there are more drda headers */ + if(payload_len > len) { + + count = len; + + while(count + sizeof(struct ndpi_drda_hdr) < payload_len) + { + /* update info */ + drda = (struct ndpi_drda_hdr *)(packet->payload + count); + len = ntohs(drda->length); + + if(len != ntohs(drda->length2) + 6 || + drda->magic != 0xd0) + goto no_drda; + + count += len; + } + if(count != payload_len) goto no_drda; + } + NDPI_LOG(NDPI_PROTOCOL_DRDA, ndpi_struct, NDPI_LOG_DEBUG, "found DRDA.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DRDA, NDPI_PROTOCOL_UNKNOWN); + return; + } + } + + no_drda: + NDPI_LOG(NDPI_PROTOCOL_DRDA, ndpi_struct, NDPI_LOG_DEBUG, "exclude DRDA.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DRDA); +} + + +/* ***************************************************************** */ + + +void init_drda_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) +{ + ndpi_set_bitmask_protocol_detection("DRDA", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_DRDA, + ndpi_search_drda, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif /* NDPI_PROTOCOL_DRDA */ diff --git a/src/lib/protocols/dropbox.c b/src/lib/protocols/dropbox.c index f51de95d2..d8babfb1b 100644 --- a/src/lib/protocols/dropbox.c +++ b/src/lib/protocols/dropbox.c @@ -1,7 +1,7 @@ /* * dropbox.c * - * Copyright (C) 2011-13 by ntop.org + * Copyright (C) 2012-16 by ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -44,7 +44,6 @@ static void ndpi_check_dropbox(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t payload_len = packet->payload_packet_len; if(packet->udp != NULL) { - u_int16_t dropbox_port = htons(DB_LSP_PORT); if((packet->udp->source == dropbox_port) diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c index 8710096be..9bc2bf904 100644 --- a/src/lib/protocols/ftp_control.c +++ b/src/lib/protocols/ftp_control.c @@ -30,904 +30,904 @@ static void ndpi_int_ftp_control_add_connection(struct ndpi_detection_module_str ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_FTP_CONTROL, NDPI_PROTOCOL_UNKNOWN); } -static int ndpi_ftp_control_check_request(const u_int8_t *payload) { +static int ndpi_ftp_control_check_request(const u_int8_t *payload, size_t payload_len) { - if (match_first_bytes(payload, "ABOR")) { + if (ndpi_match_strprefix(payload, payload_len, "ABOR")) { return 1; } - if (match_first_bytes(payload, "ACCT")) { + if (ndpi_match_strprefix(payload, payload_len, "ACCT")) { return 1; } - if (match_first_bytes(payload, "ADAT")) { + if (ndpi_match_strprefix(payload, payload_len, "ADAT")) { return 1; } - if (match_first_bytes(payload, "ALLO")) { + if (ndpi_match_strprefix(payload, payload_len, "ALLO")) { return 1; } - if (match_first_bytes(payload, "APPE")) { + if (ndpi_match_strprefix(payload, payload_len, "APPE")) { return 1; } - if (match_first_bytes(payload, "AUTH")) { + if (ndpi_match_strprefix(payload, payload_len, "AUTH")) { return 1; } - if (match_first_bytes(payload, "CCC")) { + if (ndpi_match_strprefix(payload, payload_len, "CCC")) { return 1; } - if (match_first_bytes(payload, "CDUP")) { + if (ndpi_match_strprefix(payload, payload_len, "CDUP")) { return 1; } - if (match_first_bytes(payload, "CONF")) { + if (ndpi_match_strprefix(payload, payload_len, "CONF")) { return 1; } - if (match_first_bytes(payload, "CWD")) { + if (ndpi_match_strprefix(payload, payload_len, "CWD")) { return 1; } - if (match_first_bytes(payload, "DELE")) { + if (ndpi_match_strprefix(payload, payload_len, "DELE")) { return 1; } - if (match_first_bytes(payload, "ENC")) { + if (ndpi_match_strprefix(payload, payload_len, "ENC")) { return 1; } - if (match_first_bytes(payload, "EPRT")) { + if (ndpi_match_strprefix(payload, payload_len, "EPRT")) { return 1; } - if (match_first_bytes(payload, "EPSV")) { + if (ndpi_match_strprefix(payload, payload_len, "EPSV")) { return 1; } - if (match_first_bytes(payload, "FEAT")) { + if (ndpi_match_strprefix(payload, payload_len, "FEAT")) { return 1; } - if (match_first_bytes(payload, "HELP")) { + if (ndpi_match_strprefix(payload, payload_len, "HELP")) { return 1; } - if (match_first_bytes(payload, "LANG")) { + if (ndpi_match_strprefix(payload, payload_len, "LANG")) { return 1; } - if (match_first_bytes(payload, "LIST")) { + if (ndpi_match_strprefix(payload, payload_len, "LIST")) { return 1; } - if (match_first_bytes(payload, "LPRT")) { + if (ndpi_match_strprefix(payload, payload_len, "LPRT")) { return 1; } - if (match_first_bytes(payload, "LPSV")) { + if (ndpi_match_strprefix(payload, payload_len, "LPSV")) { return 1; } - if (match_first_bytes(payload, "MDTM")) { + if (ndpi_match_strprefix(payload, payload_len, "MDTM")) { return 1; } - if (match_first_bytes(payload, "MIC")) { + if (ndpi_match_strprefix(payload, payload_len, "MIC")) { return 1; } - if (match_first_bytes(payload, "MKD")) { + if (ndpi_match_strprefix(payload, payload_len, "MKD")) { return 1; } - if (match_first_bytes(payload, "MLSD")) { + if (ndpi_match_strprefix(payload, payload_len, "MLSD")) { return 1; } - if (match_first_bytes(payload, "MLST")) { + if (ndpi_match_strprefix(payload, payload_len, "MLST")) { return 1; } - if (match_first_bytes(payload, "MODE")) { + if (ndpi_match_strprefix(payload, payload_len, "MODE")) { return 1; } - if (match_first_bytes(payload, "NLST")) { + if (ndpi_match_strprefix(payload, payload_len, "NLST")) { return 1; } - if (match_first_bytes(payload, "NOOP")) { + if (ndpi_match_strprefix(payload, payload_len, "NOOP")) { return 1; } - if (match_first_bytes(payload, "OPTS")) { + if (ndpi_match_strprefix(payload, payload_len, "OPTS")) { return 1; } - if (match_first_bytes(payload, "PASS")) { + if (ndpi_match_strprefix(payload, payload_len, "PASS")) { return 1; } - if (match_first_bytes(payload, "PASV")) { + if (ndpi_match_strprefix(payload, payload_len, "PASV")) { return 1; } - if (match_first_bytes(payload, "PBSZ")) { + if (ndpi_match_strprefix(payload, payload_len, "PBSZ")) { return 1; } - if (match_first_bytes(payload, "PORT")) { + if (ndpi_match_strprefix(payload, payload_len, "PORT")) { return 1; } - if (match_first_bytes(payload, "PROT")) { + if (ndpi_match_strprefix(payload, payload_len, "PROT")) { return 1; } - if (match_first_bytes(payload, "PWD")) { + if (ndpi_match_strprefix(payload, payload_len, "PWD")) { return 1; } - if (match_first_bytes(payload, "QUIT")) { + if (ndpi_match_strprefix(payload, payload_len, "QUIT")) { return 1; } - if (match_first_bytes(payload, "REIN")) { + if (ndpi_match_strprefix(payload, payload_len, "REIN")) { return 1; } - if (match_first_bytes(payload, "REST")) { + if (ndpi_match_strprefix(payload, payload_len, "REST")) { return 1; } - if (match_first_bytes(payload, "RETR")) { + if (ndpi_match_strprefix(payload, payload_len, "RETR")) { return 1; } - if (match_first_bytes(payload, "RMD")) { + if (ndpi_match_strprefix(payload, payload_len, "RMD")) { return 1; } - if (match_first_bytes(payload, "RNFR")) { + if (ndpi_match_strprefix(payload, payload_len, "RNFR")) { return 1; } - if (match_first_bytes(payload, "RNTO")) { + if (ndpi_match_strprefix(payload, payload_len, "RNTO")) { return 1; } - if (match_first_bytes(payload, "SITE")) { + if (ndpi_match_strprefix(payload, payload_len, "SITE")) { return 1; } - if (match_first_bytes(payload, "SIZE")) { + if (ndpi_match_strprefix(payload, payload_len, "SIZE")) { return 1; } - if (match_first_bytes(payload, "SMNT")) { + if (ndpi_match_strprefix(payload, payload_len, "SMNT")) { return 1; } - if (match_first_bytes(payload, "STAT")) { + if (ndpi_match_strprefix(payload, payload_len, "STAT")) { return 1; } - if (match_first_bytes(payload, "STOR")) { + if (ndpi_match_strprefix(payload, payload_len, "STOR")) { return 1; } - if (match_first_bytes(payload, "STOU")) { + if (ndpi_match_strprefix(payload, payload_len, "STOU")) { return 1; } - if (match_first_bytes(payload, "STRU")) { + if (ndpi_match_strprefix(payload, payload_len, "STRU")) { return 1; } - if (match_first_bytes(payload, "SYST")) { + if (ndpi_match_strprefix(payload, payload_len, "SYST")) { return 1; } - if (match_first_bytes(payload, "TYPE")) { + if (ndpi_match_strprefix(payload, payload_len, "TYPE")) { return 1; } - if (match_first_bytes(payload, "USER")) { + if (ndpi_match_strprefix(payload, payload_len, "USER")) { return 1; } - if (match_first_bytes(payload, "XCUP")) { + if (ndpi_match_strprefix(payload, payload_len, "XCUP")) { return 1; } - if (match_first_bytes(payload, "XMKD")) { + if (ndpi_match_strprefix(payload, payload_len, "XMKD")) { return 1; } - if (match_first_bytes(payload, "XPWD")) { + if (ndpi_match_strprefix(payload, payload_len, "XPWD")) { return 1; } - if (match_first_bytes(payload, "XRCP")) { + if (ndpi_match_strprefix(payload, payload_len, "XRCP")) { return 1; } - if (match_first_bytes(payload, "XRMD")) { + if (ndpi_match_strprefix(payload, payload_len, "XRMD")) { return 1; } - if (match_first_bytes(payload, "XRSQ")) { + if (ndpi_match_strprefix(payload, payload_len, "XRSQ")) { return 1; } - if (match_first_bytes(payload, "XSEM")) { + if (ndpi_match_strprefix(payload, payload_len, "XSEM")) { return 1; } - if (match_first_bytes(payload, "XSEN")) { + if (ndpi_match_strprefix(payload, payload_len, "XSEN")) { return 1; } - if (match_first_bytes(payload, "HOST")) { + if (ndpi_match_strprefix(payload, payload_len, "HOST")) { return 1; } - if (match_first_bytes(payload, "abor")) { + if (ndpi_match_strprefix(payload, payload_len, "abor")) { return 1; } - if (match_first_bytes(payload, "acct")) { + if (ndpi_match_strprefix(payload, payload_len, "acct")) { return 1; } - if (match_first_bytes(payload, "adat")) { + if (ndpi_match_strprefix(payload, payload_len, "adat")) { return 1; } - if (match_first_bytes(payload, "allo")) { + if (ndpi_match_strprefix(payload, payload_len, "allo")) { return 1; } - if (match_first_bytes(payload, "appe")) { + if (ndpi_match_strprefix(payload, payload_len, "appe")) { return 1; } - if (match_first_bytes(payload, "auth")) { + if (ndpi_match_strprefix(payload, payload_len, "auth")) { return 1; } - if (match_first_bytes(payload, "ccc")) { + if (ndpi_match_strprefix(payload, payload_len, "ccc")) { return 1; } - if (match_first_bytes(payload, "cdup")) { + if (ndpi_match_strprefix(payload, payload_len, "cdup")) { return 1; } - if (match_first_bytes(payload, "conf")) { + if (ndpi_match_strprefix(payload, payload_len, "conf")) { return 1; } - if (match_first_bytes(payload, "cwd")) { + if (ndpi_match_strprefix(payload, payload_len, "cwd")) { return 1; } - if (match_first_bytes(payload, "dele")) { + if (ndpi_match_strprefix(payload, payload_len, "dele")) { return 1; } - if (match_first_bytes(payload, "enc")) { + if (ndpi_match_strprefix(payload, payload_len, "enc")) { return 1; } - if (match_first_bytes(payload, "eprt")) { + if (ndpi_match_strprefix(payload, payload_len, "eprt")) { return 1; } - if (match_first_bytes(payload, "epsv")) { + if (ndpi_match_strprefix(payload, payload_len, "epsv")) { return 1; } - if (match_first_bytes(payload, "feat")) { + if (ndpi_match_strprefix(payload, payload_len, "feat")) { return 1; } - if (match_first_bytes(payload, "help")) { + if (ndpi_match_strprefix(payload, payload_len, "help")) { return 1; } - if (match_first_bytes(payload, "lang")) { + if (ndpi_match_strprefix(payload, payload_len, "lang")) { return 1; } - if (match_first_bytes(payload, "list")) { + if (ndpi_match_strprefix(payload, payload_len, "list")) { return 1; } - if (match_first_bytes(payload, "lprt")) { + if (ndpi_match_strprefix(payload, payload_len, "lprt")) { return 1; } - if (match_first_bytes(payload, "lpsv")) { + if (ndpi_match_strprefix(payload, payload_len, "lpsv")) { return 1; } - if (match_first_bytes(payload, "mdtm")) { + if (ndpi_match_strprefix(payload, payload_len, "mdtm")) { return 1; } - if (match_first_bytes(payload, "mic")) { + if (ndpi_match_strprefix(payload, payload_len, "mic")) { return 1; } - if (match_first_bytes(payload, "mkd")) { + if (ndpi_match_strprefix(payload, payload_len, "mkd")) { return 1; } - if (match_first_bytes(payload, "mlsd")) { + if (ndpi_match_strprefix(payload, payload_len, "mlsd")) { return 1; } - if (match_first_bytes(payload, "mlst")) { + if (ndpi_match_strprefix(payload, payload_len, "mlst")) { return 1; } - if (match_first_bytes(payload, "mode")) { + if (ndpi_match_strprefix(payload, payload_len, "mode")) { return 1; } - if (match_first_bytes(payload, "nlst")) { + if (ndpi_match_strprefix(payload, payload_len, "nlst")) { return 1; } - if (match_first_bytes(payload, "noop")) { + if (ndpi_match_strprefix(payload, payload_len, "noop")) { return 1; } - if (match_first_bytes(payload, "opts")) { + if (ndpi_match_strprefix(payload, payload_len, "opts")) { return 1; } - if (match_first_bytes(payload, "pass")) { + if (ndpi_match_strprefix(payload, payload_len, "pass")) { return 1; } - if (match_first_bytes(payload, "pasv")) { + if (ndpi_match_strprefix(payload, payload_len, "pasv")) { return 1; } - if (match_first_bytes(payload, "pbsz")) { + if (ndpi_match_strprefix(payload, payload_len, "pbsz")) { return 1; } - if (match_first_bytes(payload, "port")) { + if (ndpi_match_strprefix(payload, payload_len, "port")) { return 1; } - if (match_first_bytes(payload, "prot")) { + if (ndpi_match_strprefix(payload, payload_len, "prot")) { return 1; } - if (match_first_bytes(payload, "pwd")) { + if (ndpi_match_strprefix(payload, payload_len, "pwd")) { return 1; } - if (match_first_bytes(payload, "quit")) { + if (ndpi_match_strprefix(payload, payload_len, "quit")) { return 1; } - if (match_first_bytes(payload, "rein")) { + if (ndpi_match_strprefix(payload, payload_len, "rein")) { return 1; } - if (match_first_bytes(payload, "rest")) { + if (ndpi_match_strprefix(payload, payload_len, "rest")) { return 1; } - if (match_first_bytes(payload, "retr")) { + if (ndpi_match_strprefix(payload, payload_len, "retr")) { return 1; } - if (match_first_bytes(payload, "rmd")) { + if (ndpi_match_strprefix(payload, payload_len, "rmd")) { return 1; } - if (match_first_bytes(payload, "rnfr")) { + if (ndpi_match_strprefix(payload, payload_len, "rnfr")) { return 1; } - if (match_first_bytes(payload, "rnto")) { + if (ndpi_match_strprefix(payload, payload_len, "rnto")) { return 1; } - if (match_first_bytes(payload, "site")) { + if (ndpi_match_strprefix(payload, payload_len, "site")) { return 1; } - if (match_first_bytes(payload, "size")) { + if (ndpi_match_strprefix(payload, payload_len, "size")) { return 1; } - if (match_first_bytes(payload, "smnt")) { + if (ndpi_match_strprefix(payload, payload_len, "smnt")) { return 1; } - if (match_first_bytes(payload, "stat")) { + if (ndpi_match_strprefix(payload, payload_len, "stat")) { return 1; } - if (match_first_bytes(payload, "stor")) { + if (ndpi_match_strprefix(payload, payload_len, "stor")) { return 1; } - if (match_first_bytes(payload, "stou")) { + if (ndpi_match_strprefix(payload, payload_len, "stou")) { return 1; } - if (match_first_bytes(payload, "stru")) { + if (ndpi_match_strprefix(payload, payload_len, "stru")) { return 1; } - if (match_first_bytes(payload, "syst")) { + if (ndpi_match_strprefix(payload, payload_len, "syst")) { return 1; } - if (match_first_bytes(payload, "type")) { + if (ndpi_match_strprefix(payload, payload_len, "type")) { return 1; } - if (match_first_bytes(payload, "user")) { + if (ndpi_match_strprefix(payload, payload_len, "user")) { return 1; } - if (match_first_bytes(payload, "xcup")) { + if (ndpi_match_strprefix(payload, payload_len, "xcup")) { return 1; } - if (match_first_bytes(payload, "xmkd")) { + if (ndpi_match_strprefix(payload, payload_len, "xmkd")) { return 1; } - if (match_first_bytes(payload, "xpwd")) { + if (ndpi_match_strprefix(payload, payload_len, "xpwd")) { return 1; } - if (match_first_bytes(payload, "xrcp")) { + if (ndpi_match_strprefix(payload, payload_len, "xrcp")) { return 1; } - if (match_first_bytes(payload, "xrmd")) { + if (ndpi_match_strprefix(payload, payload_len, "xrmd")) { return 1; } - if (match_first_bytes(payload, "xrsq")) { + if (ndpi_match_strprefix(payload, payload_len, "xrsq")) { return 1; } - if (match_first_bytes(payload, "xsem")) { + if (ndpi_match_strprefix(payload, payload_len, "xsem")) { return 1; } - if (match_first_bytes(payload, "xsen")) { + if (ndpi_match_strprefix(payload, payload_len, "xsen")) { return 1; } - if (match_first_bytes(payload, "host")) { + if (ndpi_match_strprefix(payload, payload_len, "host")) { return 1; } return 0; } -static int ndpi_ftp_control_check_response(const u_int8_t *payload) { +static int ndpi_ftp_control_check_response(const u_int8_t *payload, size_t payload_len) { - if (match_first_bytes(payload, "110-")) { + if (ndpi_match_strprefix(payload, payload_len, "110-")) { return 1; } - if (match_first_bytes(payload, "120-")) { + if (ndpi_match_strprefix(payload, payload_len, "120-")) { return 1; } - if (match_first_bytes(payload, "125-")) { + if (ndpi_match_strprefix(payload, payload_len, "125-")) { return 1; } - if (match_first_bytes(payload, "150-")) { + if (ndpi_match_strprefix(payload, payload_len, "150-")) { return 1; } - if (match_first_bytes(payload, "202-")) { + if (ndpi_match_strprefix(payload, payload_len, "202-")) { return 1; } - if (match_first_bytes(payload, "211-")) { + if (ndpi_match_strprefix(payload, payload_len, "211-")) { return 1; } - if (match_first_bytes(payload, "212-")) { + if (ndpi_match_strprefix(payload, payload_len, "212-")) { return 1; } - if (match_first_bytes(payload, "213-")) { + if (ndpi_match_strprefix(payload, payload_len, "213-")) { return 1; } - if (match_first_bytes(payload, "214-")) { + if (ndpi_match_strprefix(payload, payload_len, "214-")) { return 1; } - if (match_first_bytes(payload, "215-")) { + if (ndpi_match_strprefix(payload, payload_len, "215-")) { return 1; } - if (match_first_bytes(payload, "220-")) { + if (ndpi_match_strprefix(payload, payload_len, "220-")) { return 1; } - if (match_first_bytes(payload, "221-")) { + if (ndpi_match_strprefix(payload, payload_len, "221-")) { return 1; } - if (match_first_bytes(payload, "225-")) { + if (ndpi_match_strprefix(payload, payload_len, "225-")) { return 1; } - if (match_first_bytes(payload, "226-")) { + if (ndpi_match_strprefix(payload, payload_len, "226-")) { return 1; } - if (match_first_bytes(payload, "227-")) { + if (ndpi_match_strprefix(payload, payload_len, "227-")) { return 1; } - if (match_first_bytes(payload, "228-")) { + if (ndpi_match_strprefix(payload, payload_len, "228-")) { return 1; } - if (match_first_bytes(payload, "229-")) { + if (ndpi_match_strprefix(payload, payload_len, "229-")) { return 1; } - if (match_first_bytes(payload, "230-")) { + if (ndpi_match_strprefix(payload, payload_len, "230-")) { return 1; } - if (match_first_bytes(payload, "231-")) { + if (ndpi_match_strprefix(payload, payload_len, "231-")) { return 1; } - if (match_first_bytes(payload, "232-")) { + if (ndpi_match_strprefix(payload, payload_len, "232-")) { return 1; } - if (match_first_bytes(payload, "250-")) { + if (ndpi_match_strprefix(payload, payload_len, "250-")) { return 1; } - if (match_first_bytes(payload, "257-")) { + if (ndpi_match_strprefix(payload, payload_len, "257-")) { return 1; } - if (match_first_bytes(payload, "331-")) { + if (ndpi_match_strprefix(payload, payload_len, "331-")) { return 1; } - if (match_first_bytes(payload, "332-")) { + if (ndpi_match_strprefix(payload, payload_len, "332-")) { return 1; } - if (match_first_bytes(payload, "350-")) { + if (ndpi_match_strprefix(payload, payload_len, "350-")) { return 1; } - if (match_first_bytes(payload, "421-")) { + if (ndpi_match_strprefix(payload, payload_len, "421-")) { return 1; } - if (match_first_bytes(payload, "425-")) { + if (ndpi_match_strprefix(payload, payload_len, "425-")) { return 1; } - if (match_first_bytes(payload, "426-")) { + if (ndpi_match_strprefix(payload, payload_len, "426-")) { return 1; } - if (match_first_bytes(payload, "430-")) { + if (ndpi_match_strprefix(payload, payload_len, "430-")) { return 1; } - if (match_first_bytes(payload, "434-")) { + if (ndpi_match_strprefix(payload, payload_len, "434-")) { return 1; } - if (match_first_bytes(payload, "450-")) { + if (ndpi_match_strprefix(payload, payload_len, "450-")) { return 1; } - if (match_first_bytes(payload, "451-")) { + if (ndpi_match_strprefix(payload, payload_len, "451-")) { return 1; } - if (match_first_bytes(payload, "452-")) { + if (ndpi_match_strprefix(payload, payload_len, "452-")) { return 1; } - if (match_first_bytes(payload, "501-")) { + if (ndpi_match_strprefix(payload, payload_len, "501-")) { return 1; } - if (match_first_bytes(payload, "502-")) { + if (ndpi_match_strprefix(payload, payload_len, "502-")) { return 1; } - if (match_first_bytes(payload, "503-")) { + if (ndpi_match_strprefix(payload, payload_len, "503-")) { return 1; } - if (match_first_bytes(payload, "504-")) { + if (ndpi_match_strprefix(payload, payload_len, "504-")) { return 1; } - if (match_first_bytes(payload, "530-")) { + if (ndpi_match_strprefix(payload, payload_len, "530-")) { return 1; } - if (match_first_bytes(payload, "532-")) { + if (ndpi_match_strprefix(payload, payload_len, "532-")) { return 1; } - if (match_first_bytes(payload, "550-")) { + if (ndpi_match_strprefix(payload, payload_len, "550-")) { return 1; } - if (match_first_bytes(payload, "551-")) { + if (ndpi_match_strprefix(payload, payload_len, "551-")) { return 1; } - if (match_first_bytes(payload, "552-")) { + if (ndpi_match_strprefix(payload, payload_len, "552-")) { return 1; } - if (match_first_bytes(payload, "553-")) { + if (ndpi_match_strprefix(payload, payload_len, "553-")) { return 1; } - if (match_first_bytes(payload, "631-")) { + if (ndpi_match_strprefix(payload, payload_len, "631-")) { return 1; } - if (match_first_bytes(payload, "632-")) { + if (ndpi_match_strprefix(payload, payload_len, "632-")) { return 1; } - if (match_first_bytes(payload, "633-")) { + if (ndpi_match_strprefix(payload, payload_len, "633-")) { return 1; } - if (match_first_bytes(payload, "10054-")) { + if (ndpi_match_strprefix(payload, payload_len, "10054-")) { return 1; } - if (match_first_bytes(payload, "10060-")) { + if (ndpi_match_strprefix(payload, payload_len, "10060-")) { return 1; } - if (match_first_bytes(payload, "10061-")) { + if (ndpi_match_strprefix(payload, payload_len, "10061-")) { return 1; } - if (match_first_bytes(payload, "10066-")) { + if (ndpi_match_strprefix(payload, payload_len, "10066-")) { return 1; } - if (match_first_bytes(payload, "10068-")) { + if (ndpi_match_strprefix(payload, payload_len, "10068-")) { return 1; } - if (match_first_bytes(payload, "110 ")) { + if (ndpi_match_strprefix(payload, payload_len, "110 ")) { return 1; } - if (match_first_bytes(payload, "120 ")) { + if (ndpi_match_strprefix(payload, payload_len, "120 ")) { return 1; } - if (match_first_bytes(payload, "125 ")) { + if (ndpi_match_strprefix(payload, payload_len, "125 ")) { return 1; } - if (match_first_bytes(payload, "150 ")) { + if (ndpi_match_strprefix(payload, payload_len, "150 ")) { return 1; } - if (match_first_bytes(payload, "202 ")) { + if (ndpi_match_strprefix(payload, payload_len, "202 ")) { return 1; } - if (match_first_bytes(payload, "211 ")) { + if (ndpi_match_strprefix(payload, payload_len, "211 ")) { return 1; } - if (match_first_bytes(payload, "212 ")) { + if (ndpi_match_strprefix(payload, payload_len, "212 ")) { return 1; } - if (match_first_bytes(payload, "213 ")) { + if (ndpi_match_strprefix(payload, payload_len, "213 ")) { return 1; } - if (match_first_bytes(payload, "214 ")) { + if (ndpi_match_strprefix(payload, payload_len, "214 ")) { return 1; } - if (match_first_bytes(payload, "215 ")) { + if (ndpi_match_strprefix(payload, payload_len, "215 ")) { return 1; } - if (match_first_bytes(payload, "220 ")) { + if (ndpi_match_strprefix(payload, payload_len, "220 ")) { return 1; } - if (match_first_bytes(payload, "221 ")) { + if (ndpi_match_strprefix(payload, payload_len, "221 ")) { return 1; } - if (match_first_bytes(payload, "225 ")) { + if (ndpi_match_strprefix(payload, payload_len, "225 ")) { return 1; } - if (match_first_bytes(payload, "226 ")) { + if (ndpi_match_strprefix(payload, payload_len, "226 ")) { return 1; } - if (match_first_bytes(payload, "227 ")) { + if (ndpi_match_strprefix(payload, payload_len, "227 ")) { return 1; } - if (match_first_bytes(payload, "228 ")) { + if (ndpi_match_strprefix(payload, payload_len, "228 ")) { return 1; } - if (match_first_bytes(payload, "229 ")) { + if (ndpi_match_strprefix(payload, payload_len, "229 ")) { return 1; } - if (match_first_bytes(payload, "230 ")) { + if (ndpi_match_strprefix(payload, payload_len, "230 ")) { return 1; } - if (match_first_bytes(payload, "231 ")) { + if (ndpi_match_strprefix(payload, payload_len, "231 ")) { return 1; } - if (match_first_bytes(payload, "232 ")) { + if (ndpi_match_strprefix(payload, payload_len, "232 ")) { return 1; } - if (match_first_bytes(payload, "250 ")) { + if (ndpi_match_strprefix(payload, payload_len, "250 ")) { return 1; } - if (match_first_bytes(payload, "257 ")) { + if (ndpi_match_strprefix(payload, payload_len, "257 ")) { return 1; } - if (match_first_bytes(payload, "331 ")) { + if (ndpi_match_strprefix(payload, payload_len, "331 ")) { return 1; } - if (match_first_bytes(payload, "332 ")) { + if (ndpi_match_strprefix(payload, payload_len, "332 ")) { return 1; } - if (match_first_bytes(payload, "350 ")) { + if (ndpi_match_strprefix(payload, payload_len, "350 ")) { return 1; } - if (match_first_bytes(payload, "421 ")) { + if (ndpi_match_strprefix(payload, payload_len, "421 ")) { return 1; } - if (match_first_bytes(payload, "425 ")) { + if (ndpi_match_strprefix(payload, payload_len, "425 ")) { return 1; } - if (match_first_bytes(payload, "426 ")) { + if (ndpi_match_strprefix(payload, payload_len, "426 ")) { return 1; } - if (match_first_bytes(payload, "430 ")) { + if (ndpi_match_strprefix(payload, payload_len, "430 ")) { return 1; } - if (match_first_bytes(payload, "434 ")) { + if (ndpi_match_strprefix(payload, payload_len, "434 ")) { return 1; } - if (match_first_bytes(payload, "450 ")) { + if (ndpi_match_strprefix(payload, payload_len, "450 ")) { return 1; } - if (match_first_bytes(payload, "451 ")) { + if (ndpi_match_strprefix(payload, payload_len, "451 ")) { return 1; } - if (match_first_bytes(payload, "452 ")) { + if (ndpi_match_strprefix(payload, payload_len, "452 ")) { return 1; } - if (match_first_bytes(payload, "501 ")) { + if (ndpi_match_strprefix(payload, payload_len, "501 ")) { return 1; } - if (match_first_bytes(payload, "502 ")) { + if (ndpi_match_strprefix(payload, payload_len, "502 ")) { return 1; } - if (match_first_bytes(payload, "503 ")) { + if (ndpi_match_strprefix(payload, payload_len, "503 ")) { return 1; } - if (match_first_bytes(payload, "504 ")) { + if (ndpi_match_strprefix(payload, payload_len, "504 ")) { return 1; } - if (match_first_bytes(payload, "530 ")) { + if (ndpi_match_strprefix(payload, payload_len, "530 ")) { return 1; } - if (match_first_bytes(payload, "532 ")) { + if (ndpi_match_strprefix(payload, payload_len, "532 ")) { return 1; } - if (match_first_bytes(payload, "550 ")) { + if (ndpi_match_strprefix(payload, payload_len, "550 ")) { return 1; } - if (match_first_bytes(payload, "551 ")) { + if (ndpi_match_strprefix(payload, payload_len, "551 ")) { return 1; } - if (match_first_bytes(payload, "552 ")) { + if (ndpi_match_strprefix(payload, payload_len, "552 ")) { return 1; } - if (match_first_bytes(payload, "553 ")) { + if (ndpi_match_strprefix(payload, payload_len, "553 ")) { return 1; } - if (match_first_bytes(payload, "631 ")) { + if (ndpi_match_strprefix(payload, payload_len, "631 ")) { return 1; } - if (match_first_bytes(payload, "632 ")) { + if (ndpi_match_strprefix(payload, payload_len, "632 ")) { return 1; } - if (match_first_bytes(payload, "633 ")) { + if (ndpi_match_strprefix(payload, payload_len, "633 ")) { return 1; } - if (match_first_bytes(payload, "10054 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10054 ")) { return 1; } - if (match_first_bytes(payload, "10060 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10060 ")) { return 1; } - if (match_first_bytes(payload, "10061 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10061 ")) { return 1; } - if (match_first_bytes(payload, "10066 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10066 ")) { return 1; } - if (match_first_bytes(payload, "10068 ")) { + if (ndpi_match_strprefix(payload, payload_len, "10068 ")) { return 1; } @@ -956,7 +956,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str if (flow->ftp_control_stage == 0) { NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "FTP_CONTROL stage 0: \n"); - if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload)) { + if ((payload_len > 0) && ndpi_ftp_control_check_request(packet->payload, payload_len)) { NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Possible FTP_CONTROL request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -972,7 +972,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload)) { + if ((payload_len > 0) && ndpi_ftp_control_check_response(packet->payload, payload_len)) { NDPI_LOG(NDPI_PROTOCOL_FTP_CONTROL, ndpi_struct, NDPI_LOG_DEBUG, "Found FTP_CONTROL.\n"); ndpi_int_ftp_control_add_connection(ndpi_struct, flow); } else { diff --git a/src/lib/protocols/ftp_data.c b/src/lib/protocols/ftp_data.c index e87b4402f..7daf9190d 100644 --- a/src/lib/protocols/ftp_data.c +++ b/src/lib/protocols/ftp_data.c @@ -60,13 +60,14 @@ static int ndpi_match_ftp_data_directory(struct ndpi_detection_module_struct *nd static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; /* A FTP packet is pretty long so 256 is a bit consrvative but it should be OK */ if(packet->payload_packet_len < 256) return 0; /* RIFF is a meta-format for storing AVI and WAV files */ - if(match_first_bytes(packet->payload, "RIFF")) + if(ndpi_match_strprefix(packet->payload, payload_len, "RIFF")) return 1; /* MZ is a .exe file */ @@ -74,7 +75,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* Ogg files */ - if(match_first_bytes(packet->payload, "OggS")) + if(ndpi_match_strprefix(packet->payload, payload_len, "OggS")) return 1; /* ZIP files */ @@ -86,7 +87,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* RAR files */ - if(match_first_bytes(packet->payload, "Rar!")) + if(ndpi_match_strprefix(packet->payload, payload_len, "Rar!")) return 1; /* EBML */ @@ -98,7 +99,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* GIF */ - if(match_first_bytes(packet->payload, "GIF8")) + if(ndpi_match_strprefix(packet->payload, payload_len, "GIF8")) return 1; /* PHP scripts */ @@ -110,7 +111,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* PDFs */ - if(match_first_bytes(packet->payload, "%PDF")) + if(ndpi_match_strprefix(packet->payload, payload_len, "%PDF")) return 1; /* PNG */ @@ -118,7 +119,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* HTML */ - if(match_first_bytes(packet->payload, "<htm")) + if(ndpi_match_strprefix(packet->payload, payload_len, "<htm")) return 1; if((packet->payload[0] == 0x0a) && (packet->payload[1] == '<') && (packet->payload[2] == '!') && (packet->payload[3] == 'D')) return 1; @@ -132,17 +133,17 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* XML */ - if(match_first_bytes(packet->payload, "<!DO")) + if(ndpi_match_strprefix(packet->payload, payload_len, "<!DO")) return 1; /* FLAC */ - if(match_first_bytes(packet->payload, "fLaC")) + if(ndpi_match_strprefix(packet->payload, payload_len, "fLaC")) return 1; /* MP3 */ if((packet->payload[0] == 'I') && (packet->payload[1] == 'D') && (packet->payload[2] == '3') && (packet->payload[3] == 0x03)) return 1; - if(match_first_bytes(packet->payload, "\xff\xfb\x90\xc0")) + if(ndpi_match_strprefix(packet->payload, payload_len, "\xff\xfb\x90\xc0")) return 1; /* RPM */ @@ -150,7 +151,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* Wz Patch */ - if(match_first_bytes(packet->payload, "WzPa")) + if(ndpi_match_strprefix(packet->payload, payload_len, "WzPa")) return 1; /* Flash Video */ @@ -158,7 +159,7 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* .BKF (Microsoft Tape Format) */ - if(match_first_bytes(packet->payload, "TAPE")) + if(ndpi_match_strprefix(packet->payload, payload_len, "TAPE")) return 1; /* MS Office Doc file - this is unpleasantly geeky */ @@ -174,23 +175,23 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; /* ar archive, typically .deb files */ - if(match_first_bytes(packet->payload, "!<ar")) + if(ndpi_match_strprefix(packet->payload, payload_len, "!<ar")) return 1; /* Raw XML (skip jabber-like traffic as this is not FTP but unencrypted jabber) */ - if((match_first_bytes(packet->payload, "<?xm")) + if((ndpi_match_strprefix(packet->payload, payload_len, "<?xm")) && (ndpi_strnstr((const char *)packet->payload, "jabber", packet->payload_packet_len) == NULL)) return 1; - if(match_first_bytes(packet->payload, "<iq ")) + if(ndpi_match_strprefix(packet->payload, payload_len, "<iq ")) return 1; /* SPF */ - if(match_first_bytes(packet->payload, "SPFI")) + if(ndpi_match_strprefix(packet->payload, payload_len, "SPFI")) return 1; /* ABIF - Applied Biosystems */ - if(match_first_bytes(packet->payload, "ABIF")) + if(ndpi_match_strprefix(packet->payload, payload_len, "ABIF")) return 1; /* bzip2 - other digits are also possible instead of 9 */ @@ -203,11 +204,11 @@ static int ndpi_match_file_header(struct ndpi_detection_module_struct *ndpi_stru return 1; if((packet->payload[0] == '<') && (packet->payload[1] == 'C') && (packet->payload[2] == 'F')) return 1; - if(match_first_bytes(packet->payload, ".tem")) + if(ndpi_match_strprefix(packet->payload, payload_len, ".tem")) return 1; - if(match_first_bytes(packet->payload, ".ite")) + if(ndpi_match_strprefix(packet->payload, payload_len, ".ite")) return 1; - if(match_first_bytes(packet->payload, ".lef")) + if(ndpi_match_strprefix(packet->payload, payload_len, ".lef")) return 1; return 0; @@ -229,7 +230,6 @@ static void ndpi_check_ftp_data(struct ndpi_detection_module_struct *ndpi_struct } void ndpi_search_ftp_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; /* Break after 20 packets. */ if(flow->packet_counter > 20) { diff --git a/src/lib/protocols/git.c b/src/lib/protocols/git.c new file mode 100644 index 000000000..e156b7913 --- /dev/null +++ b/src/lib/protocols/git.c @@ -0,0 +1,83 @@ +/* + * git.c + * + * Copyright (C) 2012-16 - ntop.org + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ +#include <stdlib.h> +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_GIT + +#define GIT_PORT 9418 + +void ndpi_search_git(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct * packet = &flow->packet; + + if((packet->tcp != NULL) && (packet->payload_packet_len > 4)) { + if((ntohs(packet->tcp->source) == GIT_PORT) + || (ntohs(packet->tcp->dest) == GIT_PORT)) { + const u_int8_t * pp = packet->payload; + u_int16_t payload_len = packet->payload_packet_len; + u_int8_t found_git = 1; + u_int16_t git_len = 0, offset = 0; + + while((offset+4) < payload_len) { + char len[5]; + u_int32_t git_pkt_len; + + memcpy(&len, &pp[offset], 4), len[4] = 0; + git_pkt_len = atoi(len); + + if((payload_len < git_pkt_len) || (git_pkt_len == 0 /* Bad */)) { + found_git = 0; + break; + } else + offset += git_pkt_len, payload_len -= git_pkt_len; + } + + if(found_git) { + NDPI_LOG(NDPI_PROTOCOL_GIT, ndpi_struct, NDPI_LOG_DEBUG, "found Git.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_GIT, NDPI_PROTOCOL_UNKNOWN); + return; + } + } + } + + NDPI_LOG(NDPI_PROTOCOL_GIT, ndpi_struct, NDPI_LOG_DEBUG, "exclude Git.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GIT); +} + + +/* ***************************************************************** */ + + +void init_git_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) +{ + ndpi_set_bitmask_protocol_detection("Git", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_GIT, + ndpi_search_git, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif /* NDPI_PROTOCOL_GIT */ diff --git a/src/lib/protocols/gnutella.c b/src/lib/protocols/gnutella.c index 09d4d0852..e45096391 100644 --- a/src/lib/protocols/gnutella.c +++ b/src/lib/protocols/gnutella.c @@ -294,7 +294,7 @@ void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, stru return; } - if (memcmp(packet->payload, "GND", 3) == 0) { + if (packet->payload_packet_len >= 3 && memcmp(packet->payload, "GND", 3) == 0) { if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0)) || (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5) == 0)) || (packet->payload_packet_len == 17 diff --git a/src/lib/protocols/gtp.c b/src/lib/protocols/gtp.c index 97044f94e..88235f2a8 100644 --- a/src/lib/protocols/gtp.c +++ b/src/lib/protocols/gtp.c @@ -18,7 +18,6 @@ * */ - #include "ndpi_api.h" #ifdef NDPI_PROTOCOL_GTP diff --git a/src/lib/protocols/h323.c b/src/lib/protocols/h323.c index 1d503a747..31d578455 100644 --- a/src/lib/protocols/h323.c +++ b/src/lib/protocols/h323.c @@ -27,7 +27,8 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n"); /* H323 */ - if((packet->payload[0] == 0x03) + if(packet->payload_packet_len >= 3 + && (packet->payload[0] == 0x03) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { struct tpkt *t = (struct tpkt*)packet->payload; @@ -63,7 +64,8 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over udp.\n"); - if(packet->payload[0] == 0x80 && packet->payload[1] == 0x08 && (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) && + if(packet->payload_packet_len >= 6 && packet->payload[0] == 0x80 && packet->payload[1] == 0x08 && + (packet->payload[2] == 0xe7 || packet->payload[2] == 0x26) && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) { NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); @@ -79,7 +81,7 @@ void ndpi_search_h323(struct ndpi_detection_module_struct *ndpi_struct, struct n ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); return; } - else if(packet->payload_packet_len >= 20 || packet->payload_packet_len <= 117) + else if(packet->payload_packet_len >= 20 && packet->payload_packet_len <= 117) { NDPI_LOG(NDPI_PROTOCOL_H323, ndpi_struct, NDPI_LOG_DEBUG, "found H323 broadcast.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_H323, NDPI_PROTOCOL_UNKNOWN); diff --git a/src/lib/protocols/hangout.c b/src/lib/protocols/hangout.c new file mode 100644 index 000000000..ca53a8814 --- /dev/null +++ b/src/lib/protocols/hangout.c @@ -0,0 +1,105 @@ +/* + * hangout.c + * + * Copyright (C) 2012-16 - ntop.org + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ +#include "ndpi_api.h" + +#ifdef NDPI_SERVICE_HANGOUT + +/* https://support.google.com/a/answer/1279090?hl=en */ +#define HANGOUT_UDP_LOW_PORT 19302 +#define HANGOUT_UDP_HIGH_PORT 19309 +#define HANGOUT_TCP_LOW_PORT 19305 +#define HANGOUT_TCP_HIGH_PORT 19309 + +/* ***************************************************************** */ + +static u_int8_t isHangoutUDPPort(u_int16_t port) { + if((port >= HANGOUT_UDP_LOW_PORT) && (port <= HANGOUT_UDP_HIGH_PORT)) + return(1); + else + return(0); +} + +/* ***************************************************************** */ + +static u_int8_t isHangoutTCPPort(u_int16_t port) { + if((port >= HANGOUT_TCP_LOW_PORT) && (port <= HANGOUT_TCP_HIGH_PORT)) + return(1); + else + return(0); +} + +/* ******************************************* */ + +static u_int8_t google_ptree_match(struct ndpi_detection_module_struct *ndpi_struct, struct in_addr *pin) { + return((ndpi_network_ptree_match(ndpi_struct, pin) == NDPI_SERVICE_GOOGLE) ? 1 : 0); +} + +/* ******************************************* */ + +static u_int8_t is_google_flow(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &flow->packet; + + if(packet->iph) { + if(google_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->saddr) + || google_ptree_match(ndpi_struct, (struct in_addr *)&packet->iph->daddr)) { + return(1); + } + } + + return(0); +} + +/* ***************************************************************** */ + +void ndpi_search_hangout(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct * packet = &flow->packet; + + if((packet->payload_packet_len > 24) && is_google_flow(ndpi_struct, flow)) { + if( + ((packet->udp != NULL) && (isHangoutUDPPort(ntohs(packet->udp->source)) || isHangoutUDPPort(ntohs(packet->udp->dest)))) + || + ((packet->tcp != NULL) && (isHangoutTCPPort(ntohs(packet->tcp->source)) || isHangoutTCPPort(ntohs(packet->tcp->dest))))) { + NDPI_LOG(NDPI_SERVICE_HANGOUT, ndpi_struct, NDPI_LOG_DEBUG, "Found Hangout.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_SERVICE_HANGOUT, NDPI_PROTOCOL_UNKNOWN); + return; + } + } + + NDPI_LOG(NDPI_SERVICE_HANGOUT, ndpi_struct, NDPI_LOG_DEBUG, "No Hangout.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_SERVICE_HANGOUT); +} + +/* ***************************************************************** */ + +void init_hangout_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) { + ndpi_set_bitmask_protocol_detection("GoogleHangout", ndpi_struct, detection_bitmask, *id, + NDPI_SERVICE_HANGOUT, + ndpi_search_hangout, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif /* NDPI_SERVICE_HANGOUT */ diff --git a/src/lib/protocols/kakaotalk_voice.c b/src/lib/protocols/kakaotalk_voice.c index c6972c7a1..368532c5d 100644 --- a/src/lib/protocols/kakaotalk_voice.c +++ b/src/lib/protocols/kakaotalk_voice.c @@ -33,7 +33,7 @@ void ndpi_search_kakaotalk_voice(struct ndpi_detection_module_struct *ndpi_struc if(packet->iph && packet->udp - && (packet->payload_packet_len > 0) + && (packet->payload_packet_len >= 4) ) { if((packet->payload[0] == 0x81) || (packet->payload[1] == 0xC8) diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c index c62c1d366..4e352583e 100644 --- a/src/lib/protocols/mail_imap.c +++ b/src/lib/protocols/mail_imap.c @@ -1,8 +1,7 @@ /* * mail_imap.c * - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2016 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -42,6 +41,15 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, /* const u_int8_t *command = 0; */ NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "search IMAP.\n"); + + if (flow->l4.tcp.mail_imap_starttls == 2) { +#ifdef NDPI_PROTOCOL_SSL + NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "starttls detected\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_IMAP); + NDPI_DEL_PROTOCOL_FROM_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL); + return; +#endif + } if (packet->payload_packet_len >= 4 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) { // the DONE command appears without a tag @@ -62,7 +70,7 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, } if (!((packet->payload[i] >= 'a' && packet->payload[i] <= 'z') || (packet->payload[i] >= 'A' && packet->payload[i] <= 'Z') || - (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*')) { + (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*' || packet->payload[i] == '.')) { goto imap_excluded; } i++; @@ -99,6 +107,8 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, && (packet->payload[command_start + 1] == 'K' || packet->payload[command_start + 1] == 'k') && packet->payload[command_start + 2] == ' ') { flow->l4.tcp.mail_imap_stage += 1; + if (flow->l4.tcp.mail_imap_starttls == 1) + flow->l4.tcp.mail_imap_starttls = 2; saw_command = 1; } else if ((packet->payload[command_start] == 'U' || packet->payload[command_start] == 'u') && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i') @@ -131,8 +141,10 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, && (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't') && (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l') && (packet->payload[command_start + 7] == 'S' || packet->payload[command_start + 7] == 's')) { - flow->l4.tcp.mail_imap_stage += 1; - saw_command = 1; + flow->l4.tcp.mail_imap_stage += 1; + flow->l4.tcp.mail_imap_starttls = 1; + flow->detected_protocol_stack[0] = NDPI_PROTOCOL_MAIL_IMAPS; + saw_command = 1; } } if ((command_start + 5) < packet->payload_packet_len) { diff --git a/src/lib/protocols/mqtt.c b/src/lib/protocols/mqtt.c index 024fad8a7..37c469066 100644 --- a/src/lib/protocols/mqtt.c +++ b/src/lib/protocols/mqtt.c @@ -144,7 +144,7 @@ void ndpi_search_mqtt (struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG,"====>>>> Passed second stage of identification\n"); // third stage verification (payload) if (pt == CONNECT) { - if (memcmp(&(packet->payload[4]),"MQTT",4) == 0) { + if (packet->payload_packet_len >= 8 && memcmp(&(packet->payload[4]),"MQTT",4) == 0) { NDPI_LOG(NDPI_PROTOCOL_MQTT, ndpi_struct, NDPI_LOG_DEBUG, "Mqtt found CONNECT\n"); ndpi_int_mqtt_add_connection(ndpi_struct,flow); return; diff --git a/src/lib/protocols/msn.c b/src/lib/protocols/msn.c index af537d7ff..ff81a12b3 100644 --- a/src/lib/protocols/msn.c +++ b/src/lib/protocols/msn.c @@ -130,7 +130,7 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct if (get_u_int8_t(packet->payload, packet->payload_packet_len - 2) == 0x0d && get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a) { /* The MSNP string is used in XBOX clients. */ - if (memcmp(packet->payload, "VER ", 4) == 0) { + if (ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "VER ")) { if (memcmp(&packet->payload[packet->payload_packet_len - 6], "CVR", 3) == 0 || memcmp(&packet->payload[packet->payload_packet_len - 8], "MSNP", 4) == 0) { @@ -139,7 +139,7 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct ndpi_int_msn_add_connection(ndpi_struct, flow); return; } - if (memcmp(&packet->payload[4], "MSNFT", 5) == 0) { + if (ndpi_match_strprefix(&packet->payload[4], packet->payload_packet_len-4, "MSNFT")) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN FT by pattern VER MSNFT...0d0a.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow); @@ -153,8 +153,8 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif - memcmp(packet->payload, "GET ", NDPI_STATICSTRING_LEN("GET ")) == 0 || - memcmp(packet->payload, "POST ", NDPI_STATICSTRING_LEN("POST ")) == 0) { + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "GET ") || + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "POST ")) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Messenger/") && @@ -277,8 +277,8 @@ static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif - (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) || - (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0) + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "HTTP/1.0 200 OK") || + ndpi_match_strprefix(packet->payload, packet->payload_packet_len, "HTTP/1.1 200 OK") ) { ndpi_parse_packet_line_info(ndpi_struct, flow); diff --git a/src/lib/protocols/netbios.c b/src/lib/protocols/netbios.c index 9c2283a81..ca649782b 100644 --- a/src/lib/protocols/netbios.c +++ b/src/lib/protocols/netbios.c @@ -324,7 +324,7 @@ void ndpi_search_netbios(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG_DEBUG, "found netbios with checked ip-address.\n"); if(netbios_name_interpret((char*)&packet->payload[12], name, sizeof(name)) > 0) - snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name), "%s", name); + snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name)-1, "%s", name); ndpi_int_netbios_add_connection(ndpi_struct, flow); return; diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c index a0fa92a20..6e355c9f8 100644 --- a/src/lib/protocols/ntp.c +++ b/src/lib/protocols/ntp.c @@ -22,54 +22,44 @@ * */ - #include "ndpi_protocols.h" + #ifdef NDPI_PROTOCOL_NTP + static void ndpi_int_ntp_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NTP, NDPI_PROTOCOL_UNKNOWN); } -/* detection also works asymmetrically */ - void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; - -// struct ndpi_id_struct *src=ndpi_struct->src; -// struct ndpi_id_struct *dst=ndpi_struct->dst; - - if (!(packet->udp->dest == htons(123) || packet->udp->source == htons(123))) - goto exclude_ntp; - - NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n"); - - // It's not correct because packets could be bigger - //if (packet->payload_packet_len != 48) - // goto exclude_ntp; - - NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n"); - - - if ((((packet->payload[0] & 0x38) >> 3) <= 4)) { - NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP."); + struct ndpi_packet_struct *packet = &flow->packet; + + if (!(packet->udp->dest == htons(123) || packet->udp->source == htons(123))) + goto exclude_ntp; + + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP port detected\n"); + + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP length detected\n"); + + + if ((((packet->payload[0] & 0x38) >> 3) <= 4)) { + NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "detected NTP."); - // 38 in binary representation is 00111000 - flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3; - - if (flow->protos.ntp.version == 2) { - flow->protos.ntp.request_code = packet->payload[3]; - } - - ndpi_int_ntp_add_connection(ndpi_struct, flow); - return; - } - - - - exclude_ntp: + // 38 in binary representation is 00111000 + flow->protos.ntp.version = (packet->payload[0] & 0x38) >> 3; + + if (flow->protos.ntp.version == 2) { + flow->protos.ntp.request_code = packet->payload[3]; + } + + ndpi_int_ntp_add_connection(ndpi_struct, flow); + return; + } + + exclude_ntp: NDPI_LOG(NDPI_PROTOCOL_NTP, ndpi_struct, NDPI_LOG_DEBUG, "NTP excluded.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NTP); } diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c index 9005dc3ff..3e8412355 100644 --- a/src/lib/protocols/openvpn.c +++ b/src/lib/protocols/openvpn.c @@ -1,68 +1,113 @@ /* - * h323.c + * openvpn.c * - * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> + * Copyright (C) 2011-16 - ntop.org + * + * OpenVPN TCP / UDP Detection - 128/160 hmac + * + * Detection based upon these openvpn protocol properties: + * - opcode + * - packet ID + * - session ID + * + * Two (good) packets are needed to perform detection. + * - First packet from client: save session ID + * - Second packet from server: report saved session ID + * + * TODO + * - Support PSK only mode (instead of TLS) + * - Support PSK + TLS mode (PSK used for early authentication) + * - TLS certificate extraction * */ #include "ndpi_api.h" - #ifdef NDPI_PROTOCOL_OPENVPN +#define P_CONTROL_HARD_RESET_CLIENT_V1 (0x01 << 3) +#define P_CONTROL_HARD_RESET_CLIENT_V2 (0x07 << 3) +#define P_CONTROL_HARD_RESET_SERVER_V1 (0x02 << 3) +#define P_CONTROL_HARD_RESET_SERVER_V2 (0x08 << 3) +#define P_OPCODE_MASK 0xF8 +#define P_SHA1_HMAC_SIZE 20 +#define P_HMAC_128 16 // (RSA-)MD5, (RSA-)MD4, ..others +#define P_HMAC_160 20 // (RSA-|DSA-)SHA(1), ..others, SHA1 is openvpn default +#define P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) (9 + hmac_size) +#define P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) (P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) + 8) +#define P_HARD_RESET_CLIENT_MAX_COUNT 5 + +static inline u_int32_t get_packet_id(const u_int8_t * payload, u_int8_t hms) { + return ntohl(*(u_int32_t*)(payload + P_HARD_RESET_PACKET_ID_OFFSET(hms))); +} + +static inline int8_t check_pkid_and_detect_hmac_size(const u_int8_t * payload) { + // try to guess + if (get_packet_id(payload, P_HMAC_160) == 1) + return P_HMAC_160; + if (get_packet_id(payload, P_HMAC_128) == 1) + return P_HMAC_128; + return -1; +} + void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { struct ndpi_packet_struct* packet = &flow->packet; - u_int16_t dport = 0, sport = 0; - - if (packet->udp != NULL) { - - sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); - - if ((packet->payload_packet_len >= 25) && (sport == 443 || dport == 443) && - (packet->payload[0] == 0x17 && packet->payload[1] == 0x01 && - packet->payload[2] == 0x00 && packet->payload[3] == 0x00)) { - NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, - "found openvpn udp 443.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); - return; - } - - if ( ( (packet->payload_packet_len > 40) || - (packet->payload_packet_len <= 14) ) && // hard-reset - (sport == 1194 || dport == 1194) && - (packet->payload[0] == 0x30 || packet->payload[0] == 0x31 || - packet->payload[0] == 0x32 || packet->payload[0] == 0x33 || - packet->payload[0] == 0x34 || packet->payload[0] == 0x35 || - packet->payload[0] == 0x36 || packet->payload[0] == 0x37 || - packet->payload[0] == 0x38 || packet->payload[0] == 0x39)) { - NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, - "found openvpn broadcast udp STD.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); - return; - } - - } - - if (packet->tcp != NULL) { - - sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest); - - if ((packet->payload_packet_len >= 40) && - (sport == 1194 || dport == 1194) && - ((packet->payload[0] == 0x00) && (packet->payload[1] == 0x2a) && - (packet->payload[2] == 0x38))) { - NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, - "found openvpn broadcast udp STD.\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); - return; - } + const u_int8_t * ovpn_payload = packet->payload; + const u_int8_t * session_remote; + u_int8_t opcode; + u_int8_t alen; + int8_t hmac_size; + int8_t failed = 0; + + if (packet->payload_packet_len >= 40) { + // skip openvpn TCP transport packet size + if (packet->tcp != NULL) + ovpn_payload += 2; + + opcode = ovpn_payload[0] & P_OPCODE_MASK; + + if (flow->ovpn_counter < P_HARD_RESET_CLIENT_MAX_COUNT && (opcode == P_CONTROL_HARD_RESET_CLIENT_V1 || + opcode == P_CONTROL_HARD_RESET_CLIENT_V2)) { + + if (check_pkid_and_detect_hmac_size(ovpn_payload) > 0) { + memcpy(flow->ovpn_session_id, ovpn_payload+1, 8); + + NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, + "session key: %02x%02x%02x%02x%02x%02x%02x%02x\n", + flow->ovpn_session_id[0], flow->ovpn_session_id[1], flow->ovpn_session_id[2], flow->ovpn_session_id[3], + flow->ovpn_session_id[4], flow->ovpn_session_id[5], flow->ovpn_session_id[6], flow->ovpn_session_id[7]); + } + } else if (flow->ovpn_counter >= 1 && flow->ovpn_counter <= P_HARD_RESET_CLIENT_MAX_COUNT && + (opcode == P_CONTROL_HARD_RESET_SERVER_V1 || opcode == P_CONTROL_HARD_RESET_SERVER_V2)) { + + hmac_size = check_pkid_and_detect_hmac_size(ovpn_payload); + + if (hmac_size > 0) { + alen = ovpn_payload[P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size)]; + session_remote = ovpn_payload + P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) + 1 + alen * 4; + + if (memcmp(flow->ovpn_session_id, session_remote, 8) == 0) + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN); + else { + NDPI_LOG(NDPI_PROTOCOL_OPENVPN, ndpi_struct, NDPI_LOG_DEBUG, + "key mismatch: %02x%02x%02x%02x%02x%02x%02x%02x\n", + session_remote[0], session_remote[1], session_remote[2], session_remote[3], + session_remote[4], session_remote[5], session_remote[6], session_remote[7]); + failed = 1; + } + } else + failed = 1; + } else + failed = 1; + + flow->ovpn_counter++; + + if (failed) + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENVPN); } - - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENVPN); } - void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("OpenVPN", ndpi_struct, detection_bitmask, *id, diff --git a/src/lib/protocols/oscar.c b/src/lib/protocols/oscar.c index a43394a8d..869b36378 100644 --- a/src/lib/protocols/oscar.c +++ b/src/lib/protocols/oscar.c @@ -244,10 +244,19 @@ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct */ if (channel == DATA) { - family = get_u_int16_t(packet->payload, 6); - type = get_u_int16_t(packet->payload, 8); - flag = get_u_int16_t(packet->payload, 10); - req_ID = get_u_int32_t(packet->payload, 12); + if (packet->payload_packet_len >= 8) + family = get_u_int16_t(packet->payload, 6); + else + family = 0; + if (packet->payload_packet_len >= 10) + type = get_u_int16_t(packet->payload, 8); + else + type = 0; + if (family == 0 || type == 0) + { + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR); + return; + } /* Family 0x0001 */ if (family == htons(GE_SE_CTL)) @@ -561,16 +570,24 @@ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct } /* flag */ - if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001)) - { - /* request ID */ - if((req_ID <= 4294967295)) + if (packet->payload_packet_len >= 12) + { + flag = get_u_int16_t(packet->payload, 10); + if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001)) + { + if (packet->payload_packet_len >= 16) { - NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n"); - ndpi_int_oscar_add_connection(ndpi_struct, flow); - return; + /* request ID */ + req_ID = get_u_int32_t(packet->payload, 12); + if((req_ID <= 4294967295)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } } - } + } + } } /* ERROR -> FLAP__ERROR_CHANNEL_0x03 diff --git a/src/lib/protocols/pando.c b/src/lib/protocols/pando.c index f3ed00783..b906e7ed9 100644 --- a/src/lib/protocols/pando.c +++ b/src/lib/protocols/pando.c @@ -34,7 +34,7 @@ static void ndpi_check_pando_tcp(struct ndpi_detection_module_struct *ndpi_struc struct ndpi_packet_struct *packet = &flow->packet; u_int32_t payload_len = packet->payload_packet_len; - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x0ePan")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x0ePan")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); ndpi_int_pando_add_connection(ndpi_struct, flow); } @@ -56,7 +56,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "UDPA")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -64,7 +64,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc return; } - if ((payload_len > 0) && (match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE"))) { + if (ndpi_match_strprefix(packet->payload, payload_len, "UDPR") || ndpi_match_strprefix(packet->payload, payload_len, "UDPE")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Possible PANDO request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -98,7 +98,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len == 0) || match_first_bytes(packet->payload, "UDPR") || match_first_bytes(packet->payload, "UDPE")) { + if ((payload_len == 0) || (ndpi_match_strprefix(packet->payload, payload_len, "UDPR") || ndpi_match_strprefix(packet->payload, payload_len, "UDPE"))) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); ndpi_int_pando_add_connection(ndpi_struct, flow); } else { @@ -115,7 +115,7 @@ static void ndpi_check_pando_udp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "UDPA")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "UDPA")) { NDPI_LOG(NDPI_PROTOCOL_PANDO, ndpi_struct, NDPI_LOG_DEBUG, "Found PANDO.\n"); ndpi_int_pando_add_connection(ndpi_struct, flow); } else { diff --git a/src/lib/protocols/pplive.c b/src/lib/protocols/pplive.c index cf9260f17..2e4747159 100644 --- a/src/lib/protocols/pplive.c +++ b/src/lib/protocols/pplive.c @@ -39,7 +39,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str if (flow->pplive_stage1 == 0) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n"); - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -47,7 +47,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x42\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x42\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -55,7 +55,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x1c\x1c\x32\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -72,7 +72,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && (match_first_bytes(packet->payload, "\xe9\x03\x42\x01") || match_first_bytes(packet->payload, "\xe9\x03\x41\x01"))) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x42\x01") || ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); ndpi_int_pplive_add_connection(ndpi_struct, flow); } else { @@ -89,7 +89,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); ndpi_int_pplive_add_connection(ndpi_struct, flow); } else { @@ -105,7 +105,7 @@ static void ndpi_check_pplive_udp1(struct ndpi_detection_module_struct *ndpi_str } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x1c\x1c\x32\x01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x1c\x1c\x32\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Found PPLIVE.\n"); ndpi_int_pplive_add_connection(ndpi_struct, flow); } else { @@ -124,7 +124,7 @@ static void ndpi_check_pplive_udp2(struct ndpi_detection_module_struct *ndpi_str if (flow->pplive_stage2 == 0) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "PPLIVE stage 0: \n"); - if ((payload_len == 57) && match_first_bytes(packet->payload, "\xe9\x03\x41\x01")) { + if ((payload_len == 57) && ndpi_match_strprefix(packet->payload, payload_len, "\xe9\x03\x41\x01")) { NDPI_LOG(NDPI_PROTOCOL_PPLIVE, ndpi_struct, NDPI_LOG_DEBUG, "Possible PPLIVE request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index 2bece25a7..8050a9b61 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1,11 +1,12 @@ /* * quic.c * + * Copyright (C) 2012-16 - ntop.org + * + * Based on code of: * Andrea Buscarinu - <andrea.buscarinu@gmail.com> * Michele Campus - <campus@ntop.org> * - * Copyright (C) 2012-15 - ntop.org - * * This module is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -21,164 +22,122 @@ * */ - #include "ndpi_api.h" -#define QUIC_NO_V_RES_RSV 0xC3 // 1100 0011 - -#define QUIC_CID_MASK 0x0C // 0000 1100 -#define QUIC_VER_MASK 0x01 // 0000 0001 -#define QUIC_SEQ_MASK 0x30 // 0011 0000 - -#define CID_LEN_8 0x0C // 0000 1100 -#define CID_LEN_4 0x08 // 0000 1000 -#define CID_LEN_1 0x04 // 0000 0100 -#define CID_LEN_0 0x00 // 0000 0000 - -#define SEQ_LEN_6 0x30 // 0011 0000 -#define SEQ_LEN_4 0x20 // 0010 0000 -#define SEQ_LEN_2 0x10 // 0001 0000 -#define SEQ_LEN_1 0x00 // 0000 0000 - -#define SEQ_CONV(ARR) (ARR[0] | ARR[1] | ARR[2] | ARR[3] | ARR[4] | ARR[5] << 8) - - #ifdef NDPI_PROTOCOL_QUIC -static void ndpi_int_quic_add_connection(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) + +static int quic_ports(u_int16_t sport, u_int16_t dport) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN); + if ((sport == 443 || dport == 443 || sport == 80 || dport == 80) && + (sport != 123 && dport != 123)) + return 1; + + return 0; } -static int connect_id(const unsigned char pflags) -{ - u_int cid_len; - - // Check CID length. - switch (pflags & QUIC_CID_MASK) - { - case CID_LEN_8: cid_len = 8; break; - case CID_LEN_4: cid_len = 4; break; - case CID_LEN_1: cid_len = 1; break; - case CID_LEN_0: cid_len = 0; break; - default: - return -1; - - } - // Return offset. - return cid_len + 1; +/* ***************************************************************** */ + +static int quic_len(u_int8_t l) { + switch(l) { + case 0: + return(1); + break; + case 1: + return(2); + break; + case 2: + return(4); + break; + case 3: + return(8); + break; + } + + return(0); /* NOTREACHED */ } -static int sequence(const unsigned char *payload) +/* ***************************************************************** */ + +void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { - unsigned char conv[6] = {0}; - u_int seq_value = -1; - int seq_lens; - int cid_offs; + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t udp_len = packet->payload_packet_len; + u_int version_len = ((packet->payload[0] & 0x01) == 0) ? 0 : 4; + u_int cid_len = quic_len((packet->payload[0] & 0x0C) >> 2); + u_int seq_len = quic_len((packet->payload[0] & 0x30) >> 4); + u_int quic_hlen = 1 /* flags */ + version_len + seq_len + cid_len; + + if(packet->udp != NULL + && (udp_len > (quic_hlen+4 /* QXXX */)) + && ((packet->payload[0] & 0xC2) == 0x00) + && (quic_ports(ntohs(packet->udp->source), ntohs(packet->udp->dest))) + ) { + char *begin; int i; - // Search SEQ bytes length. - switch (payload[0] & QUIC_SEQ_MASK) - { - case SEQ_LEN_6: seq_lens = 6; break; - case SEQ_LEN_4: seq_lens = 4; break; - case SEQ_LEN_2: seq_lens = 2; break; - case SEQ_LEN_1: seq_lens = 1; break; - default: - return -1; - } - // Retrieve SEQ offset. - cid_offs = connect_id(payload[0]); - - if (cid_offs >= 0 && seq_lens > 0) - { - for (i = 0; i < seq_lens; i++) - conv[i] = payload[cid_offs + i]; - - seq_value = SEQ_CONV(conv); - } - - // Return SEQ dec value; - return seq_value; -} + if((version_len > 0) && (packet->payload[1+cid_len] != 'Q')) + goto no_quic; -void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - int ver_offs; - - if(packet->udp != NULL) { - - u_int16_t sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); - - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "calculating quic over udp.\n"); - - if((((sport == 80) || (dport == 80) || (sport == 443) || (dport == 443)))) - { - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); - - - // Settings without version. First check if PUBLIC FLAGS & SEQ bytes are 0x0. SEQ must be 1 at least. - if ((packet->payload[0] == 0x00 && packet->payload[1] != 0x00) || ((packet->payload[0] & QUIC_NO_V_RES_RSV) == 0)) - { - if (sequence(packet->payload) < 1) - { - - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); - } + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found QUIC.\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN); - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); - ndpi_int_quic_add_connection(ndpi_struct, flow); - } + if(udp_len > quic_hlen + 17 + 4 && + !strncmp((char*)&packet->payload[quic_hlen+17], "CHLO" /* Client Hello */, 4)) { + /* Check if SNI (Server Name Identification) is present */ + for(i=quic_hlen+12; i<udp_len-3; i++) { + if((packet->payload[i] == 'S') + && (packet->payload[i+1] == 'N') + && (packet->payload[i+2] == 'I') + && (packet->payload[i+3] == 0)) { + u_int32_t offset = *((u_int32_t*)&packet->payload[i+4]); + u_int32_t prev_offset = *((u_int32_t*)&packet->payload[i-4]); + int len = offset-prev_offset; + int sni_offset = i+prev_offset+1; + + while((sni_offset < udp_len) && (packet->payload[sni_offset] == '-')) + sni_offset++; - // Check if version, than the CID length. - else if (packet->payload[0] & QUIC_VER_MASK) - { - // Skip CID length. - ver_offs = connect_id(packet->payload[0]); - - if (ver_offs >= 0) - { - unsigned char vers[] = {packet->payload[ver_offs], packet->payload[ver_offs + 1], - packet->payload[ver_offs + 2], packet->payload[ver_offs + 3]}; - - // Version Match. - if ((vers[0] == 'Q' && vers[1] == '0') && - ((vers[2] == '2' && (vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || - vers[3] == '1' || vers[3] == '0')) || - (vers[2] == '1' && (vers[3] == '9' || vers[3] == '8' || vers[3] == '7' || vers[3] == '6' || - vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || - vers[3] == '1' || vers[3] == '0')) || - (vers[2] == '0' && vers[3] == '9'))) - - { - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); - ndpi_int_quic_add_connection(ndpi_struct, flow); + if((sni_offset+len) < udp_len) { + int max_len = sizeof(flow->host_server_name)-1, j = 0; + + if(len > max_len) len = max_len; + + while((len > 0) && (sni_offset < udp_len)) { + flow->host_server_name[j++] = packet->payload[sni_offset]; + sni_offset++, len--; } + + ndpi_match_host_subprotocol(ndpi_struct, flow, + (char *)flow->host_server_name, + strlen((const char*)flow->host_server_name), + NDPI_PROTOCOL_QUIC); + } + + break; } - } - else - { - NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); - NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); } } + return; + } + + no_quic: + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude QUIC.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); } +/* ***************************************************************** */ -void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) +void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) { - ndpi_set_bitmask_protocol_detection("Quic", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_QUIC, - ndpi_search_quic, + ndpi_set_bitmask_protocol_detection("QUIC", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_QUIC, ndpi_search_quic, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); + SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } -#endif +#endif /* NDPI_PROTOCOL_QUIC */ diff --git a/src/lib/protocols/radius.c b/src/lib/protocols/radius.c index 625dc4108..308049522 100644 --- a/src/lib/protocols/radius.c +++ b/src/lib/protocols/radius.c @@ -37,12 +37,11 @@ static void ndpi_check_radius(struct ndpi_detection_module_struct *ndpi_struct, if(packet->udp != NULL) { struct radius_header *h = (struct radius_header*)packet->payload; - u_int len = ntohs(h->len); if((payload_len > sizeof(struct radius_header)) && (h->code > 0) && (h->code <= 5) - && (len == payload_len)) { + && (ntohs(h->len) == payload_len)) { NDPI_LOG(NDPI_PROTOCOL_RADIUS, ndpi_struct, NDPI_LOG_DEBUG, "Found radius.\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RADIUS, NDPI_PROTOCOL_UNKNOWN); diff --git a/src/lib/protocols/rtcp.c b/src/lib/protocols/rtcp.c index c8fc90953..cc6265220 100644 --- a/src/lib/protocols/rtcp.c +++ b/src/lib/protocols/rtcp.c @@ -38,7 +38,7 @@ void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct n /* Let's check first the RTCP packet length */ u_int16_t len, offset = 0, rtcp_section_len; - while(offset < packet->payload_packet_len) { + while(offset + 3 < packet->payload_packet_len) { len = packet->payload[2+offset] * 256 + packet->payload[2+offset+1]; rtcp_section_len = (len + 1) * 4; @@ -48,11 +48,11 @@ void ndpi_search_rtcp(struct ndpi_detection_module_struct *ndpi_struct, struct n offset += rtcp_section_len; } - sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest); NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "calculating dport over udp.\n"); - if(((packet->payload_packet_len >= 28 || packet->payload_packet_len <= 1200) && + /* TODO changed a pair of length condition to the && from ||. Is it correct? */ + if(((packet->payload_packet_len >= 28 && packet->payload_packet_len <= 1200) && ((packet->payload[0] == 0x80) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) && (packet->payload[2] == 0x00))) - || (((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) + || (packet->payload_packet_len >= 3 && ((packet->payload[0] == 0x81) && ((packet->payload[1] == 0xc8) || (packet->payload[1] == 0xc9)) && (packet->payload[2] == 0x00)))) { NDPI_LOG(NDPI_PROTOCOL_RTCP, ndpi_struct, NDPI_LOG_DEBUG, "found rtcp.\n"); ndpi_int_rtcp_add_connection(ndpi_struct, flow); diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c index 17744ed95..9bcaec941 100644 --- a/src/lib/protocols/rtp.c +++ b/src/lib/protocols/rtp.c @@ -73,6 +73,8 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const u_int8_t * payload, const u_int16_t payload_len) { + if (payload_len < 2) + return; //struct ndpi_packet_struct *packet = &flow->packet; u_int8_t payloadType, payload_type = payload[1] & 0x7F; u_int32_t *ssid = (u_int32_t*)&payload[8]; diff --git a/src/lib/protocols/rx.c b/src/lib/protocols/rx.c new file mode 100644 index 000000000..9d27d5e18 --- /dev/null +++ b/src/lib/protocols/rx.c @@ -0,0 +1,234 @@ +/* + * rx.c + * + * Copyright (C) 2012-16 - ntop.org + * + * Giovanni Mascellani <gio@debian.org> + * + * This file is part of nDPI, an open source deep packet inspection + * library based on the OpenDPI and PACE technology by ipoque GmbH + * + * nDPI is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nDPI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with nDPI. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "ndpi_api.h" + +#ifdef NDPI_PROTOCOL_RX + +/* See http://web.mit.edu/kolya/afs/rx/rx-spec for procotol description. */ + +/* The should be no need for explicit packing, but just in case... */ +PACK_ON +struct ndpi_rx_header { + u_int32_t conn_epoch; + u_int32_t conn_id; + u_int32_t call_number; + u_int32_t sequence_number; + u_int32_t serial_number; + u_int8_t type; + u_int8_t flags; + u_int8_t status; + u_int8_t security; + u_int16_t checksum; + u_int16_t service_id; +} PACK_OFF; + +/* Type values */ +#define DATA 1 +#define ACK 2 +#define BUSY 3 +#define ABORT 4 +#define ACKALL 5 +#define CHALLENGE 6 +#define RESPONSE 7 +#define DEBUG 8 +#define PARAM_1 9 +#define PARAM_2 10 +#define PARAM_3 11 +#define PARAMS_4 12 +#define VERSION 13 + +/* Flags values */ +#define EMPTY 0 +#define CLIENT_INIT_1 1 +#define REQ_ACK 2 +#define PLUS_0 3 +#define LAST_PKT 4 +#define PLUS_1 5 +#define PLUS_2 6 +#define MORE_1 9 +#define CLIENT_INIT_2 33 + + + +void ndpi_check_rx(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int32_t payload_len = packet->payload_packet_len; + int found = 0; + + + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "RX: pck: %d, dir[0]: %d, dir[1]: %d\n", + flow->packet_counter, flow->packet_direction_counter[0], flow->packet_direction_counter[1]); + + /* Check that packet is long enough */ + if (payload_len < sizeof(struct ndpi_rx_header)) { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + struct ndpi_rx_header *header = (struct ndpi_rx_header*) packet->payload; + + /** + * Useless check: a session could be detected also after it starts + * and this check limit the correct detection for -d option (disable guess) + * TODO - maybe to improve + **/ + /* Check whether the packet has counters beginning from one; the + Sequence Number can be zero if the packet is just an ACK. */ + /* if ((ntohl(header->sequence_number) | 1) != 1 || ntohl(header->serial_number) != 1) */ + + + /** + * Check the TYPE and FLAGS fields of an RX packet header. + * This check is necessary because we could detect an RX session already begun + **/ + + /* TYPE field */ + if((header->type < DATA) || (header->type > VERSION)) { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + /* FLAGS fields */ + if(header->flags == EMPTY || header->flags == LAST_PKT || + header->flags == PLUS_0 || header->flags == PLUS_1 || + header->flags == PLUS_2 || header->flags == REQ_ACK || + header->flags == MORE_1 || header->flags == CLIENT_INIT_1 || + header->flags == CLIENT_INIT_2) { + + /* TYPE and FLAGS combo */ + switch(header->type) + { + case DATA: + if(header->flags == LAST_PKT || header->flags == EMPTY || + header->flags == PLUS_0 || header->flags == PLUS_1 || + header->flags == PLUS_2 || header->flags == REQ_ACK || + header->flags == MORE_1) + goto security; + case ACK: + if(header->flags == CLIENT_INIT_1 || header->flags == CLIENT_INIT_2 || + header->flags == EMPTY) + goto security; + case CHALLENGE: + if(header->flags == EMPTY || header->call_number == 0) + goto security; + case RESPONSE: + if(header->flags == EMPTY || header->call_number == 0) + goto security; + case ACKALL: + if(header->flags == EMPTY) + goto security; + case BUSY: + goto security; + case ABORT: + goto security; + case DEBUG: + goto security; + case PARAM_1: + goto security; + case PARAM_2: + goto security; + case PARAM_3: + goto security; + case VERSION: + goto security; + default: + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } // switch + } else { // FLAG + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + security: + /* SECURITY field */ + if(header->security > 3) + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + + /* If we have already seen one packet in the other direction, then + the two must have matching connection numbers. Otherwise store + them. */ + if(flow->packet_direction_counter[!packet->packet_direction] != 0) + { + if (flow->l4.udp.rx_conn_epoch == header->conn_epoch && + flow->l4.udp.rx_conn_id == header->conn_id) + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "found RX\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RX, NDPI_PROTOCOL_UNKNOWN); + } + /* https://www.central.org/frameless/numbers/rxservice.html. */ + else + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "excluding RX\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RX); + return; + } + } else { + flow->l4.udp.rx_conn_epoch = header->conn_epoch; + flow->l4.udp.rx_conn_id = header->conn_id; + { + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "found RX\n"); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RX, NDPI_PROTOCOL_UNKNOWN); + } + } +} + +void ndpi_search_rx(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + NDPI_LOG(NDPI_PROTOCOL_RX, ndpi_struct, NDPI_LOG_DEBUG, "entering RX search\n"); + if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_RX) { + ndpi_check_rx(ndpi_struct, flow); + } +} + +void init_rx_dissector(struct ndpi_detection_module_struct *ndpi_struct, + u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) +{ + ndpi_set_bitmask_protocol_detection("RX", ndpi_struct, detection_bitmask, *id, + NDPI_PROTOCOL_RX, + ndpi_search_rx, + NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); + + *id += 1; +} + +#endif diff --git a/src/lib/protocols/spotify.c b/src/lib/protocols/spotify.c index 274312163..e7dac5d66 100644 --- a/src/lib/protocols/spotify.c +++ b/src/lib/protocols/spotify.c @@ -54,7 +54,7 @@ static void ndpi_check_spotify(struct ndpi_detection_module_struct *ndpi_struct, } } else if(packet->tcp != NULL) { - if(packet->payload[0] == 0x00 && packet->payload[1] == 0x04 && + if(payload_len >= 8 && packet->payload[0] == 0x00 && packet->payload[1] == 0x04 && packet->payload[2] == 0x00 && packet->payload[3] == 0x00&& packet->payload[6] == 0x52 && packet->payload[7] == 0x0e && packet->payload[8] == 0x50 ) { diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c index 2269ae782..5632741e5 100644 --- a/src/lib/protocols/ssl.c +++ b/src/lib/protocols/ssl.c @@ -1,8 +1,7 @@ /* * ssl.c * - * Copyright (C) 2009-2011 by ipoque GmbH - * Copyright (C) 2011-15 - ntop.org + * Copyright (C) 2016 - ntop.org * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -35,6 +34,52 @@ extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +static u_int32_t ndpi_ssl_refine_master_protocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, u_int32_t protocol) +{ + struct ndpi_packet_struct *packet = &flow->packet; + + if((flow->protos.ssl.client_certificate[0] != '\0') + || (flow->protos.ssl.server_certificate[0] != '\0') + || (flow->host_server_name[0] != '\0')) + protocol = NDPI_PROTOCOL_SSL; + else + protocol = NDPI_PROTOCOL_SSL_NO_CERT; + + if(packet->tcp != NULL) { + switch(protocol) { + + case NDPI_PROTOCOL_SSL: + case NDPI_PROTOCOL_SSL_NO_CERT: + { + /* + In case of SSL there are probably sub-protocols + such as IMAPS that can be otherwise detected + */ + u_int16_t sport = ntohs(packet->tcp->source); + u_int16_t dport = ntohs(packet->tcp->dest); + + if((sport == 465) || (dport == 465)) + protocol = NDPI_PROTOCOL_MAIL_SMTPS; + else if((sport == 993) || (dport == 993) +#ifdef NDPI_PROTOCOL_MAIL_IMAP + || (flow->l4.tcp.mail_imap_starttls) +#endif + ) protocol = NDPI_PROTOCOL_MAIL_IMAPS; + else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS; + } + break; + } + + if((protocol == NDPI_PROTOCOL_SSL_NO_CERT) + && is_skype_flow(ndpi_struct, flow)) { + protocol = NDPI_PROTOCOL_SKYPE; + } + } + + return protocol; +} + static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int32_t protocol) { @@ -42,40 +87,7 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp && (protocol != NDPI_PROTOCOL_SSL_NO_CERT)) { ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } else { - struct ndpi_packet_struct *packet = &flow->packet; - - if((flow->protos.ssl.client_certificate[0] != '\0') - || (flow->protos.ssl.server_certificate[0] != '\0') - || (flow->host_server_name[0] != '\0')) - protocol = NDPI_PROTOCOL_SSL; - else - protocol = NDPI_PROTOCOL_SSL_NO_CERT; - - if(packet->tcp != NULL) { - switch(protocol) { - case NDPI_PROTOCOL_SSL: - case NDPI_PROTOCOL_SSL_NO_CERT: - { - /* - In case of SSL there are probably sub-protocols - such as IMAPS that can be otherwise detected - */ - u_int16_t sport = ntohs(packet->tcp->source); - u_int16_t dport = ntohs(packet->tcp->dest); - - if((sport == 465) || (dport == 465)) protocol = NDPI_PROTOCOL_MAIL_SMTPS; - else if((sport == 993) || (dport == 993)) protocol = NDPI_PROTOCOL_MAIL_IMAPS; - else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS; - } - break; - } - - if((protocol == NDPI_PROTOCOL_SSL_NO_CERT) - && is_skype_flow(ndpi_struct, flow)) { - protocol = NDPI_PROTOCOL_SKYPE; - } - } - + protocol = ndpi_ssl_refine_master_protocol(ndpi_struct, flow, protocol); ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN); } } @@ -86,20 +98,20 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp #define ndpi_isdigit(ch) ((ch) >= '0' && (ch) <= '9') #define ndpi_isspace(ch) (((ch) >= '\t' && (ch) <= '\r') || ((ch) == ' ')) #define ndpi_isprint(ch) ((ch) >= 0x20 && (ch) <= 0x7e) -#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ - ((ch) >= ':' && (ch) <= '@') || \ - ((ch) >= '[' && (ch) <= '`') || \ - ((ch) >= '{' && (ch) <= '~')) +#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ + ((ch) >= ':' && (ch) <= '@') || \ + ((ch) >= '[' && (ch) <= '`') || \ + ((ch) >= '{' && (ch) <= '~')) static void stripCertificateTrailer(char *buffer, int buffer_len) { - + int i, is_puny; - + // printf("->%s<-\n", buffer); - + for(i = 0; i < buffer_len; i++) { // printf("%c [%d]\n", buffer[i], buffer[i]); - + if((buffer[i] != '.') && (buffer[i] != '-') && (buffer[i] != '*') @@ -153,7 +165,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, /* Nothing matched so far: let's decode the certificate with some heuristics Patches courtesy of Denys Fedoryshchenko <nuclearcat@nuclearcat.com> - */ + */ if(packet->payload[0] == 0x16 /* Handshake */) { u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */; u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */ @@ -162,7 +174,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, /* Truncate total len, search at least in incomplete packet */ if(total_len > packet->payload_packet_len) - total_len = packet->payload_packet_len; + total_len = packet->payload_packet_len; /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */ if(total_len > 4) { @@ -223,69 +235,74 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, } } else if(handshake_protocol == 0x01 /* Client Hello */) { u_int offset, base_offset = 43; - u_int16_t session_id_len = packet->payload[base_offset]; + if (base_offset + 2 <= packet->payload_packet_len) + { + u_int16_t session_id_len = packet->payload[base_offset]; - if((session_id_len+base_offset+2) <= total_len) { - u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); - offset = base_offset + session_id_len + cypher_len + 2; + if((session_id_len+base_offset+2) <= total_len) { + u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); + offset = base_offset + session_id_len + cypher_len + 2; - flow->l4.tcp.ssl_seen_client_cert = 1; + flow->l4.tcp.ssl_seen_client_cert = 1; - if(offset < total_len) { - u_int16_t compression_len; - u_int16_t extensions_len; + if(offset < total_len) { + u_int16_t compression_len; + u_int16_t extensions_len; - compression_len = packet->payload[offset+1]; - offset += compression_len + 3; + compression_len = packet->payload[offset+1]; + offset += compression_len + 3; - if(offset < total_len) { - extensions_len = packet->payload[offset]; + if(offset < total_len) { + extensions_len = packet->payload[offset]; - if((extensions_len+offset) < total_len) { - u_int16_t extension_offset = 1; /* Move to the first extension */ + if((extensions_len+offset) < total_len) { + /* Move to the first extension + Type is u_int to avoid possible overflow on extension_len addition */ + u_int extension_offset = 1; - while(extension_offset < extensions_len) { - u_int16_t extension_id, extension_len; + while(extension_offset < extensions_len) { + u_int16_t extension_id, extension_len; - memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); - extension_offset += 2; + memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; - memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); - extension_offset += 2; + memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; - extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); + extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); - if(extension_id == 0) { - u_int begin = 0,len; - char *server_name = (char*)&packet->payload[offset+extension_offset]; + if(extension_id == 0) { + u_int begin = 0,len; + char *server_name = (char*)&packet->payload[offset+extension_offset]; - while(begin < extension_len) { - if((!ndpi_isprint(server_name[begin])) - || ndpi_ispunct(server_name[begin]) - || ndpi_isspace(server_name[begin])) - begin++; - else - break; - } + while(begin < extension_len) { + if((!ndpi_isprint(server_name[begin])) + || ndpi_ispunct(server_name[begin]) + || ndpi_isspace(server_name[begin])) + begin++; + else + break; + } - len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); - strncpy(buffer, &server_name[begin], len); - buffer[len] = '\0'; - stripCertificateTrailer(buffer, buffer_len); + len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); + strncpy(buffer, &server_name[begin], len); + buffer[len] = '\0'; + stripCertificateTrailer(buffer, buffer_len); - snprintf(flow->protos.ssl.client_certificate, - sizeof(flow->protos.ssl.client_certificate), "%s", buffer); + snprintf(flow->protos.ssl.client_certificate, + sizeof(flow->protos.ssl.client_certificate), "%s", buffer); - /* We're happy now */ - return(2 /* Client Certificate */); - } + /* We're happy now */ + return(2 /* Client Certificate */); + } - extension_offset += extension_len; + extension_offset += extension_len; + } + } } } } } - } } } } @@ -312,11 +329,14 @@ int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_s #ifdef CERTIFICATE_DEBUG printf("***** [SSL] %s\n", certificate); #endif - - if(ndpi_match_host_subprotocol(ndpi_struct, flow, certificate, - strlen(certificate), - NDPI_PROTOCOL_SSL) != NDPI_PROTOCOL_UNKNOWN) + u_int32_t subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, certificate, + strlen(certificate), NDPI_PROTOCOL_SSL); + + if(subproto != NDPI_PROTOCOL_UNKNOWN) { + ndpi_set_detected_protocol(ndpi_struct, flow, subproto, + ndpi_ssl_refine_master_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSL)); return(rc); /* Fix courtesy of Gianluca Costa <g.costa@xplico.org> */ + } #ifdef NDPI_PROTOCOL_TOR if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0) @@ -366,7 +386,7 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct if(memcmp(&packet->payload[a], "talk.google.com", 15) == 0) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n"); if(NDPI_COMPARE_PROTOCOL_TO_BITMASK - (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { + (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER); return; } @@ -375,18 +395,18 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct #endif #ifdef NDPI_PROTOCOL_OSCAR if(packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c' - || packet->payload[a] == 'h') { + || packet->payload[a] == 'h') { if(((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0) - // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) - // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) - || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) - || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) - || ((a + 41) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) - || ((a + 28) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) - || ((a + 32) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { + // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) + // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) + || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) + || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) + || ((a + 41) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) + || ((a + 28) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) + || ((a + 32) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); if(flow->dst != NULL && packet->payload_packet_len > 75) { @@ -402,8 +422,8 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct if(packet->payload[a] == 'm' || packet->payload[a] == 's') { if((a + 21) < packet->payload_packet_len && - (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 - || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { + (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 + || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); return; @@ -438,13 +458,13 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct if((packet->payload_packet_len >= 5) - && (packet->payload[0] == 0x16) - && (packet->payload[1] == 0x03) - && ((packet->payload[2] == 0x00) - || (packet->payload[2] == 0x01) - || (packet->payload[2] == 0x02) - || (packet->payload[2] == 0x03) - )) { + && (packet->payload[0] == 0x16) + && (packet->payload[1] == 0x03) + && ((packet->payload[2] == 0x00) + || (packet->payload[2] == 0x01) + || (packet->payload[2] == 0x02) + || (packet->payload[2] == 0x03) + )) { u_int32_t temp; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n"); // SSLv3 Record @@ -454,7 +474,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); if(packet->payload_packet_len == temp - || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { + || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { return 1; } @@ -499,7 +519,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct if(packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16) - && packet->payload[temp + 1] == 0x03) { + && packet->payload[temp + 1] == 0x03) { u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -510,7 +530,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct return 1; } if(packet->payload_packet_len >= temp + 5 && - packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -521,7 +541,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct return 1; } if(packet->payload_packet_len >= temp + 5 && - packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -590,16 +610,16 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n"); // SSLv2 Record if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03 - && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) - && (packet->payload_packet_len - packet->payload[1] == 2)) { + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - packet->payload[1] == 2)) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n"); flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; return; } if(packet->payload[0] == 0x16 && packet->payload[1] == 0x03 - && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02) - && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) { + && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02) + && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) { // SSLv3 Record NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n"); flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; @@ -608,8 +628,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc } if(packet->payload_packet_len > 40 && - flow->l4.tcp.ssl_stage == 1 + packet->packet_direction - && flow->packet_direction_counter[packet->packet_direction] < 5) { + flow->l4.tcp.ssl_stage == 1 + packet->packet_direction + && flow->packet_direction_counter[packet->packet_direction] < 5) { return; } @@ -617,8 +637,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n"); // SSLv2 Record if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03 - && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) - && (packet->payload_packet_len - 2) >= packet->payload[1]) { + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - 2) >= packet->payload[1]) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n"); ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); return; diff --git a/src/lib/protocols/starcraft.c b/src/lib/protocols/starcraft.c index f96853f23..760578563 100644 --- a/src/lib/protocols/starcraft.c +++ b/src/lib/protocols/starcraft.c @@ -49,9 +49,8 @@ u_int8_t ndpi_check_starcraft_tcp(struct ndpi_detection_module_struct* ndpi_stru { if (sc2_match_logon_ip(&flow->packet) && flow->packet.tcp->dest == htons(1119) //bnetgame port - && flow->packet.payload_packet_len >= 10 - && (match_first_bytes(flow->packet.payload, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66") - || match_first_bytes(flow->packet.payload, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66"))) + && (ndpi_match_strprefix(flow->packet.payload, flow->packet.payload_packet_len, "\x4a\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66") + || ndpi_match_strprefix(flow->packet.payload, flow->packet.payload_packet_len, "\x49\x00\x00\x0a\x66\x02\x0a\xed\x2d\x66"))) return 1; else return -1; diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c index 7ed0eae29..d12a0cb4b 100644 --- a/src/lib/protocols/steam.c +++ b/src/lib/protocols/steam.c @@ -50,7 +50,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc if (flow->steam_stage == 0) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) { + if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -58,7 +58,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc return; } - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { + if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -74,7 +74,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && (packet->payload[0] == 0x00) && (packet->payload[1] == 0x00) && (packet->payload[2] == 0x00)) { + if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -90,7 +90,7 @@ static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struc } /* This is a packet in another direction. Check if we find the proper response. */ - if (((payload_len == 1) || (payload_len == 4) || (payload_len == 5)) && match_first_bytes(packet->payload, "\x01\x00\x00\x00")) { + if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -104,7 +104,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru struct ndpi_packet_struct *packet = &flow->packet; u_int32_t payload_len = packet->payload_packet_len; - if ((payload_len > 0) && match_first_bytes(packet->payload, "VS01")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "VS01")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); return; @@ -114,7 +114,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru if (flow->steam_stage1 == 0) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -122,7 +122,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru return; } - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -139,7 +139,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -156,7 +156,7 @@ static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_stru } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len > 0) && match_first_bytes(packet->payload, "\x31\xff\x30\x2e")) { + if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { @@ -175,7 +175,7 @@ static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_stru if (flow->steam_stage2 == 0) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "STEAM stage 0: \n"); - if ((payload_len == 25) && match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if ((payload_len == 25) && ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Possible STEAM request detected, we will look further for the response...\n"); /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ @@ -191,7 +191,7 @@ static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_stru } /* This is a packet in another direction. Check if we find the proper response. */ - if ((payload_len == 0) || match_first_bytes(packet->payload, "\xff\xff\xff\xff")) { + if ((payload_len == 0) || ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) { NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "Found STEAM.\n"); ndpi_int_steam_add_connection(ndpi_struct, flow); } else { diff --git a/src/lib/protocols/teredo.c b/src/lib/protocols/teredo.c index 9fb2c6483..079d1fbcd 100644 --- a/src/lib/protocols/teredo.c +++ b/src/lib/protocols/teredo.c @@ -29,6 +29,8 @@ void ndpi_search_teredo(struct ndpi_detection_module_struct *ndpi_struct, struct struct ndpi_packet_struct *packet = &flow->packet; if(packet->udp + && packet->iph + && ((ntohl(packet->iph->daddr) & 0xF0000000) == 0xE0000000 /* A multicast address */) && ((ntohs(packet->udp->source) == 3544) || (ntohs(packet->udp->dest) == 3544)) && (packet->payload_packet_len >= 40 /* IPv6 header */)) ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEREDO, NDPI_PROTOCOL_UNKNOWN); diff --git a/src/lib/protocols/tor.c b/src/lib/protocols/tor.c index 7903bf511..2152da328 100644 --- a/src/lib/protocols/tor.c +++ b/src/lib/protocols/tor.c @@ -1,7 +1,7 @@ /* * tor.c * - * Copyright (C) 2015 ntop.org + * Copyright (C) 2016 ntop.org * Copyright (C) 2013 Remy Mudingay <mudingay@ill.fr> * */ @@ -24,7 +24,7 @@ int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct, if((certificate == NULL) || (strlen(certificate) < 6) - || !(strncmp(certificate, "www.", 4))) + || (strncmp(certificate, "www.", 4))) return(0); // printf("***** [SSL] %s(): %s\n", __FUNCTION__, certificate); @@ -39,10 +39,11 @@ int ndpi_is_ssl_tor(struct ndpi_detection_module_struct *ndpi_struct, len = strlen(name); - if(len > 6) { + if(len >= 5) { for(i = 0; name[i+1] != '\0'; i++) { + // printf("***** [SSL] %s(): [%d][%c]", __FUNCTION__, i, name[i]); + if((name[i] >= '0') && (name[i] <= '9')) { - if(prev_num != 1) { numbers_found++; diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 000000000..a8a127088 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,3 @@ +TESTS = do.sh + +EXTRA_DIST = do.sh pcap result diff --git a/tests/pcap/Meu.pcap b/tests/pcap/Meu.pcap Binary files differdeleted file mode 100644 index 9c724928a..000000000 --- a/tests/pcap/Meu.pcap +++ /dev/null diff --git a/tests/pcap/Torcedor.pcap b/tests/pcap/Torcedor.pcap Binary files differdeleted file mode 100644 index 7d7f03a1d..000000000 --- a/tests/pcap/Torcedor.pcap +++ /dev/null diff --git a/tests/pcap/drda_db2.pcap b/tests/pcap/drda_db2.pcap Binary files differnew file mode 100755 index 000000000..e91629e04 --- /dev/null +++ b/tests/pcap/drda_db2.pcap diff --git a/tests/pcap/facebook.pcap b/tests/pcap/facebook.pcap Binary files differnew file mode 100644 index 000000000..153d497a3 --- /dev/null +++ b/tests/pcap/facebook.pcap diff --git a/tests/pcap/git.pcap b/tests/pcap/git.pcap Binary files differnew file mode 100644 index 000000000..b32a255ef --- /dev/null +++ b/tests/pcap/git.pcap diff --git a/tests/pcap/hangout.pcap b/tests/pcap/hangout.pcap Binary files differnew file mode 100644 index 000000000..9f3482679 --- /dev/null +++ b/tests/pcap/hangout.pcap diff --git a/tests/pcap/openvpn.pcap b/tests/pcap/openvpn.pcap Binary files differnew file mode 100644 index 000000000..9ae8351a1 --- /dev/null +++ b/tests/pcap/openvpn.pcap diff --git a/tests/pcap/quic.pcap b/tests/pcap/quic.pcap Binary files differindex 5de878c1a..1b1994a70 100644 --- a/tests/pcap/quic.pcap +++ b/tests/pcap/quic.pcap diff --git a/tests/pcap/rx.pcap b/tests/pcap/rx.pcap Binary files differnew file mode 100644 index 000000000..68fd825ac --- /dev/null +++ b/tests/pcap/rx.pcap diff --git a/tests/pcap/tor.pcap b/tests/pcap/tor.pcap Binary files differnew file mode 100644 index 000000000..bf5b43649 --- /dev/null +++ b/tests/pcap/tor.pcap diff --git a/tests/pcap/weibo.pcap b/tests/pcap/weibo.pcap Binary files differnew file mode 100644 index 000000000..44ab450c9 --- /dev/null +++ b/tests/pcap/weibo.pcap diff --git a/tests/result/Instagram.pcap.out b/tests/result/Instagram.pcap.out index 3e349a331..a715b8f7f 100644 --- a/tests/result/Instagram.pcap.out +++ b/tests/result/Instagram.pcap.out @@ -2,40 +2,40 @@ Unknown 1 66 1 HTTP 266 245342 7 ICMP 5 510 1 SSL 103 62597 5 -DropBox 5 725 2 +Dropbox 5 725 2 Instagram 363 255094 16 - 1 UDP 192.168.0.106:17500 <-> 192.168.0.255:17500 [proto: 121/DropBox][1 pkts/145 bytes] - 2 UDP 8.8.8.8:53 <-> 192.168.0.103:26540 [proto: 5.211/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-g-a.akamaihd.net] - 3 UDP 8.8.8.8:53 <-> 192.168.0.103:27124 [proto: 5.211/DNS.Instagram][1 pkts/85 bytes][Host: photos-b.ak.instagram.com] + 1 UDP 192.168.0.106:17500 <-> 192.168.0.255:17500 [proto: 121/Dropbox][1 pkts/145 bytes] + 2 UDP 8.8.8.8:53 <-> 192.168.0.103:26540 [proto: 5.201/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-g-a.akamaihd.net] + 3 UDP 8.8.8.8:53 <-> 192.168.0.103:27124 [proto: 5.201/DNS.Instagram][1 pkts/85 bytes][Host: photos-b.ak.instagram.com] 4 TCP 31.13.93.52:443 <-> 192.168.0.103:33763 [proto: 91/SSL][11 pkts/5397 bytes] 5 TCP 31.13.93.52:443 <-> 192.168.0.103:33935 [proto: 91/SSL][10 pkts/5299 bytes] 6 TCP 2.22.236.51:80 <-> 192.168.0.103:44151 [proto: 7/HTTP][49 pkts/38684 bytes] - 7 TCP 192.168.0.103:38816 <-> 46.33.70.160:80 [proto: 7.211/HTTP.Instagram][52 pkts/58994 bytes][Host: photos-h.ak.instagram.com] + 7 TCP 192.168.0.103:38816 <-> 46.33.70.160:80 [proto: 7.201/HTTP.Instagram][52 pkts/58994 bytes][Host: photos-h.ak.instagram.com] 8 TCP 77.67.29.17:80 <-> 192.168.0.103:33976 [proto: 7/HTTP][34 pkts/29039 bytes] - 9 TCP 192.168.0.103:37350 <-> 82.85.26.153:80 [proto: 7.211/HTTP.Instagram][1 pkts/324 bytes][Host: photos-a.ak.instagram.com] - 10 TCP 192.168.0.103:41181 <-> 82.85.26.154:443 [proto: 91.211/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net] + 9 TCP 192.168.0.103:37350 <-> 82.85.26.153:80 [proto: 7.201/HTTP.Instagram][1 pkts/324 bytes][Host: photos-a.ak.instagram.com] + 10 TCP 192.168.0.103:41181 <-> 82.85.26.154:443 [proto: 91.201/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net] 11 TCP 31.13.86.52:80 <-> 192.168.0.103:58216 [proto: 7/HTTP][150 pkts/153558 bytes] - 12 TCP 192.168.0.103:57936 <-> 82.85.26.162:80 [proto: 7.211/HTTP.Instagram][58 pkts/50220 bytes][Host: photos-g.ak.instagram.com] + 12 TCP 192.168.0.103:57936 <-> 82.85.26.162:80 [proto: 7.201/HTTP.Instagram][58 pkts/50220 bytes][Host: photos-g.ak.instagram.com] 13 TCP 192.168.0.103:57966 <-> 82.85.26.185:80 [proto: 7/HTTP][3 pkts/198 bytes] - 14 TCP 192.168.0.103:58052 <-> 82.85.26.162:80 [proto: 7.211/HTTP.Instagram][75 pkts/57239 bytes][Host: photos-g.ak.instagram.com] - 15 TCP 173.252.107.4:443 <-> 192.168.0.103:56382 [proto: 91.211/SSL.Instagram][17 pkts/2647 bytes][SSL client: telegraph-ash.instagram.com] - 16 UDP 192.168.0.106:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][4 pkts/580 bytes] - 17 UDP 8.8.8.8:53 <-> 192.168.0.103:33603 [proto: 5.211/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-a-a.akamaihd.net] + 14 TCP 192.168.0.103:58052 <-> 82.85.26.162:80 [proto: 7.201/HTTP.Instagram][75 pkts/57239 bytes][Host: photos-g.ak.instagram.com] + 15 TCP 173.252.107.4:443 <-> 192.168.0.103:56382 [proto: 91.201/SSL.Instagram][17 pkts/2647 bytes][SSL client: telegraph-ash.instagram.com] + 16 UDP 192.168.0.106:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][4 pkts/580 bytes] + 17 UDP 8.8.8.8:53 <-> 192.168.0.103:33603 [proto: 5.201/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-a-a.akamaihd.net] 18 TCP 31.13.93.52:443 <-> 192.168.0.103:33936 [proto: 91/SSL][68 pkts/45688 bytes] 19 TCP 31.13.93.52:443 <-> 192.168.0.103:33934 [proto: 91/SSL][12 pkts/6044 bytes] 20 ICMP 192.168.0.103:0 <-> 192.168.0.103:0 [proto: 81/ICMP][5 pkts/510 bytes] 21 TCP 192.168.0.103:38817 <-> 46.33.70.160:80 [proto: 7/HTTP][3 pkts/198 bytes] 22 TCP 192.168.0.103:40855 <-> 46.33.70.150:80 [proto: 7/HTTP][2 pkts/140 bytes] - 23 UDP 8.8.8.8:53 <-> 192.168.0.103:51219 [proto: 5.211/DNS.Instagram][2 pkts/394 bytes][Host: igcdn-photos-h-a.akamaihd.net] - 24 TCP 192.168.0.103:44558 <-> 46.33.70.174:443 [proto: 91.211/SSL.Instagram][17 pkts/6369 bytes][SSL client: igcdn-photos-h-a.akamaihd.net] - 25 TCP 192.168.0.103:41182 <-> 82.85.26.154:443 [proto: 91.211/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net] + 23 UDP 8.8.8.8:53 <-> 192.168.0.103:51219 [proto: 5.201/DNS.Instagram][2 pkts/394 bytes][Host: igcdn-photos-h-a.akamaihd.net] + 24 TCP 192.168.0.103:44558 <-> 46.33.70.174:443 [proto: 91.201/SSL.Instagram][17 pkts/6369 bytes][SSL client: igcdn-photos-h-a.akamaihd.net] + 25 TCP 192.168.0.103:41182 <-> 82.85.26.154:443 [proto: 91.201/SSL.Instagram][14 pkts/5567 bytes][SSL client: igcdn-photos-a-a.akamaihd.net] 26 TCP 192.168.0.103:41562 <-> 92.122.48.138:80 [proto: 7/HTTP][25 pkts/23525 bytes] - 27 TCP 192.168.0.103:44379 <-> 82.85.26.186:80 [proto: 7.211/HTTP.Instagram][81 pkts/53416 bytes][Host: photos-e.ak.instagram.com] + 27 TCP 192.168.0.103:44379 <-> 82.85.26.186:80 [proto: 7.201/HTTP.Instagram][81 pkts/53416 bytes][Host: photos-e.ak.instagram.com] 28 TCP 192.168.0.103:58690 <-> 46.33.70.159:443 [proto: 91/SSL][2 pkts/169 bytes] - 29 TCP 192.168.0.103:60908 <-> 46.33.70.136:443 [proto: 91.211/SSL.Instagram][19 pkts/9340 bytes][SSL client: igcdn-photos-g-a.akamaihd.net] - 30 TCP 192.168.0.103:57965 <-> 82.85.26.185:80 [proto: 7.211/HTTP.Instagram][7 pkts/4015 bytes][Host: photos-f.ak.instagram.com] - 31 TCP 192.168.0.103:58053 <-> 82.85.26.162:80 [proto: 7.211/HTTP.Instagram][1 pkts/321 bytes][Host: photos-g.ak.instagram.com] + 29 TCP 192.168.0.103:60908 <-> 46.33.70.136:443 [proto: 91.201/SSL.Instagram][19 pkts/9340 bytes][SSL client: igcdn-photos-g-a.akamaihd.net] + 30 TCP 192.168.0.103:57965 <-> 82.85.26.185:80 [proto: 7.201/HTTP.Instagram][7 pkts/4015 bytes][Host: photos-f.ak.instagram.com] + 31 TCP 192.168.0.103:58053 <-> 82.85.26.162:80 [proto: 7.201/HTTP.Instagram][1 pkts/321 bytes][Host: photos-g.ak.instagram.com] Undetected flows: diff --git a/tests/result/Meu.pcap.out b/tests/result/Meu.pcap.out deleted file mode 100644 index 788681ba2..000000000 --- a/tests/result/Meu.pcap.out +++ /dev/null @@ -1,28 +0,0 @@ -TIM_Meu 814 658545 26 - - 1 TCP 10.8.0.1:55226 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][62 pkts/31584 bytes][SSL client: appmeutim.tim.com.br] - 2 TCP 10.8.0.1:55230 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][27 pkts/11642 bytes][SSL client: appmeutim.tim.com.br] - 3 TCP 10.8.0.1:55232 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][37 pkts/37269 bytes][SSL client: appmeutim.tim.com.br] - 4 TCP 10.8.0.1:55234 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][21 pkts/9350 bytes][SSL client: appmeutim.tim.com.br] - 5 TCP 10.8.0.1:55236 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][13 pkts/1181 bytes][SSL client: appmeutim.tim.com.br] - 6 TCP 10.8.0.1:55238 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][13 pkts/1181 bytes][SSL client: appmeutim.tim.com.br] - 7 TCP 10.8.0.1:55250 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][22 pkts/9903 bytes][SSL client: appmeutim.tim.com.br] - 8 TCP 10.8.0.1:55252 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][34 pkts/20796 bytes][SSL client: appmeutim.tim.com.br] - 9 TCP 10.8.0.1:55254 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][27 pkts/8864 bytes][SSL client: appmeutim.tim.com.br] - 10 TCP 10.8.0.1:55262 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br] - 11 TCP 10.8.0.1:55264 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br] - 12 TCP 10.8.0.1:55268 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][26 pkts/6969 bytes][SSL client: appmeutim.tim.com.br] - 13 TCP 10.8.0.1:55270 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][56 pkts/36838 bytes][SSL client: appmeutim.tim.com.br] - 14 TCP 10.8.0.1:55272 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][53 pkts/142338 bytes][SSL client: appmeutim.tim.com.br] - 15 TCP 10.8.0.1:55276 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][20 pkts/7059 bytes][SSL client: appmeutim.tim.com.br] - 16 TCP 10.8.0.1:55227 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][41 pkts/19844 bytes][SSL client: appmeutim.tim.com.br] - 17 TCP 10.8.0.1:55231 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][33 pkts/14083 bytes][SSL client: appmeutim.tim.com.br] - 18 TCP 10.8.0.1:55233 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][96 pkts/137364 bytes][SSL client: appmeutim.tim.com.br] - 19 TCP 10.8.0.1:55235 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][19 pkts/5178 bytes][SSL client: appmeutim.tim.com.br] - 20 TCP 10.8.0.1:55237 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][13 pkts/1181 bytes][SSL client: appmeutim.tim.com.br] - 21 TCP 10.8.0.1:55239 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][85 pkts/122532 bytes][SSL client: appmeutim.tim.com.br] - 22 TCP 10.8.0.1:55251 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][20 pkts/6243 bytes][SSL client: appmeutim.tim.com.br] - 23 TCP 10.8.0.1:55253 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br] - 24 TCP 10.8.0.1:55255 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][17 pkts/4594 bytes][SSL client: appmeutim.tim.com.br] - 25 TCP 10.8.0.1:55263 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][15 pkts/4486 bytes][SSL client: appmeutim.tim.com.br] - 26 TCP 10.8.0.1:55273 <-> 189.40.216.95:443 [proto: 91.191/SSL.TIM_Meu][19 pkts/4608 bytes][SSL client: appmeutim.tim.com.br] diff --git a/tests/result/NTPv3.pcap.out b/tests/result/NTPv3.pcap.out index dcf9eafda..91d817e5e 100644 --- a/tests/result/NTPv3.pcap.out +++ b/tests/result/NTPv3.pcap.out @@ -1,3 +1,3 @@ -Quic 1 90 1 +NTP 1 90 1 - 1 UDP 78.46.76.2:80 <-> 175.144.140.29:123 [proto: 188/Quic][1 pkts/90 bytes] + 1 UDP 78.46.76.2:80 <-> 175.144.140.29:123 [proto: 9/NTP][1 pkts/90 bytes] diff --git a/tests/result/Torcedor.pcap.out b/tests/result/Torcedor.pcap.out deleted file mode 100644 index 17528c48c..000000000 --- a/tests/result/Torcedor.pcap.out +++ /dev/null @@ -1,10 +0,0 @@ -HTTP 4 216 1 -SSL 26 1558 2 -Torcedor 55 67338 3 - - 1 TCP 10.8.0.1:55944 <-> 52.25.136.177:80 [proto: 7.192/HTTP.Torcedor][7 pkts/1118 bytes][Host: usuario.timtorcedor.com.br] - 2 TCP 10.8.0.1:53114 <-> 31.13.85.8:443 [proto: 91/SSL][4 pkts/216 bytes] - 3 TCP 10.8.0.1:56117 <-> 52.25.136.177:80 [proto: 7.192/HTTP.Torcedor][23 pkts/33056 bytes][Host: usuario.timtorcedor.com.br] - 4 TCP 10.8.0.1:40016 <-> 158.85.58.105:443 [proto: 91/SSL][22 pkts/1342 bytes] - 5 TCP 10.8.0.1:33415 <-> 187.109.32.201:80 [proto: 7/HTTP][4 pkts/216 bytes] - 6 TCP 10.8.0.1:39422 <-> 54.149.207.220:80 [proto: 7.192/HTTP.Torcedor][25 pkts/33164 bytes][Host: usuario.timtorcedor.com.br] diff --git a/tests/result/Viber_session.pcap.out b/tests/result/Viber_session.pcap.out index 89bdd3a92..e73acc6f4 100644 --- a/tests/result/Viber_session.pcap.out +++ b/tests/result/Viber_session.pcap.out @@ -3,7 +3,7 @@ HTTP 14 862 8 SSL_No_Cert 34 4141 1 ICMP 2 196 1 SSL 109 11647 10 -DropBox 1 97 1 +Dropbox 1 97 1 GMail 21 1891 1 Google 50 4084 5 Viber 4163 392492 4 @@ -37,7 +37,7 @@ Viber 4163 392492 4 27 UDP 54.169.63.186:7987 <-> 192.168.200.222:48564 [proto: 144/Viber][2 pkts/138 bytes] 28 UDP 54.169.63.186:7985 <-> 192.168.200.222:48564 [proto: 144/Viber][4143 pkts/390781 bytes] 29 TCP 93.184.221.200:80 <-> 192.168.200.222:50854 [proto: 7/HTTP][1 pkts/60 bytes] - 30 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.DropBox][1 pkts/97 bytes] + 30 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.Dropbox][1 pkts/97 bytes] 31 TCP 107.22.192.179:443 <-> 192.168.200.222:52269 [proto: 91/SSL][16 pkts/1419 bytes][SSL client: settings.crashlytics.com] diff --git a/tests/result/coap_mqtt.pcap.out b/tests/result/coap_mqtt.pcap.out index 2e6f7abc9..a9bd983e1 100644 --- a/tests/result/coap_mqtt.pcap.out +++ b/tests/result/coap_mqtt.pcap.out @@ -1,19 +1,20 @@ -COAP 819 82290 12 +COAP 19 1614 8 +Dropbox 800 80676 4 MQTT 7695 668291 4 1 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61043 [proto: 27/COAP][1 pkts/86 bytes] 2 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61045 [proto: 27/COAP][1 pkts/86 bytes] 3 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61047 [proto: 27/COAP][1 pkts/90 bytes] - 4 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20220 bytes] - 5 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20194 bytes] - 6 TCP 192.168.56.1:53523 <-> 192.168.56.101:17501 [proto: 222/MQTT][1926 pkts/167126 bytes] + 4 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20220 bytes] + 5 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20194 bytes] + 6 TCP 192.168.56.1:53523 <-> 192.168.56.101:17501 [proto: 208/MQTT][1926 pkts/167126 bytes] 7 UDP [bbbb::1]:33499 <-> [bbbb::3]:5683 [proto: 27/COAP][4 pkts/404 bytes] 8 UDP [bbbb::1]:46819 <-> [bbbb::3]:5683 [proto: 27/COAP][6 pkts/467 bytes] 9 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61044 [proto: 27/COAP][1 pkts/86 bytes] 10 UDP [2001:da8:215:1171:a10b:cb48:8f83:57f6]:5683 <-> [2001:620:8:35d9::10]:61046 [proto: 27/COAP][1 pkts/86 bytes] - 11 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20120 bytes] - 12 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20142 bytes] - 13 TCP 192.168.56.1:53522 <-> 192.168.56.101:17501 [proto: 222/MQTT][1922 pkts/166928 bytes] - 14 TCP 192.168.56.1:53528 <-> 192.168.56.101:17501 [proto: 222/MQTT][1928 pkts/167509 bytes] - 15 TCP 192.168.56.1:53524 <-> 192.168.56.101:17501 [proto: 222/MQTT][1919 pkts/166728 bytes] + 11 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20120 bytes] + 12 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20142 bytes] + 13 TCP 192.168.56.1:53522 <-> 192.168.56.101:17501 [proto: 208/MQTT][1922 pkts/166928 bytes] + 14 TCP 192.168.56.1:53528 <-> 192.168.56.101:17501 [proto: 208/MQTT][1928 pkts/167509 bytes] + 15 TCP 192.168.56.1:53524 <-> 192.168.56.101:17501 [proto: 208/MQTT][1919 pkts/166728 bytes] 16 UDP [bbbb::1]:50250 <-> [bbbb::3]:5683 [proto: 27/COAP][4 pkts/309 bytes] diff --git a/tests/result/drda_db2.pcap.out b/tests/result/drda_db2.pcap.out new file mode 100644 index 000000000..2543776b2 --- /dev/null +++ b/tests/result/drda_db2.pcap.out @@ -0,0 +1,3 @@ +DRDA 38 6691 1 + + 1 TCP 192.168.106.1:4847 <-> 192.168.106.128:50000 [proto: 192/DRDA][38 pkts/6691 bytes] diff --git a/tests/result/dropbox.pcap.out b/tests/result/dropbox.pcap.out index 343ba0ad5..c8b862513 100644 --- a/tests/result/dropbox.pcap.out +++ b/tests/result/dropbox.pcap.out @@ -1,17 +1,16 @@ MDNS 16 1648 1 SSDP 140 61108 22 -COAP 800 80676 4 -DropBox 304 165446 12 +Dropbox 1104 246122 16 - 1 UDP 192.168.1.105:33189 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/744 bytes][Host: notify.dropbox.com] - 2 UDP 192.168.1.105:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][6 pkts/1422 bytes] - 3 TCP 192.168.1.105:59975 <-> 108.160.172.204:443 [proto: 91.121/SSL.DropBox][34 pkts/18026 bytes][SSL client: client.dropbox.com] - 4 UDP 192.168.1.105:36173 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][8 pkts/1390 bytes][Host: log.getdropbox.com] - 5 TCP 192.168.1.105:46394 <-> 162.125.17.131:443 [proto: 91.121/SSL.DropBox][22 pkts/11392 bytes][SSL client: notify.dropbox.com] - 6 UDP 192.168.1.105:50789 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/792 bytes][Host: d.dropbox.com] - 7 UDP 192.168.1.105:55407 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/822 bytes][Host: client.dropbox.com] - 8 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20220 bytes] - 9 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20194 bytes] + 1 UDP 192.168.1.105:33189 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/744 bytes][Host: notify.dropbox.com] + 2 UDP 192.168.1.105:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][6 pkts/1422 bytes] + 3 TCP 192.168.1.105:59975 <-> 108.160.172.204:443 [proto: 91.121/SSL.Dropbox][34 pkts/18026 bytes][SSL client: client.dropbox.com] + 4 UDP 192.168.1.105:36173 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][8 pkts/1390 bytes][Host: log.getdropbox.com] + 5 TCP 192.168.1.105:46394 <-> 162.125.17.131:443 [proto: 91.121/SSL.Dropbox][22 pkts/11392 bytes][SSL client: notify.dropbox.com] + 6 UDP 192.168.1.105:50789 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/792 bytes][Host: d.dropbox.com] + 7 UDP 192.168.1.105:55407 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/822 bytes][Host: client.dropbox.com] + 8 UDP 192.168.56.1:50318 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20220 bytes] + 9 UDP 192.168.56.1:50312 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20194 bytes] 10 UDP 192.168.1.101:1280 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes] 11 UDP 192.168.1.101:1346 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes] 12 UDP 192.168.1.101:1650 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes] @@ -20,14 +19,14 @@ DropBox 304 165446 12 15 UDP 192.168.1.101:2604 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes] 16 UDP 192.168.1.101:3412 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes] 17 UDP 192.168.1.101:4974 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes] - 18 UDP 192.168.1.105:49112 <-> 192.168.1.254:53 [proto: 5.121/DNS.DropBox][4 pkts/774 bytes][Host: client-cf.dropbox.com] - 19 UDP 192.168.1.105:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][6 pkts/1422 bytes] + 18 UDP 192.168.1.105:49112 <-> 192.168.1.254:53 [proto: 5.121/DNS.Dropbox][4 pkts/774 bytes][Host: client-cf.dropbox.com] + 19 UDP 192.168.1.105:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][6 pkts/1422 bytes] 20 UDP 239.255.255.250:1900 <-> 192.168.1.254:50828 [proto: 12/SSDP][44 pkts/19936 bytes] - 21 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20120 bytes] - 22 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 27/COAP][200 pkts/20142 bytes] + 21 UDP 192.168.56.1:50311 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20120 bytes] + 22 UDP 192.168.56.1:50319 <-> 192.168.56.101:17500 [proto: 121/Dropbox][200 pkts/20142 bytes] 23 UDP 192.168.1.106:57268 <-> 239.255.255.250:1900 [proto: 12/SSDP][16 pkts/2632 bytes] - 24 TCP 54.240.174.31:443 <-> 192.168.1.105:44949 [proto: 91.121/SSL.DropBox][138 pkts/97302 bytes][SSL client: client-cf.dropbox.com] - 25 TCP 192.168.1.105:36226 <-> 108.160.172.195:80 [proto: 7.121/HTTP.DropBox][20 pkts/3928 bytes][Host: log.getdropbox.com] + 24 TCP 54.240.174.31:443 <-> 192.168.1.105:44949 [proto: 91.121/SSL.Dropbox][138 pkts/97302 bytes][SSL client: client-cf.dropbox.com] + 25 TCP 192.168.1.105:36226 <-> 108.160.172.195:80 [proto: 7.121/HTTP.Dropbox][20 pkts/3928 bytes][Host: log.getdropbox.com] 26 UDP 192.168.1.101:2169 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes] 27 UDP 192.168.1.101:2141 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes] 28 UDP 192.168.1.101:2159 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/1018 bytes] @@ -41,4 +40,4 @@ DropBox 304 165446 12 36 UDP 192.168.1.101:4169 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes] 37 UDP 192.168.1.106:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][16 pkts/1648 bytes] 38 UDP 192.168.1.101:4625 <-> 239.255.255.250:1900 [proto: 12/SSDP][6 pkts/2836 bytes] - 39 TCP 192.168.1.105:47747 <-> 108.160.172.225:443 [proto: 91.121/SSL.DropBox][54 pkts/27432 bytes][SSL client: d.dropbox.com] + 39 TCP 192.168.1.105:47747 <-> 108.160.172.225:443 [proto: 91.121/SSL.Dropbox][54 pkts/27432 bytes][SSL client: d.dropbox.com] diff --git a/tests/result/facebook.pcap.out b/tests/result/facebook.pcap.out new file mode 100644 index 000000000..ad3cbdaad --- /dev/null +++ b/tests/result/facebook.pcap.out @@ -0,0 +1,4 @@ +Facebook 60 30511 2 + + 1 TCP 192.168.43.18:52066 <-> 66.220.156.68:443 [proto: 91.119/SSL.Facebook][19 pkts/5745 bytes][SSL client: facebook.com] + 2 TCP 192.168.43.18:44614 <-> 31.13.86.36:443 [proto: 91.119/SSL.Facebook][41 pkts/24766 bytes][SSL client: www.facebook.com] diff --git a/tests/result/git.pcap.out b/tests/result/git.pcap.out new file mode 100644 index 000000000..1df4f5da9 --- /dev/null +++ b/tests/result/git.pcap.out @@ -0,0 +1,3 @@ +Git 90 74005 1 + + 1 TCP 5.153.231.21:9418 <-> 192.168.0.77:47991 [proto: 191/Git][90 pkts/74005 bytes] diff --git a/tests/result/hangout.pcap.out b/tests/result/hangout.pcap.out new file mode 100644 index 000000000..481ddfe3c --- /dev/null +++ b/tests/result/hangout.pcap.out @@ -0,0 +1,3 @@ +GoogleHangout 19 2774 1 + + 1 UDP 10.89.61.13:56406 <-> 74.125.134.127:19305 [proto: 215/GoogleHangout][19 pkts/2774 bytes] diff --git a/tests/result/http_ipv6.pcap.out b/tests/result/http_ipv6.pcap.out index 77bc0d9db..8117cef8e 100644 --- a/tests/result/http_ipv6.pcap.out +++ b/tests/result/http_ipv6.pcap.out @@ -1,6 +1,7 @@ SSL 106 39646 11 Facebook 22 10202 2 -Quic 65 16479 2 +Google 62 15977 1 +QUIC 3 502 1 1 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:33062 <-> [2a00:1450:400b:c02::9a]:443 [proto: 91/SSL][2 pkts/172 bytes] 2 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a03:b0c0:3:d0::70:1001]:37486 [proto: 91/SSL][19 pkts/7014 bytes][SSL client: www.ntop.org] @@ -15,5 +16,5 @@ Quic 65 16479 2 11 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a00:1450:4001:803::1012]:59690 [proto: 91/SSL][2 pkts/172 bytes] 12 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:60124 <-> [2a02:26f0:ad:1a1::eed]:443 [proto: 91/SSL][2 pkts/172 bytes] 13 TCP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:40308 <-> [2a03:2880:1010:3f20:face:b00c::25de]:443 [proto: 91/SSL][2 pkts/172 bytes] - 14 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a00:1450:4001:803::1017]:45931 [proto: 188/Quic][62 pkts/15977 bytes] - 15 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:55145 <-> [2a00:1450:400b:c02::5f]:443 [proto: 188/Quic][3 pkts/502 bytes] + 14 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:443 <-> [2a00:1450:4001:803::1017]:45931 [proto: 188.126/QUIC.Google][62 pkts/15977 bytes][Host: www.google.it] + 15 UDP [2a00:d40:1:3:7aac:c0ff:fea7:d4c]:55145 <-> [2a00:1450:400b:c02::5f]:443 [proto: 188/QUIC][3 pkts/502 bytes] diff --git a/tests/result/ocs.pcap.out b/tests/result/ocs.pcap.out index 253583c88..e65f45829 100644 --- a/tests/result/ocs.pcap.out +++ b/tests/result/ocs.pcap.out @@ -5,21 +5,21 @@ SSL 45 5771 3 Google 14 2349 3 OCS 863 57552 7 - 1 TCP 192.168.180.2:42590 <-> 178.248.208.210:80 [proto: 7.218/HTTP.OCS][83 pkts/5408 bytes][Host: www.ocs.fr] - 2 TCP 192.168.180.2:48250 <-> 178.248.208.54:80 [proto: 7.218/HTTP.OCS][6 pkts/1092 bytes][Host: ocu03.labgency.ws] + 1 TCP 192.168.180.2:42590 <-> 178.248.208.210:80 [proto: 7.204/HTTP.OCS][83 pkts/5408 bytes][Host: www.ocs.fr] + 2 TCP 192.168.180.2:48250 <-> 178.248.208.54:80 [proto: 7.204/HTTP.OCS][6 pkts/1092 bytes][Host: ocu03.labgency.ws] 3 TCP 192.168.180.2:41223 <-> 216.58.208.46:443 [proto: 91/SSL][13 pkts/1448 bytes] - 4 UDP 192.168.180.2:38472 <-> 8.8.8.8:53 [proto: 5.218/DNS.OCS][1 pkts/63 bytes][Host: ocu03.labgency.ws] + 4 UDP 192.168.180.2:38472 <-> 8.8.8.8:53 [proto: 5.204/DNS.OCS][1 pkts/63 bytes][Host: ocu03.labgency.ws] 5 TCP 192.168.180.2:39263 <-> 23.21.230.199:443 [proto: 91/SSL][20 pkts/2715 bytes][SSL client: settings.crashlytics.com] 6 UDP 192.168.180.2:48770 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][1 pkts/72 bytes][Host: android.clients.google.com] 7 TCP 192.168.180.2:47803 <-> 64.233.166.95:443 [proto: 91/SSL][12 pkts/1608 bytes] 8 UDP 192.168.180.2:1291 <-> 8.8.8.8:53 [proto: 5/DNS][1 pkts/67 bytes][Host: api.eu01.capptain.com] - 9 UDP 192.168.180.2:2589 <-> 8.8.8.8:53 [proto: 5.218/DNS.OCS][1 pkts/61 bytes][Host: ocs.labgency.ws] + 9 UDP 192.168.180.2:2589 <-> 8.8.8.8:53 [proto: 5.204/DNS.OCS][1 pkts/61 bytes][Host: ocs.labgency.ws] 10 UDP 192.168.180.2:3621 <-> 8.8.8.8:53 [proto: 5/DNS][1 pkts/77 bytes][Host: xmpp.device06.eu01.capptain.com] 11 UDP 192.168.180.2:11793 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][1 pkts/65 bytes][Host: play.googleapis.com] - 12 TCP 192.168.180.2:36680 <-> 178.248.208.54:443 [proto: 91.218/SSL.OCS][20 pkts/6089 bytes][SSL client: ocs.labgency.ws] + 12 TCP 192.168.180.2:36680 <-> 178.248.208.54:443 [proto: 91.204/SSL.OCS][20 pkts/6089 bytes][SSL client: ocs.labgency.ws] 13 TCP 192.168.180.2:53356 <-> 137.135.129.206:80 [proto: 7/HTTP][6 pkts/479 bytes] - 14 UDP 192.168.180.2:24245 <-> 8.8.8.8:53 [proto: 5.218/DNS.OCS][1 pkts/56 bytes][Host: www.ocs.fr] - 15 TCP 192.168.180.2:49881 <-> 178.248.208.54:80 [proto: 7.218/HTTP.OCS][751 pkts/44783 bytes][Host: ocu03.labgency.ws] + 14 UDP 192.168.180.2:24245 <-> 8.8.8.8:53 [proto: 5.204/DNS.OCS][1 pkts/56 bytes][Host: www.ocs.fr] + 15 TCP 192.168.180.2:49881 <-> 178.248.208.54:80 [proto: 7.204/HTTP.OCS][751 pkts/44783 bytes][Host: ocu03.labgency.ws] 16 UDP 192.168.180.2:40097 <-> 8.8.8.8:53 [proto: 5/DNS][1 pkts/70 bytes][Host: settings.crashlytics.com] 17 TCP 192.168.180.2:32946 <-> 64.233.184.188:443 [proto: 91.126/SSL.Google][12 pkts/2212 bytes][SSL client: mtalk.google.com] 18 TCP 192.168.180.2:44959 <-> 137.135.129.206:80 [proto: 7/HTTP][7 pkts/540 bytes] diff --git a/tests/result/openvpn.pcap.out b/tests/result/openvpn.pcap.out new file mode 100644 index 000000000..81d959dc1 --- /dev/null +++ b/tests/result/openvpn.pcap.out @@ -0,0 +1,5 @@ +OpenVPN 298 57111 3 + + 1 UDP 192.168.43.12:41507 <-> 139.59.151.137:13680 [proto: 159/OpenVPN][83 pkts/13559 bytes] + 2 UDP 192.168.43.18:13680 <-> 139.59.151.137:13680 [proto: 159/OpenVPN][120 pkts/28172 bytes] + 3 TCP 192.168.1.77:60140 <-> 46.101.231.218:443 [proto: 159/OpenVPN][95 pkts/15380 bytes] diff --git a/tests/result/quic.pcap.out b/tests/result/quic.pcap.out index 082d4b328..b79529833 100644 --- a/tests/result/quic.pcap.out +++ b/tests/result/quic.pcap.out @@ -1,3 +1,19 @@ -Quic 413 254874 1 +Unknown 6 7072 1 +GMail 413 254874 1 +YouTube 85 76193 5 +Google 11 10063 2 +QUIC 3 364 1 - 1 UDP 216.58.212.101:443 <-> 192.168.1.109:57833 [proto: 188/Quic][413 pkts/254874 bytes] + 1 UDP 192.168.1.105:48445 <-> 216.58.214.110:443 [proto: 188.124/QUIC.YouTube][3 pkts/2863 bytes][Host: i.ytimg.com] + 2 UDP 192.168.1.105:53817 <-> 216.58.210.225:443 [proto: 188.124/QUIC.YouTube][2 pkts/2784 bytes][Host: yt3.ggpht.com] + 3 UDP 216.58.212.101:443 <-> 192.168.1.109:57833 [proto: 188.122/QUIC.GMail][413 pkts/254874 bytes][Host: mail.google.com] + 4 UDP 172.217.16.3:443 <-> 192.168.1.105:40461 [proto: 188/QUIC][3 pkts/364 bytes] + 5 UDP 172.217.16.4:443 <-> 192.168.1.105:45669 [proto: 188.126/QUIC.Google][5 pkts/4334 bytes][Host: www.google.com] + 6 UDP 192.168.1.105:34438 <-> 216.58.210.238:443 [proto: 188.124/QUIC.YouTube][7 pkts/6545 bytes][Host: www.youtube.com] + 7 UDP 192.168.1.109:35236 <-> 216.58.210.206:443 [proto: 188.124/QUIC.YouTube][69 pkts/58433 bytes][Host: www.youtube.com] + 8 UDP 192.168.1.105:40030 <-> 216.58.201.227:443 [proto: 188.126/QUIC.Google][6 pkts/5729 bytes][Host: fonts.gstatic.com] + 9 UDP 192.168.1.105:55934 <-> 216.58.201.238:443 [proto: 188.124/QUIC.YouTube][4 pkts/5568 bytes][Host: s.ytimg.com] + + +Undetected flows: + 1 UDP 10.0.0.3:6121 <-> 10.0.0.4:40134 [proto: 0/Unknown][6 pkts/7072 bytes] diff --git a/tests/result/rx.pcap.out b/tests/result/rx.pcap.out new file mode 100644 index 000000000..f38fc982d --- /dev/null +++ b/tests/result/rx.pcap.out @@ -0,0 +1,7 @@ +RX 132 26475 5 + + 1 UDP 192.167.206.124:7002 <-> 131.114.219.168:38331 [proto: 209/RX][3 pkts/519 bytes] + 2 UDP 192.167.206.124:7002 <-> 131.114.219.168:41559 [proto: 209/RX][3 pkts/519 bytes] + 3 UDP 192.167.206.124:7003 <-> 131.114.219.168:7001 [proto: 209/RX][27 pkts/9919 bytes] + 4 UDP 131.114.219.168:7001 <-> 192.167.206.241:7000 [proto: 209/RX][79 pkts/12376 bytes] + 5 UDP 192.167.206.124:7000 <-> 131.114.219.168:7001 [proto: 209/RX][20 pkts/3142 bytes] diff --git a/tests/result/skype.pcap.out b/tests/result/skype.pcap.out index abcece480..316399879 100644 --- a/tests/result/skype.pcap.out +++ b/tests/result/skype.pcap.out @@ -1,16 +1,17 @@ -Unknown 396 52104 15 +Unknown 404 52712 16 DNS 8 807 4 MDNS 8 1736 2 NTP 2 180 1 SSDP 101 38156 6 ICMP 8 656 1 IGMP 5 258 4 -SSL 88 8268 6 -DropBox 38 17948 5 -Skype 2307 491376 244 +SSL 96 8876 7 +Dropbox 38 17948 5 +Skype 1904 292070 241 Apple 15 2045 2 AppleiCloud 88 20520 2 Spotify 5 430 1 +MS_OneDrive 387 198090 1 1 TCP 192.168.1.34:50114 <-> 5.248.186.221:31010 [proto: 125/Skype][18 pkts/1402 bytes] 2 UDP 111.221.74.15:40024 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes] @@ -33,8 +34,8 @@ Spotify 5 430 1 19 UDP 192.168.1.34:13021 <-> 111.221.77.176:40020 [proto: 125/Skype][1 pkts/73 bytes] 20 TCP 192.168.1.34:50110 <-> 91.190.216.125:12350 [proto: 125/Skype][6 pkts/377 bytes] 21 TCP 91.190.216.23:12350 <-> 192.168.1.34:50126 [proto: 125/Skype][20 pkts/5160 bytes] - 22 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][6 pkts/3264 bytes] - 23 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][5 pkts/2720 bytes] + 22 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][6 pkts/3264 bytes] + 23 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][5 pkts/2720 bytes] 24 TCP 192.168.1.34:50113 <-> 71.238.7.203:18767 [proto: 125/Skype][14 pkts/1152 bytes] 25 TCP 192.168.1.34:50116 <-> 81.83.77.141:17639 [proto: 125/Skype][19 pkts/1510 bytes] 26 UDP 157.56.52.18:33033 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/71 bytes] @@ -169,7 +170,7 @@ Spotify 5 430 1 155 UDP 192.168.1.34:13021 <-> 157.55.130.146:33033 [proto: 125/Skype][1 pkts/69 bytes] 156 UDP 192.168.1.34:13021 <-> 157.55.56.146:33033 [proto: 125/Skype][1 pkts/70 bytes] 157 TCP 76.167.161.6:20274 <-> 192.168.1.34:50112 [proto: 125/Skype][15 pkts/1254 bytes] - 158 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 125/Skype][387 pkts/198090 bytes] + 158 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 91.207/SSL.MS_OneDrive][387 pkts/198090 bytes][SSL server: *.gateway.messenger.live.com] 159 TCP 192.168.1.34:50036 <-> 157.56.52.44:443 [proto: 125/Skype][14 pkts/1328 bytes] 160 TCP 192.168.1.34:50037 <-> 157.55.56.170:443 [proto: 125/Skype][15 pkts/1569 bytes] 161 TCP 192.168.1.34:50045 <-> 157.55.130.167:443 [proto: 125/Skype][15 pkts/1411 bytes] @@ -179,7 +180,7 @@ Spotify 5 430 1 165 TCP 192.168.1.34:50081 <-> 157.55.130.176:443 [proto: 125/Skype][15 pkts/1513 bytes] 166 TCP 192.168.1.34:50091 <-> 157.55.235.146:443 [proto: 125/Skype][16 pkts/1754 bytes] 167 TCP 192.168.1.34:50101 <-> 157.55.235.176:443 [proto: 125/Skype][15 pkts/1590 bytes] - 168 TCP 192.168.1.34:50146 <-> 157.56.53.51:443 [proto: 91.125/SSL.Skype][8 pkts/608 bytes] + 168 TCP 192.168.1.34:50146 <-> 157.56.53.51:443 [proto: 91/SSL][8 pkts/608 bytes] 169 UDP 192.168.1.34:13021 <-> 157.55.130.160:40029 [proto: 125/Skype][1 pkts/67 bytes] 170 UDP 192.168.1.34:13021 <-> 157.55.130.154:40005 [proto: 125/Skype][1 pkts/79 bytes] 171 UDP 192.168.1.34:13021 <-> 157.56.52.45:40012 [proto: 125/Skype][1 pkts/67 bytes] @@ -209,87 +210,86 @@ Spotify 5 430 1 195 TCP 149.13.32.15:13392 <-> 192.168.1.34:50132 [proto: 125/Skype][18 pkts/1412 bytes] 196 UDP 192.168.1.92:57621 <-> 192.168.1.255:57621 [proto: 156/Spotify][5 pkts/430 bytes] 197 UDP 192.168.1.1:53 <-> 192.168.1.34:49990 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net] - 198 TCP 192.168.1.34:50145 <-> 157.56.53.51:12350 [proto: 125/Skype][8 pkts/608 bytes] - 199 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][6 pkts/3264 bytes] - 200 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][5 pkts/2720 bytes] - 201 UDP 192.168.1.34:13021 <-> 213.199.179.146:33033 [proto: 125/Skype][1 pkts/67 bytes] - 202 UDP 192.168.1.1:53 <-> 192.168.1.34:51802 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] - 203 UDP 192.168.1.1:53 <-> 192.168.1.34:52714 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] - 204 UDP 192.168.1.1:53 <-> 192.168.1.34:52850 [proto: 5.125/DNS.Skype][8 pkts/648 bytes][Host: conn.skype.akadns.net] - 205 UDP 192.168.1.1:53 <-> 192.168.1.34:52742 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst5.r.skype.net] - 206 TCP 192.168.1.34:50039 <-> 213.199.179.175:443 [proto: 91/SSL][16 pkts/1592 bytes] - 207 TCP 192.168.1.34:50079 <-> 213.199.179.142:443 [proto: 91/SSL][16 pkts/1376 bytes] - 208 UDP 192.168.1.1:53 <-> 192.168.1.34:54396 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com] - 209 TCP 192.168.1.34:50099 <-> 64.4.23.166:40022 [proto: 125/Skype][16 pkts/1355 bytes] - 210 TCP 65.55.223.33:40002 <-> 192.168.1.34:50026 [proto: 125/Skype][17 pkts/1370 bytes] - 211 TCP 65.55.223.12:40031 <-> 192.168.1.34:50065 [proto: 125/Skype][17 pkts/1401 bytes] - 212 TCP 65.55.223.15:40026 <-> 192.168.1.34:50098 [proto: 125/Skype][17 pkts/1381 bytes] - 213 UDP 192.168.1.1:53 <-> 192.168.1.34:57288 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net] - 214 UDP 192.168.1.1:53 <-> 192.168.1.34:57406 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] - 215 UDP 192.168.1.1:53 <-> 192.168.1.34:57726 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] - 216 UDP 192.168.1.34:13021 <-> 213.199.179.165:40007 [proto: 125/Skype][1 pkts/74 bytes] - 217 UDP 192.168.1.34:13021 <-> 213.199.179.141:40015 [proto: 125/Skype][1 pkts/75 bytes] - 218 UDP 192.168.1.34:13021 <-> 213.199.179.162:40029 [proto: 125/Skype][1 pkts/70 bytes] - 219 UDP 192.168.1.34:13021 <-> 213.199.179.152:40023 [proto: 125/Skype][1 pkts/64 bytes] - 220 UDP 192.168.1.34:13021 <-> 213.199.179.145:40027 [proto: 125/Skype][1 pkts/66 bytes] - 221 UDP 192.168.1.34:13021 <-> 213.199.179.170:40011 [proto: 125/Skype][1 pkts/71 bytes] - 222 UDP 192.168.1.1:53 <-> 192.168.1.34:58458 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] - 223 UDP 192.168.1.1:53 <-> 192.168.1.34:58368 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst13.r.skype.net] - 224 UDP 192.168.1.1:53 <-> 192.168.1.34:60288 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] - 225 ICMP 192.168.1.1:0 <-> 192.168.1.34:0 [proto: 81/ICMP][8 pkts/656 bytes] - 226 UDP 192.168.1.1:53 <-> 192.168.1.34:62454 [proto: 5.143/DNS.AppleiCloud][2 pkts/234 bytes][Host: p05-keyvalueservice.icloud.com.akadns.net] - 227 UDP 192.168.1.1:53 <-> 192.168.1.34:63108 [proto: 5.125/DNS.Skype][7 pkts/651 bytes][Host: a.config.skype.trafficmanager.net] - 228 UDP 192.168.1.92:50084 <-> 239.255.255.250:1900 [proto: 12/SSDP][14 pkts/7281 bytes] - 229 UDP 192.168.1.34:51066 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] - 230 UDP 192.168.1.1:53 <-> 192.168.1.34:65426 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com] - 231 TCP 192.168.1.34:50130 <-> 212.161.8.36:13392 [proto: 125/Skype][17 pkts/1380 bytes] - 232 TCP 192.168.1.34:50059 <-> 111.221.74.38:40015 [proto: 125/Skype][16 pkts/1236 bytes] - 233 TCP 192.168.1.34:50029 <-> 23.206.33.166:443 [proto: 91.125/SSL.Skype][17 pkts/3535 bytes][SSL client: apps.skype.com] - 234 IGMP 224.0.0.1:0 <-> 192.168.0.254:0 [proto: 82/IGMP][2 pkts/92 bytes] - 235 IGMP 224.0.0.1:0 <-> 192.168.1.1:0 [proto: 82/IGMP][1 pkts/60 bytes] - 236 IGMP 192.168.1.92:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/60 bytes] - 237 IGMP 192.168.1.34:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/46 bytes] - 238 UDP 192.168.1.34:56886 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] - 239 TCP 192.168.1.34:50033 <-> 157.55.56.170:40015 [proto: 125/Skype][17 pkts/1361 bytes] - 240 TCP 157.56.52.28:40009 <-> 192.168.1.34:50108 [proto: 125/Skype][472 pkts/164627 bytes] - 241 TCP 192.168.1.34:50049 <-> 157.55.130.166:40021 [proto: 125/Skype][16 pkts/1278 bytes] - 242 TCP 192.168.1.34:50067 <-> 157.55.56.160:40027 [proto: 125/Skype][17 pkts/1305 bytes] - 243 TCP 192.168.1.34:50070 <-> 157.55.130.170:40018 [proto: 125/Skype][17 pkts/1312 bytes] - 244 TCP 192.168.1.34:50076 <-> 157.55.235.156:40014 [proto: 125/Skype][18 pkts/1442 bytes] - 245 TCP 192.168.1.34:50092 <-> 157.55.130.155:40020 [proto: 125/Skype][17 pkts/1387 bytes] - 246 UDP 192.168.1.34:64560 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] - 247 UDP 192.168.1.34:13021 <-> 64.4.23.146:33033 [proto: 125/Skype][1 pkts/66 bytes] - 248 TCP 86.31.35.30:59621 <-> 192.168.1.34:50115 [proto: 125/Skype][17 pkts/1386 bytes] - 249 TCP 192.168.1.34:50103 <-> 64.4.23.166:443 [proto: 91/SSL][12 pkts/1147 bytes] - 250 TCP 65.55.223.33:443 <-> 192.168.1.34:50030 [proto: 91/SSL][15 pkts/1311 bytes] - 251 TCP 65.55.223.12:443 <-> 192.168.1.34:50066 [proto: 91/SSL][15 pkts/1452 bytes] - 252 TCP 65.55.223.15:443 <-> 192.168.1.34:50102 [proto: 91/SSL][14 pkts/1390 bytes] - 253 UDP 239.255.255.250:1900 <-> 192.168.0.254:1025 [proto: 12/SSDP][79 pkts/29479 bytes] - 254 UDP 192.168.1.34:13021 <-> 71.62.0.85:33647 [proto: 125/Skype][1 pkts/60 bytes] - 255 UDP 192.168.1.92:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][4 pkts/828 bytes] - 256 UDP 192.168.1.34:13021 <-> 64.4.23.159:40009 [proto: 125/Skype][1 pkts/70 bytes] - 257 UDP 192.168.1.34:13021 <-> 64.4.23.151:40029 [proto: 125/Skype][1 pkts/72 bytes] - 258 UDP 192.168.1.34:13021 <-> 64.4.23.170:40011 [proto: 125/Skype][1 pkts/68 bytes] - 259 UDP 192.168.1.34:13021 <-> 64.4.23.173:40017 [proto: 125/Skype][1 pkts/66 bytes] - 260 UDP 65.55.223.15:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/66 bytes] - 261 UDP 192.168.1.34:13021 <-> 65.55.223.43:40002 [proto: 125/Skype][1 pkts/76 bytes] - 262 UDP 65.55.223.17:40022 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/70 bytes] - 263 UDP 65.55.223.25:40028 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/76 bytes] - 264 UDP 65.55.223.24:40032 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/67 bytes] - 265 UDP 65.55.223.28:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/74 bytes] - 266 UDP 65.55.223.26:40004 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/79 bytes] - 267 UDP 65.55.223.29:40010 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes] - 268 UDP 192.168.1.34:13021 <-> 65.55.223.45:40012 [proto: 125/Skype][1 pkts/71 bytes] - 269 UDP 192.168.1.34:123 <-> 17.253.48.245:123 [proto: 9/NTP][2 pkts/180 bytes] - 270 TCP 192.168.1.34:50111 <-> 91.190.216.125:443 [proto: 125/Skype][20 pkts/1516 bytes] - 271 TCP 192.168.1.34:50123 <-> 80.14.46.121:4415 [proto: 125/Skype][18 pkts/1506 bytes] - 272 TCP 192.168.1.34:50141 <-> 80.14.46.121:4415 [proto: 125/Skype][15 pkts/1237 bytes] - 273 TCP 192.168.1.34:49445 <-> 108.160.170.46:443 [proto: 91.121/SSL.DropBox][16 pkts/5980 bytes] - 274 TCP 192.168.1.34:50058 <-> 111.221.74.47:443 [proto: 125/Skype][14 pkts/1208 bytes] - 275 TCP 192.168.1.34:50100 <-> 111.221.74.46:443 [proto: 125/Skype][13 pkts/1109 bytes] - 276 TCP 192.168.1.34:50035 <-> 213.199.179.175:40021 [proto: 125/Skype][17 pkts/1304 bytes] - 277 TCP 192.168.1.34:50075 <-> 213.199.179.142:40003 [proto: 125/Skype][19 pkts/1495 bytes] - 278 UDP [fe80::c62c:3ff:fe06:49fe]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][4 pkts/908 bytes] + 198 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][6 pkts/3264 bytes] + 199 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][5 pkts/2720 bytes] + 200 UDP 192.168.1.34:13021 <-> 213.199.179.146:33033 [proto: 125/Skype][1 pkts/67 bytes] + 201 UDP 192.168.1.1:53 <-> 192.168.1.34:51802 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] + 202 UDP 192.168.1.1:53 <-> 192.168.1.34:52714 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] + 203 UDP 192.168.1.1:53 <-> 192.168.1.34:52850 [proto: 5.125/DNS.Skype][8 pkts/648 bytes][Host: conn.skype.akadns.net] + 204 UDP 192.168.1.1:53 <-> 192.168.1.34:52742 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst5.r.skype.net] + 205 TCP 192.168.1.34:50039 <-> 213.199.179.175:443 [proto: 91/SSL][16 pkts/1592 bytes] + 206 TCP 192.168.1.34:50079 <-> 213.199.179.142:443 [proto: 91/SSL][16 pkts/1376 bytes] + 207 UDP 192.168.1.1:53 <-> 192.168.1.34:54396 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com] + 208 TCP 192.168.1.34:50099 <-> 64.4.23.166:40022 [proto: 125/Skype][16 pkts/1355 bytes] + 209 TCP 65.55.223.33:40002 <-> 192.168.1.34:50026 [proto: 125/Skype][17 pkts/1370 bytes] + 210 TCP 65.55.223.12:40031 <-> 192.168.1.34:50065 [proto: 125/Skype][17 pkts/1401 bytes] + 211 TCP 65.55.223.15:40026 <-> 192.168.1.34:50098 [proto: 125/Skype][17 pkts/1381 bytes] + 212 UDP 192.168.1.1:53 <-> 192.168.1.34:57288 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net] + 213 UDP 192.168.1.1:53 <-> 192.168.1.34:57406 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] + 214 UDP 192.168.1.1:53 <-> 192.168.1.34:57726 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] + 215 UDP 192.168.1.34:13021 <-> 213.199.179.165:40007 [proto: 125/Skype][1 pkts/74 bytes] + 216 UDP 192.168.1.34:13021 <-> 213.199.179.141:40015 [proto: 125/Skype][1 pkts/75 bytes] + 217 UDP 192.168.1.34:13021 <-> 213.199.179.162:40029 [proto: 125/Skype][1 pkts/70 bytes] + 218 UDP 192.168.1.34:13021 <-> 213.199.179.152:40023 [proto: 125/Skype][1 pkts/64 bytes] + 219 UDP 192.168.1.34:13021 <-> 213.199.179.145:40027 [proto: 125/Skype][1 pkts/66 bytes] + 220 UDP 192.168.1.34:13021 <-> 213.199.179.170:40011 [proto: 125/Skype][1 pkts/71 bytes] + 221 UDP 192.168.1.1:53 <-> 192.168.1.34:58458 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] + 222 UDP 192.168.1.1:53 <-> 192.168.1.34:58368 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst13.r.skype.net] + 223 UDP 192.168.1.1:53 <-> 192.168.1.34:60288 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] + 224 ICMP 192.168.1.1:0 <-> 192.168.1.34:0 [proto: 81/ICMP][8 pkts/656 bytes] + 225 UDP 192.168.1.1:53 <-> 192.168.1.34:62454 [proto: 5.143/DNS.AppleiCloud][2 pkts/234 bytes][Host: p05-keyvalueservice.icloud.com.akadns.net] + 226 UDP 192.168.1.1:53 <-> 192.168.1.34:63108 [proto: 5.125/DNS.Skype][7 pkts/651 bytes][Host: a.config.skype.trafficmanager.net] + 227 UDP 192.168.1.92:50084 <-> 239.255.255.250:1900 [proto: 12/SSDP][14 pkts/7281 bytes] + 228 UDP 192.168.1.34:51066 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] + 229 UDP 192.168.1.1:53 <-> 192.168.1.34:65426 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com] + 230 TCP 192.168.1.34:50130 <-> 212.161.8.36:13392 [proto: 125/Skype][17 pkts/1380 bytes] + 231 TCP 192.168.1.34:50059 <-> 111.221.74.38:40015 [proto: 125/Skype][16 pkts/1236 bytes] + 232 TCP 192.168.1.34:50029 <-> 23.206.33.166:443 [proto: 91.125/SSL.Skype][17 pkts/3535 bytes][SSL client: apps.skype.com] + 233 IGMP 224.0.0.1:0 <-> 192.168.0.254:0 [proto: 82/IGMP][2 pkts/92 bytes] + 234 IGMP 224.0.0.1:0 <-> 192.168.1.1:0 [proto: 82/IGMP][1 pkts/60 bytes] + 235 IGMP 192.168.1.92:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/60 bytes] + 236 IGMP 192.168.1.34:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/46 bytes] + 237 UDP 192.168.1.34:56886 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] + 238 TCP 192.168.1.34:50033 <-> 157.55.56.170:40015 [proto: 125/Skype][17 pkts/1361 bytes] + 239 TCP 157.56.52.28:40009 <-> 192.168.1.34:50108 [proto: 125/Skype][472 pkts/164627 bytes] + 240 TCP 192.168.1.34:50049 <-> 157.55.130.166:40021 [proto: 125/Skype][16 pkts/1278 bytes] + 241 TCP 192.168.1.34:50067 <-> 157.55.56.160:40027 [proto: 125/Skype][17 pkts/1305 bytes] + 242 TCP 192.168.1.34:50070 <-> 157.55.130.170:40018 [proto: 125/Skype][17 pkts/1312 bytes] + 243 TCP 192.168.1.34:50076 <-> 157.55.235.156:40014 [proto: 125/Skype][18 pkts/1442 bytes] + 244 TCP 192.168.1.34:50092 <-> 157.55.130.155:40020 [proto: 125/Skype][17 pkts/1387 bytes] + 245 UDP 192.168.1.34:64560 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] + 246 UDP 192.168.1.34:13021 <-> 64.4.23.146:33033 [proto: 125/Skype][1 pkts/66 bytes] + 247 TCP 86.31.35.30:59621 <-> 192.168.1.34:50115 [proto: 125/Skype][17 pkts/1386 bytes] + 248 TCP 192.168.1.34:50103 <-> 64.4.23.166:443 [proto: 91/SSL][12 pkts/1147 bytes] + 249 TCP 65.55.223.33:443 <-> 192.168.1.34:50030 [proto: 91/SSL][15 pkts/1311 bytes] + 250 TCP 65.55.223.12:443 <-> 192.168.1.34:50066 [proto: 91/SSL][15 pkts/1452 bytes] + 251 TCP 65.55.223.15:443 <-> 192.168.1.34:50102 [proto: 91/SSL][14 pkts/1390 bytes] + 252 UDP 239.255.255.250:1900 <-> 192.168.0.254:1025 [proto: 12/SSDP][79 pkts/29479 bytes] + 253 UDP 192.168.1.34:13021 <-> 71.62.0.85:33647 [proto: 125/Skype][1 pkts/60 bytes] + 254 UDP 192.168.1.92:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][4 pkts/828 bytes] + 255 UDP 192.168.1.34:13021 <-> 64.4.23.159:40009 [proto: 125/Skype][1 pkts/70 bytes] + 256 UDP 192.168.1.34:13021 <-> 64.4.23.151:40029 [proto: 125/Skype][1 pkts/72 bytes] + 257 UDP 192.168.1.34:13021 <-> 64.4.23.170:40011 [proto: 125/Skype][1 pkts/68 bytes] + 258 UDP 192.168.1.34:13021 <-> 64.4.23.173:40017 [proto: 125/Skype][1 pkts/66 bytes] + 259 UDP 65.55.223.15:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/66 bytes] + 260 UDP 192.168.1.34:13021 <-> 65.55.223.43:40002 [proto: 125/Skype][1 pkts/76 bytes] + 261 UDP 65.55.223.17:40022 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/70 bytes] + 262 UDP 65.55.223.25:40028 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/76 bytes] + 263 UDP 65.55.223.24:40032 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/67 bytes] + 264 UDP 65.55.223.28:40026 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/74 bytes] + 265 UDP 65.55.223.26:40004 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/79 bytes] + 266 UDP 65.55.223.29:40010 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes] + 267 UDP 192.168.1.34:13021 <-> 65.55.223.45:40012 [proto: 125/Skype][1 pkts/71 bytes] + 268 UDP 192.168.1.34:123 <-> 17.253.48.245:123 [proto: 9/NTP][2 pkts/180 bytes] + 269 TCP 192.168.1.34:50111 <-> 91.190.216.125:443 [proto: 125/Skype][20 pkts/1516 bytes] + 270 TCP 192.168.1.34:50123 <-> 80.14.46.121:4415 [proto: 125/Skype][18 pkts/1506 bytes] + 271 TCP 192.168.1.34:50141 <-> 80.14.46.121:4415 [proto: 125/Skype][15 pkts/1237 bytes] + 272 TCP 192.168.1.34:49445 <-> 108.160.170.46:443 [proto: 91.121/SSL.Dropbox][16 pkts/5980 bytes] + 273 TCP 192.168.1.34:50058 <-> 111.221.74.47:443 [proto: 125/Skype][14 pkts/1208 bytes] + 274 TCP 192.168.1.34:50100 <-> 111.221.74.46:443 [proto: 125/Skype][13 pkts/1109 bytes] + 275 TCP 192.168.1.34:50035 <-> 213.199.179.175:40021 [proto: 125/Skype][17 pkts/1304 bytes] + 276 TCP 192.168.1.34:50075 <-> 213.199.179.142:40003 [proto: 125/Skype][19 pkts/1495 bytes] + 277 UDP [fe80::c62c:3ff:fe06:49fe]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][4 pkts/908 bytes] Undetected flows: @@ -306,5 +306,6 @@ Undetected flows: 11 TCP 192.168.1.34:50121 <-> 81.83.77.141:17639 [proto: 0/Unknown][40 pkts/5609 bytes] 12 TCP 76.167.161.6:20274 <-> 192.168.1.34:50140 [proto: 0/Unknown][3 pkts/206 bytes] 13 TCP 192.168.1.34:50144 <-> 78.202.226.115:29059 [proto: 0/Unknown][14 pkts/1139 bytes] - 14 TCP 86.31.35.30:59621 <-> 192.168.1.34:50119 [proto: 0/Unknown][100 pkts/12266 bytes] - 15 TCP 192.168.1.34:50127 <-> 80.14.46.121:4415 [proto: 0/Unknown][27 pkts/2098 bytes] + 14 TCP 192.168.1.34:50145 <-> 157.56.53.51:12350 [proto: 0/Unknown][8 pkts/608 bytes] + 15 TCP 86.31.35.30:59621 <-> 192.168.1.34:50119 [proto: 0/Unknown][100 pkts/12266 bytes] + 16 TCP 192.168.1.34:50127 <-> 80.14.46.121:4415 [proto: 0/Unknown][27 pkts/2098 bytes] diff --git a/tests/result/skype_no_unknown.pcap.out b/tests/result/skype_no_unknown.pcap.out index c307ca471..b3be14eb1 100644 --- a/tests/result/skype_no_unknown.pcap.out +++ b/tests/result/skype_no_unknown.pcap.out @@ -6,9 +6,10 @@ SSDP 40 14100 3 ICMP 4 328 1 IGMP 4 226 4 SSL 79 7742 6 -DropBox 16 7342 5 -Skype 1585 362654 220 +Dropbox 16 7342 5 +Skype 1237 180967 219 Apple 84 20699 2 +MS_OneDrive 348 181687 1 1 UDP 192.168.1.34:13021 <-> 189.138.161.88:19521 [proto: 125/Skype][1 pkts/60 bytes] 2 TCP 192.168.1.34:51290 <-> 5.248.186.221:31010 [proto: 125/Skype][18 pkts/1490 bytes] @@ -23,9 +24,9 @@ Apple 84 20699 2 11 UDP 192.168.1.34:13021 <-> 111.221.77.149:40016 [proto: 125/Skype][1 pkts/75 bytes] 12 UDP 192.168.1.34:13021 <-> 111.221.77.171:40030 [proto: 125/Skype][1 pkts/64 bytes] 13 UDP 192.168.1.34:13021 <-> 111.221.77.173:40012 [proto: 125/Skype][1 pkts/79 bytes] - 14 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes] + 14 UDP 192.168.1.34:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes] 15 TCP 192.168.1.34:51284 <-> 91.190.218.125:12350 [proto: 125/Skype][6 pkts/423 bytes] - 16 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes] + 16 UDP 192.168.1.92:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes] 17 TCP 192.168.1.34:51296 <-> 91.190.216.125:12350 [proto: 125/Skype][6 pkts/479 bytes] 18 TCP 192.168.1.34:51289 <-> 71.238.7.203:18767 [proto: 125/Skype][17 pkts/1369 bytes] 19 UDP 157.56.52.18:33033 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/77 bytes] @@ -123,7 +124,7 @@ Apple 84 20699 2 111 TCP 192.168.1.34:51302 <-> 91.190.216.125:443 [proto: 125/Skype][10 pkts/599 bytes] 112 UDP 192.168.1.34:13021 <-> 111.221.77.146:33033 [proto: 125/Skype][1 pkts/70 bytes] 113 UDP 111.221.74.18:33033 <-> 192.168.1.34:13021 [proto: 125/Skype][1 pkts/67 bytes] - 114 TCP 192.168.1.34:51222 <-> 108.160.163.108:443 [proto: 91.121/SSL.DropBox][8 pkts/2990 bytes] + 114 TCP 192.168.1.34:51222 <-> 108.160.163.108:443 [proto: 91.121/SSL.Dropbox][8 pkts/2990 bytes] 115 TCP 192.168.1.34:51259 <-> 111.221.77.142:443 [proto: 125/Skype][14 pkts/1253 bytes] 116 TCP 192.168.1.34:51283 <-> 111.221.74.48:443 [proto: 91.125/SSL.Skype][3 pkts/206 bytes] 117 TCP 192.168.1.34:51258 <-> 213.199.179.176:40021 [proto: 125/Skype][19 pkts/1496 bytes] @@ -150,7 +151,7 @@ Apple 84 20699 2 138 UDP 192.168.1.34:13021 <-> 157.55.130.146:33033 [proto: 125/Skype][1 pkts/69 bytes] 139 TCP 192.168.1.34:51291 <-> 81.83.77.141:17639 [proto: 125/Skype][15 pkts/1226 bytes] 140 TCP 76.167.161.6:20274 <-> 192.168.1.34:51288 [proto: 125/Skype][15 pkts/1258 bytes] - 141 TCP 192.168.1.34:51230 <-> 157.56.126.211:443 [proto: 125/Skype][348 pkts/181687 bytes] + 141 TCP 192.168.1.34:51230 <-> 157.56.126.211:443 [proto: 91.207/SSL.MS_OneDrive][348 pkts/181687 bytes][SSL server: *.gateway.messenger.live.com] 142 TCP 157.56.52.28:443 <-> 192.168.1.34:51232 [proto: 125/Skype][13 pkts/1157 bytes] 143 TCP 192.168.1.34:51241 <-> 157.55.130.176:443 [proto: 125/Skype][15 pkts/1584 bytes] 144 TCP 192.168.1.34:51261 <-> 157.55.235.170:443 [proto: 125/Skype][15 pkts/1569 bytes] @@ -188,8 +189,8 @@ Apple 84 20699 2 176 UDP 192.168.1.34:13021 <-> 157.55.235.175:40023 [proto: 125/Skype][1 pkts/74 bytes] 177 UDP 192.168.1.1:53 <-> 192.168.1.34:49864 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com] 178 TCP 149.13.32.15:13392 <-> 192.168.1.34:51316 [proto: 125/Skype][14 pkts/1176 bytes] - 179 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes] - 180 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes] + 179 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes] + 180 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes] 181 UDP 192.168.1.34:13021 <-> 213.199.179.146:33033 [proto: 125/Skype][1 pkts/75 bytes] 182 UDP 192.168.1.1:53 <-> 192.168.1.34:53372 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst11.r.skype.net] 183 UDP 192.168.1.92:53826 <-> 192.168.1.255:137 [proto: 10/NetBIOS][1 pkts/92 bytes] diff --git a/tests/result/starcraft_battle.pcap.out b/tests/result/starcraft_battle.pcap.out index e221e9ab6..c094ab4ed 100644 --- a/tests/result/starcraft_battle.pcap.out +++ b/tests/result/starcraft_battle.pcap.out @@ -7,7 +7,7 @@ WorldOfWarcraft 9 880 1 IGMP 2 120 1 SSL 41 2782 12 Google 14 1588 3 -Quic 6 475 1 +QUIC 6 475 1 Starcraft 236 51494 6 1 TCP 80.239.186.21:80 <-> 192.168.1.100:3516 [proto: 7/HTTP][12 pkts/3680 bytes][Host: eu.launcher.battle.net] @@ -15,14 +15,14 @@ Starcraft 236 51494 6 3 TCP 80.239.186.21:80 <-> 192.168.1.100:3522 [proto: 7/HTTP][11 pkts/3620 bytes][Host: eu.launcher.battle.net] 4 TCP 80.239.186.26:80 <-> 192.168.1.100:3524 [proto: 7/HTTP][10 pkts/1214 bytes][Host: nydus.battle.net] 5 TCP 80.239.186.40:80 <-> 192.168.1.100:3526 [proto: 7/HTTP][11 pkts/3686 bytes][Host: eu.battle.net] - 6 TCP 192.168.1.100:3427 <-> 80.239.208.193:1119 [proto: 213/Starcraft][13 pkts/902 bytes] + 6 TCP 192.168.1.100:3427 <-> 80.239.208.193:1119 [proto: 211/Starcraft][13 pkts/902 bytes] 7 UDP 239.255.255.250:1900 <-> 192.168.1.254:38605 [proto: 12/SSDP][11 pkts/4984 bytes] 8 UDP 192.168.1.100:53145 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/336 bytes][Host: nydus.battle.net] 9 UDP 192.168.1.100:58831 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/417 bytes][Host: 254.1.168.192.in-addr.arpa] 10 UDP 192.168.1.100:58851 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/455 bytes][Host: 22.40.194.173.in-addr.arpa] 11 TCP 192.168.1.100:3484 <-> 173.194.113.224:443 [proto: 91.126/SSL.Google][3 pkts/168 bytes] 12 TCP 192.168.1.100:3486 <-> 199.38.164.156:443 [proto: 91/SSL][4 pkts/228 bytes] - 13 UDP 192.168.1.100:53146 <-> 5.42.180.154:1119 [proto: 213/Starcraft][2 pkts/104 bytes] + 13 UDP 192.168.1.100:53146 <-> 5.42.180.154:1119 [proto: 211/Starcraft][2 pkts/104 bytes] 14 TCP 192.168.1.100:3052 <-> 216.58.212.110:443 [proto: 91.126/SSL.Google][2 pkts/121 bytes] 15 TCP 192.168.1.100:3528 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25105 bytes][Host: bnetcmsus-a.akamaihd.net] 16 TCP 192.168.1.100:3530 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25102 bytes][Host: bnetcmsus-a.akamaihd.net] @@ -40,7 +40,7 @@ Starcraft 236 51494 6 28 TCP 80.239.186.26:443 <-> 192.168.1.100:3476 [proto: 91/SSL][1 pkts/60 bytes] 29 TCP 80.239.186.40:443 <-> 192.168.1.100:3478 [proto: 91/SSL][1 pkts/60 bytes] 30 TCP 192.168.1.100:3508 <-> 87.248.221.254:80 [proto: 7.60/HTTP.HTTPDownload][179 pkts/134204 bytes][Host: llnw.blizzard.com] - 31 UDP 173.194.40.22:443 <-> 192.168.1.100:53568 [proto: 188/Quic][6 pkts/475 bytes] + 31 UDP 173.194.40.22:443 <-> 192.168.1.100:53568 [proto: 188/QUIC][6 pkts/475 bytes] 32 UDP 192.168.1.100:55468 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/556 bytes][Host: bnetcmsus-a.akamaihd.net] 33 UDP 192.168.1.100:58818 <-> 192.168.1.254:53 [proto: 5/DNS][4 pkts/432 bytes][Host: 91.252.30.192.in-addr.arpa] 34 UDP 192.168.1.100:58844 <-> 192.168.1.254:53 [proto: 5/DNS][2 pkts/210 bytes][Host: 40.186.239.80.in-addr.arpa] @@ -48,9 +48,9 @@ Starcraft 236 51494 6 36 TCP 192.168.1.100:3506 <-> 173.194.113.224:80 [proto: 7.126/HTTP.Google][9 pkts/1299 bytes][Host: www.google-analytics.com] 37 TCP 192.30.252.91:443 <-> 192.168.1.100:3213 [proto: 91/SSL][3 pkts/234 bytes] 38 IGMP 224.0.0.22:0 <-> 192.168.1.107:0 [proto: 82/IGMP][2 pkts/120 bytes] - 39 TCP 192.168.1.100:3517 <-> 213.248.127.130:1119 [proto: 213/Starcraft][215 pkts/50178 bytes] - 40 UDP 192.168.1.100:6113 <-> 213.248.127.212:1119 [proto: 213/Starcraft][2 pkts/103 bytes] - 41 UDP 192.168.1.100:6113 <-> 213.248.127.166:1119 [proto: 213/Starcraft][2 pkts/103 bytes] + 39 TCP 192.168.1.100:3517 <-> 213.248.127.130:1119 [proto: 211/Starcraft][215 pkts/50178 bytes] + 40 UDP 192.168.1.100:6113 <-> 213.248.127.212:1119 [proto: 211/Starcraft][2 pkts/103 bytes] + 41 UDP 192.168.1.100:6113 <-> 213.248.127.166:1119 [proto: 211/Starcraft][2 pkts/103 bytes] 42 TCP 192.168.1.100:3527 <-> 2.228.46.112:80 [proto: 7/HTTP][41 pkts/37433 bytes][Host: bnetcmsus-a.akamaihd.net] 43 TCP 192.168.1.100:3529 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25102 bytes][Host: bnetcmsus-a.akamaihd.net] 44 TCP 192.168.1.100:3531 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25102 bytes][Host: bnetcmsus-a.akamaihd.net] @@ -60,7 +60,7 @@ Starcraft 236 51494 6 48 TCP 192.168.1.100:3482 <-> 2.228.46.114:443 [proto: 91/SSL][4 pkts/275 bytes] 49 TCP 192.168.1.100:3480 <-> 2.228.46.114:443 [proto: 91/SSL][4 pkts/275 bytes] 50 TCP 12.129.222.54:80 <-> 192.168.1.100:3512 [proto: 7.76/HTTP.WorldOfWarcraft][9 pkts/880 bytes][Host: us.scan.worldofwarcraft.com] - 51 UDP 62.115.246.51:1119 <-> 192.168.1.100:53146 [proto: 213/Starcraft][2 pkts/104 bytes] + 51 UDP 62.115.246.51:1119 <-> 192.168.1.100:53146 [proto: 211/Starcraft][2 pkts/104 bytes] Undetected flows: diff --git a/tests/result/teredo.pcap.out b/tests/result/teredo.pcap.out index 6c65bc313..c0c37a425 100644 --- a/tests/result/teredo.pcap.out +++ b/tests/result/teredo.pcap.out @@ -1,7 +1,7 @@ Teredo 24 2574 5 - 1 UDP 194.136.28.76:3544 <-> 10.112.16.106:52513 [proto: 214/Teredo][4 pkts/508 bytes] - 2 UDP 194.136.28.76:3544 <-> 10.112.16.89:60381 [proto: 214/Teredo][2 pkts/254 bytes] - 3 UDP 10.112.16.67:51812 <-> 194.136.28.76:3544 [proto: 214/Teredo][14 pkts/1304 bytes] - 4 UDP 10.112.16.64:56154 <-> 194.136.28.76:3544 [proto: 214/Teredo][2 pkts/254 bytes] - 5 UDP 194.136.28.76:3544 <-> 10.112.16.92:63448 [proto: 214/Teredo][2 pkts/254 bytes] + 1 UDP 194.136.28.76:3544 <-> 10.112.16.106:52513 [proto: 212/Teredo][4 pkts/508 bytes] + 2 UDP 194.136.28.76:3544 <-> 10.112.16.89:60381 [proto: 212/Teredo][2 pkts/254 bytes] + 3 UDP 10.112.16.67:51812 <-> 194.136.28.76:3544 [proto: 212/Teredo][14 pkts/1304 bytes] + 4 UDP 10.112.16.64:56154 <-> 194.136.28.76:3544 [proto: 212/Teredo][2 pkts/254 bytes] + 5 UDP 194.136.28.76:3544 <-> 10.112.16.92:63448 [proto: 212/Teredo][2 pkts/254 bytes] diff --git a/tests/result/tor.pcap.out b/tests/result/tor.pcap.out new file mode 100644 index 000000000..4fb9eb1d4 --- /dev/null +++ b/tests/result/tor.pcap.out @@ -0,0 +1,17 @@ +NetBIOS 1 252 1 +SSL 1 60 1 +DHCPV6 6 906 1 +Dropbox 10 1860 1 +Tor 3676 3014362 7 + + 1 UDP 192.168.1.1:17500 <-> 192.168.1.255:17500 [proto: 121/Dropbox][10 pkts/1860 bytes] + 2 UDP [fe80::c583:1972:5728:7323]:547 <-> [ff02::1:2]:546 [proto: 103/DHCPV6][6 pkts/906 bytes] + 3 TCP 212.83.155.250:443 <-> 192.168.1.252:51174 [proto: 163/Tor][32 pkts/10431 bytes][SSL client: www.t3i3ru.com] + 4 TCP 46.59.52.31:443 <-> 192.168.1.252:51111 [proto: 163/Tor][34 pkts/11142 bytes][SSL client: www.e6r5p57kbafwrxj3plz.com] + 5 TCP 91.143.93.242:443 <-> 192.168.1.252:51175 [proto: 163/Tor][38 pkts/12520 bytes][SSL client: www.gfu7hbxpfp.com] + 6 TCP 157.56.30.46:443 <-> 192.168.1.252:51104 [proto: 91/SSL][1 pkts/60 bytes] + 7 UDP 192.168.1.252:138 <-> 192.168.1.255:138 [proto: 10/NetBIOS][1 pkts/252 bytes] + 8 TCP 38.229.70.53:443 <-> 192.168.1.252:51112 [proto: 163/Tor][1576 pkts/1388792 bytes][SSL client: www.q4cyamnc6mtokjurvdclt.com] + 9 TCP 38.229.70.53:443 <-> 192.168.1.252:51176 [proto: 163/Tor][1826 pkts/1513278 bytes][SSL client: www.jmts2id.com] + 10 TCP 62.210.137.230:443 <-> 192.168.1.252:51185 [proto: 163/Tor][29 pkts/9661 bytes][SSL client: www.6gyip7tqim7sieb.com] + 11 TCP 91.143.93.242:443 <-> 192.168.1.252:51110 [proto: 163/Tor][141 pkts/68538 bytes][SSL client: www.ct7ctrgb6cr7.com] diff --git a/tests/result/viber_mobile.pcap.out b/tests/result/viber_mobile.pcap.out index df601dd7d..e08572565 100644 --- a/tests/result/viber_mobile.pcap.out +++ b/tests/result/viber_mobile.pcap.out @@ -6,7 +6,7 @@ SSL_No_Cert 36 5874 1 ICMP 4 518 3 SSL 90 22731 8 Facebook 39 16382 2 -DropBox 2 163 1 +Dropbox 2 163 1 GMail 35 14773 2 Google 75 17027 7 WhatsApp 31 6224 2 @@ -82,7 +82,7 @@ Viber 10081 1413446 4 68 TCP 93.184.221.200:80 <-> 192.168.200.222:50854 [proto: 7/HTTP][5 pkts/300 bytes] 69 UDP 192.168.200.222:39413 <-> 81.192.42.247:15057 [proto: 37/BitTorrent][1 pkts/146 bytes] 70 UDP 92.245.59.202:12998 <-> 192.168.200.222:39413 [proto: 37/BitTorrent][2 pkts/505 bytes] - 71 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.DropBox][2 pkts/163 bytes] + 71 TCP 108.160.172.205:443 <-> 192.168.200.222:51765 [proto: 91.121/SSL.Dropbox][2 pkts/163 bytes] 72 TCP 107.22.192.179:443 <-> 192.168.200.222:52269 [proto: 91/SSL][26 pkts/10057 bytes][SSL client: settings.crashlytics.com] diff --git a/tests/result/waze.pcap.out b/tests/result/waze.pcap.out index 0429e66a0..65169ea40 100644 --- a/tests/result/waze.pcap.out +++ b/tests/result/waze.pcap.out @@ -1,21 +1,22 @@ Unknown 10 786 1 +HTTP 28 1572 7 NTP 2 180 1 HTTPDownload 37 63205 1 SSL_No_Cert 13 2142 1 +SSL 8 432 2 Waze 484 289335 19 WhatsApp 15 1341 1 -Simet 36 2004 9 1 TCP 10.8.0.1:50828 <-> 108.168.176.228:443 [proto: 142/WhatsApp][15 pkts/1341 bytes] 2 TCP 10.8.0.1:36312 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][32 pkts/44619 bytes][SSL server: *.world.waze.com] 3 TCP 10.8.0.1:36314 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][20 pkts/5673 bytes][SSL server: *.world.waze.com] 4 TCP 10.8.0.1:36316 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][28 pkts/27886 bytes][SSL server: *.world.waze.com] - 5 TCP 200.160.4.49:80 <-> 10.16.37.157:41823 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes] - 6 TCP 200.160.4.31:80 <-> 10.16.37.157:43991 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes] + 5 TCP 200.160.4.49:80 <-> 10.16.37.157:41823 [proto: 7/HTTP][4 pkts/228 bytes] + 6 TCP 200.160.4.31:80 <-> 10.16.37.157:43991 [proto: 7/HTTP][4 pkts/228 bytes] 7 TCP 10.8.0.1:51050 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][18 pkts/5553 bytes][SSL server: *.waze.com] - 8 TCP 10.8.0.1:45169 <-> 200.160.4.198:80 [proto: 7.200/HTTP.Simet][4 pkts/216 bytes] - 9 TCP 200.160.4.49:80 <-> 10.16.37.157:46473 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes] - 10 TCP 200.160.4.49:80 <-> 10.16.37.157:52953 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes] + 8 TCP 10.8.0.1:45169 <-> 200.160.4.198:80 [proto: 7/HTTP][4 pkts/216 bytes] + 9 TCP 200.160.4.49:80 <-> 10.16.37.157:46473 [proto: 7/HTTP][4 pkts/228 bytes] + 10 TCP 200.160.4.49:80 <-> 10.16.37.157:52953 [proto: 7/HTTP][4 pkts/228 bytes] 11 TCP 10.8.0.1:36100 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][107 pkts/85712 bytes][SSL server: *.world.waze.com] 12 TCP 10.8.0.1:36102 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][37 pkts/11984 bytes][SSL server: *.world.waze.com] 13 TCP 10.8.0.1:36134 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][24 pkts/6585 bytes][SSL server: *.world.waze.com] @@ -28,13 +29,13 @@ Simet 36 2004 9 20 TCP 10.8.0.1:45554 <-> 54.230.227.172:80 [proto: 7.135/HTTP.Waze][14 pkts/1319 bytes][Host: cres.waze.com] 21 TCP 10.8.0.1:54915 <-> 65.39.128.135:80 [proto: 7.60/HTTP.HTTPDownload][37 pkts/63205 bytes][Host: xtra1.gpsonextra.net] 22 TCP 10.8.0.1:36585 <-> 173.194.118.48:443 [proto: 64/SSL_No_Cert][13 pkts/2142 bytes] - 23 TCP 10.8.0.1:43089 <-> 200.160.4.198:443 [proto: 91.200/SSL.Simet][4 pkts/216 bytes] + 23 TCP 10.8.0.1:43089 <-> 200.160.4.198:443 [proto: 91/SSL][4 pkts/216 bytes] 24 TCP 10.8.0.1:51049 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][23 pkts/7823 bytes][SSL server: *.waze.com] 25 TCP 10.8.0.1:51051 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][21 pkts/7715 bytes][SSL server: *.waze.com] 26 UDP 10.8.0.1:46214 <-> 200.89.75.198:123 [proto: 9/NTP][2 pkts/180 bytes] - 27 TCP 200.160.4.49:80 <-> 10.16.37.157:52746 [proto: 7.200/HTTP.Simet][4 pkts/228 bytes] - 28 TCP 10.8.0.1:60574 <-> 200.160.4.49:80 [proto: 7.200/HTTP.Simet][4 pkts/216 bytes] - 29 TCP 10.8.0.1:60479 <-> 200.160.4.49:443 [proto: 91.200/SSL.Simet][4 pkts/216 bytes] + 27 TCP 200.160.4.49:80 <-> 10.16.37.157:52746 [proto: 7/HTTP][4 pkts/228 bytes] + 28 TCP 10.8.0.1:60574 <-> 200.160.4.49:80 [proto: 7/HTTP][4 pkts/216 bytes] + 29 TCP 10.8.0.1:60479 <-> 200.160.4.49:443 [proto: 91/SSL][4 pkts/216 bytes] 30 TCP 10.8.0.1:36137 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][23 pkts/5742 bytes][SSL server: *.world.waze.com] 31 TCP 10.8.0.1:39021 <-> 52.17.114.219:443 [proto: 91.135/SSL.Waze][33 pkts/58896 bytes][SSL server: *.world.waze.com] 32 TCP 10.8.0.1:45529 <-> 54.230.227.172:80 [proto: 7.135/HTTP.Waze][17 pkts/4015 bytes][Host: roadshields.waze.com] diff --git a/tests/result/weibo.pcap.out b/tests/result/weibo.pcap.out new file mode 100644 index 000000000..2be5bb816 --- /dev/null +++ b/tests/result/weibo.pcap.out @@ -0,0 +1,51 @@ +DNS 11 1129 6 +HTTP 19 2275 5 +SSL 17 1366 11 +Google 10 660 5 +QUIC 23 4118 2 +Weibo 418 258007 15 + + 1 TCP 140.205.174.1:443 <-> 192.168.1.105:48352 [proto: 91/SSL][1 pkts/74 bytes] + 2 TCP 140.205.174.1:443 <-> 192.168.1.105:48356 [proto: 91/SSL][1 pkts/74 bytes] + 3 TCP 192.168.1.105:59120 <-> 114.134.80.162:80 [proto: 7/HTTP][3 pkts/194 bytes] + 4 TCP 216.58.212.65:443 <-> 192.168.1.105:34699 [proto: 91.126/SSL.Google][2 pkts/132 bytes] + 5 TCP 222.73.28.96:80 <-> 192.168.1.105:42275 [proto: 7.210/HTTP.Weibo][4 pkts/676 bytes][Host: u1.img.mobile.sina.cn] + 6 UDP 192.168.1.1:53 <-> 192.168.1.105:50533 [proto: 5.210/DNS.Weibo][1 pkts/74 bytes][Host: data.weibo.com] + 7 UDP 192.168.1.1:53 <-> 192.168.1.105:53543 [proto: 5.210/DNS.Weibo][2 pkts/266 bytes][Host: img.t.sinajs.cn] + 8 UDP 216.58.210.14:443 <-> 192.168.1.105:49361 [proto: 188/QUIC][9 pkts/1944 bytes] + 9 TCP 216.58.214.78:443 <-> 192.168.1.105:58481 [proto: 91.126/SSL.Google][2 pkts/132 bytes] + 10 UDP 192.168.1.1:53 <-> 192.168.1.105:7148 [proto: 5.210/DNS.Weibo][2 pkts/215 bytes][Host: www.weibo.com] + 11 TCP 192.168.1.105:35803 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][106 pkts/76903 bytes][Host: img.t.sinajs.cn] + 12 TCP 192.168.1.105:35805 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][41 pkts/23245 bytes][Host: img.t.sinajs.cn] + 13 TCP 192.168.1.105:35807 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][53 pkts/36468 bytes][Host: img.t.sinajs.cn] + 14 TCP 192.168.1.105:35809 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][35 pkts/22361 bytes][Host: img.t.sinajs.cn] + 15 TCP 192.168.1.105:35811 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][5 pkts/744 bytes][Host: js.t.sinajs.cn] + 16 TCP 192.168.1.105:50827 <-> 47.89.65.229:443 [proto: 91/SSL][4 pkts/448 bytes][SSL client: g.alicdn.com] + 17 TCP 192.168.1.105:50831 <-> 47.89.65.229:443 [proto: 91/SSL][3 pkts/194 bytes] + 18 TCP 42.156.184.19:443 <-> 192.168.1.105:52272 [proto: 91/SSL][1 pkts/74 bytes] + 19 TCP 42.156.184.19:443 <-> 192.168.1.105:52274 [proto: 91/SSL][1 pkts/74 bytes] + 20 UDP 192.168.1.1:53 <-> 192.168.1.105:11798 [proto: 5.210/DNS.Weibo][1 pkts/77 bytes][Host: account.weibo.com] + 21 UDP 192.168.1.1:53 <-> 192.168.1.105:16804 [proto: 5/DNS][1 pkts/70 bytes][Host: c.weibo.cn] + 22 TCP 140.205.170.63:443 <-> 192.168.1.105:47721 [proto: 91/SSL][1 pkts/74 bytes] + 23 TCP 140.205.170.63:443 <-> 192.168.1.105:47723 [proto: 91/SSL][1 pkts/74 bytes] + 24 TCP 140.205.174.1:443 <-> 192.168.1.105:48353 [proto: 91/SSL][1 pkts/74 bytes] + 25 UDP 192.168.1.1:53 <-> 192.168.1.105:33822 [proto: 5/DNS][2 pkts/242 bytes][Host: login.taobao.com] + 26 TCP 192.168.1.105:59119 <-> 114.134.80.162:80 [proto: 7/HTTP][9 pkts/1599 bytes][Host: weibo.com] + 27 TCP 192.168.1.105:59121 <-> 114.134.80.162:80 [proto: 7/HTTP][3 pkts/194 bytes] + 28 TCP 192.168.1.105:35154 <-> 216.58.210.206:443 [proto: 91.126/SSL.Google][2 pkts/132 bytes] + 29 TCP 216.58.212.69:443 <-> 192.168.1.105:37802 [proto: 91.126/SSL.Google][2 pkts/132 bytes] + 30 UDP 192.168.1.1:53 <-> 192.168.1.105:41352 [proto: 5.210/DNS.Weibo][2 pkts/264 bytes][Host: js.t.sinajs.cn] + 31 TCP 222.73.28.96:80 <-> 192.168.1.105:42280 [proto: 7/HTTP][1 pkts/74 bytes] + 32 UDP 192.168.1.1:53 <-> 192.168.1.105:50640 [proto: 5/DNS][2 pkts/234 bytes][Host: acjstb.aliyun.com] + 33 UDP 192.168.1.1:53 <-> 192.168.1.105:51440 [proto: 5/DNS][2 pkts/243 bytes][Host: g.alicdn.com] + 34 UDP 192.168.1.1:53 <-> 192.168.1.105:53466 [proto: 5/DNS][2 pkts/186 bytes][Host: log.mmstat.com] + 35 UDP 192.168.1.1:53 <-> 192.168.1.105:54988 [proto: 5/DNS][2 pkts/154 bytes][Host: weibo.com] + 36 UDP 192.168.1.105:53656 <-> 216.58.210.227:443 [proto: 188/QUIC][14 pkts/2174 bytes] + 37 TCP 216.58.214.78:443 <-> 192.168.1.105:58480 [proto: 91.126/SSL.Google][2 pkts/132 bytes] + 38 TCP 192.168.1.105:40440 <-> 54.225.163.210:443 [proto: 91/SSL][2 pkts/132 bytes] + 39 TCP 192.168.1.105:35804 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][72 pkts/54281 bytes][Host: img.t.sinajs.cn] + 40 TCP 192.168.1.105:35806 <-> 93.188.134.246:80 [proto: 7.210/HTTP.Weibo][13 pkts/4701 bytes][Host: img.t.sinajs.cn] + 41 TCP 192.168.1.105:35808 <-> 93.188.134.246:80 [proto: 7/HTTP][3 pkts/214 bytes] + 42 TCP 42.156.184.19:443 <-> 192.168.1.105:52271 [proto: 91/SSL][1 pkts/74 bytes] + 43 UDP 192.168.1.1:53 <-> 192.168.1.105:18035 [proto: 5.210/DNS.Weibo][2 pkts/240 bytes][Host: u1.img.mobile.sina.cn] + 44 TCP 192.168.1.105:51698 <-> 93.188.134.137:80 [proto: 7.210/HTTP.Weibo][79 pkts/37492 bytes][Host: www.weibo.com] diff --git a/tests/result/whatsapp_login_call.pcap.out b/tests/result/whatsapp_login_call.pcap.out index fd2edb823..41ec89cdf 100644 --- a/tests/result/whatsapp_login_call.pcap.out +++ b/tests/result/whatsapp_login_call.pcap.out @@ -4,7 +4,7 @@ DHCP 10 3420 1 STUN 97 11786 16 ICMP 10 700 1 SSL 8 589 2 -DropBox 4 2176 1 +Dropbox 4 2176 1 Apple 127 28102 20 WhatsApp 182 25154 2 AppleiTunes 85 28087 2 @@ -12,7 +12,7 @@ Spotify 3 258 1 WhatsAppVoice 706 91156 4 1 UDP [fe80::da30:62ff:fe56:1c]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][2 pkts/258 bytes] - 2 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/DropBox][4 pkts/2176 bytes] + 2 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/Dropbox][4 pkts/2176 bytes] 3 ICMP 192.168.2.4:0 <-> 91.253.176.65:0 [proto: 81/ICMP][10 pkts/700 bytes] 4 UDP 192.168.2.4:52794 <-> 91.253.176.65:9665 [proto: 189/WhatsAppVoice][198 pkts/30418 bytes] 5 UDP 173.252.114.1:3478 <-> 192.168.2.4:52794 [proto: 78/STUN][5 pkts/676 bytes] diff --git a/tests/result/whatsapp_login_chat.pcap.out b/tests/result/whatsapp_login_chat.pcap.out index 0a904dd54..13c56555a 100644 --- a/tests/result/whatsapp_login_chat.pcap.out +++ b/tests/result/whatsapp_login_chat.pcap.out @@ -1,11 +1,11 @@ MDNS 2 202 2 DHCP 6 2052 1 -DropBox 2 1088 1 +Dropbox 2 1088 1 Apple 50 23466 2 WhatsApp 32 3243 2 Spotify 1 86 1 - 1 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/DropBox][2 pkts/1088 bytes] + 1 UDP 192.168.2.1:17500 <-> 192.168.2.255:17500 [proto: 121/Dropbox][2 pkts/1088 bytes] 2 UDP [fe80::189c:c31b:1298:224]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][1 pkts/111 bytes] 3 UDP 192.168.2.1:53 <-> 192.168.2.4:61697 [proto: 5.142/DNS.WhatsApp][2 pkts/280 bytes][Host: e12.whatsapp.net] 4 TCP 192.168.2.4:49205 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][44 pkts/21371 bytes] |