2 * Routines for QUIC (IETF) dissection
3 * Copyright 2017, Alexis La Goutte <alexis.lagoutte at gmail dot com>
4 * Copyright 2018 Peter Wu <peter@lekensteyn.nl>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 * See https://quicwg.org
15 * https://tools.ietf.org/html/draft-ietf-quic-transport-14
16 * https://tools.ietf.org/html/draft-ietf-quic-tls-14
17 * https://tools.ietf.org/html/draft-ietf-quic-invariants-02
22 #include <epan/packet.h>
23 #include <epan/expert.h>
24 #include <epan/proto_data.h>
25 #include <epan/to_str.h>
26 #include "packet-ssl-utils.h"
27 #include "packet-ssl.h"
28 #include <epan/prefs.h>
29 #include <wsutil/pint.h>
31 #if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
32 /* Whether to provide support for authentication in addition to decryption. */
33 #define HAVE_LIBGCRYPT_AEAD
35 #if GCRYPT_VERSION_NUMBER >= 0x010700 /* 1.7.0 */
36 /* Whether ChaCh20 PNE can be supported. */
37 #define HAVE_LIBGCRYPT_CHACHA20
41 void proto_reg_handoff_quic(void);
42 void proto_register_quic(void);
44 /* Initialize the protocol and registered fields */
45 static int proto_quic = -1;
46 static int hf_quic_connection_number = -1;
47 static int hf_quic_header_form = -1;
48 static int hf_quic_long_packet_type = -1;
49 static int hf_quic_dcid = -1;
50 static int hf_quic_scid = -1;
51 static int hf_quic_dcil = -1;
52 static int hf_quic_scil = -1;
53 static int hf_quic_token_length = -1;
54 static int hf_quic_token = -1;
55 static int hf_quic_length = -1;
56 static int hf_quic_packet_number = -1;
57 static int hf_quic_packet_number_full = -1;
58 static int hf_quic_version = -1;
59 static int hf_quic_supported_version = -1;
60 static int hf_quic_vn_unused = -1;
61 static int hf_quic_short_kp_flag = -1;
62 static int hf_quic_short_reserved = -1;
63 static int hf_quic_payload = -1;
64 static int hf_quic_protected_payload = -1;
65 static int hf_quic_remaining_payload = -1;
66 static int hf_quic_odcil_draft13 = -1;
67 static int hf_quic_odcil = -1;
68 static int hf_quic_odcid = -1;
69 static int hf_quic_retry_token = -1;
71 static int hf_quic_frame = -1;
72 static int hf_quic_frame_type = -1;
73 static int hf_quic_frame_type_stream_fin = -1;
74 static int hf_quic_frame_type_stream_len = -1;
75 static int hf_quic_frame_type_stream_off = -1;
76 static int hf_quic_stream_stream_id = -1;
77 static int hf_quic_stream_offset = -1;
78 static int hf_quic_stream_length = -1;
79 static int hf_quic_stream_data = -1;
81 static int hf_quic_frame_type_ack_largest_acknowledged = -1;
82 static int hf_quic_frame_type_ack_ack_delay = -1;
83 static int hf_quic_frame_type_ack_ack_block_count = -1;
84 static int hf_quic_frame_type_ack_fab = -1;
85 static int hf_quic_frame_type_ack_gap = -1;
86 static int hf_quic_frame_type_ack_ack_block = -1;
88 static int hf_quic_frame_type_path_challenge_data = -1;
89 static int hf_quic_frame_type_path_response_data = -1;
91 static int hf_quic_frame_type_padding_length = -1;
92 static int hf_quic_frame_type_rsts_stream_id = -1;
93 static int hf_quic_frame_type_rsts_application_error_code = -1;
94 static int hf_quic_frame_type_rsts_final_offset = -1;
95 static int hf_quic_frame_type_cc_error_code = -1;
96 static int hf_quic_frame_type_cc_frame_type = -1;
97 static int hf_quic_frame_type_cc_reason_phrase_length = -1;
98 static int hf_quic_frame_type_cc_reason_phrase = -1;
99 static int hf_quic_frame_type_ac_error_code = -1;
100 static int hf_quic_frame_type_ac_reason_phrase_length = -1;
101 static int hf_quic_frame_type_ac_reason_phrase = -1;
102 static int hf_quic_frame_type_md_maximum_data = -1;
103 static int hf_quic_frame_type_msd_stream_id = -1;
104 static int hf_quic_frame_type_msd_maximum_stream_data = -1;
105 static int hf_quic_frame_type_msi_stream_id = -1;
106 static int hf_quic_frame_type_blocked_offset = -1;
107 static int hf_quic_frame_type_sb_stream_id = -1;
108 static int hf_quic_frame_type_sb_offset = -1;
109 static int hf_quic_frame_type_sib_stream_id = -1;
110 static int hf_quic_frame_type_nci_sequence = -1;
111 static int hf_quic_frame_type_nci_connection_id_length = -1;
112 static int hf_quic_frame_type_nci_connection_id = -1;
113 static int hf_quic_frame_type_nci_stateless_reset_token = -1;
114 static int hf_quic_frame_type_ss_stream_id = -1;
115 static int hf_quic_frame_type_ss_application_error_code = -1;
116 static int hf_quic_frame_type_crypto_offset = -1;
117 static int hf_quic_frame_type_crypto_length = -1;
118 static int hf_quic_frame_type_crypto_crypto_data = -1;
119 static int hf_quic_frame_type_nt_length = -1;
120 static int hf_quic_frame_type_nt_token = -1;
121 static int hf_quic_frame_type_ae_largest_acknowledged = -1;
122 static int hf_quic_frame_type_ae_ack_delay = -1;
123 static int hf_quic_frame_type_ae_ect0_count = -1;
124 static int hf_quic_frame_type_ae_ect1_count = -1;
125 static int hf_quic_frame_type_ae_ecn_ce_count = -1;
126 static int hf_quic_frame_type_ae_ack_block_count = -1;
127 static int hf_quic_frame_type_ae_fab = -1;
128 static int hf_quic_frame_type_ae_gap = -1;
129 static int hf_quic_frame_type_ae_ack_block = -1;
131 static expert_field ei_quic_connection_unknown = EI_INIT;
132 static expert_field ei_quic_ft_unknown = EI_INIT;
133 static expert_field ei_quic_decryption_failed = EI_INIT;
134 static expert_field ei_quic_protocol_violation = EI_INIT;
136 static gint ett_quic = -1;
137 static gint ett_quic_connection_info = -1;
138 static gint ett_quic_ft = -1;
139 static gint ett_quic_ftflags = -1;
141 static dissector_handle_t quic_handle;
142 static dissector_handle_t tls13_handshake_handle;
145 * PROTECTED PAYLOAD DECRYPTION (done in first pass)
147 * Long packet types always use a single cipher depending on packet type.
148 * Short packet types always use 1-RTT secrets for packet protection (pp).
149 * TODO 0-RTT decryption requires another (client) cipher.
152 * - QUIC packets might appear out-of-order (short packets before handshake
153 * message is captured), lost or retransmitted/duplicated.
154 * - During live capture, keys might not be immediately be available. 1-RTT
155 * client keys will be ready while client proceses Server Hello (Handshake).
156 * 1-RTT server keys will be ready while server creates Handshake message in
157 * response to Initial Handshake.
158 * - So delay cipher creation until first short packet is received.
160 * Required input from TLS dissector: TLS-Exporter 0-RTT/1-RTT secrets and
161 * cipher/hash algorithms.
164 * DONE key update via KEY_PHASE bit (untested)
165 * TODO 0-RTT decryption
168 typedef struct quic_decrypt_result {
169 const guchar *error; /**< Error message or NULL for success. */
170 const guint8 *data; /**< Decrypted result on success (file-scoped). */
171 guint data_len; /**< Size of decrypted data. */
172 } quic_decrypt_result_t;
174 typedef struct quic_cid {
179 /** QUIC decryption context. */
180 typedef struct quic_cipher {
181 gcry_cipher_hd_t pn_cipher; /* Packet number protection cipher. */
182 gcry_cipher_hd_t pp_cipher; /* Packet protection cipher. */
183 guint8 pp_iv[TLS13_AEAD_NONCE_LENGTH];
187 * Packet protection state for an endpoint.
189 typedef struct quic_pp_state {
190 guint8 *next_secret; /**< Next application traffic secret. */
191 quic_cipher cipher[2]; /**< Cipher for KEY_PHASE 0/1 */
192 guint64 changed_in_pkn; /**< Packet number where key change occurred. */
193 gboolean key_phase : 1; /**< Current key phase. */
196 /** Singly-linked list of Connection IDs. */
197 typedef struct quic_cid_item quic_cid_item_t;
198 struct quic_cid_item {
199 struct quic_cid_item *next;
204 * State for a single QUIC connection, identified by one or more Destination
205 * Connection IDs (DCID).
207 typedef struct quic_info_data {
208 guint32 number; /** Similar to "udp.stream", but for identifying QUIC connections across migrations. */
210 address server_address;
212 gboolean skip_decryption : 1; /**< Set to 1 if no keys are available. */
213 int hash_algo; /**< Libgcrypt hash algorithm for key derivation. */
214 int cipher_algo; /**< Cipher algorithm for packet number and packet encryption. */
215 int cipher_mode; /**< Cipher mode for packet encryption. */
216 quic_cipher client_initial_cipher;
217 quic_cipher server_initial_cipher;
218 quic_cipher client_handshake_cipher;
219 quic_cipher server_handshake_cipher;
220 quic_pp_state_t client_pp;
221 quic_pp_state_t server_pp;
222 guint64 max_client_pkn;
223 guint64 max_server_pkn;
224 quic_cid_item_t client_cids; /**< SCID of client from first Initial Packet. */
225 quic_cid_item_t server_cids; /**< SCID of server from first Retry/Handshake. */
226 quic_cid_t client_dcid_initial; /**< DCID from Initial Packet. */
229 /** Per-packet information about QUIC, populated on the first pass. */
230 struct quic_packet_info {
231 struct quic_packet_info *next;
232 guint64 packet_number; /**< Reconstructed full packet number. */
233 quic_decrypt_result_t decryption;
234 guint8 pkn_len; /**< Length of PKN (1/2/4) or unknown (0). */
236 typedef struct quic_packet_info quic_packet_info_t;
238 /** A UDP datagram contains one or more QUIC packets. */
239 typedef struct quic_datagram {
240 quic_info_data_t *conn;
241 quic_packet_info_t first_packet;
242 gboolean from_server : 1;
246 * Maps CID (quic_cid_t *) to a QUIC Connection (quic_info_data_t *).
247 * This assumes that the CIDs are not shared between two different connections
248 * (potentially with different versions) as that would break dissection.
250 * These mappings are authorative. For example, Initial.SCID is stored in
251 * quic_client_connections while Retry.SCID is stored in
252 * quic_server_connections. Retry.DCID should normally correspond to an entry in
253 * quic_client_connections.
255 static wmem_map_t *quic_client_connections, *quic_server_connections;
256 static wmem_map_t *quic_initial_connections; /* Initial.DCID -> connection */
257 static wmem_list_t *quic_connections; /* All unique connections. */
258 static guint32 quic_cid_lengths; /* Bitmap of CID lengths. */
259 static guint quic_connections_count;
261 /* Returns the QUIC draft version or 0 if not applicable. */
262 static inline guint8 quic_draft_version(guint32 version) {
263 if ((version >> 8) == 0xff0000) {
264 return (guint8) version;
268 static inline gboolean is_quic_draft_max(guint32 version, guint8 max_version) {
269 guint8 draft_version = quic_draft_version(version);
270 return draft_version && draft_version <= max_version;
273 const value_string quic_version_vals[] = {
274 { 0x00000000, "Version Negotiation" },
275 { 0xff000004, "draft-04" },
276 { 0xff000005, "draft-05" },
277 { 0xff000006, "draft-06" },
278 { 0xff000007, "draft-07" },
279 { 0xff000008, "draft-08" },
280 { 0xff000009, "draft-09" },
281 { 0xff00000a, "draft-10" },
282 { 0xff00000b, "draft-11" },
283 { 0xff00000c, "draft-12" },
284 { 0xff00000d, "draft-13" },
285 { 0xff00000e, "draft-14" },
289 static const value_string quic_short_long_header_vals[] = {
290 { 0, "Short Header" },
291 { 1, "Long Header" },
295 #define SH_KP 0x40 /* since draft -11 */
297 static const value_string quic_cid_len_vals[] = {
317 #define QUIC_LPT_INITIAL 0x7F
318 #define QUIC_LPT_RETRY 0x7E
319 #define QUIC_LPT_HANDSHAKE 0x7D
320 #define QUIC_LPT_0RTT 0x7C
321 #define QUIC_SHORT_PACKET 0xff /* dummy value that is definitely not LPT */
323 static const value_string quic_long_packet_type_vals[] = {
324 { QUIC_LPT_INITIAL, "Initial" },
325 { QUIC_LPT_RETRY, "Retry" },
326 { QUIC_LPT_HANDSHAKE, "Handshake" },
327 { QUIC_LPT_0RTT, "0-RTT Protected" },
331 #define FT_PADDING 0x00
332 #define FT_RST_STREAM 0x01
333 #define FT_CONNECTION_CLOSE 0x02
334 #define FT_APPLICATION_CLOSE 0x03 /* Add in draft07 */
335 #define FT_MAX_DATA 0x04
336 #define FT_MAX_STREAM_DATA 0x05
337 #define FT_MAX_STREAM_ID 0x06
339 #define FT_BLOCKED 0x08
340 #define FT_STREAM_BLOCKED 0x09
341 #define FT_STREAM_ID_BLOCKED 0x0a
342 #define FT_NEW_CONNECTION_ID 0x0b
343 #define FT_STOP_SENDING 0x0c
345 #define FT_PATH_CHALLENGE 0x0e
346 #define FT_PATH_RESPONSE 0x0f
347 #define FT_STREAM_10 0x10
348 #define FT_STREAM_11 0x11
349 #define FT_STREAM_12 0x12
350 #define FT_STREAM_13 0x13
351 #define FT_STREAM_14 0x14
352 #define FT_STREAM_15 0x15
353 #define FT_STREAM_16 0x16
354 #define FT_STREAM_17 0x17
355 #define FT_CRYPTO 0x18
356 #define FT_NEW_TOKEN 0x19 /* Add in draft 13 */
357 #define FT_ACK_ECN 0x1a /* Add in draft 14 */
358 #define FT_ACK_ECN_OLD 0x20 /* Remove in draft 14 */
360 static const range_string quic_frame_type_vals[] = {
361 { 0x00, 0x00, "PADDING" },
362 { 0x01, 0x01, "RST_STREAM" },
363 { 0x02, 0x02, "CONNECTION_CLOSE" },
364 { 0x03, 0x03, "APPLICATION_CLOSE" },
365 { 0x04, 0x04, "MAX_DATA" },
366 { 0x05, 0x05, "MAX_STREAM_DATA" },
367 { 0x06, 0x06, "MAX_STREAM_ID" },
368 { 0x07, 0x07, "PING" },
369 { 0x08, 0x08, "BLOCKED" },
370 { 0x09, 0x09, "STREAM_BLOCKED" },
371 { 0x0a, 0x0a, "STREAM_ID_BLOCKED" },
372 { 0x0b, 0x0b, "NEW_CONNECTION_ID" },
373 { 0x0c, 0x0c, "STOP_SENDING" },
374 { 0x0d, 0x0d, "ACK" },
375 { 0x0e, 0x0e, "PATH_CHALLENGE" },
376 { 0x0f, 0x0f, "PATH_RESPONSE" },
377 { 0x10, 0x17, "STREAM" },
378 { 0x18, 0x18, "CRYPTO" },
379 { 0x19, 0x19, "NEW_TOKEN" },
380 { 0x1a, 0x1a, "ACK_ECN" },
381 { 0x20, 0x20, "ACK_ECN" },
387 #define FTFLAGS_STREAM_FIN 0x01
388 #define FTFLAGS_STREAM_LEN 0x02
389 #define FTFLAGS_STREAM_OFF 0x04
391 static const range_string quic_transport_error_code_vals[] = {
392 { 0x0000, 0x0000, "NO_ERROR" },
393 { 0x0001, 0x0001, "INTERNAL_ERROR" },
394 { 0x0002, 0x0002, "SERVER_BUSY" },
395 { 0x0003, 0x0003, "FLOW_CONTROL_ERROR" },
396 { 0x0004, 0x0004, "STREAM_ID_ERROR" },
397 { 0x0005, 0x0005, "STREAM_STATE_ERROR" },
398 { 0x0006, 0x0006, "FINAL_OFFSET_ERROR" },
399 { 0x0007, 0x0007, "FRAME_ENCODING_ERROR" },
400 { 0x0008, 0x0008, "TRANSPORT_PARAMETER_ERROR" },
401 { 0x0009, 0x0009, "VERSION_NEGOTIATION_ERROR" },
402 { 0x000A, 0x000A, "PROTOCOL_VIOLATION" },
403 { 0x000C, 0x000C, "INVALID_MIGRATION" },
407 static const value_string quic_application_error_code_vals[] = {
408 { 0x0000, "STOPPING" },
413 quic_cipher_reset(quic_cipher *cipher)
415 gcry_cipher_close(cipher->pn_cipher);
416 gcry_cipher_close(cipher->pp_cipher);
417 memset(cipher, 0, sizeof(*cipher));
420 /* Inspired from ngtcp2 */
421 static guint64 quic_pkt_adjust_pkt_num(guint64 max_pkt_num, guint64 pkt_num,
423 guint64 k = max_pkt_num == G_MAXUINT64 ? max_pkt_num : max_pkt_num + 1;
424 guint64 u = k & ~((G_GUINT64_CONSTANT(1) << n) - 1);
425 guint64 a = u | pkt_num;
426 guint64 b = (u + (G_GUINT64_CONSTANT(1) << n)) | pkt_num;
427 guint64 a1 = k < a ? a - k : k - a;
428 guint64 b1 = k < b ? b - k : k - b;
436 #ifdef HAVE_LIBGCRYPT_AEAD
438 quic_decrypt_packet_number(tvbuff_t *tvb, guint offset, quic_cipher *cipher,
439 int pn_cipher_algo, guint64 *pkn)
443 guint8 *pkn_bytes = (guint8 *)&pkt_pkn;
445 if (!cipher || !(h = cipher->pn_cipher)) {
446 // need to know the cipher.
450 tvb_memcpy(tvb, pkn_bytes, offset, sizeof(pkt_pkn));
452 // Both AES-CTR and ChaCha20 use 16 octets as sample length.
453 // https://tools.ietf.org/html/draft-ietf-quic-tls-13#section-5.3
454 const guint sample_length = 16;
455 guint sample_offset = offset + 4;
457 if (sample_offset + sample_length > tvb_reported_length(tvb)) {
458 sample_offset = tvb_reported_length(tvb) - sample_length;
460 tvb_memcpy(tvb, sample, sample_offset, sample_length);
462 switch (pn_cipher_algo) {
463 case GCRY_CIPHER_AES128:
464 case GCRY_CIPHER_AES256:
465 if (gcry_cipher_setctr(h, sample, sample_length)) {
469 #ifdef HAVE_LIBGCRYPT_CHACHA20
470 case GCRY_CIPHER_CHACHA20:
471 /* If Gcrypt receives a 16 byte IV, it will assume the buffer to be
472 * counter || nonce (in little endian), as desired. */
473 if (gcry_cipher_setiv(h, sample, 16)) {
477 #endif /* HAVE_LIBGCRYPT_CHACHA20 */
482 /* in-place decrypt. */
483 if (gcry_cipher_decrypt(h, pkn_bytes, 4, NULL, 0)) {
487 // | First octet pattern | Encoded Length | Bits Present |
488 // | 0b0xxxxxxx | 1 octet | 7 |
489 // | 0b10xxxxxx | 2 | 14 |
490 // | 0b11xxxxxx | 4 | 30 |
491 switch (pkn_bytes[0] >> 6) {
497 pkn_bytes[0] &= 0x3f;
501 pkn_bytes[0] &= 0x3f;
504 *pkn = g_htonl(pkt_pkn) >> (8 * (4 - pkn_len));
509 quic_encode_packet_number(guint8 *output, guint32 pkn, guint pkn_len)
513 output[0] = (guint8)pkn;
516 phton16(output, (guint16)pkn);
520 phton32(output, pkn);
525 #else /* !HAVE_LIBGCRYPT_AEAD */
527 quic_decrypt_packet_number(tvbuff_t *tvb _U_, guint offset _U_, quic_cipher *cipher _U_,
528 int pn_cipher_algo _U_, guint64 *pkn _U_)
532 #endif /* !HAVE_LIBGCRYPT_AEAD */
535 * Calculate the full packet number and store it for later use.
538 dissect_quic_packet_number(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
539 quic_info_data_t *quic_info, quic_packet_info_t *quic_packet,
540 gboolean from_server,
541 quic_cipher *cipher, int pn_cipher_algo, guint64 *pkn_out)
547 /* Try to decrypt on the first pass, reuse results on the second pass. */
548 if (!PINFO_FD_VISITED(pinfo)) {
549 pkn_len = quic_decrypt_packet_number(tvb, offset, cipher, pn_cipher_algo, &pkn);
550 quic_packet->pkn_len = pkn_len;
552 pkn_len = quic_packet->pkn_len;
553 pkn = quic_packet->packet_number & ((1UL << (8 * pkn_len)) - 1);
556 expert_add_info_format(pinfo, tree, &ei_quic_decryption_failed, "Failed to decrypt packet number");
560 // TODO separate field for encrypted and decrypted PKN?
561 proto_tree_add_uint64(tree, hf_quic_packet_number, tvb, offset, pkn_len, pkn);
564 // if not part of a connection, the full PKN cannot be reconstructed.
569 /* Sequential first pass, try to reconstruct full packet number. */
570 if (!PINFO_FD_VISITED(pinfo)) {
572 pkn = quic_pkt_adjust_pkt_num(quic_info->max_server_pkn, pkn, 8 * pkn_len);
573 quic_info->max_server_pkn = pkn;
575 pkn = quic_pkt_adjust_pkt_num(quic_info->max_client_pkn, pkn, 8 * pkn_len);
576 quic_info->max_client_pkn = pkn;
578 quic_packet->packet_number = pkn;
580 pkn = quic_packet->packet_number;
583 /* always add the full packet number for use in columns */
584 ti = proto_tree_add_uint64(tree, hf_quic_packet_number_full, tvb, offset, pkn_len, pkn);
585 PROTO_ITEM_SET_GENERATED(ti);
592 cid_to_string(const quic_cid_t *cid)
597 char *str = (char *)wmem_alloc0(wmem_packet_scope(), 2 * cid->len + 1);
598 bytes_to_hexstr(str, cid->cid, cid->len);
602 /* QUIC Connection tracking. {{{ */
604 quic_connection_hash(gconstpointer key)
606 const quic_cid_t *cid = (const quic_cid_t *)key;
608 return wmem_strong_hash((const guint8 *)cid, cid->len);
612 quic_connection_equal(gconstpointer a, gconstpointer b)
614 const quic_cid_t *cid1 = (const quic_cid_t *)a;
615 const quic_cid_t *cid2 = (const quic_cid_t *)b;
617 return cid1->len == cid2->len && !memcmp(cid1->cid, cid2->cid, cid1->len);
621 quic_cids_has_match(const quic_cid_item_t *items, const quic_cid_t *raw_cid)
624 const quic_cid_t *cid = &items->data;
625 // "raw_cid" potentially has some trailing data that is not part of the
626 // actual CID, so accept any prefix match against "cid".
627 // Note that this explicitly matches an empty CID.
628 if (raw_cid->len >= cid->len && !memcmp(raw_cid->cid, cid->cid, cid->len)) {
637 quic_cids_insert(quic_cid_t *cid, quic_info_data_t *conn, gboolean from_server)
639 wmem_map_t *connections = from_server ? quic_server_connections : quic_client_connections;
640 // Replace any previous CID key with the new one.
641 wmem_map_remove(connections, cid);
642 wmem_map_insert(connections, cid, conn);
643 quic_cid_lengths |= (1 << cid->len);
646 static inline gboolean
647 quic_cids_is_known_length(const quic_cid_t *cid)
649 return (quic_cid_lengths & (1 << cid->len)) != 0;
653 * Tries to lookup a matching connection (Connection ID is optional).
654 * If connection is found, "from_server" is set accordingly.
656 static quic_info_data_t *
657 quic_connection_find_dcid(packet_info *pinfo, const quic_cid_t *dcid, gboolean *from_server)
659 /* https://tools.ietf.org/html/draft-ietf-quic-transport-13#section-6.2
661 * "If the packet has a Destination Connection ID corresponding to an
662 * existing connection, QUIC processes that packet accordingly."
663 * "If the Destination Connection ID is zero length and the packet matches
664 * the address/port tuple of a connection where the host did not require
665 * connection IDs, QUIC processes the packet as part of that connection."
667 quic_info_data_t *conn = NULL;
668 gboolean check_ports = FALSE;
670 if (dcid && dcid->len > 0 && quic_cids_is_known_length(dcid)) {
671 conn = (quic_info_data_t *) wmem_map_lookup(quic_client_connections, dcid);
673 // DCID recognized by client, so it was from server.
675 // On collision (both client and server choose the same CID), check
676 // the port to learn about the side.
677 // This is required for supporting draft -10 which has a single CID.
678 check_ports = !!wmem_map_lookup(quic_server_connections, dcid);
680 conn = (quic_info_data_t *) wmem_map_lookup(quic_server_connections, dcid);
682 // DCID recognized by server, so it was from client.
683 *from_server = FALSE;
687 conversation_t *conv = find_conversation_pinfo(pinfo, 0);
689 conn = (quic_info_data_t *)conversation_get_proto_data(conv, proto_quic);
690 check_ports = !!conn;
695 *from_server = conn->server_port == pinfo->srcport &&
696 addresses_equal(&conn->server_address, &pinfo->src);
703 * Try to find a QUIC connection based on DCID. For short header packets, DCID
704 * will be modified in order to find the actual length.
705 * DCID can be empty, in that case a connection is looked up by address only.
707 static quic_info_data_t *
708 quic_connection_find(packet_info *pinfo, guint8 long_packet_type,
709 quic_cid_t *dcid, gboolean *from_server)
711 gboolean is_long_packet = long_packet_type != QUIC_SHORT_PACKET;
712 quic_info_data_t *conn = NULL;
714 if ((long_packet_type == QUIC_LPT_INITIAL || long_packet_type == QUIC_LPT_0RTT) && dcid->len > 0) {
715 conn = (quic_info_data_t *) wmem_map_lookup(quic_initial_connections, dcid);
716 // Both the client and server can send Initial (since draft -13).
717 if (!conn && long_packet_type == QUIC_LPT_INITIAL) {
718 conn = quic_connection_find_dcid(pinfo, dcid, from_server);
721 conn = quic_connection_find_dcid(pinfo, dcid, from_server);
724 if (!is_long_packet && !conn) {
725 // For short packets, first try to find a match based on the address.
726 conn = quic_connection_find_dcid(pinfo, NULL, from_server);
728 if ((*from_server && !quic_cids_has_match(&conn->server_cids, dcid)) ||
729 (!*from_server && !quic_cids_has_match(&conn->client_cids, dcid))) {
730 // Connection does not match packet.
735 // No match found so far, potentially connection migration. Length of
736 // actual DCID is unknown, so just keep decrementing until found.
737 while (!conn && dcid->len > 4) {
739 if (quic_cids_is_known_length(dcid)) {
740 conn = quic_connection_find_dcid(pinfo, dcid, from_server);
744 // No match found, truncate DCID (not really needed, but this
745 // ensures that debug prints clearly show that DCID is invalid).
752 /** Create a new QUIC Connection based on a Client Initial packet. */
753 static quic_info_data_t *
754 quic_connection_create(packet_info *pinfo, guint32 version, const quic_cid_t *scid, const quic_cid_t *dcid)
756 quic_info_data_t *conn = NULL;
758 conn = wmem_new0(wmem_file_scope(), quic_info_data_t);
759 wmem_list_append(quic_connections, conn);
760 conn->number = quic_connections_count++;
761 conn->version = version;
762 copy_address_wmem(wmem_file_scope(), &conn->server_address, &pinfo->dst);
763 conn->server_port = pinfo->destport;
765 // Key connection by Client CID (if provided).
767 memcpy(&conn->client_cids.data, scid, sizeof(quic_cid_t));
768 quic_cids_insert(&conn->client_cids.data, conn, FALSE);
771 // According to the spec, the Initial Packet DCID MUST be at least 8
772 // bytes, but non-conforming implementations could exist.
773 memcpy(&conn->client_dcid_initial, dcid, sizeof(quic_cid_t));
774 wmem_map_insert(quic_initial_connections, &conn->client_dcid_initial, conn);
777 // For faster lookups without having to check DCID
778 conversation_t *conv = find_or_create_conversation(pinfo);
779 conversation_add_proto_data(conv, proto_quic, conn);
784 #ifdef HAVE_LIBGCRYPT_AEAD
786 * Use the new CID as additional identifier for the specified connection and
787 * remember it for connection tracking.
790 quic_connection_add_cid(quic_info_data_t *conn, const quic_cid_t *new_cid, gboolean from_server)
792 DISSECTOR_ASSERT(new_cid->len > 0);
793 quic_cid_item_t *items = from_server ? &conn->server_cids : &conn->client_cids;
795 if (quic_cids_has_match(items, new_cid)) {
796 // CID is already known for this connection.
800 // Insert new CID right after the first known CID (the very first CID cannot
801 // be overwritten since it might be used as key somewhere else).
802 quic_cid_item_t *new_item = wmem_new0(wmem_file_scope(), quic_cid_item_t);
803 new_item->data = *new_cid;
804 new_item->next = items->next;
805 items->next = new_item;
807 quic_cids_insert(&new_item->data, conn, from_server);
811 /** Create or update a connection. */
813 quic_connection_create_or_update(quic_info_data_t **conn_p,
814 packet_info *pinfo, guint32 long_packet_type,
815 guint32 version, const quic_cid_t *scid,
816 const quic_cid_t *dcid, gboolean from_server)
818 quic_info_data_t *conn = *conn_p;
820 switch (long_packet_type) {
821 case QUIC_LPT_INITIAL:
824 // The first Initial Packet from the client creates a new connection.
825 *conn_p = quic_connection_create(pinfo, version, scid, dcid);
826 } else if (conn->client_dcid_initial.len == 0 && dcid->len &&
827 scid->len && !quic_cids_has_match(&conn->server_cids, scid)) {
828 // If this client Initial Packet responds to a Retry Packet,
829 // then remember the new DCID for the new Initial cipher and
830 // clear the first server CID such that the next server Initial
831 // Packet can link the connection with that new SCID.
832 memcpy(&conn->client_dcid_initial, dcid, sizeof(quic_cid_t));
833 wmem_map_insert(quic_initial_connections, &conn->client_dcid_initial, conn);
834 wmem_map_remove(quic_server_connections, &conn->server_cids.data);
835 memset(&conn->server_cids, 0, sizeof(quic_cid_t));
841 case QUIC_LPT_HANDSHAKE:
842 // Remember CID from first server Retry/Handshake packet
843 // (or from the first server Initial packet, since draft -13).
844 if (from_server && conn) {
845 if (long_packet_type == QUIC_LPT_RETRY) {
846 // Stateless Retry Packet: the next Initial Packet from the
847 // client should start a new cryptographic handshake. Erase the
848 // current "Initial DCID" such that the next client Initial
849 // packet populates the new value.
850 wmem_map_remove(quic_initial_connections, &conn->client_dcid_initial);
851 memset(&conn->client_dcid_initial, 0, sizeof(quic_cid_t));
853 if (conn->server_cids.data.len == 0 && scid->len) {
854 memcpy(&conn->server_cids.data, scid, sizeof(quic_cid_t));
855 quic_cids_insert(&conn->server_cids.data, conn, TRUE);
863 quic_connection_destroy(gpointer data, gpointer user_data _U_)
865 quic_info_data_t *conn = (quic_info_data_t *)data;
866 quic_cipher_reset(&conn->client_initial_cipher);
867 quic_cipher_reset(&conn->server_initial_cipher);
868 quic_cipher_reset(&conn->client_handshake_cipher);
869 quic_cipher_reset(&conn->server_handshake_cipher);
871 for (int i = 0; i < 2; i++) {
872 quic_cipher_reset(&conn->client_pp.cipher[i]);
873 quic_cipher_reset(&conn->server_pp.cipher[i]);
876 /* QUIC Connection tracking. }}} */
879 #ifdef HAVE_LIBGCRYPT_AEAD
881 dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_info_data_t *quic_info, gboolean from_server)
883 proto_item *ti_ft, *ti_ftflags, *ti;
884 proto_tree *ft_tree, *ftflags_tree;
886 guint orig_offset = offset;
888 ti_ft = proto_tree_add_item(quic_tree, hf_quic_frame, tvb, offset, 1, ENC_NA);
889 ft_tree = proto_item_add_subtree(ti_ft, ett_quic_ft);
891 ti_ftflags = proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type, tvb, offset, 1, ENC_NA, &frame_type);
892 proto_item_set_text(ti_ft, "%s", rval_to_str(frame_type, quic_frame_type_vals, "Unknown"));
899 col_append_fstr(pinfo->cinfo, COL_INFO, ", PADDING");
901 /* A padding frame consists of a single zero octet, but for brevity
902 * sake let's combine multiple zeroes into a single field. */
903 pad_len = 1 + tvb_skip_guint8(tvb, offset, tvb_reported_length_remaining(tvb, offset), '\0') - offset;
904 ti = proto_tree_add_uint(ft_tree, hf_quic_frame_type_padding_length, tvb, offset, 0, pad_len);
905 PROTO_ITEM_SET_GENERATED(ti);
906 proto_item_append_text(ti_ft, " Length: %u", pad_len);
907 offset += pad_len - 1;
912 guint32 error_code, len_streamid = 0, len_finaloffset = 0;
914 col_append_fstr(pinfo->cinfo, COL_INFO, ", RS");
916 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_rsts_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, &stream_id, &len_streamid);
917 offset += len_streamid;
919 proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_rsts_application_error_code, tvb, offset, 2, ENC_BIG_ENDIAN, &error_code);
922 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_rsts_final_offset, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_finaloffset);
923 offset += len_finaloffset;
925 proto_item_append_text(ti_ft, " Stream ID: %" G_GINT64_MODIFIER "u, Error code: %s", stream_id, val_to_str(error_code, quic_application_error_code_vals, "0x%04x"));
928 case FT_CONNECTION_CLOSE:{
929 guint32 len_reasonphrase, len_frametype, error_code;
930 guint64 len_reason = 0;
932 col_append_fstr(pinfo->cinfo, COL_INFO, ", CC");
934 proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_cc_error_code, tvb, offset, 2, ENC_BIG_ENDIAN, &error_code);
937 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_cc_frame_type, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_frametype);
938 offset += len_frametype;
940 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_cc_reason_phrase_length, tvb, offset, -1, ENC_VARINT_QUIC, &len_reason, &len_reasonphrase);
941 offset += len_reasonphrase;
943 proto_tree_add_item(ft_tree, hf_quic_frame_type_cc_reason_phrase, tvb, offset, (guint32)len_reason, ENC_ASCII|ENC_NA);
944 offset += (guint32)len_reason;
946 proto_item_append_text(ti_ft, " Error code: %s", rval_to_str(error_code, quic_transport_error_code_vals, "Unknown (%d)"));
949 case FT_APPLICATION_CLOSE:{
950 guint32 len_reasonphrase, error_code;
953 col_append_fstr(pinfo->cinfo, COL_INFO, ", AC");
955 proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_ac_error_code, tvb, offset, 2, ENC_BIG_ENDIAN, &error_code);
958 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ac_reason_phrase_length, tvb, offset, -1, ENC_VARINT_QUIC, &len_reason, &len_reasonphrase);
959 offset += len_reasonphrase;
960 proto_tree_add_item(ft_tree, hf_quic_frame_type_ac_reason_phrase, tvb, offset, (guint32)len_reason, ENC_ASCII|ENC_NA);
961 offset += (guint32)len_reason;
963 proto_item_append_text(ti_ft, " Error code: %s", val_to_str(error_code, quic_application_error_code_vals, "0x%04x"));
967 guint32 len_maximumdata;
969 col_append_fstr(pinfo->cinfo, COL_INFO, ", MD");
971 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_md_maximum_data, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_maximumdata);
972 offset += len_maximumdata;
975 case FT_MAX_STREAM_DATA:{
976 guint32 len_streamid, len_maximumstreamdata;
978 col_append_fstr(pinfo->cinfo, COL_INFO, ", MSD");
980 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_msd_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_streamid);
981 offset += len_streamid;
983 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_msd_maximum_stream_data, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_maximumstreamdata);
984 offset += len_maximumstreamdata;
987 case FT_MAX_STREAM_ID:{
988 guint32 len_streamid;
990 col_append_fstr(pinfo->cinfo, COL_INFO, ", MSI");
992 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_msi_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_streamid);
993 offset += len_streamid;
997 col_append_fstr(pinfo->cinfo, COL_INFO, ", PING");
1003 col_append_fstr(pinfo->cinfo, COL_INFO, ", B");
1005 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_blocked_offset, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_offset);
1006 offset += len_offset;
1009 case FT_STREAM_BLOCKED:{
1010 guint32 len_streamid, len_offset;
1012 col_append_fstr(pinfo->cinfo, COL_INFO, ", SB");
1014 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_sb_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_streamid);
1015 offset += len_streamid;
1017 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_sb_offset, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_offset);
1018 offset += len_offset;
1021 case FT_STREAM_ID_BLOCKED:{
1022 guint32 len_streamid;
1024 col_append_fstr(pinfo->cinfo, COL_INFO, ", SIB");
1026 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_sib_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_streamid);
1027 offset += len_streamid;
1030 case FT_NEW_CONNECTION_ID:{
1031 guint32 len_sequence;
1033 gboolean valid_cid = FALSE;
1035 col_append_fstr(pinfo->cinfo, COL_INFO, ", NCI");
1037 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_nci_sequence, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_sequence);
1038 offset += len_sequence;
1040 ti = proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_nci_connection_id_length, tvb, offset, 1, ENC_BIG_ENDIAN, &nci_length);
1043 valid_cid = nci_length >= 4 && nci_length <= 18;
1045 expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
1046 "Connection ID Length must be between 4 and 18 bytes");
1049 proto_tree_add_item(ft_tree, hf_quic_frame_type_nci_connection_id, tvb, offset, nci_length, ENC_NA);
1050 if (valid_cid && quic_info) {
1051 quic_cid_t cid = {.len=0};
1052 tvb_memcpy(tvb, cid.cid, offset, nci_length);
1053 cid.len = nci_length;
1054 quic_connection_add_cid(quic_info, &cid, from_server);
1056 offset += nci_length;
1058 proto_tree_add_item(ft_tree, hf_quic_frame_type_nci_stateless_reset_token, tvb, offset, 16, ENC_NA);
1062 case FT_STOP_SENDING:{
1063 guint32 len_streamid, error_code;
1065 col_append_fstr(pinfo->cinfo, COL_INFO, ", SS");
1067 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ss_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_streamid);
1068 offset += len_streamid;
1070 proto_tree_add_item_ret_uint(ft_tree, hf_quic_frame_type_ss_application_error_code, tvb, offset, 2, ENC_BIG_ENDIAN, &error_code);
1073 proto_item_append_text(ti_ft, " Error code: 0x%04x", error_code);
1077 guint64 ack_block_count;
1080 col_append_fstr(pinfo->cinfo, COL_INFO, ", ACK");
1082 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ack_largest_acknowledged, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1085 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ack_ack_delay, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1088 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ack_ack_block_count, tvb, offset, -1, ENC_VARINT_QUIC, &ack_block_count, &lenvar);
1092 /* First ACK Block Length */
1093 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ack_fab, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1096 /* Repeated "Ack Block Count" */
1097 while(ack_block_count){
1099 /* Gap To Next Block */
1100 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ack_gap, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1103 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ack_ack_block, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1110 case FT_PATH_CHALLENGE:{
1111 col_append_fstr(pinfo->cinfo, COL_INFO, ", PC");
1113 proto_tree_add_item(ft_tree, hf_quic_frame_type_path_challenge_data, tvb, offset, 8, ENC_NA);
1117 case FT_PATH_RESPONSE:{
1118 col_append_fstr(pinfo->cinfo, COL_INFO, ", PR");
1120 proto_tree_add_item(ft_tree, hf_quic_frame_type_path_response_data, tvb, offset, 8, ENC_NA);
1131 case FT_STREAM_17: {
1132 guint64 stream_id, length;
1137 col_append_fstr(pinfo->cinfo, COL_INFO, ", STREAM");
1139 ftflags_tree = proto_item_add_subtree(ti_ftflags, ett_quic_ftflags);
1140 proto_tree_add_item(ftflags_tree, hf_quic_frame_type_stream_fin, tvb, offset, 1, ENC_NA);
1141 proto_tree_add_item(ftflags_tree, hf_quic_frame_type_stream_len, tvb, offset, 1, ENC_NA);
1142 proto_tree_add_item(ftflags_tree, hf_quic_frame_type_stream_off, tvb, offset, 1, ENC_NA);
1145 proto_tree_add_item_ret_varint(ft_tree, hf_quic_stream_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, &stream_id, &lenvar);
1148 proto_item_append_text(ti_ft, " Stream ID: %" G_GINT64_MODIFIER "u", stream_id);
1149 col_append_fstr(pinfo->cinfo, COL_INFO, "(%" G_GINT64_MODIFIER "u)", stream_id);
1151 if (frame_type & FTFLAGS_STREAM_OFF) {
1152 proto_tree_add_item_ret_varint(ft_tree, hf_quic_stream_offset, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1156 if (frame_type & FTFLAGS_STREAM_LEN) {
1157 proto_tree_add_item_ret_varint(ft_tree, hf_quic_stream_length, tvb, offset, -1, ENC_VARINT_QUIC, &length, &lenvar);
1160 length = tvb_reported_length_remaining(tvb, offset);
1163 proto_tree_add_item(ft_tree, hf_quic_stream_data, tvb, offset, (int)length, ENC_NA);
1164 offset += (int)length;
1168 guint64 crypto_offset, crypto_length;
1170 col_append_fstr(pinfo->cinfo, COL_INFO, ", CRYPTO");
1171 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_crypto_offset, tvb, offset, -1, ENC_VARINT_QUIC, &crypto_offset, &lenvar);
1173 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_crypto_length, tvb, offset, -1, ENC_VARINT_QUIC, &crypto_length, &lenvar);
1175 proto_tree_add_item(ft_tree, hf_quic_frame_type_crypto_crypto_data, tvb, offset, (guint32)crypto_length, ENC_NA);
1177 tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset, (int)crypto_length);
1178 col_set_writable(pinfo->cinfo, -1, FALSE);
1180 * Dissect TLS handshake record. The Client/Server Hello (CH/SH)
1181 * are contained in the Initial Packet. 0-RTT keys are ready
1182 * after CH. HS + 1-RTT keys are ready after SH.
1183 * (Note: keys captured from the client might become available
1184 * after capturing the packets due to processing delay.)
1185 * These keys will be loaded in the first HS/0-RTT/1-RTT msg.
1187 call_dissector(tls13_handshake_handle, next_tvb, pinfo, ft_tree);
1188 col_set_writable(pinfo->cinfo, -1, TRUE);
1190 offset += (guint32)crypto_length;
1193 case FT_NEW_TOKEN: {
1194 guint64 token_length;
1197 col_append_fstr(pinfo->cinfo, COL_INFO, ", NT");
1199 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_nt_length, tvb, offset, -1, ENC_VARINT_QUIC, &token_length, &lenvar);
1202 proto_tree_add_item(ft_tree, hf_quic_frame_type_nt_token, tvb, offset, (guint32)token_length, ENC_NA);
1203 offset += (guint32)token_length;
1207 guint64 ack_block_count;
1210 col_append_fstr(pinfo->cinfo, COL_INFO, ", AE");
1212 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_largest_acknowledged, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1215 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_ack_delay, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1218 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_ect0_count, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1221 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_ect1_count, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1224 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_ecn_ce_count, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1227 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_ack_block_count, tvb, offset, -1, ENC_VARINT_QUIC, &ack_block_count, &lenvar);
1231 /* First ACK Block Length */
1232 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_fab, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1235 /* Repeated "Ack Block Count" */
1236 while(ack_block_count){
1238 /* Gap To Next Block */
1239 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_gap, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1242 proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type_ae_ack_block, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1250 expert_add_info_format(pinfo, ti_ft, &ei_quic_ft_unknown, "Unknown Frame Type %u", frame_type);
1254 proto_item_set_len(ti_ft, offset - orig_offset);
1258 #endif /* HAVE_LIBGCRYPT_AEAD */
1260 #ifdef HAVE_LIBGCRYPT_AEAD
1262 qhkdf_expand(int md, const guint8 *secret, guint secret_len,
1263 const char *label, guint8 *out, guint out_len);
1266 quic_cipher_init(guint32 version, quic_cipher *cipher, int hash_algo, guint8 key_length, guint8 *secret);
1270 * Given a QUIC message (header + non-empty payload), the actual packet number,
1271 * try to decrypt it using the cipher.
1272 * As the header points to the original buffer with an encrypted packet number,
1273 * the (encrypted) packet number length is also included.
1275 * The actual packet number must be constructed according to
1276 * https://tools.ietf.org/html/draft-ietf-quic-transport-13#section-4.8
1279 quic_decrypt_message(quic_cipher *cipher, tvbuff_t *head, guint header_length, guint pkn_len, guint64 packet_number, quic_decrypt_result_t *result)
1283 guint8 nonce[TLS13_AEAD_NONCE_LENGTH];
1286 guint buffer_length;
1287 const guchar **error = &result->error;
1289 DISSECTOR_ASSERT(cipher != NULL);
1290 DISSECTOR_ASSERT(cipher->pp_cipher != NULL);
1291 DISSECTOR_ASSERT(pkn_len < header_length);
1292 DISSECTOR_ASSERT(1 <= pkn_len && pkn_len <= 4);
1293 // copy header, but replace encrypted PKN by plaintext PKN.
1294 header = (guint8 *)tvb_memdup(wmem_packet_scope(), head, 0, header_length);
1295 quic_encode_packet_number(header + header_length - pkn_len, (guint32)packet_number, pkn_len);
1297 /* Input is "header || ciphertext (buffer) || auth tag (16 bytes)" */
1298 buffer_length = tvb_captured_length_remaining(head, header_length + 16);
1299 if (buffer_length == 0) {
1300 *error = "Decryption not possible, ciphertext is too short";
1303 buffer = (guint8 *)tvb_memdup(wmem_file_scope(), head, header_length, buffer_length);
1304 tvb_memcpy(head, atag, header_length + buffer_length, 16);
1306 memcpy(nonce, cipher->pp_iv, TLS13_AEAD_NONCE_LENGTH);
1307 /* Packet number is left-padded with zeroes and XORed with write_iv */
1308 phton64(nonce + sizeof(nonce) - 8, pntoh64(nonce + sizeof(nonce) - 8) ^ packet_number);
1310 gcry_cipher_reset(cipher->pp_cipher);
1311 err = gcry_cipher_setiv(cipher->pp_cipher, nonce, TLS13_AEAD_NONCE_LENGTH);
1313 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (setiv) failed: %s", gcry_strerror(err));
1317 /* associated data (A) is the contents of QUIC header */
1318 err = gcry_cipher_authenticate(cipher->pp_cipher, header, header_length);
1320 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (authenticate) failed: %s", gcry_strerror(err));
1324 /* Output ciphertext (C) */
1325 err = gcry_cipher_decrypt(cipher->pp_cipher, buffer, buffer_length, NULL, 0);
1327 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (decrypt) failed: %s", gcry_strerror(err));
1331 err = gcry_cipher_checktag(cipher->pp_cipher, atag, 16);
1333 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (checktag) failed: %s", gcry_strerror(err));
1337 result->error = NULL;
1338 result->data = buffer;
1339 result->data_len = buffer_length;
1343 quic_hkdf_expand_label(int hash_algo, guint8 *secret, guint secret_len, const char *label, guint8 *out, guint out_len)
1345 const StringInfo secret_si = { secret, secret_len };
1346 guchar *out_mem = NULL;
1347 if (tls13_hkdf_expand_label(hash_algo, &secret_si, "quic ", label, out_len, &out_mem)) {
1348 memcpy(out, out_mem, out_len);
1349 wmem_free(NULL, out_mem);
1356 * Compute the client and server initial secrets given Connection ID "cid".
1358 * On success TRUE is returned and the two initial secrets are set.
1359 * FALSE is returned on error (see "error" parameter for the reason).
1362 quic_derive_initial_secrets(const quic_cid_t *cid,
1363 guint8 client_initial_secret[HASH_SHA2_256_LENGTH],
1364 guint8 server_initial_secret[HASH_SHA2_256_LENGTH],
1365 const gchar **error)
1368 * https://tools.ietf.org/html/draft-ietf-quic-tls-14#section-5.1.1
1370 * initial_salt = 0x9c108f98520a5c5c32968e950e8a2c5fe06d6c38
1371 * initial_secret = HKDF-Extract(initial_salt, client_dst_connection_id)
1373 * client_initial_secret = HKDF-Expand-Label(initial_secret,
1374 * "client in", "", Hash.length)
1375 * server_initial_secret = HKDF-Expand-Label(initial_secret,
1376 * "server in", "", Hash.length)
1378 * Hash for handshake packets is SHA-256 (output size 32).
1380 static const guint8 handshake_salt[20] = {
1381 0x9c, 0x10, 0x8f, 0x98, 0x52, 0x0a, 0x5c, 0x5c, 0x32, 0x96,
1382 0x8e, 0x95, 0x0e, 0x8a, 0x2c, 0x5f, 0xe0, 0x6d, 0x6c, 0x38
1385 guint8 secret[HASH_SHA2_256_LENGTH];
1387 err = hkdf_extract(GCRY_MD_SHA256, handshake_salt, sizeof(handshake_salt),
1388 cid->cid, cid->len, secret);
1390 *error = wmem_strdup_printf(wmem_packet_scope(), "Failed to extract secrets: %s", gcry_strerror(err));
1394 if (!quic_hkdf_expand_label(GCRY_MD_SHA256, secret, sizeof(secret), "client in",
1395 client_initial_secret, HASH_SHA2_256_LENGTH)) {
1396 *error = "Key expansion (client) failed";
1400 if (!quic_hkdf_expand_label(GCRY_MD_SHA256, secret, sizeof(secret), "server in",
1401 server_initial_secret, HASH_SHA2_256_LENGTH)) {
1402 *error = "Key expansion (server) failed";
1411 * Maps a Packet Protection cipher to the Packet Number protection cipher.
1412 * See https://tools.ietf.org/html/draft-ietf-quic-tls-14#section-5.3
1415 quic_get_pn_cipher_algo(int cipher_algo, int *pn_cipher_mode)
1417 switch (cipher_algo) {
1418 case GCRY_CIPHER_AES128:
1419 case GCRY_CIPHER_AES256:
1420 *pn_cipher_mode = GCRY_CIPHER_MODE_CTR;
1422 #ifdef HAVE_LIBGCRYPT_CHACHA20
1423 case GCRY_CIPHER_CHACHA20:
1424 *pn_cipher_mode = 0;
1426 #endif /* HAVE_LIBGCRYPT_CHACHA20 */
1433 * (Re)initialize the PNE/PP ciphers using the given cipher algorithm.
1434 * If the optional base secret is given, then its length MUST match the hash
1438 quic_cipher_prepare(guint32 version, quic_cipher *cipher, int hash_algo, int cipher_algo, int cipher_mode, guint8 *secret, const char **error)
1440 /* Clear previous state (if any). */
1441 quic_cipher_reset(cipher);
1444 if (!quic_get_pn_cipher_algo(cipher_algo, &pn_cipher_mode)) {
1445 *error = "Unsupported cipher algorithm";
1449 if (gcry_cipher_open(&cipher->pn_cipher, cipher_algo, pn_cipher_mode, 0) ||
1450 gcry_cipher_open(&cipher->pp_cipher, cipher_algo, cipher_mode, 0)) {
1451 quic_cipher_reset(cipher);
1452 *error = "Failed to create ciphers";
1457 guint cipher_keylen = (guint8) gcry_cipher_get_algo_keylen(cipher_algo);
1458 if (!quic_cipher_init(version, cipher, hash_algo, cipher_keylen, secret)) {
1459 quic_cipher_reset(cipher);
1460 *error = "Failed to derive key material for cipher";
1469 quic_create_initial_decoders(const quic_cid_t *cid, const gchar **error, quic_info_data_t *quic_info)
1471 guint8 client_secret[HASH_SHA2_256_LENGTH];
1472 guint8 server_secret[HASH_SHA2_256_LENGTH];
1473 guint32 version = quic_info->version;
1475 if (!quic_derive_initial_secrets(cid, client_secret, server_secret, error)) {
1479 /* Packet numbers are protected with AES128-CTR,
1480 * initial packets are protected with AEAD_AES_128_GCM. */
1481 if (!quic_cipher_prepare(version, &quic_info->client_initial_cipher, GCRY_MD_SHA256,
1482 GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, client_secret, error) ||
1483 !quic_cipher_prepare(version, &quic_info->server_initial_cipher, GCRY_MD_SHA256,
1484 GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, server_secret, error)) {
1492 quic_create_decoders(packet_info *pinfo, guint32 version, quic_info_data_t *quic_info, quic_cipher *cipher,
1493 gboolean from_server, TLSRecordType type, const char **error)
1495 if (!quic_info->hash_algo) {
1496 if (!tls_get_cipher_info(pinfo, &quic_info->cipher_algo, &quic_info->cipher_mode, &quic_info->hash_algo)) {
1497 *error = "Unable to retrieve cipher information";
1502 guint hash_len = gcry_md_get_algo_dlen(quic_info->hash_algo);
1503 char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
1505 if (!tls13_get_quic_secret(pinfo, from_server, type, hash_len, secret)) {
1506 *error = "Secrets are not available";
1510 if (!quic_cipher_prepare(version, cipher, quic_info->hash_algo,
1511 quic_info->cipher_algo, quic_info->cipher_mode, secret, error)) {
1519 * Computes QHKDF-Expand(Secret, Label, Length).
1520 * Caller must ensure that "out" is large enough for "out_len".
1523 qhkdf_expand(int md, const guint8 *secret, guint secret_len,
1524 const char *label, guint8 *out, guint out_len)
1526 /* https://tools.ietf.org/html/draft-ietf-quic-tls-10#section-5.2.1
1527 * QHKDF-Expand(Secret, Label, Length) =
1528 * HKDF-Expand(Secret, QhkdfLabel, Length)
1530 * uint16 length = Length;
1531 * opaque label<6..255> = "QUIC " + Label;
1535 const guint label_length = (guint) strlen(label);
1537 /* Some sanity checks */
1538 DISSECTOR_ASSERT(label_length > 0 && 5 + label_length <= 255);
1540 /* info = QhkdfLabel { length, label } */
1541 GByteArray *info = g_byte_array_new();
1542 const guint16 length = g_htons(out_len);
1543 g_byte_array_append(info, (const guint8 *)&length, sizeof(length));
1545 const guint8 label_vector_length = 5 + label_length;
1546 g_byte_array_append(info, &label_vector_length, 1);
1547 g_byte_array_append(info, "QUIC ", 5);
1548 g_byte_array_append(info, label, label_length);
1550 err = hkdf_expand(md, secret, secret_len, info->data, info->len, out, out_len);
1551 g_byte_array_free(info, TRUE);
1556 * Tries to obtain the QUIC application traffic secrets.
1559 quic_get_traffic_secret(packet_info *pinfo, int hash_algo, quic_pp_state_t *pp_state, gboolean from_client)
1561 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
1562 char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
1563 if (!tls13_get_quic_secret(pinfo, !from_client, TLS_SECRET_APP, hash_len, secret)) {
1566 pp_state->next_secret = (guint8 *)wmem_memdup(wmem_file_scope(), secret, hash_len);
1571 * Expands the secret (length MUST be the same as the "hash_algo" digest size)
1572 * and initialize cipher with the new key.
1575 quic_cipher_init(guint32 version _U_, quic_cipher *cipher, int hash_algo, guint8 key_length, guint8 *secret)
1577 guchar write_key[256/8]; /* Maximum key size is for AES256 cipher. */
1578 guchar pn_key[256/8];
1579 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
1581 if (key_length > sizeof(write_key)) {
1585 if (!quic_hkdf_expand_label(hash_algo, secret, hash_len, "key", write_key, key_length) ||
1586 !quic_hkdf_expand_label(hash_algo, secret, hash_len, "iv", cipher->pp_iv, sizeof(cipher->pp_iv)) ||
1587 !quic_hkdf_expand_label(hash_algo, secret, hash_len, "pn", pn_key, key_length)) {
1591 return gcry_cipher_setkey(cipher->pn_cipher, pn_key, key_length) == 0 &&
1592 gcry_cipher_setkey(cipher->pp_cipher, write_key, key_length) == 0;
1596 * Updates the packet protection secret to the next one.
1599 quic_update_key(int hash_algo, quic_pp_state_t *pp_state, gboolean from_client)
1601 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
1602 qhkdf_expand(hash_algo, pp_state->next_secret, hash_len,
1603 from_client ? "client 1rtt" : "server 1rtt",
1604 pp_state->next_secret, hash_len);
1608 * Tries to construct the appropriate cipher for the current key phase.
1609 * See also "PROTECTED PAYLOAD DECRYPTION" comment on top of this file.
1611 static quic_cipher *
1612 quic_get_pp_cipher(packet_info *pinfo, gboolean key_phase, quic_info_data_t *quic_info, gboolean from_server)
1614 guint32 version = quic_info->version;
1615 const char *error = NULL;
1616 gboolean success = FALSE;
1618 /* Keys were previously not available. */
1619 if (quic_info->skip_decryption) {
1623 quic_pp_state_t *client_pp = &quic_info->client_pp;
1624 quic_pp_state_t *server_pp = &quic_info->server_pp;
1625 quic_pp_state_t *pp_state = !from_server ? client_pp : server_pp;
1627 /* Try to lookup secrets if not available. */
1628 if (!quic_info->client_pp.next_secret) {
1629 /* Query TLS for the cipher suite. */
1630 if (!tls_get_cipher_info(pinfo, &quic_info->cipher_algo, &quic_info->cipher_mode, &quic_info->hash_algo)) {
1631 /* No previous TLS handshake found or unsupported ciphers, fail. */
1632 quic_info->skip_decryption = TRUE;
1636 /* Retrieve secrets for both the client and server. */
1637 if (!quic_get_traffic_secret(pinfo, quic_info->hash_algo, client_pp, TRUE) ||
1638 !quic_get_traffic_secret(pinfo, quic_info->hash_algo, server_pp, FALSE)) {
1639 quic_info->skip_decryption = TRUE;
1643 /* Create initial cipher handles for KEY_PHASE 0 and 1. */
1644 if (!quic_cipher_prepare(version, &client_pp->cipher[0], quic_info->hash_algo,
1645 quic_info->cipher_algo, quic_info->cipher_mode, client_pp->next_secret, &error) ||
1646 !quic_cipher_prepare(version, &server_pp->cipher[0], quic_info->hash_algo,
1647 quic_info->cipher_algo, quic_info->cipher_mode, server_pp->next_secret, &error)) {
1648 quic_info->skip_decryption = TRUE;
1651 quic_update_key(quic_info->hash_algo, pp_state, !from_server);
1655 * If the key phase changed, try to decrypt the packet using the new cipher.
1656 * If that fails, then it is either a malicious packet or out-of-order.
1657 * In that case, try the previous cipher (unless it is the very first KP1).
1659 if (key_phase != pp_state->key_phase) {
1660 quic_cipher new_cipher;
1662 memset(&new_cipher, 0, sizeof(quic_cipher));
1663 if (!quic_cipher_prepare(version, &new_cipher, quic_info->hash_algo,
1664 quic_info->cipher_algo, quic_info->cipher_mode, server_pp->next_secret, &error)) {
1665 /* This should never be reached, if the parameters were wrong
1666 * before, then it should have set "skip_decryption". */
1667 REPORT_DISSECTOR_BUG("quic_cipher_prepare unexpectedly failed: %s", error);
1671 // TODO verify decryption before switching keys.
1675 /* Verified the cipher, use it from now on and rotate the key. */
1676 quic_cipher_reset(&pp_state->cipher[key_phase]);
1677 pp_state->cipher[key_phase] = new_cipher;
1678 quic_update_key(quic_info->hash_algo, pp_state, !from_server);
1680 pp_state->key_phase = key_phase;
1681 //pp_state->changed_in_pkn = pkn;
1683 return &pp_state->cipher[key_phase];
1685 // TODO fallback to previous cipher
1690 return &pp_state->cipher[key_phase];
1692 #endif /* HAVE_LIBGCRYPT_AEAD */
1694 #ifdef HAVE_LIBGCRYPT_AEAD
1696 * Process (protected) payload, adding the encrypted payload to the tree. If
1697 * decryption is possible, frame dissection is also attempted.
1699 * The given offset must correspond to the end of the QUIC header and begin of
1700 * the (protected) payload. Dissected frames are appended to "tree" and expert
1701 * info is attached to "ti" (the field with the encrypted payload).
1704 quic_process_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint offset,
1705 quic_info_data_t *quic_info, quic_packet_info_t *quic_packet, gboolean from_server,
1706 quic_cipher *cipher, guint pkn_len)
1708 quic_decrypt_result_t *decryption = &quic_packet->decryption;
1711 * If no decryption error has occurred yet, try decryption on the first
1712 * pass and store the result for later use.
1714 if (!PINFO_FD_VISITED(pinfo)) {
1715 if (!quic_packet->decryption.error && cipher && cipher->pp_cipher) {
1716 quic_decrypt_message(cipher, tvb, offset, pkn_len, quic_packet->packet_number, &quic_packet->decryption);
1720 if (decryption->error) {
1721 expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed,
1722 "Decryption failed: %s", decryption->error);
1723 } else if (decryption->data_len) {
1724 tvbuff_t *decrypted_tvb = tvb_new_child_real_data(tvb, decryption->data,
1725 decryption->data_len, decryption->data_len);
1726 add_new_data_source(pinfo, decrypted_tvb, "Decrypted QUIC");
1728 guint decrypted_offset = 0;
1729 while (tvb_reported_length_remaining(decrypted_tvb, decrypted_offset) > 0) {
1730 decrypted_offset = dissect_quic_frame_type(decrypted_tvb, pinfo, tree, decrypted_offset, quic_info, from_server);
1732 } else if (quic_info->skip_decryption) {
1733 expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed,
1734 "Decryption skipped because keys are not available.");
1737 #else /* !HAVE_LIBGCRYPT_AEAD */
1739 quic_process_payload(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, proto_item *ti, guint offset _U_,
1740 quic_info_data_t *quic_info _U_, quic_packet_info_t *quic_packet _U_, gboolean from_server _U_,
1741 quic_cipher *cipher _U_, guint pkn_len _U_)
1743 expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Libgcrypt >= 1.6.0 is required for QUIC decryption");
1745 #endif /* !HAVE_LIBGCRYPT_AEAD */
1748 quic_add_connection_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, quic_info_data_t *conn)
1753 ctree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_quic_connection_info, NULL, "QUIC Connection information");
1755 expert_add_info(pinfo, ctree, &ei_quic_connection_unknown);
1759 pi = proto_tree_add_uint(ctree, hf_quic_connection_number, tvb, 0, 0, conn->number);
1760 PROTO_ITEM_SET_GENERATED(pi);
1762 proto_tree_add_debug_text(ctree, "Client CID: %s", cid_to_string(&conn->client_cids.data));
1763 proto_tree_add_debug_text(ctree, "Server CID: %s", cid_to_string(&conn->server_cids.data));
1764 proto_tree_add_debug_text(ctree, "InitialCID: %s", cid_to_string(&conn->client_dcid_initial));
1769 * Dissects the common part after the first byte for packets using the Long
1773 dissect_quic_long_header_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
1774 guint offset, const quic_packet_info_t *quic_packet _U_,
1775 guint32 *version_out, quic_cid_t *dcid, quic_cid_t *scid)
1780 version = tvb_get_ntohl(tvb, offset);
1783 *version_out = version;
1786 proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
1789 proto_tree_add_item_ret_uint(quic_tree, hf_quic_dcil, tvb, offset, 1, ENC_BIG_ENDIAN, &dcil);
1790 proto_tree_add_item_ret_uint(quic_tree, hf_quic_scil, tvb, offset, 1, ENC_BIG_ENDIAN, &scil);
1795 proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, dcil, ENC_NA);
1796 // TODO expert info on CID mismatch with connection
1797 tvb_memcpy(tvb, dcid->cid, offset, dcil);
1804 proto_tree_add_item(quic_tree, hf_quic_scid, tvb, offset, scil, ENC_NA);
1805 // TODO expert info on CID mismatch with connection
1806 tvb_memcpy(tvb, scid->cid, offset, scil);
1811 if (dcid->len > 0) {
1812 col_append_fstr(pinfo->cinfo, COL_INFO, ", DCID=%s", cid_to_string(dcid));
1814 if (scid->len > 0) {
1815 col_append_fstr(pinfo->cinfo, COL_INFO, ", SCID=%s", cid_to_string(scid));
1820 /* Retry Packet dissection for draft -13 and newer. */
1822 dissect_quic_retry_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
1823 quic_datagram *dgram_info _U_, quic_packet_info_t *quic_packet)
1827 guint32 len_payload_length;
1828 guint64 payload_length;
1829 quic_cid_t dcid = {.len=0}, scid = {.len=0};
1831 guint retry_token_len;
1833 proto_tree_add_item(quic_tree, hf_quic_long_packet_type, tvb, offset, 1, ENC_NA);
1835 col_set_str(pinfo->cinfo, COL_INFO, "Retry");
1837 offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, &version, &dcid, &scid);
1839 if (is_quic_draft_max(version, 13)) {
1840 proto_tree_add_item_ret_varint(quic_tree, hf_quic_length, tvb, offset, -1, ENC_VARINT_QUIC, &payload_length, &len_payload_length);
1841 offset += len_payload_length;
1842 // PKN is encrypted, but who cares about draft -13 anyway.
1843 proto_tree_add_item(quic_tree, hf_quic_packet_number, tvb, offset, 1, ENC_NA);
1845 proto_tree_add_item_ret_uint(quic_tree, hf_quic_odcil_draft13, tvb, offset, 1, ENC_NA, &odcil);
1847 proto_tree_add_item_ret_uint(quic_tree, hf_quic_odcil, tvb, offset, 1, ENC_NA, &odcil);
1853 proto_tree_add_item(quic_tree, hf_quic_odcid, tvb, offset, odcil, ENC_NA);
1855 retry_token_len = tvb_reported_length_remaining(tvb, offset);
1856 proto_tree_add_item(quic_tree, hf_quic_retry_token, tvb, offset, retry_token_len, ENC_NA);
1857 offset += retry_token_len;
1863 dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
1864 quic_datagram *dgram_info, quic_packet_info_t *quic_packet)
1867 guint32 long_packet_type;
1869 quic_cid_t dcid = {.len=0}, scid = {.len=0};
1870 guint32 len_token_length;
1871 guint64 token_length;
1872 guint32 len_payload_length;
1873 guint64 payload_length;
1876 quic_info_data_t *conn = dgram_info->conn;
1877 const gboolean from_server = dgram_info->from_server;
1878 quic_cipher *cipher = NULL;
1881 proto_tree_add_item_ret_uint(quic_tree, hf_quic_long_packet_type, tvb, offset, 1, ENC_NA, &long_packet_type);
1883 col_set_str(pinfo->cinfo, COL_INFO, val_to_str(long_packet_type, quic_long_packet_type_vals, "Long Header"));
1885 offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, &version, &dcid, &scid);
1887 if (long_packet_type == QUIC_LPT_INITIAL) {
1888 proto_tree_add_item_ret_varint(quic_tree, hf_quic_token_length, tvb, offset, -1, ENC_VARINT_QUIC, &token_length, &len_token_length);
1889 offset += len_token_length;
1892 proto_tree_add_item(quic_tree, hf_quic_token, tvb, offset, (guint32)token_length, ENC_NA);
1893 offset += (guint)token_length;
1897 proto_tree_add_item_ret_varint(quic_tree, hf_quic_length, tvb, offset, -1, ENC_VARINT_QUIC, &payload_length, &len_payload_length);
1898 offset += len_payload_length;
1900 #ifdef HAVE_LIBGCRYPT_AEAD
1902 if (long_packet_type == QUIC_LPT_INITIAL) {
1903 cipher = !from_server ? &conn->client_initial_cipher : &conn->server_initial_cipher;
1904 } else if (long_packet_type == QUIC_LPT_HANDSHAKE) {
1905 cipher = !from_server ? &conn->client_handshake_cipher : &conn->server_handshake_cipher;
1908 /* Build handshake cipher now for PKN (and handshake) decryption. */
1909 if (!PINFO_FD_VISITED(pinfo) && conn) {
1910 const gchar *error = NULL;
1911 if (long_packet_type == QUIC_LPT_INITIAL && !from_server &&
1912 !memcmp(&dcid, &conn->client_dcid_initial, sizeof(quic_cid_t))) {
1913 /* Create new decryption context based on the Client Connection
1914 * ID from the *very first* Client Initial packet. */
1915 quic_create_initial_decoders(&dcid, &error, conn);
1916 } else if (long_packet_type == QUIC_LPT_HANDSHAKE) {
1917 if (!cipher->pn_cipher) {
1918 quic_create_decoders(pinfo, version, conn, cipher, from_server, TLS_SECRET_HANDSHAKE, &error);
1922 quic_packet->decryption.error = wmem_strdup(wmem_file_scope(), error);
1925 #endif /* !HAVE_LIBGCRYPT_AEAD */
1926 if (quic_packet->decryption.error) {
1927 expert_add_info_format(pinfo, quic_tree, &ei_quic_decryption_failed,
1928 "Failed to create decryption context: %s", quic_packet->decryption.error);
1932 pkn_len = dissect_quic_packet_number(tvb, pinfo, quic_tree, offset, conn, quic_packet, from_server,
1933 cipher, GCRY_CIPHER_AES128, &pkn);
1938 col_append_fstr(pinfo->cinfo, COL_INFO, ", PKN: %" G_GINT64_MODIFIER "u", pkn);
1941 ti = proto_tree_add_item(quic_tree, hf_quic_payload, tvb, offset, -1, ENC_NA);
1944 quic_process_payload(tvb, pinfo, quic_tree, ti, offset,
1945 conn, quic_packet, from_server, cipher, pkn_len);
1947 offset += tvb_reported_length_remaining(tvb, offset);
1953 dissect_quic_short_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
1954 quic_datagram *dgram_info, quic_packet_info_t *quic_packet)
1957 quic_cid_t dcid = {.len=0};
1961 gboolean key_phase = FALSE;
1962 quic_cipher *cipher = NULL;
1963 quic_info_data_t *conn = dgram_info->conn;
1964 const gboolean from_server = dgram_info->from_server;
1966 proto_tree_add_item_ret_boolean(quic_tree, hf_quic_short_kp_flag, tvb, offset, 1, ENC_NA, &key_phase);
1967 proto_tree_add_item(quic_tree, hf_quic_short_reserved, tvb, offset, 1, ENC_NA);
1969 dcid.len = from_server ? conn->client_cids.data.len : conn->server_cids.data.len;
1973 col_clear(pinfo->cinfo, COL_INFO);
1974 col_append_fstr(pinfo->cinfo, COL_INFO, "Protected Payload (KP%u)", key_phase);
1978 proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, dcid.len, ENC_NA);
1979 tvb_memcpy(tvb, dcid.cid, offset, dcid.len);
1981 col_append_fstr(pinfo->cinfo, COL_INFO, ", DCID=%s", cid_to_string(&dcid));
1984 #ifdef HAVE_LIBGCRYPT_AEAD
1985 if (!PINFO_FD_VISITED(pinfo) && conn) {
1986 cipher = quic_get_pp_cipher(pinfo, key_phase, conn, from_server);
1988 #endif /* !HAVE_LIBGCRYPT_AEAD */
1989 if (!conn || conn->skip_decryption) {
1994 pkn_len = dissect_quic_packet_number(tvb, pinfo, quic_tree, offset, conn, quic_packet, from_server,
1995 cipher, conn ? conn->cipher_algo : 0, &pkn);
2001 col_append_fstr(pinfo->cinfo, COL_INFO, ", PKN: %" G_GINT64_MODIFIER "u", pkn);
2003 /* Protected Payload */
2004 ti = proto_tree_add_item(quic_tree, hf_quic_protected_payload, tvb, offset, -1, ENC_NA);
2007 quic_process_payload(tvb, pinfo, quic_tree, ti, offset,
2008 conn, quic_packet, from_server, cipher, pkn_len);
2010 offset += tvb_reported_length_remaining(tvb, offset);
2016 dissect_quic_version_negotiation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, const quic_packet_info_t *quic_packet)
2019 quic_cid_t dcid = {.len=0}, scid = {.len=0};
2020 guint32 supported_version;
2023 col_set_str(pinfo->cinfo, COL_INFO, "Version Negotiation");
2025 proto_tree_add_item(quic_tree, hf_quic_vn_unused, tvb, offset, 1, ENC_NA);
2028 offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, NULL, &dcid, &scid);
2030 /* Supported Version */
2031 while(tvb_reported_length_remaining(tvb, offset) > 0){
2032 ti = proto_tree_add_item_ret_uint(quic_tree, hf_quic_supported_version, tvb, offset, 4, ENC_BIG_ENDIAN, &supported_version);
2033 if ((supported_version & 0x0F0F0F0F) == 0x0a0a0a0a) {
2034 proto_item_append_text(ti, " (GREASE)");
2043 quic_get_message_tvb(tvbuff_t *tvb, const guint offset)
2045 guint64 token_length;
2046 guint64 payload_length;
2047 guint8 packet_type = tvb_get_guint8(tvb, offset);
2048 guint8 long_packet_type = packet_type & 0x7f;
2049 // Retry and VN packets cannot be coalesced (clarified in draft -14).
2050 if ((packet_type & 0x80) && long_packet_type != QUIC_LPT_RETRY) {
2051 // long header form, check version
2052 guint version = tvb_get_ntohl(tvb, offset + 1);
2053 // If this is not a VN packet but a valid long form, extract a subset.
2054 // TODO check for valid QUIC versions as future versions might change the format.
2056 guint8 cid_lengths = tvb_get_guint8(tvb, offset + 5);
2057 guint8 dcil = cid_lengths >> 4;
2058 guint8 scil = cid_lengths & 0xf;
2066 if (long_packet_type == QUIC_LPT_INITIAL) {
2067 length += tvb_get_varint(tvb, offset + length, 8, &token_length, ENC_VARINT_QUIC);
2068 length += (guint)token_length;
2070 length += tvb_get_varint(tvb, offset + length, 8, &payload_length, ENC_VARINT_QUIC);
2071 length += (guint)payload_length;
2072 if (payload_length <= G_MAXINT32 && length < (guint)tvb_reported_length_remaining(tvb, offset)) {
2073 return tvb_new_subset_length(tvb, offset, length);
2078 // short header form, VN or unknown message, return remaining data.
2079 return tvb_new_subset_remaining(tvb, offset);
2083 * Extracts necessary information from header to find any existing connection.
2084 * "long_packet_type" is set to QUIC_SHORT_PACKET for short header packets.
2085 * DCID and SCID are not modified unless available. For short header packets,
2086 * DCID length is unknown, so the caller should truncate it as needed.
2089 quic_extract_header(tvbuff_t *tvb, guint8 *long_packet_type, guint32 *version,
2090 quic_cid_t *dcid, quic_cid_t *scid)
2094 guint8 packet_type = tvb_get_guint8(tvb, offset);
2095 gboolean is_long_header = packet_type & 0x80;
2096 if (is_long_header) {
2098 *long_packet_type = packet_type & 0x7f;
2100 // short header form, store dummy value that is not a long packet type.
2101 *long_packet_type = QUIC_SHORT_PACKET;
2105 *version = tvb_get_ntohl(tvb, offset);
2107 if (is_long_header) {
2111 // read DCIL/SCIL (Connection ID Lengths).
2112 guint8 cid_lengths = tvb_get_guint8(tvb, offset);
2113 guint8 dcil = cid_lengths >> 4;
2114 guint8 scil = cid_lengths & 0xf;
2119 tvb_memcpy(tvb, dcid->cid, offset, dcil);
2126 tvb_memcpy(tvb, scid->cid, offset, scil);
2130 // Definitely not draft -10, set version to dummy value.
2132 // For short headers, the DCID length is unknown and could be 0 or
2133 // anything from 4 to 18 bytes. Copy the maximum possible and let the
2134 // consumer truncate it as necessary.
2135 tvb_memcpy(tvb, dcid->cid, offset, 18);
2141 dissect_quic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2145 proto_tree *quic_tree;
2147 guint32 header_form;
2148 quic_datagram *dgram_info = NULL;
2149 quic_packet_info_t *quic_packet = NULL;
2151 col_set_str(pinfo->cinfo, COL_PROTOCOL, "QUIC");
2153 if (PINFO_FD_VISITED(pinfo)) {
2154 dgram_info = (quic_datagram *)p_get_proto_data(wmem_file_scope(), pinfo, proto_quic, 0);
2157 dgram_info = wmem_new0(wmem_file_scope(), quic_datagram);
2158 p_add_proto_data(wmem_file_scope(), pinfo, proto_quic, 0, dgram_info);
2161 ti = proto_tree_add_item(tree, proto_quic, tvb, 0, -1, ENC_NA);
2163 quic_tree = proto_item_add_subtree(ti, ett_quic);
2165 if (!PINFO_FD_VISITED(pinfo)) {
2166 guint8 long_packet_type;
2168 quic_cid_t dcid = {.len=0}, scid = {.len=0};
2169 gboolean from_server = FALSE;
2170 quic_info_data_t *conn;
2172 quic_extract_header(tvb, &long_packet_type, &version, &dcid, &scid);
2173 conn = quic_connection_find(pinfo, long_packet_type, &dcid, &from_server);
2174 quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &scid, &dcid, from_server);
2175 dgram_info->conn = conn;
2176 dgram_info->from_server = from_server;
2178 proto_tree_add_debug_text(quic_tree, "Connection: %d %p DCID=%s SCID=%s from_server:%d", pinfo->num, dgram_info->conn, cid_to_string(&dcid), cid_to_string(&scid), dgram_info->from_server);
2180 proto_tree_add_debug_text(quic_tree, "Connection: %d %p from_server:%d", pinfo->num, dgram_info->conn, dgram_info->from_server);
2184 quic_add_connection_info(tvb, pinfo, quic_tree, dgram_info->conn);
2188 quic_packet = &dgram_info->first_packet;
2189 } else if (!PINFO_FD_VISITED(pinfo)) {
2190 quic_packet->next = wmem_new0(wmem_file_scope(), quic_packet_info_t);
2191 quic_packet = quic_packet->next;
2193 quic_packet = quic_packet->next;
2194 DISSECTOR_ASSERT(quic_packet);
2197 tvbuff_t *next_tvb = quic_get_message_tvb(tvb, offset);
2198 proto_tree_add_item_ret_uint(quic_tree, hf_quic_header_form, next_tvb, 0, 1, ENC_NA, &header_form);
2199 guint new_offset = 0;
2201 guint8 long_packet_type = tvb_get_guint8(next_tvb, 0) & 0x7f;
2202 guint32 version = tvb_get_ntohl(next_tvb, 1);
2204 dissect_quic_version_negotiation(next_tvb, pinfo, quic_tree, quic_packet);
2207 if (long_packet_type == QUIC_LPT_RETRY) {
2208 new_offset = dissect_quic_retry_packet(next_tvb, pinfo, quic_tree, dgram_info, quic_packet);
2210 new_offset = dissect_quic_long_header(next_tvb, pinfo, quic_tree, dgram_info, quic_packet);
2213 new_offset = dissect_quic_short_header(next_tvb, pinfo, quic_tree, dgram_info, quic_packet);
2215 if (tvb_reported_length_remaining(next_tvb, new_offset)) {
2216 // should usually not be present unless decryption is not possible.
2217 proto_tree_add_item(quic_tree, hf_quic_remaining_payload, next_tvb, new_offset, -1, ENC_NA);
2219 offset += tvb_reported_length(next_tvb);
2220 } while (tvb_reported_length_remaining(tvb, offset));
2226 dissect_quic_short_header_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2228 // If this capture does not contain QUIC, skip the more expensive checks.
2229 if (quic_cid_lengths == 0) {
2233 // Is this a SH packet after connection migration? SH (draft -14):
2234 // Flag (1) + DCID (4-18) + PKN (1/2/4) + encrypted payload (>= 16).
2235 if (tvb_captured_length(tvb) < 1 + 4 + 1 + 16) {
2239 // DCID length is unknown, so extract the maximum and look for a match.
2240 quic_cid_t dcid = {.len=18};
2241 tvb_memcpy(tvb, dcid.cid, 1, 18);
2242 gboolean from_server;
2243 if (!quic_connection_find(pinfo, QUIC_SHORT_PACKET, &dcid, &from_server)) {
2247 conversation_t *conversation = find_or_create_conversation(pinfo);
2248 conversation_set_dissector(conversation, quic_handle);
2249 dissect_quic(tvb, pinfo, tree, NULL);
2253 static gboolean dissect_quic_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2257 * Flag (1 byte) + Version (4 bytes) + DCIL/SCIL (1 byte) +
2258 * Destination Connection ID (0/4..18 based on DCIL) +
2259 * Source Connection ID (0/4..18 based on SCIL) +
2260 * Payload length (1/2/4/8) + Packet number (1/2/4 bytes) + Payload.
2261 * (absolute minimum: 8 + payload)
2262 * (for Version Negotiation, payload len + PKN + payload is replaced by
2263 * Supported Version (multiple of 4 bytes.)
2265 conversation_t *conversation = NULL;
2268 gboolean is_quic = FALSE;
2270 /* Verify packet size (Flag (1 byte) + Connection ID (8 bytes) + Version (4 bytes)) */
2271 if (tvb_captured_length(tvb) < 13)
2276 flags = tvb_get_guint8(tvb, offset);
2277 /* Check if long Packet is set */
2278 if((flags & 0x80) == 0) {
2279 // Perhaps this is a short header, check it.
2280 return dissect_quic_short_header_heur(tvb, pinfo, tree);
2284 // check for draft QUIC version (for draft -11 and newer)
2285 is_quic = quic_draft_version(tvb_get_ntohl(tvb, offset)) >= 11;
2288 conversation = find_or_create_conversation(pinfo);
2289 conversation_set_dissector(conversation, quic_handle);
2290 dissect_quic(tvb, pinfo, tree, data);
2296 /** Initialize QUIC dissection state for a new capture file. */
2300 quic_connections = wmem_list_new(wmem_file_scope());
2301 quic_connections_count = 0;
2302 quic_initial_connections = wmem_map_new(wmem_file_scope(), quic_connection_hash, quic_connection_equal);
2303 quic_client_connections = wmem_map_new(wmem_file_scope(), quic_connection_hash, quic_connection_equal);
2304 quic_server_connections = wmem_map_new(wmem_file_scope(), quic_connection_hash, quic_connection_equal);
2305 quic_cid_lengths = 0;
2308 /** Release QUIC dissection state on closing a capture file. */
2312 wmem_list_foreach(quic_connections, quic_connection_destroy, NULL);
2313 quic_initial_connections = NULL;
2314 quic_client_connections = NULL;
2315 quic_server_connections = NULL;
2319 proto_register_quic(void)
2321 expert_module_t *expert_quic;
2323 static hf_register_info hf[] = {
2324 { &hf_quic_connection_number,
2325 { "Connection Number", "quic.connection.number",
2326 FT_UINT32, BASE_DEC, NULL, 0x0,
2327 "Connection identifier within this capture file", HFILL }
2330 { &hf_quic_header_form,
2331 { "Header Form", "quic.header_form",
2332 FT_UINT8, BASE_DEC, VALS(quic_short_long_header_vals), 0x80,
2333 "The most significant bit (0x80) of the first octet is set to 1 for long headers and 0 for short headers.", HFILL }
2336 { &hf_quic_long_packet_type,
2337 { "Packet Type", "quic.long.packet_type",
2338 FT_UINT8, BASE_DEC, VALS(quic_long_packet_type_vals), 0x7F,
2339 "Long Header Packet Type", HFILL }
2342 { "Destination Connection ID", "quic.dcid",
2343 FT_BYTES, BASE_NONE, NULL, 0x0,
2347 { "Source Connection ID", "quic.scid",
2348 FT_BYTES, BASE_NONE, NULL, 0x0,
2352 { "Destination Connection ID Length", "quic.dcil",
2353 FT_UINT8, BASE_DEC, VALS(quic_cid_len_vals), 0xf0,
2354 "Destination Connection ID Length (for non-zero lengths, add 3 for actual length)", HFILL }
2357 { "Source Connection ID Length", "quic.scil",
2358 FT_UINT8, BASE_DEC, VALS(quic_cid_len_vals), 0x0f,
2359 "Source Connection ID Length (for non-zero lengths, add 3 for actual length)", HFILL }
2361 { &hf_quic_token_length,
2362 { "Token Length", "quic.token_length",
2363 FT_UINT64, BASE_DEC, NULL, 0x0,
2367 { "Token", "quic.token",
2368 FT_BYTES, BASE_NONE, NULL, 0x0,
2372 { "Length", "quic.length",
2373 FT_UINT64, BASE_DEC, NULL, 0x0,
2374 "Length of Packet Number and Payload fields", HFILL }
2377 { &hf_quic_packet_number,
2378 { "Packet Number", "quic.packet_number",
2379 FT_UINT64, BASE_DEC, NULL, 0x0,
2382 { &hf_quic_packet_number_full,
2383 { "Packet Number (full)", "quic.packet_number_full",
2384 FT_UINT64, BASE_DEC, NULL, 0x0,
2385 "Full packet number", HFILL }
2388 { "Version", "quic.version",
2389 FT_UINT32, BASE_HEX, VALS(quic_version_vals), 0x0,
2392 { &hf_quic_supported_version,
2393 { "Supported Version", "quic.supported_version",
2394 FT_UINT32, BASE_HEX, VALS(quic_version_vals), 0x0,
2397 { &hf_quic_vn_unused, /* <= draft-07 */
2398 { "Unused", "quic.vn.unused",
2399 FT_UINT8, BASE_HEX, NULL, 0x7F,
2402 { &hf_quic_short_kp_flag,
2403 { "Key Phase Bit", "quic.short.kp_flag",
2404 FT_BOOLEAN, 8, NULL, SH_KP,
2407 { &hf_quic_short_reserved,
2408 { "Reserved", "quic.short.reserved",
2409 FT_UINT8, BASE_DEC, NULL, 0x07,
2410 "Reserved bits for experimentation", HFILL }
2414 { "Payload", "quic.payload",
2415 FT_BYTES, BASE_NONE, NULL, 0x0,
2416 "(Encrypted) payload of a packet", HFILL }
2418 { &hf_quic_protected_payload,
2419 { "Protected Payload", "quic.protected_payload",
2420 FT_BYTES, BASE_NONE, NULL, 0x0,
2421 "1-RTT protected payload", HFILL }
2423 { &hf_quic_remaining_payload,
2424 { "Remaining Payload", "quic.remaining_payload",
2425 FT_BYTES, BASE_NONE, NULL, 0x0,
2426 "Remaining payload in a packet (possibly PKN followed by encrypted payload)", HFILL }
2429 { &hf_quic_odcil_draft13,
2430 { "Original Destination Connection ID Length", "quic.odcil_draft13",
2431 FT_UINT8, BASE_DEC, NULL, 0x0,
2435 { "Original Destination Connection ID Length", "quic.odcil",
2436 FT_UINT8, BASE_DEC, VALS(quic_cid_len_vals), 0x0f,
2440 { "Original Destination Connection ID", "quic.odcid",
2441 FT_BYTES, BASE_NONE, NULL, 0x0,
2444 { &hf_quic_retry_token,
2445 { "Retry Token", "quic.retry_token",
2446 FT_BYTES, BASE_NONE, NULL, 0x0,
2451 { "Frame", "quic.frame",
2452 FT_NONE, BASE_NONE, NULL, 0x0,
2455 { &hf_quic_frame_type,
2456 { "Frame Type", "quic.frame_type",
2457 FT_UINT8, BASE_RANGE_STRING | BASE_HEX, RVALS(quic_frame_type_vals), 0x0,
2462 { &hf_quic_frame_type_stream_fin,
2463 { "Fin", "quic.frame_type.stream.fin",
2464 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM_FIN,
2467 { &hf_quic_frame_type_stream_len,
2468 { "Len(gth)", "quic.frame_type.stream.len",
2469 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM_LEN,
2472 { &hf_quic_frame_type_stream_off,
2473 { "Off(set)", "quic.frame_type.stream.off",
2474 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM_OFF,
2478 { &hf_quic_stream_stream_id,
2479 { "Stream ID", "quic.stream.stream_id",
2480 FT_UINT64, BASE_DEC, NULL, 0x0,
2483 { &hf_quic_stream_offset,
2484 { "Offset", "quic.stream.offset",
2485 FT_UINT64, BASE_DEC, NULL, 0x0,
2488 { &hf_quic_stream_length,
2489 { "Length", "quic.stream.length",
2490 FT_UINT64, BASE_DEC, NULL, 0x0,
2493 { &hf_quic_stream_data,
2494 { "Stream Data", "quic.stream_data",
2495 FT_BYTES, BASE_NONE, NULL, 0x0,
2499 { &hf_quic_frame_type_ack_largest_acknowledged,
2500 { "Largest Acknowledged", "quic.frame_type.ack.largest_acknowledged",
2501 FT_UINT64, BASE_DEC, NULL, 0x0,
2502 "Representing the largest packet number the peer is acknowledging in this packet", HFILL }
2504 { &hf_quic_frame_type_ack_ack_delay,
2505 { "ACK Delay", "quic.frame_type.ack.ack_delay",
2506 FT_UINT64, BASE_DEC, NULL, 0x0,
2507 "The time from when the largest acknowledged packet, as indicated in the Largest Acknowledged field, was received by this peer to when this ACK was sent", HFILL }
2509 { &hf_quic_frame_type_ack_ack_block_count,
2510 { "ACK Block Count", "quic.frame_type.ack.ack_block_count",
2511 FT_UINT64, BASE_DEC, NULL, 0x0,
2512 "The number of Additional ACK Block (and Gap) fields after the First ACK Block", HFILL }
2514 { &hf_quic_frame_type_ack_fab,
2515 { "First ACK Block", "quic.frame_type.ack.fab",
2516 FT_UINT64, BASE_DEC, NULL, 0x0,
2517 "Indicates the number of contiguous additional packets being acknowledged starting at the Largest Acknowledged", HFILL }
2519 { &hf_quic_frame_type_ack_gap,
2520 { "Gap", "quic.frame_type.ack.gap",
2521 FT_UINT64, BASE_DEC, NULL, 0x0,
2522 "Indicating the number of contiguous unacknowledged packets preceding the packet number one lower than the smallest in the preceding ACK Block", HFILL }
2524 { &hf_quic_frame_type_ack_ack_block,
2525 { "ACK Block", "quic.frame_type.ack.ack_block",
2526 FT_UINT64, BASE_DEC, NULL, 0x0,
2527 "Indicating the number of contiguous acknowledged packets preceding the largest packet number, as determined by the preceding Gap", HFILL }
2529 /* PATH_CHALLENGE */
2530 { &hf_quic_frame_type_path_challenge_data,
2531 { "Data", "quic.frame_type.path_challenge.data",
2532 FT_BYTES, BASE_NONE, NULL, 0x0,
2533 "Arbitrary data that must be matched by a PATH_RESPONSE frame", HFILL }
2536 { &hf_quic_frame_type_path_response_data,
2537 { "Data", "quic.frame_type.path_response.data",
2538 FT_BYTES, BASE_NONE, NULL, 0x0,
2539 "Arbitrary data that must match a PATH_CHALLENGE frame", HFILL }
2542 { &hf_quic_frame_type_padding_length,
2543 { "Padding Length", "quic.frame_type.padding_length",
2544 FT_UINT32, BASE_DEC, NULL, 0x0,
2548 { &hf_quic_frame_type_rsts_stream_id,
2549 { "Stream ID", "quic.frame_type.rsts.stream_id",
2550 FT_UINT64, BASE_DEC, NULL, 0x0,
2551 "Stream ID of the stream being terminated", HFILL }
2553 { &hf_quic_frame_type_rsts_application_error_code,
2554 { "Application Error code", "quic.frame_type.rsts.application_error_code",
2555 FT_UINT16, BASE_DEC, VALS(quic_application_error_code_vals), 0x0,
2556 "Indicates why the stream is being closed", HFILL }
2558 { &hf_quic_frame_type_rsts_final_offset,
2559 { "Final offset", "quic.frame_type.rsts.byte_offset",
2560 FT_UINT64, BASE_DEC, NULL, 0x0,
2561 "Indicating the absolute byte offset of the end of data written on this stream", HFILL }
2563 /* CONNECTION_CLOSE */
2564 { &hf_quic_frame_type_cc_error_code,
2565 { "Error code", "quic.frame_type.cc.error_code",
2566 FT_UINT16, BASE_DEC|BASE_RANGE_STRING, RVALS(quic_transport_error_code_vals), 0x0,
2567 "Indicates the reason for closing this connection", HFILL }
2569 { &hf_quic_frame_type_cc_frame_type,
2570 { "Frame Type", "quic.frame_type.cc.frame_type",
2571 FT_UINT64, BASE_DEC, NULL, 0x0,
2572 "The type of frame that triggered the error", HFILL }
2574 { &hf_quic_frame_type_cc_reason_phrase_length,
2575 { "Reason phrase Length", "quic.frame_type.cc.reason_phrase.length",
2576 FT_UINT64, BASE_DEC, NULL, 0x0,
2577 "Specifying the length of the reason phrase", HFILL }
2579 { &hf_quic_frame_type_cc_reason_phrase,
2580 { "Reason phrase", "quic.frame_type.cc.reason_phrase",
2581 FT_STRING, BASE_NONE, NULL, 0x0,
2582 "A human-readable explanation for why the connection was closed", HFILL }
2584 /* APPLICATION_CLOSE */
2585 { &hf_quic_frame_type_ac_error_code,
2586 { "Application Error code", "quic.frame_type.ac.error_code",
2587 FT_UINT16, BASE_DEC, VALS(quic_application_error_code_vals), 0x0,
2588 "Indicates the reason for closing this application", HFILL }
2590 { &hf_quic_frame_type_ac_reason_phrase_length,
2591 { "Reason phrase Length", "quic.frame_type.ac.reason_phrase.length",
2592 FT_UINT64, BASE_DEC, NULL, 0x0,
2593 "Specifying the length of the reason phrase", HFILL }
2595 { &hf_quic_frame_type_ac_reason_phrase,
2596 { "Reason phrase", "quic.frame_type.ac.reason_phrase",
2597 FT_STRING, BASE_NONE, NULL, 0x0,
2598 "A human-readable explanation for why the application was closed", HFILL }
2601 { &hf_quic_frame_type_md_maximum_data,
2602 { "Maximum Data", "quic.frame_type.md.maximum_data",
2603 FT_UINT64, BASE_DEC, NULL, 0x0,
2604 "Indicating the maximum amount of data that can be sent on the entire connection, in units of 1024 octets", HFILL }
2606 /* MAX_STREAM_DATA */
2607 { &hf_quic_frame_type_msd_stream_id,
2608 { "Stream ID", "quic.frame_type.msd.stream_id",
2609 FT_UINT64, BASE_DEC, NULL, 0x0,
2610 "The stream ID of the stream that is affected", HFILL }
2612 { &hf_quic_frame_type_msd_maximum_stream_data,
2613 { "Maximum Stream Data", "quic.frame_type.msd.maximum_stream_data",
2614 FT_UINT64, BASE_DEC, NULL, 0x0,
2615 "Indicating the maximum amount of data that can be sent on the identified stream, in units of octets", HFILL }
2618 { &hf_quic_frame_type_msi_stream_id,
2619 { "Stream ID", "quic.frame_type.msi.stream_id",
2620 FT_UINT64, BASE_DEC, NULL, 0x0,
2621 "ID of the maximum peer-initiated stream ID for the connection", HFILL }
2624 { &hf_quic_frame_type_blocked_offset,
2625 { "Offset", "quic.frame_type.sb.offset",
2626 FT_UINT64, BASE_DEC, NULL, 0x0,
2627 "Indicating the connection-level offset at which the blocking occurred", HFILL }
2629 /* STREAM_BLOCKED */
2630 { &hf_quic_frame_type_sb_stream_id,
2631 { "Stream ID", "quic.frame_type.sb.stream_id",
2632 FT_UINT64, BASE_DEC, NULL, 0x0,
2633 "Indicating the stream which is flow control blocked", HFILL }
2635 { &hf_quic_frame_type_sb_offset,
2636 { "Offset", "quic.frame_type.sb.offset",
2637 FT_UINT64, BASE_DEC, NULL, 0x0,
2638 "Indicating the offset of the stream at which the blocking occurred", HFILL }
2640 /* STREAM_ID_BLOCKED */
2641 { &hf_quic_frame_type_sib_stream_id,
2642 { "Stream ID", "quic.frame_type.sib.stream_id",
2643 FT_UINT64, BASE_DEC, NULL, 0x0,
2644 "Indicating the highest stream ID that the sender was permitted to open", HFILL }
2646 /* NEW_CONNECTION_ID */
2647 { &hf_quic_frame_type_nci_sequence,
2648 { "Sequence", "quic.frame_type.nci.sequence",
2649 FT_UINT64, BASE_DEC, NULL, 0x0,
2650 "Increases by 1 for each connection ID that is provided by the server", HFILL }
2652 { &hf_quic_frame_type_nci_connection_id_length,
2653 { "Connection ID Length", "quic.frame_type.nci.connection_id.length",
2654 FT_UINT8, BASE_DEC, NULL, 0x0,
2657 { &hf_quic_frame_type_nci_connection_id,
2658 { "Connection ID", "quic.frame_type.nci.connection_id",
2659 FT_BYTES, BASE_NONE, NULL, 0x0,
2662 { &hf_quic_frame_type_nci_stateless_reset_token,
2663 { "Stateless Reset Token", "quic.frame_type.stateless_reset_token",
2664 FT_BYTES, BASE_NONE, NULL, 0x0,
2668 { &hf_quic_frame_type_ss_stream_id,
2669 { "Stream ID", "quic.frame_type.ss.stream_id",
2670 FT_UINT64, BASE_DEC, NULL, 0x0,
2671 "Stream ID of the stream being ignored", HFILL }
2673 { &hf_quic_frame_type_ss_application_error_code,
2674 { "Application Error code", "quic.frame_type.ss.application_error_code",
2675 FT_UINT16, BASE_DEC, NULL, 0x0,
2676 "Indicates why the sender is ignoring the stream", HFILL }
2680 { &hf_quic_frame_type_crypto_offset,
2681 { "Offset", "quic.frame_type.crypto.offset",
2682 FT_UINT64, BASE_DEC, NULL, 0x0,
2683 "Byte offset into the stream", HFILL }
2685 { &hf_quic_frame_type_crypto_length,
2686 { "Length", "quic.frame_type.crypto.length",
2687 FT_UINT64, BASE_DEC, NULL, 0x0,
2688 "Length of the Crypto Data field", HFILL }
2690 { &hf_quic_frame_type_crypto_crypto_data,
2691 { "Crypto Data", "quic.frame_type.crypto.crypto_data",
2692 FT_NONE, BASE_NONE, NULL, 0x0,
2693 "The cryptographic message data", HFILL }
2697 { &hf_quic_frame_type_nt_length,
2698 { "(Token) Length", "quic.frame_type.nt.length",
2699 FT_UINT64, BASE_DEC, NULL, 0x0,
2700 "Specifying the length of the token", HFILL }
2702 { &hf_quic_frame_type_nt_token,
2703 { "Token", "quic.frame_type.nt.token",
2704 FT_BYTES, BASE_NONE, NULL, 0x0,
2705 "An opaque blob that the client may use with a future Initial packet", HFILL }
2709 { &hf_quic_frame_type_ae_largest_acknowledged,
2710 { "Largest Acknowledged", "quic.frame_type.ae.largest_acknowledged",
2711 FT_UINT64, BASE_DEC, NULL, 0x0,
2712 "Representing the largest packet number the peer is acknowledging in this packet", HFILL }
2714 { &hf_quic_frame_type_ae_ack_delay,
2715 { "ACK Delay", "quic.frame_type.ae.ack_delay",
2716 FT_UINT64, BASE_DEC, NULL, 0x0,
2717 "The time from when the largest acknowledged packet, as indicated in the Largest Acknowledged field, was received by this peer to when this ACK was sent", HFILL }
2719 { &hf_quic_frame_type_ae_ect0_count,
2720 { "ECT(0) Count", "quic.frame_type.ae.ect0_count",
2721 FT_UINT64, BASE_DEC, NULL, 0x0,
2722 "Representing the total number packets received with the ECT(0) codepoint", HFILL }
2724 { &hf_quic_frame_type_ae_ect1_count,
2725 { "ECT(1) Count", "quic.frame_type.ae.ect1_count",
2726 FT_UINT64, BASE_DEC, NULL, 0x0,
2727 "Representing the total number packets received with the ECT(1) codepoint", HFILL }
2729 { &hf_quic_frame_type_ae_ecn_ce_count,
2730 { "CE Count", "quic.frame_type.ae.ecn_ce_count",
2731 FT_UINT64, BASE_DEC, NULL, 0x0,
2732 "Representing the total number packets received with the CE codepoint", HFILL }
2734 { &hf_quic_frame_type_ae_ack_block_count,
2735 { "ACK Block Count", "quic.frame_type.ae.ack_block_count",
2736 FT_UINT64, BASE_DEC, NULL, 0x0,
2737 "The number of Additional ACK Block (and Gap) fields after the First ACK Block", HFILL }
2739 { &hf_quic_frame_type_ae_fab,
2740 { "First ACK Block", "quic.frame_type.ack.fab",
2741 FT_UINT64, BASE_DEC, NULL, 0x0,
2742 "Indicates the number of contiguous additional packets being acknowledged starting at the Largest Acknowledged", HFILL }
2744 { &hf_quic_frame_type_ae_gap,
2745 { "Gap", "quic.frame_type.ae.gap",
2746 FT_UINT64, BASE_DEC, NULL, 0x0,
2747 "Indicating the number of contiguous unacknowledged packets preceding the packet number one lower than the smallest in the preceding ACK Block", HFILL }
2749 { &hf_quic_frame_type_ae_ack_block,
2750 { "ACK Block", "quic.frame_type.ae.ack_block",
2751 FT_UINT64, BASE_DEC, NULL, 0x0,
2752 "Indicating the number of contiguous acknowledged packets preceding the largest packet number, as determined by the preceding Gap", HFILL }
2756 static gint *ett[] = {
2758 &ett_quic_connection_info,
2763 static ei_register_info ei[] = {
2764 { &ei_quic_connection_unknown,
2765 { "quic.connection.unknown", PI_PROTOCOL, PI_NOTE,
2766 "Unknown QUIC connection. Missing Initial Packet or migrated connection?", EXPFILL }
2768 { &ei_quic_ft_unknown,
2769 { "quic.ft.unknown", PI_UNDECODED, PI_NOTE,
2770 "Unknown Frame Type", EXPFILL }
2772 { &ei_quic_decryption_failed,
2773 { "quic.decryption_failed", PI_DECRYPTION, PI_WARN,
2774 "Failed to decrypt handshake", EXPFILL }
2776 { &ei_quic_protocol_violation,
2777 { "quic.protocol_violation", PI_PROTOCOL, PI_WARN,
2778 "Invalid data according to the protocol", EXPFILL }
2782 proto_quic = proto_register_protocol("QUIC IETF", "QUIC", "quic");
2784 proto_register_field_array(proto_quic, hf, array_length(hf));
2785 proto_register_subtree_array(ett, array_length(ett));
2787 expert_quic = expert_register_protocol(proto_quic);
2788 expert_register_field_array(expert_quic, ei, array_length(ei));
2790 quic_handle = register_dissector("quic", dissect_quic, proto_quic);
2792 register_init_routine(quic_init);
2793 register_cleanup_routine(quic_cleanup);
2797 proto_reg_handoff_quic(void)
2799 tls13_handshake_handle = find_dissector("tls13-handshake");
2800 dissector_add_uint_with_preference("udp.port", 0, quic_handle);
2801 heur_dissector_add("udp", dissect_quic_heur, "QUIC", "quic", proto_quic, HEURISTIC_ENABLE);
2805 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2810 * indent-tabs-mode: nil
2813 * vi: set shiftwidth=4 tabstop=8 expandtab:
2814 * :indentSize=4:tabSize=8:noTabs=true: