diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2023-06-21 09:16:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-21 09:16:20 +0200 |
commit | 3608ab01b61bde1b7ac88baa448fe37724a313db (patch) | |
tree | 6e3223c4908f82bf057c0d2477c2780baf9fc8b6 /src | |
parent | 04be3080921507b69899d01bc79be86181e6f536 (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.h | 6 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 9 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 43 | ||||
-rw-r--r-- | src/lib/protocols/rtp.c | 20 | ||||
-rw-r--r-- | src/lib/protocols/stun.c | 48 |
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); } } |