From d8b2189cc30f675fba46b072d162dc5943b1c362 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Fri, 14 Apr 2017 00:07:46 +0200 Subject: Initial wireshark integration via extcap interface --- example/ndpiReader.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 230 insertions(+), 12 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index dda137df9..0852777c8 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -24,11 +24,11 @@ #endif #include #include +#include #ifdef WIN32 #include /* winsock.h is included automatically */ #include #include -#include #define getopt getopt____ #else #include @@ -81,6 +81,10 @@ static time_t capture_for = 0; static time_t capture_until = 0; static u_int32_t num_flows; +static pcap_dumper_t *extcap_dumper = NULL; +static char *extcap_capture_fifo = NULL; +static u_int16_t extcap_packet_filter = (u_int16_t)-1; + // struct associated to a workflow for a thread struct reader_thread { struct ndpi_workflow * workflow; @@ -104,8 +108,15 @@ typedef struct ndpi_id { u_int32_t current_ndpi_memory = 0, max_ndpi_memory = 0; -/********************** FUNCTIONS ********************* */ +void test_lib(); /* Forward */ + +/* ********************************** */ + +#ifdef DEBUG_TRACE +FILE *trace = NULL; +#endif +/********************** FUNCTIONS ********************* */ /** * @brief Set main components necessary to the detection @@ -142,6 +153,20 @@ static void help(u_int long_help) { " -h | This help\n" " -v <1|2> | Verbose 'unknown protocol' packet print. 1=verbose, 2=very verbose\n"); + #ifndef WIN32 + printf("\nExcap (wireshark) options:\n" + " --extcap-interfaces\n" + " --extcap-version\n" + " --extcap-dlts\n" + " --extcap-interface \n" + " --extcap-config\n" + " --capture\n" + " --extcap-capture-filter\n" + " --fifo \n" + " --debug\n" + ); + #endif + if(long_help) { printf("\n\nSupported protocols:\n"); num_threads = 1; @@ -152,28 +177,153 @@ static void help(u_int long_help) { } +static struct option longopts[] = { + /* mandatory extcap options */ + { "extcap-interfaces", no_argument, NULL, '0'}, + { "extcap-version", optional_argument, NULL, '1'}, + { "extcap-dlts", no_argument, NULL, '2'}, + { "extcap-interface", required_argument, NULL, '3'}, + { "extcap-config", no_argument, NULL, '4'}, + { "capture", no_argument, NULL, '5'}, + { "extcap-capture-filter", required_argument, NULL, '6'}, + { "fifo", required_argument, NULL, '7'}, + { "debug", optional_argument, NULL, '8'}, + { "ndpi-proto-filter", required_argument, NULL, '9'}, + + /* ndpiReader options */ + { "enable-protocol-guess", no_argument, NULL, 'd'}, + { "interface", required_argument, NULL, 'i'}, + { "filter", required_argument, NULL, 'f'}, + { "cpu-bind", required_argument, NULL, 'g'}, + { "loops", required_argument, NULL, 'l'}, + { "num-threads", required_argument, NULL, 'n'}, + + { "protos", required_argument, NULL, 'p'}, + { "capture-duration", required_argument, NULL, 's'}, + { "decode-tunnels", no_argument, NULL, 't'}, + { "revision", no_argument, NULL, 'r'}, + { "verbose", no_argument, NULL, 'v'}, + { "version", no_argument, NULL, 'V'}, + { "help", no_argument, NULL, 'h'}, + { "json", required_argument, NULL, 'j'}, + { "result-path", required_argument, NULL, 'w'}, + { "quiet", no_argument, NULL, 'q'}, + + {0, 0, 0, 0} +}; + +/* ********************************** */ + +void extcap_interfaces() { + printf("extcap {version=%s}\n", ndpi_revision()); + printf("interface {value=ndpi}{display=nDPI interface}\n"); + exit(0); +} + +/* ********************************** */ + +void extcap_dlts() { + u_int dlts_number = DLT_EN10MB; + printf("dlt {number=%u}{name=%s}{display=%s}\n", dlts_number, "ndpi", "nDPI interface"); + exit(0); +} + +/* ********************************** */ + +void extcap_config() { + int i, argidx = 0; + struct ndpi_detection_module_struct *ndpi_mod; + +#if 1 + printf("arg {number=%u}{call=-i}{display=Capture Interface Name}{type=string}" + "{tooltip=The interface name}\n", argidx++); +#else + + printf("arg {number=%u}{call=-i}{display=Pcap File to Analize}{type=fileselect}" + "{tooltip=The pcap file to analyze (if the interface is unspecified)}\n", argidx++); +#endif + + printf("arg {number=%u}{call=-9}{display=nDPI Protocol}{type=selector}" + "{tooltip=nDPI Protocol to be filtered}\n", argidx); + + setupDetection(0, NULL); + ndpi_mod = ndpi_thread_info[0].workflow->ndpi_struct; + + printf("value {arg=%d}{value=%d}{display=%s}\n", argidx, -1, "All Protocols (no nDPI filtering)"); + + for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) + printf("value {arg=%d}{value=%d}{display=%s (%u)}\n", argidx, i, + ndpi_mod->proto_defaults[i].protoName, i); + + exit(0); +} + +/* ********************************** */ + +void extcap_capture() { +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, " #### %s #### \n", __FUNCTION__); +#endif + + if((extcap_dumper = pcap_dump_open(pcap_open_dead(DLT_EN10MB, 16384 /* MTU */), + extcap_capture_fifo)) == NULL) { + fprintf(stderr, "Unable to open the pcap dumper on %s", extcap_capture_fifo); + +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, "Unable to open the pcap dumper on %s\n", + extcap_capture_fifo); +#endif + return; + } + +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, "Starting packet capture [%p]\n", extcap_dumper); +#endif + + test_lib(); + pcap_dump_close(extcap_dumper); + +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, "End of packet capture [%p]\n", extcap_dumper); +#endif +} + +/* ********************************** */ + /** * @brief Option parser */ static void parseOptions(int argc, char **argv) { - + int option_idx = 0, do_capture = 0; char *__pcap_file = NULL, *bind_mask = NULL; int thread_id, opt; #ifdef linux u_int num_cores = sysconf(_SC_NPROCESSORS_ONLN); #endif - while ((opt = getopt(argc, argv, "df:g:i:hp:l:s:tv:V:n:j:rp:w:q")) != EOF) { +#ifdef DEBUG_TRACE + trace = fopen("/tmp/ndpiReader.log", "a"); + + if(trace) fprintf(trace, " #### %s #### \n", __FUNCTION__); +#endif + + while ((opt = getopt_long(argc, argv, "df:g:i:hp:l:s:tv:V:n:j:rp:w:q0123:456:7:89:", longopts, &option_idx)) != EOF) { +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, " #### -%c [%s] #### \n", opt, optarg ? optarg : ""); +#endif + switch (opt) { case 'd': enable_protocol_guess = 0; break; case 'i': + case '3': _pcap_file[0] = optarg; break; case 'f': + case '6': _bpf_filter = optarg; break; @@ -240,12 +390,47 @@ static void parseOptions(int argc, char **argv) { quiet_mode = 1; break; + /* Extcap */ + case '0': + extcap_interfaces(); + break; + + case '1': + printf("extcap {version=%s}\n", ndpi_revision()); + break; + + case '2': + extcap_dlts(); + break; + + case '4': + extcap_config(); + break; + + case '5': + do_capture = 1; + break; + + case '7': + extcap_capture_fifo = strdup(optarg); + break; + + case '8': + nDPI_traceLevel = 9; + break; + + case '9': + extcap_packet_filter = atoi(optarg); + break; + default: help(0); break; } } + if(do_capture) extcap_capture(); + // check parameters if(_pcap_file[0] == NULL || strcmp(_pcap_file[0], "") == 0) { help(0); @@ -277,6 +462,10 @@ static void parseOptions(int argc, char **argv) { } } #endif + +#ifdef DEBUG_TRACE + if(trace) fclose(trace); +#endif } @@ -370,7 +559,7 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { ntohs(flow->upper_port)); if(flow->vlan_id > 0) fprintf(out, "[VLAN: %u]", flow->vlan_id); - + if(flow->detected_protocol.master_protocol) { char buf[64]; @@ -388,7 +577,7 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { if(flow->host_server_name[0] != '\0') fprintf(out, "[Host: %s]", flow->host_server_name); if(flow->info[0] != '\0') fprintf(out, "[%s]", flow->info); - + if(flow->ssh_ssl.client_info[0] != '\0') fprintf(out, "[client: %s]", flow->ssh_ssl.client_info); if(flow->ssh_ssl.server_info[0] != '\0') fprintf(out, "[server: %s]", flow->ssh_ssl.server_info); if(flow->bittorent_hash[0] != '\0') fprintf(out, "[BT Hash: %s]", flow->bittorent_hash); @@ -1138,13 +1327,14 @@ static pcap_t * openPcapFileOrDevice(u_int16_t thread_id, const u_char * pcap_fi static void pcap_packet_callback_checked(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { - + struct ndpi_proto p; u_int16_t thread_id = *((u_int16_t*)args); /* 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); + p = 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].workflow->pcap_handle != NULL) @@ -1182,6 +1372,25 @@ static void pcap_packet_callback_checked(u_char *args, } } +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, "Found %u bytes packet %u.%u\n", header->caplen, p.app_protocol, p.master_protocol); +#endif + + if(extcap_dumper + && ((extcap_packet_filter == (u_int16_t)-1) + || (p.app_protocol == extcap_packet_filter) + || (p.master_protocol == extcap_packet_filter) + ) + ) { + struct pcap_pkthdr *h = (struct pcap_pkthdr*)header; + +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, "Dumping %u bytes packet\n", header->caplen); +#endif + // h->caplen += 8, h->len += 8; + pcap_dump((u_char*)extcap_dumper, h, packet); + } + /* check for buffer changes */ if(memcmp(packet, packet_checked, header->caplen) != 0) printf("INTERNAL ERROR: ingress packet was modified by nDPI: this should not happen [thread_id=%u, packetId=%lu]\n", @@ -1244,7 +1453,6 @@ void * processing_thread(void *_thread_id) { * @brief Begin, process, end detection process */ void test_lib() { - struct timeval begin, end; u_int64_t tot_usec; long thread_id; @@ -1253,8 +1461,18 @@ void test_lib() { json_init(); #endif +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, "Num threads: %d\n", num_threads); +#endif + for(thread_id = 0; thread_id < num_threads; thread_id++) { - pcap_t * cap = openPcapFileOrDevice(thread_id, (const u_char*)_pcap_file[thread_id]); + pcap_t *cap; + +#ifdef DEBUG_TRACE + if(trace) fprintf(trace, "Opening %s\n", (const u_char*)_pcap_file[thread_id]); +#endif + + cap = openPcapFileOrDevice(thread_id, (const u_char*)_pcap_file[thread_id]); setupDetection(thread_id, cap); } @@ -1275,9 +1493,9 @@ void test_lib() { printResults(tot_usec); for(thread_id = 0; thread_id < num_threads; thread_id++) { - if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL) { + if(ndpi_thread_info[thread_id].workflow->pcap_handle != NULL) pcap_close(ndpi_thread_info[thread_id].workflow->pcap_handle); - } + terminateDetection(thread_id); } } -- cgit v1.2.3 From 29cd6ef9942188633b79b5c1fe62360f048a6450 Mon Sep 17 00:00:00 2001 From: Campus Date: Sat, 15 Apr 2017 00:29:53 +0200 Subject: fix segmentation fault caused by missing spanning tree check - add control for threads return values --- example/ndpiReader.c | 32 +++++++++++++++++++++++++------- example/ndpi_util.c | 13 ++++++++++--- 2 files changed, 35 insertions(+), 10 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 0852777c8..3df43a9fe 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1331,7 +1331,7 @@ static void pcap_packet_callback_checked(u_char *args, u_int16_t thread_id = *((u_int16_t*)args); /* allocate an exact size buffer to check overflows */ - uint8_t *packet_checked = malloc(header->caplen); + uint8_t *packet_checked = malloc(header->caplen); /* HEAP OVERFLOW !!! */ memcpy(packet_checked, packet, header->caplen); p = ndpi_workflow_process_packet(ndpi_thread_info[thread_id].workflow, header, packet_checked); @@ -1478,14 +1478,32 @@ void test_lib() { gettimeofday(&begin, NULL); - /* Running processing threads */ - for(thread_id = 0; thread_id < num_threads; thread_id++) - pthread_create(&ndpi_thread_info[thread_id].pthread, NULL, processing_thread, (void *) thread_id); + int status; + void * thd_res; + /* Running processing threads */ + for(thread_id = 0; thread_id < num_threads; thread_id++) { + status = pthread_create(&ndpi_thread_info[thread_id].pthread, NULL, processing_thread, (void *) thread_id); + /* check pthreade_create return value */ + if(status != 0) { + fprintf(stderr, "error on create %ld thread\n", thread_id); + exit(-1); + } + } /* Waiting for completion */ - for(thread_id = 0; thread_id < num_threads; thread_id++) - pthread_join(ndpi_thread_info[thread_id].pthread, NULL); - + for(thread_id = 0; thread_id < num_threads; thread_id++) { + status = pthread_join(ndpi_thread_info[thread_id].pthread, thd_res); + /* check pthreade_join return value */ + if(status != 0) { + fprintf(stderr, "error on join %ld thread\n", thread_id); + exit(-1); + } + if(thd_res != NULL) { + fprintf(stderr, "error on returned value of %ld joined thread\n", thread_id); + exit(-1); + } + } + gettimeofday(&end, NULL); tot_usec = end.tv_sec*1000000 + end.tv_usec - (begin.tv_sec*1000000 + begin.tv_usec); diff --git a/example/ndpi_util.c b/example/ndpi_util.c index 60dc94230..a5d9d300d 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -48,6 +48,7 @@ #define MPLS_MULTI 0x8848 #define PPPoE 0x8864 #define SNAP 0xaa +#define BSTP 0x42 /* Bridge Spanning Tree Protocol */ /* mask for FCF */ #define WIFI_DATA 0x2 /* 0000 0010 */ @@ -286,8 +287,10 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow 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 == IPPROTO_UDP && l4_packet_len >= 8) { + // udp + } else if(iph->protocol == IPPROTO_UDP && l4_packet_len >= 8) { + workflow->stats.udp_count++; *udph = (struct ndpi_udphdr *)l4; @@ -670,12 +673,16 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, type = check; if(pyld_eth_len != 0) { + llc = (struct ndpi_llc_header *)(&packet[ip_offset]); /* check for LLC layer with SNAP extension */ - if(packet[ip_offset] == SNAP) { - llc = (struct ndpi_llc_header *)(&packet[ip_offset]); + if(llc->dsap == SNAP || llc->ssap == SNAP) { +#define SNAP_EXT type = llc->snap.proto_ID; ip_offset += + 8; } + else if(llc->dsap == BSTP || llc->ssap == BSTP) { + goto v4_warning; + } } break; -- cgit v1.2.3 From 2b0809f3dc297289f9413db4dde2eaa109a3603e Mon Sep 17 00:00:00 2001 From: Campus Date: Sat, 15 Apr 2017 00:40:01 +0200 Subject: name correction for llc_snap header and minor fix --- example/ndpiReader.c | 2 +- example/ndpi_util.c | 10 +++++----- src/include/ndpi_typedefs.h | 4 +--- 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 3df43a9fe..b32650871 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1331,7 +1331,7 @@ static void pcap_packet_callback_checked(u_char *args, u_int16_t thread_id = *((u_int16_t*)args); /* allocate an exact size buffer to check overflows */ - uint8_t *packet_checked = malloc(header->caplen); /* HEAP OVERFLOW !!! */ + uint8_t *packet_checked = malloc(header->caplen); memcpy(packet_checked, packet, header->caplen); p = ndpi_workflow_process_packet(ndpi_thread_info[thread_id].workflow, header, packet_checked); diff --git a/example/ndpi_util.c b/example/ndpi_util.c index a5d9d300d..8fe80111a 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -582,7 +582,7 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, /* --- Ethernet header --- */ const struct ndpi_ethhdr *ethernet; /* --- LLC header --- */ - const struct ndpi_llc_header *llc; + const struct ndpi_llc_header_snap *llc; /* --- Cisco HDLC header --- */ const struct ndpi_chdlc *chdlc; @@ -673,13 +673,13 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, type = check; if(pyld_eth_len != 0) { - llc = (struct ndpi_llc_header *)(&packet[ip_offset]); + llc = (struct ndpi_llc_header_snap *)(&packet[ip_offset]); /* check for LLC layer with SNAP extension */ if(llc->dsap == SNAP || llc->ssap == SNAP) { -#define SNAP_EXT type = llc->snap.proto_ID; ip_offset += + 8; } + /* No SNAP extension - Spanning Tree pkt must be discarted */ else if(llc->dsap == BSTP || llc->ssap == BSTP) { goto v4_warning; } @@ -716,12 +716,12 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, break; /* Check ether_type from LLC */ - llc = (struct ndpi_llc_header*)(packet + eth_offset + wifi_len + radio_len); + llc = (struct ndpi_llc_header_snap*)(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; + ip_offset = wifi_len + radio_len + sizeof(struct ndpi_llc_header_snap) + eth_offset; break; case DLT_RAW: diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 490098086..e1fbeb71c 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -138,14 +138,12 @@ struct ndpi_snap_extension } PACK_OFF; PACK_ON -struct ndpi_llc_header +struct ndpi_llc_header_snap { u_int8_t dsap; u_int8_t ssap; u_int8_t ctrl; -#ifdef SNAP_EXT struct ndpi_snap_extension snap; -#endif } PACK_OFF; /* ++++++++++ RADIO TAP header (for IEEE 802.11) +++++++++++++ */ -- cgit v1.2.3 From 4c5de9ef8e9e14289ce9024349390fe06b59c769 Mon Sep 17 00:00:00 2001 From: Luca Date: Mon, 17 Apr 2017 09:38:30 +0200 Subject: Added ethernet checksum reforging and nDPI protocol export in nDPI-extcap reader --- example/ndpiReader.c | 26 +++++++++++++++++++++----- example/ndpi_util.c | 40 ++++++++++++++++++++++++++++++++++++++++ example/ndpi_util.h | 2 +- 3 files changed, 62 insertions(+), 6 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index b32650871..9eab4500f 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -81,7 +81,13 @@ static time_t capture_for = 0; static time_t capture_until = 0; static u_int32_t num_flows; +struct ndpi_packet_trailer { + u_int32_t magic; /* 0x19682017 */ + u_int16_t master_protocol /* e.g. HTTP */, app_protocol /* e.g. FaceBook */; +}; + static pcap_dumper_t *extcap_dumper = NULL; +static char extcap_buf[2048]; static char *extcap_capture_fifo = NULL; static u_int16_t extcap_packet_filter = (u_int16_t)-1; @@ -422,7 +428,7 @@ static void parseOptions(int argc, char **argv) { case '9': extcap_packet_filter = atoi(optarg); break; - + default: help(0); break; @@ -1383,12 +1389,22 @@ static void pcap_packet_callback_checked(u_char *args, ) ) { struct pcap_pkthdr *h = (struct pcap_pkthdr*)header; - + uint32_t *crc, delta = sizeof(struct ndpi_packet_trailer) + 4 /* ethernet trailer */; + struct ndpi_packet_trailer *trailer = (struct ndpi_packet_trailer*)&extcap_buf[h->caplen]; + + memcpy(extcap_buf, packet, h->caplen); + trailer->magic = 0x19682017; + trailer->master_protocol = p.master_protocol, trailer->app_protocol = p.app_protocol; + crc = (uint32_t*)&extcap_buf[h->caplen+sizeof(struct ndpi_packet_trailer)]; + *crc = 0; + ethernet_crc32((const void*)extcap_buf, h->caplen+sizeof(struct ndpi_packet_trailer), crc); + h->caplen += delta, h->len += delta; + #ifdef DEBUG_TRACE if(trace) fprintf(trace, "Dumping %u bytes packet\n", header->caplen); #endif - // h->caplen += 8, h->len += 8; - pcap_dump((u_char*)extcap_dumper, h, packet); + + pcap_dump((u_char*)extcap_dumper, h, (const u_char *)extcap_buf); } /* check for buffer changes */ @@ -1503,7 +1519,7 @@ void test_lib() { exit(-1); } } - + gettimeofday(&end, NULL); tot_usec = end.tv_sec*1000000 + end.tv_usec - (begin.tv_sec*1000000 + begin.tv_usec); diff --git a/example/ndpi_util.c b/example/ndpi_util.c index 8fe80111a..cd3c8a1e3 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -909,3 +909,43 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, return(packet_processing(workflow, time, vlan_id, iph, iph6, ip_offset, header->len - ip_offset, header->len)); } + +/* ********************************************************** */ +/* http://home.thep.lu.se/~bjorn/crc/crc32_fast.c */ +/* ********************************************************** */ + +static uint32_t crc32_for_byte(uint32_t r) { + for(int j = 0; j < 8; ++j) + r = (r & 1? 0: (uint32_t)0xEDB88320L) ^ r >> 1; + return r ^ (uint32_t)0xFF000000L; +} + +/* Any unsigned integer type with at least 32 bits may be used as + * accumulator type for fast crc32-calulation, but unsigned long is + * probably the optimal choice for most systems. */ +typedef unsigned long accum_t; + +static void init_tables(uint32_t* table, uint32_t* wtable) { + for(size_t i = 0; i < 0x100; ++i) + table[i] = crc32_for_byte(i); + for(size_t k = 0; k < sizeof(accum_t); ++k) + for(size_t w, i = 0; i < 0x100; ++i) { + for(size_t j = w = 0; j < sizeof(accum_t); ++j) + w = table[(uint8_t)(j == k? w ^ i: w)] ^ w >> 8; + wtable[(k << 8) + i] = w ^ (k? wtable[0]: 0); + } +} + +void ethernet_crc32(const void* data, size_t n_bytes, uint32_t* crc) { + static uint32_t table[0x100], wtable[0x100*sizeof(accum_t)]; + size_t n_accum = n_bytes/sizeof(accum_t); + if(!*table) + init_tables(table, wtable); + for(size_t i = 0; i < n_accum; ++i) { + accum_t a = *crc ^ ((accum_t*)data)[i]; + for(size_t j = *crc = 0; j < sizeof(accum_t); ++j) + *crc ^= wtable[(j << 8) + (uint8_t)(a >> 8*j)]; + } + for(size_t i = n_accum*sizeof(accum_t); i < n_bytes; ++i) + *crc = table[(uint8_t)*crc ^ ((uint8_t*)data)[i]] ^ *crc >> 8; +} diff --git a/example/ndpi_util.h b/example/ndpi_util.h index 4895cdcb1..a8e21d673 100644 --- a/example/ndpi_util.h +++ b/example/ndpi_util.h @@ -160,5 +160,5 @@ static inline void ndpi_workflow_set_flow_giveup_callback(struct ndpi_workflow * /* compare two nodes in workflow */ int ndpi_workflow_node_cmp(const void *a, const void *b); void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow); - +void ethernet_crc32(const void* data, size_t n_bytes, uint32_t* crc); #endif -- cgit v1.2.3 From 56b6c7ed93b7fbdc1963200c208437c16fe5437f Mon Sep 17 00:00:00 2001 From: Luca Date: Wed, 19 Apr 2017 09:50:54 +0200 Subject: Fixed thread crash caused by commit 29cd6ef9942188633b79b5c1fe62360f048a6450 --- example/ndpiReader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 9eab4500f..b0b21b2b3 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1508,7 +1508,7 @@ void test_lib() { } /* Waiting for completion */ for(thread_id = 0; thread_id < num_threads; thread_id++) { - status = pthread_join(ndpi_thread_info[thread_id].pthread, thd_res); + status = pthread_join(ndpi_thread_info[thread_id].pthread, &thd_res); /* check pthreade_join return value */ if(status != 0) { fprintf(stderr, "error on join %ld thread\n", thread_id); -- cgit v1.2.3 From a9c01ded174ed380a2d135cfb9b903f616b0e175 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Wed, 19 Apr 2017 21:55:49 +0200 Subject: ndpiReader now prints (-v) the flows with the correct direction --- example/ndpiReader.c | 28 +++++++++++++++++----------- example/ndpi_util.c | 22 ++++++++++------------ example/ndpi_util.h | 2 +- 3 files changed, 28 insertions(+), 24 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index b0b21b2b3..ca06e98b8 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -553,17 +553,23 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { if(!json_flag) { fprintf(out, "\t%u", ++num_flows); - fprintf(out, "\t%s %s%s%s:%u <-> %s%s%s:%u ", - ipProto2Name(flow->protocol), - (flow->ip_version == 6) ? "[" : "", - flow->lower_name, - (flow->ip_version == 6) ? "]" : "", - ntohs(flow->lower_port), - (flow->ip_version == 6) ? "[" : "", - flow->upper_name, - (flow->ip_version == 6) ? "]" : "", - ntohs(flow->upper_port)); - + fprintf(out, "\t%s ", ipProto2Name(flow->protocol)); + + if(flow->src_to_dst_direction == 1) + fprintf(out, "%s%s%s:%u <-> %s%s%s:%u ", + (flow->ip_version == 6) ? "[" : "", + flow->lower_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->lower_port), + (flow->ip_version == 6) ? "[" : "", + flow->upper_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->upper_port) + ); + else + fprintf(out, "%s%s%s:%u <-> %s%s%s:%u ", + (flow->ip_version == 6) ? "[" : "", + flow->upper_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->upper_port), + (flow->ip_version == 6) ? "[" : "", + flow->lower_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->lower_port) + ); + if(flow->vlan_id > 0) fprintf(out, "[VLAN: %u]", flow->vlan_id); if(flow->detected_protocol.master_protocol) { diff --git a/example/ndpi_util.c b/example/ndpi_util.c index 783f05c86..445ade1ac 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -260,9 +260,8 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow if(iph->protocol == IPPROTO_TCP && l4_packet_len >= 20) { u_int tcp_len; + // tcp workflow->stats.tcp_count++; - - // tcp *tcph = (struct ndpi_tcphdr *)l4; *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest); @@ -287,12 +286,10 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow 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); - - // udp } else if(iph->protocol == IPPROTO_UDP && 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)]; @@ -335,7 +332,9 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow 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); + 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)); @@ -350,7 +349,8 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow newflow->lower_ip = lower_ip, newflow->upper_ip = upper_ip; newflow->lower_port = lower_port, newflow->upper_port = upper_port; newflow->ip_version = version; - + newflow->src_to_dst_direction = *src_to_dst_direction; + if(version == IPVERSION) { 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)); @@ -520,7 +520,7 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, struct ndpi_udphdr *udph = NULL; u_int16_t sport, dport, payload_len; u_int8_t *payload; - u_int8_t src_to_dst_direction= 1; + u_int8_t src_to_dst_direction = 1; if(iph) flow = get_ndpi_flow_info(workflow, IPVERSION, vlan_id, iph, NULL, @@ -542,9 +542,8 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, ndpi_flow = flow->ndpi_flow; flow->packets++, flow->bytes += rawsize; flow->last_seen = time; - } else { + } else return(flow->detected_protocol); - } /* Protocol already detected */ if(flow->detection_completed) return(flow->detected_protocol); @@ -556,8 +555,7 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, if((flow->detected_protocol.app_protocol != NDPI_PROTOCOL_UNKNOWN) || ((proto == IPPROTO_UDP) && (flow->packets > 8)) || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { - /* New protocol detected or give up */ - + /* New protocol detected or give up */ flow->detection_completed = 1; } diff --git a/example/ndpi_util.h b/example/ndpi_util.h index a8e21d673..335c94ddf 100644 --- a/example/ndpi_util.h +++ b/example/ndpi_util.h @@ -46,7 +46,7 @@ typedef struct ndpi_flow_info { u_int32_t upper_ip; u_int16_t lower_port; u_int16_t upper_port; - u_int8_t detection_completed, protocol; + u_int8_t detection_completed, protocol, src_to_dst_direction; u_int16_t vlan_id; struct ndpi_flow_struct *ndpi_flow; char lower_name[48], upper_name[48]; -- cgit v1.2.3 From 4cc54cceb5514acce67bf577f2116ee97505d805 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Wed, 19 Apr 2017 23:31:45 +0200 Subject: Added port stats when verbose mode (-v) is used --- example/ndpiReader.c | 113 +++++- example/uthash.h | 1096 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1200 insertions(+), 9 deletions(-) create mode 100644 example/uthash.h (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index ca06e98b8..2b02093cb 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -44,6 +44,7 @@ #include #include "../config.h" #include "ndpi_api.h" +#include "uthash.h" #ifdef HAVE_JSON_C #include @@ -81,9 +82,17 @@ static time_t capture_for = 0; static time_t capture_until = 0; static u_int32_t num_flows; +struct port_stats { + u_int32_t port; /* we'll use this field as the key */ + u_int32_t num_pkts, num_bytes; + UT_hash_handle hh; /* makes this structure hashable */ +}; + +struct port_stats *srcStats = NULL, *dstStats = NULL; + struct ndpi_packet_trailer { - u_int32_t magic; /* 0x19682017 */ - u_int16_t master_protocol /* e.g. HTTP */, app_protocol /* e.g. FaceBook */; + u_int32_t magic; /* 0x19682017 */ + u_int16_t master_protocol /* e.g. HTTP */, app_protocol /* e.g. FaceBook */; }; static pcap_dumper_t *extcap_dumper = NULL; @@ -554,7 +563,7 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { fprintf(out, "\t%u", ++num_flows); fprintf(out, "\t%s ", ipProto2Name(flow->protocol)); - + if(flow->src_to_dst_direction == 1) fprintf(out, "%s%s%s:%u <-> %s%s%s:%u ", (flow->ip_version == 6) ? "[" : "", @@ -569,7 +578,7 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { (flow->ip_version == 6) ? "[" : "", flow->lower_name, (flow->ip_version == 6) ? "]" : "", ntohs(flow->lower_port) ); - + if(flow->vlan_id > 0) fprintf(out, "[VLAN: %u]", flow->vlan_id); if(flow->detected_protocol.master_protocol) { @@ -703,7 +712,6 @@ static u_int16_t node_guess_undetected_protocol(u_int16_t thread_id, struct ndpi * @brief Proto Guess Walker */ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { - struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node; u_int16_t thread_id = *((u_int16_t *) user_data); @@ -725,6 +733,53 @@ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int dept } } +/* *********************************************** */ + +static void updatePortStats(struct port_stats **stats, u_int32_t port, u_int32_t num_pkts, u_int32_t num_bytes) { + struct port_stats *s; + + HASH_FIND_INT(*stats, &port, s); + if(s == NULL) { + s = (struct port_stats*)malloc(sizeof(struct port_stats)); + if(!s) return; + + s->port = port, s->num_pkts = 0, s->num_bytes = 0; + HASH_ADD_INT(*stats, port, s); + } + + s->num_pkts += num_pkts, s->num_bytes += num_bytes; +} + +/* *********************************************** */ + +static void deletePortsStats(struct port_stats *stats) { + struct port_stats *current_port, *tmp; + + HASH_ITER(hh, stats, current_port, tmp) { + HASH_DEL(stats, current_port); + free(current_port); + } +} + +/* *********************************************** */ + +/** + * @brief Ports stats + */ +static void port_stats_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { + struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node; + u_int16_t sport, dport; + + if(flow->src_to_dst_direction == 1) + sport = ntohs(flow->lower_port), dport = ntohs(flow->upper_port); + else + sport = ntohs(flow->upper_port), dport = ntohs(flow->lower_port); + + updatePortStats(&srcStats, sport, flow->packets, flow->bytes); + updatePortStats(&dstStats, dport, flow->packets, flow->bytes); +} + +/* *********************************************** */ /** * @brief Idle Scan Walker @@ -929,12 +984,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) { @@ -956,6 +1011,29 @@ char* formatBytes(u_int32_t howMuch, char *buf, u_int buf_len) { return(buf); } +/* *********************************************** */ + +static int port_stats_sort(void *_a, void *_b) { + struct port_stats *a = (struct port_stats*)_a; + struct port_stats *b = (struct port_stats*)_b; + + return(b->num_pkts - a->num_pkts); +} + +/* *********************************************** */ + +void printPortStats(struct port_stats *stats) { + struct port_stats *s, *tmp; + int i = 0; + + HASH_ITER(hh, stats, s, tmp) { + i++; + printf("\t%2d\tPort %5u\t[%u pkts/%u bytes]\n", i, s->port, s->num_pkts, s->num_bytes); + if(i >= 10) break; + } +} + +/* *********************************************** */ /** * @brief Print result @@ -973,17 +1051,24 @@ static void printResults(u_int64_t tot_usec) { json_object *jObj_main = NULL, *jObj_trafficStats, *jArray_detProto = NULL, *jObj; #endif long long unsigned int breed_stats[NUM_BREEDS] = { 0 }; - + memset(&cumulative_stats, 0, sizeof(cumulative_stats)); - for(thread_id = 0; thread_id < num_threads; thread_id++) { + for(thread_id = 0; thread_id < num_threads; thread_id++) { 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; indpi_flows_root[i], node_proto_guess_walker, &thread_id); + if(verbose) ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], port_stats_walker, &thread_id); + } + if(verbose) { + HASH_SORT(srcStats, port_stats_sort); + HASH_SORT(dstStats, port_stats_sort); + } + /* Stats aggregation */ 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; @@ -1204,6 +1289,16 @@ static void printResults(u_int64_t tot_usec) { fclose(json_fp); #endif } + + if(verbose) { + printf("\n\nSource Ports Stats:\n"); + printPortStats(srcStats); + + printf("\nDestination Ports Stats:\n"); + printPortStats(dstStats); + + deletePortsStats(srcStats), deletePortsStats(dstStats); + } } diff --git a/example/uthash.h b/example/uthash.h new file mode 100644 index 000000000..f78a73b86 --- /dev/null +++ b/example/uthash.h @@ -0,0 +1,1096 @@ +/* +Copyright (c) 2003-2017, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.0.2 + +#include /* memcmp,strlen */ +#include /* ptrdiff_t */ +#include /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif +#ifndef uthash_memcmp +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) \ + break; \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + unsigned _hd_bkt; \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev != NULL) { \ + ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count; \ + char *_prev; \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %u, actual %u\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen=(unsigned)keylen; \ + const unsigned char *_hb_key=(const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key=(const unsigned char*)(key); \ + hashv = 2166136261U; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6bu; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35u; \ + _h ^= _h >> 16; \ +} while (0) + +#define HASH_MUR(key,keylen,hashv) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (int)(keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353u; \ + uint32_t _mur_c1 = 0xcc9e2d51u; \ + uint32_t _mur_c2 = 0x1b873593u; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i!=0; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ + _mur_k1=0; \ + switch((keylen) & 3U) { \ + case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ + case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ + case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (uint32_t)(keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ +} while (0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head != NULL) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if ((head.count >= ((head.expand_mult+1U) * HASH_BKT_CAPACITY_THRESH)) \ + && ((addhh)->tbl->noexpand != 1U)) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1U)) + \ + (((tbl->num_items & ((tbl->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { _he_newbkt->hh_head->hh_prev = \ + _he_thh; } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2U; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1U) : 0U; \ + if (tbl->ineff_expands > 1U) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) { break; } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0U) || ((_hs_qsize > 0U) && (_hs_q != NULL))) {\ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0U) || (_hs_q == NULL) ) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL){ \ + _hs_tail->next = NULL; \ + } \ + if ( _hs_nmerges <= 1U ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src != NULL) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { _last_elt_hh->next = _elt; } \ + if (dst == NULL) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head != NULL) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + ((head != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ -- cgit v1.2.3 From b9a2511ea80341a5b7186dc49835e4173c4437e5 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Sun, 23 Apr 2017 19:58:41 +0200 Subject: Initial Wireshark nDPI integration --- example/ndpiReader.c | 10 +++---- example/ndpi_util.c | 85 ++++++++++++++++++++++++++-------------------------- wireshark/README.md | 20 +++++++++++++ wireshark/ndpi.lua | 47 +++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 48 deletions(-) create mode 100644 wireshark/README.md create mode 100644 wireshark/ndpi.lua (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 2b02093cb..254934ba9 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -93,6 +93,7 @@ struct port_stats *srcStats = NULL, *dstStats = NULL; struct ndpi_packet_trailer { u_int32_t magic; /* 0x19682017 */ u_int16_t master_protocol /* e.g. HTTP */, app_protocol /* e.g. FaceBook */; + char name[16]; }; static pcap_dumper_t *extcap_dumper = NULL; @@ -249,14 +250,12 @@ void extcap_config() { int i, argidx = 0; struct ndpi_detection_module_struct *ndpi_mod; -#if 1 + /* -i */ printf("arg {number=%u}{call=-i}{display=Capture Interface Name}{type=string}" "{tooltip=The interface name}\n", argidx++); -#else printf("arg {number=%u}{call=-i}{display=Pcap File to Analize}{type=fileselect}" "{tooltip=The pcap file to analyze (if the interface is unspecified)}\n", argidx++); -#endif printf("arg {number=%u}{call=-9}{display=nDPI Protocol}{type=selector}" "{tooltip=nDPI Protocol to be filtered}\n", argidx); @@ -1494,8 +1493,9 @@ static void pcap_packet_callback_checked(u_char *args, struct ndpi_packet_trailer *trailer = (struct ndpi_packet_trailer*)&extcap_buf[h->caplen]; memcpy(extcap_buf, packet, h->caplen); - trailer->magic = 0x19682017; - trailer->master_protocol = p.master_protocol, trailer->app_protocol = p.app_protocol; + trailer->magic = htonl(0x19680924); + trailer->master_protocol = htons(p.master_protocol), trailer->app_protocol = htons(p.app_protocol); + ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, p, trailer->name, sizeof(trailer->name)); crc = (uint32_t*)&extcap_buf[h->caplen+sizeof(struct ndpi_packet_trailer)]; *crc = 0; ethernet_crc32((const void*)extcap_buf, h->caplen+sizeof(struct ndpi_packet_trailer), crc); diff --git a/example/ndpi_util.c b/example/ndpi_util.c index d6be479a0..941e7f88d 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -260,7 +260,7 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow if(iph->protocol == IPPROTO_TCP && l4_packet_len >= 20) { u_int tcp_len; - // tcp + // tcp workflow->stats.tcp_count++; *tcph = (struct ndpi_tcphdr *)l4; *sport = ntohs((*tcph)->source), *dport = ntohs((*tcph)->dest); @@ -288,7 +288,7 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow *payload_len = ndpi_max(0, l4_packet_len-4*(*tcph)->doff); } else if(iph->protocol == IPPROTO_UDP && l4_packet_len >= 8) { // udp - + workflow->stats.udp_count++; *udph = (struct ndpi_udphdr *)l4; *sport = ntohs((*udph)->source), *dport = ntohs((*udph)->dest); @@ -350,7 +350,7 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow newflow->lower_port = lower_port, newflow->upper_port = upper_port; newflow->ip_version = version; newflow->src_to_dst_direction = *src_to_dst_direction; - + if(version == IPVERSION) { 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)); @@ -442,19 +442,19 @@ static struct ndpi_flow_info *get_ndpi_flow_info6(struct ndpi_workflow * workflo void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow) { if(!flow->ndpi_flow) return; - - snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", + + snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); /* BITTORRENT */ if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_BITTORRENT) { int i, j, n = 0; - + for(i=0, j = 0; j < sizeof(flow->bittorent_hash)-1; 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'; } /* MDNS */ @@ -545,7 +545,7 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, flow->last_seen = time; } else { // flow is NULL workflow->stats.total_discarded_bytes++; - return (nproto); + return(nproto); } /* Protocol already detected */ @@ -558,17 +558,16 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, if((flow->detected_protocol.app_protocol != NDPI_PROTOCOL_UNKNOWN) || ((proto == IPPROTO_UDP) && (flow->packets > 8)) || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { - /* New protocol detected or give up */ + /* New protocol detected or give up */ flow->detection_completed = 1; - } - if(flow->detection_completed) { + process_ndpi_collected_info(workflow, flow); + if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_UNKNOWN) flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow); - } + } - process_ndpi_collected_info(workflow, flow); return(flow->detected_protocol); } @@ -602,7 +601,7 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, struct ndpi_ipv6hdr *iph6; struct ndpi_proto nproto = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN }; - + /* lengths and offsets */ u_int16_t eth_offset = 0; u_int16_t radio_len; @@ -916,11 +915,11 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow, /* ********************************************************** */ static uint32_t crc32_for_byte(uint32_t r) { - int j; - - for(j = 0; j < 8; ++j) - r = (r & 1? 0: (uint32_t)0xEDB88320L) ^ r >> 1; - return r ^ (uint32_t)0xFF000000L; + int j; + + for(j = 0; j < 8; ++j) + r = (r & 1? 0: (uint32_t)0xEDB88320L) ^ r >> 1; + return r ^ (uint32_t)0xFF000000L; } /* Any unsigned integer type with at least 32 bits may be used as @@ -929,31 +928,31 @@ static uint32_t crc32_for_byte(uint32_t r) { typedef unsigned long accum_t; static void init_tables(uint32_t* table, uint32_t* wtable) { - size_t i, k, w, j; - - for(i = 0; i < 0x100; ++i) - table[i] = crc32_for_byte(i); - for(k = 0; k < sizeof(accum_t); ++k) - for(i = 0; i < 0x100; ++i) { - for(j = w = 0; j < sizeof(accum_t); ++j) - w = table[(uint8_t)(j == k? w ^ i: w)] ^ w >> 8; - wtable[(k << 8) + i] = w ^ (k? wtable[0]: 0); - } + size_t i, k, w, j; + + for(i = 0; i < 0x100; ++i) + table[i] = crc32_for_byte(i); + for(k = 0; k < sizeof(accum_t); ++k) + for(i = 0; i < 0x100; ++i) { + for(j = w = 0; j < sizeof(accum_t); ++j) + w = table[(uint8_t)(j == k? w ^ i: w)] ^ w >> 8; + wtable[(k << 8) + i] = w ^ (k? wtable[0]: 0); + } } void ethernet_crc32(const void* data, size_t n_bytes, uint32_t* crc) { - static uint32_t table[0x100], wtable[0x100*sizeof(accum_t)]; - size_t n_accum = n_bytes/sizeof(accum_t); - size_t i, k, j; - - if(!*table) - init_tables(table, wtable); - for(i = 0; i < n_accum; ++i) { - accum_t a = *crc ^ ((accum_t*)data)[i]; - for(j = *crc = 0; j < sizeof(accum_t); ++j) - *crc ^= wtable[(j << 8) + (uint8_t)(a >> 8*j)]; - } - - for(i = n_accum*sizeof(accum_t); i < n_bytes; ++i) - *crc = table[(uint8_t)*crc ^ ((uint8_t*)data)[i]] ^ *crc >> 8; + static uint32_t table[0x100], wtable[0x100*sizeof(accum_t)]; + size_t n_accum = n_bytes/sizeof(accum_t); + size_t i, k, j; + + if(!*table) + init_tables(table, wtable); + for(i = 0; i < n_accum; ++i) { + accum_t a = *crc ^ ((accum_t*)data)[i]; + for(j = *crc = 0; j < sizeof(accum_t); ++j) + *crc ^= wtable[(j << 8) + (uint8_t)(a >> 8*j)]; + } + + for(i = n_accum*sizeof(accum_t); i < n_bytes; ++i) + *crc = table[(uint8_t)*crc ^ ((uint8_t*)data)[i]] ^ *crc >> 8; } diff --git a/wireshark/README.md b/wireshark/README.md new file mode 100644 index 000000000..1811c663e --- /dev/null +++ b/wireshark/README.md @@ -0,0 +1,20 @@ +# nDPI Wireshark Plugin + +## Introduction + +nDPI can provide Wireshark protocol dissection to complement internal protocol decoding. In order to do this, the ndpiReader application is used to provide Wireshark nDPI protocol dissection, and a Wireshark plugin interprets nDPI information. + +## Installation + +- Copy the ndpiReader application (it is located under nDPI/example) to the Extcap path. See Wireshark -> About menu for identifying the extcap directory. Under OSX it is usually /Applications/Wireshark.app/Contents/MacOS/extcap +- Copy the ndpi.lua plugin under ~/.wireshark/plugins (or in the global Wireshark plugins directory) + +## Usage + +At Wireshark startup you will find a new extcap interface named "nDPI interface". Select that interface and specify an interface name (for live capture) or a pcap file path (for reading packets from a pcap file). You can choose a nDPI protocol list from the dropdown menu in case you want Wireshark to dissect only protocols of the specified nDPI application protocol. + +During capture the ndpiReader plugin will pass Wireshark the nDPI protocol information adding an ethernet packet trailer that contains nDPI information. The lua plugin interprets this information and it displays it in the Wireshark GUI. + +## nDPI Packet Filtering + +As nDPI is natively integrated into Wireshark, you can filter packets using the usual filtering mechanism. Example use "ndpi.protocol.name==BitTorrent" to filter all BitTorrent traffic. diff --git a/wireshark/ndpi.lua b/wireshark/ndpi.lua new file mode 100644 index 000000000..2065d2335 --- /dev/null +++ b/wireshark/ndpi.lua @@ -0,0 +1,47 @@ +-- +-- (C) 2017 - ntop.org +-- +-- This plugin is part of nDPI (https://github.com/ntop/nDPI) +-- +-- +local ndpi_proto = Proto("ndpi", "nDPI", "nDPI Protocol Interpreter") + +ndpi_proto.fields = {} +local fds = ndpi_proto.fields + +fds.network_protocol = ProtoField.new("nDPI Network Protocol", "ndpi.protocol.network", ftypes.UINT8, nil, base.DEC) +fds.application_protocol = ProtoField.new("nDPI Application Protocol", "ndpi.protocol.application", ftypes.UINT8, nil, base.DEC) +fds.name = ProtoField.new("nDPI Protocol Name", "ndpi.protocol.name", ftypes.STRING) + +local f_eth_trailer = Field.new("eth.trailer") + +-- ############################################### + +-- the dissector function callback +function ndpi_proto.dissector(tvb, pinfo, tree) + local pktlen = tvb:len() + local eth_trailer = f_eth_trailer() + local magic = tostring(tvb(pktlen-28,4)) + + if(magic == "19680924") then + local ndpi_subtree = tree:add(ndpi_proto, tvb(), "nDPI Protocol") + local network_protocol = tvb(pktlen-24,2) + local application_protocol = tvb(pktlen-22,2) + local name = tvb(pktlen-20,16) + local name_str = name:string(ENC_UTF_8) + + ndpi_subtree:add(fds.network_protocol, network_protocol) + ndpi_subtree:add(fds.application_protocol, application_protocol) + ndpi_subtree:add(fds.name, name) + + local pname = ""..application_protocol + if(pname ~= "0000") then + -- Set protocol name in the wireshark protocol column (if not Unknown) + pinfo.cols.protocol = name_str + end + end +end + +register_postdissector(ndpi_proto) + +-- ############################################### -- cgit v1.2.3 From 43f18ddb0f5b849deb454fa68e447a22912b9ba9 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Mon, 24 Apr 2017 00:45:43 +0200 Subject: Updated Wireshark lua dissector Added -v to ndpiReader to print port stats Recomputed protocol test results --- example/ndpiReader.c | 23 +- tests/result/Instagram.pcap.out | 14 +- tests/result/KakaoTalk_chat.pcap.out | 6 +- tests/result/Viber_session.pcap.out | 40 ++-- tests/result/ocs.pcap.out | 4 +- tests/result/skype.pcap.out | 386 +++++++++++++++--------------- tests/result/skype_no_unknown.pcap.out | 2 +- tests/result/starcraft_battle.pcap.out | 8 +- tests/result/viber_mobile.pcap.out | 160 ++++++------- tests/result/whatsapp_login_call.pcap.out | 105 ++++---- wireshark/ndpi.lua | 135 ++++++++++- 11 files changed, 512 insertions(+), 371 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 254934ba9..e23e0c1f9 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -167,7 +167,7 @@ static void help(u_int long_help) { " -w | Write test output on the specified file. This is useful for\n" " | testing purposes in order to compare results across runs\n" " -h | This help\n" - " -v <1|2> | Verbose 'unknown protocol' packet print. 1=verbose, 2=very verbose\n"); + " -v <1|2|3> | Verbose 'unknown protocol' packet print. 1=verbose, 2=very verbose, 3=port stats\n"); #ifndef WIN32 printf("\nExcap (wireshark) options:\n" @@ -240,7 +240,7 @@ void extcap_interfaces() { void extcap_dlts() { u_int dlts_number = DLT_EN10MB; - printf("dlt {number=%u}{name=%s}{display=%s}\n", dlts_number, "ndpi", "nDPI interface"); + printf("dlt {number=%u}{name=%s}{display=%s}\n", dlts_number, "ndpi", "nDPI Interface"); exit(0); } @@ -251,13 +251,16 @@ void extcap_config() { struct ndpi_detection_module_struct *ndpi_mod; /* -i */ - printf("arg {number=%u}{call=-i}{display=Capture Interface Name}{type=string}" + printf("arg {number=%u}{call=-i}{display=Capture Interface or Pcap File Path}{type=string}" "{tooltip=The interface name}\n", argidx++); +#if 0 printf("arg {number=%u}{call=-i}{display=Pcap File to Analize}{type=fileselect}" "{tooltip=The pcap file to analyze (if the interface is unspecified)}\n", argidx++); +#endif - printf("arg {number=%u}{call=-9}{display=nDPI Protocol}{type=selector}" + + printf("arg {number=%u}{call=-9}{display=nDPI Protocol Filter}{type=selector}" "{tooltip=nDPI Protocol to be filtered}\n", argidx); setupDetection(0, NULL); @@ -558,6 +561,9 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { #endif FILE *out = results_file ? results_file : stdout; + if((verbose != 1) && (verbose != 2)) + return; + if(!json_flag) { fprintf(out, "\t%u", ++num_flows); @@ -1060,10 +1066,10 @@ static void printResults(u_int64_t tot_usec) { for(i=0; indpi_flows_root[i], node_proto_guess_walker, &thread_id); - if(verbose) ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], port_stats_walker, &thread_id); + if(verbose == 3) ndpi_twalk(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], port_stats_walker, &thread_id); } - if(verbose) { + if(verbose == 3) { HASH_SORT(srcStats, port_stats_sort); HASH_SORT(dstStats, port_stats_sort); } @@ -1242,7 +1248,7 @@ static void printResults(u_int64_t tot_usec) { // printf("\n\nTotal Flow Traffic: %llu (diff: %llu)\n", total_flow_bytes, cumulative_stats.total_ip_bytes-total_flow_bytes); - if(verbose) { + if((verbose == 1) || (verbose == 2)) { FILE *out = results_file ? results_file : stdout; if(!json_flag) fprintf(out, "\n"); @@ -1289,7 +1295,7 @@ static void printResults(u_int64_t tot_usec) { #endif } - if(verbose) { + if(verbose == 3) { printf("\n\nSource Ports Stats:\n"); printPortStats(srcStats); @@ -1493,6 +1499,7 @@ static void pcap_packet_callback_checked(u_char *args, struct ndpi_packet_trailer *trailer = (struct ndpi_packet_trailer*)&extcap_buf[h->caplen]; memcpy(extcap_buf, packet, h->caplen); + memset(trailer, 0, sizeof(struct ndpi_packet_trailer)); trailer->magic = htonl(0x19680924); trailer->master_protocol = htons(p.master_protocol), trailer->app_protocol = htons(p.app_protocol); ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, p, trailer->name, sizeof(trailer->name)); diff --git a/tests/result/Instagram.pcap.out b/tests/result/Instagram.pcap.out index edd889471..83b0492bb 100644 --- a/tests/result/Instagram.pcap.out +++ b/tests/result/Instagram.pcap.out @@ -1,30 +1,30 @@ Unknown 1 66 1 -HTTP 116 91784 6 +HTTP 266 245342 7 ICMP 5 510 1 -SSL 2 169 1 -Facebook 251 215986 5 +SSL 93 57298 4 +Facebook 10 5299 1 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 192.168.0.103:26540 <-> 8.8.8.8:53 [proto: 5.211/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-g-a.akamaihd.net] 3 UDP 192.168.0.103:27124 <-> 8.8.8.8:53 [proto: 5.211/DNS.Instagram][1 pkts/85 bytes][Host: photos-b.ak.instagram.com] - 4 TCP 192.168.0.103:33763 <-> 31.13.93.52:443 [proto: 91.119/SSL.Facebook][11 pkts/5397 bytes] + 4 TCP 192.168.0.103:33763 <-> 31.13.93.52:443 [proto: 91/SSL][11 pkts/5397 bytes] 5 TCP 192.168.0.103:33935 <-> 31.13.93.52:443 [proto: 91.119/SSL.Facebook][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] 8 TCP 192.168.0.103:33976 <-> 77.67.29.17:80 [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][client: igcdn-photos-a-a.akamaihd.net] - 11 TCP 31.13.86.52:80 <-> 192.168.0.103:58216 [proto: 7.119/HTTP.Facebook][150 pkts/153558 bytes] + 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] 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 192.168.0.103:56382 <-> 173.252.107.4:443 [proto: 91.211/SSL.Instagram][17 pkts/2647 bytes][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 192.168.0.103:33603 <-> 8.8.8.8:53 [proto: 5.211/DNS.Instagram][2 pkts/298 bytes][Host: igcdn-photos-a-a.akamaihd.net] - 18 TCP 192.168.0.103:33936 <-> 31.13.93.52:443 [proto: 91.119/SSL.Facebook][68 pkts/45688 bytes] - 19 TCP 31.13.93.52:443 <-> 192.168.0.103:33934 [proto: 91.119/SSL.Facebook][12 pkts/6044 bytes] + 18 TCP 192.168.0.103:33936 <-> 31.13.93.52:443 [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 46.33.70.150:80 <-> 192.168.0.103:40855 [proto: 7/HTTP][2 pkts/140 bytes] diff --git a/tests/result/KakaoTalk_chat.pcap.out b/tests/result/KakaoTalk_chat.pcap.out index 4fee1d276..b1df9ee34 100644 --- a/tests/result/KakaoTalk_chat.pcap.out +++ b/tests/result/KakaoTalk_chat.pcap.out @@ -1,9 +1,9 @@ DNS 2 217 1 -HTTP 1 56 1 +HTTP 15 840 2 ICMP 1 147 1 SSL 29 4579 3 Facebook 215 51809 12 -Google 16 1031 3 +Google 2 247 2 HTTP_Proxy 26 3926 1 Amazon 2 181 1 KakaoTalk 55 9990 15 @@ -36,7 +36,7 @@ KakaoTalk 55 9990 15 26 TCP 10.24.82.188:34686 <-> 173.194.72.188:5228 [proto: 126/Google][1 pkts/164 bytes] 27 UDP 10.24.82.188:14650 <-> 10.188.1.1:53 [proto: 5/DNS][2 pkts/217 bytes][Host: 2.97.252.173.in-addr.arpa] 28 UDP 10.24.82.188:19582 <-> 10.188.1.1:53 [proto: 5.119/DNS.Facebook][2 pkts/218 bytes][Host: graph.facebook.com] - 29 TCP 216.58.221.10:80 <-> 10.24.82.188:35922 [proto: 7.126/HTTP.Google][14 pkts/784 bytes] + 29 TCP 216.58.221.10:80 <-> 10.24.82.188:35922 [proto: 7/HTTP][14 pkts/784 bytes] 30 UDP 10.24.82.188:24596 <-> 10.188.1.1:53 [proto: 5.119/DNS.Facebook][2 pkts/196 bytes][Host: api.facebook.com] 31 TCP 10.24.82.188:42332 <-> 210.103.240.15:443 [proto: 91/SSL][5 pkts/280 bytes] 32 TCP 10.24.82.188:49217 <-> 216.58.220.174:443 [proto: 91.126/SSL.Google][1 pkts/83 bytes] diff --git a/tests/result/Viber_session.pcap.out b/tests/result/Viber_session.pcap.out index 81ef39da8..f396686c7 100644 --- a/tests/result/Viber_session.pcap.out +++ b/tests/result/Viber_session.pcap.out @@ -1,13 +1,13 @@ -Unknown 163 9995 7 +Unknown 145 9356 7 HTTP 13 796 7 SSL_No_Cert 34 4141 1 ICMP 2 196 1 -SSL 80 7703 8 -Facebook 29 3944 2 +SSL 104 9782 9 +Facebook 59 5744 3 Dropbox 1 97 1 GMail 21 1891 1 -Google 50 4084 5 -Viber 4163 392492 4 +Google 26 2005 4 +Viber 4151 391331 3 Amazon 1 66 1 1 TCP 192.168.200.222:57999 <-> 74.125.130.188:5228 [proto: 126/Google][10 pkts/757 bytes] @@ -22,17 +22,17 @@ Amazon 1 66 1 10 TCP 192.168.200.222:33161 <-> 93.184.221.200:80 [proto: 7/HTTP][1 pkts/60 bytes] 11 TCP 192.168.200.222:52491 <-> 31.13.79.245:443 [proto: 91.119/SSL.Facebook][6 pkts/599 bytes] 12 TCP 192.168.200.222:36675 <-> 112.124.219.82:80 [proto: 7/HTTP][1 pkts/60 bytes] - 13 TCP 192.168.200.222:51055 <-> 74.125.68.156:443 [proto: 91.126/SSL.Google][24 pkts/2079 bytes] - 14 TCP 192.168.200.222:46761 <-> 112.124.219.93:80 [proto: 7/HTTP][7 pkts/436 bytes] - 15 TCP 192.168.200.222:52977 <-> 93.184.221.200:80 [proto: 7/HTTP][1 pkts/60 bytes] - 16 TCP 222.165.163.93:443 <-> 192.168.200.222:52635 [proto: 91/SSL][5 pkts/385 bytes] - 17 TCP 222.165.163.93:443 <-> 192.168.200.222:52641 [proto: 91/SSL][5 pkts/385 bytes] - 18 TCP 222.165.163.91:443 <-> 192.168.200.222:56243 [proto: 91/SSL][5 pkts/385 bytes] - 19 ICMP 192.168.1.1:0 <-> 192.168.200.222:0 [proto: 81/ICMP][2 pkts/196 bytes] - 20 TCP 74.125.68.239:443 <-> 192.168.200.222:37376 [proto: 91.126/SSL.Google][5 pkts/424 bytes] - 21 TCP 192.168.200.222:43287 <-> 52.0.253.46:443 [proto: 64/SSL_No_Cert][34 pkts/4141 bytes] - 22 TCP 192.168.200.222:51146 <-> 23.21.254.189:443 [proto: 91/SSL][15 pkts/1484 bytes][client: e.crashlytics.com] - 23 TCP 192.168.200.222:43454 <-> 52.0.253.46:4244 [proto: 144/Viber][12 pkts/1161 bytes] + 13 UDP 192.168.200.222:48564 <-> 175.157.52.135:37299 [proto: 119/Facebook][30 pkts/1800 bytes] + 14 TCP 192.168.200.222:51055 <-> 74.125.68.156:443 [proto: 91/SSL][24 pkts/2079 bytes] + 15 TCP 192.168.200.222:46761 <-> 112.124.219.93:80 [proto: 7/HTTP][7 pkts/436 bytes] + 16 TCP 192.168.200.222:52977 <-> 93.184.221.200:80 [proto: 7/HTTP][1 pkts/60 bytes] + 17 TCP 222.165.163.93:443 <-> 192.168.200.222:52635 [proto: 91/SSL][5 pkts/385 bytes] + 18 TCP 222.165.163.93:443 <-> 192.168.200.222:52641 [proto: 91/SSL][5 pkts/385 bytes] + 19 TCP 222.165.163.91:443 <-> 192.168.200.222:56243 [proto: 91/SSL][5 pkts/385 bytes] + 20 ICMP 192.168.1.1:0 <-> 192.168.200.222:0 [proto: 81/ICMP][2 pkts/196 bytes] + 21 TCP 74.125.68.239:443 <-> 192.168.200.222:37376 [proto: 91.126/SSL.Google][5 pkts/424 bytes] + 22 TCP 192.168.200.222:43287 <-> 52.0.253.46:443 [proto: 64/SSL_No_Cert][34 pkts/4141 bytes] + 23 TCP 192.168.200.222:51146 <-> 23.21.254.189:443 [proto: 91/SSL][15 pkts/1484 bytes][client: e.crashlytics.com] 24 TCP 192.168.200.222:42040 <-> 74.125.200.18:443 [proto: 91.122/SSL.GMail][21 pkts/1891 bytes][client: mail.google.com] 25 TCP 192.168.200.222:43646 <-> 93.184.221.200:80 [proto: 7/HTTP][1 pkts/60 bytes] 26 TCP 192.168.200.222:40005 <-> 108.168.176.234:443 [proto: 91/SSL][24 pkts/2848 bytes] @@ -45,9 +45,9 @@ Amazon 1 66 1 Undetected flows: 1 TCP 192.168.200.222:55554 <-> 113.31.80.142:7003 [proto: 0/Unknown][6 pkts/446 bytes] - 2 UDP 192.168.200.222:48564 <-> 175.157.52.135:37299 [proto: 0/Unknown][30 pkts/1800 bytes] - 3 UDP 192.168.200.222:48564 <-> 175.157.52.135:37301 [proto: 0/Unknown][30 pkts/1800 bytes] - 4 TCP 192.168.200.222:55565 <-> 113.31.80.142:7003 [proto: 0/Unknown][7 pkts/549 bytes] - 5 UDP 192.168.200.222:48564 <-> 10.216.246.82:59027 [proto: 0/Unknown][30 pkts/1800 bytes] + 2 UDP 192.168.200.222:48564 <-> 175.157.52.135:37301 [proto: 0/Unknown][30 pkts/1800 bytes] + 3 TCP 192.168.200.222:55565 <-> 113.31.80.142:7003 [proto: 0/Unknown][7 pkts/549 bytes] + 4 UDP 192.168.200.222:48564 <-> 10.216.246.82:59027 [proto: 0/Unknown][30 pkts/1800 bytes] + 5 TCP 192.168.200.222:43454 <-> 52.0.253.46:4244 [proto: 0/Unknown][12 pkts/1161 bytes] 6 UDP 192.168.200.222:48564 <-> 175.157.52.135:37300 [proto: 0/Unknown][30 pkts/1800 bytes] 7 UDP 192.168.200.222:48564 <-> 175.157.52.135:37302 [proto: 0/Unknown][30 pkts/1800 bytes] diff --git a/tests/result/ocs.pcap.out b/tests/result/ocs.pcap.out index abb202085..feb238eb8 100644 --- a/tests/result/ocs.pcap.out +++ b/tests/result/ocs.pcap.out @@ -1,15 +1,15 @@ Unknown 6 360 1 DNS 3 214 3 HTTP 13 1019 2 -SSL 20 2715 1 Google 41 5525 6 +Amazon 20 2715 1 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] 3 TCP 192.168.180.2:41223 <-> 216.58.208.46:443 [proto: 91.126/SSL.Google][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] - 5 TCP 192.168.180.2:39263 <-> 23.21.230.199:443 [proto: 91/SSL][20 pkts/2715 bytes][client: settings.crashlytics.com] + 5 TCP 192.168.180.2:39263 <-> 23.21.230.199:443 [proto: 91.178/SSL.Amazon][20 pkts/2715 bytes] 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.126/SSL.Google][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] diff --git a/tests/result/skype.pcap.out b/tests/result/skype.pcap.out index fd4ad387f..0f0a3cc5e 100644 --- a/tests/result/skype.pcap.out +++ b/tests/result/skype.pcap.out @@ -1,14 +1,14 @@ -Unknown 404 52712 16 +Unknown 416 54589 17 DNS 2 267 1 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 1918 293218 245 -Apple 15 2045 2 +SSL 96 8876 7 +Dropbox 52 19156 6 +Skype 1896 291402 243 +Apple 3 168 1 AppleiCloud 88 20520 2 Spotify 5 430 1 MS_OneDrive 387 198090 1 @@ -111,185 +111,184 @@ MS_OneDrive 387 198090 1 96 TCP 192.168.1.34:50088 <-> 157.55.235.146:33033 [proto: 125/Skype][18 pkts/1400 bytes] 97 UDP 192.168.1.34:13021 <-> 106.188.249.186:15120 [proto: 125/Skype][1 pkts/60 bytes] 98 UDP 192.168.1.34:13021 <-> 176.26.55.167:63773 [proto: 125/Skype][5 pkts/300 bytes] - 99 TCP 17.143.160.22:5223 <-> 192.168.1.34:49447 [proto: 140/Apple][12 pkts/1877 bytes] - 100 TCP 192.168.1.34:50032 <-> 157.56.52.44:40032 [proto: 125/Skype][16 pkts/1306 bytes] - 101 TCP 192.168.1.34:50034 <-> 157.55.130.140:40033 [proto: 125/Skype][17 pkts/1400 bytes] - 102 TCP 192.168.1.34:50044 <-> 157.55.130.167:40031 [proto: 125/Skype][17 pkts/1353 bytes] - 103 TCP 192.168.1.34:50046 <-> 157.55.130.150:40011 [proto: 125/Skype][15 pkts/1229 bytes] - 104 TCP 192.168.1.34:50053 <-> 157.55.56.146:40030 [proto: 125/Skype][17 pkts/1355 bytes] - 105 TCP 192.168.1.34:50054 <-> 157.55.130.153:40005 [proto: 125/Skype][17 pkts/1441 bytes] - 106 TCP 192.168.1.34:50074 <-> 157.55.130.173:40003 [proto: 125/Skype][17 pkts/1327 bytes] - 107 TCP 192.168.1.34:50077 <-> 157.55.130.176:40022 [proto: 125/Skype][17 pkts/1338 bytes] - 108 TCP 192.168.1.34:50097 <-> 157.55.235.176:40022 [proto: 125/Skype][17 pkts/1371 bytes] - 109 UDP 192.168.1.34:13021 <-> 65.55.223.18:33033 [proto: 125/Skype][1 pkts/69 bytes] - 110 UDP 192.168.1.34:13021 <-> 64.4.23.166:40022 [proto: 125/Skype][1 pkts/76 bytes] - 111 UDP 192.168.1.34:13021 <-> 64.4.23.165:40020 [proto: 125/Skype][1 pkts/72 bytes] - 112 UDP 192.168.1.34:13021 <-> 64.4.23.140:40012 [proto: 125/Skype][1 pkts/68 bytes] - 113 UDP 192.168.1.34:13021 <-> 64.4.23.150:40004 [proto: 125/Skype][1 pkts/70 bytes] - 114 UDP 192.168.1.34:13021 <-> 64.4.23.143:40018 [proto: 125/Skype][1 pkts/77 bytes] - 115 UDP 192.168.1.34:13021 <-> 64.4.23.141:40004 [proto: 125/Skype][1 pkts/73 bytes] - 116 UDP 192.168.1.34:13021 <-> 64.4.23.148:40010 [proto: 125/Skype][1 pkts/69 bytes] - 117 UDP 192.168.1.34:13021 <-> 64.4.23.145:40024 [proto: 125/Skype][1 pkts/79 bytes] - 118 UDP 192.168.1.34:13021 <-> 64.4.23.155:40004 [proto: 125/Skype][1 pkts/77 bytes] - 119 UDP 192.168.1.34:13021 <-> 64.4.23.168:40006 [proto: 125/Skype][1 pkts/71 bytes] - 120 UDP 192.168.1.34:13021 <-> 65.55.223.38:40015 [proto: 125/Skype][1 pkts/66 bytes] - 121 UDP 192.168.1.34:13021 <-> 65.55.223.20:40033 [proto: 125/Skype][1 pkts/64 bytes] - 122 UDP 192.168.1.34:13021 <-> 65.55.223.33:40011 [proto: 125/Skype][1 pkts/79 bytes] - 123 UDP 192.168.1.34:13021 <-> 65.55.223.21:40027 [proto: 125/Skype][1 pkts/71 bytes] - 124 UDP 192.168.1.34:13021 <-> 65.55.223.44:40013 [proto: 125/Skype][1 pkts/66 bytes] - 125 UDP 192.168.1.34:13021 <-> 65.55.223.41:40027 [proto: 125/Skype][1 pkts/69 bytes] - 126 UDP 192.168.1.34:13021 <-> 111.221.74.18:33033 [proto: 125/Skype][1 pkts/70 bytes] - 127 UDP 192.168.1.34:13021 <-> 111.221.77.146:33033 [proto: 125/Skype][1 pkts/78 bytes] - 128 TCP 192.168.1.34:50063 <-> 111.221.74.38:443 [proto: 91.125/SSL.Skype][13 pkts/1287 bytes] - 129 TCP 192.168.1.34:50087 <-> 111.221.77.142:443 [proto: 91.125/SSL.Skype][12 pkts/1107 bytes] - 130 UDP 192.168.1.34:13021 <-> 76.185.207.12:45493 [proto: 125/Skype][5 pkts/300 bytes] - 131 TCP 192.168.1.34:50137 <-> 5.248.186.221:31010 [proto: 125/Skype][18 pkts/1445 bytes] - 132 UDP 192.168.1.34:13021 <-> 111.221.77.142:40023 [proto: 125/Skype][1 pkts/72 bytes] - 133 UDP 192.168.1.34:13021 <-> 111.221.74.46:40027 [proto: 125/Skype][1 pkts/71 bytes] - 134 UDP 192.168.1.34:13021 <-> 111.221.74.24:40001 [proto: 125/Skype][1 pkts/64 bytes] - 135 UDP 192.168.1.34:13021 <-> 111.221.74.19:40001 [proto: 125/Skype][1 pkts/68 bytes] - 136 UDP 192.168.1.34:13021 <-> 111.221.74.12:40031 [proto: 125/Skype][1 pkts/75 bytes] - 137 UDP 192.168.1.34:13021 <-> 111.221.74.44:40031 [proto: 125/Skype][1 pkts/71 bytes] - 138 UDP 192.168.1.34:13021 <-> 111.221.74.43:40001 [proto: 125/Skype][1 pkts/76 bytes] - 139 UDP 192.168.1.34:13021 <-> 111.221.74.32:40009 [proto: 125/Skype][1 pkts/70 bytes] - 140 UDP 192.168.1.34:13021 <-> 111.221.74.31:40021 [proto: 125/Skype][1 pkts/73 bytes] - 141 UDP 192.168.1.34:13021 <-> 111.221.77.140:40003 [proto: 125/Skype][1 pkts/64 bytes] - 142 UDP 192.168.1.34:13021 <-> 111.221.77.145:40027 [proto: 125/Skype][1 pkts/77 bytes] - 143 UDP 192.168.1.34:13021 <-> 111.221.77.151:40027 [proto: 125/Skype][1 pkts/76 bytes] - 144 UDP 192.168.1.34:13021 <-> 111.221.77.148:40029 [proto: 125/Skype][1 pkts/69 bytes] - 145 UDP 192.168.1.34:13021 <-> 111.221.77.168:40007 [proto: 125/Skype][1 pkts/68 bytes] - 146 UDP 192.168.1.34:13021 <-> 111.221.77.166:40011 [proto: 125/Skype][1 pkts/77 bytes] - 147 UDP 192.168.1.34:13021 <-> 111.221.77.154:40017 [proto: 125/Skype][1 pkts/67 bytes] - 148 UDP 192.168.1.34:13021 <-> 111.221.77.159:40009 [proto: 125/Skype][1 pkts/78 bytes] - 149 TCP 192.168.1.34:50109 <-> 91.190.216.125:12350 [proto: 125/Skype][6 pkts/483 bytes] - 150 TCP 192.168.1.34:50125 <-> 91.190.218.125:12350 [proto: 125/Skype][10 pkts/769 bytes] - 151 TCP 192.168.1.34:50129 <-> 91.190.218.125:12350 [proto: 125/Skype][10 pkts/599 bytes] - 152 TCP 192.168.1.34:50136 <-> 71.238.7.203:18767 [proto: 125/Skype][14 pkts/1101 bytes] - 153 UDP 192.168.1.34:13021 <-> 176.97.100.249:26635 [proto: 125/Skype][1 pkts/60 bytes] - 154 UDP 192.168.1.34:13021 <-> 157.55.235.146:33033 [proto: 125/Skype][1 pkts/66 bytes] - 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 192.168.1.34:50112 <-> 76.167.161.6:20274 [proto: 125/Skype][15 pkts/1254 bytes] - 158 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 91.221/SSL.MS_OneDrive][387 pkts/198090 bytes][server: *.gateway.messenger.live.com] - 159 TCP 192.168.1.34:50036 <-> 157.56.52.44:443 [proto: 91.125/SSL.Skype][14 pkts/1328 bytes] - 160 TCP 192.168.1.34:50037 <-> 157.55.56.170:443 [proto: 91.125/SSL.Skype][15 pkts/1569 bytes] - 161 TCP 192.168.1.34:50045 <-> 157.55.130.167:443 [proto: 91.125/SSL.Skype][15 pkts/1411 bytes] - 162 TCP 192.168.1.34:50051 <-> 157.55.130.166:443 [proto: 91.125/SSL.Skype][15 pkts/1351 bytes] - 163 TCP 192.168.1.34:50057 <-> 157.55.130.153:443 [proto: 91.125/SSL.Skype][15 pkts/1349 bytes] - 164 TCP 192.168.1.34:50069 <-> 157.55.56.160:443 [proto: 91.125/SSL.Skype][15 pkts/1401 bytes] - 165 TCP 192.168.1.34:50081 <-> 157.55.130.176:443 [proto: 91.125/SSL.Skype][15 pkts/1513 bytes] - 166 TCP 192.168.1.34:50091 <-> 157.55.235.146:443 [proto: 91.125/SSL.Skype][16 pkts/1754 bytes] - 167 TCP 192.168.1.34:50101 <-> 157.55.235.176:443 [proto: 91.125/SSL.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] - 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] - 172 UDP 192.168.1.34:13021 <-> 157.56.52.21:40004 [proto: 125/Skype][1 pkts/64 bytes] - 173 UDP 192.168.1.34:13021 <-> 157.56.52.26:40026 [proto: 125/Skype][1 pkts/74 bytes] - 174 UDP 192.168.1.34:13021 <-> 157.56.52.37:40032 [proto: 125/Skype][1 pkts/69 bytes] - 175 UDP 192.168.1.34:13021 <-> 157.55.235.142:40025 [proto: 125/Skype][1 pkts/70 bytes] - 176 UDP 192.168.1.34:13021 <-> 157.55.56.142:40023 [proto: 125/Skype][1 pkts/77 bytes] - 177 UDP 192.168.1.34:13021 <-> 157.55.235.152:40001 [proto: 125/Skype][1 pkts/79 bytes] - 178 UDP 192.168.1.34:13021 <-> 157.55.56.151:40027 [proto: 125/Skype][1 pkts/77 bytes] - 179 UDP 192.168.1.34:13021 <-> 157.55.56.145:40027 [proto: 125/Skype][1 pkts/68 bytes] - 180 UDP 192.168.1.34:13021 <-> 157.55.130.143:40017 [proto: 125/Skype][1 pkts/77 bytes] - 181 UDP 192.168.1.34:13021 <-> 157.55.130.148:40019 [proto: 125/Skype][1 pkts/64 bytes] - 182 UDP 192.168.1.34:13021 <-> 157.55.130.147:40019 [proto: 125/Skype][1 pkts/76 bytes] - 183 UDP 192.168.1.34:13021 <-> 157.55.130.151:40017 [proto: 125/Skype][1 pkts/72 bytes] - 184 UDP 192.168.1.34:13021 <-> 157.55.235.153:40023 [proto: 125/Skype][1 pkts/73 bytes] - 185 UDP 192.168.1.34:13021 <-> 157.55.130.157:40013 [proto: 125/Skype][1 pkts/67 bytes] - 186 UDP 192.168.1.34:13021 <-> 157.55.235.155:40003 [proto: 125/Skype][1 pkts/77 bytes] - 187 UDP 192.168.1.34:13021 <-> 157.55.235.158:40031 [proto: 125/Skype][1 pkts/64 bytes] - 188 UDP 192.168.1.34:13021 <-> 157.55.235.159:40021 [proto: 125/Skype][1 pkts/64 bytes] - 189 UDP 192.168.1.34:13021 <-> 157.55.56.175:40013 [proto: 125/Skype][1 pkts/77 bytes] - 190 UDP 192.168.1.34:13021 <-> 157.55.235.161:40011 [proto: 125/Skype][1 pkts/78 bytes] - 191 UDP 192.168.1.34:13021 <-> 157.55.235.160:40027 [proto: 125/Skype][1 pkts/69 bytes] - 192 UDP 192.168.1.34:13021 <-> 157.55.130.172:40019 [proto: 125/Skype][1 pkts/67 bytes] - 193 UDP 192.168.1.34:13021 <-> 157.55.235.166:40015 [proto: 125/Skype][1 pkts/69 bytes] - 194 UDP 192.168.1.34:49360 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] - 195 TCP 192.168.1.34:50132 <-> 149.13.32.15:13392 [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.34:49990 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net] - 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.34:51802 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] - 202 UDP 192.168.1.34:52714 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] - 203 UDP 192.168.1.34:52850 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][8 pkts/648 bytes][Host: conn.skype.akadns.net] - 204 UDP 192.168.1.34:52742 <-> 192.168.1.1:53 [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.34:54396 <-> 192.168.1.1:53 [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 192.168.1.34:50026 <-> 65.55.223.33:40002 [proto: 125/Skype][17 pkts/1370 bytes] - 210 TCP 192.168.1.34:50065 <-> 65.55.223.12:40031 [proto: 125/Skype][17 pkts/1401 bytes] - 211 TCP 192.168.1.34:50098 <-> 65.55.223.15:40026 [proto: 125/Skype][17 pkts/1381 bytes] - 212 UDP 192.168.1.34:57288 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net] - 213 UDP 192.168.1.34:57406 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] - 214 UDP 192.168.1.34:57726 <-> 192.168.1.1:53 [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.34:58458 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] - 222 UDP 192.168.1.34:58368 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst13.r.skype.net] - 223 UDP 192.168.1.34:60288 <-> 192.168.1.1:53 [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.34:62454 <-> 192.168.1.1:53 [proto: 5.143/DNS.AppleiCloud][2 pkts/234 bytes][Host: p05-keyvalueservice.icloud.com.akadns.net] - 226 UDP 192.168.1.34:63108 <-> 192.168.1.1:53 [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.34:65426 <-> 192.168.1.1:53 [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][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 192.168.1.34:50108 <-> 157.56.52.28:40009 [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 192.168.1.34:50115 <-> 86.31.35.30:59621 [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 192.168.1.34:50030 <-> 65.55.223.33:443 [proto: 91/SSL][15 pkts/1311 bytes] - 250 TCP 192.168.1.34:50066 <-> 65.55.223.12:443 [proto: 91/SSL][15 pkts/1452 bytes] - 251 TCP 192.168.1.34:50102 <-> 65.55.223.15:443 [proto: 91/SSL][14 pkts/1390 bytes] - 252 UDP 192.168.0.254:1025 <-> 239.255.255.250:1900 [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 192.168.1.34:13021 <-> 65.55.223.15:40026 [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 192.168.1.34:13021 <-> 65.55.223.17:40022 [proto: 125/Skype][1 pkts/70 bytes] - 262 UDP 192.168.1.34:13021 <-> 65.55.223.25:40028 [proto: 125/Skype][1 pkts/76 bytes] - 263 UDP 192.168.1.34:13021 <-> 65.55.223.24:40032 [proto: 125/Skype][1 pkts/67 bytes] - 264 UDP 192.168.1.34:13021 <-> 65.55.223.28:40026 [proto: 125/Skype][1 pkts/74 bytes] - 265 UDP 192.168.1.34:13021 <-> 65.55.223.26:40004 [proto: 125/Skype][1 pkts/79 bytes] - 266 UDP 192.168.1.34:13021 <-> 65.55.223.29:40010 [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: 91.125/SSL.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 108.160.170.46:443 <-> 192.168.1.34:49445 [proto: 91.121/SSL.Dropbox][16 pkts/5980 bytes] - 273 TCP 192.168.1.34:50058 <-> 111.221.74.47:443 [proto: 91.125/SSL.Skype][14 pkts/1208 bytes] - 274 TCP 192.168.1.34:50100 <-> 111.221.74.46:443 [proto: 91.125/SSL.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 [ff02::fb]:5353 <-> [fe80::c62c:3ff:fe06:49fe]:5353 [proto: 8/MDNS][4 pkts/908 bytes] + 99 TCP 192.168.1.34:50032 <-> 157.56.52.44:40032 [proto: 125/Skype][16 pkts/1306 bytes] + 100 TCP 192.168.1.34:50034 <-> 157.55.130.140:40033 [proto: 125/Skype][17 pkts/1400 bytes] + 101 TCP 192.168.1.34:50044 <-> 157.55.130.167:40031 [proto: 125/Skype][17 pkts/1353 bytes] + 102 TCP 192.168.1.34:50046 <-> 157.55.130.150:40011 [proto: 125/Skype][15 pkts/1229 bytes] + 103 TCP 192.168.1.34:50053 <-> 157.55.56.146:40030 [proto: 125/Skype][17 pkts/1355 bytes] + 104 TCP 192.168.1.34:50054 <-> 157.55.130.153:40005 [proto: 125/Skype][17 pkts/1441 bytes] + 105 TCP 192.168.1.34:50074 <-> 157.55.130.173:40003 [proto: 125/Skype][17 pkts/1327 bytes] + 106 TCP 192.168.1.34:50077 <-> 157.55.130.176:40022 [proto: 125/Skype][17 pkts/1338 bytes] + 107 TCP 192.168.1.34:50097 <-> 157.55.235.176:40022 [proto: 125/Skype][17 pkts/1371 bytes] + 108 UDP 192.168.1.34:13021 <-> 65.55.223.18:33033 [proto: 125/Skype][1 pkts/69 bytes] + 109 UDP 192.168.1.34:13021 <-> 64.4.23.166:40022 [proto: 125/Skype][1 pkts/76 bytes] + 110 UDP 192.168.1.34:13021 <-> 64.4.23.165:40020 [proto: 125/Skype][1 pkts/72 bytes] + 111 UDP 192.168.1.34:13021 <-> 64.4.23.140:40012 [proto: 125/Skype][1 pkts/68 bytes] + 112 UDP 192.168.1.34:13021 <-> 64.4.23.150:40004 [proto: 125/Skype][1 pkts/70 bytes] + 113 UDP 192.168.1.34:13021 <-> 64.4.23.143:40018 [proto: 125/Skype][1 pkts/77 bytes] + 114 UDP 192.168.1.34:13021 <-> 64.4.23.141:40004 [proto: 125/Skype][1 pkts/73 bytes] + 115 UDP 192.168.1.34:13021 <-> 64.4.23.148:40010 [proto: 125/Skype][1 pkts/69 bytes] + 116 UDP 192.168.1.34:13021 <-> 64.4.23.145:40024 [proto: 125/Skype][1 pkts/79 bytes] + 117 UDP 192.168.1.34:13021 <-> 64.4.23.155:40004 [proto: 125/Skype][1 pkts/77 bytes] + 118 UDP 192.168.1.34:13021 <-> 64.4.23.168:40006 [proto: 125/Skype][1 pkts/71 bytes] + 119 UDP 192.168.1.34:13021 <-> 65.55.223.38:40015 [proto: 125/Skype][1 pkts/66 bytes] + 120 UDP 192.168.1.34:13021 <-> 65.55.223.20:40033 [proto: 125/Skype][1 pkts/64 bytes] + 121 UDP 192.168.1.34:13021 <-> 65.55.223.33:40011 [proto: 125/Skype][1 pkts/79 bytes] + 122 UDP 192.168.1.34:13021 <-> 65.55.223.21:40027 [proto: 125/Skype][1 pkts/71 bytes] + 123 UDP 192.168.1.34:13021 <-> 65.55.223.44:40013 [proto: 125/Skype][1 pkts/66 bytes] + 124 UDP 192.168.1.34:13021 <-> 65.55.223.41:40027 [proto: 125/Skype][1 pkts/69 bytes] + 125 UDP 192.168.1.34:13021 <-> 111.221.74.18:33033 [proto: 125/Skype][1 pkts/70 bytes] + 126 UDP 192.168.1.34:13021 <-> 111.221.77.146:33033 [proto: 125/Skype][1 pkts/78 bytes] + 127 TCP 192.168.1.34:50063 <-> 111.221.74.38:443 [proto: 91.125/SSL.Skype][13 pkts/1287 bytes] + 128 TCP 192.168.1.34:50087 <-> 111.221.77.142:443 [proto: 91.125/SSL.Skype][12 pkts/1107 bytes] + 129 UDP 192.168.1.34:13021 <-> 76.185.207.12:45493 [proto: 125/Skype][5 pkts/300 bytes] + 130 TCP 192.168.1.34:50137 <-> 5.248.186.221:31010 [proto: 125/Skype][18 pkts/1445 bytes] + 131 UDP 192.168.1.34:13021 <-> 111.221.77.142:40023 [proto: 125/Skype][1 pkts/72 bytes] + 132 UDP 192.168.1.34:13021 <-> 111.221.74.46:40027 [proto: 125/Skype][1 pkts/71 bytes] + 133 UDP 192.168.1.34:13021 <-> 111.221.74.24:40001 [proto: 125/Skype][1 pkts/64 bytes] + 134 UDP 192.168.1.34:13021 <-> 111.221.74.19:40001 [proto: 125/Skype][1 pkts/68 bytes] + 135 UDP 192.168.1.34:13021 <-> 111.221.74.12:40031 [proto: 125/Skype][1 pkts/75 bytes] + 136 UDP 192.168.1.34:13021 <-> 111.221.74.44:40031 [proto: 125/Skype][1 pkts/71 bytes] + 137 UDP 192.168.1.34:13021 <-> 111.221.74.43:40001 [proto: 125/Skype][1 pkts/76 bytes] + 138 UDP 192.168.1.34:13021 <-> 111.221.74.32:40009 [proto: 125/Skype][1 pkts/70 bytes] + 139 UDP 192.168.1.34:13021 <-> 111.221.74.31:40021 [proto: 125/Skype][1 pkts/73 bytes] + 140 UDP 192.168.1.34:13021 <-> 111.221.77.140:40003 [proto: 125/Skype][1 pkts/64 bytes] + 141 UDP 192.168.1.34:13021 <-> 111.221.77.145:40027 [proto: 125/Skype][1 pkts/77 bytes] + 142 UDP 192.168.1.34:13021 <-> 111.221.77.151:40027 [proto: 125/Skype][1 pkts/76 bytes] + 143 UDP 192.168.1.34:13021 <-> 111.221.77.148:40029 [proto: 125/Skype][1 pkts/69 bytes] + 144 UDP 192.168.1.34:13021 <-> 111.221.77.168:40007 [proto: 125/Skype][1 pkts/68 bytes] + 145 UDP 192.168.1.34:13021 <-> 111.221.77.166:40011 [proto: 125/Skype][1 pkts/77 bytes] + 146 UDP 192.168.1.34:13021 <-> 111.221.77.154:40017 [proto: 125/Skype][1 pkts/67 bytes] + 147 UDP 192.168.1.34:13021 <-> 111.221.77.159:40009 [proto: 125/Skype][1 pkts/78 bytes] + 148 TCP 192.168.1.34:50109 <-> 91.190.216.125:12350 [proto: 125/Skype][6 pkts/483 bytes] + 149 TCP 192.168.1.34:50125 <-> 91.190.218.125:12350 [proto: 125/Skype][10 pkts/769 bytes] + 150 TCP 192.168.1.34:50129 <-> 91.190.218.125:12350 [proto: 125/Skype][10 pkts/599 bytes] + 151 TCP 192.168.1.34:50136 <-> 71.238.7.203:18767 [proto: 125/Skype][14 pkts/1101 bytes] + 152 UDP 192.168.1.34:13021 <-> 176.97.100.249:26635 [proto: 125/Skype][1 pkts/60 bytes] + 153 UDP 192.168.1.34:13021 <-> 157.55.235.146:33033 [proto: 125/Skype][1 pkts/66 bytes] + 154 UDP 192.168.1.34:13021 <-> 157.55.130.146:33033 [proto: 125/Skype][1 pkts/69 bytes] + 155 UDP 192.168.1.34:13021 <-> 157.55.56.146:33033 [proto: 125/Skype][1 pkts/70 bytes] + 156 TCP 192.168.1.34:50112 <-> 76.167.161.6:20274 [proto: 125/Skype][15 pkts/1254 bytes] + 157 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 91.221/SSL.MS_OneDrive][387 pkts/198090 bytes][server: *.gateway.messenger.live.com] + 158 TCP 192.168.1.34:50036 <-> 157.56.52.44:443 [proto: 91.125/SSL.Skype][14 pkts/1328 bytes] + 159 TCP 192.168.1.34:50037 <-> 157.55.56.170:443 [proto: 91.125/SSL.Skype][15 pkts/1569 bytes] + 160 TCP 192.168.1.34:50045 <-> 157.55.130.167:443 [proto: 91.125/SSL.Skype][15 pkts/1411 bytes] + 161 TCP 192.168.1.34:50051 <-> 157.55.130.166:443 [proto: 91.125/SSL.Skype][15 pkts/1351 bytes] + 162 TCP 192.168.1.34:50057 <-> 157.55.130.153:443 [proto: 91.125/SSL.Skype][15 pkts/1349 bytes] + 163 TCP 192.168.1.34:50069 <-> 157.55.56.160:443 [proto: 91.125/SSL.Skype][15 pkts/1401 bytes] + 164 TCP 192.168.1.34:50081 <-> 157.55.130.176:443 [proto: 91.125/SSL.Skype][15 pkts/1513 bytes] + 165 TCP 192.168.1.34:50091 <-> 157.55.235.146:443 [proto: 91.125/SSL.Skype][16 pkts/1754 bytes] + 166 TCP 192.168.1.34:50101 <-> 157.55.235.176:443 [proto: 91.125/SSL.Skype][15 pkts/1590 bytes] + 167 TCP 192.168.1.34:50146 <-> 157.56.53.51:443 [proto: 91/SSL][8 pkts/608 bytes] + 168 UDP 192.168.1.34:13021 <-> 157.55.130.160:40029 [proto: 125/Skype][1 pkts/67 bytes] + 169 UDP 192.168.1.34:13021 <-> 157.55.130.154:40005 [proto: 125/Skype][1 pkts/79 bytes] + 170 UDP 192.168.1.34:13021 <-> 157.56.52.45:40012 [proto: 125/Skype][1 pkts/67 bytes] + 171 UDP 192.168.1.34:13021 <-> 157.56.52.21:40004 [proto: 125/Skype][1 pkts/64 bytes] + 172 UDP 192.168.1.34:13021 <-> 157.56.52.26:40026 [proto: 125/Skype][1 pkts/74 bytes] + 173 UDP 192.168.1.34:13021 <-> 157.56.52.37:40032 [proto: 125/Skype][1 pkts/69 bytes] + 174 UDP 192.168.1.34:13021 <-> 157.55.235.142:40025 [proto: 125/Skype][1 pkts/70 bytes] + 175 UDP 192.168.1.34:13021 <-> 157.55.56.142:40023 [proto: 125/Skype][1 pkts/77 bytes] + 176 UDP 192.168.1.34:13021 <-> 157.55.235.152:40001 [proto: 125/Skype][1 pkts/79 bytes] + 177 UDP 192.168.1.34:13021 <-> 157.55.56.151:40027 [proto: 125/Skype][1 pkts/77 bytes] + 178 UDP 192.168.1.34:13021 <-> 157.55.56.145:40027 [proto: 125/Skype][1 pkts/68 bytes] + 179 UDP 192.168.1.34:13021 <-> 157.55.130.143:40017 [proto: 125/Skype][1 pkts/77 bytes] + 180 UDP 192.168.1.34:13021 <-> 157.55.130.148:40019 [proto: 125/Skype][1 pkts/64 bytes] + 181 UDP 192.168.1.34:13021 <-> 157.55.130.147:40019 [proto: 125/Skype][1 pkts/76 bytes] + 182 UDP 192.168.1.34:13021 <-> 157.55.130.151:40017 [proto: 125/Skype][1 pkts/72 bytes] + 183 UDP 192.168.1.34:13021 <-> 157.55.235.153:40023 [proto: 125/Skype][1 pkts/73 bytes] + 184 UDP 192.168.1.34:13021 <-> 157.55.130.157:40013 [proto: 125/Skype][1 pkts/67 bytes] + 185 UDP 192.168.1.34:13021 <-> 157.55.235.155:40003 [proto: 125/Skype][1 pkts/77 bytes] + 186 UDP 192.168.1.34:13021 <-> 157.55.235.158:40031 [proto: 125/Skype][1 pkts/64 bytes] + 187 UDP 192.168.1.34:13021 <-> 157.55.235.159:40021 [proto: 125/Skype][1 pkts/64 bytes] + 188 UDP 192.168.1.34:13021 <-> 157.55.56.175:40013 [proto: 125/Skype][1 pkts/77 bytes] + 189 UDP 192.168.1.34:13021 <-> 157.55.235.161:40011 [proto: 125/Skype][1 pkts/78 bytes] + 190 UDP 192.168.1.34:13021 <-> 157.55.235.160:40027 [proto: 125/Skype][1 pkts/69 bytes] + 191 UDP 192.168.1.34:13021 <-> 157.55.130.172:40019 [proto: 125/Skype][1 pkts/67 bytes] + 192 UDP 192.168.1.34:13021 <-> 157.55.235.166:40015 [proto: 125/Skype][1 pkts/69 bytes] + 193 UDP 192.168.1.34:49360 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] + 194 TCP 192.168.1.34:50132 <-> 149.13.32.15:13392 [proto: 125/Skype][18 pkts/1412 bytes] + 195 UDP 192.168.1.92:57621 <-> 192.168.1.255:57621 [proto: 156/Spotify][5 pkts/430 bytes] + 196 UDP 192.168.1.34:49990 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net] + 197 UDP 192.168.1.34:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][6 pkts/3264 bytes] + 198 UDP 192.168.1.92:17500 <-> 255.255.255.255:17500 [proto: 121/Dropbox][5 pkts/2720 bytes] + 199 UDP 192.168.1.34:13021 <-> 213.199.179.146:33033 [proto: 125/Skype][1 pkts/67 bytes] + 200 UDP 192.168.1.34:51802 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] + 201 UDP 192.168.1.34:52714 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] + 202 UDP 192.168.1.34:52850 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][8 pkts/648 bytes][Host: conn.skype.akadns.net] + 203 UDP 192.168.1.34:52742 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst5.r.skype.net] + 204 TCP 192.168.1.34:50039 <-> 213.199.179.175:443 [proto: 91/SSL][16 pkts/1592 bytes] + 205 TCP 192.168.1.34:50079 <-> 213.199.179.142:443 [proto: 91/SSL][16 pkts/1376 bytes] + 206 UDP 192.168.1.34:54396 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com] + 207 TCP 192.168.1.34:50099 <-> 64.4.23.166:40022 [proto: 125/Skype][16 pkts/1355 bytes] + 208 TCP 192.168.1.34:50026 <-> 65.55.223.33:40002 [proto: 125/Skype][17 pkts/1370 bytes] + 209 TCP 192.168.1.34:50065 <-> 65.55.223.12:40031 [proto: 125/Skype][17 pkts/1401 bytes] + 210 TCP 192.168.1.34:50098 <-> 65.55.223.15:40026 [proto: 125/Skype][17 pkts/1381 bytes] + 211 UDP 192.168.1.34:57288 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/616 bytes][Host: 335.0.7.7.3.rst6.r.skype.net] + 212 UDP 192.168.1.34:57406 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/546 bytes][Host: b.config.skype.com] + 213 UDP 192.168.1.34:57726 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] + 214 UDP 192.168.1.34:13021 <-> 213.199.179.165:40007 [proto: 125/Skype][1 pkts/74 bytes] + 215 UDP 192.168.1.34:13021 <-> 213.199.179.141:40015 [proto: 125/Skype][1 pkts/75 bytes] + 216 UDP 192.168.1.34:13021 <-> 213.199.179.162:40029 [proto: 125/Skype][1 pkts/70 bytes] + 217 UDP 192.168.1.34:13021 <-> 213.199.179.152:40023 [proto: 125/Skype][1 pkts/64 bytes] + 218 UDP 192.168.1.34:13021 <-> 213.199.179.145:40027 [proto: 125/Skype][1 pkts/66 bytes] + 219 UDP 192.168.1.34:13021 <-> 213.199.179.170:40011 [proto: 125/Skype][1 pkts/71 bytes] + 220 UDP 192.168.1.34:58458 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] + 221 UDP 192.168.1.34:58368 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: 335.0.7.7.3.rst13.r.skype.net] + 222 UDP 192.168.1.34:60288 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/623 bytes][Host: pipe.prd.skypedata.akadns.net] + 223 ICMP 192.168.1.1:0 <-> 192.168.1.34:0 [proto: 81/ICMP][8 pkts/656 bytes] + 224 UDP 192.168.1.34:62454 <-> 192.168.1.1:53 [proto: 5.143/DNS.AppleiCloud][2 pkts/234 bytes][Host: p05-keyvalueservice.icloud.com.akadns.net] + 225 UDP 192.168.1.34:63108 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/651 bytes][Host: a.config.skype.trafficmanager.net] + 226 UDP 192.168.1.92:50084 <-> 239.255.255.250:1900 [proto: 12/SSDP][14 pkts/7281 bytes] + 227 UDP 192.168.1.34:51066 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] + 228 UDP 192.168.1.34:65426 <-> 192.168.1.1:53 [proto: 5.125/DNS.Skype][7 pkts/511 bytes][Host: api.skype.com] + 229 TCP 192.168.1.34:50130 <-> 212.161.8.36:13392 [proto: 125/Skype][17 pkts/1380 bytes] + 230 TCP 192.168.1.34:50059 <-> 111.221.74.38:40015 [proto: 125/Skype][16 pkts/1236 bytes] + 231 TCP 192.168.1.34:50029 <-> 23.206.33.166:443 [proto: 91.125/SSL.Skype][17 pkts/3535 bytes][client: apps.skype.com] + 232 IGMP 224.0.0.1:0 <-> 192.168.0.254:0 [proto: 82/IGMP][2 pkts/92 bytes] + 233 IGMP 224.0.0.1:0 <-> 192.168.1.1:0 [proto: 82/IGMP][1 pkts/60 bytes] + 234 IGMP 192.168.1.92:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/60 bytes] + 235 IGMP 192.168.1.34:0 <-> 224.0.0.251:0 [proto: 82/IGMP][1 pkts/46 bytes] + 236 UDP 192.168.1.34:56886 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] + 237 TCP 192.168.1.34:50033 <-> 157.55.56.170:40015 [proto: 125/Skype][17 pkts/1361 bytes] + 238 TCP 192.168.1.34:50108 <-> 157.56.52.28:40009 [proto: 125/Skype][472 pkts/164627 bytes] + 239 TCP 192.168.1.34:50049 <-> 157.55.130.166:40021 [proto: 125/Skype][16 pkts/1278 bytes] + 240 TCP 192.168.1.34:50067 <-> 157.55.56.160:40027 [proto: 125/Skype][17 pkts/1305 bytes] + 241 TCP 192.168.1.34:50070 <-> 157.55.130.170:40018 [proto: 125/Skype][17 pkts/1312 bytes] + 242 TCP 192.168.1.34:50076 <-> 157.55.235.156:40014 [proto: 125/Skype][18 pkts/1442 bytes] + 243 TCP 192.168.1.34:50092 <-> 157.55.130.155:40020 [proto: 125/Skype][17 pkts/1387 bytes] + 244 UDP 192.168.1.34:64560 <-> 239.255.255.250:1900 [proto: 12/SSDP][2 pkts/349 bytes] + 245 UDP 192.168.1.34:13021 <-> 64.4.23.146:33033 [proto: 125/Skype][1 pkts/66 bytes] + 246 TCP 192.168.1.34:50115 <-> 86.31.35.30:59621 [proto: 125/Skype][17 pkts/1386 bytes] + 247 TCP 192.168.1.34:50103 <-> 64.4.23.166:443 [proto: 91/SSL][12 pkts/1147 bytes] + 248 TCP 192.168.1.34:50030 <-> 65.55.223.33:443 [proto: 91/SSL][15 pkts/1311 bytes] + 249 TCP 192.168.1.34:50066 <-> 65.55.223.12:443 [proto: 91/SSL][15 pkts/1452 bytes] + 250 TCP 192.168.1.34:50102 <-> 65.55.223.15:443 [proto: 91/SSL][14 pkts/1390 bytes] + 251 UDP 192.168.0.254:1025 <-> 239.255.255.250:1900 [proto: 12/SSDP][79 pkts/29479 bytes] + 252 UDP 192.168.1.34:13021 <-> 71.62.0.85:33647 [proto: 125/Skype][1 pkts/60 bytes] + 253 UDP 192.168.1.92:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][4 pkts/828 bytes] + 254 UDP 192.168.1.34:13021 <-> 64.4.23.159:40009 [proto: 125/Skype][1 pkts/70 bytes] + 255 UDP 192.168.1.34:13021 <-> 64.4.23.151:40029 [proto: 125/Skype][1 pkts/72 bytes] + 256 UDP 192.168.1.34:13021 <-> 64.4.23.170:40011 [proto: 125/Skype][1 pkts/68 bytes] + 257 UDP 192.168.1.34:13021 <-> 64.4.23.173:40017 [proto: 125/Skype][1 pkts/66 bytes] + 258 UDP 192.168.1.34:13021 <-> 65.55.223.15:40026 [proto: 125/Skype][1 pkts/66 bytes] + 259 UDP 192.168.1.34:13021 <-> 65.55.223.43:40002 [proto: 125/Skype][1 pkts/76 bytes] + 260 UDP 192.168.1.34:13021 <-> 65.55.223.17:40022 [proto: 125/Skype][1 pkts/70 bytes] + 261 UDP 192.168.1.34:13021 <-> 65.55.223.25:40028 [proto: 125/Skype][1 pkts/76 bytes] + 262 UDP 192.168.1.34:13021 <-> 65.55.223.24:40032 [proto: 125/Skype][1 pkts/67 bytes] + 263 UDP 192.168.1.34:13021 <-> 65.55.223.28:40026 [proto: 125/Skype][1 pkts/74 bytes] + 264 UDP 192.168.1.34:13021 <-> 65.55.223.26:40004 [proto: 125/Skype][1 pkts/79 bytes] + 265 UDP 192.168.1.34:13021 <-> 65.55.223.29:40010 [proto: 125/Skype][1 pkts/77 bytes] + 266 UDP 192.168.1.34:13021 <-> 65.55.223.45:40012 [proto: 125/Skype][1 pkts/71 bytes] + 267 UDP 192.168.1.34:123 <-> 17.253.48.245:123 [proto: 9/NTP][2 pkts/180 bytes] + 268 TCP 192.168.1.34:50111 <-> 91.190.216.125:443 [proto: 91.125/SSL.Skype][20 pkts/1516 bytes] + 269 TCP 192.168.1.34:50123 <-> 80.14.46.121:4415 [proto: 125/Skype][18 pkts/1506 bytes] + 270 TCP 192.168.1.34:50141 <-> 80.14.46.121:4415 [proto: 125/Skype][15 pkts/1237 bytes] + 271 TCP 108.160.170.46:443 <-> 192.168.1.34:49445 [proto: 91.121/SSL.Dropbox][16 pkts/5980 bytes] + 272 TCP 192.168.1.34:50058 <-> 111.221.74.47:443 [proto: 91.121/SSL.Dropbox][14 pkts/1208 bytes] + 273 TCP 192.168.1.34:50100 <-> 111.221.74.46:443 [proto: 91.125/SSL.Skype][13 pkts/1109 bytes] + 274 TCP 192.168.1.34:50035 <-> 213.199.179.175:40021 [proto: 125/Skype][17 pkts/1304 bytes] + 275 TCP 192.168.1.34:50075 <-> 213.199.179.142:40003 [proto: 125/Skype][19 pkts/1495 bytes] + 276 UDP [ff02::fb]:5353 <-> [fe80::c62c:3ff:fe06:49fe]:5353 [proto: 8/MDNS][4 pkts/908 bytes] Undetected flows: @@ -300,12 +299,13 @@ Undetected flows: 5 UDP 192.168.1.34:54067 <-> 192.168.1.1:5351 [proto: 0/Unknown][4 pkts/216 bytes] 6 TCP 192.168.1.34:50124 <-> 81.133.19.185:44431 [proto: 0/Unknown][22 pkts/1636 bytes] 7 TCP 192.168.1.34:50131 <-> 212.161.8.36:13392 [proto: 0/Unknown][19 pkts/5111 bytes] - 8 TCP 192.168.1.34:50142 <-> 80.14.46.121:4415 [proto: 0/Unknown][18 pkts/1474 bytes] - 9 TCP 192.168.1.34:50139 <-> 5.248.186.221:31010 [proto: 0/Unknown][23 pkts/4119 bytes] - 10 TCP 192.168.1.34:50138 <-> 71.238.7.203:18767 [proto: 0/Unknown][32 pkts/4972 bytes] - 11 TCP 192.168.1.34:50121 <-> 81.83.77.141:17639 [proto: 0/Unknown][40 pkts/5609 bytes] - 12 TCP 192.168.1.34:50140 <-> 76.167.161.6:20274 [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 192.168.1.34:50145 <-> 157.56.53.51:12350 [proto: 0/Unknown][8 pkts/608 bytes] - 15 TCP 192.168.1.34:50119 <-> 86.31.35.30:59621 [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] + 8 TCP 17.143.160.22:5223 <-> 192.168.1.34:49447 [proto: 0/Unknown][12 pkts/1877 bytes] + 9 TCP 192.168.1.34:50142 <-> 80.14.46.121:4415 [proto: 0/Unknown][18 pkts/1474 bytes] + 10 TCP 192.168.1.34:50139 <-> 5.248.186.221:31010 [proto: 0/Unknown][23 pkts/4119 bytes] + 11 TCP 192.168.1.34:50138 <-> 71.238.7.203:18767 [proto: 0/Unknown][32 pkts/4972 bytes] + 12 TCP 192.168.1.34:50121 <-> 81.83.77.141:17639 [proto: 0/Unknown][40 pkts/5609 bytes] + 13 TCP 192.168.1.34:50140 <-> 76.167.161.6:20274 [proto: 0/Unknown][3 pkts/206 bytes] + 14 TCP 192.168.1.34:50144 <-> 78.202.226.115:29059 [proto: 0/Unknown][14 pkts/1139 bytes] + 15 TCP 192.168.1.34:50145 <-> 157.56.53.51:12350 [proto: 0/Unknown][8 pkts/608 bytes] + 16 TCP 192.168.1.34:50119 <-> 86.31.35.30:59621 [proto: 0/Unknown][100 pkts/12266 bytes] + 17 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 2d9048852..6f39106c4 100644 --- a/tests/result/skype_no_unknown.pcap.out +++ b/tests/result/skype_no_unknown.pcap.out @@ -261,7 +261,7 @@ MS_OneDrive 348 181687 1 248 UDP 192.168.1.34:13021 <-> 65.55.223.43:40006 [proto: 125/Skype][1 pkts/77 bytes] 249 UDP [ff02::fb]:5353 <-> [fe80::c62c:3ff:fe06:49fe]:5353 [proto: 8/MDNS][2 pkts/258 bytes] 250 TCP 192.168.1.34:51240 <-> 111.221.74.45:443 [proto: 91.125/SSL.Skype][14 pkts/1373 bytes] - 251 TCP 192.168.1.34:51268 <-> 111.221.74.18:443 [proto: 91.125/SSL.Skype][14 pkts/1203 bytes] + 251 TCP 192.168.1.34:51268 <-> 111.221.74.18:443 [proto: 125/Skype][14 pkts/1203 bytes] 252 TCP 192.168.1.34:51250 <-> 111.221.77.175:443 [proto: 91.125/SSL.Skype][14 pkts/1363 bytes] 253 TCP 192.168.1.34:51269 <-> 213.199.179.175:40029 [proto: 125/Skype][19 pkts/1491 bytes] diff --git a/tests/result/starcraft_battle.pcap.out b/tests/result/starcraft_battle.pcap.out index f2d26ea0a..3d096ba01 100644 --- a/tests/result/starcraft_battle.pcap.out +++ b/tests/result/starcraft_battle.pcap.out @@ -4,11 +4,11 @@ SSDP 11 4984 1 HTTP_Download 179 134204 1 WorldOfWarcraft 9 880 1 IGMP 2 120 1 -SSL 38 2548 11 +SSL 30 1998 9 Google 16 1709 4 QUIC 6 475 1 Github 3 234 1 -Starcraft 236 51494 6 +Starcraft 244 52044 8 1 TCP 192.168.1.100:3516 <-> 80.239.186.21:80 [proto: 7/HTTP][12 pkts/3680 bytes][Host: eu.launcher.battle.net] 2 TCP 192.168.1.100:3518 <-> 80.239.186.26:80 [proto: 7/HTTP][10 pkts/1226 bytes][Host: nydus.battle.net] @@ -28,8 +28,8 @@ Starcraft 236 51494 6 16 TCP 192.168.1.100:3530 <-> 2.228.46.112:80 [proto: 7/HTTP][29 pkts/25102 bytes][Host: bnetcmsus-a.akamaihd.net] 17 TCP 192.168.1.100:3532 <-> 2.228.46.112:80 [proto: 7/HTTP][4 pkts/386 bytes][Host: bnetcmsus-a.akamaihd.net] 18 TCP 192.168.1.100:3534 <-> 2.228.46.112:80 [proto: 7/HTTP][1 pkts/66 bytes] - 19 TCP 192.168.1.100:3489 <-> 2.228.46.104:443 [proto: 91/SSL][4 pkts/275 bytes] - 20 TCP 192.168.1.100:3481 <-> 2.228.46.114:443 [proto: 91/SSL][4 pkts/275 bytes] + 19 TCP 192.168.1.100:3489 <-> 2.228.46.104:443 [proto: 91.213/SSL.Starcraft][4 pkts/275 bytes] + 20 TCP 192.168.1.100:3481 <-> 2.228.46.114:443 [proto: 91.213/SSL.Starcraft][4 pkts/275 bytes] 21 TCP 192.168.1.100:3479 <-> 2.228.46.114:443 [proto: 91/SSL][4 pkts/275 bytes] 22 TCP 192.168.1.100:3491 <-> 2.228.46.104:443 [proto: 91/SSL][4 pkts/275 bytes] 23 TCP 192.168.1.100:3515 <-> 80.239.186.26:80 [proto: 7/HTTP][10 pkts/1224 bytes][Host: nydus.battle.net] diff --git a/tests/result/viber_mobile.pcap.out b/tests/result/viber_mobile.pcap.out index c311e74b3..80e00c267 100644 --- a/tests/result/viber_mobile.pcap.out +++ b/tests/result/viber_mobile.pcap.out @@ -1,4 +1,4 @@ -Unknown 163 9995 7 +Unknown 195 17876 9 DNS 16 1943 7 HTTP 43 4771 7 BitTorrent 57 13074 27 @@ -8,90 +8,90 @@ SSL 79 21658 7 Facebook 50 17455 3 Dropbox 2 163 1 GMail 35 14773 2 -Google 76 17175 8 +Google 60 11337 7 WhatsApp 31 6224 2 -Viber 10081 1413446 4 +Viber 10065 1411403 3 Amazon 8 528 1 1 TCP 192.168.200.222:57999 <-> 74.125.130.188:5228 [proto: 91.126/SSL.Google][15 pkts/2458 bytes][client: mtalk.google.com] 2 UDP 192.168.200.222:39413 <-> 122.146.250.88:9415 [proto: 37/BitTorrent][1 pkts/146 bytes] - 3 TCP 192.168.200.222:59011 <-> 74.125.130.188:5228 [proto: 126/Google][16 pkts/5838 bytes] - 4 UDP 192.168.200.222:39413 <-> 134.249.176.227:7108 [proto: 37/BitTorrent][2 pkts/475 bytes] - 5 TCP 192.168.200.222:60828 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] - 6 TCP 192.168.200.222:44058 <-> 158.85.58.23:443 [proto: 91/SSL][7 pkts/532 bytes] - 7 UDP 192.168.200.222:15836 <-> 8.8.8.8:53 [proto: 5.122/DNS.GMail][2 pkts/241 bytes][Host: mail.google.com] - 8 UDP 192.168.200.222:39413 <-> 84.202.23.122:22737 [proto: 37/BitTorrent][2 pkts/505 bytes] - 9 UDP 192.168.200.222:39413 <-> 178.57.5.53:64731 [proto: 37/BitTorrent][2 pkts/498 bytes] - 10 UDP 192.168.200.222:39413 <-> 60.71.113.134:37764 [proto: 37/BitTorrent][2 pkts/505 bytes] - 11 UDP 192.168.200.222:39413 <-> 23.113.222.89:49548 [proto: 37/BitTorrent][2 pkts/503 bytes] - 12 UDP 192.168.200.222:39413 <-> 1.163.234.205:58738 [proto: 37/BitTorrent][2 pkts/471 bytes] - 13 TCP 222.165.163.117:443 <-> 192.168.200.222:47424 [proto: 91/SSL][5 pkts/385 bytes] - 14 UDP 192.168.200.222:39413 <-> 90.19.187.56:40500 [proto: 37/BitTorrent][1 pkts/146 bytes] - 15 UDP 192.168.200.222:39413 <-> 80.47.129.1:44420 [proto: 37/BitTorrent][2 pkts/505 bytes] - 16 UDP 192.168.200.222:39413 <-> 70.112.231.62:51413 [proto: 37/BitTorrent][3 pkts/438 bytes] - 17 TCP 192.168.200.222:38039 <-> 31.13.79.246:443 [proto: 91.119/SSL.Facebook][37 pkts/16168 bytes][client: graph.facebook.com] - 18 UDP 192.168.200.222:39413 <-> 94.6.33.9:46735 [proto: 37/BitTorrent][2 pkts/505 bytes] - 19 TCP 216.58.199.206:443 <-> 192.168.200.222:58663 [proto: 91.126/SSL.Google][2 pkts/132 bytes] - 20 UDP 192.168.200.222:39413 <-> 88.176.55.218:51413 [proto: 37/BitTorrent][1 pkts/146 bytes] - 21 UDP 192.168.200.222:39413 <-> 182.57.65.243:27736 [proto: 37/BitTorrent][2 pkts/292 bytes] - 22 TCP 192.168.200.222:38778 <-> 54.251.141.219:80 [proto: 7.178/HTTP.Amazon][8 pkts/528 bytes] - 23 UDP 192.168.200.222:47874 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][2 pkts/197 bytes][Host: mtalk.google.com] - 24 TCP 192.168.200.222:39339 <-> 54.169.63.186:443 [proto: 91.144/SSL.Viber][6 pkts/412 bytes] - 25 UDP 192.168.200.222:39413 <-> 92.249.148.218:53810 [proto: 37/BitTorrent][2 pkts/505 bytes] - 26 TCP 192.168.200.222:33161 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] - 27 TCP 192.168.200.222:52491 <-> 31.13.79.245:443 [proto: 91.119/SSL.Facebook][11 pkts/1073 bytes] - 28 UDP 192.168.200.222:55854 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/236 bytes][Host: s.jpush.cn] - 29 UDP 192.168.200.222:58434 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/349 bytes][Host: e.crashlytics.com] - 30 UDP 192.168.200.222:39413 <-> 2.85.108.0:21241 [proto: 37/BitTorrent][2 pkts/505 bytes] - 31 TCP 192.168.200.222:36675 <-> 112.124.219.82:80 [proto: 7/HTTP][9 pkts/2188 bytes][Host: androiddailyyogacn.oss-cn-hangzhou.aliyuncs.com] - 32 UDP 192.168.200.222:60474 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/218 bytes][Host: easytomessage.com] - 33 UDP 192.168.200.222:39413 <-> 24.43.1.206:17193 [proto: 37/BitTorrent][8 pkts/1992 bytes] - 34 ICMP 8.8.8.8:0 <-> 192.168.200.222:0 [proto: 81.126/ICMP.Google][1 pkts/148 bytes] - 35 UDP 192.168.200.222:39413 <-> 186.220.157.231:45235 [proto: 37/BitTorrent][2 pkts/505 bytes] - 36 TCP 192.168.200.222:51055 <-> 74.125.68.156:443 [proto: 91.126/SSL.Google][31 pkts/7607 bytes][client: googleads.g.doubleclick.net] - 37 ICMP 37.214.167.82:0 <-> 192.168.200.222:0 [proto: 81/ICMP][1 pkts/174 bytes] - 38 UDP 192.168.200.222:39413 <-> 80.234.25.211:12624 [proto: 37/BitTorrent][2 pkts/505 bytes] - 39 TCP 192.168.200.222:46761 <-> 112.124.219.93:80 [proto: 7/HTTP][9 pkts/1083 bytes][Host: androiddailyyogacn.oss-cn-hangzhou.aliyuncs.com] - 40 TCP 192.168.200.222:52977 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] - 41 UDP 192.168.200.222:39413 <-> 120.57.18.255:10201 [proto: 37/BitTorrent][2 pkts/505 bytes] - 42 UDP 192.168.200.222:16965 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/366 bytes][Host: settings.crashlytics.com] - 43 UDP 192.168.200.222:39413 <-> 24.43.1.206:40959 [proto: 37/BitTorrent][4 pkts/996 bytes] - 44 UDP 192.168.200.222:39413 <-> 46.181.170.37:36237 [proto: 37/BitTorrent][2 pkts/505 bytes] - 45 UDP 192.168.200.222:22761 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/246 bytes][Host: androiddailyyogacn.oss-cn-hangzhou.aliyuncs.com] - 46 UDP 192.168.200.222:39413 <-> 188.165.225.138:6881 [proto: 37/BitTorrent][2 pkts/480 bytes] - 47 UDP 192.168.200.222:39149 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/192 bytes][Host: sis.jpush.io] - 48 TCP 222.165.163.93:443 <-> 192.168.200.222:52635 [proto: 91/SSL][7 pkts/529 bytes] - 49 TCP 222.165.163.93:443 <-> 192.168.200.222:52641 [proto: 91/SSL][5 pkts/385 bytes] - 50 UDP 192.168.200.222:39413 <-> 178.157.199.144:22133 [proto: 37/BitTorrent][1 pkts/146 bytes] - 51 UDP 192.168.200.222:39695 <-> 8.8.8.8:53 [proto: 5.119/DNS.Facebook][2 pkts/214 bytes][Host: graph.facebook.com] - 52 TCP 222.165.163.91:443 <-> 192.168.200.222:56243 [proto: 91/SSL][7 pkts/529 bytes] - 53 ICMP 192.168.1.1:0 <-> 192.168.200.222:0 [proto: 81/ICMP][2 pkts/196 bytes] - 54 UDP 192.168.200.222:43901 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][2 pkts/263 bytes][Host: googleads.g.doubleclick.net] - 55 TCP 74.125.68.239:443 <-> 192.168.200.222:37376 [proto: 91.126/SSL.Google][7 pkts/532 bytes] - 56 TCP 192.168.200.222:43287 <-> 52.0.253.46:443 [proto: 64/SSL_No_Cert][36 pkts/5874 bytes] - 57 UDP 192.168.200.222:52263 <-> 8.8.8.8:53 [proto: 5.142/DNS.WhatsApp][2 pkts/278 bytes][Host: e9.whatsapp.net] - 58 TCP 192.168.200.222:51146 <-> 23.21.254.189:443 [proto: 91/SSL][22 pkts/9241 bytes][client: e.crashlytics.com][server: *.crashlytics.com] - 59 TCP 52.0.253.46:4244 <-> 192.168.200.222:43454 [proto: 144/Viber][16 pkts/2043 bytes] - 60 TCP 192.168.200.222:42040 <-> 74.125.200.18:443 [proto: 91.122/SSL.GMail][33 pkts/14532 bytes][client: mail.google.com] - 61 UDP 192.168.200.222:39413 <-> 37.214.167.82:11905 [proto: 37/BitTorrent][1 pkts/146 bytes] - 62 UDP 192.168.200.222:58921 <-> 8.8.8.8:53 [proto: 5/DNS][4 pkts/336 bytes][Host: sis.jpush.io] - 63 TCP 192.168.200.222:43646 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] - 64 TCP 192.168.200.222:40005 <-> 108.168.176.234:443 [proto: 142/WhatsApp][29 pkts/5946 bytes] - 65 UDP 192.168.200.222:39413 <-> 93.100.186.199:6881 [proto: 37/BitTorrent][2 pkts/498 bytes] - 66 UDP 192.168.200.222:48564 <-> 54.169.63.186:7985 [proto: 144/Viber][10057 pkts/1410853 bytes] - 67 UDP 192.168.200.222:48564 <-> 54.169.63.186:7987 [proto: 144/Viber][2 pkts/138 bytes] - 68 TCP 192.168.200.222:50854 <-> 93.184.221.200:80 [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 192.168.200.222:39413 <-> 92.245.59.202:12998 [proto: 37/BitTorrent][2 pkts/505 bytes] - 71 TCP 192.168.200.222:51765 <-> 108.160.172.205:443 [proto: 91.121/SSL.Dropbox][2 pkts/163 bytes] - 72 TCP 192.168.200.222:52269 <-> 107.22.192.179:443 [proto: 91/SSL][26 pkts/10057 bytes][client: settings.crashlytics.com][server: *.crashlytics.com] + 3 UDP 192.168.200.222:39413 <-> 134.249.176.227:7108 [proto: 37/BitTorrent][2 pkts/475 bytes] + 4 TCP 192.168.200.222:60828 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] + 5 TCP 192.168.200.222:44058 <-> 158.85.58.23:443 [proto: 91/SSL][7 pkts/532 bytes] + 6 UDP 192.168.200.222:15836 <-> 8.8.8.8:53 [proto: 5.122/DNS.GMail][2 pkts/241 bytes][Host: mail.google.com] + 7 UDP 192.168.200.222:39413 <-> 84.202.23.122:22737 [proto: 37/BitTorrent][2 pkts/505 bytes] + 8 UDP 192.168.200.222:39413 <-> 178.57.5.53:64731 [proto: 37/BitTorrent][2 pkts/498 bytes] + 9 UDP 192.168.200.222:39413 <-> 60.71.113.134:37764 [proto: 37/BitTorrent][2 pkts/505 bytes] + 10 UDP 192.168.200.222:39413 <-> 23.113.222.89:49548 [proto: 37/BitTorrent][2 pkts/503 bytes] + 11 UDP 192.168.200.222:39413 <-> 1.163.234.205:58738 [proto: 37/BitTorrent][2 pkts/471 bytes] + 12 TCP 222.165.163.117:443 <-> 192.168.200.222:47424 [proto: 91/SSL][5 pkts/385 bytes] + 13 UDP 192.168.200.222:39413 <-> 90.19.187.56:40500 [proto: 37/BitTorrent][1 pkts/146 bytes] + 14 UDP 192.168.200.222:39413 <-> 80.47.129.1:44420 [proto: 37/BitTorrent][2 pkts/505 bytes] + 15 UDP 192.168.200.222:39413 <-> 70.112.231.62:51413 [proto: 37/BitTorrent][3 pkts/438 bytes] + 16 TCP 192.168.200.222:38039 <-> 31.13.79.246:443 [proto: 91.119/SSL.Facebook][37 pkts/16168 bytes][client: graph.facebook.com] + 17 UDP 192.168.200.222:39413 <-> 94.6.33.9:46735 [proto: 37/BitTorrent][2 pkts/505 bytes] + 18 TCP 216.58.199.206:443 <-> 192.168.200.222:58663 [proto: 91.126/SSL.Google][2 pkts/132 bytes] + 19 UDP 192.168.200.222:39413 <-> 88.176.55.218:51413 [proto: 37/BitTorrent][1 pkts/146 bytes] + 20 UDP 192.168.200.222:39413 <-> 182.57.65.243:27736 [proto: 37/BitTorrent][2 pkts/292 bytes] + 21 TCP 192.168.200.222:38778 <-> 54.251.141.219:80 [proto: 7.178/HTTP.Amazon][8 pkts/528 bytes] + 22 UDP 192.168.200.222:47874 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][2 pkts/197 bytes][Host: mtalk.google.com] + 23 TCP 192.168.200.222:39339 <-> 54.169.63.186:443 [proto: 91.144/SSL.Viber][6 pkts/412 bytes] + 24 UDP 192.168.200.222:39413 <-> 92.249.148.218:53810 [proto: 37/BitTorrent][2 pkts/505 bytes] + 25 TCP 192.168.200.222:33161 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] + 26 TCP 192.168.200.222:52491 <-> 31.13.79.245:443 [proto: 91.119/SSL.Facebook][11 pkts/1073 bytes] + 27 UDP 192.168.200.222:55854 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/236 bytes][Host: s.jpush.cn] + 28 UDP 192.168.200.222:58434 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/349 bytes][Host: e.crashlytics.com] + 29 UDP 192.168.200.222:39413 <-> 2.85.108.0:21241 [proto: 37/BitTorrent][2 pkts/505 bytes] + 30 TCP 192.168.200.222:36675 <-> 112.124.219.82:80 [proto: 7/HTTP][9 pkts/2188 bytes][Host: androiddailyyogacn.oss-cn-hangzhou.aliyuncs.com] + 31 UDP 192.168.200.222:60474 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/218 bytes][Host: easytomessage.com] + 32 UDP 192.168.200.222:39413 <-> 24.43.1.206:17193 [proto: 37/BitTorrent][8 pkts/1992 bytes] + 33 ICMP 8.8.8.8:0 <-> 192.168.200.222:0 [proto: 81.126/ICMP.Google][1 pkts/148 bytes] + 34 UDP 192.168.200.222:39413 <-> 186.220.157.231:45235 [proto: 37/BitTorrent][2 pkts/505 bytes] + 35 TCP 192.168.200.222:51055 <-> 74.125.68.156:443 [proto: 91.126/SSL.Google][31 pkts/7607 bytes][client: googleads.g.doubleclick.net] + 36 ICMP 37.214.167.82:0 <-> 192.168.200.222:0 [proto: 81/ICMP][1 pkts/174 bytes] + 37 UDP 192.168.200.222:39413 <-> 80.234.25.211:12624 [proto: 37/BitTorrent][2 pkts/505 bytes] + 38 TCP 192.168.200.222:46761 <-> 112.124.219.93:80 [proto: 7/HTTP][9 pkts/1083 bytes][Host: androiddailyyogacn.oss-cn-hangzhou.aliyuncs.com] + 39 TCP 192.168.200.222:52977 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] + 40 UDP 192.168.200.222:39413 <-> 120.57.18.255:10201 [proto: 37/BitTorrent][2 pkts/505 bytes] + 41 UDP 192.168.200.222:16965 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/366 bytes][Host: settings.crashlytics.com] + 42 UDP 192.168.200.222:39413 <-> 24.43.1.206:40959 [proto: 37/BitTorrent][4 pkts/996 bytes] + 43 UDP 192.168.200.222:39413 <-> 46.181.170.37:36237 [proto: 37/BitTorrent][2 pkts/505 bytes] + 44 UDP 192.168.200.222:22761 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/246 bytes][Host: androiddailyyogacn.oss-cn-hangzhou.aliyuncs.com] + 45 UDP 192.168.200.222:39413 <-> 188.165.225.138:6881 [proto: 37/BitTorrent][2 pkts/480 bytes] + 46 UDP 192.168.200.222:39149 <-> 8.8.8.8:53 [proto: 5/DNS][2 pkts/192 bytes][Host: sis.jpush.io] + 47 TCP 222.165.163.93:443 <-> 192.168.200.222:52635 [proto: 91/SSL][7 pkts/529 bytes] + 48 TCP 222.165.163.93:443 <-> 192.168.200.222:52641 [proto: 91/SSL][5 pkts/385 bytes] + 49 UDP 192.168.200.222:39413 <-> 178.157.199.144:22133 [proto: 37/BitTorrent][1 pkts/146 bytes] + 50 UDP 192.168.200.222:39695 <-> 8.8.8.8:53 [proto: 5.119/DNS.Facebook][2 pkts/214 bytes][Host: graph.facebook.com] + 51 TCP 222.165.163.91:443 <-> 192.168.200.222:56243 [proto: 91/SSL][7 pkts/529 bytes] + 52 ICMP 192.168.1.1:0 <-> 192.168.200.222:0 [proto: 81/ICMP][2 pkts/196 bytes] + 53 UDP 192.168.200.222:43901 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][2 pkts/263 bytes][Host: googleads.g.doubleclick.net] + 54 TCP 74.125.68.239:443 <-> 192.168.200.222:37376 [proto: 91.126/SSL.Google][7 pkts/532 bytes] + 55 TCP 192.168.200.222:43287 <-> 52.0.253.46:443 [proto: 64/SSL_No_Cert][36 pkts/5874 bytes] + 56 UDP 192.168.200.222:52263 <-> 8.8.8.8:53 [proto: 5.142/DNS.WhatsApp][2 pkts/278 bytes][Host: e9.whatsapp.net] + 57 TCP 192.168.200.222:51146 <-> 23.21.254.189:443 [proto: 91/SSL][22 pkts/9241 bytes][client: e.crashlytics.com][server: *.crashlytics.com] + 58 TCP 192.168.200.222:42040 <-> 74.125.200.18:443 [proto: 91.122/SSL.GMail][33 pkts/14532 bytes][client: mail.google.com] + 59 UDP 192.168.200.222:39413 <-> 37.214.167.82:11905 [proto: 37/BitTorrent][1 pkts/146 bytes] + 60 UDP 192.168.200.222:58921 <-> 8.8.8.8:53 [proto: 5/DNS][4 pkts/336 bytes][Host: sis.jpush.io] + 61 TCP 192.168.200.222:43646 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] + 62 TCP 192.168.200.222:40005 <-> 108.168.176.234:443 [proto: 142/WhatsApp][29 pkts/5946 bytes] + 63 UDP 192.168.200.222:39413 <-> 93.100.186.199:6881 [proto: 37/BitTorrent][2 pkts/498 bytes] + 64 UDP 192.168.200.222:48564 <-> 54.169.63.186:7985 [proto: 144/Viber][10057 pkts/1410853 bytes] + 65 UDP 192.168.200.222:48564 <-> 54.169.63.186:7987 [proto: 144/Viber][2 pkts/138 bytes] + 66 TCP 192.168.200.222:50854 <-> 93.184.221.200:80 [proto: 7/HTTP][5 pkts/300 bytes] + 67 UDP 192.168.200.222:39413 <-> 81.192.42.247:15057 [proto: 37/BitTorrent][1 pkts/146 bytes] + 68 UDP 192.168.200.222:39413 <-> 92.245.59.202:12998 [proto: 37/BitTorrent][2 pkts/505 bytes] + 69 TCP 192.168.200.222:51765 <-> 108.160.172.205:443 [proto: 91.121/SSL.Dropbox][2 pkts/163 bytes] + 70 TCP 192.168.200.222:52269 <-> 107.22.192.179:443 [proto: 91/SSL][26 pkts/10057 bytes][client: settings.crashlytics.com][server: *.crashlytics.com] Undetected flows: - 1 TCP 192.168.200.222:55554 <-> 113.31.80.142:7003 [proto: 0/Unknown][6 pkts/446 bytes] - 2 UDP 192.168.200.222:48564 <-> 175.157.52.135:37299 [proto: 0/Unknown][30 pkts/1800 bytes] - 3 UDP 192.168.200.222:48564 <-> 175.157.52.135:37301 [proto: 0/Unknown][30 pkts/1800 bytes] - 4 TCP 192.168.200.222:55565 <-> 113.31.80.142:7003 [proto: 0/Unknown][7 pkts/549 bytes] - 5 UDP 192.168.200.222:48564 <-> 10.216.246.82:59027 [proto: 0/Unknown][30 pkts/1800 bytes] - 6 UDP 192.168.200.222:48564 <-> 175.157.52.135:37300 [proto: 0/Unknown][30 pkts/1800 bytes] - 7 UDP 192.168.200.222:48564 <-> 175.157.52.135:37302 [proto: 0/Unknown][30 pkts/1800 bytes] + 1 TCP 192.168.200.222:59011 <-> 74.125.130.188:5228 [proto: 0/Unknown][16 pkts/5838 bytes] + 2 TCP 192.168.200.222:55554 <-> 113.31.80.142:7003 [proto: 0/Unknown][6 pkts/446 bytes] + 3 UDP 192.168.200.222:48564 <-> 175.157.52.135:37299 [proto: 0/Unknown][30 pkts/1800 bytes] + 4 UDP 192.168.200.222:48564 <-> 175.157.52.135:37301 [proto: 0/Unknown][30 pkts/1800 bytes] + 5 TCP 192.168.200.222:55565 <-> 113.31.80.142:7003 [proto: 0/Unknown][7 pkts/549 bytes] + 6 UDP 192.168.200.222:48564 <-> 10.216.246.82:59027 [proto: 0/Unknown][30 pkts/1800 bytes] + 7 TCP 52.0.253.46:4244 <-> 192.168.200.222:43454 [proto: 0/Unknown][16 pkts/2043 bytes] + 8 UDP 192.168.200.222:48564 <-> 175.157.52.135:37300 [proto: 0/Unknown][30 pkts/1800 bytes] + 9 UDP 192.168.200.222:48564 <-> 175.157.52.135:37302 [proto: 0/Unknown][30 pkts/1800 bytes] diff --git a/tests/result/whatsapp_login_call.pcap.out b/tests/result/whatsapp_login_call.pcap.out index f689282ed..99ff51ed5 100644 --- a/tests/result/whatsapp_login_call.pcap.out +++ b/tests/result/whatsapp_login_call.pcap.out @@ -1,7 +1,7 @@ +Unknown 27 2322 2 HTTP 11 726 3 MDNS 8 952 4 DHCP 10 3420 1 -STUN 27 2322 2 ICMP 10 700 1 SSL 8 589 2 Facebook 70 9464 14 @@ -19,53 +19,56 @@ WhatsAppVoice 706 91156 4 5 UDP 192.168.2.4:52794 <-> 173.252.114.1:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] 6 UDP 192.168.2.4:51897 <-> 192.168.2.1:53 [proto: 5.140/DNS.Apple][2 pkts/330 bytes][Host: query.ess.apple.com] 7 UDP 192.168.2.4:52794 <-> 179.60.192.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 8 UDP 192.168.2.4:51518 <-> 1.194.90.191:60312 [proto: 78/STUN][15 pkts/1290 bytes] - 9 TCP 192.168.2.4:49166 <-> 17.154.66.121:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 10 TCP 192.168.2.4:49169 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 11 TCP 192.168.2.4:49176 <-> 17.130.137.77:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 12 TCP 192.168.2.4:49182 <-> 17.172.100.52:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 13 TCP 192.168.2.4:49180 <-> 17.172.100.59:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 14 TCP 192.168.2.4:49197 <-> 17.167.142.39:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 15 TCP 192.168.2.4:49205 <-> 17.173.66.102:443 [proto: 91.145/SSL.AppleiTunes][32 pkts/9705 bytes][client: p53-buy.itunes.apple.com] - 16 TCP 192.168.2.4:49172 <-> 23.50.148.228:443 [proto: 91/SSL][5 pkts/391 bytes] - 17 UDP 192.168.2.4:51518 <-> 31.13.100.14:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 18 UDP 192.168.2.4:51518 <-> 31.13.70.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 19 UDP 192.168.2.4:51518 <-> 31.13.64.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 20 UDP 192.168.2.4:51518 <-> 31.13.85.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 21 UDP 192.168.2.4:51518 <-> 31.13.73.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 22 UDP 192.168.2.4:51518 <-> 31.13.91.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 23 UDP 192.168.2.4:51518 <-> 31.13.79.192:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 24 UDP 192.168.2.4:51518 <-> 31.13.93.48:3478 [proto: 189/WhatsAppVoice][24 pkts/4825 bytes] - 25 UDP 192.168.2.4:52794 <-> 31.13.73.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 26 UDP 192.168.2.4:52794 <-> 31.13.93.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 27 UDP 192.168.2.4:52794 <-> 31.13.90.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 28 UDP 192.168.2.4:52794 <-> 31.13.74.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 29 UDP 192.168.2.4:52794 <-> 31.13.84.48:3478 [proto: 189/WhatsAppVoice][20 pkts/2993 bytes] - 30 UDP 192.168.2.4:52794 <-> 31.13.79.192:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] - 31 TCP 192.168.2.4:49173 <-> 93.186.135.82:80 [proto: 7/HTTP][3 pkts/198 bytes] - 32 TCP 192.168.2.4:49194 <-> 93.62.150.157:443 [proto: 91/SSL][3 pkts/198 bytes] - 33 UDP 0.0.0.0:68 <-> 255.255.255.255:67 [proto: 18/DHCP][10 pkts/3420 bytes][Host: lucas-imac] - 34 UDP 192.168.2.4:51518 <-> 91.253.176.65:9344 [proto: 189/WhatsAppVoice][464 pkts/52920 bytes] - 35 TCP 192.168.2.4:49202 <-> 184.173.179.37:5222 [proto: 142/WhatsApp][180 pkts/24874 bytes] - 36 UDP 192.168.2.1:57621 <-> 192.168.2.255:57621 [proto: 156/Spotify][3 pkts/258 bytes] - 37 UDP 192.168.2.4:52190 <-> 192.168.2.1:53 [proto: 5.142/DNS.WhatsApp][2 pkts/280 bytes][Host: e13.whatsapp.net] - 38 UDP 192.168.2.4:52794 <-> 1.194.90.191:51727 [proto: 78/STUN][12 pkts/1032 bytes] - 39 TCP 192.168.2.4:49174 <-> 5.178.42.26:80 [proto: 7/HTTP][3 pkts/198 bytes] - 40 TCP 192.168.2.4:49163 <-> 17.154.66.111:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 41 TCP 192.168.2.4:49175 <-> 17.172.100.53:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 42 TCP 192.168.2.4:49165 <-> 17.172.100.55:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 43 TCP 192.168.2.4:49164 <-> 17.167.142.31:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 44 TCP 192.168.2.4:49167 <-> 17.172.100.8:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 45 TCP 192.168.2.4:49201 <-> 17.178.104.12:443 [proto: 91.140/SSL.Apple][38 pkts/17220 bytes][client: query.ess.apple.com] - 46 TCP 192.168.2.4:49191 <-> 17.172.100.49:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 47 TCP 192.168.2.4:49181 <-> 17.172.100.37:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 48 TCP 192.168.2.4:49198 <-> 17.167.142.13:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 49 TCP 192.168.2.4:49200 <-> 17.167.142.13:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] - 50 TCP 192.168.2.4:49203 <-> 17.178.104.14:443 [proto: 91.140/SSL.Apple][3 pkts/198 bytes] - 51 TCP 192.168.2.4:49204 <-> 17.173.66.102:443 [proto: 91.145/SSL.AppleiTunes][53 pkts/18382 bytes][client: p53-buy.itunes.apple.com] - 52 TCP 192.168.2.4:49199 <-> 17.172.100.70:993 [proto: 51.140/IMAPS.Apple][17 pkts/1998 bytes] - 53 TCP 192.168.2.4:49193 <-> 17.110.229.14:5223 [proto: 140/Apple][22 pkts/5926 bytes] - 54 UDP 169.254.166.207:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][2 pkts/218 bytes] - 55 UDP 192.168.2.1:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][2 pkts/218 bytes] - 56 TCP 192.168.2.4:49192 <-> 93.186.135.8:80 [proto: 7/HTTP][5 pkts/330 bytes] - 57 UDP [fe80::c42c:3ff:fe60:6a64]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][2 pkts/258 bytes] + 8 TCP 192.168.2.4:49166 <-> 17.154.66.121:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 9 TCP 192.168.2.4:49169 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 10 TCP 192.168.2.4:49176 <-> 17.130.137.77:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 11 TCP 192.168.2.4:49182 <-> 17.172.100.52:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 12 TCP 192.168.2.4:49180 <-> 17.172.100.59:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 13 TCP 192.168.2.4:49197 <-> 17.167.142.39:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 14 TCP 192.168.2.4:49205 <-> 17.173.66.102:443 [proto: 91.145/SSL.AppleiTunes][32 pkts/9705 bytes][client: p53-buy.itunes.apple.com] + 15 TCP 192.168.2.4:49172 <-> 23.50.148.228:443 [proto: 91/SSL][5 pkts/391 bytes] + 16 UDP 192.168.2.4:51518 <-> 31.13.100.14:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 17 UDP 192.168.2.4:51518 <-> 31.13.70.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 18 UDP 192.168.2.4:51518 <-> 31.13.64.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 19 UDP 192.168.2.4:51518 <-> 31.13.85.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 20 UDP 192.168.2.4:51518 <-> 31.13.73.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 21 UDP 192.168.2.4:51518 <-> 31.13.91.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 22 UDP 192.168.2.4:51518 <-> 31.13.79.192:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 23 UDP 192.168.2.4:51518 <-> 31.13.93.48:3478 [proto: 189/WhatsAppVoice][24 pkts/4825 bytes] + 24 UDP 192.168.2.4:52794 <-> 31.13.73.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 25 UDP 192.168.2.4:52794 <-> 31.13.93.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 26 UDP 192.168.2.4:52794 <-> 31.13.90.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 27 UDP 192.168.2.4:52794 <-> 31.13.74.48:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 28 UDP 192.168.2.4:52794 <-> 31.13.84.48:3478 [proto: 189/WhatsAppVoice][20 pkts/2993 bytes] + 29 UDP 192.168.2.4:52794 <-> 31.13.79.192:3478 [proto: 78.119/STUN.Facebook][5 pkts/676 bytes] + 30 TCP 192.168.2.4:49173 <-> 93.186.135.82:80 [proto: 7/HTTP][3 pkts/198 bytes] + 31 TCP 192.168.2.4:49194 <-> 93.62.150.157:443 [proto: 91/SSL][3 pkts/198 bytes] + 32 UDP 0.0.0.0:68 <-> 255.255.255.255:67 [proto: 18/DHCP][10 pkts/3420 bytes][Host: lucas-imac] + 33 UDP 192.168.2.4:51518 <-> 91.253.176.65:9344 [proto: 189/WhatsAppVoice][464 pkts/52920 bytes] + 34 TCP 192.168.2.4:49202 <-> 184.173.179.37:5222 [proto: 142/WhatsApp][180 pkts/24874 bytes] + 35 UDP 192.168.2.1:57621 <-> 192.168.2.255:57621 [proto: 156/Spotify][3 pkts/258 bytes] + 36 UDP 192.168.2.4:52190 <-> 192.168.2.1:53 [proto: 5.142/DNS.WhatsApp][2 pkts/280 bytes][Host: e13.whatsapp.net] + 37 TCP 192.168.2.4:49174 <-> 5.178.42.26:80 [proto: 7/HTTP][3 pkts/198 bytes] + 38 TCP 192.168.2.4:49163 <-> 17.154.66.111:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 39 TCP 192.168.2.4:49175 <-> 17.172.100.53:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 40 TCP 192.168.2.4:49165 <-> 17.172.100.55:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 41 TCP 192.168.2.4:49164 <-> 17.167.142.31:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 42 TCP 192.168.2.4:49167 <-> 17.172.100.8:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 43 TCP 192.168.2.4:49201 <-> 17.178.104.12:443 [proto: 91.140/SSL.Apple][38 pkts/17220 bytes][client: query.ess.apple.com] + 44 TCP 192.168.2.4:49191 <-> 17.172.100.49:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 45 TCP 192.168.2.4:49181 <-> 17.172.100.37:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 46 TCP 192.168.2.4:49198 <-> 17.167.142.13:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 47 TCP 192.168.2.4:49200 <-> 17.167.142.13:443 [proto: 91.140/SSL.Apple][3 pkts/162 bytes] + 48 TCP 192.168.2.4:49203 <-> 17.178.104.14:443 [proto: 91.140/SSL.Apple][3 pkts/198 bytes] + 49 TCP 192.168.2.4:49204 <-> 17.173.66.102:443 [proto: 91.145/SSL.AppleiTunes][53 pkts/18382 bytes][client: p53-buy.itunes.apple.com] + 50 TCP 192.168.2.4:49199 <-> 17.172.100.70:993 [proto: 51.140/IMAPS.Apple][17 pkts/1998 bytes] + 51 TCP 192.168.2.4:49193 <-> 17.110.229.14:5223 [proto: 140/Apple][22 pkts/5926 bytes] + 52 UDP 169.254.166.207:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][2 pkts/218 bytes] + 53 UDP 192.168.2.1:5353 <-> 224.0.0.251:5353 [proto: 8/MDNS][2 pkts/218 bytes] + 54 TCP 192.168.2.4:49192 <-> 93.186.135.8:80 [proto: 7/HTTP][5 pkts/330 bytes] + 55 UDP [fe80::c42c:3ff:fe60:6a64]:5353 <-> [ff02::fb]:5353 [proto: 8/MDNS][2 pkts/258 bytes] + + +Undetected flows: + 1 UDP 192.168.2.4:51518 <-> 1.194.90.191:60312 [proto: 0/Unknown][15 pkts/1290 bytes] + 2 UDP 192.168.2.4:52794 <-> 1.194.90.191:51727 [proto: 0/Unknown][12 pkts/1032 bytes] diff --git a/wireshark/ndpi.lua b/wireshark/ndpi.lua index 2065d2335..177e0f121 100644 --- a/wireshark/ndpi.lua +++ b/wireshark/ndpi.lua @@ -15,8 +15,36 @@ fds.name = ProtoField.new("nDPI Protocol Name", "ndpi.protocol.name", ftypes.STR local f_eth_trailer = Field.new("eth.trailer") +local ndpi_protos = {} +local ndpi_senders = {} +local ndpi_receivers = {} + -- ############################################### +function ndpi_proto.init() + ndpi_protos = {} + ndpi_senders = {} + ndpi_receivers = {} +end + +function slen(str) + local i = 1 + local len = 0 + local zero = string.char(0) + + for i = 1, 16 do + local c = str:sub(i,i) + + if(c ~= zero) then + len = len + 1 + else + break + end + end + + return(str:sub(1, len)) +end + -- the dissector function callback function ndpi_proto.dissector(tvb, pinfo, tree) local pktlen = tvb:len() @@ -28,8 +56,9 @@ function ndpi_proto.dissector(tvb, pinfo, tree) local network_protocol = tvb(pktlen-24,2) local application_protocol = tvb(pktlen-22,2) local name = tvb(pktlen-20,16) - local name_str = name:string(ENC_UTF_8) - + local name_str = name:string(ENC_ASCII) + local key + ndpi_subtree:add(fds.network_protocol, network_protocol) ndpi_subtree:add(fds.application_protocol, application_protocol) ndpi_subtree:add(fds.name, name) @@ -39,9 +68,111 @@ function ndpi_proto.dissector(tvb, pinfo, tree) -- Set protocol name in the wireshark protocol column (if not Unknown) pinfo.cols.protocol = name_str end + + key = tostring(slen(name_str)) + if(ndpi_protos[key] == nil) then ndpi_protos[key] = 0 end + ndpi_protos[key] = ndpi_protos[key] + pinfo.len + + key = tostring(pinfo.src) + if(ndpi_senders[key] == nil) then ndpi_senders[key] = 0 end + ndpi_senders[key] = ndpi_senders[key] + pinfo.len + + key = tostring(pinfo.dst) + if(ndpi_receivers[key] == nil) then ndpi_receivers[key] = 0 end + ndpi_receivers[key] = ndpi_receivers[key] + pinfo.len end end register_postdissector(ndpi_proto) -- ############################################### + +function round(num, idp) return tonumber(string.format("%." .. (idp or 0) .. "f", num)) end + +-- Convert bytes to human readable format +function bytesToSize(bytes) + if(bytes == nil) then + return("0") + else + precision = 2 + kilobyte = 1024; + megabyte = kilobyte * 1024; + gigabyte = megabyte * 1024; + terabyte = gigabyte * 1024; + + bytes = tonumber(bytes) + if((bytes >= 0) and (bytes < kilobyte)) then + return round(bytes, precision) .. " Bytes"; + elseif((bytes >= kilobyte) and (bytes < megabyte)) then + return round(bytes / kilobyte, precision) .. ' KB'; + elseif((bytes >= megabyte) and (bytes < gigabyte)) then + return round(bytes / megabyte, precision) .. ' MB'; + elseif((bytes >= gigabyte) and (bytes < terabyte)) then + return round(bytes / gigabyte, precision) .. ' GB'; + elseif(bytes >= terabyte) then + return round(bytes / terabyte, precision) .. ' TB'; + else + return round(bytes, precision) .. ' Bytes'; + end + end +end + +function pairsByValues(t, f) + local a = {} + for n in pairs(t) do table.insert(a, n) end + table.sort(a, function(x, y) return f(t[x], t[y]) end) + local i = 0 -- iterator variable + local iter = function () -- iterator function + i = i + 1 + if a[i] == nil then return nil + else return a[i], t[a[i]] + end + end + return iter +end + +function asc(a,b) return (a < b) end +function rev(a,b) return (a > b) end + +local function ndpi_dialog_menu() + local win = TextWindow.new("nDPI Protocol Statistics"); + local label = "" + local i + local max_i = 10 + + if(ndpi_protos ~= {}) then + label = "nDPI Protocol Breakdown\n" + label = label .. "-----------------------\n" + + i = 0 + for k,v in pairsByValues(ndpi_protos, rev) do + -- label = label .. k .. "\t".. bytesToSize(v) .. "\n" + label = label .. string.format("%-24s\t%s\n", k, bytesToSize(v)) + if(i == max_i) then break else i = i + 1 end + end + + -- ####### + + label = label .. "\nTop Senders\n" + label = label .. "-----------\n" + i = 0 + for k,v in pairsByValues(ndpi_senders, rev) do + label = label .. string.format("%-24s\t%s\n", k, bytesToSize(v)) + if(i == max_i) then break else i = i + 1 end + end + + -- ####### + + label = label .. "\nTop Receivers\n" + label = label .. "-------------\n" + i = 0 + for k,v in pairsByValues(ndpi_receivers, rev) do + label = label .. string.format("%-24s\t%s\n", k, bytesToSize(v)) + if(i == max_i) then break else i = i + 1 end + end + + win:set(label) + end +end + +register_menu("nDPI", ndpi_dialog_menu, MENU_STAT_UNSORTED) -- cgit v1.2.3 From 6c2c885176c6f102f15fc6b781525c23b1435cb7 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Tue, 25 Apr 2017 10:42:03 +0200 Subject: Extcap crash fix --- example/ndpiReader.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index e23e0c1f9..cd83b9ff5 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -97,7 +97,7 @@ struct ndpi_packet_trailer { }; static pcap_dumper_t *extcap_dumper = NULL; -static char extcap_buf[2048]; +static char extcap_buf[16384]; static char *extcap_capture_fifo = NULL; static u_int16_t extcap_packet_filter = (u_int16_t)-1; @@ -296,13 +296,6 @@ void extcap_capture() { #ifdef DEBUG_TRACE if(trace) fprintf(trace, "Starting packet capture [%p]\n", extcap_dumper); #endif - - test_lib(); - pcap_dump_close(extcap_dumper); - -#ifdef DEBUG_TRACE - if(trace) fprintf(trace, "End of packet capture [%p]\n", extcap_dumper); -#endif } /* ********************************** */ @@ -1494,31 +1487,39 @@ static void pcap_packet_callback_checked(u_char *args, || (p.master_protocol == extcap_packet_filter) ) ) { - struct pcap_pkthdr *h = (struct pcap_pkthdr*)header; + struct pcap_pkthdr h; uint32_t *crc, delta = sizeof(struct ndpi_packet_trailer) + 4 /* ethernet trailer */; - struct ndpi_packet_trailer *trailer = (struct ndpi_packet_trailer*)&extcap_buf[h->caplen]; + struct ndpi_packet_trailer *trailer; - memcpy(extcap_buf, packet, h->caplen); + memcpy(&h, header, sizeof(h)); + + if(h.caplen > (sizeof(extcap_buf)-sizeof(struct ndpi_packet_trailer) - 4)) { + printf("INTERNAL ERROR: caplen=%u\n", h.caplen); + h.caplen = sizeof(extcap_buf)-sizeof(struct ndpi_packet_trailer) - 4; + } + + trailer = (struct ndpi_packet_trailer*)&extcap_buf[h.caplen]; + memcpy(extcap_buf, packet, h.caplen); memset(trailer, 0, sizeof(struct ndpi_packet_trailer)); trailer->magic = htonl(0x19680924); trailer->master_protocol = htons(p.master_protocol), trailer->app_protocol = htons(p.app_protocol); ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, p, trailer->name, sizeof(trailer->name)); - crc = (uint32_t*)&extcap_buf[h->caplen+sizeof(struct ndpi_packet_trailer)]; + crc = (uint32_t*)&extcap_buf[h.caplen+sizeof(struct ndpi_packet_trailer)]; *crc = 0; - ethernet_crc32((const void*)extcap_buf, h->caplen+sizeof(struct ndpi_packet_trailer), crc); - h->caplen += delta, h->len += delta; + ethernet_crc32((const void*)extcap_buf, h.caplen+sizeof(struct ndpi_packet_trailer), crc); + h.caplen += delta, h.len += delta; #ifdef DEBUG_TRACE - if(trace) fprintf(trace, "Dumping %u bytes packet\n", header->caplen); + if(trace) fprintf(trace, "Dumping %u bytes packet\n", h.caplen); #endif - pcap_dump((u_char*)extcap_dumper, h, (const u_char *)extcap_buf); + pcap_dump((u_char*)extcap_dumper, &h, (const u_char *)extcap_buf); } /* check for buffer changes */ if(memcmp(packet, packet_checked, header->caplen) != 0) - printf("INTERNAL ERROR: ingress packet was modified by nDPI: this should not happen [thread_id=%u, packetId=%lu]\n", - thread_id, (unsigned long)ndpi_thread_info[thread_id].workflow->stats.raw_packet_count); + printf("INTERNAL ERROR: ingress packet was modified by nDPI: this should not happen [thread_id=%u, packetId=%lu, caplen=%u]\n", + thread_id, (unsigned long)ndpi_thread_info[thread_id].workflow->stats.raw_packet_count, header->caplen); free(packet_checked); } @@ -1685,9 +1686,10 @@ int main(int argc, char **argv) { for(i=0; i Date: Tue, 25 Apr 2017 11:21:40 +0200 Subject: Improced extcap configuration window with sorted protocol list Reported flow stats in Statistics -> nDPI menu --- example/ndpiReader.c | 41 ++++++++++++++++++++++++++++++-------- wireshark/ndpi.lua | 56 ++++++++++++++++++++++++---------------------------- 2 files changed, 59 insertions(+), 38 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index cd83b9ff5..1f982b60b 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -246,10 +246,23 @@ void extcap_dlts() { /* ********************************** */ +struct ndpi_proto_sorter { + int id; + char name[16]; +}; + +int cmpProto(const void *_a, const void *_b) { + struct ndpi_proto_sorter *a = (struct ndpi_proto_sorter*)_a; + struct ndpi_proto_sorter *b = (struct ndpi_proto_sorter*)_b; + + return(strcmp(a->name, b->name)); +} + void extcap_config() { int i, argidx = 0; struct ndpi_detection_module_struct *ndpi_mod; - + struct ndpi_proto_sorter *protos; + /* -i */ printf("arg {number=%u}{call=-i}{display=Capture Interface or Pcap File Path}{type=string}" "{tooltip=The interface name}\n", argidx++); @@ -258,20 +271,31 @@ void extcap_config() { printf("arg {number=%u}{call=-i}{display=Pcap File to Analize}{type=fileselect}" "{tooltip=The pcap file to analyze (if the interface is unspecified)}\n", argidx++); #endif + + setupDetection(0, NULL); + ndpi_mod = ndpi_thread_info[0].workflow->ndpi_struct; + + protos = (struct ndpi_proto_sorter*)malloc(sizeof(struct ndpi_proto_sorter)*ndpi_mod->ndpi_num_supported_protocols); + if(!protos) exit(0); + + for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) { + protos[i].id = i; + snprintf(protos[i].name, sizeof(protos[i].name), "%s", ndpi_mod->proto_defaults[i].protoName); + } + qsort(protos, ndpi_mod->ndpi_num_supported_protocols, sizeof(struct ndpi_proto_sorter), cmpProto); printf("arg {number=%u}{call=-9}{display=nDPI Protocol Filter}{type=selector}" "{tooltip=nDPI Protocol to be filtered}\n", argidx); - setupDetection(0, NULL); - ndpi_mod = ndpi_thread_info[0].workflow->ndpi_struct; - printf("value {arg=%d}{value=%d}{display=%s}\n", argidx, -1, "All Protocols (no nDPI filtering)"); - + for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) - printf("value {arg=%d}{value=%d}{display=%s (%u)}\n", argidx, i, - ndpi_mod->proto_defaults[i].protoName, i); + printf("value {arg=%d}{value=%d}{display=%s (%u)}\n", argidx, protos[i].id, + protos[i].name, protos[i].id); + free(protos); + exit(0); } @@ -1507,13 +1531,14 @@ static void pcap_packet_callback_checked(u_char *args, crc = (uint32_t*)&extcap_buf[h.caplen+sizeof(struct ndpi_packet_trailer)]; *crc = 0; ethernet_crc32((const void*)extcap_buf, h.caplen+sizeof(struct ndpi_packet_trailer), crc); - h.caplen += delta, h.len += delta; + h.caplen += delta, h.len += delta; #ifdef DEBUG_TRACE if(trace) fprintf(trace, "Dumping %u bytes packet\n", h.caplen); #endif pcap_dump((u_char*)extcap_dumper, &h, (const u_char *)extcap_buf); + pcap_dump_flush(extcap_dumper); } /* check for buffer changes */ diff --git a/wireshark/ndpi.lua b/wireshark/ndpi.lua index 177e0f121..3d35c9083 100644 --- a/wireshark/ndpi.lua +++ b/wireshark/ndpi.lua @@ -15,16 +15,15 @@ fds.name = ProtoField.new("nDPI Protocol Name", "ndpi.protocol.name", ftypes.STR local f_eth_trailer = Field.new("eth.trailer") -local ndpi_protos = {} -local ndpi_senders = {} -local ndpi_receivers = {} +local ndpi_protos = {} +local ndpi_flows = {} +local compute_flows_stats = true -- ############################################### function ndpi_proto.init() ndpi_protos = {} - ndpi_senders = {} - ndpi_receivers = {} + ndpi_flows = {} end function slen(str) @@ -57,7 +56,7 @@ function ndpi_proto.dissector(tvb, pinfo, tree) local application_protocol = tvb(pktlen-22,2) local name = tvb(pktlen-20,16) local name_str = name:string(ENC_ASCII) - local key + local ndpikey, srckey, dstkey, flowkey ndpi_subtree:add(fds.network_protocol, network_protocol) ndpi_subtree:add(fds.application_protocol, application_protocol) @@ -69,17 +68,22 @@ function ndpi_proto.dissector(tvb, pinfo, tree) pinfo.cols.protocol = name_str end - key = tostring(slen(name_str)) - if(ndpi_protos[key] == nil) then ndpi_protos[key] = 0 end - ndpi_protos[key] = ndpi_protos[key] + pinfo.len + if(compute_flows_stats) then + ndpikey = tostring(slen(name_str)) - key = tostring(pinfo.src) - if(ndpi_senders[key] == nil) then ndpi_senders[key] = 0 end - ndpi_senders[key] = ndpi_senders[key] + pinfo.len + if(ndpi_protos[ndpikey] == nil) then ndpi_protos[ndpikey] = 0 end + ndpi_protos[ndpikey] = ndpi_protos[ndpikey] + pinfo.len + + srckey = tostring(pinfo.src) + dstkey = tostring(pinfo.dst) + + flowkey = srckey.." / "..dstkey.." ["..ndpikey.."]" + if(ndpi_flows[flowkey] == nil) then + ndpi_flows[flowkey] = 0 + end - key = tostring(pinfo.dst) - if(ndpi_receivers[key] == nil) then ndpi_receivers[key] = 0 end - ndpi_receivers[key] = ndpi_receivers[key] + pinfo.len + ndpi_flows[flowkey] = ndpi_flows[flowkey] + pinfo.len + end end end @@ -147,27 +151,17 @@ local function ndpi_dialog_menu() i = 0 for k,v in pairsByValues(ndpi_protos, rev) do -- label = label .. k .. "\t".. bytesToSize(v) .. "\n" - label = label .. string.format("%-24s\t%s\n", k, bytesToSize(v)) + label = label .. string.format("%-32s\t%s\n", k, bytesToSize(v)) if(i == max_i) then break else i = i + 1 end end -- ####### - label = label .. "\nTop Senders\n" + label = label .. "\nTop nDPI Flows\n" label = label .. "-----------\n" i = 0 - for k,v in pairsByValues(ndpi_senders, rev) do - label = label .. string.format("%-24s\t%s\n", k, bytesToSize(v)) - if(i == max_i) then break else i = i + 1 end - end - - -- ####### - - label = label .. "\nTop Receivers\n" - label = label .. "-------------\n" - i = 0 - for k,v in pairsByValues(ndpi_receivers, rev) do - label = label .. string.format("%-24s\t%s\n", k, bytesToSize(v)) + for k,v in pairsByValues(ndpi_flows, rev) do + label = label .. string.format("%-32s\t%s\n", k, bytesToSize(v)) if(i == max_i) then break else i = i + 1 end end @@ -175,4 +169,6 @@ local function ndpi_dialog_menu() end end -register_menu("nDPI", ndpi_dialog_menu, MENU_STAT_UNSORTED) +if(compute_flows_stats) then + register_menu("nDPI", ndpi_dialog_menu, MENU_STAT_UNSORTED) +end -- cgit v1.2.3 From 064b50df819918734062294984e529bd62bd594c Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Sun, 30 Apr 2017 10:12:28 +0200 Subject: Added -m for splitting analysis in sub-analysis steps --- example/ndpiReader.c | 102 ++++++++++++++++++++++++++++++++------------------- example/ndpi_util.c | 2 +- example/ndpi_util.h | 1 + 3 files changed, 67 insertions(+), 38 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 1f982b60b..59ca8b3a1 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -69,10 +69,12 @@ static u_int8_t live_capture = 0; static u_int8_t undetected_flows_deleted = 0; /** User preferences **/ static u_int8_t enable_protocol_guess = 1, verbose = 0, nDPI_traceLevel = 0, json_flag = 0; +static u_int32_t pcap_analysis_duration = (u_int32_t)-1; 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 struct timeval begin, end; #ifdef linux static int core_affinity[MAX_NUM_READER_THREADS]; #endif @@ -146,13 +148,14 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle); static void help(u_int long_help) { printf("Welcome to nDPI %s\n\n", ndpi_revision()); - printf("ndpiReader -i [-f ][-s ]\n" + printf("ndpiReader -i [-f ][-s ][-m ]\n" " [-p ][-l [-q][-d][-h][-t][-v ]\n" " [-n ] [-w ] [-j ]\n\n" "Usage:\n" " -i | Specify a pcap file/playlist to read packets from or a device for live capture (comma-separated list)\n" " -f | Specify a BPF filter for filtering selected traffic\n" " -s | Maximum capture duration in seconds (live traffic capture only)\n" + " -m | Split analysis duration in max seconds\n" " -p .protos | Specify a protocol file (eg. protos.txt)\n" " -l | Number of detection loops (test only)\n" " -n | Number of threads. Default: number of interfaces in -i. Ignored with pcap files.\n" @@ -262,7 +265,7 @@ void extcap_config() { int i, argidx = 0; struct ndpi_detection_module_struct *ndpi_mod; struct ndpi_proto_sorter *protos; - + /* -i */ printf("arg {number=%u}{call=-i}{display=Capture Interface or Pcap File Path}{type=string}" "{tooltip=The interface name}\n", argidx++); @@ -271,12 +274,12 @@ void extcap_config() { printf("arg {number=%u}{call=-i}{display=Pcap File to Analize}{type=fileselect}" "{tooltip=The pcap file to analyze (if the interface is unspecified)}\n", argidx++); #endif - + setupDetection(0, NULL); ndpi_mod = ndpi_thread_info[0].workflow->ndpi_struct; - + protos = (struct ndpi_proto_sorter*)malloc(sizeof(struct ndpi_proto_sorter)*ndpi_mod->ndpi_num_supported_protocols); - if(!protos) exit(0); + if(!protos) exit(0); for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) { protos[i].id = i; @@ -284,18 +287,18 @@ void extcap_config() { } qsort(protos, ndpi_mod->ndpi_num_supported_protocols, sizeof(struct ndpi_proto_sorter), cmpProto); - + printf("arg {number=%u}{call=-9}{display=nDPI Protocol Filter}{type=selector}" "{tooltip=nDPI Protocol to be filtered}\n", argidx); printf("value {arg=%d}{value=%d}{display=%s}\n", argidx, -1, "All Protocols (no nDPI filtering)"); - + for(i=0; i<(int)ndpi_mod->ndpi_num_supported_protocols; i++) printf("value {arg=%d}{value=%d}{display=%s (%u)}\n", argidx, protos[i].id, protos[i].name, protos[i].id); free(protos); - + exit(0); } @@ -341,7 +344,7 @@ static void parseOptions(int argc, char **argv) { if(trace) fprintf(trace, " #### %s #### \n", __FUNCTION__); #endif - while ((opt = getopt_long(argc, argv, "df:g:i:hp:l:s:tv:V:n:j:rp:w:q0123:456:7:89:", longopts, &option_idx)) != EOF) { + while ((opt = getopt_long(argc, argv, "df:g:i:hp:l:s:tv:V:n:j:rp:w:q0123:456:7:89:m:", longopts, &option_idx)) != EOF) { #ifdef DEBUG_TRACE if(trace) fprintf(trace, " #### -%c [%s] #### \n", opt, optarg ? optarg : ""); #endif @@ -356,6 +359,10 @@ static void parseOptions(int argc, char **argv) { _pcap_file[0] = optarg; break; + case 'm': + pcap_analysis_duration = atol(optarg); + break; + case 'f': case '6': _bpf_filter = optarg; @@ -580,7 +587,7 @@ static void printFlow(u_int16_t thread_id, struct ndpi_flow_info *flow) { if((verbose != 1) && (verbose != 2)) return; - + if(!json_flag) { fprintf(out, "\t%u", ++num_flows); @@ -937,7 +944,6 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) { * @brief End of detection and free flow */ static void terminateDetection(u_int16_t thread_id) { - ndpi_workflow_free(ndpi_thread_info[thread_id].workflow); } @@ -1047,12 +1053,12 @@ static int port_stats_sort(void *_a, void *_b) { void printPortStats(struct port_stats *stats) { struct port_stats *s, *tmp; int i = 0; - + HASH_ITER(hh, stats, s, tmp) { i++; printf("\t%2d\tPort %5u\t[%u pkts/%u bytes]\n", i, s->port, s->num_pkts, s->num_bytes); if(i >= 10) break; - } + } } /* *********************************************** */ @@ -1061,7 +1067,6 @@ void printPortStats(struct port_stats *stats) { * @brief Print result */ static void printResults(u_int64_t tot_usec) { - u_int32_t i; u_int64_t total_flow_bytes = 0; u_int32_t avg_pkt_size = 0; @@ -1073,10 +1078,10 @@ static void printResults(u_int64_t tot_usec) { json_object *jObj_main = NULL, *jObj_trafficStats, *jArray_detProto = NULL, *jObj; #endif long long unsigned int breed_stats[NUM_BREEDS] = { 0 }; - + memset(&cumulative_stats, 0, sizeof(cumulative_stats)); - for(thread_id = 0; thread_id < num_threads; thread_id++) { + for(thread_id = 0; thread_id < num_threads; thread_id++) { if((ndpi_thread_info[thread_id].workflow->stats.total_wire_bytes == 0) && (ndpi_thread_info[thread_id].workflow->stats.raw_packet_count == 0)) continue; @@ -1090,7 +1095,7 @@ static void printResults(u_int64_t tot_usec) { HASH_SORT(srcStats, port_stats_sort); HASH_SORT(dstStats, port_stats_sort); } - + /* Stats aggregation */ 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; @@ -1117,6 +1122,8 @@ static void printResults(u_int64_t tot_usec) { cumulative_stats.max_packet_len += ndpi_thread_info[thread_id].workflow->stats.max_packet_len; } + if(cumulative_stats.total_wire_bytes == 0) return; + if(!quiet_mode) { printf("\nnDPI Memory statistics:\n"); printf("\tnDPI Memory (once): %-13s\n", formatBytes(sizeof(struct ndpi_detection_module_struct), buf, sizeof(buf))); @@ -1155,7 +1162,7 @@ static void printResults(u_int64_t tot_usec) { printf("\tPacket Len > 1500: %-13lu\n", (unsigned long)cumulative_stats.packet_len[5]); if(tot_usec > 0) { - char buf[32], buf1[32]; + char buf[32], buf1[32], when[64]; float t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)tot_usec; float b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)tot_usec; float traffic_duration; @@ -1164,6 +1171,11 @@ static void printResults(u_int64_t tot_usec) { printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)traffic_duration; + + strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", localtime(&pcap_start.tv_sec)); + printf("\tAnalysis begin: %s\n", when); + strftime(when, sizeof(when), "%d/%b/%Y %H:%M:%S", localtime(&pcap_end.tv_sec)); + printf("\tAnalysis end: %s\n", when); printf("\tTraffic throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); printf("\tTraffic duration: %.3f sec\n", traffic_duration/1000000); } @@ -1315,11 +1327,12 @@ static void printResults(u_int64_t tot_usec) { if(verbose == 3) { printf("\n\nSource Ports Stats:\n"); printPortStats(srcStats); - + printf("\nDestination Ports Stats:\n"); printPortStats(dstStats); - + deletePortsStats(srcStats), deletePortsStats(dstStats); + srcStats = NULL, dstStats = NULL; } } @@ -1328,14 +1341,11 @@ static void printResults(u_int64_t tot_usec) { * @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].workflow->pcap_handle != NULL) { pcap_breakloop(ndpi_thread_info[thread_id].workflow->pcap_handle); } } - - /** * @brief Sigproc is executed for each packet in the pcap file */ @@ -1453,9 +1463,9 @@ static pcap_t * openPcapFileOrDevice(u_int16_t thread_id, const u_char * pcap_fi /** * @brief Check pcap packet */ -static void pcap_packet_callback_checked(u_char *args, - const struct pcap_pkthdr *header, - const u_char *packet) { +static void pcap_process_packet(u_char *args, + const struct pcap_pkthdr *header, + const u_char *packet) { struct ndpi_proto p; u_int16_t thread_id = *((u_int16_t*)args); @@ -1516,13 +1526,13 @@ static void pcap_packet_callback_checked(u_char *args, struct ndpi_packet_trailer *trailer; memcpy(&h, header, sizeof(h)); - + if(h.caplen > (sizeof(extcap_buf)-sizeof(struct ndpi_packet_trailer) - 4)) { printf("INTERNAL ERROR: caplen=%u\n", h.caplen); - h.caplen = sizeof(extcap_buf)-sizeof(struct ndpi_packet_trailer) - 4; + h.caplen = sizeof(extcap_buf)-sizeof(struct ndpi_packet_trailer) - 4; } - trailer = (struct ndpi_packet_trailer*)&extcap_buf[h.caplen]; + trailer = (struct ndpi_packet_trailer*)&extcap_buf[h.caplen]; memcpy(extcap_buf, packet, h.caplen); memset(trailer, 0, sizeof(struct ndpi_packet_trailer)); trailer->magic = htonl(0x19680924); @@ -1546,6 +1556,28 @@ static void pcap_packet_callback_checked(u_char *args, printf("INTERNAL ERROR: ingress packet was modified by nDPI: this should not happen [thread_id=%u, packetId=%lu, caplen=%u]\n", thread_id, (unsigned long)ndpi_thread_info[thread_id].workflow->stats.raw_packet_count, header->caplen); free(packet_checked); + + if((pcap_end.tv_sec-pcap_start.tv_sec) > pcap_analysis_duration) { + int i; + u_int64_t tot_usec; + + gettimeofday(&end, NULL); + tot_usec = end.tv_sec*1000000 + end.tv_usec - (begin.tv_sec*1000000 + begin.tv_usec); + + printResults(tot_usec); + + for(i=0; iprefs.num_roots; i++) { + ndpi_tdestroy(ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i], ndpi_flow_info_freer); + ndpi_thread_info[thread_id].workflow->ndpi_flows_root[i] = NULL; + + memset(&ndpi_thread_info[thread_id].workflow->stats, 0, sizeof(struct ndpi_stats)); + } + + printf("\n-------------------------------------------\n\n"); + + memcpy(&begin, &end, sizeof(begin)); + memcpy(&pcap_start, &pcap_end, sizeof(pcap_start)); + } } @@ -1553,12 +1585,10 @@ static void pcap_packet_callback_checked(u_char *args, * @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].workflow->pcap_handle != NULL)) - pcap_loop(ndpi_thread_info[thread_id].workflow->pcap_handle, -1, &pcap_packet_callback_checked, (u_char*)&thread_id); + pcap_loop(ndpi_thread_info[thread_id].workflow->pcap_handle, -1, &pcap_process_packet, (u_char*)&thread_id); } - /** * @brief Process a running thread */ @@ -1583,7 +1613,7 @@ void * processing_thread(void *_thread_id) { if((!json_flag) && (!quiet_mode)) printf("Running thread %ld...\n", thread_id); pcap_loop: - runPcapLoop(thread_id); + runPcapLoop(thread_id); if(playlist_fp[thread_id] != NULL) { /* playlist: read next file */ char filename[256]; @@ -1603,7 +1633,7 @@ void * processing_thread(void *_thread_id) { * @brief Begin, process, end detection process */ void test_lib() { - struct timeval begin, end; + struct timeval end; u_int64_t tot_usec; long thread_id; @@ -1690,8 +1720,6 @@ int main(int argc, char **argv) { automataUnitTest(); memset(ndpi_thread_info, 0, sizeof(ndpi_thread_info)); - memset(&pcap_start, 0, sizeof(pcap_start)); - memset(&pcap_end, 0, sizeof(pcap_end)); parseOptions(argc, argv); @@ -1714,7 +1742,7 @@ int main(int argc, char **argv) { if(results_path) free(results_path); if(results_file) fclose(results_file); if(extcap_dumper) pcap_dump_close(extcap_dumper); - + return 0; } diff --git a/example/ndpi_util.c b/example/ndpi_util.c index eb6744ccc..1ba77eb80 100644 --- a/example/ndpi_util.c +++ b/example/ndpi_util.c @@ -129,7 +129,7 @@ struct ndpi_workflow * ndpi_workflow_init(const struct ndpi_workflow_prefs * pre /* ***************************************************** */ -static void ndpi_flow_info_freer(void *node) { +void ndpi_flow_info_freer(void *node) { struct ndpi_flow_info *flow = (struct ndpi_flow_info*)node; ndpi_free_flow_info_half(flow); diff --git a/example/ndpi_util.h b/example/ndpi_util.h index 335c94ddf..9d8f1e446 100644 --- a/example/ndpi_util.h +++ b/example/ndpi_util.h @@ -161,4 +161,5 @@ static inline void ndpi_workflow_set_flow_giveup_callback(struct ndpi_workflow * int ndpi_workflow_node_cmp(const void *a, const void *b); void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow); void ethernet_crc32(const void* data, size_t n_bytes, uint32_t* crc); +void ndpi_flow_info_freer(void *node); #endif -- cgit v1.2.3 From 4030b52ecb5c7a98eeb3eadc362eab60521fb565 Mon Sep 17 00:00:00 2001 From: berat Date: Mon, 1 May 2017 14:07:41 +0200 Subject: Added IP Statistics to Port Stats --- example/ndpiReader.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++--- example/ndpi_util.h | 3 +- 2 files changed, 172 insertions(+), 10 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 59ca8b3a1..63e33d783 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -84,9 +84,24 @@ static time_t capture_for = 0; static time_t capture_until = 0; static u_int32_t num_flows; +struct info_pair{ + u_int32_t addr; + int count; +}; + +typedef struct node_a{ + u_int32_t addr; + int count; + struct node_a *left, *right; +}addr_node; + struct port_stats { u_int32_t port; /* we'll use this field as the key */ u_int32_t num_pkts, num_bytes; + u_int32_t num_addr; /*to hold number of distinct IP addresses*/ + u_int32_t cumulative_addr; /*to hold cumulative some of IP addresses*/ + addr_node *addr_tree; /* to hold distinct IP addresses*/ + struct info_pair top_ip_addrs[MAX_NUM_IP_ADDRESS]; UT_hash_handle hh; /* makes this structure hashable */ }; @@ -136,6 +151,9 @@ FILE *trace = NULL; /********************** FUNCTIONS ********************* */ + + + /** * @brief Set main components necessary to the detection */ @@ -764,8 +782,99 @@ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int dept /* *********************************************** */ -static void updatePortStats(struct port_stats **stats, u_int32_t port, u_int32_t num_pkts, u_int32_t num_bytes) { +int updateIpTree(const u_int32_t key, addr_node **vrootp){ + addr_node *q; + addr_node **rootp = vrootp; + + if(rootp == (addr_node **)0) + return 0; + + while (*rootp != (addr_node *)0) { /* Knuth's T1: */ + + if(key == ((*rootp)->addr)) { /* T2: */ + return ++((*rootp)->count); + } + + rootp = (key < ((*rootp)->addr)) ? + &(*rootp)->left : /* T3: follow left branch */ + &(*rootp)->right; /* T4: follow right branch */ + } + q = (addr_node *) malloc(sizeof(addr_node)); /* T5: key not found */ + if(q != (addr_node *)0) { /* make new node */ + *rootp = q; /* link new node to old */ + q->addr = key; /* initialize new node */ + q->count = 1; + q->left = q->right = (addr_node *)0; + return q->count; + } + +} + +/* *********************************************** */ + +void freeIpTree(addr_node *root) { + while (root != NULL) { + addr_node *left = root->left; + if (left == NULL) { + addr_node *right = root->right; + root->right = NULL; + root = right; + } else { + /* Rotate the left child up.*/ + root->left = left->right; + left->right = root; + root = left; + } + } +} + +/* *********************************************** */ + +void updateTopIpAddress(u_int32_t addr, int count, struct info_pair top[], int size){ + int update = 0; + int min_i = 0; + int min = count; + + if(count == 0) return; + + struct info_pair pair; + pair.addr = addr, pair.count = count; + + /* if the same ip with a bigger + count just update it */ + for(int i=0; iport = port, s->num_pkts = 0, s->num_bytes = 0; + s->num_addr = 1, s->cumulative_addr = 1; + + memset(s->top_ip_addrs, 0, MAX_NUM_IP_ADDRESS*sizeof(struct info_pair)); + updateTopIpAddress(addr, 1, s->top_ip_addrs, MAX_NUM_IP_ADDRESS); + + s->addr_tree = (addr_node *) malloc(sizeof(addr_node)); + if(!s->addr_tree) return; + + s->addr_tree->addr = addr; + s->addr_tree->count = 1; + s->addr_tree->left = NULL; + s->addr_tree->right = NULL; + HASH_ADD_INT(*stats, port, s); } + int count = updateIpTree(addr, &(*s).addr_tree); + if(count == UPDATED_TREE) s->num_addr++; + if(count) { + s->cumulative_addr++; + updateTopIpAddress(addr, count, s->top_ip_addrs, MAX_NUM_IP_ADDRESS); + } + s->num_pkts += num_pkts, s->num_bytes += num_bytes; + } /* *********************************************** */ @@ -786,6 +916,8 @@ static void deletePortsStats(struct port_stats *stats) { HASH_ITER(hh, stats, current_port, tmp) { HASH_DEL(stats, current_port); + freeIpTree(current_port->addr_tree); + free(current_port->addr_tree); free(current_port); } } @@ -798,14 +930,18 @@ static void deletePortsStats(struct port_stats *stats) { static void port_stats_walker(const void *node, ndpi_VISIT which, int depth, void *user_data) { struct ndpi_flow_info *flow = *(struct ndpi_flow_info **) node; u_int16_t sport, dport; + u_int32_t saddr, daddr; - if(flow->src_to_dst_direction == 1) - sport = ntohs(flow->lower_port), dport = ntohs(flow->upper_port); - else - sport = ntohs(flow->upper_port), dport = ntohs(flow->lower_port); - - updatePortStats(&srcStats, sport, flow->packets, flow->bytes); - updatePortStats(&dstStats, dport, flow->packets, flow->bytes); + if(flow->src_to_dst_direction == 1) { + sport = ntohs(flow->lower_port), dport = ntohs(flow->upper_port); + saddr = flow->lower_ip, daddr = flow->upper_ip; + } + else { + sport = ntohs(flow->upper_port), dport = ntohs(flow->lower_port); + saddr = flow->upper_ip, daddr = flow->lower_ip; + } + updatePortStats(&srcStats, sport, saddr, flow->packets, flow->bytes); + updatePortStats(&dstStats, dport, daddr, flow->packets, flow->bytes); } /* *********************************************** */ @@ -1050,13 +1186,38 @@ static int port_stats_sort(void *_a, void *_b) { /* *********************************************** */ +static int info_pair_cmp (const void *_a, const void *_b) +{ + struct info_pair *a = (struct info_pair *)_a; + struct info_pair *b = (struct info_pair *)_b; + return b->count - a->count; +} + +/* *********************************************** */ + void printPortStats(struct port_stats *stats) { struct port_stats *s, *tmp; + char ip_name[48]; int i = 0; + int first = 1; + HASH_ITER(hh, stats, s, tmp) { i++; - printf("\t%2d\tPort %5u\t[%u pkts/%u bytes]\n", i, s->port, s->num_pkts, s->num_bytes); + printf("\t%2d\tPort %5u\t[%u IP address/%u pkts/%u bytes]\n", i, s->port, s->num_addr, s->num_pkts, s->num_bytes); + + qsort(&s->top_ip_addrs[0], MAX_NUM_IP_ADDRESS, sizeof(struct info_pair), info_pair_cmp); + + for(int i=0;itop_ip_addrs[i].count != 0) { + inet_ntop(AF_INET, &s->top_ip_addrs[i].addr, ip_name, sizeof(ip_name)); + printf("\t\t\t\t%s\t%s ~ %.2f%%\n", (first) ? "Top IP Stats:" : "\t", + ip_name, ((s->top_ip_addrs[i].count) * 100.0) / s->cumulative_addr); + first = 0; + } + } + printf("\n"); + first = 1; if(i >= 10) break; } } diff --git a/example/ndpi_util.h b/example/ndpi_util.h index 9d8f1e446..ca9f20274 100644 --- a/example/ndpi_util.h +++ b/example/ndpi_util.h @@ -38,7 +38,8 @@ #define NUM_ROOTS 512 #define MAX_NDPI_FLOWS 200000000 #define TICK_RESOLUTION 1000 - +#define MAX_NUM_IP_ADDRESS 5 /* len of ip address array */ +#define UPDATED_TREE 1 // flow tracking typedef struct ndpi_flow_info { -- cgit v1.2.3 From 32d02836f01c2c2938750e608c64e0c98775649b Mon Sep 17 00:00:00 2001 From: berat Date: Mon, 1 May 2017 14:37:12 +0200 Subject: fixed syntax for gcc compiler --- example/ndpiReader.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 63e33d783..8fa1b10ce 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -832,6 +832,7 @@ void freeIpTree(addr_node *root) { void updateTopIpAddress(u_int32_t addr, int count, struct info_pair top[], int size){ int update = 0; + int i; int min_i = 0; int min = count; @@ -842,7 +843,7 @@ void updateTopIpAddress(u_int32_t addr, int count, struct info_pair top[], int s /* if the same ip with a bigger count just update it */ - for(int i=0; itop_ip_addrs[0], MAX_NUM_IP_ADDRESS, sizeof(struct info_pair), info_pair_cmp); - for(int i=0;itop_ip_addrs[i].count != 0) { - inet_ntop(AF_INET, &s->top_ip_addrs[i].addr, ip_name, sizeof(ip_name)); + for(j=0; jtop_ip_addrs[j].count != 0) { + inet_ntop(AF_INET, &s->top_ip_addrs[j].addr, ip_name, sizeof(ip_name)); printf("\t\t\t\t%s\t%s ~ %.2f%%\n", (first) ? "Top IP Stats:" : "\t", - ip_name, ((s->top_ip_addrs[i].count) * 100.0) / s->cumulative_addr); + ip_name, ((s->top_ip_addrs[j].count) * 100.0) / s->cumulative_addr); first = 0; } } + printf("\n"); first = 1; + if(i >= 10) break; } } -- cgit v1.2.3 From a03a343723889c49c33c1011aac13ef61c36f7b7 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Mon, 1 May 2017 19:44:46 +0200 Subject: Minor code cleanup --- example/ndpiReader.c | 103 ++++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 51 deletions(-) (limited to 'example/ndpiReader.c') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 8fa1b10ce..ac3d75e77 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -98,9 +98,9 @@ typedef struct node_a{ struct port_stats { u_int32_t port; /* we'll use this field as the key */ u_int32_t num_pkts, num_bytes; - u_int32_t num_addr; /*to hold number of distinct IP addresses*/ - u_int32_t cumulative_addr; /*to hold cumulative some of IP addresses*/ - addr_node *addr_tree; /* to hold distinct IP addresses*/ + u_int32_t num_addr; /*to hold number of distinct IP addresses */ + u_int32_t cumulative_addr; /*to hold cumulative some of IP addresses */ + addr_node *addr_tree; /* to hold distinct IP addresses */ struct info_pair top_ip_addrs[MAX_NUM_IP_ADDRESS]; UT_hash_handle hh; /* makes this structure hashable */ }; @@ -782,50 +782,52 @@ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int dept /* *********************************************** */ -int updateIpTree(const u_int32_t key, addr_node **vrootp){ - addr_node *q; - addr_node **rootp = vrootp; +int updateIpTree(const u_int32_t key, addr_node **vrootp) { + addr_node *q; + addr_node **rootp = vrootp; - if(rootp == (addr_node **)0) - return 0; + if(rootp == (addr_node **)0) + return 0; - while (*rootp != (addr_node *)0) { /* Knuth's T1: */ + while (*rootp != (addr_node *)0) { /* Knuth's T1: */ + if(key == ((*rootp)->addr)) { /* T2: */ + return ++((*rootp)->count); + } - if(key == ((*rootp)->addr)) { /* T2: */ - return ++((*rootp)->count); - } + rootp = (key < ((*rootp)->addr)) ? + &(*rootp)->left : /* T3: follow left branch */ + &(*rootp)->right; /* T4: follow right branch */ + } - rootp = (key < ((*rootp)->addr)) ? - &(*rootp)->left : /* T3: follow left branch */ - &(*rootp)->right; /* T4: follow right branch */ - } - q = (addr_node *) malloc(sizeof(addr_node)); /* T5: key not found */ - if(q != (addr_node *)0) { /* make new node */ - *rootp = q; /* link new node to old */ - q->addr = key; /* initialize new node */ - q->count = 1; - q->left = q->right = (addr_node *)0; - return q->count; - } + q = (addr_node *) malloc(sizeof(addr_node)); /* T5: key not found */ + if(q != (addr_node *)0) { /* make new node */ + *rootp = q; /* link new node to old */ + q->addr = key; /* initialize new node */ + q->count = UPDATED_TREE; + q->left = q->right = (addr_node *)0; + return q->count; + } + return(0); } /* *********************************************** */ void freeIpTree(addr_node *root) { - while (root != NULL) { - addr_node *left = root->left; - if (left == NULL) { - addr_node *right = root->right; - root->right = NULL; - root = right; - } else { - /* Rotate the left child up.*/ - root->left = left->right; - left->right = root; - root = left; - } + while (root != NULL) { + addr_node *left = root->left; + + if(left == NULL) { + addr_node *right = root->right; + root->right = NULL; + root = right; + } else { + /* Rotate the left child up.*/ + root->left = left->right; + left->right = root; + root = left; } + } } /* *********************************************** */ @@ -844,7 +846,7 @@ void updateTopIpAddress(u_int32_t addr, int count, struct info_pair top[], int s /* if the same ip with a bigger count just update it */ for(i=0; inum_addr++; + if(count) { s->cumulative_addr++; updateTopIpAddress(addr, count, s->top_ip_addrs, MAX_NUM_IP_ADDRESS); } s->num_pkts += num_pkts, s->num_bytes += num_bytes; - } /* *********************************************** */ @@ -1199,21 +1202,19 @@ static int info_pair_cmp (const void *_a, const void *_b) void printPortStats(struct port_stats *stats) { struct port_stats *s, *tmp; char ip_name[48]; - int i = 0; - int j = 0; - int first = 1; - + int i = 0, j = 0, first = 1; HASH_ITER(hh, stats, s, tmp) { i++; - printf("\t%2d\tPort %5u\t[%u IP address/%u pkts/%u bytes]\n", i, s->port, s->num_addr, s->num_pkts, s->num_bytes); + printf("\t%2d\tPort %5u\t[%u IP address(es)/%u pkts/%u bytes]\n\t\tTop IP Stats:\n", + i, s->port, s->num_addr, s->num_pkts, s->num_bytes); qsort(&s->top_ip_addrs[0], MAX_NUM_IP_ADDRESS, sizeof(struct info_pair), info_pair_cmp); for(j=0; jtop_ip_addrs[j].count != 0) { + if(s->top_ip_addrs[j].count != 0) { inet_ntop(AF_INET, &s->top_ip_addrs[j].addr, ip_name, sizeof(ip_name)); - printf("\t\t\t\t%s\t%s ~ %.2f%%\n", (first) ? "Top IP Stats:" : "\t", + printf("\t\t%-16s ~ %.2f%%\n", ip_name, ((s->top_ip_addrs[j].count) * 100.0) / s->cumulative_addr); first = 0; } @@ -1331,7 +1332,7 @@ static void printResults(u_int64_t tot_usec) { float t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)tot_usec; float b = (float)(cumulative_stats.total_wire_bytes * 8 *1000000)/(float)tot_usec; float traffic_duration; - if (live_capture) traffic_duration = tot_usec; + if(live_capture) traffic_duration = tot_usec; else traffic_duration = (pcap_end.tv_sec*1000000 + pcap_end.tv_usec) - (pcap_start.tv_sec*1000000 + pcap_start.tv_usec); printf("\tnDPI throughput: %s pps / %s/sec\n", formatPackets(t, buf), formatTraffic(b, 1, buf1)); t = (float)(cumulative_stats.ip_packet_count*1000000)/(float)traffic_duration; @@ -1647,8 +1648,8 @@ static void pcap_process_packet(u_char *args, } /* 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; + 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; } -- cgit v1.2.3