diff options
Diffstat (limited to 'src/lib/protocols/stun.c')
-rw-r--r-- | src/lib/protocols/stun.c | 80 |
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) { |