aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/protocols/stun.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index e21f9331b..1b2bb9843 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -29,7 +29,6 @@
#define MAX_NUM_STUN_PKTS 10
-
struct stun_packet_header {
u_int16_t msg_type, msg_len;
u_int32_t cookie;
@@ -48,13 +47,14 @@ typedef enum {
static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- const u_int8_t * payload,
+ const u_int8_t * payload,
const u_int16_t payload_length,
u_int8_t *is_whatsapp,
u_int8_t *is_lync) {
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;
+
if(payload_length < sizeof(struct stun_packet_header)) {
if(flow->num_stun_udp_pkts > 0) {
*is_whatsapp = 1;
@@ -68,18 +68,18 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "Found stun.\n");
goto udp_stun_found;
}
-
+
msg_type = ntohs(h->msg_type) & 0x3EEF, msg_len = ntohs(h->msg_len);
if((payload[0] != 0x80) && ((msg_len+20) > payload_length))
return(NDPI_IS_NOT_STUN);
/* printf("msg_type=%04X, msg_len=%u\n", msg_type, msg_len); */
-
+
if((payload_length == (msg_len+20))
&& ((msg_type <= 0x000b) /* http://www.3cx.com/blog/voip-howto/stun-details/ */)) {
u_int offset = 20;
-
+
/*
This can either be the standard RTCP or Ms Lync RTCP that
later will becomg Ms Lync RTP. In this case we need to
@@ -91,6 +91,12 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
u_int16_t len = ntohs(*((u_int16_t*)&payload[offset+2]));
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)
&& (payload[offset+4] == 0x31)
@@ -101,7 +107,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
return(NDPI_IS_STUN);
}
break;
-
+
case 0x8070: /* Implementation Version */
if((len == 4)
&& (payload[offset+4] == 0x00)
@@ -110,15 +116,20 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
&& (payload[offset+7] == 0x02)) {
*is_lync = 1;
return(NDPI_IS_STUN);
- }
- break;
+ }
+ break;
+
+ default:
+ /* This means this STUN packet cannot be confused with whatsapp voice */
+ can_this_be_whatsapp_voice = 0;
+ break;
}
offset += len + 4;
}
- goto udp_stun_found;
+ goto udp_stun_found;
}
-
+
#ifdef ORIGINAL_CODE
/*
* token list of message types and attribute types from
@@ -224,11 +235,12 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
*is_whatsapp = 1;
return NDPI_IS_STUN; /* This is WhatsApp Voice */
} else
- return NDPI_IS_NOT_STUN;
+ return NDPI_IS_NOT_STUN;
udp_stun_found:
- flow->num_stun_udp_pkts++;
-
+ if(can_this_be_whatsapp_voice)
+ flow->num_stun_udp_pkts++;
+
return((flow->num_stun_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN);
}
@@ -244,11 +256,11 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
if(packet->payload_packet_len >= 2 + 20 &&
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 */
- if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload + 2,
+ if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload + 2,
packet->payload_packet_len - 2, &is_whatsapp, &is_lync) == NDPI_IS_STUN) {
NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found TCP stun.\n");
ndpi_int_stun_add_connection(ndpi_struct, NDPI_PROTOCOL_STUN, flow);
@@ -257,14 +269,14 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
}
}
- if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload,
+ if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload,
packet->payload_packet_len, &is_whatsapp, &is_lync) == NDPI_IS_STUN) {
if(is_lync) {
NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "Found MS Lync\n");
ndpi_int_stun_add_connection(ndpi_struct, NDPI_PROTOCOL_MS_LYNC, flow);
} else {
NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found UDP stun.\n");
- ndpi_int_stun_add_connection(ndpi_struct,
+ ndpi_int_stun_add_connection(ndpi_struct,
is_whatsapp ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_STUN, flow);
}
return;