diff options
Diffstat (limited to 'src/lib/protocols/quic.c')
-rw-r--r-- | src/lib/protocols/quic.c | 59 |
1 files changed, 51 insertions, 8 deletions
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) { |