aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2023-06-21 09:16:20 +0200
committerGitHub <noreply@github.com>2023-06-21 09:16:20 +0200
commit3608ab01b61bde1b7ac88baa448fe37724a313db (patch)
tree6e3223c4908f82bf057c0d2477c2780baf9fc8b6 /src
parent04be3080921507b69899d01bc79be86181e6f536 (diff)
STUN: keep monitoring/processing STUN flows (#2012)
Look for RTP packets in the STUN sessions. TODO: tell RTP from RTCP
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_api.h6
-rw-r--r--src/include/ndpi_typedefs.h9
-rw-r--r--src/lib/ndpi_main.c43
-rw-r--r--src/lib/protocols/rtp.c20
-rw-r--r--src/lib/protocols/stun.c48
5 files changed, 120 insertions, 6 deletions
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h
index b378dfb58..258c09ae8 100644
--- a/src/include/ndpi_api.h
+++ b/src/include/ndpi_api.h
@@ -1050,6 +1050,12 @@ extern "C" {
u_int32_t ndpi_get_protocol_aggressiveness(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t proto);
+ int ndpi_set_monitoring_state(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, u_int32_t num_pkts, u_int32_t flags);
+ int ndpi_get_monitoring_state(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, u_int32_t *num_pkts, u_int32_t *flags);
+
+
/**
* Find a protocol id associated with a string automata
*
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index c45669432..80dd05c9a 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -726,6 +726,12 @@ struct ndpi_lru_cache {
/* Ookla */
#define NDPI_AGGRESSIVENESS_OOKLA_TLS 0x01 /* Enable detection over TLS (using ookla cache) */
+
+/* Monitoring flags */
+
+/* Stun */
+#define NDPI_MONITORING_STUN_SUBCLASSIFIED 0x01 /* Monitor STUN flows even if we have a valid sub-protocol */
+
/* ************************************************** */
struct ndpi_flow_tcp_struct {
@@ -1301,6 +1307,9 @@ struct ndpi_detection_module_struct {
int opportunistic_tls_pop_enabled;
int opportunistic_tls_ftp_enabled;
+ u_int32_t monitoring_stun_pkts_to_process;
+ u_int32_t monitoring_stun_flags;
+
u_int32_t aggressiveness_ookla;
int tcp_ack_paylod_heuristic;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 59f21c555..80b9f6d42 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -329,8 +329,10 @@ u_int16_t ndpi_map_user_proto_id_to_ndpi_id(struct ndpi_detection_module_struct
u_int16_t user_proto_id) {
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
+#if 0 /* Too much verbose... */
NDPI_LOG_DBG2(ndpi_str, "[DEBUG] ***** %s(%u)\n", __FUNCTION__, user_proto_id);
#endif
+#endif
if(user_proto_id < NDPI_MAX_SUPPORTED_PROTOCOLS)
return(user_proto_id);
@@ -356,8 +358,10 @@ u_int16_t ndpi_map_user_proto_id_to_ndpi_id(struct ndpi_detection_module_struct
u_int16_t ndpi_map_ndpi_id_to_user_proto_id(struct ndpi_detection_module_struct *ndpi_str,
u_int16_t ndpi_proto_id) {
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
+#if 0 /* Too much verbose... */
NDPI_LOG_DBG2(ndpi_str, "[DEBUG] ***** %s(%u)\n", __FUNCTION__, ndpi_proto_id);
#endif
+#endif
if(ndpi_proto_id < NDPI_MAX_SUPPORTED_PROTOCOLS)
return(ndpi_proto_id);
@@ -2996,6 +3000,9 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
ndpi_str->opportunistic_tls_pop_enabled = 1;
ndpi_str->opportunistic_tls_ftp_enabled = 1;
+ ndpi_str->monitoring_stun_pkts_to_process = 4;
+ ndpi_str->monitoring_stun_flags = 0;
+
ndpi_str->aggressiveness_ookla = NDPI_AGGRESSIVENESS_OOKLA_TLS;
if(prefs & ndpi_enable_tcp_ack_payload_heuristic)
@@ -9774,6 +9781,42 @@ int ndpi_seen_flow_beginning(const struct ndpi_flow_struct *flow)
/* ******************************************************************** */
+int ndpi_set_monitoring_state(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, u_int32_t num_pkts, u_int32_t flags)
+{
+ if(!ndpi_struct || num_pkts > 0xFFFF)
+ return -1;
+
+ switch(proto) {
+ case NDPI_PROTOCOL_STUN:
+ ndpi_struct->monitoring_stun_pkts_to_process = num_pkts;
+ ndpi_struct->monitoring_stun_flags = flags;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+/* ******************************************************************** */
+
+int ndpi_get_monitoring_state(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, u_int32_t *num_pkts, u_int32_t *flags)
+{
+ if(!ndpi_struct || !num_pkts || !flags)
+ return -1;
+
+ switch(proto) {
+ case NDPI_PROTOCOL_STUN:
+ *num_pkts = ndpi_struct->monitoring_stun_pkts_to_process;
+ *flags = ndpi_struct->monitoring_stun_flags;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+/* ******************************************************************** */
+
int ndpi_set_opportunistic_tls(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t proto, int value)
{
diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c
index 093e509af..3ac7f83cb 100644
--- a/src/lib/protocols/rtp.c
+++ b/src/lib/protocols/rtp.c
@@ -179,7 +179,6 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct,
if((payload_len < 2)
|| (d_port == 5355 /* LLMNR_PORT */)
|| (d_port == 5353 /* MDNS_PORT */)
- || flow->stun.num_binding_requests
) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
return;
@@ -237,12 +236,21 @@ static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct,
/* It seems that it is a LINE stuff; let its dissector to evaluate */
return;
} else {
- NDPI_LOG_INFO(ndpi_struct, "Found RTP\n");
-
isValidMSRTPType(payload_type, &flow->protos.rtp.stream_type);
- ndpi_set_detected_protocol(ndpi_struct, flow,
- NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_RTP,
- NDPI_CONFIDENCE_DPI);
+
+ /* Previous pkts were STUN */
+ if(flow->stun.num_binding_requests > 0 ||
+ flow->stun.num_processed_pkts > 0) {
+ NDPI_LOG_INFO(ndpi_struct, "Found RTP (previous traffic was STUN)\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ NDPI_PROTOCOL_RTP, NDPI_PROTOCOL_STUN,
+ NDPI_CONFIDENCE_DPI);
+ } else {
+ NDPI_LOG_INFO(ndpi_struct, "Found RTP\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_RTP,
+ NDPI_CONFIDENCE_DPI);
+ }
return;
}
}
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index 8eeb28260..98e4ab05c 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -32,9 +32,44 @@
// #define DEBUG_STUN 1
// #define DEBUG_LRU 1
// #define DEBUG_ZOOM_LRU 1
+// #define DEBUG_MONITORING 1
#define STUN_HDR_LEN 20 /* STUN message header length, Classic-STUN (RFC 3489) and STUN (RFC 8489) both */
+static int stun_monitoring(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &ndpi_struct->packet;
+ u_int8_t first_byte;
+
+#ifdef DEBUG_MONITORING
+ printf("[STUN-MON] Packet counter %d\n", flow->packet_counter);
+#endif
+
+ if(packet->payload_packet_len == 0)
+ return 1;
+
+ first_byte = packet->payload[0];
+
+ /* draft-ietf-avtcore-rfc7983bis */
+ if(first_byte >= 128 && first_byte <= 191) { /* TODO: should we tell RTP from RTCP? */
+ NDPI_LOG_INFO(ndpi_struct, "Found RTP over STUN\n");
+ if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
+ /* STUN/SUBPROTO -> SUBPROTO/RTP */
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ NDPI_PROTOCOL_RTP, flow->detected_protocol_stack[0],
+ NDPI_CONFIDENCE_DPI);
+ } else {
+ /* STUN -> STUN/RTP */
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ NDPI_PROTOCOL_RTP, NDPI_PROTOCOL_STUN,
+ NDPI_CONFIDENCE_DPI);
+ }
+ return 0; /* Stop */
+ }
+ return 1; /* Keep going */
+}
+
/* ************************************************************ */
u_int32_t get_stun_lru_key(struct ndpi_flow_struct *flow, u_int8_t rev) {
@@ -150,6 +185,17 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd
}
ndpi_set_detected_protocol(ndpi_struct, flow, app_proto, NDPI_PROTOCOL_STUN, confidence);
+
+ if(ndpi_struct->monitoring_stun_pkts_to_process > 0 &&
+ flow->l4_proto == IPPROTO_UDP /* TODO: support TCP. We need to pay some attention because:
+ * multiple msg in the same TCP segment
+ * same msg split across multiple segments */) {
+ if((ndpi_struct->monitoring_stun_flags & NDPI_MONITORING_STUN_SUBCLASSIFIED) ||
+ app_proto == NDPI_PROTOCOL_UNKNOWN /* No-subclassification */) {
+ flow->max_extra_packets_to_check = ndpi_struct->monitoring_stun_pkts_to_process;
+ flow->extra_packets_func = stun_monitoring;
+ }
+ }
}
typedef enum {
@@ -497,6 +543,8 @@ static void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, s
if(flow->packet_counter > 0) {
/* This might be a RTP stream: let's make sure we check it */
+ /* At this point the flow has not been fully classified as STUN yet */
+ NDPI_LOG_DBG(ndpi_struct, "re-enable RTP\n");
NDPI_CLR(&flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
}
}