aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/stun.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/protocols/stun.c')
-rw-r--r--src/lib/protocols/stun.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index acc0e1e91..7207c1b9f 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -187,7 +187,8 @@ static void add_to_cache(struct ndpi_detection_module_struct *ndpi_struct,
}
static void parse_ip_port_attribute(const u_int8_t *payload, u_int16_t payload_length,
- int off, u_int16_t real_len,ndpi_address_port *ap)
+ int off, u_int16_t real_len, ndpi_address_port *ap,
+ ndpi_address_port *ap_monit)
{
if(off + 4 + real_len <= payload_length &&
(real_len == 8 || real_len == 20)) {
@@ -201,6 +202,9 @@ static void parse_ip_port_attribute(const u_int8_t *payload, u_int16_t payload_l
ap->port = port;
ap->address.v4 = htonl(ip);
ap->is_ipv6 = 0;
+
+ if(ap_monit)
+ memcpy(ap_monit, ap, sizeof(*ap_monit));
} else if(protocol_family == 0x02 /* IPv6 */ &&
real_len == 20) {
u_int16_t port = ntohs(*((u_int16_t*)&payload[off+6]));
@@ -214,6 +218,9 @@ static void parse_ip_port_attribute(const u_int8_t *payload, u_int16_t payload_l
ap->port = port;
memcpy(&ap->address, &ip, 16);
ap->is_ipv6 = 1;
+
+ if(ap_monit)
+ memcpy(ap_monit, ap, sizeof(*ap_monit));
}
}
}
@@ -221,7 +228,8 @@ static void parse_ip_port_attribute(const u_int8_t *payload, u_int16_t payload_l
static void parse_xor_ip_port_attribute(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
const u_int8_t *payload, u_int16_t payload_length,
- int off, u_int16_t real_len,ndpi_address_port *ap,
+ int off, u_int16_t real_len,
+ ndpi_address_port *ap, ndpi_address_port *ap_monit,
u_int32_t transaction_id[3], u_int32_t magic_cookie,
int add_to_cache)
{
@@ -245,6 +253,9 @@ static void parse_xor_ip_port_attribute(struct ndpi_detection_module_struct *ndp
ap->address.v4 = ip;
ap->is_ipv6 = 0;
+ if(ap_monit)
+ memcpy(ap_monit, ap, sizeof(*ap_monit));
+
if(add_to_cache) {
NDPI_LOG_DBG(ndpi_struct, "Peer %s:%d [proto %d]\n",
inet_ntop(AF_INET, &ip, buf, sizeof(buf)), port,
@@ -277,6 +288,9 @@ static void parse_xor_ip_port_attribute(struct ndpi_detection_module_struct *ndp
memcpy(&ap->address, &ip, 16);
ap->is_ipv6 = 1;
+ if(ap_monit)
+ memcpy(ap_monit, ap, sizeof(*ap_monit));
+
if(add_to_cache) {
NDPI_LOG_DBG(ndpi_struct, "Peer %s:%d [proto %d]\n",
inet_ntop(AF_INET6, &ip, buf, sizeof(buf)), port,
@@ -407,6 +421,10 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
/* STUN */
+ if(flow->monit == NULL &&
+ is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN))
+ flow->monit = ndpi_calloc(1, sizeof(struct ndpi_metadata_monitoring));
+
if(msg_type == 0x0800 || msg_type == 0x0801 || msg_type == 0x0802) {
*app_proto = NDPI_PROTOCOL_WHATSAPP_CALL;
return 1;
@@ -440,19 +458,22 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
switch(attribute) {
case 0x0001: /* MAPPED-ADDRESS */
if(ndpi_struct->cfg.stun_mapped_address_enabled) {
- parse_ip_port_attribute(payload, payload_length, off, real_len, &flow->stun.mapped_address);
+ parse_ip_port_attribute(payload, payload_length, off, real_len, &flow->stun.mapped_address,
+ flow->monit ? &flow->monit->protos.dtls_stun_rtp.mapped_address : NULL);
}
break;
case 0x802b: /* RESPONSE-ORIGIN */
if(ndpi_struct->cfg.stun_response_origin_enabled) {
- parse_ip_port_attribute(payload, payload_length, off, real_len, &flow->stun.response_origin);
+ parse_ip_port_attribute(payload, payload_length, off, real_len, &flow->stun.response_origin,
+ flow->monit ? &flow->monit->protos.dtls_stun_rtp.response_origin : NULL);
}
break;
case 0x802c: /* OTHER-ADDRESS */
if(ndpi_struct->cfg.stun_other_address_enabled) {
- parse_ip_port_attribute(payload, payload_length, off, real_len, &flow->stun.other_address);
+ parse_ip_port_attribute(payload, payload_length, off, real_len, &flow->stun.other_address,
+ flow->monit ? &flow->monit->protos.dtls_stun_rtp.other_address : NULL);
}
break;
@@ -461,6 +482,7 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
parse_xor_ip_port_attribute(ndpi_struct, flow,
payload, payload_length, off, real_len,
&flow->stun.peer_address,
+ flow->monit ? &flow->monit->protos.dtls_stun_rtp.peer_address : NULL,
transaction_id, magic_cookie, 1);
}
break;
@@ -555,6 +577,7 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
parse_xor_ip_port_attribute(ndpi_struct, flow,
payload, payload_length, off, real_len,
&flow->stun.mapped_address,
+ flow->monit ? &flow->monit->protos.dtls_stun_rtp.mapped_address : NULL,
transaction_id, magic_cookie, 0);
}
break;
@@ -564,6 +587,7 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
parse_xor_ip_port_attribute(ndpi_struct, flow,
payload, payload_length, off, real_len,
&flow->stun.relayed_address,
+ flow->monit ? &flow->monit->protos.dtls_stun_rtp.relayed_address : NULL,
transaction_id, magic_cookie, 0);
}
break;
@@ -593,14 +617,28 @@ static int keep_extra_dissection(struct ndpi_detection_module_struct *ndpi_struc
* for the other protocols, we stop after we have all metadata (if enabled)
* for some specific protocol, we might know that some attributes
are never used
+
+ **After** extra dissection is ended, we might move to monitoring. Note that:
+ * classification doesn't change while in monitoring!
*/
- if(!is_subclassification_real(flow))
+ if(flow->monitoring)
return 1;
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_ZOOM)
return 0;
+ if(flow->num_extra_packets_checked + 1 == flow->max_extra_packets_to_check) {
+ if(is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN)) {
+ NDPI_LOG_DBG(ndpi_struct, "Enabling monitoring (end extra dissection)\n");
+ flow->monitoring = 1;
+ return 1;
+ }
+ }
+
+ if(!is_subclassification_real(flow))
+ return 1;
+
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TELEGRAM_VOIP &&
ndpi_struct->cfg.stun_peer_address_enabled)
return 1;
@@ -610,14 +648,26 @@ static int keep_extra_dissection(struct ndpi_detection_module_struct *ndpi_struc
(flow->stun.peer_address.port || !ndpi_struct->cfg.stun_peer_address_enabled) &&
(flow->stun.relayed_address.port || !ndpi_struct->cfg.stun_relayed_address_enabled) &&
(flow->stun.response_origin.port || !ndpi_struct->cfg.stun_response_origin_enabled) &&
- (flow->stun.other_address.port || !ndpi_struct->cfg.stun_other_address_enabled))
+ (flow->stun.other_address.port || !ndpi_struct->cfg.stun_other_address_enabled)) {
+ if(is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN)) {
+ NDPI_LOG_DBG(ndpi_struct, "Enabling monitoring (found all metadata)\n");
+ flow->monitoring = 1;
+ return 1;
+ }
return 0;
+ }
/* Exception WA: only relayed and mapped address attributes */
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_WHATSAPP_CALL &&
(flow->stun.mapped_address.port || !ndpi_struct->cfg.stun_mapped_address_enabled) &&
- (flow->stun.relayed_address.port || !ndpi_struct->cfg.stun_relayed_address_enabled))
+ (flow->stun.relayed_address.port || !ndpi_struct->cfg.stun_relayed_address_enabled)) {
+ if(is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN)) {
+ NDPI_LOG_DBG(ndpi_struct, "Enabling monitor (found all metadata; wa case)\n");
+ flow->monitoring = 1;
+ return 1;
+ }
return 0;
+ }
return 1;
}
@@ -642,8 +692,10 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
int first_dtls_pkt = 0;
u_int16_t old_proto_stack[2] = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN};
- NDPI_LOG_DBG2(ndpi_struct, "Packet counter %d protos %d/%d\n", flow->packet_counter,
- flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+ NDPI_LOG_DBG2(ndpi_struct, "Packet counter %d protos %d/%d Monitoring? %d\n",
+ flow->packet_counter,
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1],
+ flow->monitoring);
/* TODO: check TCP support. We need to pay some attention because:
* multiple msg in the same TCP segment
@@ -694,7 +746,7 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
if(flow->tls_quic.certificate_processed == 1) {
NDPI_LOG_DBG(ndpi_struct, "Interesting DTLS stuff already processed. Ignoring\n");
- } else {
+ } else if(!flow->monitoring) {
NDPI_LOG_DBG(ndpi_struct, "Switch to DTLS (%d/%d)\n",
flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
@@ -746,6 +798,8 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
NDPI_LOG_DBG(ndpi_struct, "(%d/%d)\n",
flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+ } else {
+ NDPI_LOG_DBG(ndpi_struct, "Skip DTLS packet because in monitoring\n");
}
}
} else if(first_byte <= 79) {
@@ -897,6 +951,10 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd
ndpi_confidence_t confidence = NDPI_CONFIDENCE_DPI;
u_int16_t new_app_proto;
+ /* In monitoring the classification can't change again */
+ if(flow->monitoring)
+ return;
+
NDPI_LOG_DBG(ndpi_struct, "Wanting %d/%d\n", master_proto, app_proto);
if(app_proto == NDPI_PROTOCOL_UNKNOWN) {