aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/protocols')
-rw-r--r--src/lib/protocols/rtp.c2
-rw-r--r--src/lib/protocols/stun.c78
-rw-r--r--src/lib/protocols/telegram.c8
3 files changed, 81 insertions, 7 deletions
diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c
index 5a27d887b..f859aba4e 100644
--- a/src/lib/protocols/rtp.c
+++ b/src/lib/protocols/rtp.c
@@ -269,7 +269,7 @@ static void ndpi_int_rtp_add_connection(struct ndpi_detection_module_struct *ndp
from the beginning */
if(!(flow->l4_proto == IPPROTO_TCP && ndpi_seen_flow_beginning(flow))) {
NDPI_LOG_DBG(ndpi_struct, "Enabling (STUN) extra dissection\n");
- switch_extra_dissection_to_stun(ndpi_struct, flow);
+ switch_extra_dissection_to_stun(ndpi_struct, flow, 1);
}
}
}
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index 515a4ba8c..4ffb5568c 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -61,7 +61,8 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
/* Valid classifications:
- * STUN, DTLS, STUN/RTP, DTLS/SRTP, RTP or RTCP (the last two, only from RTP dissector)
+ * STUN, DTLS, STUN/RTP, DTLS/SRTP, RTP or RTCP (only from RTP dissector)
+ and TELEGRAM (only from Telegram dissector, note that TELEGRAM != TELEGRAM_VOIP!!)
* STUN/APP, DTLS/APP, SRTP/APP ["real" sub-classification]
The idea is:
* the specific "real" application (WA/FB/Signal/...), if present, should
@@ -79,7 +80,8 @@ static int is_subclassification_real_by_proto(u_int16_t proto)
proto == NDPI_PROTOCOL_RTP ||
proto == NDPI_PROTOCOL_RTCP ||
proto == NDPI_PROTOCOL_SRTP ||
- proto == NDPI_PROTOCOL_DTLS)
+ proto == NDPI_PROTOCOL_DTLS ||
+ proto == NDPI_PROTOCOL_TELEGRAM)
return 0;
return 1;
}
@@ -493,6 +495,9 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
*app_proto = NDPI_PROTOCOL_SIGNAL_VOIP;
}
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TELEGRAM)
+ *app_proto = NDPI_PROTOCOL_TELEGRAM_VOIP;
+
off = STUN_HDR_LEN;
while(off + 4 < payload_length) {
u_int16_t attribute = ntohs(*((u_int16_t *)&payload[off]));
@@ -783,7 +788,8 @@ static u_int32_t __get_master(struct ndpi_flow_struct *flow) {
if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
return flow->detected_protocol_stack[1];
- if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN &&
+ flow->detected_protocol_stack[0] != NDPI_PROTOCOL_TELEGRAM)
return flow->detected_protocol_stack[0];
return NDPI_PROTOCOL_STUN;
}
@@ -1039,6 +1045,62 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
/* ************************************************************ */
+static int stun_telegram_search_again(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &ndpi_struct->packet;
+ const u_int8_t *orig_payload;
+ u_int16_t orig_payload_length;
+ char pattern[12] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ u_int16_t length;
+
+ NDPI_LOG_DBG2(ndpi_struct, "[T] Packet counter %d protos %d/%d Monitoring? %d\n",
+ flow->packet_counter,
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1],
+ flow->monitoring);
+
+ /* For SOME of its STUN flows, Telegram uses a custom encapsulation
+ There is no documentation. It seems:
+ * some unknown packets (especially at the beginning/end of the flow) have a bunch of 0xFF
+ * the other packets encapsulate standard STUN/DTLS/RTP payload at offset 24
+ (with a previous field containing the payload length)
+ */
+
+ if(packet->payload_packet_len <= 28) {
+ NDPI_LOG_DBG(ndpi_struct, "Malformed custom Telegram packet (too short)\n");
+ return keep_extra_dissection(ndpi_struct, flow);
+ }
+
+ if(memcmp(&packet->payload[16], pattern, sizeof(pattern)) == 0) {
+ NDPI_LOG_DBG(ndpi_struct, "Custom/Unknown Telegram packet\n");
+ return keep_extra_dissection(ndpi_struct, flow);
+ }
+
+ /* It should be STUN/DTLS/RTP */
+
+ length = ntohs(*(u_int16_t *)&packet->payload[22]);
+ if(24 + length > packet->payload_packet_len) {
+ NDPI_LOG_DBG(ndpi_struct, "Malformed custom Telegram packet (too long: %d %d)\n",
+ length, packet->payload_packet_len);
+ return keep_extra_dissection(ndpi_struct, flow);
+ }
+
+ orig_payload = packet->payload;
+ orig_payload_length = packet->payload_packet_len ;
+ packet->payload = packet->payload + 24;
+ packet->payload_packet_len = length;
+
+ stun_search_again(ndpi_struct, flow);
+
+ packet->payload = orig_payload;
+ packet->payload_packet_len = orig_payload_length;
+
+ return keep_extra_dissection(ndpi_struct, flow);
+}
+
+/* ************************************************************ */
+
static u_int64_t get_stun_lru_key(struct ndpi_flow_struct *flow, u_int8_t rev) {
if(rev) {
if(flow->is_ipv6)
@@ -1150,19 +1212,23 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd
}
}
- switch_extra_dissection_to_stun(ndpi_struct, flow);
+ switch_extra_dissection_to_stun(ndpi_struct, flow, 1);
}
/* ************************************************************ */
void switch_extra_dissection_to_stun(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow)
+ struct ndpi_flow_struct *flow,
+ int std_callback)
{
if(!flow->extra_packets_func) {
if(keep_extra_dissection(ndpi_struct, flow)) {
NDPI_LOG_DBG(ndpi_struct, "Enabling extra dissection\n");
flow->max_extra_packets_to_check = ndpi_struct->cfg.stun_max_packets_extra_dissection;
- flow->extra_packets_func = stun_search_again;
+ if(std_callback)
+ flow->extra_packets_func = stun_search_again;
+ else
+ flow->extra_packets_func = stun_telegram_search_again;
}
}
}
diff --git a/src/lib/protocols/telegram.c b/src/lib/protocols/telegram.c
index 23f7cca51..affeede36 100644
--- a/src/lib/protocols/telegram.c
+++ b/src/lib/protocols/telegram.c
@@ -93,6 +93,14 @@ static void ndpi_search_telegram(struct ndpi_detection_module_struct *ndpi_struc
if(found == 12) {
ndpi_int_telegram_add_connection(ndpi_struct, flow, NDPI_CONFIDENCE_DPI);
+ /* It seems this kind of traffic is used:
+ * for "normal" stuff (at least years ago... and now? TODO)
+ * for calls, as a custom encapsulation of STUN/DTLS/RTP packets
+ Since we are not able to tell the former from the latter, always
+ switch to STUN dissection. If we find STUN/DTLS/RTP stuff we will
+ update the classification to something like STUN/Telegram_voip,
+ otherwise it will remain Telegram */
+ switch_extra_dissection_to_stun(ndpi_struct, flow, 0);
return;
}
}