From 564d622cc994dc0f2960b3beb0af1ebe02881187 Mon Sep 17 00:00:00 2001
From: Luca Deri <deri@ntop.org>
Date: Fri, 11 May 2018 13:48:14 +0200
Subject: Added ndpi_fill_protocol_category call Introduced intitial Skype
 in/out support

---
 src/lib/protocols/rtp.c  |   3 +
 src/lib/protocols/stun.c | 148 ++++++++++-------------------------------------
 2 files changed, 34 insertions(+), 117 deletions(-)

(limited to 'src/lib/protocols')

diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c
index 2f19acf46..38cd62504 100644
--- a/src/lib/protocols/rtp.c
+++ b/src/lib/protocols/rtp.c
@@ -103,9 +103,12 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct,
       ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE, NDPI_PROTOCOL_UNKNOWN);
       return;
     } else /* RTCP */ {
+#if 0
+      /* If it's RTCP the RTCP decoder will catch it */
       NDPI_LOG_INFO(ndpi_struct, "Found MS RTCP\n");
       ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RTCP, NDPI_PROTOCOL_UNKNOWN);
       return;
+#endif
     }
   }  
 
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index bb4780aab..1f5ed34f4 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -52,14 +52,15 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
 					   struct ndpi_flow_struct *flow,
 					   const u_int8_t * payload,
 					   const u_int16_t payload_length,
-					   u_int8_t *is_whatsapp,
-					   u_int8_t *is_skype) {
+					   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;
 
+  flow->protos.stun.num_processed_pkts++;
+  
   if(payload_length < sizeof(struct stun_packet_header)) {
-    if(flow->num_stun_udp_pkts > 0) {
+    if(flow->protos.stun.num_udp_pkts > 0) {
       *is_whatsapp = 1;
       return NDPI_IS_STUN; /* This is WhatsApp Voice */
     } else
@@ -74,6 +75,9 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
 
   msg_type = ntohs(h->msg_type) & 0x3EEF, msg_len = ntohs(h->msg_len);
 
+  if(ntohs(h->msg_type) == 0x01 /* Binding Request */)
+    flow->protos.stun.num_binding_requests++;
+  
   if((payload[0] != 0x80) && ((msg_len+20) > payload_length))
     return(NDPI_IS_NOT_STUN);
 
@@ -112,7 +116,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
 	   && (payload[offset+6] == 0x00)
 	   && (payload[offset+7] == 0x00)) {
 	  /* Either skype for business or "normal" skype with multiparty call */
-	  *is_skype = 1;
+	  flow->protos.stun.is_skype = 1;
 	  return(NDPI_IS_STUN);
 	}
 	break;
@@ -125,7 +129,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
 	   && (payload[offset+6] == 0x00)
 	   && ((payload[offset+7] == 0x02) || (payload[offset+7] == 0x03))
 	   ) {
-	  *is_skype = 1;
+	  flow->protos.stun.is_skype = 1;
 	  return(NDPI_IS_STUN);
 	}
 	break;
@@ -141,117 +145,17 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
     goto udp_stun_found;
   }
 
-#ifdef ORIGINAL_CODE
-  /*
-   * token list of message types and attribute types from
-   * http://wwwbs1.informatik.htw-dresden.de/svortrag/i02/Schoene/stun/stun.html
-   * the same list you can find in
-   * https://summersoft.fay.ar.us/repos/ethereal/branches/redhat-9/ethereal-0.10.3-1/ethereal-0.10.3/packet-stun.c
-   * token further message types and attributes from
-   * http://www.freeswitch.org/docs/group__stun1.html
-   * added further attributes observed
-   * message types: 0x0001, 0x0101, 0x0111, 0x0002, 0x0102, 0x0112, 0x0003, 0x0103, 0x0004, 0x0104, 0x0114, 0x0115
-   * attribute types: 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
-   * 0x000a, 0x000b, 0c000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0020,
-   * 0x0022, 0x0024, 0x8001, 0x8006, 0x8008, 0x8015, 0x8020, 0x8028, 0x802a, 0x8029, 0x8050, 0x8054, 0x8055
-   *
-   * 0x8003, 0x8004 used by facetime
-   */
-
-  if(payload_length >= 20 && ntohs(get_u_int16_t(payload, 2)) + 20 == payload_length &&
-     ((payload[0] == 0x00 && (payload[1] >= 0x01 && payload[1] <= 0x04)) ||
-      (payload[0] == 0x01 &&
-       ((payload[1] >= 0x01 && payload[1] <= 0x04) || (payload[1] >= 0x11 && payload[1] <= 0x15))))) {
-    u_int8_t mod;
-    u_int8_t old = 1;
-    u_int8_t padding = 0;
-    NDPI_LOG_DBG2(ndpi_struct, "len and type match\n");
-
-    if(payload_length == 20) {
-      NDPI_LOG_INFO(ndpi_struct, "found stun\n");
-      goto udp_stun_found;
-    }
-
-    a = 20;
-
-    while (a < payload_length) {
-
-      if(old && payload_length >= a + 4
-	 &&
-	 ((payload[a] == 0x00
-	   && ((payload[a + 1] >= 0x01 && payload[a + 1] <= 0x16) || payload[a + 1] == 0x19
-	       || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x24
-	       || payload[a + 1] == 0x25))
-	  || (payload[a] == 0x80
-	      && (payload[a + 1] == 0x01 || payload[a + 1] == 0x03 || payload[a + 1] == 0x04
-		  || payload[a + 1] == 0x06 || payload[a + 1] == 0x08 || payload[a + 1] == 0x15
-		  || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x28
-		  || payload[a + 1] == 0x2a || payload[a + 1] == 0x29 || payload[a + 1] == 0x50
-		  || payload[a + 1] == 0x54 || payload[a + 1] == 0x55)))) {
-
-	NDPI_LOG_DBG2(ndpi_struct, "attribute match\n");
-
-	a += ((payload[a + 2] << 8) + payload[a + 3] + 4);
-	mod = a % 4;
-	if(mod) {
-	  padding = 4 - mod;
-	}
-	if(a == payload_length || (padding && (a + padding) == payload_length)) {
-	  NDPI_LOG_INFO(ndpi_struct, "found stun\n");
-	  goto udp_stun_found;
-	}
-
-      } else if(payload_length >= a + padding + 4
-		&&
-		((payload[a + padding] == 0x00
-		  && ((payload[a + 1 + padding] >= 0x01 && payload[a + 1 + padding] <= 0x16)
-		      || payload[a + 1 + padding] == 0x19 || payload[a + 1 + padding] == 0x20
-		      || payload[a + 1 + padding] == 0x22 || payload[a + 1 + padding] == 0x24
-		      || payload[a + 1 + padding] == 0x25))
-		 || (payload[a + padding] == 0x80
-		     && (payload[a + 1 + padding] == 0x01 || payload[a + 1 + padding] == 0x03
-			 || payload[a + 1 + padding] == 0x04 || payload[a + 1 + padding] == 0x06
-			 || payload[a + 1 + padding] == 0x08 || payload[a + 1 + padding] == 0x15
-			 || payload[a + 1 + padding] == 0x20 || payload[a + 1 + padding] == 0x22
-			 || payload[a + 1 + padding] == 0x28 || payload[a + 1 + padding] == 0x2a
-			 || payload[a + 1 + padding] == 0x29 || payload[a + 1 + padding] == 0x50
-			 || payload[a + 1 + padding] == 0x54 || payload[a + 1 + padding] == 0x55))
-		 || ((payload[a + padding] == 0x40) && (payload[a + padding + 1] == 0x00))
-		 )) {
-	if((payload[a + padding] == 0x40) && (payload[a + padding + 1] == 0x00))
-	  goto udp_stun_found;
-
-	NDPI_LOG_DBG2(ndpi_struct, "New STUN - attribute match\n");
-
-	old = 0;
-	a += ((payload[a + 2 + padding] << 8) + payload[a + 3 + padding] + 4);
-	padding = 0;
-	mod = a % 4;
-	if(mod) {
-	  a += 4 - mod;
-	}
-	if(a == payload_length) {
-	  NDPI_LOG_INFO(ndpi_struct, "found stun\n");
-	  goto udp_stun_found;
-	}
-      } else {
-	break;
-      }
-    }
-  }
-#endif
-
-  if((flow->num_stun_udp_pkts > 0) && (msg_type <= 0x00FF)) {
+  if((flow->protos.stun.num_udp_pkts > 0) && (msg_type <= 0x00FF)) {
     *is_whatsapp = 1;
     return NDPI_IS_STUN; /* This is WhatsApp Voice */
   } else
     return NDPI_IS_NOT_STUN;
 
- udp_stun_found:
+ udp_stun_found:      
   if(can_this_be_whatsapp_voice) {
-    flow->num_stun_udp_pkts++;
+    flow->protos.stun.num_udp_pkts++;
 
-    return((flow->num_stun_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN);
+    return((flow->protos.stun.num_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN);
   } else {
     /*
       We cannot immediately say that this is STUN as there are other protocols
@@ -266,7 +170,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
 void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
 {
   struct ndpi_packet_struct *packet = &flow->packet;
-  u_int8_t is_whatsapp = 0, is_skype = 0;
+  u_int8_t is_whatsapp = 0;
 
   NDPI_LOG_DBG(ndpi_struct, "search stun\n");
 
@@ -280,10 +184,14 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
        * improved by checking only the STUN packet of given length */
 
       if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload + 2,
-			     packet->payload_packet_len - 2, &is_whatsapp, &is_skype) == NDPI_IS_STUN) {
-	if(is_skype) {
+			     packet->payload_packet_len - 2, &is_whatsapp) == NDPI_IS_STUN) {
+	if(flow->guessed_protocol_id == 0) flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
+
+	if(flow->protos.stun.is_skype) {
 	  NDPI_LOG_INFO(ndpi_struct, "found Skype\n");
-	  ndpi_int_stun_add_connection(ndpi_struct, NDPI_PROTOCOL_SKYPE, flow);
+
+	  if((flow->protos.stun.num_processed_pkts >= 8) || (flow->protos.stun.num_binding_requests >= 4))
+	    ndpi_int_stun_add_connection(ndpi_struct, (flow->protos.stun.num_binding_requests < 4) ? NDPI_PROTOCOL_SKYPE_CALL_IN : NDPI_PROTOCOL_SKYPE_CALL_OUT, flow);
 	} 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,
@@ -296,10 +204,16 @@ 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, &is_skype) == NDPI_IS_STUN) {
-    if(is_skype) {
+			 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.is_skype) {
       NDPI_LOG_INFO(ndpi_struct, "Found Skype\n");
-      ndpi_int_stun_add_connection(ndpi_struct, NDPI_PROTOCOL_SKYPE, flow);
+      
+      if((flow->protos.stun.num_processed_pkts >= 8) || (flow->protos.stun.num_binding_requests >= 4))
+	ndpi_int_stun_add_connection(ndpi_struct,
+				     (flow->protos.stun.num_binding_requests < 4) ? NDPI_PROTOCOL_SKYPE_CALL_IN : NDPI_PROTOCOL_SKYPE_CALL_OUT,
+				     flow);
     } else {
       NDPI_LOG_INFO(ndpi_struct, "found UDP stun\n");
       ndpi_int_stun_add_connection(ndpi_struct,
@@ -309,7 +223,7 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
     return;
   }
 
-  if(flow->num_stun_udp_pkts >= MAX_NUM_STUN_PKTS)
+  if(flow->protos.stun.num_udp_pkts >= MAX_NUM_STUN_PKTS)
     NDPI_EXCLUDE_PROTO(ndpi_struct, flow);  
 
   if(flow->packet_counter > 0) {
-- 
cgit v1.2.3