aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/ndpiReader.c23
-rw-r--r--example/ndpi_util.c32
-rw-r--r--example/ndpi_util.h3
-rw-r--r--src/include/ndpi_api.h5
-rw-r--r--src/include/ndpi_protocol_ids.h2
-rw-r--r--src/lib/Makefile.in2
-rw-r--r--src/lib/ndpi_content_match.c.inc1
-rw-r--r--src/lib/ndpi_main.c529
-rw-r--r--src/lib/ndpi_utils.c596
-rw-r--r--src/lib/protocols/btlib.c10
-rw-r--r--src/lib/protocols/dhcp.c13
-rw-r--r--src/lib/protocols/memcached.c160
-rw-r--r--src/lib/protocols/openvpn.c69
-rw-r--r--src/lib/protocols/ssl.c2
-rw-r--r--src/lib/protocols/stun.c191
-rw-r--r--src/lib/protocols/viber.c2
-rw-r--r--tests/result/1kxun.pcap.out16
-rw-r--r--tests/result/6in4tunnel.pcap.out2
-rw-r--r--tests/result/KakaoTalk_chat.pcap.out10
-rw-r--r--tests/result/KakaoTalk_talk.pcap.out2
-rw-r--r--tests/result/dnscrypt.pcap.out8
-rw-r--r--tests/result/google_ssl.pcap.out2
-rw-r--r--tests/result/skype.pcap.out2
-rw-r--r--tests/result/skype_no_unknown.pcap.out2
-rw-r--r--tests/result/viber.pcap.out10
-rw-r--r--tests/result/waze.pcap.out24
-rw-r--r--tests/result/webex.pcap.out52
-rw-r--r--tests/result/wechat.pcap.out2
-rw-r--r--tests/result/whatsapp_login_call.pcap.out6
-rw-r--r--tests/result/whatsapp_login_chat.pcap.out2
30 files changed, 1077 insertions, 703 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 1a5dbbfd0..8551992bf 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -18,9 +18,7 @@
*
*/
-#ifdef HAVE_CONFIG_H
#include "ndpi_config.h"
-#endif
#ifdef linux
#define _GNU_SOURCE
@@ -845,7 +843,10 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa
if(flow->ssh_ssl.ja3_server[0] != '\0') fprintf(out, "[JA3S: %s%s]", flow->ssh_ssl.ja3_server,
print_cipher(flow->ssh_ssl.server_unsafe_cipher));
if(flow->ssh_ssl.server_organization[0] != '\0') fprintf(out, "[organization: %s]", flow->ssh_ssl.server_organization);
+ if(flow->ssh_ssl.server_cipher != '\0') fprintf(out, "[%s]", ndpi_cipher2str(flow->ssh_ssl.server_cipher));;
+
if(flow->bittorent_hash[0] != '\0') fprintf(out, "[BT Hash: %s]", flow->bittorent_hash);
+ if(flow->dhcp_fingerprint[0] != '\0') fprintf(out, "[DHCP Fingerprint: %s]", flow->dhcp_fingerprint);
fprintf(out, "\n");
} else {
@@ -896,8 +897,8 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa
if(flow->ssh_ssl.ja3_client[0] != '\0')
json_object_object_add(jObj,"ja3c",json_object_new_string(flow->ssh_ssl.ja3_client));
- if(flow->ja3_server[0] != '\0')
- json_object_object_add(jObj,"host.server.ja3",json_object_new_string(flow->ja3_server));
+ if(flow->ssh_ssl.ja3_server[0] != '\0')
+ json_object_object_add(jObj,"host.server.ja3",json_object_new_string(flow->ssh_ssl.ja3_server));
if(flow->ssh_ssl.client_info[0] != '\0')
json_object_object_add(sjObj, "client", json_object_new_string(flow->ssh_ssl.client_info));
@@ -1437,6 +1438,7 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth,
}
}
+/* *********************************************** */
/**
* @brief On Protocol Discover - demo callback
@@ -1447,6 +1449,8 @@ static void on_protocol_discovered(struct ndpi_workflow * workflow,
;
}
+/* *********************************************** */
+
#if 0
/**
* @brief Print debug
@@ -1454,7 +1458,6 @@ static void on_protocol_discovered(struct ndpi_workflow * workflow,
static void debug_printf(u_int32_t protocol, void *id_struct,
ndpi_log_level_t log_level,
const char *format, ...) {
-
va_list va_ap;
#ifndef WIN32
struct tm result;
@@ -1488,6 +1491,8 @@ static void debug_printf(u_int32_t protocol, void *id_struct,
}
#endif
+/* *********************************************** */
+
/**
* @brief Setup for detection begin
*/
@@ -1575,6 +1580,7 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
}
}
+/* *********************************************** */
/**
* @brief End of detection and free flow
@@ -1583,6 +1589,7 @@ static void terminateDetection(u_int16_t thread_id) {
ndpi_workflow_free(ndpi_thread_info[thread_id].workflow);
}
+/* *********************************************** */
/**
* @brief Traffic stats format
@@ -1619,6 +1626,7 @@ char* formatTraffic(float numBits, int bits, char *buf) {
return(buf);
}
+/* *********************************************** */
/**
* @brief Packets stats format
@@ -1637,6 +1645,7 @@ char* formatPackets(float numPkts, char *buf) {
return(buf);
}
+/* *********************************************** */
/**
* @brief JSON function init
@@ -1648,6 +1657,8 @@ static void json_init() {
jArray_topStats = json_object_new_array();
}
+/* *********************************************** */
+
static void json_open_stats_file() {
if((file_first_time && ((stats_fp = fopen(_statsFilePath,"w")) == NULL))
||
@@ -1658,6 +1669,8 @@ static void json_open_stats_file() {
else file_first_time = 0;
}
+/* *********************************************** */
+
static void json_close_stats_file() {
json_object *jObjFinal = json_object_new_object();
diff --git a/example/ndpi_util.c b/example/ndpi_util.c
index 8bf440b59..328047b90 100644
--- a/example/ndpi_util.c
+++ b/example/ndpi_util.c
@@ -249,21 +249,21 @@ int ndpi_workflow_node_cmp(const void *a, const void *b) {
if(
(
- (fa->src_ip == fb->src_ip )
- && (fa->src_port == fb->src_port)
- && (fa->dst_ip == fb->dst_ip )
- && (fa->dst_port == fb->dst_port)
- )
+ (fa->src_ip == fb->src_ip )
+ && (fa->src_port == fb->src_port)
+ && (fa->dst_ip == fb->dst_ip )
+ && (fa->dst_port == fb->dst_port)
+ )
||
(
- (fa->src_ip == fb->dst_ip )
- && (fa->src_port == fb->dst_port)
- && (fa->dst_ip == fb->src_ip )
- && (fa->dst_port == fb->src_port)
- )
- )
+ (fa->src_ip == fb->dst_ip )
+ && (fa->src_port == fb->dst_port)
+ && (fa->dst_ip == fb->src_ip )
+ && (fa->dst_port == fb->src_port)
+ )
+ )
return(0);
-
+
if(fa->src_ip < fb->src_ip ) return(-1); else { if(fa->src_ip > fb->src_ip ) return(1); }
if(fa->src_port < fb->src_port) return(-1); else { if(fa->src_port > fb->src_port) return(1); }
if(fa->dst_ip < fb->dst_ip ) return(-1); else { if(fa->dst_ip > fb->dst_ip ) return(1); }
@@ -379,10 +379,10 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow
flow.src_ip = iph->saddr, flow.dst_ip = iph->daddr;
flow.src_port = htons(*sport), flow.dst_port = htons(*dport);
flow.hashval = hashval = flow.protocol + flow.vlan_id + flow.src_ip + flow.dst_ip + flow.src_port + flow.dst_port;
+ /* printf("hashval=%u [%u][%u][%u:%u][%u:%u]\n", hashval, flow.protocol, flow.vlan_id, flow.src_ip, flow.src_port, flow.dst_ip, flow.dst_port); */
idx = hashval % workflow->prefs.num_roots;
ret = ndpi_tfind(&flow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp);
-
/* to avoid two nodes in one binary tree for a flow */
int is_changed = 0;
if(ret == NULL) {
@@ -533,8 +533,9 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
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) {
+ if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_DHCP) {
+ snprintf(flow->dhcp_fingerprint, sizeof(flow->dhcp_fingerprint), "%s", flow->ndpi_flow->protos.dhcp.fingerprint);
+ } else if(flow->detected_protocol.app_protocol == NDPI_PROTOCOL_BITTORRENT) {
u_int i, j, n = 0;
for(i=0, j = 0; j < sizeof(flow->bittorent_hash)-1; i++) {
@@ -577,6 +578,7 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
snprintf(flow->ssh_ssl.ja3_server, sizeof(flow->ssh_ssl.ja3_server), "%s",
flow->ndpi_flow->protos.stun_ssl.ssl.ja3_server);
flow->ssh_ssl.server_unsafe_cipher = flow->ndpi_flow->protos.stun_ssl.ssl.server_unsafe_cipher;
+ flow->ssh_ssl.server_cipher = flow->ndpi_flow->protos.stun_ssl.ssl.server_cipher;
}
}
diff --git a/example/ndpi_util.h b/example/ndpi_util.h
index 538753834..dfcc98a72 100644
--- a/example/ndpi_util.h
+++ b/example/ndpi_util.h
@@ -95,11 +95,13 @@ typedef struct ndpi_flow_info {
char info[96];
char host_server_name[256];
char bittorent_hash[41];
+ char dhcp_fingerprint[48];
struct {
u_int16_t ssl_version;
char client_info[64], server_info[64], server_organization[64],
ja3_client[33], ja3_server[33];
+ u_int16_t server_cipher;
ndpi_cipher_weakness client_unsafe_cipher, server_unsafe_cipher;
} ssh_ssl;
@@ -200,6 +202,7 @@ 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);
u_int32_t ethernet_crc32(const void* data, size_t n_bytes);
void ndpi_flow_info_freer(void *node);
+const char* print_cipher_id(u_int32_t cipher);
extern int nDPI_LogLevel;
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h
index afe22c329..206007a66 100644
--- a/src/include/ndpi_api.h
+++ b/src/include/ndpi_api.h
@@ -58,7 +58,7 @@ extern "C" {
* else 0
*
*/
- int check_punycode_string(char *buff, int len);
+ int ndpi_check_punycode_string(char *buff, int len);
/**
@@ -807,7 +807,8 @@ extern "C" {
u_int16_t src_port, u_int16_t dst_port, u_int8_t icmp_type, u_int8_t icmp_code,
u_char *hash_buf, u_int8_t hash_buf_len);
- u_int8_t ndpi_is_safe_ssl_cipher(u_int16_t cipher);
+ u_int8_t ndpi_is_safe_ssl_cipher(u_int32_t cipher);
+ const char* ndpi_cipher2str(u_int32_t cipher);
#ifdef __cplusplus
}
#endif
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h
index 7e2f55711..b8b77ada4 100644
--- a/src/include/ndpi_protocol_ids.h
+++ b/src/include/ndpi_protocol_ids.h
@@ -79,8 +79,8 @@ typedef enum {
NDPI_PROTOCOL_MINING = 42, /* Bitcoin, Ethereum, ZCash, Monero */
NDPI_PROTOCOL_NEST_LOG_SINK = 43, /* Nest Log Sink (Nest Protect) - Darryl Sokoloski <darryl@egloo.ca> */
NDPI_PROTOCOL_MODBUS = 44, /* Modbus */
+ NDPI_PROTOCOL_WHATSAPP_VIDEO = 45,
- NDPI_PROTOCOL_FREE_45 = 45, /* Free */
NDPI_PROTOCOL_FREE_46 = 46, /* Free */
NDPI_PROTOCOL_XBOX = 47,
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index 65934502d..aa2bbcc31 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -17,7 +17,7 @@ CC = @CC@
CFLAGS += -fPIC -DPIC -I../include -Ithird_party/include -DNDPI_LIB_COMPILATION -O2 -g
RANLIB = ranlib
-OBJECTS = $(patsubst protocols/%.c, protocols/%.o, $(wildcard protocols/*.c)) $(patsubst third_party/src/%.c, third_party/src/%.o, $(wildcard third_party/src/*.c)) ndpi_main.o
+OBJECTS = $(patsubst protocols/%.c, protocols/%.o, $(wildcard protocols/*.c)) $(patsubst third_party/src/%.c, third_party/src/%.o, $(wildcard third_party/src/*.c)) ndpi_main.o ndpi_utils.o
HEADERS = $(wildcard ../include/*.h)
NDPI_VERSION_MAJOR = @NDPI_MAJOR@
NDPI_LIB_STATIC = libndpi.a
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index 730050a2e..a58d80e25 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -8485,6 +8485,7 @@ ndpi_protocol_match host_match[] = {
{ "audio-fa.scdn.co", NULL, "audio-fa\\.scdn" TLD, "Spotify", NDPI_PROTOCOL_SPOTIFY, NDPI_PROTOCOL_CATEGORY_MUSIC, NDPI_PROTOCOL_FUN },
{ "edge-mqtt.facebook.com", NULL, "edge-mqtt\\.facebook" TLD, "Messenger", NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_CATEGORY_CHAT, NDPI_PROTOCOL_FUN },
+ { "mqtt-mini.facebook.com", NULL, "mqtt-mini\\.facebook" TLD, "Messenger", NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_CATEGORY_CHAT, NDPI_PROTOCOL_FUN }, /* Messenger Lite */
{ "messenger.com", NULL, "messenger\\.com" TLD, "Messenger", NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_CATEGORY_CHAT, NDPI_PROTOCOL_FUN },
{ ".pandora.com", NULL, "\\.pandora" TLD, "Pandora", NDPI_PROTOCOL_PANDORA, NDPI_PROTOCOL_CATEGORY_STREAMING, NDPI_PROTOCOL_FUN },
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 4bc89fb6e..bf9c4069e 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -55,180 +55,6 @@ static int _ndpi_debug_callbacks = 0;
// #define MATCH_DEBUG 1
-/* implementation of the punycode check function */
-int check_punycode_string(char * buffer , int len)
-{
- int i = 0;
-
- while(i++ < len)
- {
- if( buffer[i] == 'x' &&
- buffer[i+1] == 'n' &&
- buffer[i+2] == '-' &&
- buffer[i+3] == '-' )
- // is a punycode string
- return 1;
- }
- // not a punycode string
- return 0;
-}
-
-/* ftp://ftp.cc.uoc.gr/mirrors/OpenBSD/src/lib/libc/stdlib/tsearch.c */
-/* find or insert datum into search tree */
-void * ndpi_tsearch(const void *vkey, void **vrootp,
- int (*compar)(const void *, const void *))
-{
- ndpi_node *q;
- char *key = (char *)vkey;
- ndpi_node **rootp = (ndpi_node **)vrootp;
-
- if(rootp == (ndpi_node **)0)
- return ((void *)0);
- while (*rootp != (ndpi_node *)0) { /* Knuth's T1: */
- int r;
-
- if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
- return ((void *)*rootp); /* we found it! */
- rootp = (r < 0) ?
- &(*rootp)->left : /* T3: follow left branch */
- &(*rootp)->right; /* T4: follow right branch */
- }
- q = (ndpi_node *) ndpi_malloc(sizeof(ndpi_node)); /* T5: key not found */
- if(q != (ndpi_node *)0) { /* make new node */
- *rootp = q; /* link new node to old */
- q->key = key; /* initialize new node */
- q->left = q->right = (ndpi_node *)0;
- }
- return ((void *)q);
-}
-
-/* delete node with given key */
-void * ndpi_tdelete(const void *vkey, void **vrootp,
- int (*compar)(const void *, const void *))
-{
- ndpi_node **rootp = (ndpi_node **)vrootp;
- char *key = (char *)vkey;
- ndpi_node *p = (ndpi_node *)1;
- ndpi_node *q;
- ndpi_node *r;
- int cmp;
-
- if(rootp == (ndpi_node **)0 || *rootp == (ndpi_node *)0)
- return ((ndpi_node *)0);
- while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
- p = *rootp;
- rootp = (cmp < 0) ?
- &(*rootp)->left : /* follow left branch */
- &(*rootp)->right; /* follow right branch */
- if(*rootp == (ndpi_node *)0)
- return ((void *)0); /* key not found */
- }
- r = (*rootp)->right; /* D1: */
- if((q = (*rootp)->left) == (ndpi_node *)0) /* Left (ndpi_node *)0? */
- q = r;
- else if(r != (ndpi_node *)0) { /* Right link is null? */
- if(r->left == (ndpi_node *)0) { /* D2: Find successor */
- r->left = q;
- q = r;
- } else { /* D3: Find (ndpi_node *)0 link */
- for(q = r->left; q->left != (ndpi_node *)0; q = r->left)
- r = q;
- r->left = q->right;
- q->left = (*rootp)->left;
- q->right = (*rootp)->right;
- }
- }
- ndpi_free((ndpi_node *) *rootp); /* D4: Free node */
- *rootp = q; /* link parent to new node */
- return(p);
-}
-
-/* Walk the nodes of a tree */
-static void ndpi_trecurse(ndpi_node *root, void (*action)(const void *, ndpi_VISIT, int, void*), int level, void *user_data)
-{
- if(root->left == (ndpi_node *)0 && root->right == (ndpi_node *)0)
- (*action)(root, ndpi_leaf, level, user_data);
- else {
- (*action)(root, ndpi_preorder, level, user_data);
- if(root->left != (ndpi_node *)0)
- ndpi_trecurse(root->left, action, level + 1, user_data);
- (*action)(root, ndpi_postorder, level, user_data);
- if(root->right != (ndpi_node *)0)
- ndpi_trecurse(root->right, action, level + 1, user_data);
- (*action)(root, ndpi_endorder, level, user_data);
- }
-}
-
-/* Walk the nodes of a tree */
-void ndpi_twalk(const void *vroot, void (*action)(const void *, ndpi_VISIT, int, void *), void *user_data)
-{
- ndpi_node *root = (ndpi_node *)vroot;
-
- if(root != (ndpi_node *)0 && action != (void (*)(const void *, ndpi_VISIT, int, void*))0)
- ndpi_trecurse(root, action, 0, user_data);
-}
-
-/* find a node, or return 0 */
-void * ndpi_tfind(const void *vkey, void *vrootp,
- int (*compar)(const void *, const void *))
-{
- char *key = (char *)vkey;
- ndpi_node **rootp = (ndpi_node **)vrootp;
-
- if(rootp == (ndpi_node **)0)
- return ((ndpi_node *)0);
- while (*rootp != (ndpi_node *)0) { /* T1: */
- int r;
- if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
- return (*rootp); /* key found */
- rootp = (r < 0) ?
- &(*rootp)->left : /* T3: follow left branch */
- &(*rootp)->right; /* T4: follow right branch */
- }
- return (ndpi_node *)0;
-}
-
-/* ****************************************** */
-
-/* Walk the nodes of a tree */
-static void ndpi_tdestroy_recurse(ndpi_node* root, void (*free_action)(void *))
-{
- if(root->left != NULL)
- ndpi_tdestroy_recurse(root->left, free_action);
- if(root->right != NULL)
- ndpi_tdestroy_recurse(root->right, free_action);
-
- (*free_action) ((void *) root->key);
- ndpi_free(root);
-}
-
-void ndpi_tdestroy(void *vrootp, void (*freefct)(void *))
-{
- ndpi_node *root = (ndpi_node *) vrootp;
-
- if(root != NULL)
- ndpi_tdestroy_recurse(root, freefct);
-}
-
-/* ****************************************** */
-
-u_int8_t ndpi_net_match(u_int32_t ip_to_check,
- u_int32_t net,
- u_int32_t num_bits)
-{
- u_int32_t mask = 0;
-
- mask = ~(~mask >> num_bits);
-
- return(((ip_to_check & mask) == (net & mask)) ? 1 : 0);
-}
-
-u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst,
- u_int32_t net, u_int32_t num_bits)
-{
- return(ndpi_net_match(src, net, num_bits) || ndpi_net_match(dst, net, num_bits));
-}
-
/* ****************************************** */
static void *(*_ndpi_flow_malloc)(size_t size);
@@ -239,197 +65,6 @@ static void (*_ndpi_free)(void *ptr);
/* ****************************************** */
-#ifdef WIN32
-/* http://opensource.apple.com/source/Libc/Libc-186/string.subproj/strcasecmp.c */
-
-/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison. The mappings are
- * based upon ascii character sequences.
- */
-static const u_char charmap[] = {
- '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
- '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
- '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
- '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
- '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
- '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
- '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
- '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
- '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
- '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
- '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
- '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
- '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
- '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
- '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
- '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
- '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
- '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
- '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
- '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
- '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
- '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
- '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
- '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
- '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
- '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
-};
-
-int strcasecmp(s1, s2)
- const char *s1, *s2;
-{
- register const u_char *cm = charmap,
- *us1 = (const u_char *)s1,
- *us2 = (const u_char *)s2;
-
- while (cm[*us1] == cm[*us2++])
- if(*us1++ == '\0')
- return (0);
- return (cm[*us1] - cm[*--us2]);
-}
-
-int strncasecmp(s1, s2, n)
- const char *s1, *s2;
- register size_t n;
-{
- if(n != 0) {
- register const u_char *cm = charmap,
- *us1 = (const u_char *)s1,
- *us2 = (const u_char *)s2;
-
- do {
- if(cm[*us1] != cm[*us2++])
- return (cm[*us1] - cm[*--us2]);
- if(*us1++ == '\0')
- break;
- } while (--n != 0);
- }
- return (0);
-}
-
-#endif
-
-/* ****************************************** */
-
-/* Keep it in order and in sync with ndpi_protocol_category_t in ndpi_typedefs.h */
-static const char* categories[] = {
- "Unspecified",
- "Media",
- "VPN",
- "Email",
- "DataTransfer",
- "Web",
- "SocialNetwork",
- "Download-FileTransfer-FileSharing",
- "Game",
- "Chat",
- "VoIP",
- "Database",
- "RemoteAccess",
- "Cloud",
- "Network",
- "Collaborative",
- "RPC",
- "Streaming",
- "System",
- "SoftwareUpdate",
- "",
- "",
- "",
- "",
- "",
- "Music",
- "Video",
- "Shopping",
- "Productivity",
- "FileSharing",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "Mining", /* 99 */
- "Malware",
- "Advertisement",
- "Banned_Site",
- "Site_Unavailable",
- "Allowed_Site",
- "Antimalware",
-};
-
-/* ****************************************** */
-
/* Forward */
static void addDefaultPort(struct ndpi_detection_module_struct *ndpi_mod,
ndpi_port_range *range,
@@ -1348,9 +983,9 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
no_master, "Modbus", NDPI_PROTOCOL_CATEGORY_NETWORK, /* Perhaps IoT in the future */
ndpi_build_default_ports(ports_a, 502, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
- ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_FREE_45,
+ ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_WHATSAPP_VIDEO,
0 /* can_have_a_subprotocol */, no_master,
- no_master, "Free", NDPI_PROTOCOL_CATEGORY_CUSTOM_1 /* dummy */,
+ no_master, "WhatsAppVideo", NDPI_PROTOCOL_CATEGORY_VOIP,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_FREE_46,
@@ -2290,6 +1925,118 @@ void set_ndpi_debug_function(struct ndpi_detection_module_struct *ndpi_str, ndpi
#endif
}
+/* ****************************************** */
+
+/* Keep it in order and in sync with ndpi_protocol_category_t in ndpi_typedefs.h */
+static const char* categories[] = {
+ "Unspecified",
+ "Media",
+ "VPN",
+ "Email",
+ "DataTransfer",
+ "Web",
+ "SocialNetwork",
+ "Download-FileTransfer-FileSharing",
+ "Game",
+ "Chat",
+ "VoIP",
+ "Database",
+ "RemoteAccess",
+ "Cloud",
+ "Network",
+ "Collaborative",
+ "RPC",
+ "Streaming",
+ "System",
+ "SoftwareUpdate",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Music",
+ "Video",
+ "Shopping",
+ "Productivity",
+ "FileSharing",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Mining", /* 99 */
+ "Malware",
+ "Advertisement",
+ "Banned_Site",
+ "Site_Unavailable",
+ "Allowed_Site",
+ "Antimalware",
+};
+
/* ******************************************************************** */
struct ndpi_detection_module_struct *ndpi_init_detection_module(void) {
@@ -6408,51 +6155,3 @@ int ndpi_flowv6_flow_hash(u_int8_t l4_proto, struct ndpi_in6_addr *src_ip, struc
/* **************************************** */
-/* **************************************** */
-
-struct cipher_weakness {
- u_int16_t cipher_id;
- ndpi_cipher_weakness weakness_type;
-};
-
-static struct cipher_weakness safe_ssl_ciphers[] = {
- /* https://community.qualys.com/thread/18212-how-does-qualys-determine-the-server-cipher-suites */
- /* INSECURE */
- { 0xc011, NDPI_CIPHER_INSECURE }, /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
- { 0x0005, NDPI_CIPHER_INSECURE }, /* TLS_RSA_WITH_RC4_128_SHA */
- { 0x0004, NDPI_CIPHER_INSECURE }, /* TLS_RSA_WITH_RC4_128_MD5 */
- /* WEAK */
- { 0x009d, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
- { 0x003d, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
- { 0x0035, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_256_CBC_SHA */
- { 0x0084, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
- { 0x009c, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
- { 0x003c, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
- { 0x002f, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_AES_128_CBC_SHA */
- { 0x0041, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
- { 0xc012, NDPI_CIPHER_WEAK }, /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
- { 0x0016, NDPI_CIPHER_WEAK }, /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
- { 0x000a, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
- { 0x0096, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_SEED_CBC_SHA */
- { 0x0007, NDPI_CIPHER_WEAK }, /* TLS_RSA_WITH_IDEA_CBC_SHA */
-
- { 0x0, NDPI_CIPHER_SAFE } /* END */
-};
-
-u_int8_t ndpi_is_safe_ssl_cipher(u_int16_t cipher) {
- u_int i;
-
- for(i=0; safe_ssl_ciphers[i].cipher_id != 0; i++) {
- if(safe_ssl_ciphers[i].cipher_id == cipher) {
-#ifdef CERTIFICATE_DEBUG
- printf("%s %s(%04X / %u)\n",
- (safe_ssl_ciphers[i].weakness_type == NDPI_CIPHER_WEAK) ? "WEAK" : "INSECURE",
- __FUNCTION__, cipher, cipher);
-#endif
-
- return(safe_ssl_ciphers[i].weakness_type);
- }
- }
-
- return(NDPI_CIPHER_SAFE); /* We're safe */
-}
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
new file mode 100644
index 000000000..bcd8e5f48
--- /dev/null
+++ b/src/lib/ndpi_utils.c
@@ -0,0 +1,596 @@
+/*
+ * ndpi_utils.cc
+ *
+ * Copyright (C) 2011-19 - ntop.org
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "ndpi_config.h"
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include "ahocorasick.h"
+#include "libcache.h"
+
+#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_UNKNOWN
+
+#include "ndpi_api.h"
+#include "ndpi_config.h"
+
+#include <time.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+
+#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
+#include <sys/endian.h>
+#endif
+
+#include "third_party/include/ndpi_patricia.h"
+#include "third_party/include/ht_hash.h"
+
+#define NDPI_CONST_GENERIC_PROTOCOL_NAME "GenericProtocol"
+
+static int _ndpi_debug_callbacks = 0;
+
+// #define MATCH_DEBUG 1
+
+/* implementation of the punycode check function */
+int ndpi_check_punycode_string(char * buffer , int len) {
+ int i = 0;
+
+ while(i++ < len) {
+ if((buffer[i] == 'x')
+ && (buffer[i+1] == 'n')
+ && (buffer[i+2] == '-')
+ && (buffer[i+3] == '-'))
+ // is a punycode string
+ return(1);
+ }
+
+ // not a punycode string
+ return 0;
+}
+
+/* ftp://ftp.cc.uoc.gr/mirrors/OpenBSD/src/lib/libc/stdlib/tsearch.c */
+/* find or insert datum into search tree */
+void * ndpi_tsearch(const void *vkey, void **vrootp,
+ int (*compar)(const void *, const void *))
+{
+ ndpi_node *q;
+ char *key = (char *)vkey;
+ ndpi_node **rootp = (ndpi_node **)vrootp;
+
+ if(rootp == (ndpi_node **)0)
+ return ((void *)0);
+ while (*rootp != (ndpi_node *)0) { /* Knuth's T1: */
+ int r;
+
+ if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
+ return ((void *)*rootp); /* we found it! */
+ rootp = (r < 0) ?
+ &(*rootp)->left : /* T3: follow left branch */
+ &(*rootp)->right; /* T4: follow right branch */
+ }
+ q = (ndpi_node *) ndpi_malloc(sizeof(ndpi_node)); /* T5: key not found */
+ if(q != (ndpi_node *)0) { /* make new node */
+ *rootp = q; /* link new node to old */
+ q->key = key; /* initialize new node */
+ q->left = q->right = (ndpi_node *)0;
+ }
+ return ((void *)q);
+}
+
+/* delete node with given key */
+void * ndpi_tdelete(const void *vkey, void **vrootp,
+ int (*compar)(const void *, const void *))
+{
+ ndpi_node **rootp = (ndpi_node **)vrootp;
+ char *key = (char *)vkey;
+ ndpi_node *p = (ndpi_node *)1;
+ ndpi_node *q;
+ ndpi_node *r;
+ int cmp;
+
+ if(rootp == (ndpi_node **)0 || *rootp == (ndpi_node *)0)
+ return ((ndpi_node *)0);
+ while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
+ p = *rootp;
+ rootp = (cmp < 0) ?
+ &(*rootp)->left : /* follow left branch */
+ &(*rootp)->right; /* follow right branch */
+ if(*rootp == (ndpi_node *)0)
+ return ((void *)0); /* key not found */
+ }
+ r = (*rootp)->right; /* D1: */
+ if((q = (*rootp)->left) == (ndpi_node *)0) /* Left (ndpi_node *)0? */
+ q = r;
+ else if(r != (ndpi_node *)0) { /* Right link is null? */
+ if(r->left == (ndpi_node *)0) { /* D2: Find successor */
+ r->left = q;
+ q = r;
+ } else { /* D3: Find (ndpi_node *)0 link */
+ for(q = r->left; q->left != (ndpi_node *)0; q = r->left)
+ r = q;
+ r->left = q->right;
+ q->left = (*rootp)->left;
+ q->right = (*rootp)->right;
+ }
+ }
+ ndpi_free((ndpi_node *) *rootp); /* D4: Free node */
+ *rootp = q; /* link parent to new node */
+ return(p);
+}
+
+/* Walk the nodes of a tree */
+static void ndpi_trecurse(ndpi_node *root, void (*action)(const void *, ndpi_VISIT, int, void*), int level, void *user_data)
+{
+ if(root->left == (ndpi_node *)0 && root->right == (ndpi_node *)0)
+ (*action)(root, ndpi_leaf, level, user_data);
+ else {
+ (*action)(root, ndpi_preorder, level, user_data);
+ if(root->left != (ndpi_node *)0)
+ ndpi_trecurse(root->left, action, level + 1, user_data);
+ (*action)(root, ndpi_postorder, level, user_data);
+ if(root->right != (ndpi_node *)0)
+ ndpi_trecurse(root->right, action, level + 1, user_data);
+ (*action)(root, ndpi_endorder, level, user_data);
+ }
+}
+
+/* Walk the nodes of a tree */
+void ndpi_twalk(const void *vroot, void (*action)(const void *, ndpi_VISIT, int, void *), void *user_data)
+{
+ ndpi_node *root = (ndpi_node *)vroot;
+
+ if(root != (ndpi_node *)0 && action != (void (*)(const void *, ndpi_VISIT, int, void*))0)
+ ndpi_trecurse(root, action, 0, user_data);
+}
+
+/* find a node, or return 0 */
+void * ndpi_tfind(const void *vkey, void *vrootp,
+ int (*compar)(const void *, const void *))
+{
+ char *key = (char *)vkey;
+ ndpi_node **rootp = (ndpi_node **)vrootp;
+
+ if(rootp == (ndpi_node **)0)
+ return ((ndpi_node *)0);
+ while (*rootp != (ndpi_node *)0) { /* T1: */
+ int r;
+ if((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
+ return (*rootp); /* key found */
+ rootp = (r < 0) ?
+ &(*rootp)->left : /* T3: follow left branch */
+ &(*rootp)->right; /* T4: follow right branch */
+ }
+ return (ndpi_node *)0;
+}
+
+/* ****************************************** */
+
+/* Walk the nodes of a tree */
+static void ndpi_tdestroy_recurse(ndpi_node* root, void (*free_action)(void *))
+{
+ if(root->left != NULL)
+ ndpi_tdestroy_recurse(root->left, free_action);
+ if(root->right != NULL)
+ ndpi_tdestroy_recurse(root->right, free_action);
+
+ (*free_action) ((void *) root->key);
+ ndpi_free(root);
+}
+
+void ndpi_tdestroy(void *vrootp, void (*freefct)(void *))
+{
+ ndpi_node *root = (ndpi_node *) vrootp;
+
+ if(root != NULL)
+ ndpi_tdestroy_recurse(root, freefct);
+}
+
+/* ****************************************** */
+
+u_int8_t ndpi_net_match(u_int32_t ip_to_check,
+ u_int32_t net,
+ u_int32_t num_bits)
+{
+ u_int32_t mask = 0;
+
+ mask = ~(~mask >> num_bits);
+
+ return(((ip_to_check & mask) == (net & mask)) ? 1 : 0);
+}
+
+u_int8_t ndpi_ips_match(u_int32_t src, u_int32_t dst,
+ u_int32_t net, u_int32_t num_bits)
+{
+ return(ndpi_net_match(src, net, num_bits) || ndpi_net_match(dst, net, num_bits));
+}
+
+/* ****************************************** */
+
+#ifdef WIN32
+/* http://opensource.apple.com/source/Libc/Libc-186/string.subproj/strcasecmp.c */
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static const u_char charmap[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+ '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+ '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+ '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+int strcasecmp(const char *s1, const char *s2) {
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if(*us1++ == '\0')
+ return (0);
+ return (cm[*us1] - cm[*--us2]);
+}
+
+/* ****************************************** */
+
+int strncasecmp(const char *s1, const char *s2, size_t n) {
+ if(n != 0) {
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ do {
+ if(cm[*us1] != cm[*us2++])
+ return (cm[*us1] - cm[*--us2]);
+ if(*us1++ == '\0')
+ break;
+ } while (--n != 0);
+ }
+ return (0);
+}
+
+#endif
+
+/* **************************************** */
+
+u_int8_t ndpi_is_safe_ssl_cipher(u_int32_t cipher) {
+ /* https://community.qualys.com/thread/18212-how-does-qualys-determine-the-server-cipher-suites */
+ /* INSECURE */
+ switch(cipher) {
+ case 0xc011: return(NDPI_CIPHER_INSECURE); /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
+ case 0x0005: return(NDPI_CIPHER_INSECURE); /* TLS_RSA_WITH_RC4_128_SHA */
+ case 0x0004: return(NDPI_CIPHER_INSECURE); /* TLS_RSA_WITH_RC4_128_MD5 */
+ /* WEAK */
+ case 0x009d: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
+ case 0x003d: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
+ case 0x0035: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_AES_256_CBC_SHA */
+ case 0x0084: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
+ case 0x009c: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
+ case 0x003c: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
+ case 0x002f: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_AES_128_CBC_SHA */
+ case 0x0041: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
+ case 0xc012: return(NDPI_CIPHER_WEAK); /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
+ case 0x0016: return(NDPI_CIPHER_WEAK); /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
+ case 0x000a: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
+ case 0x0096: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_SEED_CBC_SHA */
+ case 0x0007: return(NDPI_CIPHER_WEAK); /* TLS_RSA_WITH_IDEA_CBC_SHA */
+ default: return(NDPI_CIPHER_SAFE);
+ }
+}
+
+/* ***************************************************** */
+
+const char* ndpi_cipher2str(u_int32_t cipher) {
+ switch(cipher) {
+ case 0x000000: return("TLS_NULL_WITH_NULL_NULL");
+ case 0x000001: return("TLS_RSA_WITH_NULL_MD5");
+ case 0x000002: return("TLS_RSA_WITH_NULL_SHA");
+ case 0x000003: return("TLS_RSA_EXPORT_WITH_RC4_40_MD5");
+ case 0x000004: return("TLS_RSA_WITH_RC4_128_MD5");
+ case 0x000005: return("TLS_RSA_WITH_RC4_128_SHA");
+ case 0x000006: return("TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5");
+ case 0x000007: return("TLS_RSA_WITH_IDEA_CBC_SHA");
+ case 0x000008: return("TLS_RSA_EXPORT_WITH_DES40_CBC_SHA");
+ case 0x000009: return("TLS_RSA_WITH_DES_CBC_SHA");
+ case 0x00000a: return("TLS_RSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00000b: return("TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA");
+ case 0x00000c: return("TLS_DH_DSS_WITH_DES_CBC_SHA");
+ case 0x00000d: return("TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA");
+ case 0x00000e: return("TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA");
+ case 0x00000f: return("TLS_DH_RSA_WITH_DES_CBC_SHA");
+ case 0x000010: return("TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x000011: return("TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
+ case 0x000012: return("TLS_DHE_DSS_WITH_DES_CBC_SHA");
+ case 0x000013: return("TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
+ case 0x000014: return("TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
+ case 0x000015: return("TLS_DHE_RSA_WITH_DES_CBC_SHA");
+ case 0x000016: return("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x000017: return("TLS_DH_anon_EXPORT_WITH_RC4_40_MD5");
+ case 0x000018: return("TLS_DH_anon_WITH_RC4_128_MD5");
+ case 0x000019: return("TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
+ case 0x00001a: return("TLS_DH_anon_WITH_DES_CBC_SHA");
+ case 0x00001b: return("TLS_DH_anon_WITH_3DES_EDE_CBC_SHA");
+ case 0x00001c: return("SSL_FORTEZZA_KEA_WITH_NULL_SHA");
+ case 0x00001d: return("SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA");
+ /* case 0x00001e: return("SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"); */
+ case 0x00001E: return("TLS_KRB5_WITH_DES_CBC_SHA");
+ case 0x00001F: return("TLS_KRB5_WITH_3DES_EDE_CBC_SHA");
+ case 0x000020: return("TLS_KRB5_WITH_RC4_128_SHA");
+ case 0x000021: return("TLS_KRB5_WITH_IDEA_CBC_SHA");
+ case 0x000022: return("TLS_KRB5_WITH_DES_CBC_MD5");
+ case 0x000023: return("TLS_KRB5_WITH_3DES_EDE_CBC_MD5");
+ case 0x000024: return("TLS_KRB5_WITH_RC4_128_MD5");
+ case 0x000025: return("TLS_KRB5_WITH_IDEA_CBC_MD5");
+ case 0x000026: return("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA");
+ case 0x000027: return("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA");
+ case 0x000028: return("TLS_KRB5_EXPORT_WITH_RC4_40_SHA");
+ case 0x000029: return("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5");
+ case 0x00002A: return("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5");
+ case 0x00002B: return("TLS_KRB5_EXPORT_WITH_RC4_40_MD5");
+ case 0x00002C: return("TLS_PSK_WITH_NULL_SHA");
+ case 0x00002D: return("TLS_DHE_PSK_WITH_NULL_SHA");
+ case 0x00002E: return("TLS_RSA_PSK_WITH_NULL_SHA");
+ case 0x00002f: return("TLS_RSA_WITH_AES_128_CBC_SHA");
+ case 0x000030: return("TLS_DH_DSS_WITH_AES_128_CBC_SHA");
+ case 0x000031: return("TLS_DH_RSA_WITH_AES_128_CBC_SHA");
+ case 0x000032: return("TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
+ case 0x000033: return("TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
+ case 0x000034: return("TLS_DH_anon_WITH_AES_128_CBC_SHA");
+ case 0x000035: return("TLS_RSA_WITH_AES_256_CBC_SHA");
+ case 0x000036: return("TLS_DH_DSS_WITH_AES_256_CBC_SHA");
+ case 0x000037: return("TLS_DH_RSA_WITH_AES_256_CBC_SHA");
+ case 0x000038: return("TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
+ case 0x000039: return("TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
+ case 0x00003A: return("TLS_DH_anon_WITH_AES_256_CBC_SHA");
+ case 0x00003B: return("TLS_RSA_WITH_NULL_SHA256");
+ case 0x00003C: return("TLS_RSA_WITH_AES_128_CBC_SHA256");
+ case 0x00003D: return("TLS_RSA_WITH_AES_256_CBC_SHA256");
+ case 0x00003E: return("TLS_DH_DSS_WITH_AES_128_CBC_SHA256");
+ case 0x00003F: return("TLS_DH_RSA_WITH_AES_128_CBC_SHA256");
+ case 0x000040: return("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256");
+ case 0x000041: return("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA");
+ case 0x000042: return("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA");
+ case 0x000043: return("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA");
+ case 0x000044: return("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA");
+ case 0x000045: return("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA");
+ case 0x000046: return("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA");
+ case 0x000047: return("TLS_ECDH_ECDSA_WITH_NULL_SHA");
+ case 0x000048: return("TLS_ECDH_ECDSA_WITH_RC4_128_SHA");
+ case 0x000049: return("TLS_ECDH_ECDSA_WITH_DES_CBC_SHA");
+ case 0x00004A: return("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00004B: return("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA");
+ case 0x00004C: return("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
+ case 0x000060: return("TLS_RSA_EXPORT1024_WITH_RC4_56_MD5");
+ case 0x000061: return("TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5");
+ case 0x000062: return("TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA");
+ case 0x000063: return("TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA");
+ case 0x000064: return("TLS_RSA_EXPORT1024_WITH_RC4_56_SHA");
+ case 0x000065: return("TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA");
+ case 0x000066: return("TLS_DHE_DSS_WITH_RC4_128_SHA");
+ case 0x000067: return("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256");
+ case 0x000068: return("TLS_DH_DSS_WITH_AES_256_CBC_SHA256");
+ case 0x000069: return("TLS_DH_RSA_WITH_AES_256_CBC_SHA256");
+ case 0x00006A: return("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256");
+ case 0x00006B: return("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256");
+ case 0x00006C: return("TLS_DH_anon_WITH_AES_128_CBC_SHA256");
+ case 0x00006D: return("TLS_DH_anon_WITH_AES_256_CBC_SHA256");
+ case 0x000084: return("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA");
+ case 0x000085: return("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA");
+ case 0x000086: return("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA");
+ case 0x000087: return("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA");
+ case 0x000088: return("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA");
+ case 0x000089: return("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA");
+ case 0x00008A: return("TLS_PSK_WITH_RC4_128_SHA");
+ case 0x00008B: return("TLS_PSK_WITH_3DES_EDE_CBC_SHA");
+ case 0x00008C: return("TLS_PSK_WITH_AES_128_CBC_SHA");
+ case 0x00008D: return("TLS_PSK_WITH_AES_256_CBC_SHA");
+ case 0x00008E: return("TLS_DHE_PSK_WITH_RC4_128_SHA");
+ case 0x00008F: return("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA");
+ case 0x000090: return("TLS_DHE_PSK_WITH_AES_128_CBC_SHA");
+ case 0x000091: return("TLS_DHE_PSK_WITH_AES_256_CBC_SHA");
+ case 0x000092: return("TLS_RSA_PSK_WITH_RC4_128_SHA");
+ case 0x000093: return("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA");
+ case 0x000094: return("TLS_RSA_PSK_WITH_AES_128_CBC_SHA");
+ case 0x000095: return("TLS_RSA_PSK_WITH_AES_256_CBC_SHA");
+ case 0x000096: return("TLS_RSA_WITH_SEED_CBC_SHA");
+ case 0x000097: return("TLS_DH_DSS_WITH_SEED_CBC_SHA");
+ case 0x000098: return("TLS_DH_RSA_WITH_SEED_CBC_SHA");
+ case 0x000099: return("TLS_DHE_DSS_WITH_SEED_CBC_SHA");
+ case 0x00009A: return("TLS_DHE_RSA_WITH_SEED_CBC_SHA");
+ case 0x00009B: return("TLS_DH_anon_WITH_SEED_CBC_SHA");
+ case 0x00009C: return("TLS_RSA_WITH_AES_128_GCM_SHA256");
+ case 0x00009D: return("TLS_RSA_WITH_AES_256_GCM_SHA384");
+ case 0x00009E: return("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256");
+ case 0x00009F: return("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384");
+ case 0x0000A0: return("TLS_DH_RSA_WITH_AES_128_GCM_SHA256");
+ case 0x0000A1: return("TLS_DH_RSA_WITH_AES_256_GCM_SHA384");
+ case 0x0000A2: return("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256");
+ case 0x0000A3: return("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384");
+ case 0x0000A4: return("TLS_DH_DSS_WITH_AES_128_GCM_SHA256");
+ case 0x0000A5: return("TLS_DH_DSS_WITH_AES_256_GCM_SHA384");
+ case 0x0000A6: return("TLS_DH_anon_WITH_AES_128_GCM_SHA256");
+ case 0x0000A7: return("TLS_DH_anon_WITH_AES_256_GCM_SHA384");
+ case 0x0000A8: return("TLS_PSK_WITH_AES_128_GCM_SHA256");
+ case 0x0000A9: return("TLS_PSK_WITH_AES_256_GCM_SHA384");
+ case 0x0000AA: return("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256");
+ case 0x0000AB: return("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384");
+ case 0x0000AC: return("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256");
+ case 0x0000AD: return("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384");
+ case 0x0000AE: return("TLS_PSK_WITH_AES_128_CBC_SHA256");
+ case 0x0000AF: return("TLS_PSK_WITH_AES_256_CBC_SHA384");
+ case 0x0000B0: return("TLS_PSK_WITH_NULL_SHA256");
+ case 0x0000B1: return("TLS_PSK_WITH_NULL_SHA384");
+ case 0x0000B2: return("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256");
+ case 0x0000B3: return("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384");
+ case 0x0000B4: return("TLS_DHE_PSK_WITH_NULL_SHA256");
+ case 0x0000B5: return("TLS_DHE_PSK_WITH_NULL_SHA384");
+ case 0x0000B6: return("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256");
+ case 0x0000B7: return("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384");
+ case 0x0000B8: return("TLS_RSA_PSK_WITH_NULL_SHA256");
+ case 0x0000B9: return("TLS_RSA_PSK_WITH_NULL_SHA384");
+ case 0x0000BA: return("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256");
+ case 0x0000BB: return("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256");
+ case 0x0000BC: return("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256");
+ case 0x0000BD: return("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256");
+ case 0x0000BE: return("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256");
+ case 0x0000BF: return("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256");
+ case 0x0000C0: return("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256");
+ case 0x0000C1: return("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256");
+ case 0x0000C2: return("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256");
+ case 0x0000C3: return("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256");
+ case 0x0000C4: return("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256");
+ case 0x0000C5: return("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256");
+ case 0x0000FF: return("TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
+ case 0x00c001: return("TLS_ECDH_ECDSA_WITH_NULL_SHA");
+ case 0x00c002: return("TLS_ECDH_ECDSA_WITH_RC4_128_SHA");
+ case 0x00c003: return("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00c004: return("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA");
+ case 0x00c005: return("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
+ case 0x00c006: return("TLS_ECDHE_ECDSA_WITH_NULL_SHA");
+ case 0x00c007: return("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA");
+ case 0x00c008: return("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00c009: return("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
+ case 0x00c00a: return("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
+ case 0x00c00b: return("TLS_ECDH_RSA_WITH_NULL_SHA");
+ case 0x00c00c: return("TLS_ECDH_RSA_WITH_RC4_128_SHA");
+ case 0x00c00d: return("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00c00e: return("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA");
+ case 0x00c00f: return("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA");
+ case 0x00c010: return("TLS_ECDHE_RSA_WITH_NULL_SHA");
+ case 0x00c011: return("TLS_ECDHE_RSA_WITH_RC4_128_SHA");
+ case 0x00c012: return("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00c013: return("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
+ case 0x00c014: return("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
+ case 0x00c015: return("TLS_ECDH_anon_WITH_NULL_SHA");
+ case 0x00c016: return("TLS_ECDH_anon_WITH_RC4_128_SHA");
+ case 0x00c017: return("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA");
+ case 0x00c018: return("TLS_ECDH_anon_WITH_AES_128_CBC_SHA");
+ case 0x00c019: return("TLS_ECDH_anon_WITH_AES_256_CBC_SHA");
+ case 0x00C01A: return("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00C01B: return("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA");
+ case 0x00C01C: return("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA");
+ case 0x00C01D: return("TLS_SRP_SHA_WITH_AES_128_CBC_SHA");
+ case 0x00C01E: return("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA");
+ case 0x00C01F: return("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA");
+ case 0x00C020: return("TLS_SRP_SHA_WITH_AES_256_CBC_SHA");
+ case 0x00C021: return("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA");
+ case 0x00C022: return("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA");
+ case 0x00C023: return("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
+ case 0x00C024: return("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
+ case 0x00C025: return("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256");
+ case 0x00C026: return("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384");
+ case 0x00C027: return("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
+ case 0x00C028: return("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
+ case 0x00C029: return("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256");
+ case 0x00C02A: return("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384");
+ case 0x00C02B: return("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
+ case 0x00C02C: return("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
+ case 0x00C02D: return("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256");
+ case 0x00C02E: return("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384");
+ case 0x00C02F: return("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+ case 0x00C030: return("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");
+ case 0x00C031: return("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256");
+ case 0x00C032: return("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384");
+ case 0x00C033: return("TLS_ECDHE_PSK_WITH_RC4_128_SHA");
+ case 0x00C034: return("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA");
+ case 0x00C035: return("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA");
+ case 0x00C036: return("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA");
+ case 0x00C037: return("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
+ case 0x00C038: return("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384");
+ case 0x00C039: return("TLS_ECDHE_PSK_WITH_NULL_SHA");
+ case 0x00C03A: return("TLS_ECDHE_PSK_WITH_NULL_SHA256");
+ case 0x00C03B: return("TLS_ECDHE_PSK_WITH_NULL_SHA384");
+ case 0x00CC13: return("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CC14: return("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CC15: return("TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CCA8: return("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CCA9: return("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CCAA: return("TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CCAB: return("TLS_PSK_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CCAC: return("TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CCAD: return("TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00CCAE: return("TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256");
+ case 0x00E410: return("TLS_RSA_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E411: return("TLS_RSA_WITH_SALSA20_SHA1");
+ case 0x00E412: return("TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E413: return("TLS_ECDHE_RSA_WITH_SALSA20_SHA1");
+ case 0x00E414: return("TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E415: return("TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1");
+ case 0x00E416: return("TLS_PSK_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E417: return("TLS_PSK_WITH_SALSA20_SHA1");
+ case 0x00E418: return("TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E419: return("TLS_ECDHE_PSK_WITH_SALSA20_SHA1");
+ case 0x00E41A: return("TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E41B: return("TLS_RSA_PSK_WITH_SALSA20_SHA1");
+ case 0x00E41C: return("TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E41D: return("TLS_DHE_PSK_WITH_SALSA20_SHA1");
+ case 0x00E41E: return("TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1");
+ case 0x00E41F: return("TLS_DHE_RSA_WITH_SALSA20_SHA1");
+ case 0x00fefe: return("SSL_RSA_FIPS_WITH_DES_CBC_SHA");
+ case 0x00feff: return("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA");
+ case 0x00ffe0: return("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA");
+ case 0x00ffe1: return("SSL_RSA_FIPS_WITH_DES_CBC_SHA");
+ case 0x010080: return("SSL2_RC4_128_WITH_MD5");
+ case 0x020080: return("SSL2_RC4_128_EXPORT40_WITH_MD5");
+ case 0x030080: return("SSL2_RC2_128_CBC_WITH_MD5");
+ case 0x040080: return("SSL2_RC2_128_CBC_EXPORT40_WITH_MD5");
+ case 0x050080: return("SSL2_IDEA_128_CBC_WITH_MD5");
+ case 0x060040: return("SSL2_DES_64_CBC_WITH_MD5");
+ case 0x0700c0: return("SSL2_DES_192_EDE3_CBC_WITH_MD5");
+ case 0x080080: return("SSL2_RC4_64_WITH_MD5");
+ default: return("???");
+ }
+}
+
diff --git a/src/lib/protocols/btlib.c b/src/lib/protocols/btlib.c
index ea06a6348..309a10717 100644
--- a/src/lib/protocols/btlib.c
+++ b/src/lib/protocols/btlib.c
@@ -64,7 +64,8 @@ static char *print20b(char *s,const u_int8_t *b) {
}
static char *print_id_ip_p(char *s, const struct bt_nodes_data *b) {
- u_int8_t *p = (void*)b;
+ u_int8_t *p = (u_int8_t*)b;
+
print20b(s,b->id);
snprintf(s+40,39," %d.%d.%d.%d:%u",
p[20], p[21], p[22], p[23], htons(b->port));
@@ -72,14 +73,16 @@ static char *print_id_ip_p(char *s, const struct bt_nodes_data *b) {
}
static char *print_ip_p(char *s, const struct bt_ipv4p *b,int np) {
- const u_int8_t *p = (const void*)b;
+ const u_int8_t *p = (const u_int8_t*)b;
+
snprintf(s,39,!np ? "%d.%d.%d.%d:%u":"%d.%d.%d.%d",
p[0], p[1], p[2], p[3], htons(b->port));
return s;
}
static char *print_ip6_p(char *s, const struct bt_ipv6p *b,int np) {
- u_int16_t *p = (void*)b;
+ u_int16_t *p = (u_int16_t*)b;
+
snprintf(s,79,!np ? "%x:%x:%x:%x:%x:%x:%x:%x.%u":"%x:%x:%x:%x:%x:%x:%x:%x",
htons(p[0]), htons(p[1]), htons(p[2]), htons(p[3]),
htons(p[4]), htons(p[5]), htons(p[6]), htons(p[7]),
@@ -507,6 +510,7 @@ const u_int8_t *bt_decode(const u_int8_t *b, size_t *l, int *ret, bt_parse_data_
cbd->level--;
return b;
}
+
bad_data:
*ret=-1;
return b;
diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c
index 52415946b..14959bae8 100644
--- a/src/lib/protocols/dhcp.c
+++ b/src/lib/protocols/dhcp.c
@@ -104,10 +104,15 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru
u_int idx, offset = 0;
for(idx = 0; idx < len && offset < sizeof(flow->protos.dhcp.fingerprint) - 2; idx++) {
- snprintf((char*)&flow->protos.dhcp.fingerprint[offset],
- sizeof(flow->protos.dhcp.fingerprint) - offset,
- "%02X", dhcp->options[i+2+idx] & 0xFF);
- offset += 2;
+#if 1
+ offset += snprintf((char*)&flow->protos.dhcp.fingerprint[offset],
+ sizeof(flow->protos.dhcp.fingerprint) - offset,
+ "%s%u", (idx > 0) ? "," : "", dhcp->options[i+2+idx] & 0xFF);
+#else
+ offset += snprintf((char*)&flow->protos.dhcp.fingerprint[offset],
+ sizeof(flow->protos.dhcp.fingerprint) - offset,
+ "%02X", dhcp->options[i+2+idx] & 0xFF);
+#endif
}
flow->protos.dhcp.fingerprint[sizeof(flow->protos.dhcp.fingerprint) - 1] = '\0';
diff --git a/src/lib/protocols/memcached.c b/src/lib/protocols/memcached.c
index 44a8b0858..e527688ba 100644
--- a/src/lib/protocols/memcached.c
+++ b/src/lib/protocols/memcached.c
@@ -92,99 +92,99 @@
#define MEMCACHED_MATCH(cr) (cr ## _LEN > length || memcmp(offset, cr, cr ## _LEN))
static void ndpi_int_memcached_add_connection(struct ndpi_detection_module_struct
- *ndpi_struct, struct ndpi_flow_struct *flow)
+ *ndpi_struct, struct ndpi_flow_struct *flow)
{
- NDPI_LOG_INFO(ndpi_struct, "found memcached\n");
- ndpi_set_detected_protocol(ndpi_struct, flow,
- NDPI_PROTOCOL_MEMCACHED, NDPI_PROTOCOL_UNKNOWN);
+ NDPI_LOG_INFO(ndpi_struct, "found memcached\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ NDPI_PROTOCOL_MEMCACHED, NDPI_PROTOCOL_UNKNOWN);
}
void ndpi_search_memcached(
- struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow)
+ struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
{
- struct ndpi_packet_struct *packet = &flow->packet;
- const u_int8_t *offset = packet->payload;
- const u_int16_t length = packet->payload_packet_len;
- u_int8_t *matches;
+ struct ndpi_packet_struct *packet = &flow->packet;
+ const u_int8_t *offset = packet->payload;
+ const u_int16_t length = packet->payload_packet_len;
+ u_int8_t *matches;
- NDPI_LOG_DBG(ndpi_struct, "search memcached\n");
+ NDPI_LOG_DBG(ndpi_struct, "search memcached\n");
- if (packet->tcp != NULL) {
- if (packet->payload_packet_len < MEMCACHED_MIN_LEN) {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
-
- matches = &flow->l4.tcp.memcached_matches;
+ if (packet->tcp != NULL) {
+ if (packet->payload_packet_len < MEMCACHED_MIN_LEN) {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
}
- else if (packet->udp != NULL) {
- if (packet->payload_packet_len < MEMCACHED_MIN_UDP_LEN) {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
-
- if ((offset[4] == 0x00 && offset[5] == 0x00) ||
- offset[6] != 0x00 || offset[7] != 0x00) {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
-
- offset += MEMCACHED_UDP_HDR_LEN;
- matches = &flow->l4.udp.memcached_matches;
+
+ matches = &flow->l4.tcp.memcached_matches;
+ }
+ else if (packet->udp != NULL) {
+ if (packet->payload_packet_len < MEMCACHED_MIN_UDP_LEN) {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
}
- else {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
+
+ if ((offset[4] == 0x00 && offset[5] == 0x00) ||
+ offset[6] != 0x00 || offset[7] != 0x00) {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
}
- /* grep MCD memcached.c |\
- * egrep -v '(LEN|MATCH)' |\
- * sed -e 's/^#define //g' |\
- * awk '{ printf "else if (! MEMCACHED_MATCH(%s)) *matches += 1;\n",$1 }' */
-
- if (! MEMCACHED_MATCH(MCDC_SET)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_ADD)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_REPLACE)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_APPEND)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_PREPEND)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_CAS)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_GET)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_GETS)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_DELETE)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_INCR)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_DECR)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_TOUCH)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_GAT)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_GATS)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDC_STATS)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_ERROR)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_CLIENT_ERROR)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_SERVER_ERROR)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_STORED)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_NOT_STORED)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_EXISTS)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_NOT_FOUND)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_END)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_DELETED)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_TOUCHED)) *matches += 1;
- else if (! MEMCACHED_MATCH(MCDR_STAT)) *matches += 1;
-
- if (*matches >= MEMCACHED_MIN_MATCH)
- ndpi_int_memcached_add_connection(ndpi_struct, flow);
+ offset += MEMCACHED_UDP_HDR_LEN;
+ matches = &flow->l4.udp.memcached_matches;
+ }
+ else {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
+ }
+
+ /* grep MCD memcached.c |\
+ * egrep -v '(LEN|MATCH)' |\
+ * sed -e 's/^#define //g' |\
+ * awk '{ printf "else if (! MEMCACHED_MATCH(%s)) *matches += 1;\n",$1 }' */
+
+ if (! MEMCACHED_MATCH(MCDC_SET)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_ADD)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_REPLACE)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_APPEND)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_PREPEND)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_CAS)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_GET)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_GETS)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_DELETE)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_INCR)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_DECR)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_TOUCH)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_GAT)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_GATS)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDC_STATS)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_ERROR)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_CLIENT_ERROR)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_SERVER_ERROR)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_STORED)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_NOT_STORED)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_EXISTS)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_NOT_FOUND)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_END)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_DELETED)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_TOUCHED)) *matches += 1;
+ else if (! MEMCACHED_MATCH(MCDR_STAT)) *matches += 1;
+
+ if (*matches >= MEMCACHED_MIN_MATCH)
+ ndpi_int_memcached_add_connection(ndpi_struct, flow);
}
void init_memcached_dissector(
- struct ndpi_detection_module_struct *ndpi_struct,
- u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
+ struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
{
- ndpi_set_bitmask_protocol_detection("MEMCACHED",
- ndpi_struct, detection_bitmask, *id,
- NDPI_PROTOCOL_MEMCACHED,
- ndpi_search_memcached,
- NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
- SAVE_DETECTION_BITMASK_AS_UNKNOWN,
- ADD_TO_DETECTION_BITMASK);
-
- *id += 1;
+ ndpi_set_bitmask_protocol_detection("MEMCACHED",
+ ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_MEMCACHED,
+ ndpi_search_memcached,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ *id += 1;
}
diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c
index 6bd480ea1..b92eb5cf7 100644
--- a/src/lib/protocols/openvpn.c
+++ b/src/lib/protocols/openvpn.c
@@ -40,12 +40,19 @@
#define P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) (P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) + 8)
#define P_HARD_RESET_CLIENT_MAX_COUNT 5
+static void ndpi_int_openvpn_add_connection(struct ndpi_detection_module_struct
+ *ndpi_struct, struct ndpi_flow_struct *flow) {
+ NDPI_LOG_INFO(ndpi_struct, "found memcached\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ NDPI_PROTOCOL_MEMCACHED, NDPI_PROTOCOL_UNKNOWN);
+}
+
static
#ifndef WIN32
inline
#endif
u_int32_t get_packet_id(const u_int8_t * payload, u_int8_t hms) {
- return ntohl(*(u_int32_t*)(payload + P_HARD_RESET_PACKET_ID_OFFSET(hms)));
+ return(ntohl(*(u_int32_t*)(payload + P_HARD_RESET_PACKET_ID_OFFSET(hms))));
}
static
@@ -54,11 +61,13 @@ inline
#endif
int8_t check_pkid_and_detect_hmac_size(const u_int8_t * payload) {
// try to guess
- if (get_packet_id(payload, P_HMAC_160) == 1)
+ if(get_packet_id(payload, P_HMAC_160) == 1)
return P_HMAC_160;
- if (get_packet_id(payload, P_HMAC_128) == 1)
+
+ if(get_packet_id(payload, P_HMAC_128) == 1)
return P_HMAC_128;
- return -1;
+
+ return(-1);
}
void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct,
@@ -71,17 +80,39 @@ void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct,
int8_t hmac_size;
int8_t failed = 0;
- if (packet->payload_packet_len >= 40) {
+ if(packet->payload_packet_len >= 40) {
// skip openvpn TCP transport packet size
- if (packet->tcp != NULL)
+ if(packet->tcp != NULL)
ovpn_payload += 2;
opcode = ovpn_payload[0] & P_OPCODE_MASK;
- if (flow->ovpn_counter < P_HARD_RESET_CLIENT_MAX_COUNT && (opcode == P_CONTROL_HARD_RESET_CLIENT_V1 ||
+ if(packet->udp) {
+#ifdef DEBUG
+ printf("[packet_id: %u][opcode: %u][Packet ID: %d][%u <-> %u][len: %u]\n",
+ flow->num_processed_pkts,
+ opcode, check_pkid_and_detect_hmac_size(ovpn_payload),
+ htons(packet->udp->source), htons(packet->udp->dest), packet->payload_packet_len);
+#endif
+
+ if(
+ (flow->num_processed_pkts == 1)
+ && (
+ ((packet->payload_packet_len == 112)
+ && ((opcode == 168) || (opcode == 192))
+ )
+ || ((packet->payload_packet_len == 80)
+ && ((opcode == 184) || (opcode == 88) || (opcode == 160) || (opcode == 168) || (opcode == 200)))
+ )) {
+ NDPI_LOG_INFO(ndpi_struct,"found openvpn\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN);
+ return;
+ }
+ }
+
+ if(flow->ovpn_counter < P_HARD_RESET_CLIENT_MAX_COUNT && (opcode == P_CONTROL_HARD_RESET_CLIENT_V1 ||
opcode == P_CONTROL_HARD_RESET_CLIENT_V2)) {
-
- if (check_pkid_and_detect_hmac_size(ovpn_payload) > 0) {
+ if(check_pkid_and_detect_hmac_size(ovpn_payload) > 0) {
memcpy(flow->ovpn_session_id, ovpn_payload+1, 8);
NDPI_LOG_DBG2(ndpi_struct,
@@ -89,20 +120,20 @@ void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct,
flow->ovpn_session_id[0], flow->ovpn_session_id[1], flow->ovpn_session_id[2], flow->ovpn_session_id[3],
flow->ovpn_session_id[4], flow->ovpn_session_id[5], flow->ovpn_session_id[6], flow->ovpn_session_id[7]);
}
- } else if (flow->ovpn_counter >= 1 && flow->ovpn_counter <= P_HARD_RESET_CLIENT_MAX_COUNT &&
+ } else if(flow->ovpn_counter >= 1 && flow->ovpn_counter <= P_HARD_RESET_CLIENT_MAX_COUNT &&
(opcode == P_CONTROL_HARD_RESET_SERVER_V1 || opcode == P_CONTROL_HARD_RESET_SERVER_V2)) {
hmac_size = check_pkid_and_detect_hmac_size(ovpn_payload);
- if (hmac_size > 0) {
+ if(hmac_size > 0) {
alen = ovpn_payload[P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size)];
session_remote = ovpn_payload + P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) + 1 + alen * 4;
- if (memcmp(flow->ovpn_session_id, session_remote, 8) == 0) {
- NDPI_LOG_INFO(ndpi_struct,"found openvpn\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN);
- }
- else {
+ if(memcmp(flow->ovpn_session_id, session_remote, 8) == 0) {
+ NDPI_LOG_INFO(ndpi_struct,"found openvpn\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN);
+ return;
+ } else {
NDPI_LOG_DBG2(ndpi_struct,
"key mismatch: %02x%02x%02x%02x%02x%02x%02x%02x\n",
session_remote[0], session_remote[1], session_remote[2], session_remote[3],
@@ -116,14 +147,14 @@ void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct,
flow->ovpn_counter++;
- if (failed) {
+ if(failed) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}
}
}
-void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
-{
+void init_openvpn_dissector(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) {
ndpi_set_bitmask_protocol_detection("OpenVPN", ndpi_struct, detection_bitmask, *id,
NDPI_PROTOCOL_OPENVPN,
ndpi_search_openvpn,
diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c
index eee31e94b..9b3a6c51b 100644
--- a/src/lib/protocols/ssl.c
+++ b/src/lib/protocols/ssl.c
@@ -317,7 +317,7 @@ static void stripCertificateTrailer(char *buffer, int buffer_len) {
}
/* check for punycode encoding */
- is_puny = check_punycode_string(buffer, buffer_len);
+ is_puny = ndpi_check_punycode_string(buffer, buffer_len);
// not a punycode string - need more checks
if(is_puny == 0) {
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index c169a47db..97cf091f0 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -28,7 +28,7 @@
#include "ndpi_api.h"
-#define MAX_NUM_STUN_PKTS 10
+#define MAX_NUM_STUN_PKTS 8
struct stun_packet_header {
u_int16_t msg_type, msg_len;
@@ -53,10 +53,10 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
u_int8_t *is_whatsapp) {
u_int16_t msg_type, msg_len;
struct stun_packet_header *h = (struct stun_packet_header*)payload;
- u_int8_t can_this_be_whatsapp_voice = 1;
+ u_int8_t can_this_be_whatsapp_voice = 1, wa = 0;
flow->protos.stun_ssl.stun.num_processed_pkts++;
-
+
if(payload_length < sizeof(struct stun_packet_header)) {
if(flow->protos.stun_ssl.stun.num_udp_pkts > 0) {
*is_whatsapp = 1;
@@ -75,86 +75,104 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
if(ntohs(h->msg_type) == 0x01 /* Binding Request */)
flow->protos.stun_ssl.stun.num_binding_requests++;
-
- if((payload[0] != 0x80) && ((msg_len+20) > payload_length))
- return(NDPI_IS_NOT_STUN);
- if((payload_length == (msg_len+20))
- && ((msg_type <= 0x000b) /* http://www.3cx.com/blog/voip-howto/stun-details/ */)) {
- u_int offset = 20;
+ /* printf("[%02X][%02X][msg_len: %u][payload_length: %u]\n", payload[0], payload[1], msg_len, payload_length); */
- /*
- This can either be the standard RTCP or Ms Lync RTCP that
- later will become Ms Lync RTP. In this case we need to
- be careful before deciding about the protocol before dissecting the packet
-
- MS Lync = Skype
- https://en.wikipedia.org/wiki/Skype_for_Business
- */
+ if(((payload[0] == 0x80) && ((msg_len+20) <= payload_length)) /* WhatsApp Voice */) {
+ *is_whatsapp = 1;
+ return NDPI_IS_STUN; /* This is WhatsApp Voice */
+ } else if((payload[0] == 0x90) && ((msg_len+11) == payload_length) /* WhatsApp Video */) {
+ *is_whatsapp = 2;
+ return NDPI_IS_STUN; /* This is WhatsApp Video */
+ }
- while((offset+2) < payload_length) {
- u_int16_t attribute = ntohs(*((u_int16_t*)&payload[offset]));
- u_int16_t len = ntohs(*((u_int16_t*)&payload[offset+2]));
- u_int16_t x = (len + 4) % 4;
-
- if(x != 0)
- len += 4-x;
-
- switch(attribute) {
- case 0x0008: /* Message Integrity */
- case 0x0020: /* XOR-MAPPED-ADDRESSES */
- case 0x4002:
- /* These are the only messages apparently whatsapp voice can use */
- break;
-
- case 0x8054: /* Candidate Identifier */
- if((len == 4)
- && ((offset+7) < payload_length)
- && (payload[offset+5] == 0x00)
- && (payload[offset+6] == 0x00)
- && (payload[offset+7] == 0x00)) {
- /* Either skype for business or "normal" skype with multiparty call */
- flow->protos.stun_ssl.stun.is_skype = 1;
- return(NDPI_IS_STUN);
- }
- break;
-
- case 0x8055: /* MS Service Quality (skype?) */
- break;
-
- /* Proprietary fields found on skype calls */
- case 0x24DF:
- case 0x3802:
- case 0x8036:
- case 0x8095:
- case 0x0800:
- /* printf("====>>>> %04X\n", attribute); */
- flow->protos.stun_ssl.stun.is_skype = 1;
- return(NDPI_IS_STUN);
- break;
-
- case 0x8070: /* Implementation Version */
- if((len == 4)
- && ((offset+7) < payload_length)
- && (payload[offset+4] == 0x00)
- && (payload[offset+5] == 0x00)
- && (payload[offset+6] == 0x00)
- && ((payload[offset+7] == 0x02) || (payload[offset+7] == 0x03))
- ) {
+ if((payload[0] != 0x80) && ((msg_len+20) > payload_length))
+ return(NDPI_IS_NOT_STUN);
+
+ if(payload_length == (msg_len+20)) {
+ if(msg_type <= 0x000b) /* http://www.3cx.com/blog/voip-howto/stun-details/ */ {
+ u_int offset = 20;
+
+ // printf("[%02X][%02X][%02X][%02X][payload_length: %u]\n", payload[offset], payload[offset+1], payload[offset+2], payload[offset+3],payload_length);
+
+ /*
+ This can either be the standard RTCP or Ms Lync RTCP that
+ later will become Ms Lync RTP. In this case we need to
+ be careful before deciding about the protocol before dissecting the packet
+
+ MS Lync = Skype
+ https://en.wikipedia.org/wiki/Skype_for_Business
+ */
+
+ while((offset+2) < payload_length) {
+ u_int16_t attribute = ntohs(*((u_int16_t*)&payload[offset]));
+ u_int16_t len = ntohs(*((u_int16_t*)&payload[offset+2]));
+ u_int16_t x = (len + 4) % 4;
+
+ if(x != 0)
+ len += 4-x;
+
+ switch(attribute) {
+ case 0x0008: /* Message Integrity */
+ case 0x0020: /* XOR-MAPPED-ADDRESSES */
+ case 0x4000:
+ case 0x4002:
+ /* These are the only messages apparently whatsapp voice can use */
+ break;
+
+ case 0x8054: /* Candidate Identifier */
+ if((len == 4)
+ && ((offset+7) < payload_length)
+ && (payload[offset+5] == 0x00)
+ && (payload[offset+6] == 0x00)
+ && (payload[offset+7] == 0x00)) {
+ /* Either skype for business or "normal" skype with multiparty call */
+ flow->protos.stun_ssl.stun.is_skype = 1;
+ return(NDPI_IS_STUN);
+ }
+ break;
+
+ case 0x8055: /* MS Service Quality (skype?) */
+ break;
+
+ /* Proprietary fields found on skype calls */
+ case 0x24DF:
+ case 0x3802:
+ case 0x8036:
+ case 0x8095:
+ case 0x0800:
+ /* printf("====>>>> %04X\n", attribute); */
flow->protos.stun_ssl.stun.is_skype = 1;
return(NDPI_IS_STUN);
+ break;
+
+ case 0x8070: /* Implementation Version */
+ if((len == 4)
+ && ((offset+7) < payload_length)
+ && (payload[offset+4] == 0x00)
+ && (payload[offset+5] == 0x00)
+ && (payload[offset+6] == 0x00)
+ && ((payload[offset+7] == 0x02) || (payload[offset+7] == 0x03))
+ ) {
+ flow->protos.stun_ssl.stun.is_skype = 1;
+ return(NDPI_IS_STUN);
+ }
+ break;
+
+ default:
+ /* This means this STUN packet cannot be confused with whatsapp voice */
+ /* printf("==> %04X\n", attribute); */
+ can_this_be_whatsapp_voice = 0;
+ break;
}
- break;
- default:
- /* This means this STUN packet cannot be confused with whatsapp voice */
- can_this_be_whatsapp_voice = 0;
- break;
+ offset += len + 4;
}
-
- offset += len + 4;
+ goto udp_stun_found;
+ } else if(msg_type == 0x0800) {
+ *is_whatsapp = 1;
+ return NDPI_IS_STUN; /* This is WhatsApp */
}
- goto udp_stun_found;
}
if((flow->protos.stun_ssl.stun.num_udp_pkts > 0) && (msg_type <= 0x00FF)) {
@@ -163,7 +181,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
} else
return NDPI_IS_NOT_STUN;
- udp_stun_found:
+ udp_stun_found:
if(can_this_be_whatsapp_voice) {
flow->protos.stun_ssl.stun.num_udp_pkts++;
@@ -172,11 +190,11 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
/*
We cannot immediately say that this is STUN as there are other protocols
like GoogleHangout that might be candidates, thus we set the
- guessed protocol to STUN
+ guessed protocol to STUN
*/
flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
return(NDPI_IS_NOT_STUN);
- }
+ }
}
void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
@@ -187,11 +205,11 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
NDPI_LOG_DBG(ndpi_struct, "search stun\n");
if(packet->payload == NULL) return;
-
+
if(packet->tcp) {
/* STUN may be encapsulated in TCP packets */
if((packet->payload_packet_len >= 22)
- && ((ntohs(get_u_int16_t(packet->payload, 0)) + 2) == packet->payload_packet_len)) {
+ && ((ntohs(get_u_int16_t(packet->payload, 0)) + 2) == packet->payload_packet_len)) {
/* TODO there could be several STUN packets in a single TCP packet so maybe the detection could be
* improved by checking only the STUN packet of given length */
@@ -207,9 +225,9 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
} else {
NDPI_LOG_INFO(ndpi_struct, "found UDP stun\n"); /* Ummmmm we're in the TCP branch. This code looks bad */
ndpi_int_stun_add_connection(ndpi_struct,
- is_whatsapp ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_STUN, flow);
+ is_whatsapp ? (is_whatsapp == 1 ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_WHATSAPP_VIDEO) : NDPI_PROTOCOL_STUN, flow);
}
-
+
return;
}
}
@@ -218,24 +236,25 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload,
packet->payload_packet_len, &is_whatsapp) == NDPI_IS_STUN) {
if(flow->guessed_protocol_id == 0) flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
-
+
if(flow->protos.stun_ssl.stun.is_skype) {
NDPI_LOG_INFO(ndpi_struct, "Found Skype\n");
- /* flow->protos.stun_ssl.stun.num_binding_requests < 4) ? NDPI_PROTOCOL_SKYPE_CALL_IN : NDPI_PROTOCOL_SKYPE_CALL_OUT */
+ /* flow->protos.stun_ssl.stun.num_binding_requests < 4) ? NDPI_PROTOCOL_SKYPE_CALL_IN : NDPI_PROTOCOL_SKYPE_CALL_OUT */
if((flow->protos.stun_ssl.stun.num_processed_pkts >= 8) || (flow->protos.stun_ssl.stun.num_binding_requests >= 4))
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE_CALL, NDPI_PROTOCOL_SKYPE);
} else {
NDPI_LOG_INFO(ndpi_struct, "found UDP stun\n");
ndpi_int_stun_add_connection(ndpi_struct,
- is_whatsapp ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_STUN, flow);
+ is_whatsapp ? (is_whatsapp == 1 ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_WHATSAPP_VIDEO) : NDPI_PROTOCOL_STUN,
+ flow);
}
-
+
return;
}
if(flow->protos.stun_ssl.stun.num_udp_pkts >= MAX_NUM_STUN_PKTS)
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
if(flow->packet_counter > 0) {
/* This might be a RTP stream: let's make sure we check it */
diff --git a/src/lib/protocols/viber.c b/src/lib/protocols/viber.c
index 65e227234..9aaa0e243 100644
--- a/src/lib/protocols/viber.c
+++ b/src/lib/protocols/viber.c
@@ -36,7 +36,7 @@ void ndpi_search_viber(struct ndpi_detection_module_struct *ndpi_struct, struct
if((packet->payload_packet_len == 12 && packet->payload[2] == 0x03 && packet->payload[3] == 0x00)
|| (packet->payload_packet_len == 20 && packet->payload[2] == 0x09 && packet->payload[3] == 0x00)
- || ((packet->payload_packet_len < 135) && (packet->payload[0] == 0x11))) {
+ ) {
NDPI_LOG_DBG(ndpi_struct, "found VIBER\n");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VIBER, NDPI_PROTOCOL_UNKNOWN);
return;
diff --git a/tests/result/1kxun.pcap.out b/tests/result/1kxun.pcap.out
index 637f29815..12fba107e 100644
--- a/tests/result/1kxun.pcap.out
+++ b/tests/result/1kxun.pcap.out
@@ -32,11 +32,11 @@ LLMNR 89 6799 47
15 TCP 192.168.115.8:49608 <-> 203.205.151.234:80 [proto: 7.48/HTTP.QQ][cat: Chat/9][18 pkts/3550 bytes <-> 7 pkts/1400 bytes][Host: vv.video.qq.com]
16 UDP 192.168.119.1:67 -> 255.255.255.255:68 [proto: 18/DHCP][cat: Network/14][14 pkts/4788 bytes -> 0 pkts/0 bytes]
17 TCP 192.168.5.16:53580 <-> 31.13.87.36:443 [proto: 64.119/SSL_No_Cert.Facebook][cat: SocialNetwork/6][4 pkts/2050 bytes <-> 5 pkts/2297 bytes]
- 18 TCP 192.168.5.16:53623 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][11 pkts/1959 bytes <-> 8 pkts/1683 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)]
- 19 TCP 192.168.5.16:53625 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][11 pkts/1955 bytes <-> 8 pkts/1683 bytes][TLSv1.2][JA3C: 618ee2509ef52bf0b8216e1564eea909][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)]
- 20 TCP 192.168.5.16:53629 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][10 pkts/1895 bytes <-> 7 pkts/1623 bytes][TLSv1.2][JA3C: 618ee2509ef52bf0b8216e1564eea909][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)]
+ 18 TCP 192.168.5.16:53623 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][11 pkts/1959 bytes <-> 8 pkts/1683 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)][TLS_RSA_WITH_AES_128_CBC_SHA]
+ 19 TCP 192.168.5.16:53625 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][11 pkts/1955 bytes <-> 8 pkts/1683 bytes][TLSv1.2][JA3C: 618ee2509ef52bf0b8216e1564eea909][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)][TLS_RSA_WITH_AES_128_CBC_SHA]
+ 20 TCP 192.168.5.16:53629 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][10 pkts/1895 bytes <-> 7 pkts/1623 bytes][TLSv1.2][JA3C: 618ee2509ef52bf0b8216e1564eea909][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)][TLS_RSA_WITH_AES_128_CBC_SHA]
21 TCP 192.168.115.8:49605 <-> 106.185.35.110:80 [proto: 7.137/HTTP.GenericProtocol][cat: Streaming/17][8 pkts/1128 bytes <-> 5 pkts/2282 bytes][Host: jp.kankan.1kxun.mobi]
- 22 TCP 192.168.5.16:53626 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][11 pkts/1943 bytes <-> 8 pkts/1267 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)]
+ 22 TCP 192.168.5.16:53626 <-> 192.168.115.75:443 [proto: 91/SSL][cat: Web/5][11 pkts/1943 bytes <-> 8 pkts/1267 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: 573a9f3f80037fb40d481e2054def5bb (WEAK)][TLS_RSA_WITH_AES_128_CBC_SHA]
23 TCP 192.168.115.8:49597 <-> 106.185.35.110:80 [proto: 7.137/HTTP.GenericProtocol][cat: Streaming/17][10 pkts/1394 bytes <-> 4 pkts/1464 bytes][Host: jp.kankan.1kxun.mobi]
24 TCP 31.13.87.1:443 <-> 192.168.5.16:53578 [proto: 64.119/SSL_No_Cert.Facebook][cat: SocialNetwork/6][5 pkts/1006 bytes <-> 5 pkts/1487 bytes]
25 UDP 192.168.5.57:55809 -> 239.255.255.250:1900 [proto: 12/SSDP][cat: System/18][14 pkts/2450 bytes -> 0 pkts/0 bytes]
@@ -53,8 +53,8 @@ LLMNR 89 6799 47
36 TCP 192.168.115.8:49607 <-> 218.244.135.170:9099 [proto: 7/HTTP][cat: Web/5][10 pkts/880 bytes <-> 3 pkts/572 bytes][Host: 218.244.135.170]
37 UDP 192.168.5.47:60267 -> 239.255.255.250:1900 [proto: 12/SSDP][cat: System/18][8 pkts/1432 bytes -> 0 pkts/0 bytes]
38 UDP 192.168.5.41:55312 -> 239.255.255.250:1900 [proto: 12/SSDP][cat: System/18][8 pkts/1400 bytes -> 0 pkts/0 bytes]
- 39 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][4 pkts/1368 bytes -> 0 pkts/0 bytes][Host: shen]
- 40 UDP 192.168.5.16:68 <-> 192.168.119.1:67 [proto: 18/DHCP][cat: Network/14][2 pkts/684 bytes <-> 2 pkts/684 bytes][Host: macbook-air]
+ 39 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][4 pkts/1368 bytes -> 0 pkts/0 bytes][Host: shen][DHCP Fingerprint: 1,121,3,6,15,119,252]
+ 40 UDP 192.168.5.16:68 <-> 192.168.119.1:67 [proto: 18/DHCP][cat: Network/14][2 pkts/684 bytes <-> 2 pkts/684 bytes][Host: macbook-air][DHCP Fingerprint: 1,3,6,15,119,95,252,44,46]
41 UDP 192.168.5.48:49701 -> 239.255.255.250:1900 [proto: 12/SSDP][cat: System/18][7 pkts/1253 bytes -> 0 pkts/0 bytes]
42 UDP 192.168.3.236:137 -> 192.168.255.255:137 [proto: 10/NetBIOS][cat: System/18][13 pkts/1196 bytes -> 0 pkts/0 bytes]
43 UDP 192.168.5.45:138 -> 192.168.255.255:138 [proto: 10/NetBIOS][cat: System/18][3 pkts/648 bytes -> 0 pkts/0 bytes]
@@ -64,8 +64,8 @@ LLMNR 89 6799 47
47 UDP [fe80::beee:7bff:fe0c:b3de]:546 -> [ff02::1:2]:547 [proto: 103/DHCPV6][cat: Network/14][4 pkts/392 bytes -> 0 pkts/0 bytes]
48 UDP 192.168.5.16:63372 <-> 168.95.1.1:53 [proto: 5/DNS][cat: Network/14][1 pkts/89 bytes <-> 1 pkts/289 bytes][Host: dl-obs.official.line.naver.jp]
49 TCP 192.168.115.8:49596 <-> 203.66.182.87:443 [proto: 91/SSL][cat: Web/5][4 pkts/220 bytes <-> 2 pkts/132 bytes]
- 50 UDP 192.168.5.9:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][1 pkts/342 bytes -> 0 pkts/0 bytes][Host: joanna-pc]
- 51 UDP 192.168.5.41:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][1 pkts/342 bytes -> 0 pkts/0 bytes][Host: kevin-pc]
+ 50 UDP 192.168.5.9:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][1 pkts/342 bytes -> 0 pkts/0 bytes][Host: joanna-pc][DHCP Fingerprint: 1,15,3,6,44,46,47,31,33,121,249,43,252]
+ 51 UDP 192.168.5.41:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][1 pkts/342 bytes -> 0 pkts/0 bytes][Host: kevin-pc][DHCP Fingerprint: 1,15,3,6,44,46,47,31,33,121,249,43,252]
52 UDP 192.168.115.8:60724 <-> 8.8.8.8:53 [proto: 5.137/DNS.GenericProtocol][cat: Streaming/17][2 pkts/146 bytes <-> 1 pkts/137 bytes][Host: pic.1kxun.com]
53 UDP 192.168.0.104:137 -> 192.168.255.255:137 [proto: 10/NetBIOS][cat: System/18][3 pkts/276 bytes -> 0 pkts/0 bytes]
54 UDP 192.168.115.8:51024 <-> 8.8.8.8:53 [proto: 5.137/DNS.GenericProtocol][cat: Streaming/17][2 pkts/160 bytes <-> 1 pkts/112 bytes][Host: jp.kankan.1kxun.mobi]
diff --git a/tests/result/6in4tunnel.pcap.out b/tests/result/6in4tunnel.pcap.out
index af700dfbb..bc101179a 100644
--- a/tests/result/6in4tunnel.pcap.out
+++ b/tests/result/6in4tunnel.pcap.out
@@ -4,7 +4,7 @@ SSL 28 15397 1
ICMPV6 48 7862 3
Facebook 37 14726 3
- 1 TCP [2001:470:1f17:13f:3e97:eff:fe73:4dec]:60205 <-> [2604:a880:1:20::224:b001]:443 [proto: 91/SSL][cat: Web/5][14 pkts/2312 bytes <-> 14 pkts/13085 bytes][TLSv1.2][JA3C: 812d8bce0f85487ba7834d36568ed586][server: mail.tomasu.net][JA3S: 389ed42c02ebecc32e73aa31def07e14]
+ 1 TCP [2001:470:1f17:13f:3e97:eff:fe73:4dec]:60205 <-> [2604:a880:1:20::224:b001]:443 [proto: 91/SSL][cat: Web/5][14 pkts/2312 bytes <-> 14 pkts/13085 bytes][TLSv1.2][JA3C: 812d8bce0f85487ba7834d36568ed586][server: mail.tomasu.net][JA3S: 389ed42c02ebecc32e73aa31def07e14][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
2 TCP [2001:470:1f17:13f:3e97:eff:fe73:4dec]:53234 <-> [2a03:2880:1010:6f03:face:b00c::2]:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][18 pkts/6894 bytes <-> 15 pkts/7032 bytes][TLSv1][JA3C: eb7cdd4e7dea7a11b3016c3c9acbd2a3]
3 ICMPV6 [2001:470:1f17:13f:3e97:eff:fe73:4dec]:0 <-> [2604:a880:1:20::224:b001]:0 [proto: 102/ICMPV6][cat: Network/14][23 pkts/3174 bytes <-> 23 pkts/3174 bytes]
4 TCP [2001:470:1f17:13f:3e97:eff:fe73:4dec]:41538 <-> [2604:a880:1:20::224:b001]:80 [proto: 7/HTTP][cat: Web/5][6 pkts/786 bytes <-> 4 pkts/1006 bytes][Host: mail.tomasu.net]
diff --git a/tests/result/KakaoTalk_chat.pcap.out b/tests/result/KakaoTalk_chat.pcap.out
index 55d11abdb..a9d6d1737 100644
--- a/tests/result/KakaoTalk_chat.pcap.out
+++ b/tests/result/KakaoTalk_chat.pcap.out
@@ -11,13 +11,13 @@ KakaoTalk 55 9990 15
1 TCP 10.24.82.188:43581 <-> 31.13.68.70:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][17 pkts/3461 bytes <-> 17 pkts/6194 bytes][TLSv1][JA3C: 051d20e8adbe8dac78945de300764d5e]
2 TCP 10.24.82.188:45211 <-> 31.13.68.84:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][14 pkts/2575 bytes <-> 15 pkts/6502 bytes][TLSv1][JA3C: 051d20e8adbe8dac78945de300764d5e]
3 TCP 10.24.82.188:45209 <-> 31.13.68.84:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][10 pkts/2584 bytes <-> 9 pkts/5123 bytes][TLSv1][JA3C: 051d20e8adbe8dac78945de300764d5e]
- 4 TCP 10.24.82.188:35503 <-> 173.252.97.2:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][20 pkts/2849 bytes <-> 18 pkts/4742 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.facebook.com][JA3S: 6c13ac74a6f75099ef2480748e5d94d2]
- 5 TCP 10.24.82.188:45213 <-> 31.13.68.84:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][15 pkts/2508 bytes <-> 13 pkts/5053 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.facebook.com][JA3S: 6c13ac74a6f75099ef2480748e5d94d2]
- 6 TCP 10.24.82.188:35511 <-> 173.252.97.2:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][18 pkts/2390 bytes <-> 18 pkts/4762 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.facebook.com][JA3S: 6c13ac74a6f75099ef2480748e5d94d2]
- 7 TCP 10.24.82.188:37821 <-> 210.103.240.15:443 [proto: 91.193/SSL.KakaoTalk][cat: Chat/9][13 pkts/2036 bytes <-> 14 pkts/5090 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.kakao.com][JA3S: 4192c0a946c5bd9b544b4656d9f624a4 (WEAK)]
+ 4 TCP 10.24.82.188:35503 <-> 173.252.97.2:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][20 pkts/2849 bytes <-> 18 pkts/4742 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.facebook.com][JA3S: 6c13ac74a6f75099ef2480748e5d94d2][TLS_ECDHE_ECDSA_WITH_RC4_128_SHA]
+ 5 TCP 10.24.82.188:45213 <-> 31.13.68.84:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][15 pkts/2508 bytes <-> 13 pkts/5053 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.facebook.com][JA3S: 6c13ac74a6f75099ef2480748e5d94d2][TLS_ECDHE_ECDSA_WITH_RC4_128_SHA]
+ 6 TCP 10.24.82.188:35511 <-> 173.252.97.2:443 [proto: 91.119/SSL.Facebook][cat: SocialNetwork/6][18 pkts/2390 bytes <-> 18 pkts/4762 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.facebook.com][JA3S: 6c13ac74a6f75099ef2480748e5d94d2][TLS_ECDHE_ECDSA_WITH_RC4_128_SHA]
+ 7 TCP 10.24.82.188:37821 <-> 210.103.240.15:443 [proto: 91.193/SSL.KakaoTalk][cat: Chat/9][13 pkts/2036 bytes <-> 14 pkts/5090 bytes][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][server: *.kakao.com][JA3S: 4192c0a946c5bd9b544b4656d9f624a4 (WEAK)][TLS_RSA_WITH_AES_128_CBC_SHA]
8 TCP 10.24.82.188:51021 <-> 103.246.57.251:8080 [proto: 131/HTTP_Proxy][cat: Web/5][17 pkts/2231 bytes <-> 9 pkts/1695 bytes]
9 TCP 139.150.0.125:443 <-> 10.24.82.188:46947 [proto: 91/SSL][cat: Web/5][9 pkts/1737 bytes <-> 9 pkts/672 bytes]
- 10 TCP 10.24.82.188:58964 <-> 54.255.253.199:5223 [proto: 91.178/SSL.Amazon][cat: Web/5][3 pkts/290 bytes <-> 3 pkts/1600 bytes][TLSv1][server: *.push.samsungosp.com][JA3S: 986d18bb49fadf70a73a06ead3780d55 (INSECURE)]
+ 10 TCP 10.24.82.188:58964 <-> 54.255.253.199:5223 [proto: 91.178/SSL.Amazon][cat: Web/5][3 pkts/290 bytes <-> 3 pkts/1600 bytes][TLSv1][server: *.push.samsungosp.com][JA3S: 986d18bb49fadf70a73a06ead3780d55 (INSECURE)][TLS_RSA_WITH_RC4_128_MD5]
11 TCP 10.24.82.188:37557 <-> 31.13.68.84:80 [proto: 7.119/HTTP.Facebook][cat: SocialNetwork/6][5 pkts/487 bytes <-> 6 pkts/627 bytes][Host: www.facebook.com]
12 TCP 10.24.82.188:37553 <-> 31.13.68.84:80 [proto: 7.119/HTTP.Facebook][cat: SocialNetwork/6][5 pkts/487 bytes <-> 5 pkts/571 bytes][Host: www.facebook.com]
13 TCP 216.58.221.10:80 <-> 10.24.82.188:35922 [proto: 7.126/HTTP.Google][cat: Web/5][7 pkts/392 bytes <-> 7 pkts/392 bytes]
diff --git a/tests/result/KakaoTalk_talk.pcap.out b/tests/result/KakaoTalk_talk.pcap.out
index a9f781f39..f9b99091d 100644
--- a/tests/result/KakaoTalk_talk.pcap.out
+++ b/tests/result/KakaoTalk_talk.pcap.out
@@ -12,7 +12,7 @@ KakaoTalk_Voice 44 6196 2
1 UDP 10.24.82.188:11320 <-> 1.201.1.174:23044 [proto: 87/RTP][cat: Media/1][757 pkts/106335 bytes <-> 746 pkts/93906 bytes]
2 UDP 10.24.82.188:10268 <-> 1.201.1.174:23046 [proto: 87/RTP][cat: Media/1][746 pkts/93906 bytes <-> 742 pkts/104604 bytes]
3 TCP 10.24.82.188:58857 <-> 110.76.143.50:9001 [proto: 163/Tor][cat: VPN/2][22 pkts/5326 bytes <-> 18 pkts/5212 bytes]
- 4 TCP 10.24.82.188:32968 <-> 110.76.143.50:8080 [proto: 91/SSL][cat: Web/5][23 pkts/4380 bytes <-> 22 pkts/5728 bytes][TLSv1][JA3C: 4b79ae67eb3b2cf1c75e68ea0100ca1b][server: Kakao.com][JA3S: 4ea82b75038dd27e8a1cb69d8b839b26 (WEAK)]
+ 4 TCP 10.24.82.188:32968 <-> 110.76.143.50:8080 [proto: 91/SSL][cat: Web/5][23 pkts/4380 bytes <-> 22 pkts/5728 bytes][TLSv1][JA3C: 4b79ae67eb3b2cf1c75e68ea0100ca1b][server: Kakao.com][JA3S: 4ea82b75038dd27e8a1cb69d8b839b26 (WEAK)][TLS_RSA_WITH_AES_128_CBC_SHA]
5 TCP 10.24.82.188:59954 <-> 173.252.88.128:443 [proto: 64.119/SSL_No_Cert.Facebook][cat: SocialNetwork/6][15 pkts/2932 bytes <-> 14 pkts/1092 bytes]
6 UDP 10.24.82.188:10269 <-> 1.201.1.174:23047 [proto: 194/KakaoTalk_Voice][cat: VoIP/10][12 pkts/1692 bytes <-> 10 pkts/1420 bytes]
7 UDP 10.24.82.188:11321 <-> 1.201.1.174:23045 [proto: 194/KakaoTalk_Voice][cat: VoIP/10][11 pkts/1542 bytes <-> 11 pkts/1542 bytes]
diff --git a/tests/result/dnscrypt.pcap.out b/tests/result/dnscrypt.pcap.out
index 56644e4e1..e62f6879b 100644
--- a/tests/result/dnscrypt.pcap.out
+++ b/tests/result/dnscrypt.pcap.out
@@ -1,6 +1,6 @@
SSL 111 44676 4
- 1 TCP 192.168.43.167:50233 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][18 pkts/1788 bytes <-> 21 pkts/14580 bytes][TLSv1.2][JA3C: b8f81673c0e1d29908346f3bab892b9b][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9]
- 2 TCP 192.168.43.167:50259 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][18 pkts/1988 bytes <-> 18 pkts/9290 bytes][TLSv1.2][JA3C: 83e04bc58d402f9633983cbf22724b02][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9]
- 3 TCP 192.168.43.167:50253 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][8 pkts/780 bytes <-> 10 pkts/7735 bytes][TLSv1.2][JA3C: 83e04bc58d402f9633983cbf22724b02][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9]
- 4 TCP 192.168.43.167:50258 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][8 pkts/780 bytes <-> 10 pkts/7735 bytes][TLSv1.2][JA3C: 83e04bc58d402f9633983cbf22724b02][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9]
+ 1 TCP 192.168.43.167:50233 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][18 pkts/1788 bytes <-> 21 pkts/14580 bytes][TLSv1.2][JA3C: b8f81673c0e1d29908346f3bab892b9b][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+ 2 TCP 192.168.43.167:50259 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][18 pkts/1988 bytes <-> 18 pkts/9290 bytes][TLSv1.2][JA3C: 83e04bc58d402f9633983cbf22724b02][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+ 3 TCP 192.168.43.167:50253 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][8 pkts/780 bytes <-> 10 pkts/7735 bytes][TLSv1.2][JA3C: 83e04bc58d402f9633983cbf22724b02][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+ 4 TCP 192.168.43.167:50258 <-> 134.119.26.24:443 [proto: 91/SSL][cat: Web/5][8 pkts/780 bytes <-> 10 pkts/7735 bytes][TLSv1.2][JA3C: 83e04bc58d402f9633983cbf22724b02][server: simplednscrypt.org][JA3S: 76cc3e2d3028143b23ec18e27dbd7ca9][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
diff --git a/tests/result/google_ssl.pcap.out b/tests/result/google_ssl.pcap.out
index d258599e3..969dbf587 100644
--- a/tests/result/google_ssl.pcap.out
+++ b/tests/result/google_ssl.pcap.out
@@ -1,3 +1,3 @@
Google 28 9108 1
- 1 TCP 172.31.3.224:42835 <-> 216.58.212.100:443 [proto: 91.126/SSL.Google][cat: Web/5][16 pkts/1512 bytes <-> 12 pkts/7596 bytes][TLSv1][server: www.google.com][JA3S: 7252ecc446aba4a3e474793ae320609a (INSECURE)]
+ 1 TCP 172.31.3.224:42835 <-> 216.58.212.100:443 [proto: 91.126/SSL.Google][cat: Web/5][16 pkts/1512 bytes <-> 12 pkts/7596 bytes][TLSv1][server: www.google.com][JA3S: 7252ecc446aba4a3e474793ae320609a (INSECURE)][TLS_RSA_WITH_RC4_128_SHA]
diff --git a/tests/result/skype.pcap.out b/tests/result/skype.pcap.out
index 7d5c04255..803cd7f7b 100644
--- a/tests/result/skype.pcap.out
+++ b/tests/result/skype.pcap.out
@@ -15,7 +15,7 @@ Spotify 5 430 1
MS_OneDrive 387 198090 1
ApplePush 12 1877 1
- 1 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 91.221/SSL.MS_OneDrive][cat: Cloud/13][187 pkts/42539 bytes <-> 200 pkts/155551 bytes][TLSv1][server: *.gateway.messenger.live.com][JA3S: d9699a2032a6c5371343b7f7dfd94abe]
+ 1 TCP 192.168.1.34:50028 <-> 157.56.126.211:443 [proto: 91.221/SSL.MS_OneDrive][cat: Cloud/13][187 pkts/42539 bytes <-> 200 pkts/155551 bytes][TLSv1][server: *.gateway.messenger.live.com][JA3S: d9699a2032a6c5371343b7f7dfd94abe][TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
2 TCP 192.168.1.34:50108 <-> 157.56.52.28:40009 [proto: 125/Skype][cat: VoIP/10][231 pkts/60232 bytes <-> 241 pkts/104395 bytes]
3 UDP 192.168.0.254:1025 -> 239.255.255.250:1900 [proto: 12/SSDP][cat: System/18][79 pkts/29479 bytes -> 0 pkts/0 bytes]
4 TCP 192.168.1.34:50128 <-> 17.172.100.36:443 [proto: 91.143/SSL.AppleiCloud][cat: Web/5][43 pkts/9635 bytes <-> 43 pkts/10651 bytes][TLSv1][JA3C: 799135475da362592a4be9199d258726]
diff --git a/tests/result/skype_no_unknown.pcap.out b/tests/result/skype_no_unknown.pcap.out
index 696fd3687..24ccc2309 100644
--- a/tests/result/skype_no_unknown.pcap.out
+++ b/tests/result/skype_no_unknown.pcap.out
@@ -13,7 +13,7 @@ Apple 76 19581 1
MS_OneDrive 348 181687 1
ApplePush 8 1118 1
- 1 TCP 192.168.1.34:51230 <-> 157.56.126.211:443 [proto: 91.221/SSL.MS_OneDrive][cat: Cloud/13][166 pkts/39042 bytes <-> 182 pkts/142645 bytes][TLSv1][server: *.gateway.messenger.live.com][JA3S: d9699a2032a6c5371343b7f7dfd94abe]
+ 1 TCP 192.168.1.34:51230 <-> 157.56.126.211:443 [proto: 91.221/SSL.MS_OneDrive][cat: Cloud/13][166 pkts/39042 bytes <-> 182 pkts/142645 bytes][TLSv1][server: *.gateway.messenger.live.com][JA3S: d9699a2032a6c5371343b7f7dfd94abe][TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
2 TCP 192.168.1.34:51279 <-> 111.221.74.48:40008 [proto: 125/Skype][cat: VoIP/10][101 pkts/30681 bytes <-> 98 pkts/59934 bytes]
3 TCP 192.168.1.34:51227 <-> 17.172.100.36:443 [proto: 64.140/SSL_No_Cert.Apple][cat: Web/5][38 pkts/9082 bytes <-> 38 pkts/10499 bytes]
4 UDP 192.168.0.254:1025 -> 239.255.255.250:1900 [proto: 12/SSDP][cat: System/18][36 pkts/13402 bytes -> 0 pkts/0 bytes]
diff --git a/tests/result/viber.pcap.out b/tests/result/viber.pcap.out
index 2241d4f71..10f6d2e18 100644
--- a/tests/result/viber.pcap.out
+++ b/tests/result/viber.pcap.out
@@ -10,12 +10,12 @@ Amazon 71 24849 3
1 TCP 192.168.0.17:53934 <-> 54.230.93.53:443 [proto: 91.144/SSL.Viber][cat: VoIP/10][43 pkts/4571 bytes <-> 46 pkts/60087 bytes][TLSv1][JA3C: d8c87b9bfde38897979e41242626c2f3]
2 TCP 192.168.0.17:57520 <-> 54.230.93.96:443 [proto: 91.144/SSL.Viber][cat: VoIP/10][12 pkts/1848 bytes <-> 12 pkts/9317 bytes][TLSv1][JA3C: d8c87b9bfde38897979e41242626c2f3]
- 3 TCP 192.168.0.17:49048 <-> 54.187.91.182:443 [proto: 91.178/SSL.Amazon][cat: Web/5][13 pkts/2823 bytes <-> 14 pkts/6552 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: *.apptimize.com][JA3S: 8d2a028aa94425f76ced7826b1f39039]
+ 3 TCP 192.168.0.17:49048 <-> 54.187.91.182:443 [proto: 91.178/SSL.Amazon][cat: Web/5][13 pkts/2823 bytes <-> 14 pkts/6552 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: *.apptimize.com][JA3S: 8d2a028aa94425f76ced7826b1f39039][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
4 TCP 192.168.0.17:33208 <-> 52.0.253.101:4244 [proto: 144/Viber][cat: VoIP/10][32 pkts/6563 bytes <-> 26 pkts/2782 bytes]
- 5 TCP 192.168.0.17:43702 <-> 172.217.23.78:443 [proto: 91.126/SSL.Google][cat: Web/5][15 pkts/5339 bytes <-> 12 pkts/3436 bytes][TLSv1.2][JA3C: 3967ff2d2c9c4d144e7e30f24f4e9761][JA3S: 67619a80665d7ab92d1041b1d11f9164]
- 6 TCP 192.168.0.17:36986 <-> 54.69.166.226:443 [proto: 91.178/SSL.Amazon][cat: Web/5][11 pkts/1437 bytes <-> 11 pkts/6412 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: *.apptimize.com][JA3S: 8d2a028aa94425f76ced7826b1f39039]
- 7 TCP 192.168.0.17:55746 <-> 151.101.1.130:443 [proto: 91/SSL][cat: Web/5][10 pkts/1534 bytes <-> 9 pkts/6239 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: y.ssl.fastly.net][JA3S: 860fcf58fd757e26aa8911e5eaff6b53]
- 8 TCP 192.168.0.17:36988 <-> 54.69.166.226:443 [proto: 91.178/SSL.Amazon][cat: Web/5][11 pkts/1462 bytes <-> 11 pkts/6163 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: *.apptimize.com][JA3S: 8d2a028aa94425f76ced7826b1f39039]
+ 5 TCP 192.168.0.17:43702 <-> 172.217.23.78:443 [proto: 91.126/SSL.Google][cat: Web/5][15 pkts/5339 bytes <-> 12 pkts/3436 bytes][TLSv1.2][JA3C: 3967ff2d2c9c4d144e7e30f24f4e9761][JA3S: 67619a80665d7ab92d1041b1d11f9164][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+ 6 TCP 192.168.0.17:36986 <-> 54.69.166.226:443 [proto: 91.178/SSL.Amazon][cat: Web/5][11 pkts/1437 bytes <-> 11 pkts/6412 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: *.apptimize.com][JA3S: 8d2a028aa94425f76ced7826b1f39039][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+ 7 TCP 192.168.0.17:55746 <-> 151.101.1.130:443 [proto: 91/SSL][cat: Web/5][10 pkts/1534 bytes <-> 9 pkts/6239 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: y.ssl.fastly.net][JA3S: 860fcf58fd757e26aa8911e5eaff6b53][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+ 8 TCP 192.168.0.17:36988 <-> 54.69.166.226:443 [proto: 91.178/SSL.Amazon][cat: Web/5][11 pkts/1462 bytes <-> 11 pkts/6163 bytes][TLSv1.2][JA3C: d8c87b9bfde38897979e41242626c2f3][server: *.apptimize.com][JA3S: 8d2a028aa94425f76ced7826b1f39039][TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
9 UDP 192.168.0.17:47171 <-> 18.201.4.32:7985 [proto: 144/Viber][cat: VoIP/10][24 pkts/5035 bytes <-> 22 pkts/2302 bytes]
10 UDP 192.168.0.17:38190 <-> 18.201.4.3:7985 [proto: 144/Viber][cat: VoIP/10][25 pkts/4344 bytes <-> 18 pkts/1872 bytes]
11 ICMP 192.168.0.17:0 <-> 192.168.0.15:0 [proto: 81/ICMP][cat: Network/14][1 pkts/1514 bytes <-> 1 pkts/1514 bytes]
diff --git a/tests/result/waze.pcap.out b/tests/result/waze.pcap.out
index c654f4165..aa285ecd2 100644
--- a/tests/result/waze.pcap.out
+++ b/tests/result/waze.pcap.out
@@ -6,19 +6,19 @@ Google 13 2142 1
Waze 484 289335 19
WhatsApp 15 1341 1
- 1 TCP 10.8.0.1:36100 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][52 pkts/10860 bytes <-> 55 pkts/74852 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)]
+ 1 TCP 10.8.0.1:36100 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][52 pkts/10860 bytes <-> 55 pkts/74852 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
2 TCP 10.8.0.1:54915 <-> 65.39.128.135:80 [proto: 7/HTTP][cat: Web/5][19 pkts/1309 bytes <-> 18 pkts/61896 bytes][Host: xtra1.gpsonextra.net]
- 3 TCP 10.8.0.1:39021 <-> 52.17.114.219:443 [proto: 91.135/SSL.Waze][cat: Web/5][17 pkts/1962 bytes <-> 16 pkts/56934 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
- 4 TCP 10.8.0.1:36312 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][cat: Web/5][17 pkts/2176 bytes <-> 15 pkts/42443 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
- 5 TCP 10.8.0.1:36316 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][cat: Web/5][15 pkts/1540 bytes <-> 13 pkts/26346 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
- 6 TCP 10.8.0.1:36102 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][19 pkts/2646 bytes <-> 18 pkts/9338 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)]
- 7 TCP 10.8.0.1:39010 <-> 52.17.114.219:443 [proto: 91.135/SSL.Waze][cat: Web/5][8 pkts/1034 bytes <-> 8 pkts/8151 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
- 8 TCP 10.8.0.1:51049 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][cat: Web/5][12 pkts/1282 bytes <-> 11 pkts/6541 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
- 9 TCP 10.8.0.1:51051 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][cat: Web/5][11 pkts/1228 bytes <-> 10 pkts/6487 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
- 10 TCP 10.8.0.1:36134 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][12 pkts/1650 bytes <-> 12 pkts/4935 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)]
- 11 TCP 10.8.0.1:36137 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][12 pkts/1522 bytes <-> 11 pkts/4220 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)]
- 12 TCP 10.8.0.1:36314 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][cat: Web/5][11 pkts/1260 bytes <-> 9 pkts/4413 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
- 13 TCP 10.8.0.1:51050 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][cat: Web/5][9 pkts/1184 bytes <-> 9 pkts/4369 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75]
+ 3 TCP 10.8.0.1:39021 <-> 52.17.114.219:443 [proto: 91.135/SSL.Waze][cat: Web/5][17 pkts/1962 bytes <-> 16 pkts/56934 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
+ 4 TCP 10.8.0.1:36312 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][cat: Web/5][17 pkts/2176 bytes <-> 15 pkts/42443 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
+ 5 TCP 10.8.0.1:36316 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][cat: Web/5][15 pkts/1540 bytes <-> 13 pkts/26346 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
+ 6 TCP 10.8.0.1:36102 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][19 pkts/2646 bytes <-> 18 pkts/9338 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 7 TCP 10.8.0.1:39010 <-> 52.17.114.219:443 [proto: 91.135/SSL.Waze][cat: Web/5][8 pkts/1034 bytes <-> 8 pkts/8151 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
+ 8 TCP 10.8.0.1:51049 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][cat: Web/5][12 pkts/1282 bytes <-> 11 pkts/6541 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
+ 9 TCP 10.8.0.1:51051 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][cat: Web/5][11 pkts/1228 bytes <-> 10 pkts/6487 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
+ 10 TCP 10.8.0.1:36134 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][12 pkts/1650 bytes <-> 12 pkts/4935 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 11 TCP 10.8.0.1:36137 <-> 46.51.173.182:443 [proto: 91.135/SSL.Waze][cat: Web/5][12 pkts/1522 bytes <-> 11 pkts/4220 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 12 TCP 10.8.0.1:36314 <-> 176.34.186.180:443 [proto: 91.135/SSL.Waze][cat: Web/5][11 pkts/1260 bytes <-> 9 pkts/4413 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.world.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
+ 13 TCP 10.8.0.1:51050 <-> 176.34.103.105:443 [proto: 91.135/SSL.Waze][cat: Web/5][9 pkts/1184 bytes <-> 9 pkts/4369 bytes][TLSv1][JA3C: f392f120f1087cd2f8814539cf58cfa4][server: *.waze.com][JA3S: 39f74f5618836d3c5f7dcccc9f67ba75][TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
14 TCP 10.8.0.1:45529 <-> 54.230.227.172:80 [proto: 7.135/HTTP.Waze][cat: Web/5][9 pkts/591 bytes <-> 8 pkts/3424 bytes][Host: roadshields.waze.com]
15 TCP 10.8.0.1:36585 <-> 173.194.118.48:443 [proto: 64.126/SSL_No_Cert.Google][cat: Web/5][7 pkts/1137 bytes <-> 6 pkts/1005 bytes]
16 TCP 10.8.0.1:45536 <-> 54.230.227.172:80 [proto: 7.135/HTTP.Waze][cat: Web/5][8 pkts/594 bytes <-> 7 pkts/771 bytes][Host: cres.waze.com]
diff --git a/tests/result/webex.pcap.out b/tests/result/webex.pcap.out
index c5383f501..b1a686011 100644
--- a/tests/result/webex.pcap.out
+++ b/tests/result/webex.pcap.out
@@ -6,36 +6,36 @@ Google 17 6375 1
Webex 1380 818407 43
Amazon 33 9742 2
- 1 TCP 10.8.0.1:51155 <-> 62.109.224.120:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][256 pkts/14707 bytes <-> 257 pkts/329379 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
+ 1 TCP 10.8.0.1:51155 <-> 62.109.224.120:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][256 pkts/14707 bytes <-> 257 pkts/329379 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
2 TCP 10.8.0.1:41348 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][28 pkts/4815 bytes <-> 28 pkts/104881 bytes][TLSv1][JA3C: f9010d8c34749bdf7659b52227e6f91b]
3 TCP 10.8.0.1:41346 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][48 pkts/11540 bytes <-> 47 pkts/80696 bytes][TLSv1][JA3C: f9010d8c34749bdf7659b52227e6f91b]
- 4 TCP 10.8.0.1:41358 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][19 pkts/2005 bytes <-> 19 pkts/40477 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 5 TCP 10.8.0.1:51194 <-> 62.109.224.120:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][12 pkts/1531 bytes <-> 12 pkts/34357 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 6 TCP 10.8.0.1:41354 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][13 pkts/2145 bytes <-> 13 pkts/24239 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 7 TCP 10.8.0.1:51154 <-> 62.109.224.120:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][55 pkts/12583 bytes <-> 50 pkts/6703 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
+ 4 TCP 10.8.0.1:41358 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][19 pkts/2005 bytes <-> 19 pkts/40477 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 5 TCP 10.8.0.1:51194 <-> 62.109.224.120:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][12 pkts/1531 bytes <-> 12 pkts/34357 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 6 TCP 10.8.0.1:41354 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][13 pkts/2145 bytes <-> 13 pkts/24239 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 7 TCP 10.8.0.1:51154 <-> 62.109.224.120:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][55 pkts/12583 bytes <-> 50 pkts/6703 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
8 UDP 10.8.0.1:64538 -> 172.16.1.75:5060 [proto: 100/SIP][cat: VoIP/10][22 pkts/15356 bytes -> 0 pkts/0 bytes]
- 9 TCP 10.8.0.1:51857 <-> 62.109.229.158:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][29 pkts/4559 bytes <-> 21 pkts/5801 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 4192c0a946c5bd9b544b4656d9f624a4 (WEAK)]
- 10 TCP 10.8.0.1:46211 <-> 54.241.32.14:443 [proto: 91.178/SSL.Amazon][cat: Web/5][16 pkts/1984 bytes <-> 14 pkts/7584 bytes][TLSv1][JA3C: 54ae5fcb0159e2ddf6a50e149221c7c7][server: *.crittercism.com][JA3S: c800cea031c10ffe47e1d72c9264577a (INSECURE)]
- 11 TCP 10.8.0.1:41386 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1417 bytes <-> 8 pkts/6984 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 12 TCP 10.8.0.1:41419 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1309 bytes <-> 7 pkts/6930 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 13 TCP 10.8.0.1:52730 <-> 173.243.4.76:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1369 bytes <-> 8 pkts/6621 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 14 TCP 10.8.0.1:44492 <-> 64.68.104.140:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1369 bytes <-> 8 pkts/6600 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 15 TCP 10.8.0.1:45814 <-> 62.109.231.3:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/1315 bytes <-> 8 pkts/6653 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 16 TCP 10.8.0.1:47498 <-> 209.197.222.159:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1261 bytes <-> 7 pkts/6535 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 17 TCP 10.8.0.1:57647 <-> 64.68.121.153:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1261 bytes <-> 7 pkts/6535 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 18 TCP 10.8.0.1:37129 <-> 64.68.105.98:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1369 bytes <-> 9 pkts/5838 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 19 TCP 10.8.0.1:51370 <-> 64.68.105.97:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/1315 bytes <-> 8 pkts/5784 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 20 TCP 10.8.0.1:55669 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1830 bytes <-> 12 pkts/4811 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 21 TCP 10.8.0.1:55665 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1798 bytes <-> 11 pkts/4757 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 22 TCP 10.8.0.1:55671 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1798 bytes <-> 11 pkts/4757 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 23 TCP 10.8.0.1:55687 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1798 bytes <-> 11 pkts/4757 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
+ 9 TCP 10.8.0.1:51857 <-> 62.109.229.158:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][29 pkts/4559 bytes <-> 21 pkts/5801 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 4192c0a946c5bd9b544b4656d9f624a4 (WEAK)][TLS_RSA_WITH_AES_128_CBC_SHA]
+ 10 TCP 10.8.0.1:46211 <-> 54.241.32.14:443 [proto: 91.178/SSL.Amazon][cat: Web/5][16 pkts/1984 bytes <-> 14 pkts/7584 bytes][TLSv1][JA3C: 54ae5fcb0159e2ddf6a50e149221c7c7][server: *.crittercism.com][JA3S: c800cea031c10ffe47e1d72c9264577a (INSECURE)][TLS_RSA_WITH_RC4_128_MD5]
+ 11 TCP 10.8.0.1:41386 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1417 bytes <-> 8 pkts/6984 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 12 TCP 10.8.0.1:41419 <-> 64.68.105.103:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1309 bytes <-> 7 pkts/6930 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 13 TCP 10.8.0.1:52730 <-> 173.243.4.76:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1369 bytes <-> 8 pkts/6621 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 14 TCP 10.8.0.1:44492 <-> 64.68.104.140:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1369 bytes <-> 8 pkts/6600 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 15 TCP 10.8.0.1:45814 <-> 62.109.231.3:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/1315 bytes <-> 8 pkts/6653 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 16 TCP 10.8.0.1:47498 <-> 209.197.222.159:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1261 bytes <-> 7 pkts/6535 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 17 TCP 10.8.0.1:57647 <-> 64.68.121.153:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1261 bytes <-> 7 pkts/6535 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 18 TCP 10.8.0.1:37129 <-> 64.68.105.98:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/1369 bytes <-> 9 pkts/5838 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 19 TCP 10.8.0.1:51370 <-> 64.68.105.97:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/1315 bytes <-> 8 pkts/5784 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 20 TCP 10.8.0.1:55669 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1830 bytes <-> 12 pkts/4811 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 21 TCP 10.8.0.1:55665 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1798 bytes <-> 11 pkts/4757 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 22 TCP 10.8.0.1:55671 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1798 bytes <-> 11 pkts/4757 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 23 TCP 10.8.0.1:55687 <-> 173.243.0.110:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][11 pkts/1798 bytes <-> 11 pkts/4757 bytes][TLSv1][JA3C: 64ea4359ad4b496db653a3f30f7073e6][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
24 TCP 10.8.0.1:43433 <-> 216.58.208.40:443 [proto: 91.126/SSL.Google][cat: Web/5][9 pkts/1540 bytes <-> 8 pkts/4835 bytes][TLSv1][JA3C: 75edb912bc6f0a222ae3e3e47f5c89b1]
- 25 TCP 10.8.0.1:51646 <-> 114.29.204.49:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/895 bytes <-> 8 pkts/4398 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 26 TCP 10.8.0.1:52219 <-> 64.68.121.100:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/841 bytes <-> 7 pkts/4376 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 27 TCP 10.8.0.1:55969 <-> 64.68.121.99:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/841 bytes <-> 7 pkts/4376 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 28 TCP 10.8.0.1:49048 <-> 23.44.253.243:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1181 bytes <-> 7 pkts/4021 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: www.webex.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)]
- 29 TCP 10.8.0.1:47116 <-> 114.29.202.139:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/461 bytes <-> 6 pkts/4231 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
- 30 TCP 10.8.0.1:47841 <-> 114.29.200.11:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][6 pkts/407 bytes <-> 5 pkts/4177 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)]
+ 25 TCP 10.8.0.1:51646 <-> 114.29.204.49:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][9 pkts/895 bytes <-> 8 pkts/4398 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 26 TCP 10.8.0.1:52219 <-> 64.68.121.100:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/841 bytes <-> 7 pkts/4376 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 27 TCP 10.8.0.1:55969 <-> 64.68.121.99:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][8 pkts/841 bytes <-> 7 pkts/4376 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 28 TCP 10.8.0.1:49048 <-> 23.44.253.243:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/1181 bytes <-> 7 pkts/4021 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: www.webex.com][JA3S: 714ac86d50db68420429ca897688f5f3 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 29 TCP 10.8.0.1:47116 <-> 114.29.202.139:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][7 pkts/461 bytes <-> 6 pkts/4231 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
+ 30 TCP 10.8.0.1:47841 <-> 114.29.200.11:443 [proto: 91.141/SSL.Webex][cat: VoIP/10][6 pkts/407 bytes <-> 5 pkts/4177 bytes][TLSv1][JA3C: 7cb93b2404a98399e9f84c74fef1fb8f][server: *.webex.com][JA3S: 91589ea825a2ee41810c85fab06d2ef6 (WEAK)][TLS_RSA_WITH_AES_256_CBC_SHA]
31 TCP 10.8.0.1:33551 <-> 80.74.110.68:443 [proto: 64/SSL_No_Cert][cat: Web/5][10 pkts/1465 bytes <-> 11 pkts/1065 bytes]
32 TCP 10.8.0.1:33553 <-> 80.74.110.68:443 [proto: 64/SSL_No_Cert][cat: Web/5][10 pkts/1388 bytes <-> 10 pkts/1087 bytes]
33 TCP 10.8.0.1:33512 <-> 80.74.110.68:443 [proto: 64/SSL_No_Cert][cat: Web/5][9 pkts/1357 bytes <-> 9 pkts/615 bytes]
diff --git a/tests/result/wechat.pcap.out b/tests/result/wechat.pcap.out
index e8f1f0db9..7d306b94e 100644
--- a/tests/result/wechat.pcap.out
+++ b/tests/result/wechat.pcap.out
@@ -79,7 +79,7 @@ GoogleDocs 15 5114 2
64 TCP 192.168.1.103:58226 -> 203.205.147.171:443 [proto: 91.197/SSL.WeChat][cat: SocialNetwork/6][6 pkts/396 bytes -> 0 pkts/0 bytes]
65 UDP 192.168.1.103:53734 <-> 192.168.1.254:53 [proto: 5.126/DNS.Google][cat: Web/5][1 pkts/94 bytes <-> 1 pkts/272 bytes][Host: safebrowsing.googleusercontent.com]
66 TCP 192.168.1.103:58043 <-> 203.205.147.171:443 [proto: 91.197/SSL.WeChat][cat: SocialNetwork/6][3 pkts/206 bytes <-> 2 pkts/148 bytes]
- 67 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][1 pkts/342 bytes -> 0 pkts/0 bytes][Host: iphonedimonica]
+ 67 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][1 pkts/342 bytes -> 0 pkts/0 bytes][Host: iphonedimonica][DHCP Fingerprint: 1,121,3,6,15,119,252]
68 UDP 192.168.1.103:46078 <-> 192.168.1.254:53 [proto: 5.126/DNS.Google][cat: Web/5][1 pkts/75 bytes <-> 1 pkts/234 bytes][Host: ssl.gstatic.com]
69 UDP 192.168.1.103:60562 <-> 192.168.1.254:53 [proto: 5.126/DNS.Google][cat: Web/5][1 pkts/75 bytes <-> 1 pkts/234 bytes][Host: ssl.gstatic.com]
70 UDP 192.168.1.103:55862 <-> 192.168.1.254:53 [proto: 5.241/DNS.GoogleDocs][cat: Media/1][1 pkts/75 bytes <-> 1 pkts/227 bytes][Host: docs.google.com]
diff --git a/tests/result/whatsapp_login_call.pcap.out b/tests/result/whatsapp_login_call.pcap.out
index 11901a908..e35755516 100644
--- a/tests/result/whatsapp_login_call.pcap.out
+++ b/tests/result/whatsapp_login_call.pcap.out
@@ -15,12 +15,12 @@ ApplePush 22 5926 1
1 UDP 192.168.2.4:51518 <-> 91.253.176.65:9344 [proto: 189/WhatsAppVoice][cat: VoIP/10][186 pkts/27025 bytes <-> 278 pkts/25895 bytes]
2 UDP 192.168.2.4:52794 <-> 91.253.176.65:9665 [proto: 189/WhatsAppVoice][cat: VoIP/10][141 pkts/17530 bytes <-> 57 pkts/12888 bytes]
3 TCP 192.168.2.4:49202 <-> 184.173.179.37:5222 [proto: 142/WhatsApp][cat: Chat/9][100 pkts/14711 bytes <-> 80 pkts/10163 bytes]
- 4 TCP 192.168.2.4:49204 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][cat: Web/5][29 pkts/11770 bytes <-> 24 pkts/6612 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: c253ec3ad88e42f8da4032682892f9a0 (INSECURE)]
+ 4 TCP 192.168.2.4:49204 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][cat: Web/5][29 pkts/11770 bytes <-> 24 pkts/6612 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: c253ec3ad88e42f8da4032682892f9a0 (INSECURE)][TLS_RSA_WITH_RC4_128_MD5]
5 TCP 192.168.2.4:49201 <-> 17.178.104.12:443 [proto: 91.140/SSL.Apple][cat: Web/5][21 pkts/7644 bytes <-> 17 pkts/9576 bytes][TLSv1][JA3C: 799135475da362592a4be9199d258726]
- 6 TCP 192.168.2.4:49205 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][cat: Web/5][17 pkts/6166 bytes <-> 15 pkts/3539 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: c253ec3ad88e42f8da4032682892f9a0 (INSECURE)]
+ 6 TCP 192.168.2.4:49205 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][cat: Web/5][17 pkts/6166 bytes <-> 15 pkts/3539 bytes][TLSv1.2][JA3C: 799135475da362592a4be9199d258726][JA3S: c253ec3ad88e42f8da4032682892f9a0 (INSECURE)][TLS_RSA_WITH_RC4_128_MD5]
7 TCP 192.168.2.4:49193 <-> 17.110.229.14:5223 [proto: 238/ApplePush][cat: Cloud/13][11 pkts/4732 bytes <-> 11 pkts/1194 bytes]
8 UDP 192.168.2.4:51518 <-> 31.13.93.48:3478 [proto: 189/WhatsAppVoice][cat: VoIP/10][12 pkts/2341 bytes <-> 12 pkts/2484 bytes]
- 9 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][10 pkts/3420 bytes -> 0 pkts/0 bytes][Host: lucas-imac]
+ 9 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][10 pkts/3420 bytes -> 0 pkts/0 bytes][Host: lucas-imac][DHCP Fingerprint: 1,3,6,15,119,95,252,44,46]
10 UDP 192.168.2.4:52794 <-> 31.13.84.48:3478 [proto: 189/WhatsAppVoice][cat: VoIP/10][9 pkts/1842 bytes <-> 11 pkts/1151 bytes]
11 UDP 192.168.2.1:17500 -> 192.168.2.255:17500 [proto: 121/Dropbox][cat: Cloud/13][4 pkts/2176 bytes -> 0 pkts/0 bytes]
12 TCP 192.168.2.4:49199 <-> 17.172.100.70:993 [proto: 51.140/IMAPS.Apple][cat: Web/5][9 pkts/1130 bytes <-> 8 pkts/868 bytes]
diff --git a/tests/result/whatsapp_login_chat.pcap.out b/tests/result/whatsapp_login_chat.pcap.out
index 04aaaccf4..705d0b491 100644
--- a/tests/result/whatsapp_login_chat.pcap.out
+++ b/tests/result/whatsapp_login_chat.pcap.out
@@ -9,7 +9,7 @@ ApplePush 6 2095 1
1 TCP 192.168.2.4:49205 <-> 17.173.66.102:443 [proto: 91.140/SSL.Apple][cat: Web/5][24 pkts/15117 bytes <-> 20 pkts/6254 bytes]
2 TCP 192.168.2.4:49206 <-> 158.85.58.15:5222 [proto: 142/WhatsApp][cat: Chat/9][17 pkts/1794 bytes <-> 13 pkts/1169 bytes]
3 TCP 17.110.229.14:5223 -> 192.168.2.4:49193 [proto: 238/ApplePush][cat: Cloud/13][6 pkts/2095 bytes -> 0 pkts/0 bytes]
- 4 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][6 pkts/2052 bytes -> 0 pkts/0 bytes][Host: lucas-imac]
+ 4 UDP 0.0.0.0:68 -> 255.255.255.255:67 [proto: 18/DHCP][cat: Network/14][6 pkts/2052 bytes -> 0 pkts/0 bytes][Host: lucas-imac][DHCP Fingerprint: 1,3,6,15,119,95,252,44,46]
5 UDP 192.168.2.1:17500 -> 192.168.2.255:17500 [proto: 121/Dropbox][cat: Cloud/13][2 pkts/1088 bytes -> 0 pkts/0 bytes]
6 UDP 192.168.2.4:61697 <-> 192.168.2.1:53 [proto: 5.142/DNS.WhatsApp][cat: Chat/9][1 pkts/76 bytes <-> 1 pkts/204 bytes][Host: e12.whatsapp.net]
7 UDP [fe80::189c:c31b:1298:224]:5353 -> [ff02::fb]:5353 [proto: 8/MDNS][cat: Network/14][1 pkts/111 bytes -> 0 pkts/0 bytes]