diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_api.h | 1 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 6 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 5 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 59 |
4 files changed, 61 insertions, 10 deletions
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index ce710ddf7..51c56c8f3 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -1167,6 +1167,7 @@ extern "C" { ndpi_protocol const * const l7_protocol); char* ndpi_ssl_version2str(char *buf, int buf_len, u_int16_t version, u_int8_t *unknown_tls_version); + char *ndpi_quic_version2str(char *buf, int buf_len, u_int32_t version); int ndpi_netbios_name_interpret(u_char *in, u_int in_len, u_char *out, u_int out_len); void ndpi_patchIPv6Address(char *str); void ndpi_user_pwd_payload_copy(u_int8_t *dest, u_int dest_len, u_int offset, diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index f3439ad88..5000b0cb9 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1591,6 +1591,8 @@ struct ndpi_flow_struct { } encrypted_ch; ndpi_cipher_weakness server_unsafe_cipher; + + u_int32_t quic_version; } tls_quic; /* Used also by DTLS and POPS/IMAPS/SMTPS/FTPS */ struct { @@ -1749,8 +1751,8 @@ struct ndpi_flow_struct { #if !defined(NDPI_CFFI_PREPROCESSING) && defined(__linux__) #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(sizeof(((struct ndpi_flow_struct *)0)->protos) <= 210, - "Size of the struct member protocols increased to more than 210 bytes, " +_Static_assert(sizeof(((struct ndpi_flow_struct *)0)->protos) <= 216, + "Size of the struct member protocols increased to more than 216 bytes, " "please check if this change is necessary."); _Static_assert(sizeof(struct ndpi_flow_struct) <= 968, "Size of the flow struct increased to more than 968 bytes, " diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 25d7e2cc6..73a1b5974 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1244,6 +1244,7 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, ndpi_serializer *serializer) { char buf[64]; char const *host_server_name; + char quic_version[16]; if(flow == NULL) return(-1); @@ -1442,6 +1443,10 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, if(flow->http.user_agent) ndpi_serialize_string_string(serializer, "user_agent", flow->http.user_agent); + ndpi_quic_version2str(quic_version, sizeof(quic_version), + flow->protos.tls_quic.quic_version); + ndpi_serialize_string_string(serializer, "quic_version", quic_version); + ndpi_tls2json(serializer, flow); ndpi_serialize_end_of_block(serializer); diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index 562c299ac..4b9474d7a 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -207,6 +207,47 @@ static int is_version_quic_v2(uint32_t version) return version == V_2; } +char *ndpi_quic_version2str(char *buf, int buf_len, u_int32_t version) { + + if(buf == NULL || buf_len <= 1) + return NULL; + + switch(version) { + case V_2: strncpy(buf, "V-2", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_1: strncpy(buf, "V-1", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q024: strncpy(buf, "Q024", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q025: strncpy(buf, "Q025", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q030: strncpy(buf, "Q030", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q033: strncpy(buf, "Q033", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q034: strncpy(buf, "Q034", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q035: strncpy(buf, "Q035", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q037: strncpy(buf, "Q037", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q039: strncpy(buf, "Q039", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q043: strncpy(buf, "Q043", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q046: strncpy(buf, "Q046", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_Q050: strncpy(buf, "Q050", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_T050: strncpy(buf, "T050", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_T051: strncpy(buf, "T051", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_MVFST_22: strncpy(buf, "MVFST-22", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_MVFST_27: strncpy(buf, "MVFST-27", buf_len); buf[buf_len - 1] = '\0'; return buf; + case V_MVFST_EXP: strncpy(buf, "MVFST-EXP", buf_len); buf[buf_len - 1] = '\0'; return buf; + } + + if(is_version_forcing_vn(version)) { + strncpy(buf, "Ver-Negotiation", buf_len); + buf[buf_len - 1] = '\0'; + return buf; + } + if(((version & 0xFFFFFF00) == 0xFF000000)) { + snprintf(buf, buf_len, "Draft-%d", version & 0x000000FF); + buf[buf_len - 1] = '\0'; + return buf; + } + + ndpi_snprintf(buf, buf_len, "Unknown (%04X)", version); + return buf; +} + int quic_len(const uint8_t *buf, uint64_t *value) { *value = buf[0]; @@ -1149,7 +1190,6 @@ static const uint8_t *get_reassembled_crypto_data(struct ndpi_detection_module_s const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - uint32_t version, u_int8_t *clear_payload, uint32_t clear_payload_len, uint64_t *crypto_data_len) { @@ -1157,6 +1197,7 @@ const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_struct, uint32_t counter; uint8_t first_nonzero_payload_byte, offset_len; uint64_t unused, frag_offset, frag_len; + u_int32_t version = flow->protos.tls_quic.quic_version; counter = 0; while(counter < clear_payload_len && clear_payload[counter] == 0) @@ -1330,8 +1371,7 @@ static uint8_t *get_clear_payload(struct ndpi_detection_module_struct *ndpi_stru void process_tls(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - const u_int8_t *crypto_data, uint32_t crypto_data_len, - uint32_t version) + const u_int8_t *crypto_data, uint32_t crypto_data_len) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; @@ -1343,7 +1383,7 @@ void process_tls(struct ndpi_detection_module_struct *ndpi_struct, packet->payload = crypto_data; packet->payload_packet_len = crypto_data_len; - processClientServerHello(ndpi_struct, flow, version); + processClientServerHello(ndpi_struct, flow, flow->protos.tls_quic.quic_version); flow->protos.tls_quic.hello_processed = 1; /* Allow matching of custom categories */ /* Restore */ @@ -1614,8 +1654,10 @@ static int may_be_initial_pkt(struct ndpi_detection_module_struct *ndpi_struct, /* ***************************************************************** */ static int eval_extra_processing(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, u_int32_t version) + struct ndpi_flow_struct *flow) { + u_int32_t version = flow->protos.tls_quic.quic_version; + /* For the time being we need extra processing in two cases only: 1) to detect Snapchat calls, i.e. RTP/RTCP multiplxed with QUIC. Two cases: @@ -1846,6 +1888,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_INFO(ndpi_struct, "found QUIC\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + flow->protos.tls_quic.quic_version = version; /* * 3) Skip not supported versions @@ -1883,7 +1926,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, /* * 5) Extract Crypto Data from the Payload */ - crypto_data = get_crypto_data(ndpi_struct, flow, version, + crypto_data = get_crypto_data(ndpi_struct, flow, clear_payload, clear_payload_len, &crypto_data_len); @@ -1894,7 +1937,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, if(!is_version_with_tls(version)) { process_chlo(ndpi_struct, flow, crypto_data, crypto_data_len); } else { - process_tls(ndpi_struct, flow, crypto_data, crypto_data_len, version); + process_tls(ndpi_struct, flow, crypto_data, crypto_data_len); } } if(is_version_with_encrypted_header(version)) { @@ -1904,7 +1947,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, /* * 7) We need to process other packets than (the first) ClientHello/CHLO? */ - if(eval_extra_processing(ndpi_struct, flow, version)) { + if(eval_extra_processing(ndpi_struct, flow)) { flow->max_extra_packets_to_check = 24; /* TODO */ flow->extra_packets_func = ndpi_search_quic_extra; } else if(!crypto_data) { |