diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2021-11-15 16:20:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-15 16:20:57 +0100 |
commit | afc2b641eb9cf5035b5147e78030bafe0b40dd87 (patch) | |
tree | 99cf853d219ae6004819d2564f4cabd29c487cf6 /src/lib | |
parent | da47357762746c7fc5c537b575b5b56f252320a5 (diff) |
Fix writes to `flow->protos` union fields (#1354)
We can write to `flow->protos` only after a proper classification.
This issue has been found in Kerberos, DHCP, HTTP, STUN, IMO, FTP,
SMTP, IMAP and POP code.
There are two kinds of fixes:
* write to `flow->protos` only if a final protocol has been detected
* move protocol state out of `flow->protos`
The hard part is to find, for each protocol, the right tradeoff between
memory usage and code complexity.
Handle Kerberos like DNS: if we find a request, we set the protocol
and an extra callback to further parsing the reply.
For all the other protocols, move the state out of `flow->protos`. This
is an issue only for the FTP/MAIL stuff.
Add DHCP Class Identification value to the output of ndpiReader and to
the Jason serialization.
Extend code coverage of fuzz tests.
Close #1343
Close #1342
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/ndpi_main.c | 57 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 102 | ||||
-rw-r--r-- | src/lib/protocols/dhcp.c | 120 | ||||
-rw-r--r-- | src/lib/protocols/ftp_control.c | 22 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 6 | ||||
-rw-r--r-- | src/lib/protocols/imo.c | 8 | ||||
-rw-r--r-- | src/lib/protocols/kerberos.c | 71 | ||||
-rw-r--r-- | src/lib/protocols/mail_imap.c | 10 | ||||
-rw-r--r-- | src/lib/protocols/mail_pop.c | 12 | ||||
-rw-r--r-- | src/lib/protocols/mail_smtp.c | 58 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 30 | ||||
-rw-r--r-- | src/lib/protocols/rtp.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/stun.c | 18 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 210 |
14 files changed, 401 insertions, 325 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 7e7ecb13c..4fd952f77 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -4298,23 +4298,23 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) { flow_is_proto(flow, NDPI_PROTOCOL_MAIL_SMTPS) || flow_is_proto(flow, NDPI_PROTOCOL_MAIL_POPS) || flow_is_proto(flow, NDPI_PROTOCOL_MAIL_IMAPS)) { - if(flow->protos.tls_quic_stun.tls_quic.server_names) - ndpi_free(flow->protos.tls_quic_stun.tls_quic.server_names); + if(flow->protos.tls_quic.server_names) + ndpi_free(flow->protos.tls_quic.server_names); - if(flow->protos.tls_quic_stun.tls_quic.alpn) - ndpi_free(flow->protos.tls_quic_stun.tls_quic.alpn); + if(flow->protos.tls_quic.alpn) + ndpi_free(flow->protos.tls_quic.alpn); - if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions) - ndpi_free(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions); + if(flow->protos.tls_quic.tls_supported_versions) + ndpi_free(flow->protos.tls_quic.tls_supported_versions); - if(flow->protos.tls_quic_stun.tls_quic.issuerDN) - ndpi_free(flow->protos.tls_quic_stun.tls_quic.issuerDN); + if(flow->protos.tls_quic.issuerDN) + ndpi_free(flow->protos.tls_quic.issuerDN); - if(flow->protos.tls_quic_stun.tls_quic.subjectDN) - ndpi_free(flow->protos.tls_quic_stun.tls_quic.subjectDN); + if(flow->protos.tls_quic.subjectDN) + ndpi_free(flow->protos.tls_quic.subjectDN); - if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni) - ndpi_free(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni); + if(flow->protos.tls_quic.encrypted_sni.esni) + ndpi_free(flow->protos.tls_quic.encrypted_sni.esni); } if(flow->l4_proto == IPPROTO_TCP) { @@ -4915,13 +4915,13 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st *protocol_was_guessed = 1; ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_protocol_id, NDPI_PROTOCOL_UNKNOWN); } - else if((flow->protos.tls_quic_stun.tls_quic.hello_processed == 1) && - (flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0')) { + else if((flow->protos.tls_quic.hello_processed == 1) && + (flow->protos.tls_quic.client_requested_server_name[0] != '\0')) { *protocol_was_guessed = 1; ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_TLS, NDPI_PROTOCOL_UNKNOWN); } else if(enable_guess) { if((flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) && (flow->l4_proto == IPPROTO_TCP) && - flow->protos.tls_quic_stun.tls_quic.hello_processed) + flow->protos.tls_quic.hello_processed) flow->guessed_protocol_id = NDPI_PROTOCOL_TLS; guessed_protocol_id = flow->guessed_protocol_id, guessed_host_protocol_id = flow->guessed_host_protocol_id; @@ -4941,8 +4941,8 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st flow->guessed_protocol_id = guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN; if((guessed_protocol_id != NDPI_PROTOCOL_UNKNOWN) || (guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN)) { - if((guessed_protocol_id == 0) && (flow->protos.tls_quic_stun.stun.num_binding_requests > 0) && - (flow->protos.tls_quic_stun.stun.num_processed_pkts > 0)) + if((guessed_protocol_id == 0) && (flow->stun.num_binding_requests > 0) && + (flow->stun.num_processed_pkts > 0)) guessed_protocol_id = NDPI_PROTOCOL_STUN; if(flow->host_server_name[0] != '\0') { @@ -4983,9 +4983,9 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) && (flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)) { check_stun_export: - /* if(flow->protos.tls_quic_stun.stun.num_processed_pkts || flow->protos.tls_quic_stun.stun.num_udp_pkts) */ + /* if(flow->protos.stun.num_processed_pkts || flow->protos.stun.num_udp_pkts) */ { - // if(/* (flow->protos.tls_quic_stun.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */ + // if(/* (flow->protos.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */ *protocol_was_guessed = 1; ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_STUN); } @@ -5207,11 +5207,11 @@ void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_str, } } - if(flow->protos.tls_quic_stun.tls_quic.hello_processed == 1 && - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') { + if(flow->protos.tls_quic.hello_processed == 1 && + flow->protos.tls_quic.client_requested_server_name[0] != '\0') { u_int32_t id; - int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, - strlen(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), &id); + int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.tls_quic.client_requested_server_name, + strlen(flow->protos.tls_quic.client_requested_server_name), &id); if(rc == 0) { flow->category = ret->category = (ndpi_protocol_category_t) id; @@ -7222,9 +7222,9 @@ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndp case NDPI_PROTOCOL_MAIL_POP: case NDPI_PROTOCOL_MAIL_IMAP: case NDPI_PROTOCOL_MAIL_SMTP: - if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0' && - flow->protos.ftp_imap_pop_smtp.auth_tls == 0 && - flow->protos.ftp_imap_pop_smtp.auth_done == 0) + if(flow->ftp_imap_pop_smtp.password[0] == '\0' && + flow->ftp_imap_pop_smtp.auth_tls == 0 && + flow->ftp_imap_pop_smtp.auth_done == 0) return(1); break; @@ -7247,6 +7247,11 @@ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndp if(flow->extra_packets_func) return(1); break; + + case NDPI_PROTOCOL_KERBEROS: + if(flow->extra_packets_func) + return(1); + break; } return(0); diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index a9361f7c5..626f5ade3 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -865,9 +865,9 @@ static const char* ndpi_get_flow_info_by_proto_id(struct ndpi_flow_struct const return (char const *)flow->host_server_name; case NDPI_PROTOCOL_QUIC: case NDPI_PROTOCOL_TLS: - if (flow->protos.tls_quic_stun.tls_quic.hello_processed != 0) + if (flow->protos.tls_quic.hello_processed != 0) { - return flow->protos.tls_quic_stun.tls_quic.client_requested_server_name; + return flow->protos.tls_quic.client_requested_server_name; } break; } @@ -930,10 +930,10 @@ char* ndpi_ssl_version2str(struct ndpi_flow_struct *flow, *unknown_tls_version = 1; if(flow != NULL) { - snprintf(flow->protos.tls_quic_stun.tls_quic.ssl_version_str, - sizeof(flow->protos.tls_quic_stun.tls_quic.ssl_version_str), "TLS (%04X)", version); + snprintf(flow->protos.tls_quic.ssl_version_str, + sizeof(flow->protos.tls_quic.ssl_version_str), "TLS (%04X)", version); - return(flow->protos.tls_quic_stun.tls_quic.ssl_version_str); + return(flow->protos.tls_quic.ssl_version_str); } else return(""); } @@ -1150,7 +1150,9 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, switch(l7_protocol.master_protocol ? l7_protocol.master_protocol : l7_protocol.app_protocol) { case NDPI_PROTOCOL_DHCP: ndpi_serialize_start_of_block(serializer, "dhcp"); + ndpi_serialize_string_string(serializer, "hostname", (const char*)flow->host_server_name); ndpi_serialize_string_string(serializer, "fingerprint", flow->protos.dhcp.fingerprint); + ndpi_serialize_string_string(serializer, "class_ident", flow->protos.dhcp.class_ident); ndpi_serialize_end_of_block(serializer); break; @@ -1238,54 +1240,54 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, case NDPI_PROTOCOL_QUIC: ndpi_serialize_start_of_block(serializer, "quic"); - if(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') + if(flow->protos.tls_quic.client_requested_server_name[0] != '\0') ndpi_serialize_string_string(serializer, "client_requested_server_name", - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); - if(flow->protos.tls_quic_stun.tls_quic.server_names) - ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic_stun.tls_quic.server_names); + flow->protos.tls_quic.client_requested_server_name); + if(flow->protos.tls_quic.server_names) + ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic.server_names); if(flow->http.user_agent) ndpi_serialize_string_string(serializer, "user_agent", flow->http.user_agent); - if(flow->protos.tls_quic_stun.tls_quic.ssl_version) { + if(flow->protos.tls_quic.ssl_version) { u_int8_t unknown_tls_version; - char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic_stun.tls_quic.ssl_version, &unknown_tls_version); + char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic.ssl_version, &unknown_tls_version); if(!unknown_tls_version) ndpi_serialize_string_string(serializer, "version", version); - if(flow->protos.tls_quic_stun.tls_quic.alpn) - ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic_stun.tls_quic.alpn); - ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic_stun.tls_quic.ja3_client); - if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions) - ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic_stun.tls_quic.tls_supported_versions); + if(flow->protos.tls_quic.alpn) + ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic.alpn); + ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic.ja3_client); + if(flow->protos.tls_quic.tls_supported_versions) + ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic.tls_supported_versions); } ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_MAIL_IMAP: ndpi_serialize_start_of_block(serializer, "imap"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_MAIL_POP: ndpi_serialize_start_of_block(serializer, "pop"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_MAIL_SMTP: ndpi_serialize_start_of_block(serializer, "smtp"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_FTP_CONTROL: ndpi_serialize_start_of_block(serializer, "ftp"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); - ndpi_serialize_string_uint32(serializer, "auth_failed", flow->protos.ftp_imap_pop_smtp.auth_failed); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); + ndpi_serialize_string_uint32(serializer, "auth_failed", flow->ftp_imap_pop_smtp.auth_failed); ndpi_serialize_end_of_block(serializer); break; @@ -1300,25 +1302,25 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, case NDPI_PROTOCOL_TLS: case NDPI_PROTOCOL_DTLS: - if(flow->protos.tls_quic_stun.tls_quic.ssl_version) { + if(flow->protos.tls_quic.ssl_version) { char notBefore[32], notAfter[32]; struct tm a, b, *before = NULL, *after = NULL; u_int i, off; u_int8_t unknown_tls_version; - char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic_stun.tls_quic.ssl_version, &unknown_tls_version); + char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic.ssl_version, &unknown_tls_version); - if(flow->protos.tls_quic_stun.tls_quic.notBefore) - before = gmtime_r((const time_t *)&flow->protos.tls_quic_stun.tls_quic.notBefore, &a); - if(flow->protos.tls_quic_stun.tls_quic.notAfter) - after = gmtime_r((const time_t *)&flow->protos.tls_quic_stun.tls_quic.notAfter, &b); + if(flow->protos.tls_quic.notBefore) + before = gmtime_r((const time_t *)&flow->protos.tls_quic.notBefore, &a); + if(flow->protos.tls_quic.notAfter) + after = gmtime_r((const time_t *)&flow->protos.tls_quic.notAfter, &b); if(!unknown_tls_version) { ndpi_serialize_start_of_block(serializer, "tls"); ndpi_serialize_string_string(serializer, "version", version); ndpi_serialize_string_string(serializer, "client_requested_server_name", - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); - if(flow->protos.tls_quic_stun.tls_quic.server_names) - ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic_stun.tls_quic.server_names); + flow->protos.tls_quic.client_requested_server_name); + if(flow->protos.tls_quic.server_names) + ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic.server_names); if(before) { strftime(notBefore, sizeof(notBefore), "%Y-%m-%d %H:%M:%S", before); @@ -1329,27 +1331,27 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, strftime(notAfter, sizeof(notAfter), "%Y-%m-%d %H:%M:%S", after); ndpi_serialize_string_string(serializer, "notafter", notAfter); } - ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic_stun.tls_quic.ja3_client); - ndpi_serialize_string_string(serializer, "ja3s", flow->protos.tls_quic_stun.tls_quic.ja3_server); - ndpi_serialize_string_uint32(serializer, "unsafe_cipher", flow->protos.tls_quic_stun.tls_quic.server_unsafe_cipher); - ndpi_serialize_string_string(serializer, "cipher", ndpi_cipher2str(flow->protos.tls_quic_stun.tls_quic.server_cipher)); + ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic.ja3_client); + ndpi_serialize_string_string(serializer, "ja3s", flow->protos.tls_quic.ja3_server); + ndpi_serialize_string_uint32(serializer, "unsafe_cipher", flow->protos.tls_quic.server_unsafe_cipher); + ndpi_serialize_string_string(serializer, "cipher", ndpi_cipher2str(flow->protos.tls_quic.server_cipher)); - if(flow->protos.tls_quic_stun.tls_quic.issuerDN) - ndpi_serialize_string_string(serializer, "issuerDN", flow->protos.tls_quic_stun.tls_quic.issuerDN); + if(flow->protos.tls_quic.issuerDN) + ndpi_serialize_string_string(serializer, "issuerDN", flow->protos.tls_quic.issuerDN); - if(flow->protos.tls_quic_stun.tls_quic.subjectDN) - ndpi_serialize_string_string(serializer, "subjectDN", flow->protos.tls_quic_stun.tls_quic.subjectDN); + if(flow->protos.tls_quic.subjectDN) + ndpi_serialize_string_string(serializer, "subjectDN", flow->protos.tls_quic.subjectDN); - if(flow->protos.tls_quic_stun.tls_quic.alpn) - ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic_stun.tls_quic.alpn); + if(flow->protos.tls_quic.alpn) + ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic.alpn); - if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions) - ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic_stun.tls_quic.tls_supported_versions); + if(flow->protos.tls_quic.tls_supported_versions) + ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic.tls_supported_versions); - if(flow->protos.tls_quic_stun.tls_quic.sha1_certificate_fingerprint[0] != '\0') { + if(flow->protos.tls_quic.sha1_certificate_fingerprint[0] != '\0') { for(i=0, off=0; i<20; i++) { int rc = snprintf(&buf[off], sizeof(buf)-off,"%s%02X", (i > 0) ? ":" : "", - flow->protos.tls_quic_stun.tls_quic.sha1_certificate_fingerprint[i] & 0xFF); + flow->protos.tls_quic.sha1_certificate_fingerprint[i] & 0xFF); if(rc <= 0) break; else off += rc; } @@ -2197,8 +2199,8 @@ char* ndpi_get_flow_name(struct ndpi_flow_struct *flow) { if(flow->host_server_name[0] != '\0') return((char*)flow->host_server_name); - if(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') - return(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); + if(flow->protos.tls_quic.client_requested_server_name[0] != '\0') + return(flow->protos.tls_quic.client_requested_server_name); no_flow_info: return((char*)""); diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c index 21f052d95..d40bb5c35 100644 --- a/src/lib/protocols/dhcp.c +++ b/src/lib/protocols/dhcp.c @@ -61,6 +61,7 @@ static void ndpi_int_dhcp_add_connection(struct ndpi_detection_module_struct *nd void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int8_t msg_type = 0; NDPI_LOG_DBG(ndpi_struct, "search DHCP\n"); @@ -79,75 +80,102 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru u_int dhcp_options_size = ndpi_min(DHCP_VEND_LEN /* maximum size of options in dhcp_packet_t */, packet->payload_packet_len - 244); + + /* Parse options in two steps (since we need first the message type and + it seems there is no specific order in the options list) */ + + /* First iteration: search for the message type */ while(i + 1 /* for the len */ < dhcp_options_size) { - u_int8_t id = dhcp->options[i]; + u_int8_t id = dhcp->options[i]; - if(id == 0xFF) - break; - else { - /* Prevent malformed packets to cause out-of-bounds accesses */ - u_int8_t len = ndpi_min(dhcp->options[i+1] /* len as found in the packet */, + if(id == 0xFF) + break; + else { + /* Prevent malformed packets to cause out-of-bounds accesses */ + u_int8_t len = ndpi_min(dhcp->options[i+1] /* len as found in the packet */, dhcp_options_size - (i+2) /* 1 for the type and 1 for the value */); + if(len == 0) + break; + if(id == 53 /* DHCP Message Type */) { + msg_type = dhcp->options[i+2]; + + if(msg_type <= 8) { + foundValidMsgType = 1; + break; + } + } + i += len + 2; + } + } - if(len == 0) - break; - - + if(!foundValidMsgType) { #ifdef DHCP_DEBUG - NDPI_LOG_DBG2(ndpi_struct, "[DHCP] Id=%d [len=%d]\n", id, len); + NDPI_LOG_DBG2(ndpi_struct, "[DHCP] Invalid message type %d. Not dhcp\n", msg_type); #endif + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + return; + } + + /* Ok, we have a valid DHCP packet -> we can write to flow->protos.dhcp */ + NDPI_LOG_INFO(ndpi_struct, "found DHCP\n"); + ndpi_int_dhcp_add_connection(ndpi_struct, flow); + + /* Second iteration: parse the interesting options */ + while(i + 1 /* for the len */ < dhcp_options_size) { + u_int8_t id = dhcp->options[i]; + + if(id == 0xFF) + break; + else { + /* Prevent malformed packets to cause out-of-bounds accesses */ + u_int8_t len = ndpi_min(dhcp->options[i+1] /* len as found in the packet */, + dhcp_options_size - (i+2) /* 1 for the type and 1 for the value */); + + if(len == 0) + break; - if(id == 53 /* DHCP Message Type */) { - u_int8_t msg_type = dhcp->options[i+2]; +#ifdef DHCP_DEBUG + NDPI_LOG_DBG2(ndpi_struct, "[DHCP] Id=%d [len=%d]\n", id, len); +#endif - if(msg_type <= 8) foundValidMsgType = 1; - } else if(id == 55 /* Parameter Request List / Fingerprint */) { - u_int idx, offset = 0; + if(id == 55 /* Parameter Request List / Fingerprint */) { + u_int idx, offset = 0; - for(idx = 0; idx < len && offset < sizeof(flow->protos.dhcp.fingerprint) - 2; idx++) { - int rc = snprintf((char*)&flow->protos.dhcp.fingerprint[offset], + for(idx = 0; idx < len && offset < sizeof(flow->protos.dhcp.fingerprint) - 2; idx++) { + int rc = snprintf((char*)&flow->protos.dhcp.fingerprint[offset], sizeof(flow->protos.dhcp.fingerprint) - offset, "%s%u", (idx > 0) ? "," : "", (unsigned int)dhcp->options[i+2+idx] & 0xFF); - if(rc < 0) break; else offset += rc; - } + if(rc < 0) break; else offset += rc; + } - flow->protos.dhcp.fingerprint[sizeof(flow->protos.dhcp.fingerprint) - 1] = '\0'; - } else if(id == 60 /* Class Identifier */) { - char *name = (char*)&dhcp->options[i+2]; - int j = 0; + flow->protos.dhcp.fingerprint[sizeof(flow->protos.dhcp.fingerprint) - 1] = '\0'; + } else if(id == 60 /* Class Identifier */) { + char *name = (char*)&dhcp->options[i+2]; + int j = 0; - j = ndpi_min(len, sizeof(flow->protos.dhcp.class_ident)-1); - strncpy((char*)flow->protos.dhcp.class_ident, name, j); - flow->protos.dhcp.class_ident[j] = '\0'; - } else if(id == 12 /* Host Name */) { - char *name = (char*)&dhcp->options[i+2]; - int j = 0; + j = ndpi_min(len, sizeof(flow->protos.dhcp.class_ident)-1); + strncpy((char*)flow->protos.dhcp.class_ident, name, j); + flow->protos.dhcp.class_ident[j] = '\0'; + } else if(id == 12 /* Host Name */) { + char *name = (char*)&dhcp->options[i+2]; + int j = 0; #ifdef DHCP_DEBUG - NDPI_LOG_DBG2(ndpi_struct, "[DHCP] '%.*s'\n",name,len); + NDPI_LOG_DBG2(ndpi_struct, "[DHCP] '%.*s'\n",name,len); // while(j < len) { printf( "%c", name[j]); j++; }; printf("\n"); #endif - j = ndpi_min(len, sizeof(flow->host_server_name)-1); - strncpy((char*)flow->host_server_name, name, j); - flow->host_server_name[j] = '\0'; - } + j = ndpi_min(len, sizeof(flow->host_server_name)-1); + strncpy((char*)flow->host_server_name, name, j); + flow->host_server_name[j] = '\0'; + } - i += len + 2; - } + i += len + 2; + } } - - //get_u_int16_t(packet->payload, 240) == htons(0x3501)) { - - if(foundValidMsgType) { - NDPI_LOG_INFO(ndpi_struct, "found DHCP\n"); - ndpi_int_dhcp_add_connection(ndpi_struct, flow); - } - return; } } - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c index 7b6544bb4..2b6f1396f 100644 --- a/src/lib/protocols/ftp_control.c +++ b/src/lib/protocols/ftp_control.c @@ -50,23 +50,23 @@ static int ndpi_ftp_control_check_request(struct ndpi_detection_module_struct *n #endif if(ndpi_match_strprefix(payload, payload_len, "USER")) { - ndpi_user_pwd_payload_copy((u_int8_t*)flow->protos.ftp_imap_pop_smtp.username, - sizeof(flow->protos.ftp_imap_pop_smtp.username), 5, + ndpi_user_pwd_payload_copy((u_int8_t*)flow->ftp_imap_pop_smtp.username, + sizeof(flow->ftp_imap_pop_smtp.username), 5, payload, payload_len); ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); return 1; } if(ndpi_match_strprefix(payload, payload_len, "PASS")) { - ndpi_user_pwd_payload_copy((u_int8_t*)flow->protos.ftp_imap_pop_smtp.password, - sizeof(flow->protos.ftp_imap_pop_smtp.password), 5, + ndpi_user_pwd_payload_copy((u_int8_t*)flow->ftp_imap_pop_smtp.password, + sizeof(flow->ftp_imap_pop_smtp.password), 5, payload, payload_len); return 1; } if(ndpi_match_strprefix(payload, payload_len, "AUTH") || ndpi_match_strprefix(payload, payload_len, "auth")) { - flow->protos.ftp_imap_pop_smtp.auth_found = 1; + flow->ftp_imap_pop_smtp.auth_found = 1; return 1; } /* ***************************************************** */ @@ -562,14 +562,14 @@ static int ndpi_ftp_control_check_response(struct ndpi_flow_struct *flow, case '2': case '3': case '6': - if(flow->protos.ftp_imap_pop_smtp.auth_found == 1) - flow->protos.ftp_imap_pop_smtp.auth_tls = 1; + if(flow->ftp_imap_pop_smtp.auth_found == 1) + flow->ftp_imap_pop_smtp.auth_tls = 1; return(1); break; case '4': case '5': - flow->protos.ftp_imap_pop_smtp.auth_failed = 1; + flow->ftp_imap_pop_smtp.auth_failed = 1; return(1); break; } @@ -632,11 +632,11 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str #ifdef FTP_DEBUG printf("%s() [user: %s][pwd: %s]\n", __FUNCTION__, - flow->protos.ftp_imap_pop_smtp.username, flow->protos.ftp_imap_pop_smtp.password); + flow->ftp_imap_pop_smtp.username, flow->ftp_imap_pop_smtp.password); #endif - if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0' && - flow->protos.ftp_imap_pop_smtp.auth_tls == 0) /* TODO: any values on dissecting TLS handshake? */ + if(flow->ftp_imap_pop_smtp.password[0] == '\0' && + flow->ftp_imap_pop_smtp.auth_tls == 0) /* TODO: any values on dissecting TLS handshake? */ flow->ftp_control_stage = 0; else ndpi_int_ftp_control_add_connection(ndpi_struct, flow); diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 932b0f451..cef8b3cfc 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -574,9 +574,9 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(len > 0) ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name, 1); if(packet->forwarded_line.ptr) { - len = ndpi_min(packet->forwarded_line.len, sizeof(flow->protos.http.nat_ip)-1); - strncpy((char*)flow->protos.http.nat_ip, (char*)packet->forwarded_line.ptr, len); - flow->protos.http.nat_ip[len] = '\0'; + len = ndpi_min(packet->forwarded_line.len, sizeof(flow->http.nat_ip)-1); + strncpy((char*)flow->http.nat_ip, (char*)packet->forwarded_line.ptr, len); + flow->http.nat_ip[len] = '\0'; } ndpi_http_parse_subprotocol(ndpi_struct, flow); diff --git a/src/lib/protocols/imo.c b/src/lib/protocols/imo.c index 2784e7143..fab99d301 100644 --- a/src/lib/protocols/imo.c +++ b/src/lib/protocols/imo.c @@ -39,11 +39,11 @@ void ndpi_search_imo(struct ndpi_detection_module_struct *ndpi_struct, struct nd if(packet->payload_packet_len == 1) { /* Two one byte consecutive packets with the same payload */ - if((flow->protos.imo.last_one_byte_pkt == 1) - && (flow->protos.imo.last_byte == packet->payload[0])) + if((flow->l4.udp.imo_last_one_byte_pkt == 1) + && (flow->l4.udp.imo_last_byte == packet->payload[0])) ndpi_int_imo_add_connection(ndpi_struct, flow); else - flow->protos.imo.last_one_byte_pkt = 1, flow->protos.imo.last_byte = packet->payload[0]; + flow->l4.udp.imo_last_one_byte_pkt = 1, flow->l4.udp.imo_last_byte = packet->payload[0]; } else if(((packet->payload_packet_len == 10) && (packet->payload[0] == 0x09) && (packet->payload[1] == 0x02)) @@ -62,7 +62,7 @@ void ndpi_search_imo(struct ndpi_detection_module_struct *ndpi_struct, struct nd if(flow->num_processed_pkts > 5) NDPI_EXCLUDE_PROTO(ndpi_struct, flow); else - flow->protos.imo.last_one_byte_pkt = 0; + flow->l4.udp.imo_last_one_byte_pkt = 0; } } diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c index 1f242ac46..7702a8e07 100644 --- a/src/lib/protocols/kerberos.c +++ b/src/lib/protocols/kerberos.c @@ -32,6 +32,10 @@ #define KERBEROS_PORT 88 +static int ndpi_search_kerberos_extra(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow); + + static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_KERBEROS, NDPI_PROTOCOL_UNKNOWN); @@ -158,6 +162,9 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, #ifdef KERBEROS_DEBUG printf("[Kerberos] Packet found 0x%02X/%u\n", msg_type, msg_type); #endif + + ndpi_int_kerberos_add_connection(ndpi_struct, flow); + if(msg_type != 0x0d) /* TGS-REP */ { /* Process only on requests */ if(packet->payload[koffset+1] == 0xA3) { @@ -309,6 +316,19 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, } } } +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Setting extra func from AS-REQ\n"); +#endif + flow->check_extra_packets = 1; + flow->max_extra_packets_to_check = 5; /* Reply may be split into multiple segments */ + flow->extra_packets_func = ndpi_search_kerberos_extra; + } else if(msg_type == 0x0e) /* AS-REQ */ { +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Processing AS-REQ\n"); +#endif + /* Nothing specific to do; stop dissecting this flow */ + flow->extra_packets_func = NULL; + } else if(msg_type == 0x0c) /* TGS-REQ */ { #ifdef KERBEROS_DEBUG printf("[Kerberos] Processing TGS-REQ\n"); @@ -357,18 +377,22 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, } } } +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Setting extra func from TGS-REQ\n"); +#endif + if(!packet->udp) { + flow->check_extra_packets = 1; + flow->max_extra_packets_to_check = 5; /* Reply may be split into multiple segments */ + flow->extra_packets_func = ndpi_search_kerberos_extra; + } - if(packet->udp) - ndpi_int_kerberos_add_connection(ndpi_struct, flow); - - /* We set the protocol in the response */ if(flow->kerberos_buf.pktbuf != NULL) { ndpi_free(flow->kerberos_buf.pktbuf); packet->payload = original_packet_payload; packet->payload_packet_len = original_payload_packet_len; flow->kerberos_buf.pktbuf = NULL; } - + return; } else if(msg_type == 0x0d) /* TGS-REP */ { u_int16_t pad_data_len, cname_offset; @@ -403,24 +427,20 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, if(cname_len && cname_str[cname_len-1] == '$') { cname_str[cname_len-1] = '\0'; snprintf(flow->protos.kerberos.hostname, sizeof(flow->protos.kerberos.hostname), "%s", cname_str); - } else + } else { snprintf(flow->protos.kerberos.username, sizeof(flow->protos.kerberos.username), "%s", cname_str); + } - ndpi_int_kerberos_add_connection(ndpi_struct, flow); +#ifdef KERBEROS_DEBUG + printf("[TGS-REP] Found everything. disabling extra func\n"); +#endif + flow->extra_packets_func = NULL; } } } return; } - - if(packet->payload_packet_len > 21 && - packet->payload[16] == 0x05 && - (packet->payload[21] == 0x0a || - packet->payload[21] == 0x0c || packet->payload[21] == 0x0d || packet->payload[21] == 0x0e)) { - ndpi_int_kerberos_add_connection(ndpi_struct, flow); - return; - } } } } else { @@ -437,6 +457,27 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } +static int ndpi_search_kerberos_extra(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + +#ifdef KERBEROS_DEBUG + printf("[Kerberos] Extra function\n"); +#endif + + /* Unfortunately, generic "extra function" code doesn't honour protocol bitmask */ + /* TODO: handle that in ndpi_main.c for all the protocols */ + if(packet->payload_packet_len == 0 || + packet->tcp_retransmission) + return 1; + + /* Possibly dissect the reply */ + ndpi_search_kerberos(ndpi_struct, flow); + + /* Possibly more processing */ + return 1; +} void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c index b3c087ea2..8a4e8fa2e 100644 --- a/src/lib/protocols/mail_imap.c +++ b/src/lib/protocols/mail_imap.c @@ -177,16 +177,16 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, if(user) { char *pwd; - snprintf(flow->protos.ftp_imap_pop_smtp.username, - sizeof(flow->protos.ftp_imap_pop_smtp.username), + snprintf(flow->ftp_imap_pop_smtp.username, + sizeof(flow->ftp_imap_pop_smtp.username), "%s", user); ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); pwd = strtok_r(NULL, " \"\r\n", &saveptr); if(pwd) { - snprintf(flow->protos.ftp_imap_pop_smtp.password, - sizeof(flow->protos.ftp_imap_pop_smtp.password), + snprintf(flow->ftp_imap_pop_smtp.password, + sizeof(flow->ftp_imap_pop_smtp.password), "%s", pwd); } } @@ -320,7 +320,7 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, || (flow->l4.tcp.mail_imap_stage == 5) || (flow->l4.tcp.mail_imap_stage == 7) ) { - if((flow->protos.ftp_imap_pop_smtp.username[0] != '\0') + if((flow->ftp_imap_pop_smtp.username[0] != '\0') || (flow->l4.tcp.mail_imap_stage >= 7)) { NDPI_LOG_INFO(ndpi_struct, "found MAIL_IMAP\n"); ndpi_int_mail_imap_add_connection(ndpi_struct, flow); diff --git a/src/lib/protocols/mail_pop.c b/src/lib/protocols/mail_pop.c index c51192b44..483c4da35 100644 --- a/src/lib/protocols/mail_pop.c +++ b/src/lib/protocols/mail_pop.c @@ -77,8 +77,8 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod && (packet->payload[1] == 'S' || packet->payload[1] == 's') && (packet->payload[2] == 'E' || packet->payload[2] == 'e') && (packet->payload[3] == 'R' || packet->payload[3] == 'r')) { - ndpi_user_pwd_payload_copy((u_int8_t*)flow->protos.ftp_imap_pop_smtp.username, - sizeof(flow->protos.ftp_imap_pop_smtp.username), 5, + ndpi_user_pwd_payload_copy((u_int8_t*)flow->ftp_imap_pop_smtp.username, + sizeof(flow->ftp_imap_pop_smtp.username), 5, packet->payload, packet->payload_packet_len); ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); @@ -88,8 +88,8 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod && (packet->payload[1] == 'A' || packet->payload[1] == 'a') && (packet->payload[2] == 'S' || packet->payload[2] == 's') && (packet->payload[3] == 'S' || packet->payload[3] == 's')) { - ndpi_user_pwd_payload_copy((u_int8_t*)flow->protos.ftp_imap_pop_smtp.password, - sizeof(flow->protos.ftp_imap_pop_smtp.password), 5, + ndpi_user_pwd_payload_copy((u_int8_t*)flow->ftp_imap_pop_smtp.password, + sizeof(flow->ftp_imap_pop_smtp.password), 5, packet->payload, packet->payload_packet_len); ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); @@ -182,7 +182,7 @@ void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct if(flow->l4.tcp.mail_pop_stage > 0) { NDPI_LOG_INFO(ndpi_struct, "mail_pop identified\n"); - if((flow->protos.ftp_imap_pop_smtp.password[0] != '\0') + if((flow->ftp_imap_pop_smtp.password[0] != '\0') || (flow->l4.tcp.mail_pop_stage > 3)) { ndpi_int_mail_pop_add_connection(ndpi_struct, flow); popInitExtraPacketProcessing(flow); @@ -222,7 +222,7 @@ int ndpi_extra_search_mail_pop_tcp(struct ndpi_detection_module_struct *ndpi_str ndpi_search_mail_pop_tcp(ndpi_struct, flow); - rc = (flow->protos.ftp_imap_pop_smtp.password[0] == '\0') ? 1 : 0; + rc = (flow->ftp_imap_pop_smtp.password[0] == '\0') ? 1 : 0; #ifdef POP_DEBUG printf("**** %s() [rc: %d]\n", __FUNCTION__, rc); diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c index 551f67886..31310202b 100644 --- a/src/lib/protocols/mail_smtp.c +++ b/src/lib/protocols/mail_smtp.c @@ -93,19 +93,19 @@ static void get_credentials_auth_plain(struct ndpi_detection_module_struct *ndpi user_len = i - 1; } if(user_len > 0) { - user_len = ndpi_min(user_len, sizeof(flow->protos.ftp_imap_pop_smtp.username) - 1); + user_len = ndpi_min(user_len, sizeof(flow->ftp_imap_pop_smtp.username) - 1); - memcpy(flow->protos.ftp_imap_pop_smtp.username, out + 1, user_len); - flow->protos.ftp_imap_pop_smtp.username[user_len] = '\0'; + memcpy(flow->ftp_imap_pop_smtp.username, out + 1, user_len); + flow->ftp_imap_pop_smtp.username[user_len] = '\0'; ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); if(1 + user_len + 1 < out_len) { unsigned int pwd_len; - pwd_len = ndpi_min(out_len - (1 + user_len + 1), sizeof(flow->protos.ftp_imap_pop_smtp.password) - 1); - memcpy(flow->protos.ftp_imap_pop_smtp.password, out + 1 + user_len + 1, pwd_len); - flow->protos.ftp_imap_pop_smtp.password[pwd_len] = '\0'; + pwd_len = ndpi_min(out_len - (1 + user_len + 1), sizeof(flow->ftp_imap_pop_smtp.password) - 1); + memcpy(flow->ftp_imap_pop_smtp.password, out + 1 + user_len + 1, pwd_len); + flow->ftp_imap_pop_smtp.password[pwd_len] = '\0'; } } ndpi_free(out); @@ -183,25 +183,25 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o') && packet->line[a].ptr[4] == ' ') { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_HELO_EHLO; - flow->protos.ftp_imap_pop_smtp.auth_found = 0; + flow->ftp_imap_pop_smtp.auth_found = 0; } else if((packet->line[a].ptr[0] == 'M' || packet->line[a].ptr[0] == 'm') && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a') && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i') && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l') && packet->line[a].ptr[4] == ' ') { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_MAIL; - flow->protos.ftp_imap_pop_smtp.auth_found = 0; + flow->ftp_imap_pop_smtp.auth_found = 0; /* We shouldn't be here if there are credentials */ - flow->protos.ftp_imap_pop_smtp.auth_done = 1; + flow->ftp_imap_pop_smtp.auth_done = 1; } else if((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r') && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c') && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p') && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't') && packet->line[a].ptr[4] == ' ') { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RCPT; - flow->protos.ftp_imap_pop_smtp.auth_found = 0; + flow->ftp_imap_pop_smtp.auth_found = 0; /* We shouldn't be here if there are credentials */ - flow->protos.ftp_imap_pop_smtp.auth_done = 1; + flow->ftp_imap_pop_smtp.auth_done = 1; } else if((packet->line[a].ptr[0] == 'A' || packet->line[a].ptr[0] == 'a') && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u') && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't') @@ -210,7 +210,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, #ifdef SMTP_DEBUG printf("%s() AUTH [%.*s]\n", __FUNCTION__, packet->line[a].len, packet->line[a].ptr); #endif - flow->protos.ftp_imap_pop_smtp.auth_found = 1; + flow->ftp_imap_pop_smtp.auth_found = 1; if(packet->line[a].len >= 6) { if(packet->line[a].ptr[5] == 'L' || packet->line[a].ptr[5] == 'l') { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_AUTH_LOGIN; @@ -220,7 +220,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, /* AUTH PLAIN: username and pwd here */ get_credentials_auth_plain(ndpi_struct, flow, packet->line[a].ptr, packet->line[a].len); - flow->protos.ftp_imap_pop_smtp.auth_done = 1; + flow->ftp_imap_pop_smtp.auth_done = 1; } } } else { @@ -229,9 +229,9 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, printf("%s() => [%.*s]\n", __FUNCTION__, packet->line[a].len, packet->line[a].ptr); #endif - if(flow->protos.ftp_imap_pop_smtp.auth_found && + if(flow->ftp_imap_pop_smtp.auth_found && (flow->l4.tcp.smtp_command_bitmask & SMTP_BIT_AUTH_LOGIN)) { - if(flow->protos.ftp_imap_pop_smtp.username[0] == '\0') { + if(flow->ftp_imap_pop_smtp.username[0] == '\0') { /* Username */ u_int8_t buf[48]; u_char *out; @@ -241,22 +241,22 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, packet->line[a].ptr, packet->line[a].len); #ifdef SMTP_DEBUG - printf("%s() => [auth: %u] (username) [%s]\n", __FUNCTION__, flow->protos.ftp_imap_pop_smtp.auth_found, buf); + printf("%s() => [auth: %u] (username) [%s]\n", __FUNCTION__, flow->ftp_imap_pop_smtp.auth_found, buf); #endif out = ndpi_base64_decode((const u_char*)buf, (size_t)strlen((const char*)buf), &out_len); if(out) { - size_t len = ndpi_min(out_len, sizeof(flow->protos.ftp_imap_pop_smtp.username) - 1); + size_t len = ndpi_min(out_len, sizeof(flow->ftp_imap_pop_smtp.username) - 1); - memcpy(flow->protos.ftp_imap_pop_smtp.username, out, len); - flow->protos.ftp_imap_pop_smtp.username[len] = '\0'; + memcpy(flow->ftp_imap_pop_smtp.username, out, len); + flow->ftp_imap_pop_smtp.username[len] = '\0'; ndpi_free(out); } ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); - } else if(flow->protos.ftp_imap_pop_smtp.password[0] == '\0') { + } else if(flow->ftp_imap_pop_smtp.password[0] == '\0') { /* Password */ u_int8_t buf[48]; u_char *out; @@ -266,23 +266,23 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, packet->line[a].ptr, packet->line[a].len); #ifdef SMTP_DEBUG - printf("%s() => [auth: %u] (password) [%s]\n", __FUNCTION__, flow->protos.ftp_imap_pop_smtp.auth_found, buf); + printf("%s() => [auth: %u] (password) [%s]\n", __FUNCTION__, flow->ftp_imap_pop_smtp.auth_found, buf); #endif out = ndpi_base64_decode((const u_char*)buf, (size_t)strlen((const char*)buf), &out_len); if(out) { - size_t len = ndpi_min(out_len, sizeof(flow->protos.ftp_imap_pop_smtp.password) - 1); + size_t len = ndpi_min(out_len, sizeof(flow->ftp_imap_pop_smtp.password) - 1); - memcpy(flow->protos.ftp_imap_pop_smtp.password, out, len); - flow->protos.ftp_imap_pop_smtp.password[len] = '\0'; + memcpy(flow->ftp_imap_pop_smtp.password, out, len); + flow->ftp_imap_pop_smtp.password[len] = '\0'; ndpi_free(out); } ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); - flow->protos.ftp_imap_pop_smtp.auth_done = 1; + flow->ftp_imap_pop_smtp.auth_done = 1; } else { flow->host_server_name[0] = '\0'; NDPI_EXCLUDE_PROTO(ndpi_struct, flow); @@ -303,8 +303,8 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[6] == 'l') && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[7] == 's')) { flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_STARTTLS; - flow->protos.ftp_imap_pop_smtp.auth_tls = 1; - flow->protos.ftp_imap_pop_smtp.auth_done = 1; + flow->ftp_imap_pop_smtp.auth_tls = 1; + flow->ftp_imap_pop_smtp.auth_done = 1; } } @@ -342,7 +342,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, #ifdef SMTP_DEBUG printf("%s() [bit_count: %u][%s]\n", __FUNCTION__, - bit_count, flow->protos.ftp_imap_pop_smtp.password); + bit_count, flow->ftp_imap_pop_smtp.password); #endif /* Only if we don't have already set the protocol via hostname matching */ @@ -380,7 +380,7 @@ int ndpi_extra_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_st ndpi_search_mail_smtp_tcp(ndpi_struct, flow); - rc = (flow->protos.ftp_imap_pop_smtp.password[0] == '\0') ? 1 : 0; + rc = (flow->ftp_imap_pop_smtp.password[0] == '\0') ? 1 : 0; #ifdef SMTP_DEBUG printf("**** %s() [rc: %d]\n", __FUNCTION__, rc); diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index 206c3b951..f908dc58c 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1297,7 +1297,7 @@ static void process_tls(struct ndpi_detection_module_struct *ndpi_struct, packet->payload_packet_len = crypto_data_len; processClientServerHello(ndpi_struct, flow, version); - flow->protos.tls_quic_stun.tls_quic.hello_processed = 1; /* Allow matching of custom categories */ + flow->protos.tls_quic.hello_processed = 1; /* Allow matching of custom categories */ /* Restore */ packet->payload = p; @@ -1307,12 +1307,12 @@ static void process_tls(struct ndpi_detection_module_struct *ndpi_struct, this way we lose JA3S and negotiated ciphers... Negotiated version is only present in the ServerHello message too, but fortunately, QUIC always uses TLS version 1.3 */ - flow->protos.tls_quic_stun.tls_quic.ssl_version = 0x0304; + flow->protos.tls_quic.ssl_version = 0x0304; /* DNS-over-QUIC: ALPN is "doq" or "doq-XXX" (for drafts versions) */ - if(flow->protos.tls_quic_stun.tls_quic.alpn && - strncmp(flow->protos.tls_quic_stun.tls_quic.alpn, "doq", 3) == 0) { - NDPI_LOG_DBG(ndpi_struct, "Found DOQ (ALPN: [%s])\n", flow->protos.tls_quic_stun.tls_quic.alpn); + if(flow->protos.tls_quic.alpn && + strncmp(flow->protos.tls_quic.alpn, "doq", 3) == 0) { + NDPI_LOG_DBG(ndpi_struct, "Found DOQ (ALPN: [%s])\n", flow->protos.tls_quic.alpn); ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DOH_DOT, NDPI_PROTOCOL_QUIC); } } @@ -1356,22 +1356,22 @@ static void process_chlo(struct ndpi_detection_module_struct *ndpi_struct, crypto_data_len, tag_offset_start, prev_offset, offset, len); #endif if(memcmp(tag, "SNI\0", 4) == 0) { - sni_len = MIN(len, sizeof(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name) - 1); - memcpy(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, + sni_len = MIN(len, sizeof(flow->protos.tls_quic.client_requested_server_name) - 1); + memcpy(flow->protos.tls_quic.client_requested_server_name, &crypto_data[tag_offset_start + prev_offset], sni_len); - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[sni_len] = '\0'; + flow->protos.tls_quic.client_requested_server_name[sni_len] = '\0'; NDPI_LOG_DBG2(ndpi_struct, "SNI: [%s]\n", - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); + flow->protos.tls_quic.client_requested_server_name); ndpi_match_host_subprotocol(ndpi_struct, flow, - (char *)flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, - strlen((const char*)flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), + (char *)flow->protos.tls_quic.client_requested_server_name, + strlen((const char*)flow->protos.tls_quic.client_requested_server_name), &ret_match, NDPI_PROTOCOL_QUIC); - flow->protos.tls_quic_stun.tls_quic.hello_processed = 1; /* Allow matching of custom categories */ + flow->protos.tls_quic.hello_processed = 1; /* Allow matching of custom categories */ ndpi_check_dga_name(ndpi_struct, flow, - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, 1); + flow->protos.tls_quic.client_requested_server_name, 1); sni_found = 1; if (ua_found) @@ -1396,7 +1396,7 @@ static void process_chlo(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG(ndpi_struct, "Something went wrong in tags iteration\n"); /* Add check for missing SNI */ - if(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] == '\0') { + if(flow->protos.tls_quic.client_requested_server_name[0] == '\0') { /* This is a bit suspicious */ ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI); } @@ -1508,7 +1508,7 @@ static int eval_extra_processing(struct ndpi_detection_module_struct *ndpi_struc */ if((version == V_Q046 && - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] == '\0') || + flow->protos.tls_quic.client_requested_server_name[0] == '\0') || is_ch_reassembler_pending(flow)) { NDPI_LOG_DBG2(ndpi_struct, "We have further work to do\n"); return 1; diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c index 24f92afe2..2d5ad5981 100644 --- a/src/lib/protocols/rtp.c +++ b/src/lib/protocols/rtp.c @@ -84,7 +84,7 @@ 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->protos.tls_quic_stun.stun.num_binding_requests + || flow->stun.num_binding_requests ) { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); return; diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index e1d8f11c8..f0884fae3 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -164,7 +164,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * } else if(payload_length < sizeof(struct stun_packet_header)) { /* This looks like an invalid packet */ - if(flow->protos.tls_quic_stun.stun.num_udp_pkts > 0) { + if(flow->stun.num_udp_pkts > 0) { // flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); } else @@ -260,7 +260,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * } if(msg_type == 0x01 /* Binding Request */) { - flow->protos.tls_quic_stun.stun.num_binding_requests++; + flow->stun.num_binding_requests++; if(!msg_len && flow->guessed_host_protocol_id == NDPI_PROTOCOL_GOOGLE) flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO; @@ -268,7 +268,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; if(!msg_len) { - /* flow->protos.tls_quic_stun.stun.num_udp_pkts++; */ + /* flow->stun.num_udp_pkts++; */ return(NDPI_IS_NOT_STUN); /* This to keep analyzing STUN instead of giving up */ } } @@ -278,13 +278,13 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * return(NDPI_IS_NOT_STUN); } - flow->protos.tls_quic_stun.stun.num_udp_pkts++; + flow->stun.num_udp_pkts++; if((payload[0] == 0x80 && payload_length < 512 && ((msg_len+20) <= payload_length))) { flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); /* This is WhatsApp Call */ } else if((payload[0] == 0x90) && (((msg_len+11) == payload_length) || - (flow->protos.tls_quic_stun.stun.num_binding_requests >= 4))) { + (flow->stun.num_binding_requests >= 4))) { flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); /* This is WhatsApp Call */ } @@ -462,14 +462,14 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * } } - if((flow->protos.tls_quic_stun.stun.num_udp_pkts > 0) && (msg_type <= 0x00FF)) { + if((flow->stun.num_udp_pkts > 0) && (msg_type <= 0x00FF)) { flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); } else return(NDPI_IS_NOT_STUN); udp_stun_found: - flow->protos.tls_quic_stun.stun.num_processed_pkts++; + flow->stun.num_processed_pkts++; #ifdef DEBUG_STUN printf("==>> NDPI_PROTOCOL_WHATSAPP_CALL\n"); @@ -480,7 +480,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * else if(is_google_ip_address(ntohl(packet->iph->saddr)) || is_google_ip_address(ntohl(packet->iph->daddr))) flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO; - rc = (flow->protos.tls_quic_stun.stun.num_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN; + rc = (flow->stun.num_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN; return rc; } @@ -532,7 +532,7 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n return; } - if(flow->protos.tls_quic_stun.stun.num_udp_pkts >= MAX_NUM_STUN_PKTS) + if(flow->stun.num_udp_pkts >= MAX_NUM_STUN_PKTS) NDPI_EXCLUDE_PROTO(ndpi_struct, flow); if(flow->packet_counter > 0) { diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 5b2941405..d912ae947 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -391,8 +391,8 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi printf("[TLS] %s() IssuerDN [%s]\n", __FUNCTION__, rdnSeqBuf); #endif - if(rdn_len && (flow->protos.tls_quic_stun.tls_quic.issuerDN == NULL)) { - flow->protos.tls_quic_stun.tls_quic.issuerDN = ndpi_strdup(rdnSeqBuf); + if(rdn_len && (flow->protos.tls_quic.issuerDN == NULL)) { + flow->protos.tls_quic.issuerDN = ndpi_strdup(rdnSeqBuf); if (ndpi_is_printable_string(rdnSeqBuf, rdn_len) == 0) { ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); } @@ -421,10 +421,10 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi /* 141021000000Z */ if(strptime(utcDate, "%y%m%d%H%M%SZ", &utc) != NULL) { - flow->protos.tls_quic_stun.tls_quic.notBefore = timegm(&utc); + flow->protos.tls_quic.notBefore = timegm(&utc); #ifdef DEBUG_TLS printf("[CERTIFICATE] notBefore %u [%s]\n", - flow->protos.tls_quic_stun.tls_quic.notBefore, utcDate); + flow->protos.tls_quic.notBefore, utcDate); #endif } } @@ -455,20 +455,20 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi /* 141021000000Z */ if(strptime(utcDate, "%y%m%d%H%M%SZ", &utc) != NULL) { - flow->protos.tls_quic_stun.tls_quic.notAfter = timegm(&utc); + flow->protos.tls_quic.notAfter = timegm(&utc); #ifdef DEBUG_TLS printf("[CERTIFICATE] notAfter %u [%s]\n", - flow->protos.tls_quic_stun.tls_quic.notAfter, utcDate); + flow->protos.tls_quic.notAfter, utcDate); #endif } } - if (flow->protos.tls_quic_stun.tls_quic.notBefore > TLS_LIMIT_DATE) - if((flow->protos.tls_quic_stun.tls_quic.notAfter-flow->protos.tls_quic_stun.tls_quic.notBefore) > TLS_THRESHOLD) + if (flow->protos.tls_quic.notBefore > TLS_LIMIT_DATE) + if((flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) > TLS_THRESHOLD) ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG); /* Certificate validity longer than 13 months*/ - if((time_sec < flow->protos.tls_quic_stun.tls_quic.notBefore) - || (time_sec > flow->protos.tls_quic_stun.tls_quic.notAfter)) + if((time_sec < flow->protos.tls_quic.notBefore) + || (time_sec > flow->protos.tls_quic.notAfter)) ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED); /* Certificate expired */ } } @@ -478,7 +478,7 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi u_int8_t matched_name = 0; /* If the client hello was not observed or the requested name was missing, there is no need to trigger an alert */ - if(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] == '\0') + if(flow->protos.tls_quic.client_requested_server_name[0] == '\0') matched_name = 1; #ifdef DEBUG_TLS @@ -520,7 +520,7 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi #if DEBUG_TLS printf("[TLS] dNSName %s [%s][len: %u][leftover: %d]\n", dNSName, - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, len, + flow->protos.tls_quic.client_requested_server_name, len, packet->payload_packet_len-i-len); #endif if (ndpi_is_printable_string(dNSName, len) == 0) { @@ -530,19 +530,19 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi if(matched_name == 0) { #if DEBUG_TLS printf("[TLS] Trying to match '%s' with '%s'\n", - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, + flow->protos.tls_quic.client_requested_server_name, dNSName); #endif - if(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] == '\0') + if(flow->protos.tls_quic.client_requested_server_name[0] == '\0') matched_name = 1; /* No SNI */ else if (dNSName[0] == '*') { - char * label = strstr(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, &dNSName[1]); + char * label = strstr(flow->protos.tls_quic.client_requested_server_name, &dNSName[1]); if (label != NULL) { - char * first_dot = strchr(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, '.'); + char * first_dot = strchr(flow->protos.tls_quic.client_requested_server_name, '.'); if (first_dot == NULL || first_dot >= label) { @@ -550,33 +550,33 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi } } } - else if(strcmp(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, dNSName) == 0) { + else if(strcmp(flow->protos.tls_quic.client_requested_server_name, dNSName) == 0) { matched_name = 1; } } - if(flow->protos.tls_quic_stun.tls_quic.server_names == NULL) - flow->protos.tls_quic_stun.tls_quic.server_names = ndpi_strdup(dNSName), - flow->protos.tls_quic_stun.tls_quic.server_names_len = strlen(dNSName); + if(flow->protos.tls_quic.server_names == NULL) + flow->protos.tls_quic.server_names = ndpi_strdup(dNSName), + flow->protos.tls_quic.server_names_len = strlen(dNSName); else { u_int16_t dNSName_len = strlen(dNSName); - u_int16_t newstr_len = flow->protos.tls_quic_stun.tls_quic.server_names_len + dNSName_len + 1; - char *newstr = (char*)ndpi_realloc(flow->protos.tls_quic_stun.tls_quic.server_names, - flow->protos.tls_quic_stun.tls_quic.server_names_len+1, newstr_len+1); + u_int16_t newstr_len = flow->protos.tls_quic.server_names_len + dNSName_len + 1; + char *newstr = (char*)ndpi_realloc(flow->protos.tls_quic.server_names, + flow->protos.tls_quic.server_names_len+1, newstr_len+1); if(newstr) { - flow->protos.tls_quic_stun.tls_quic.server_names = newstr; - flow->protos.tls_quic_stun.tls_quic.server_names[flow->protos.tls_quic_stun.tls_quic.server_names_len] = ','; - strncpy(&flow->protos.tls_quic_stun.tls_quic.server_names[flow->protos.tls_quic_stun.tls_quic.server_names_len+1], + flow->protos.tls_quic.server_names = newstr; + flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len] = ','; + strncpy(&flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len+1], dNSName, dNSName_len+1); - flow->protos.tls_quic_stun.tls_quic.server_names[newstr_len] = '\0'; - flow->protos.tls_quic_stun.tls_quic.server_names_len = newstr_len; + flow->protos.tls_quic.server_names[newstr_len] = '\0'; + flow->protos.tls_quic.server_names_len = newstr_len; } } - if(!flow->protos.tls_quic_stun.tls_quic.subprotocol_detected) + if(!flow->protos.tls_quic.subprotocol_detected) if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, dNSName, len)) - flow->protos.tls_quic_stun.tls_quic.subprotocol_detected = 1; + flow->protos.tls_quic.subprotocol_detected = 1; i += len; } else { @@ -599,8 +599,8 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi } } /* for */ - if(rdn_len && (flow->protos.tls_quic_stun.tls_quic.subjectDN == NULL)) { - flow->protos.tls_quic_stun.tls_quic.subjectDN = ndpi_strdup(rdnSeqBuf); + if(rdn_len && (flow->protos.tls_quic.subjectDN == NULL)) { + flow->protos.tls_quic.subjectDN = ndpi_strdup(rdnSeqBuf); if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) { /* No idea what is happening behind the scenes: let's check the certificate */ @@ -631,8 +631,8 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi } } - if(flow->protos.tls_quic_stun.tls_quic.subjectDN && flow->protos.tls_quic_stun.tls_quic.issuerDN - && (!strcmp(flow->protos.tls_quic_stun.tls_quic.subjectDN, flow->protos.tls_quic_stun.tls_quic.issuerDN))) + if(flow->protos.tls_quic.subjectDN && flow->protos.tls_quic.issuerDN + && (!strcmp(flow->protos.tls_quic.subjectDN, flow->protos.tls_quic.issuerDN))) ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SELFSIGNED_CERTIFICATE); #if DEBUG_TLS @@ -721,12 +721,12 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct, &packet->payload[certificates_offset], certificate_len); - SHA1Final(flow->protos.tls_quic_stun.tls_quic.sha1_certificate_fingerprint, &srv_cert_fingerprint_ctx); + SHA1Final(flow->protos.tls_quic.sha1_certificate_fingerprint, &srv_cert_fingerprint_ctx); flow->l4.tcp.tls.fingerprint_set = 1; - uint8_t * sha1 = flow->protos.tls_quic_stun.tls_quic.sha1_certificate_fingerprint; - const size_t sha1_siz = sizeof(flow->protos.tls_quic_stun.tls_quic.sha1_certificate_fingerprint); + uint8_t * sha1 = flow->protos.tls_quic.sha1_certificate_fingerprint; + const size_t sha1_siz = sizeof(flow->protos.tls_quic.sha1_certificate_fingerprint); char sha1_str[20 /* sha1_siz */ * 2 + 1]; static const char hexalnum[] = "0123456789ABCDEF"; size_t i; @@ -774,7 +774,7 @@ static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_packet_struct *packet = &ndpi_struct->packet; int ret; -#ifdef DEBUG_TL +#ifdef DEBUG_TLS printf("[TLS] Processing block %u\n", packet->payload[0]); #endif @@ -782,16 +782,16 @@ static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct, case 0x01: /* Client Hello */ case 0x02: /* Server Hello */ processClientServerHello(ndpi_struct, flow, 0); - flow->protos.tls_quic_stun.tls_quic.hello_processed = 1; + flow->protos.tls_quic.hello_processed = 1; ndpi_int_tls_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TLS); #ifdef DEBUG_TLS printf("*** TLS [version: %02X][%s Hello]\n", - flow->protos.tls_quic_stun.tls_quic.ssl_version, + flow->protos.tls_quic.ssl_version, (packet->payload[0] == 0x01) ? "Client" : "Server"); #endif - if((flow->protos.tls_quic_stun.tls_quic.ssl_version >= 0x0304 /* TLS 1.3 */) + if((flow->protos.tls_quic.ssl_version >= 0x0304 /* TLS 1.3 */) && (packet->payload[0] == 0x02 /* Server Hello */)) { flow->l4.tcp.tls.certificate_processed = 1; /* No Certificate with TLS 1.3+ */ } @@ -802,7 +802,7 @@ static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct, case 0x0b: /* Certificate */ /* Important: populate the tls union fields only after * ndpi_int_tls_add_connection has been called */ - if(flow->protos.tls_quic_stun.tls_quic.hello_processed) { + if(flow->protos.tls_quic.hello_processed) { ret = processCertificate(ndpi_struct, flow); if (ret != 1) { #ifdef DEBUG_TLS @@ -1106,7 +1106,7 @@ static void tlsInitExtraPacketProcessing(struct ndpi_detection_module_struct *nd static void tlsCheckUncommonALPN(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - char * alpn_start = flow->protos.tls_quic_stun.tls_quic.alpn; + char * alpn_start = flow->protos.tls_quic.alpn; char * comma_or_nul = alpn_start; do { int alpn_len; @@ -1310,10 +1310,10 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, return(0); /* Not found */ ja3.server.num_cipher = 1, ja3.server.cipher[0] = ntohs(*((u_int16_t*)&packet->payload[offset])); - if((flow->protos.tls_quic_stun.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja3.server.cipher[0])) == 1) + if((flow->protos.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja3.server.cipher[0])) == 1) ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER); - flow->protos.tls_quic_stun.tls_quic.server_cipher = ja3.server.cipher[0]; + flow->protos.tls_quic.server_cipher = ja3.server.cipher[0]; #ifdef DEBUG_TLS printf("TLS [server][session_id_len: %u][cipher: %04X]\n", session_id_len, ja3.server.cipher[0]); @@ -1360,7 +1360,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, printf("TLS [server] [TLS version: 0x%04X]\n", tls_version); #endif - flow->protos.tls_quic_stun.tls_quic.ssl_version = ja3.server.tls_supported_version = tls_version; + flow->protos.tls_quic.ssl_version = ja3.server.tls_supported_version = tls_version; } } else if(extension_id == 16 /* application_layer_protocol_negotiation (ALPN) */ && offset + 6 < packet->payload_packet_len) { @@ -1416,10 +1416,10 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if (ndpi_is_printable_string(alpn_str, alpn_str_len) == 0) ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); - if(flow->protos.tls_quic_stun.tls_quic.alpn == NULL) - flow->protos.tls_quic_stun.tls_quic.alpn = ndpi_strdup(alpn_str); + if(flow->protos.tls_quic.alpn == NULL) + flow->protos.tls_quic.alpn = ndpi_strdup(alpn_str); - if(flow->protos.tls_quic_stun.tls_quic.alpn != NULL) + if(flow->protos.tls_quic.alpn != NULL) tlsCheckUncommonALPN(ndpi_struct, flow); snprintf(ja3.server.alpn, sizeof(ja3.server.alpn), "%s", alpn_str); @@ -1508,13 +1508,13 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, ndpi_MD5Final(md5_hash, &ctx); for(i=0, j=0; i<16; i++) { - int rc = snprintf(&flow->protos.tls_quic_stun.tls_quic.ja3_server[j], - sizeof(flow->protos.tls_quic_stun.tls_quic.ja3_server)-j, "%02x", md5_hash[i]); + int rc = snprintf(&flow->protos.tls_quic.ja3_server[j], + sizeof(flow->protos.tls_quic.ja3_server)-j, "%02x", md5_hash[i]); if(rc <= 0) break; else j += rc; } #ifdef DEBUG_TLS - printf("[JA3] Server: %s \n", flow->protos.tls_quic_stun.tls_quic.ja3_server); + printf("[JA3] Server: %s \n", flow->protos.tls_quic.ja3_server); #endif } else if(handshake_type == 0x01 /* Client Hello */) { u_int16_t cipher_len, cipher_offset; @@ -1528,8 +1528,8 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, ja3.client.supported_versions[0] = '\0'; ja3.client.alpn[0] = '\0'; - flow->protos.tls_quic_stun.tls_quic.ssl_version = ja3.client.tls_handshake_version = tls_version; - if(flow->protos.tls_quic_stun.tls_quic.ssl_version < 0x0303) /* < TLSv1.2 */ + flow->protos.tls_quic.ssl_version = ja3.client.tls_handshake_version = tls_version; + if(flow->protos.tls_quic.ssl_version < 0x0303) /* < TLSv1.2 */ ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION); if((session_id_len+base_offset+3) > packet->payload_packet_len) @@ -1629,19 +1629,19 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, this is time consuming and we want to avoid overhead whem possible */ if(this_is_not_safari) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls = 0; + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0; else if((safari_ciphers == 12) || (this_is_not_safari && looks_like_safari_on_big_sur)) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls = 1; + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1; if(chrome_ciphers == 13) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_chrome_tls = 1; + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 1; /* Note that both Safari and Chrome can overlap */ #ifdef DEBUG_HEURISTIC printf("[CIPHERS] [is_chrome_tls: %u (%u)][is_safari_tls: %u (%u)][this_is_not_safari: %u]\n", - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_chrome_tls, + flow->protos.tls_quic.browser_heuristics.is_chrome_tls, chrome_ciphers, - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls, + flow->protos.tls_quic.browser_heuristics.is_safari_tls, safari_ciphers, this_is_not_safari); #endif @@ -1729,8 +1729,8 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, cleanupServerName(buffer, sizeof(buffer)); - snprintf(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, - sizeof(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name), + snprintf(flow->protos.tls_quic.client_requested_server_name, + sizeof(flow->protos.tls_quic.client_requested_server_name), "%s", buffer); #ifdef DEBUG_TLS printf("[TLS] SNI: [%s]\n", buffer); @@ -1742,19 +1742,19 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(!is_quic) { if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, buffer, strlen(buffer))) - flow->protos.tls_quic_stun.tls_quic.subprotocol_detected = 1; + flow->protos.tls_quic.subprotocol_detected = 1; } else { if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, buffer, strlen(buffer))) - flow->protos.tls_quic_stun.tls_quic.subprotocol_detected = 1; + flow->protos.tls_quic.subprotocol_detected = 1; } if(ndpi_check_dga_name(ndpi_struct, flow, - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, 1)) { - char *sni = flow->protos.tls_quic_stun.tls_quic.client_requested_server_name; + flow->protos.tls_quic.client_requested_server_name, 1)) { + char *sni = flow->protos.tls_quic.client_requested_server_name; int len = strlen(sni); #ifdef DEBUG_TLS - printf("[TLS] SNI: (DGA) [%s]\n", flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); + printf("[TLS] SNI: (DGA) [%s]\n", flow->protos.tls_quic.client_requested_server_name); #endif if((len >= 4) @@ -1764,7 +1764,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_TLS); } else { #ifdef DEBUG_TLS - printf("[TLS] SNI: (NO DGA) [%s]\n", flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); + printf("[TLS] SNI: (NO DGA) [%s]\n", flow->protos.tls_quic.client_requested_server_name); #endif } } else { @@ -1849,10 +1849,10 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, tot_signature_algorithms_len = ndpi_min((sizeof(ja3.client.signature_algorithms) / 2) - 1, tot_signature_algorithms_len); #ifdef TLS_HANDLE_SIGNATURE_ALGORITMS - flow->protos.tls_quic_stun.tls_quic.num_tls_signature_algorithms = ndpi_min(tot_signature_algorithms_len / 2, MAX_NUM_TLS_SIGNATURE_ALGORITHMS); + flow->protos.tls_quic.num_tls_signature_algorithms = ndpi_min(tot_signature_algorithms_len / 2, MAX_NUM_TLS_SIGNATURE_ALGORITHMS); - memcpy(flow->protos.tls_quic_stun.tls_quic.client_signature_algorithms, - &packet->payload[s_offset], 2 /* 16 bit */*flow->protos.tls_quic_stun.tls_quic.num_tls_signature_algorithms); + memcpy(flow->protos.tls_quic.client_signature_algorithms, + &packet->payload[s_offset], 2 /* 16 bit */*flow->protos.tls_quic.num_tls_signature_algorithms); #endif for(i=0; i<tot_signature_algorithms_len && s_offset+i<total_len; i++) { @@ -1899,7 +1899,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, #endif switch(signature_algo) { case ECDSA_SECP521R1_SHA512: - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_firefox_tls = 1; + flow->protos.tls_quic.browser_heuristics.is_firefox_tls = 1; break; case ECDSA_SECP256R1_SHA256: @@ -1925,29 +1925,29 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, safari_signature_algorithms, chrome_signature_algorithms); #endif - if(flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_firefox_tls) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls = 0, - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_chrome_tls = 0; + if(flow->protos.tls_quic.browser_heuristics.is_firefox_tls) + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0, + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; if(safari_signature_algorithms != 8) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls = 0; + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0; if((chrome_signature_algorithms != 8) || duplicate_found) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_chrome_tls = 0; + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; /* Avoid Chrome and Safari overlaps, thing that cannot happen with Firefox */ - if(flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_chrome_tls = 0; + if(flow->protos.tls_quic.browser_heuristics.is_safari_tls) + flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0; - if((flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_chrome_tls == 0) + if((flow->protos.tls_quic.browser_heuristics.is_chrome_tls == 0) && duplicate_found) - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls = 1; /* Safari */ + flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1; /* Safari */ #ifdef DEBUG_HEURISTIC printf("[SIGNATURE] [is_firefox_tls: %u][is_chrome_tls: %u][is_safari_tls: %u][duplicate_found: %u]\n", - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_firefox_tls, - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_chrome_tls, - flow->protos.tls_quic_stun.tls_quic.browser_heuristics.is_safari_tls, + flow->protos.tls_quic.browser_heuristics.is_firefox_tls, + flow->protos.tls_quic.browser_heuristics.is_chrome_tls, + flow->protos..tls_quic.browser_heuristics.is_safari_tls, duplicate_found); #endif @@ -2003,8 +2003,8 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, #ifdef DEBUG_TLS printf("Client TLS [ALPN: %s][len: %u]\n", alpn_str, alpn_str_len); #endif - if(flow->protos.tls_quic_stun.tls_quic.alpn == NULL) - flow->protos.tls_quic_stun.tls_quic.alpn = ndpi_strdup(alpn_str); + if(flow->protos.tls_quic.alpn == NULL) + flow->protos.tls_quic.alpn = ndpi_strdup(alpn_str); snprintf(ja3.client.alpn, sizeof(ja3.client.alpn), "%s", alpn_str); @@ -2061,8 +2061,8 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, printf("Client TLS [SUPPORTED_VERSIONS: %s]\n", ja3.client.supported_versions); #endif - if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions == NULL) - flow->protos.tls_quic_stun.tls_quic.tls_supported_versions = ndpi_strdup(version_str); + if(flow->protos.tls_quic.tls_supported_versions == NULL) + flow->protos.tls_quic.tls_supported_versions = ndpi_strdup(version_str); } } else if(extension_id == 65486 /* encrypted server name */) { /* @@ -2074,7 +2074,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, int initial_offset = e_offset; u_int16_t cipher_suite = ntohs(*((u_int16_t*)&packet->payload[e_offset])); - flow->protos.tls_quic_stun.tls_quic.encrypted_sni.cipher_suite = cipher_suite; + flow->protos.tls_quic.encrypted_sni.cipher_suite = cipher_suite; e_offset += 2; /* Cipher suite len */ @@ -2097,17 +2097,17 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, printf("Client TLS [Encrypted Server Name len: %u]\n", e_sni_len); #endif - if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni == NULL) { - flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni = (char*)ndpi_malloc(e_sni_len*2+1); + if(flow->protos.tls_quic.encrypted_sni.esni == NULL) { + flow->protos.tls_quic.encrypted_sni.esni = (char*)ndpi_malloc(e_sni_len*2+1); - if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni) { + if(flow->protos.tls_quic.encrypted_sni.esni) { u_int16_t i, off; for(i=e_offset, off=0; i<(e_offset+e_sni_len); i++) { - int rc = sprintf(&flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni[off], "%02X", packet->payload[i] & 0XFF); + int rc = sprintf(&flow->protos.tls_quic.encrypted_sni.esni[off], "%02X", packet->payload[i] & 0XFF); if(rc <= 0) { - flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni[off] = '\0'; + flow->protos.tls_quic.encrypted_sni.esni[off] = '\0'; break; } else off += rc; @@ -2240,19 +2240,19 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, ndpi_MD5Final(md5_hash, &ctx); for(i=0, j=0; i<16; i++) { - rc = snprintf(&flow->protos.tls_quic_stun.tls_quic.ja3_client[j], - sizeof(flow->protos.tls_quic_stun.tls_quic.ja3_client)-j, "%02x", + rc = snprintf(&flow->protos.tls_quic.ja3_client[j], + sizeof(flow->protos.tls_quic.ja3_client)-j, "%02x", md5_hash[i]); if(rc > 0) j += rc; else break; } #ifdef DEBUG_JA3C - printf("[JA3] Client: %s \n", flow->protos.tls_quic_stun.tls_quic.ja3_client); + printf("[JA3] Client: %s \n", flow->protos.tls_quic.ja3_client); #endif if(ndpi_struct->malicious_ja3_automa.ac_automa != NULL) { u_int16_t rc1 = ndpi_match_string(ndpi_struct->malicious_ja3_automa.ac_automa, - flow->protos.tls_quic_stun.tls_quic.ja3_client); + flow->protos.tls_quic.ja3_client); if(rc1 > 0) ndpi_set_risk(ndpi_struct, flow, NDPI_MALICIOUS_JA3); @@ -2260,22 +2260,22 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, } /* Before returning to the caller we need to make a final check */ - if((flow->protos.tls_quic_stun.tls_quic.ssl_version >= 0x0303) /* >= TLSv1.2 */ - && (flow->protos.tls_quic_stun.tls_quic.alpn == NULL) /* No ALPN */) { + if((flow->protos.tls_quic.ssl_version >= 0x0303) /* >= TLSv1.2 */ + && (flow->protos.tls_quic.alpn == NULL) /* No ALPN */) { ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_NOT_CARRYING_HTTPS); } /* Suspicious Domain Fronting: https://github.com/SixGenInc/Noctilucent/blob/master/docs/ */ - if(flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni && - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') { + if(flow->protos.tls_quic.encrypted_sni.esni && + flow->protos.tls_quic.client_requested_server_name[0] != '\0') { ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_ESNI_USAGE); } /* Add check for missing SNI */ - if((flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] == 0) - && (flow->protos.tls_quic_stun.tls_quic.ssl_version >= 0x0302) /* TLSv1.1 */ - && (flow->protos.tls_quic_stun.tls_quic.encrypted_sni.esni == NULL) /* No ESNI */ + if((flow->protos.tls_quic.client_requested_server_name[0] == 0) + && (flow->protos.tls_quic.ssl_version >= 0x0302) /* TLSv1.1 */ + && (flow->protos.tls_quic.encrypted_sni.esni == NULL) /* No ESNI */ ) { /* This is a bit suspicious */ ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI); @@ -2314,7 +2314,7 @@ static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_st __FUNCTION__, flow->guessed_host_protocol_id, packet->payload_packet_len, - flow->protos.tls_quic_stun.tls_quic.ssl_version); + flow->protos.tls_quic.ssl_version); #endif if(packet->udp != NULL) |