aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/ndpiReader.c20
-rw-r--r--example/ndpi_util.c26
-rw-r--r--src/include/ndpi_protocol_ids.h2
-rw-r--r--src/lib/ndpi_content_match.c.inc1
-rw-r--r--src/lib/ndpi_main.c4
-rw-r--r--src/lib/protocols/btlib.c10
-rw-r--r--src/lib/protocols/memcached.c160
-rw-r--r--src/lib/protocols/openvpn.c69
-rw-r--r--src/lib/protocols/stun.c191
-rw-r--r--src/lib/protocols/viber.c2
10 files changed, 275 insertions, 210 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 25886af31..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
@@ -899,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));
@@ -1440,6 +1438,7 @@ static void node_idle_scan_walker(const void *node, ndpi_VISIT which, int depth,
}
}
+/* *********************************************** */
/**
* @brief On Protocol Discover - demo callback
@@ -1450,6 +1449,8 @@ static void on_protocol_discovered(struct ndpi_workflow * workflow,
;
}
+/* *********************************************** */
+
#if 0
/**
* @brief Print debug
@@ -1457,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;
@@ -1491,6 +1491,8 @@ static void debug_printf(u_int32_t protocol, void *id_struct,
}
#endif
+/* *********************************************** */
+
/**
* @brief Setup for detection begin
*/
@@ -1578,6 +1580,7 @@ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle) {
}
}
+/* *********************************************** */
/**
* @brief End of detection and free flow
@@ -1586,6 +1589,7 @@ static void terminateDetection(u_int16_t thread_id) {
ndpi_workflow_free(ndpi_thread_info[thread_id].workflow);
}
+/* *********************************************** */
/**
* @brief Traffic stats format
@@ -1622,6 +1626,7 @@ char* formatTraffic(float numBits, int bits, char *buf) {
return(buf);
}
+/* *********************************************** */
/**
* @brief Packets stats format
@@ -1640,6 +1645,7 @@ char* formatPackets(float numPkts, char *buf) {
return(buf);
}
+/* *********************************************** */
/**
* @brief JSON function init
@@ -1651,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))
||
@@ -1661,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 c8e0130ff..e453a3461 100644
--- a/example/ndpi_util.c
+++ b/example/ndpi_util.c
@@ -246,21 +246,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); }
@@ -376,10 +376,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) {
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/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 85fed4d0c..bf9c4069e 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -983,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,
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/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/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;