Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-gquic.c
blobfd227719f5773385e659730c54cfb4591b120431
1 /* packet-gquic.c
2 * Routines for (Google) Quick UDP Internet Connections dissection
3 * Copyright 2013, Alexis La Goutte <alexis.lagoutte at gmail dot com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 QUIC Wire Layout Specification : https://docs.google.com/document/d/1WJvyZflAO2pq77yOLbp9NsGjC1CHetAXV8I0fQe-B_U/
15 QUIC Crypto : https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/
17 QUIC source code in Chromium : https://code.google.com/p/chromium/codesearch#chromium/src/net/quic/quic_utils.h&sq=package:chromium
20 #include "config.h"
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/expert.h>
25 #include <epan/conversation.h>
26 #include <epan/tfs.h>
27 #include "packet-http2.h"
28 #include "packet-quic.h"
29 #include <wsutil/strtoi.h>
31 void proto_register_gquic(void);
32 void proto_reg_handoff_gquic(void);
34 static dissector_handle_t gquic_handle;
35 static dissector_handle_t tls13_handshake_handle;
36 static dissector_handle_t quic_handle;
38 static int proto_gquic;
39 static int hf_gquic_header_form;
40 static int hf_gquic_fixed_bit;
41 static int hf_gquic_long_packet_type;
42 static int hf_gquic_long_reserved;
43 static int hf_gquic_packet_number_length;
44 static int hf_gquic_dcil;
45 static int hf_gquic_scil;
46 static int hf_gquic_puflags;
47 static int hf_gquic_puflags_vrsn;
48 static int hf_gquic_puflags_rst;
49 static int hf_gquic_puflags_dnonce;
50 static int hf_gquic_puflags_cid;
51 static int hf_gquic_puflags_cid_old;
52 static int hf_gquic_puflags_pkn;
53 static int hf_gquic_puflags_mpth;
54 static int hf_gquic_puflags_rsv;
55 static int hf_gquic_cid;
56 static int hf_gquic_version;
57 static int hf_gquic_diversification_nonce;
58 static int hf_gquic_packet_number;
59 static int hf_gquic_prflags;
60 static int hf_gquic_prflags_entropy;
61 static int hf_gquic_prflags_fecg;
62 static int hf_gquic_prflags_fec;
63 static int hf_gquic_prflags_rsv;
64 static int hf_gquic_message_authentication_hash;
65 static int hf_gquic_frame;
66 static int hf_gquic_frame_type;
67 static int hf_gquic_frame_type_padding_length;
68 static int hf_gquic_frame_type_padding;
69 static int hf_gquic_frame_type_rsts_stream_id;
70 static int hf_gquic_frame_type_rsts_byte_offset;
71 static int hf_gquic_frame_type_rsts_error_code;
72 static int hf_gquic_frame_type_cc_error_code;
73 static int hf_gquic_frame_type_cc_reason_phrase_length;
74 static int hf_gquic_frame_type_cc_reason_phrase;
75 static int hf_gquic_frame_type_goaway_error_code;
76 static int hf_gquic_frame_type_goaway_last_good_stream_id;
77 static int hf_gquic_frame_type_goaway_reason_phrase_length;
78 static int hf_gquic_frame_type_goaway_reason_phrase;
79 static int hf_gquic_frame_type_wu_stream_id;
80 static int hf_gquic_frame_type_wu_byte_offset;
81 static int hf_gquic_frame_type_blocked_stream_id;
82 static int hf_gquic_frame_type_sw_send_entropy;
83 static int hf_gquic_frame_type_sw_least_unacked_delta;
84 static int hf_gquic_crypto_offset;
85 static int hf_gquic_crypto_length;
86 static int hf_gquic_crypto_crypto_data;
87 static int hf_gquic_frame_type_stream;
88 static int hf_gquic_frame_type_stream_f;
89 static int hf_gquic_frame_type_stream_d;
90 static int hf_gquic_frame_type_stream_ooo;
91 static int hf_gquic_frame_type_stream_ss;
92 /* ACK */
93 static int hf_gquic_frame_type_ack;
94 static int hf_gquic_frame_type_ack_n;
95 static int hf_gquic_frame_type_ack_u;
96 static int hf_gquic_frame_type_ack_t;
97 static int hf_gquic_frame_type_ack_ll;
98 static int hf_gquic_frame_type_ack_mm;
99 /* ACK Before Q034 */
100 static int hf_gquic_frame_type_ack_received_entropy;
101 static int hf_gquic_frame_type_ack_largest_observed;
102 static int hf_gquic_frame_type_ack_ack_delay_time;
103 static int hf_gquic_frame_type_ack_num_timestamp;
104 static int hf_gquic_frame_type_ack_delta_largest_observed;
105 static int hf_gquic_frame_type_ack_first_timestamp;
106 static int hf_gquic_frame_type_ack_time_since_previous_timestamp;
107 static int hf_gquic_frame_type_ack_num_ranges;
108 static int hf_gquic_frame_type_ack_missing_packet;
109 static int hf_gquic_frame_type_ack_range_length;
110 static int hf_gquic_frame_type_ack_num_revived;
111 static int hf_gquic_frame_type_ack_revived_packet;
112 /* ACK After Q034 */
113 static int hf_gquic_frame_type_ack_largest_acked;
114 static int hf_gquic_frame_type_ack_largest_acked_delta_time;
115 static int hf_gquic_frame_type_ack_num_blocks;
116 static int hf_gquic_frame_type_ack_first_ack_block_length;
117 static int hf_gquic_frame_type_ack_gap_to_next_block;
118 static int hf_gquic_frame_type_ack_ack_block_length;
119 static int hf_gquic_frame_type_ack_delta_largest_acked;
120 static int hf_gquic_frame_type_ack_time_since_largest_acked;
121 static int hf_gquic_stream_id;
122 static int hf_gquic_offset;
123 static int hf_gquic_data_len;
124 static int hf_gquic_tag;
125 static int hf_gquic_tags;
126 static int hf_gquic_tag_number;
127 static int hf_gquic_tag_value;
128 static int hf_gquic_tag_type;
129 static int hf_gquic_tag_offset_end;
130 static int hf_gquic_tag_length;
131 static int hf_gquic_tag_sni;
132 static int hf_gquic_tag_pad;
133 static int hf_gquic_tag_ver;
134 static int hf_gquic_tag_ccs;
135 static int hf_gquic_tag_pdmd;
136 static int hf_gquic_tag_uaid;
137 static int hf_gquic_tag_stk;
138 static int hf_gquic_tag_sno;
139 static int hf_gquic_tag_prof;
140 static int hf_gquic_tag_scfg;
141 static int hf_gquic_tag_scfg_number;
142 static int hf_gquic_tag_rrej;
143 static int hf_gquic_tag_crt;
144 static int hf_gquic_tag_aead;
145 static int hf_gquic_tag_scid;
146 static int hf_gquic_tag_pubs;
147 static int hf_gquic_tag_kexs;
148 static int hf_gquic_tag_obit;
149 static int hf_gquic_tag_expy;
150 static int hf_gquic_tag_nonc;
151 static int hf_gquic_tag_mspc;
152 static int hf_gquic_tag_tcid;
153 static int hf_gquic_tag_srbf;
154 static int hf_gquic_tag_icsl;
155 static int hf_gquic_tag_scls;
156 static int hf_gquic_tag_copt;
157 static int hf_gquic_tag_ccrt;
158 static int hf_gquic_tag_irtt;
159 static int hf_gquic_tag_cfcw;
160 static int hf_gquic_tag_sfcw;
161 static int hf_gquic_tag_cetv;
162 static int hf_gquic_tag_xlct;
163 static int hf_gquic_tag_nonp;
164 static int hf_gquic_tag_csct;
165 static int hf_gquic_tag_ctim;
166 static int hf_gquic_tag_mids;
167 static int hf_gquic_tag_fhol;
168 static int hf_gquic_tag_sttl;
169 static int hf_gquic_tag_smhl;
170 static int hf_gquic_tag_tbkp;
171 static int hf_gquic_tag_mad0;
172 static int hf_gquic_tag_qlve;
173 static int hf_gquic_tag_cgst;
174 static int hf_gquic_tag_epid;
175 static int hf_gquic_tag_srst;
177 /* Public Reset Tags */
178 static int hf_gquic_tag_rnon;
179 static int hf_gquic_tag_rseq;
180 static int hf_gquic_tag_cadr_addr_type;
181 static int hf_gquic_tag_cadr_addr_ipv4;
182 static int hf_gquic_tag_cadr_addr_ipv6;
183 static int hf_gquic_tag_cadr_addr;
184 static int hf_gquic_tag_cadr_port;
186 static int hf_gquic_tag_unknown;
188 static int hf_gquic_padding;
189 static int hf_gquic_stream_data;
190 static int hf_gquic_payload;
192 #define QUIC_PORT_RANGE "80,443"
193 static bool g_gquic_debug;
195 static int ett_gquic;
196 static int ett_gquic_puflags;
197 static int ett_gquic_prflags;
198 static int ett_gquic_ft;
199 static int ett_gquic_ftflags;
200 static int ett_gquic_tag_value;
202 static expert_field ei_gquic_tag_undecoded;
203 static expert_field ei_gquic_tag_length;
204 static expert_field ei_gquic_tag_unknown;
205 static expert_field ei_gquic_version_invalid;
206 static expert_field ei_gquic_invalid_parameter;
207 static expert_field ei_gquic_length_invalid;
208 static expert_field ei_gquic_data_invalid;
210 static const value_string gquic_short_long_header_vals[] = {
211 { 0, "Short Header" },
212 { 1, "Long Header" },
213 { 0, NULL }
215 static const value_string gquic_long_packet_type_vals[] = {
216 { 0, "Initial" },
217 { 2, "Handshake" },
218 { 1, "0-RTT" },
219 { 0, NULL }
221 static const value_string gquic_packet_number_lengths[] = {
222 { 0, "1 bytes" },
223 { 1, "2 bytes" },
224 { 2, "3 bytes" },
225 { 3, "4 bytes" },
226 { 0, NULL }
228 static const value_string quic_cid_lengths[] = {
229 { 0, "0 bytes" },
230 { 5, "8 bytes" },
231 { 0, NULL }
234 #define GQUIC_MIN_LENGTH 3
235 #define GQUIC_MAGIC2 0x513032
236 #define GQUIC_MAGIC3 0x513033
237 #define GQUIC_MAGIC4 0x513034
239 #define GQUIC_VERSION_Q046 0x51303436
241 /**************************************************************************/
242 /* Public Flags */
243 /**************************************************************************/
244 #define PUFLAGS_VRSN 0x01
245 #define PUFLAGS_RST 0x02
246 #define PUFLAGS_DNONCE 0x04
247 #define PUFLAGS_CID 0x08
248 #define PUFLAGS_CID_OLD 0x0C
249 #define PUFLAGS_PKN 0x30
250 #define PUFLAGS_MPTH 0x40
251 #define PUFLAGS_RSV 0x80
253 static const true_false_string puflags_cid_tfs = {
254 "8 Bytes",
255 "0 Byte"
258 static const value_string puflags_cid_old_vals[] = {
259 { 0, "0 Byte" },
260 { 1, "1 Bytes" },
261 { 2, "4 Bytes" },
262 { 3, "8 Bytes" },
263 { 0, NULL }
266 static const value_string puflags_pkn_vals[] = {
267 { 0, "1 Byte" },
268 { 1, "2 Bytes" },
269 { 2, "4 Bytes" },
270 { 3, "6 Bytes" },
271 { 0, NULL }
274 /**************************************************************************/
275 /* Private Flags */
276 /**************************************************************************/
277 #define PRFLAGS_ENTROPY 0x01
278 #define PRFLAGS_FECG 0x02
279 #define PRFLAGS_FEC 0x04
280 #define PRFLAGS_RSV 0xF8
283 /**************************************************************************/
284 /* Frame Type Regular */
285 /**************************************************************************/
286 #define FT_PADDING 0x00
287 #define FT_RST_STREAM 0x01
288 #define FT_CONNECTION_CLOSE 0x02
289 #define FT_GOAWAY 0x03
290 #define FT_WINDOW_UPDATE 0x04
291 #define FT_BLOCKED 0x05
292 #define FT_STOP_WAITING 0x06
293 #define FT_PING 0x07
294 /* CRYPTO is not a real GQUIC frame, but a QUIC one. Since some GQUIC flows
295 * have this kind of frame, try handling it like all the others */
296 #define FT_CRYPTO 0x08
298 /**************************************************************************/
299 /* Frame Type Special */
300 /**************************************************************************/
301 #define FTFLAGS_SPECIAL 0xE0
303 #define FTFLAGS_STREAM 0x80
304 #define FTFLAGS_STREAM_F 0x40
305 #define FTFLAGS_STREAM_D 0x20
306 #define FTFLAGS_STREAM_OOO 0x1C
307 #define FTFLAGS_STREAM_SS 0x03
309 #define FTFLAGS_ACK 0x40
310 #define FTFLAGS_ACK_N 0x20
311 #define FTFLAGS_ACK_U 0x10
312 #define FTFLAGS_ACK_T 0x10
313 #define FTFLAGS_ACK_LL 0x0C
314 #define FTFLAGS_ACK_MM 0x03
316 static const range_string frame_type_vals[] = {
317 { 0,0, "PADDING" },
318 { 1,1, "RST_STREAM" },
319 { 2,2, "CONNECTION_CLOSE" },
320 { 3,3, "GOAWAY" },
321 { 4,4, "WINDOW_UPDATE" },
322 { 5,5, "BLOCKED" },
323 { 6,6, "STOP_WAITING" },
324 { 7,7, "PING" },
325 { 8,8, "CRYPTO" },
326 { 9,31, "Unknown" },
327 { 32,63, "CONGESTION_FEEDBACK (Special Frame Type)" },
328 { 64,127, "ACK (Special Frame Type)" },
329 { 128,256, "STREAM (Special Frame Type)" },
330 { 0,0, NULL }
333 static const value_string len_offset_vals[] = {
334 { 0, "0 Byte" },
335 { 1, "2 Bytes" },
336 { 2, "3 Bytes" },
337 { 3, "4 Bytes" },
338 { 4, "5 Bytes" },
339 { 5, "6 Bytes" },
340 { 6, "7 Bytes" },
341 { 7, "8 Bytes" },
342 { 0, NULL }
345 static const value_string len_stream_vals[] = {
346 { 0, "1 Byte" },
347 { 1, "2 Bytes" },
348 { 2, "3 Bytes" },
349 { 3, "4 Bytes" },
350 { 0, NULL }
353 static const true_false_string len_data_vals = {
354 "2 Bytes",
355 "0 Byte"
358 static const value_string len_largest_observed_vals[] = {
359 { 0, "1 Byte" },
360 { 1, "2 Bytes" },
361 { 2, "4 Bytes" },
362 { 3, "6 Bytes" },
363 { 0, NULL }
366 static const value_string len_missing_packet_vals[] = {
367 { 0, "1 Byte" },
368 { 1, "2 Bytes" },
369 { 2, "4 Bytes" },
370 { 3, "6 Bytes" },
371 { 0, NULL }
375 /**************************************************************************/
376 /* Message tag */
377 /**************************************************************************/
379 #define MTAG_CHLO 0x43484C4F
380 #define MTAG_SHLO 0x53484C4F
381 #define MTAG_REJ 0x52454A00
382 #define MTAG_PRST 0x50525354
384 static const value_string message_tag_vals[] = {
385 { MTAG_CHLO, "Client Hello" },
386 { MTAG_SHLO, "Server Hello" },
387 { MTAG_REJ, "Rejection" },
388 { MTAG_PRST, "Public Reset" },
389 { 0, NULL }
392 /**************************************************************************/
393 /* Tag */
394 /**************************************************************************/
395 /* See https://chromium.googlesource.com/chromium/src.git/+/master/net/third_party/quic/core/crypto/crypto_protocol.h */
397 #define TAG_PAD 0x50414400
398 #define TAG_SNI 0x534E4900
399 #define TAG_VER 0x56455200
400 #define TAG_CCS 0x43435300
401 #define TAG_UAID 0x55414944
402 #define TAG_PDMD 0x50444d44
403 #define TAG_STK 0x53544b00
404 #define TAG_SNO 0x534E4F00
405 #define TAG_PROF 0x50524F46
406 #define TAG_SCFG 0x53434647
407 #define TAG_RREJ 0x5252454A
408 #define TAG_CRT 0x435254FF
409 #define TAG_AEAD 0x41454144
410 #define TAG_SCID 0x53434944
411 #define TAG_PUBS 0x50554253
412 #define TAG_KEXS 0x4B455853
413 #define TAG_OBIT 0x4F424954
414 #define TAG_EXPY 0x45585059
415 #define TAG_NONC 0x4E4F4E43
416 #define TAG_MSPC 0x4D535043
417 #define TAG_TCID 0x54434944
418 #define TAG_SRBF 0x53524246
419 #define TAG_ICSL 0x4943534C
420 #define TAG_SCLS 0x53434C53
421 #define TAG_COPT 0x434F5054
422 #define TAG_CCRT 0x43435254
423 #define TAG_IRTT 0x49525454
424 #define TAG_CFCW 0x43464357
425 #define TAG_SFCW 0x53464357
426 #define TAG_CETV 0x43455456
427 #define TAG_XLCT 0x584C4354
428 #define TAG_NONP 0x4E4F4E50
429 #define TAG_CSCT 0x43534354
430 #define TAG_CTIM 0x4354494D
431 #define TAG_MIDS 0x4D494453
432 #define TAG_FHOL 0x46484F4C
433 #define TAG_STTL 0x5354544C
434 #define TAG_SMHL 0x534D484C
435 #define TAG_TBKP 0x54424B50
436 #define TAG_MAD0 0x4d414400
437 #define TAG_QLVE 0x514C5645
438 #define TAG_CGST 0x43475354
439 #define TAG_EPID 0x45504944
440 #define TAG_SRST 0x53525354
442 /* Public Reset Tag */
443 #define TAG_RNON 0x524E4F4E
444 #define TAG_RSEQ 0x52534551
445 #define TAG_CADR 0x43414452
447 static const value_string tag_vals[] = {
448 { TAG_PAD, "Padding" },
449 { TAG_SNI, "Server Name Indication" },
450 { TAG_VER, "Version" },
451 { TAG_CCS, "Common Certificate Sets" },
452 { TAG_UAID, "Client's User Agent ID" },
453 { TAG_PDMD, "Proof Demand" },
454 { TAG_STK, "Source Address Token" },
455 { TAG_SNO, "Server nonce" },
456 { TAG_PROF, "Proof (Signature)" },
457 { TAG_SCFG, "Server Config" },
458 { TAG_RREJ, "Reasons for server sending" },
459 { TAG_CRT, "Certificate chain" },
460 { TAG_AEAD, "Authenticated encryption algorithms" },
461 { TAG_SCID, "Server config ID" },
462 { TAG_PUBS, "Public value" },
463 { TAG_KEXS, "Key exchange algorithms" },
464 { TAG_OBIT, "Server Orbit" },
465 { TAG_EXPY, "Expiry" },
466 { TAG_NONC, "Client Nonce" },
467 { TAG_MSPC, "Max streams per connection" },
468 { TAG_TCID, "Connection ID truncation" },
469 { TAG_SRBF, "Socket receive buffer" },
470 { TAG_ICSL, "Idle connection state" },
471 { TAG_SCLS, "Silently close on timeout" },
472 { TAG_COPT, "Connection options" },
473 { TAG_CCRT, "Cached certificates" },
474 { TAG_IRTT, "Estimated initial RTT" },
475 { TAG_CFCW, "Initial session/connection" },
476 { TAG_SFCW, "Initial stream flow control" },
477 { TAG_CETV, "Client encrypted tag-value" },
478 { TAG_XLCT, "Expected leaf certificate" },
479 { TAG_NONP, "Client Proof Nonce" },
480 { TAG_CSCT, "Signed cert timestamp (RFC6962) of leaf cert" },
481 { TAG_CTIM, "Client Timestamp" },
482 { TAG_MIDS, "Max incoming dynamic streams" },
483 { TAG_FHOL, "Force Head Of Line blocking" },
484 { TAG_STTL, "Server Config TTL" },
485 { TAG_SMHL, "Support Max Header List (size)" },
486 { TAG_TBKP, "Token Binding Key Params" },
487 { TAG_MAD0, "Max Ack Delay (IETF QUIC)" },
488 { TAG_QLVE, "Legacy Version Encapsulation" },
489 { TAG_CGST, "Congestion Control Feedback Type" },
490 { TAG_EPID, "Endpoint Identifier" },
491 { TAG_SRST, "Stateless Reset Token" },
493 { TAG_RNON, "Public Reset Nonce Proof" },
494 { TAG_RSEQ, "Rejected Packet Number" },
495 { TAG_CADR, "Client Address" },
496 { 0, NULL }
500 /**************************************************************************/
501 /* AEAD Tag */
502 /**************************************************************************/
504 #define AEAD_AESG 0x41455347
505 #define AEAD_S20P 0x53323050
506 #define AEAD_CC12 0x43433132
508 static const value_string tag_aead_vals[] = {
509 { AEAD_AESG, "AES-GCM with a 12-byte tag and IV" },
510 { AEAD_S20P, "Salsa20 with Poly1305" },
511 { AEAD_CC12, "ChaCha12 with Poly1305" },
512 { 0, NULL }
515 /**************************************************************************/
516 /* KEXS Tag */
517 /**************************************************************************/
519 #define KEXS_C255 0x43323535
520 #define KEXS_P256 0x50323536
522 static const value_string tag_kexs_vals[] = {
523 { KEXS_C255, "Curve25519" },
524 { KEXS_P256, "P-256" },
525 { 0, NULL }
528 /**************************************************************************/
529 /* Client Address Type */
530 /**************************************************************************/
532 static const value_string cadr_type_vals[] = {
533 { 2, "IPv4" },
534 { 10, "IPv6" },
535 { 0, NULL }
538 /**************************************************************************/
539 /* Error Code */
540 /**************************************************************************/
541 /* See https://chromium.googlesource.com/chromium/src.git/+/master/net/third_party/quic/core/quic_error_codes.h */
543 enum QuicErrorCode {
544 QUIC_NO_ERROR = 0,
545 /* Connection has reached an invalid state. */
546 QUIC_INTERNAL_ERROR = 1,
547 /* There were data frames after the a fin or reset. */
548 QUIC_STREAM_DATA_AFTER_TERMINATION = 2,
549 /* Control frame is malformed. */
550 QUIC_INVALID_PACKET_HEADER = 3,
551 /* Frame data is malformed. */
552 QUIC_INVALID_FRAME_DATA = 4,
553 /* The packet contained no payload. */
554 QUIC_MISSING_PAYLOAD = 48,
555 /* FEC data is malformed. */
556 QUIC_INVALID_FEC_DATA = 5,
557 /* STREAM frame data is malformed. */
558 QUIC_INVALID_STREAM_DATA = 46,
559 /* STREAM frame data overlaps with buffered data. */
560 QUIC_OVERLAPPING_STREAM_DATA = 87,
561 /* STREAM frame data is not encrypted. */
562 QUIC_UNENCRYPTED_STREAM_DATA = 61,
563 /* Attempt to send unencrypted STREAM frame. */
564 QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA = 88,
565 /* Received a frame which is likely the result of memory corruption. */
566 QUIC_MAYBE_CORRUPTED_MEMORY = 89,
567 /* FEC frame data is not encrypted. */
568 QUIC_UNENCRYPTED_FEC_DATA = 77,
569 /* RST_STREAM frame data is malformed. */
570 QUIC_INVALID_RST_STREAM_DATA = 6,
571 /* CONNECTION_CLOSE frame data is malformed. */
572 QUIC_INVALID_CONNECTION_CLOSE_DATA = 7,
573 /* GOAWAY frame data is malformed. */
574 QUIC_INVALID_GOAWAY_DATA = 8,
575 /* WINDOW_UPDATE frame data is malformed. */
576 QUIC_INVALID_WINDOW_UPDATE_DATA = 57,
577 /* BLOCKED frame data is malformed. */
578 QUIC_INVALID_BLOCKED_DATA = 58,
579 /* STOP_WAITING frame data is malformed. */
580 QUIC_INVALID_STOP_WAITING_DATA = 60,
581 /* PATH_CLOSE frame data is malformed. */
582 QUIC_INVALID_PATH_CLOSE_DATA = 78,
583 /* ACK frame data is malformed. */
584 QUIC_INVALID_ACK_DATA = 9,
585 /* deprecated: */
586 QUIC_INVALID_CONGESTION_FEEDBACK_DATA = 47,
587 /* Version negotiation packet is malformed. */
588 QUIC_INVALID_VERSION_NEGOTIATION_PACKET = 10,
589 /* Public RST packet is malformed. */
590 QUIC_INVALID_PUBLIC_RST_PACKET = 11,
591 /* There was an error decrypting. */
592 QUIC_DECRYPTION_FAILURE = 12,
593 /* There was an error encrypting. */
594 QUIC_ENCRYPTION_FAILURE = 13,
595 /* The packet exceeded kMaxPacketSize. */
596 QUIC_PACKET_TOO_LARGE = 14,
597 /* Data was sent for a stream which did not exist. */
598 QUIC_PACKET_FOR_NONEXISTENT_STREAM = 15,
599 /* The peer is going away. May be a client or server. */
600 QUIC_PEER_GOING_AWAY = 16,
601 /* A stream ID was invalid. */
602 QUIC_INVALID_STREAM_ID = 17,
603 /* A priority was invalid. */
604 QUIC_INVALID_PRIORITY = 49,
605 /* Too many streams already open. */
606 QUIC_TOO_MANY_OPEN_STREAMS = 18,
607 /* The peer created too many available streams. */
608 QUIC_TOO_MANY_AVAILABLE_STREAMS = 76,
609 /* The peer must send a FIN/RST for each stream, and has not been doing so. */
610 QUIC_TOO_MANY_UNFINISHED_STREAMS = 66,
611 /* Received public reset for this connection. */
612 QUIC_PUBLIC_RESET = 19,
613 /* Invalid protocol version. */
614 QUIC_INVALID_VERSION = 20,
615 /* deprecated: */
616 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED = 21,
617 /* The Header ID for a stream was too far from the previous. */
618 QUIC_INVALID_HEADER_ID = 22,
619 /* Negotiable parameter received during handshake had invalid value. */
620 QUIC_INVALID_NEGOTIATED_VALUE = 23,
621 /* There was an error decompressing data. */
622 QUIC_DECOMPRESSION_FAILURE = 24,
623 /* We hit our prenegotiated (or default) timeout */
624 QUIC_CONNECTION_TIMED_OUT = 25,
625 /* We hit our overall connection timeout */
626 QUIC_CONNECTION_OVERALL_TIMED_OUT = 67,
627 /* There was an error encountered migrating addresses */
628 QUIC_ERROR_MIGRATING_ADDRESS = 26,
629 /* There was an error encountered migrating port only. */
630 QUIC_ERROR_MIGRATING_PORT = 86,
631 /* There was an error while writing to the socket. */
632 QUIC_PACKET_WRITE_ERROR = 27,
633 /* There was an error while reading from the socket. */
634 QUIC_PACKET_READ_ERROR = 51,
635 /* We received a STREAM_FRAME with no data and no fin flag set. */
636 QUIC_INVALID_STREAM_FRAME = 50,
637 /* We received invalid data on the headers stream. */
638 QUIC_INVALID_HEADERS_STREAM_DATA = 56,
639 /* Invalid data on the headers stream received because of decompression failure. */
640 QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE = 97,
641 /* The peer received too much data, violating flow control. */
642 QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA = 59,
643 /* The peer sent too much data, violating flow control. */
644 QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA = 63,
645 /* The peer received an invalid flow control window. */
646 QUIC_FLOW_CONTROL_INVALID_WINDOW = 64,
647 /* The connection has been IP pooled into an existing connection. */
648 QUIC_CONNECTION_IP_POOLED = 62,
649 /* The connection has too many outstanding sent packets. */
650 QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS = 68,
651 /* The connection has too many outstanding received packets. */
652 QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS = 69,
653 /* The quic connection job to load server config is cancelled. */
654 QUIC_CONNECTION_CANCELLED = 70,
655 /* Disabled QUIC because of high packet loss rate. */
656 QUIC_BAD_PACKET_LOSS_RATE = 71,
657 /* Disabled QUIC because of too many PUBLIC_RESETs post handshake. */
658 QUIC_PUBLIC_RESETS_POST_HANDSHAKE = 73,
659 /* Disabled QUIC because of too many timeouts with streams open. */
660 QUIC_TIMEOUTS_WITH_OPEN_STREAMS = 74,
661 /* Closed because we failed to serialize a packet. */
662 QUIC_FAILED_TO_SERIALIZE_PACKET = 75,
663 /* QUIC timed out after too many RTOs. */
664 QUIC_TOO_MANY_RTOS = 85,
666 /* Crypto errors. */
667 /* Handshake failed. */
668 QUIC_HANDSHAKE_FAILED = 28,
669 /* Handshake message contained out of order tags. */
670 QUIC_CRYPTO_TAGS_OUT_OF_ORDER = 29,
671 /* Handshake message contained too many entries. */
672 QUIC_CRYPTO_TOO_MANY_ENTRIES = 30,
673 /* Handshake message contained an invalid value length. */
674 QUIC_CRYPTO_INVALID_VALUE_LENGTH = 31,
675 /* A crypto message was received after the handshake was complete. */
676 QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE = 32,
677 /* A crypto message was received with an illegal message tag. */
678 QUIC_INVALID_CRYPTO_MESSAGE_TYPE = 33,
679 /* A crypto message was received with an illegal parameter. */
680 QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER = 34,
681 /* An invalid channel id signature was supplied. */
682 QUIC_INVALID_CHANNEL_ID_SIGNATURE = 52,
683 /* A crypto message was received with a mandatory parameter missing. */
684 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND = 35,
685 /* A crypto message was received with a parameter that has no overlap
686 with the local parameter. */
687 QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP = 36,
688 /* A crypto message was received that contained a parameter with too few
689 values. */
690 QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND = 37,
691 /* A demand for an unsupport proof type was received. */
692 QUIC_UNSUPPORTED_PROOF_DEMAND = 94,
693 /* An internal error occurred in crypto processing. */
694 QUIC_CRYPTO_INTERNAL_ERROR = 38,
695 /* A crypto handshake message specified an unsupported version. */
696 QUIC_CRYPTO_VERSION_NOT_SUPPORTED = 39,
697 /* A crypto handshake message resulted in a stateless reject. */
698 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT = 72,
699 /* There was no intersection between the crypto primitives supported by the
700 peer and ourselves. */
701 QUIC_CRYPTO_NO_SUPPORT = 40,
702 /* The server rejected our client hello messages too many times. */
703 QUIC_CRYPTO_TOO_MANY_REJECTS = 41,
704 /* The client rejected the server's certificate chain or signature. */
705 QUIC_PROOF_INVALID = 42,
706 /* A crypto message was received with a duplicate tag. */
707 QUIC_CRYPTO_DUPLICATE_TAG = 43,
708 /* A crypto message was received with the wrong encryption level (i.e. it
709 should have been encrypted but was not. ) */
710 QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT = 44,
711 /* The server config for a server has expired. */
712 QUIC_CRYPTO_SERVER_CONFIG_EXPIRED = 45,
713 /* We failed to setup the symmetric keys for a connection. */
714 QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED = 53,
715 /* A handshake message arrived, but we are still validating the
716 previous handshake message. */
717 QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO = 54,
718 /* A server config update arrived before the handshake is complete. */
719 QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE = 65,
720 /* CHLO cannot fit in one packet. */
721 QUIC_CRYPTO_CHLO_TOO_LARGE = 90,
722 /* This connection involved a version negotiation which appears to have been
723 tampered with. */
724 QUIC_VERSION_NEGOTIATION_MISMATCH = 55,
726 /* Multipath is not enabled, but a packet with multipath flag on is received. */
727 QUIC_BAD_MULTIPATH_FLAG = 79,
728 /* A path is supposed to exist but does not. */
729 QUIC_MULTIPATH_PATH_DOES_NOT_EXIST = 91,
730 /* A path is supposed to be active but is not. */
731 QUIC_MULTIPATH_PATH_NOT_ACTIVE = 92,
733 /* IP address changed causing connection close. */
734 QUIC_IP_ADDRESS_CHANGED = 80,
736 /* Connection migration errors. */
737 /* Network changed, but connection had no migratable streams. */
738 QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS = 81,
739 /* Connection changed networks too many times. */
740 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES = 82,
741 /* Connection migration was attempted, but there was no new network to migrate to. */
742 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK = 83,
743 /* Network changed, but connection had one or more non-migratable streams. */
744 QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM = 84,
745 /* Network changed, but connection migration was disabled by config. */
746 QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG = 99,
747 /* Network changed, but error was encountered on the alternative network. */
748 QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR = 100,
750 /* Stream frames arrived too discontiguously so that stream sequencer buffer maintains too many gaps. */
751 QUIC_TOO_MANY_FRAME_GAPS = 93,
753 /* Sequencer buffer get into weird state where continuing read/write will lead
754 to crash. */
755 QUIC_STREAM_SEQUENCER_INVALID_STATE = 95,
756 /* Connection closed because of server hits max number of sessions allowed. */
757 QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96,
759 /* Receive a RST_STREAM with offset larger than kMaxStreamLength. */
760 QUIC_STREAM_LENGTH_OVERFLOW = 98,
762 /* No error. Used as bound while iterating. */
763 QUIC_LAST_ERROR = 101
767 static const value_string error_code_vals[] = {
768 { QUIC_NO_ERROR, "There was no error" },
769 { QUIC_INTERNAL_ERROR, "Connection has reached an invalid state" },
770 { QUIC_STREAM_DATA_AFTER_TERMINATION, "There were data frames after the a fin or reset" },
771 { QUIC_INVALID_PACKET_HEADER, "Control frame is malformed" },
772 { QUIC_INVALID_FRAME_DATA, "Frame data is malformed" },
773 { QUIC_INVALID_FEC_DATA, "FEC data is malformed" },
774 { QUIC_INVALID_RST_STREAM_DATA, "RST_STREAM frame data is malformed" },
775 { QUIC_INVALID_CONNECTION_CLOSE_DATA, "CONNECTION_CLOSE frame data is malformed" },
776 { QUIC_INVALID_GOAWAY_DATA, "GOAWAY frame data is malformed" },
777 { QUIC_INVALID_ACK_DATA, "ACK frame data is malformed" },
778 { QUIC_INVALID_VERSION_NEGOTIATION_PACKET, "Version negotiation packet is malformed" },
779 { QUIC_INVALID_PUBLIC_RST_PACKET, "Public RST packet is malformed" },
780 { QUIC_DECRYPTION_FAILURE, "There was an error decrypting" },
781 { QUIC_ENCRYPTION_FAILURE, "There was an error encrypting" },
782 { QUIC_PACKET_TOO_LARGE, "The packet exceeded kMaxPacketSize" },
783 { QUIC_PACKET_FOR_NONEXISTENT_STREAM, "Data was sent for a stream which did not exist" },
784 { QUIC_PEER_GOING_AWAY, "The peer is going away. May be a client or server" },
785 { QUIC_INVALID_STREAM_ID, "A stream ID was invalid" },
786 { QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams already open" },
787 { QUIC_PUBLIC_RESET, "Received public reset for this connection" },
788 { QUIC_INVALID_VERSION, "Invalid protocol version" },
789 { QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED, "Stream RST before Headers decompressed (Deprecated)" },
790 { QUIC_INVALID_HEADER_ID, "The Header ID for a stream was too far from the previous" },
791 { QUIC_INVALID_NEGOTIATED_VALUE, "Negotiable parameter received during handshake had invalid value" },
792 { QUIC_DECOMPRESSION_FAILURE, "There was an error decompressing data" },
793 { QUIC_CONNECTION_TIMED_OUT, "We hit our prenegotiated (or default) timeout" },
794 { QUIC_ERROR_MIGRATING_ADDRESS, "There was an error encountered migrating addresses" },
795 { QUIC_PACKET_WRITE_ERROR, "There was an error while writing to the socket" },
796 { QUIC_HANDSHAKE_FAILED, "Handshake failed" },
797 { QUIC_CRYPTO_TAGS_OUT_OF_ORDER, "Handshake message contained out of order tags" },
798 { QUIC_CRYPTO_TOO_MANY_ENTRIES, "Handshake message contained too many entries" },
799 { QUIC_CRYPTO_INVALID_VALUE_LENGTH, "Handshake message contained an invalid value length" },
800 { QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, "A crypto message was received after the handshake was complete" },
801 { QUIC_INVALID_CRYPTO_MESSAGE_TYPE, "A crypto message was received with an illegal message tag" },
802 { QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "A crypto message was received with an illegal parameter" },
803 { QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, "A crypto message was received with a mandatory parameter missing" },
804 { QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP, "A crypto message was received with a parameter that has no overlap with the local parameter" },
805 { QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND, "A crypto message was received that contained a parameter with too few values" },
806 { QUIC_CRYPTO_INTERNAL_ERROR, "An internal error occurred in crypto processing" },
807 { QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "A crypto handshake message specified an unsupported version" },
809 { QUIC_CRYPTO_NO_SUPPORT, "There was no intersection between the crypto primitives supported by the peer and ourselves" },
810 { QUIC_CRYPTO_TOO_MANY_REJECTS, "The server rejected our client hello messages too many times" },
811 { QUIC_PROOF_INVALID, "The client rejected the server's certificate chain or signature" },
812 { QUIC_CRYPTO_DUPLICATE_TAG, "A crypto message was received with a duplicate tag" },
813 { QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, "A crypto message was received with the wrong encryption level (i.e. it should have been encrypted but was not" },
814 { QUIC_CRYPTO_SERVER_CONFIG_EXPIRED, "The server config for a server has expired" },
815 { QUIC_INVALID_STREAM_DATA, "STREAM frame data is malformed" },
816 { QUIC_INVALID_CONGESTION_FEEDBACK_DATA, "Invalid congestion Feedback data (Deprecated)" },
817 { QUIC_MISSING_PAYLOAD, "The packet contained no payload" },
818 { QUIC_INVALID_PRIORITY, "A priority was invalid" },
819 { QUIC_INVALID_STREAM_FRAME, "We received a STREAM_FRAME with no data and no fin flag set" },
820 { QUIC_PACKET_READ_ERROR, "There was an error while reading from the socket" },
821 { QUIC_INVALID_CHANNEL_ID_SIGNATURE, "An invalid channel id signature was supplied" },
822 { QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, "We failed to setup the symmetric keys for a connection" },
823 { QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO, "A handshake message arrived, but we are still validating the previous handshake message" },
824 { QUIC_VERSION_NEGOTIATION_MISMATCH, "This connection involved a version negotiation which appears to have been tampered with" },
825 { QUIC_INVALID_HEADERS_STREAM_DATA, "We received invalid data on the headers stream" },
826 { QUIC_INVALID_WINDOW_UPDATE_DATA, "WINDOW_UPDATE frame data is malformed" },
827 { QUIC_INVALID_BLOCKED_DATA, "BLOCKED frame data is malformed" },
829 { QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, "The peer received too much data, violating flow control" },
830 { QUIC_INVALID_STOP_WAITING_DATA, "STOP_WAITING frame data is malformed" },
831 { QUIC_UNENCRYPTED_STREAM_DATA, "STREAM frame data is not encrypted" },
832 { QUIC_CONNECTION_IP_POOLED, "The connection has been IP pooled into an existing connection" },
833 { QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, "The peer sent too much data, violating flow control" },
834 { QUIC_FLOW_CONTROL_INVALID_WINDOW, "The peer received an invalid flow control window" },
835 { QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, "A server config update arrived before the handshake is complete" },
836 { QUIC_TOO_MANY_UNFINISHED_STREAMS, "The peer must send a FIN/RST for each stream, and has not been doing so" },
837 { QUIC_CONNECTION_OVERALL_TIMED_OUT, "We hit our overall connection timeout" },
838 { QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS, "The connection has too many outstanding sent packets" },
839 { QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS, "The connection has too many outstanding received packets" },
840 { QUIC_CONNECTION_CANCELLED, "The quic connection job to load server config is cancelled" },
841 { QUIC_BAD_PACKET_LOSS_RATE, "Disabled QUIC because of high packet loss rate" },
842 { QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "A crypto handshake message resulted in a stateless reject" },
843 { QUIC_PUBLIC_RESETS_POST_HANDSHAKE, "Disabled QUIC because of too many PUBLIC_RESETs post handshake" },
844 { QUIC_TIMEOUTS_WITH_OPEN_STREAMS, "Disabled QUIC because of too many timeouts with streams open" },
845 { QUIC_FAILED_TO_SERIALIZE_PACKET, "Closed because we failed to serialize a packet" },
846 { QUIC_TOO_MANY_AVAILABLE_STREAMS, "The peer created too many available streams" },
847 { QUIC_UNENCRYPTED_FEC_DATA, "FEC frame data is not encrypted" },
848 { QUIC_INVALID_PATH_CLOSE_DATA, "PATH_CLOSE frame data is malformed" },
849 { QUIC_BAD_MULTIPATH_FLAG, "Multipath is not enabled, but a packet with multipath flag on is received" },
850 { QUIC_IP_ADDRESS_CHANGED, "IP address changed causing connection close" },
851 { QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS, "Network changed, but connection had no migratable stream" },
852 { QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES, "Connection changed networks too many times" },
853 { QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK, "Connection migration was attempted, but there was no new network to migrate to" },
854 { QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM, "Network changed, but connection had one or more non-migratable streams" },
855 { QUIC_TOO_MANY_RTOS, "QUIC timed out after too many RTOs" },
856 { QUIC_ERROR_MIGRATING_PORT, "There was an error encountered migrating port only" },
857 { QUIC_OVERLAPPING_STREAM_DATA, "STREAM frame data overlaps with buffered data" },
858 { QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, "Attempt to send unencrypted STREAM frame" },
859 { QUIC_MAYBE_CORRUPTED_MEMORY, "Received a frame which is likely the result of memory corruption" },
860 { QUIC_CRYPTO_CHLO_TOO_LARGE, "CHLO cannot fit in one packet" },
861 { QUIC_MULTIPATH_PATH_DOES_NOT_EXIST, "A path is supposed to exist but does not" },
862 { QUIC_MULTIPATH_PATH_NOT_ACTIVE, "A path is supposed to be active but is not" },
863 { QUIC_TOO_MANY_FRAME_GAPS, "Stream frames arrived too discontiguously so that stream sequencer buffer maintains too many gaps" },
864 { QUIC_UNSUPPORTED_PROOF_DEMAND, "A demand for an unsupport proof type was received" },
865 { QUIC_STREAM_SEQUENCER_INVALID_STATE, "Sequencer buffer get into weird state where continuing read/write will lead to crash" },
866 { QUIC_TOO_MANY_SESSIONS_ON_SERVER, "Connection closed because of server hits max number of sessions allowed" },
867 { QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE, "Invalid data on the headers stream received because of decompression failure" },
868 { QUIC_STREAM_LENGTH_OVERFLOW, "Receive a RST_STREAM with offset larger than kMaxStreamLength" },
869 { QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG, "Network changed, but connection migration was disabled by config" },
870 { QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR, "Network changed, but error was encountered on the alternative network" },
871 { QUIC_LAST_ERROR, "No error. Used as bound while iterating" },
872 { 0, NULL }
875 static value_string_ext error_code_vals_ext = VALUE_STRING_EXT_INIT(error_code_vals);
877 /**************************************************************************/
878 /* RST Stream Error Code */
879 /**************************************************************************/
880 /* See https://chromium.googlesource.com/chromium/src.git/+/master/net/third_party/quic/core/quic_error_codes.h (enum QuicRstStreamErrorCode) */
882 enum QuicRstStreamErrorCode {
883 /* Complete response has been sent, sending a RST to ask the other endpoint to stop sending request data without discarding the response. */
885 QUIC_STREAM_NO_ERROR = 0,
886 /* There was some error which halted stream processing.*/
887 QUIC_ERROR_PROCESSING_STREAM,
888 /* We got two fin or reset offsets which did not match.*/
889 QUIC_MULTIPLE_TERMINATION_OFFSETS,
890 /* We got bad payload and can not respond to it at the protocol level. */
891 QUIC_BAD_APPLICATION_PAYLOAD,
892 /* Stream closed due to connection error. No reset frame is sent when this happens. */
893 QUIC_STREAM_CONNECTION_ERROR,
894 /* GoAway frame sent. No more stream can be created. */
895 QUIC_STREAM_PEER_GOING_AWAY,
896 /* The stream has been cancelled. */
897 QUIC_STREAM_CANCELLED,
898 /* Closing stream locally, sending a RST to allow for proper flow control accounting. Sent in response to a RST from the peer. */
899 QUIC_RST_ACKNOWLEDGEMENT,
900 /* Receiver refused to create the stream (because its limit on open streams has been reached). The sender should retry the request later (using another stream). */
901 QUIC_REFUSED_STREAM,
902 /* Invalid URL in PUSH_PROMISE request header. */
903 QUIC_INVALID_PROMISE_URL,
904 /* Server is not authoritative for this URL. */
905 QUIC_UNAUTHORIZED_PROMISE_URL,
906 /* Can't have more than one active PUSH_PROMISE per URL. */
907 QUIC_DUPLICATE_PROMISE_URL,
908 /* Vary check failed. */
909 QUIC_PROMISE_VARY_MISMATCH,
910 /* Only GET and HEAD methods allowed. */
911 QUIC_INVALID_PROMISE_METHOD,
912 /* The push stream is unclaimed and timed out. */
913 QUIC_PUSH_STREAM_TIMED_OUT,
914 /* Received headers were too large. */
915 QUIC_HEADERS_TOO_LARGE,
916 /* The data is not likely arrive in time. */
917 QUIC_STREAM_TTL_EXPIRED,
918 /* No error. Used as bound while iterating. */
919 QUIC_STREAM_LAST_ERROR,
922 static const value_string rststream_error_code_vals[] = {
923 { QUIC_STREAM_NO_ERROR, "Complete response has been sent, sending a RST to ask the other endpoint to stop sending request data without discarding the response." },
924 { QUIC_ERROR_PROCESSING_STREAM, "There was some error which halted stream processing" },
925 { QUIC_MULTIPLE_TERMINATION_OFFSETS, "We got two fin or reset offsets which did not match" },
926 { QUIC_BAD_APPLICATION_PAYLOAD, "We got bad payload and can not respond to it at the protocol level" },
927 { QUIC_STREAM_CONNECTION_ERROR, "Stream closed due to connection error. No reset frame is sent when this happens" },
928 { QUIC_STREAM_PEER_GOING_AWAY, "GoAway frame sent. No more stream can be created" },
929 { QUIC_STREAM_CANCELLED, "The stream has been cancelled" },
930 { QUIC_RST_ACKNOWLEDGEMENT, "Closing stream locally, sending a RST to allow for proper flow control accounting. Sent in response to a RST from the peer" },
931 { QUIC_REFUSED_STREAM, "Receiver refused to create the stream (because its limit on open streams has been reached). The sender should retry the request later (using another stream)" },
932 { QUIC_INVALID_PROMISE_URL, "Invalid URL in PUSH_PROMISE request header" },
933 { QUIC_UNAUTHORIZED_PROMISE_URL, "Server is not authoritative for this URL" },
934 { QUIC_DUPLICATE_PROMISE_URL, "Can't have more than one active PUSH_PROMISE per URL" },
935 { QUIC_PROMISE_VARY_MISMATCH, "Vary check failed" },
936 { QUIC_INVALID_PROMISE_METHOD, "Only GET and HEAD methods allowed" },
937 { QUIC_PUSH_STREAM_TIMED_OUT, "The push stream is unclaimed and timed out" },
938 { QUIC_HEADERS_TOO_LARGE, "Received headers were too large" },
939 { QUIC_STREAM_TTL_EXPIRED, "The data is not likely arrive in time" },
940 { QUIC_STREAM_LAST_ERROR, "No error. Used as bound while iterating" },
941 { 0, NULL }
943 static value_string_ext rststream_error_code_vals_ext = VALUE_STRING_EXT_INIT(rststream_error_code_vals);
945 /**************************************************************************/
946 /* Handshake Failure Reason */
947 /**************************************************************************/
948 /* See https://chromium.googlesource.com/chromium/src.git/+/master/net/third_party/quic/core/crypto/crypto_handshake.h */
950 enum HandshakeFailureReason {
951 HANDSHAKE_OK = 0,
953 /* Failure reasons for an invalid client nonce in CHLO. */
955 /* The default error value for nonce verification failures from strike register (covers old strike registers and unknown failures). */
956 CLIENT_NONCE_UNKNOWN_FAILURE = 1,
957 /* Client nonce had incorrect length. */
958 CLIENT_NONCE_INVALID_FAILURE = 2,
959 /* Client nonce is not unique. */
960 CLIENT_NONCE_NOT_UNIQUE_FAILURE = 3,
961 /* Client orbit is invalid or incorrect. */
962 CLIENT_NONCE_INVALID_ORBIT_FAILURE = 4,
963 /* Client nonce's timestamp is not in the strike register's valid time range. */
964 CLIENT_NONCE_INVALID_TIME_FAILURE = 5,
965 /* Strike register's RPC call timed out, client nonce couldn't be verified. */
966 CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT = 6,
967 /* Strike register is down, client nonce couldn't be verified. */
968 CLIENT_NONCE_STRIKE_REGISTER_FAILURE = 7,
970 /* Failure reasons for an invalid server nonce in CHLO. */
972 /* Unbox of server nonce failed. */
973 SERVER_NONCE_DECRYPTION_FAILURE = 8,
974 /* Decrypted server nonce had incorrect length. */
975 SERVER_NONCE_INVALID_FAILURE = 9,
976 /* Server nonce is not unique. */
977 SERVER_NONCE_NOT_UNIQUE_FAILURE = 10,
978 /* Server nonce's timestamp is not in the strike register's valid time range. */
979 SERVER_NONCE_INVALID_TIME_FAILURE = 11,
980 /* The server requires handshake confirmation. */
981 SERVER_NONCE_REQUIRED_FAILURE = 20,
983 /* Failure reasons for an invalid server config in CHLO. */
985 /* Missing Server config id (kSCID) tag. */
986 SERVER_CONFIG_INCHOATE_HELLO_FAILURE = 12,
987 /* Couldn't find the Server config id (kSCID). */
988 SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE = 13,
990 /* Failure reasons for an invalid source-address token. */
992 /* Missing Source-address token (kSourceAddressTokenTag) tag. */
993 SOURCE_ADDRESS_TOKEN_INVALID_FAILURE = 14,
994 /* Unbox of Source-address token failed. */
995 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE = 15,
996 /* Couldn't parse the unbox'ed Source-address token. */
997 SOURCE_ADDRESS_TOKEN_PARSE_FAILURE = 16,
998 /* Source-address token is for a different IP address. */
999 SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE = 17,
1000 /* The source-address token has a timestamp in the future. */
1001 SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE = 18,
1002 /* The source-address token has expired. */
1003 SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE = 19,
1005 /* The expected leaf certificate hash could not be validated. */
1006 INVALID_EXPECTED_LEAF_CERTIFICATE = 21,
1008 MAX_FAILURE_REASON = 22
1011 static const value_string handshake_failure_reason_vals[] = {
1012 { HANDSHAKE_OK, "Handshake OK" },
1013 { CLIENT_NONCE_UNKNOWN_FAILURE, "The default error value for nonce verification failures from strike register (covers old strike registers and unknown failures)" },
1014 { CLIENT_NONCE_INVALID_FAILURE, "Client nonce had incorrect length" },
1015 { CLIENT_NONCE_NOT_UNIQUE_FAILURE, "Client nonce is not unique" },
1016 { CLIENT_NONCE_INVALID_ORBIT_FAILURE, "Client orbit is invalid or incorrect" },
1017 { CLIENT_NONCE_INVALID_TIME_FAILURE, "Client nonce's timestamp is not in the strike register's valid time range" },
1018 { CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT, "Strike register's RPC call timed out, client nonce couldn't be verified" },
1019 { CLIENT_NONCE_STRIKE_REGISTER_FAILURE, "Strike register is down, client nonce couldn't be verified" },
1020 { SERVER_NONCE_DECRYPTION_FAILURE, "Unbox of server nonce failed" },
1021 { SERVER_NONCE_INVALID_FAILURE, "Decrypted server nonce had incorrect length" },
1022 { SERVER_NONCE_NOT_UNIQUE_FAILURE, "Server nonce is not unique" },
1023 { SERVER_NONCE_INVALID_TIME_FAILURE, "Server nonce's timestamp is not in the strike register's valid time range" },
1024 { SERVER_CONFIG_INCHOATE_HELLO_FAILURE, "Missing Server config id (kSCID) tag" },
1025 { SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE, "Couldn't find the Server config id (kSCID)" },
1026 { SOURCE_ADDRESS_TOKEN_INVALID_FAILURE, "Missing Source-address token (kSourceAddressTokenTag) tag" },
1027 { SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, "Unbox of Source-address token failed" },
1028 { SOURCE_ADDRESS_TOKEN_PARSE_FAILURE, "Couldn't parse the unbox'ed Source-address token" },
1029 { SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE, "Source-address token is for a different IP address" },
1030 { SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE, "The source-address token has a timestamp in the future" },
1031 { SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE, "The source-address token has expired" },
1032 { SERVER_NONCE_REQUIRED_FAILURE, "The server requires handshake confirmation" },
1033 { INVALID_EXPECTED_LEAF_CERTIFICATE, "The expected leaf certificate hash could not be validated" },
1034 { 0, NULL }
1036 static value_string_ext handshake_failure_reason_vals_ext = VALUE_STRING_EXT_INIT(handshake_failure_reason_vals);
1039 static uint32_t get_len_offset(uint8_t frame_type){
1041 switch((frame_type & FTFLAGS_STREAM_OOO) >> 2){
1042 case 0:
1043 return 0;
1044 break;
1045 case 1:
1046 return 2;
1047 break;
1048 case 2:
1049 return 3;
1050 break;
1051 case 3:
1052 return 4;
1053 break;
1054 case 4:
1055 return 5;
1056 break;
1057 case 5:
1058 return 6;
1059 break;
1060 case 6:
1061 return 7;
1062 break;
1063 case 7:
1064 return 8;
1065 break;
1066 default:
1067 break;
1069 return 0;
1071 static uint32_t get_len_stream(uint8_t frame_type){
1073 switch(frame_type & FTFLAGS_STREAM_SS){
1074 case 0:
1075 return 1;
1076 break;
1077 case 1:
1078 return 2;
1079 break;
1080 case 2:
1081 return 3;
1082 break;
1083 case 3:
1084 return 4;
1085 break;
1086 default:
1087 break;
1089 return 1;
1092 static uint32_t get_len_largest_observed(uint8_t frame_type){
1094 switch((frame_type & FTFLAGS_ACK_LL) >> 2){
1095 case 0:
1096 return 1;
1097 break;
1098 case 1:
1099 return 2;
1100 break;
1101 case 2:
1102 return 4;
1103 break;
1104 case 3:
1105 return 6;
1106 break;
1107 default:
1108 break;
1110 return 1;
1112 static uint32_t get_len_missing_packet(uint8_t frame_type){
1114 switch(frame_type & FTFLAGS_ACK_MM){
1115 case 0:
1116 return 1;
1117 break;
1118 case 1:
1119 return 2;
1120 break;
1121 case 2:
1122 return 4;
1123 break;
1124 case 3:
1125 return 6;
1126 break;
1127 default:
1128 break;
1130 return 1;
1133 static uint32_t get_len_packet_number(uint8_t puflags){
1135 switch((puflags & PUFLAGS_PKN) >> 4){
1136 case 0:
1137 return 1;
1138 break;
1139 case 1:
1140 return 2;
1141 break;
1142 case 2:
1143 return 4;
1144 break;
1145 case 3:
1146 return 6;
1147 break;
1148 default:
1149 break;
1151 return 6;
1154 static
1155 bool is_gquic_unencrypt(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, uint16_t len_pkn, gquic_info_data_t *gquic_info){
1156 uint8_t frame_type;
1157 uint8_t num_ranges, num_revived, num_blocks = 0, num_timestamp;
1158 uint32_t len_stream = 0, len_offset = 0, len_data = 0, len_largest_observed = 1, len_missing_packet = 1;
1159 uint32_t message_tag;
1162 if(tvb_captured_length_remaining(tvb, offset) <= 13){
1163 return false;
1165 /* Message Authentication Hash */
1166 offset += 12;
1168 if(gquic_info->version_valid && gquic_info->version < 34){ /* No longer Private Flags after Q034 */
1169 /* Private Flags */
1170 offset += 1;
1173 while(tvb_reported_length_remaining(tvb, offset) > 0){
1175 if (tvb_captured_length_remaining(tvb, offset) <= 1){
1176 return false;
1178 /* Frame type */
1179 frame_type = tvb_get_uint8(tvb, offset);
1180 if((frame_type & FTFLAGS_SPECIAL) == 0){
1181 offset += 1;
1182 switch(frame_type){
1183 case FT_PADDING:
1184 return false; /* Pad on rest of packet.. */
1185 break;
1186 case FT_RST_STREAM:
1187 /* Stream ID */
1188 offset += 4;
1189 /* Byte Offset */
1190 offset += 8;
1191 /* Error Code */
1192 offset += 4;
1193 break;
1194 case FT_CONNECTION_CLOSE:{
1195 uint16_t len_reason;
1197 /* Error Code */
1198 offset += 4;
1199 /* Reason Phrase Length */
1200 if (tvb_captured_length_remaining(tvb, offset) <= 2){
1201 return false;
1203 len_reason = tvb_get_uint16(tvb, offset, gquic_info->encoding);
1204 offset += 2;
1205 /* Reason Phrase */
1206 /* If length remaining == len_reason, it is Connection Close */
1207 if (tvb_captured_length_remaining(tvb, offset) == len_reason){
1208 return true;
1211 break;
1212 case FT_GOAWAY:{
1213 uint16_t len_reason;
1215 /* Error Code */
1216 offset += 4;
1217 /* Last Good Stream ID */
1218 offset += 4;
1219 /* Reason Phrase Length */
1220 if (tvb_captured_length_remaining(tvb, offset) <= 2){
1221 return false;
1223 len_reason = tvb_get_uint16(tvb, offset, gquic_info->encoding);
1224 offset += 2;
1225 /* Reason Phrase */
1226 offset += len_reason;
1228 break;
1229 case FT_WINDOW_UPDATE:
1230 /* Stream ID */
1231 offset += 4;
1232 /* Byte Offset */
1233 offset += 8;
1234 break;
1235 case FT_BLOCKED:
1236 /* Stream ID */
1237 offset += 4;
1238 break;
1239 case FT_STOP_WAITING:
1240 if(gquic_info->version_valid && gquic_info->version < 34){ /* No longer Entropy after Q034 */
1241 /* Send Entropy */
1242 offset += 1;
1244 /* Least Unacked Delta */
1245 offset += len_pkn;
1246 break;
1247 case FT_PING: /* No Payload */
1248 default: /* No default */
1249 break;
1251 } else {
1252 /* Special Frame Type */
1253 if(frame_type & FTFLAGS_STREAM){ /* Stream */
1255 if(frame_type & FTFLAGS_STREAM_D){
1256 len_data = 2;
1258 len_offset = get_len_offset(frame_type);
1259 len_stream = get_len_stream(frame_type);
1261 /* Frame Type */
1262 offset += 1;
1264 /* Stream */
1265 offset += len_stream;
1267 /* Offset */
1268 offset += len_offset;
1270 /* Data length */
1271 offset += len_data;
1273 if (tvb_captured_length_remaining(tvb, offset) <= 4){
1274 return false;
1277 /* Check if the Message Tag is CHLO (Client Hello) or SHLO (Server Hello) or REJ (Rejection) */
1278 message_tag = tvb_get_ntohl(tvb, offset);
1279 if (message_tag == MTAG_CHLO|| message_tag == MTAG_SHLO || message_tag == MTAG_REJ) {
1280 if(message_tag == MTAG_CHLO && pinfo->srcport != 443) { /* Found */
1281 gquic_info->server_port = pinfo->destport;
1283 return true;
1287 } else if (frame_type & FTFLAGS_ACK) {
1288 /* ACK Flags */
1290 len_largest_observed = get_len_largest_observed(frame_type);
1291 len_missing_packet = get_len_missing_packet(frame_type);
1293 /* Frame Type */
1294 offset += 1;
1296 if(gquic_info->version_valid && gquic_info->version < 34){ /* No longer Entropy after Q034 */
1297 /* Received Entropy */
1298 offset += 1;
1300 /* Largest Observed */
1301 offset += len_largest_observed;
1303 /* Ack Delay Time */
1304 offset += 2;
1306 /* Num Timestamp */
1307 if (tvb_captured_length_remaining(tvb, offset) <= 1){
1308 return false;
1310 num_timestamp = tvb_get_uint8(tvb, offset);
1311 offset += 1;
1313 if(num_timestamp > 0){
1314 /* Delta Largest Observed */
1315 offset += 1;
1317 /* First Timestamp */
1318 offset += 4;
1320 /* Num Timestamp (-1)x (Delta Largest Observed + Time Since Previous Timestamp) */
1321 offset += (num_timestamp - 1)*(1+2);
1324 if(frame_type & FTFLAGS_ACK_N){
1325 /* Num Ranges */
1326 if (tvb_captured_length_remaining(tvb, offset) <= 1){
1327 return false;
1329 num_ranges = tvb_get_uint8(tvb, offset);
1330 offset += 1;
1332 /* Num Range x (Missing Packet + Range Length) */
1333 offset += num_ranges*(len_missing_packet+1);
1335 /* Num Revived */
1336 if (tvb_captured_length_remaining(tvb, offset) <= 1){
1337 return false;
1339 num_revived = tvb_get_uint8(tvb, offset);
1340 offset += 1;
1342 /* Num Revived x Length Largest Observed */
1343 offset += num_revived*len_largest_observed;
1346 } else {
1348 /* Largest Acked */
1349 offset += len_largest_observed;
1351 /* Largest Acked Delta Time*/
1352 offset += 2;
1354 /* Ack Block */
1355 if(frame_type & FTFLAGS_ACK_N){
1356 if (tvb_captured_length_remaining(tvb, offset) <= 1){
1357 return false;
1359 num_blocks = tvb_get_uint8(tvb, offset);
1360 offset += 1;
1363 /* First Ack Block Length */
1364 offset += len_missing_packet;
1365 if(num_blocks){
1366 offset += (num_blocks)*(1 + len_missing_packet);
1369 /* Timestamp */
1370 if (tvb_captured_length_remaining(tvb, offset) <= 1){
1371 return false;
1373 num_timestamp = tvb_get_uint8(tvb, offset);
1374 offset += 1;
1376 if(num_timestamp > 0){
1378 /* Delta Largest Acked */
1379 offset += 1;
1381 /* Time Since Largest Acked */
1382 offset += 4;
1384 /* Num Timestamp x (Delta Largest Acked + Time Since Previous Timestamp) */
1385 offset += (num_timestamp - 1)*(1+2);
1389 } else { /* Other Special Frame type */
1390 offset += 1;
1395 return false;
1399 static uint32_t
1400 // NOLINTNEXTLINE(misc-no-recursion)
1401 dissect_gquic_tag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gquic_tree, unsigned offset, uint32_t tag_number){
1402 uint32_t tag_offset_start = offset + tag_number*4*2;
1403 uint32_t tag_offset = 0, total_tag_len = 0;
1404 int32_t tag_len;
1406 while(tag_number){
1407 proto_tree *tag_tree, *ti_len, *ti_tag, *ti_type;
1408 uint32_t offset_end, tag, num_iter;
1409 const uint8_t* tag_str;
1411 ti_tag = proto_tree_add_item(gquic_tree, hf_gquic_tags, tvb, offset, 8, ENC_NA);
1412 tag_tree = proto_item_add_subtree(ti_tag, ett_gquic_tag_value);
1413 ti_type = proto_tree_add_item_ret_string(tag_tree, hf_gquic_tag_type, tvb, offset, 4, ENC_ASCII|ENC_NA, pinfo->pool, &tag_str);
1414 tag = tvb_get_ntohl(tvb, offset);
1415 proto_item_append_text(ti_type, " (%s)", val_to_str_const(tag, tag_vals, "Unknown"));
1416 proto_item_append_text(ti_tag, ": %s (%s)", tag_str, val_to_str_const(tag, tag_vals, "Unknown"));
1417 offset += 4;
1419 proto_tree_add_item(tag_tree, hf_gquic_tag_offset_end, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1420 offset_end = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
1422 tag_len = offset_end - tag_offset;
1423 ti_len = proto_tree_add_uint(tag_tree, hf_gquic_tag_length, tvb, offset, 4, tag_len);
1424 proto_item_append_text(ti_tag, " (l=%u)", tag_len);
1425 proto_item_set_generated(ti_len);
1426 offset += 4;
1428 /* Fix issue with CRT.. (Fragmentation ?) */
1429 if( tag_len > tvb_reported_length_remaining(tvb, tag_offset_start + tag_offset)){
1430 tag_len = tvb_reported_length_remaining(tvb, tag_offset_start + tag_offset);
1431 offset_end = tag_offset + tag_len;
1432 expert_add_info(pinfo, ti_len, &ei_gquic_tag_length);
1435 total_tag_len += tag_len;
1437 proto_tree_add_item(tag_tree, hf_gquic_tag_value, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1439 increment_dissection_depth(pinfo);
1440 switch(tag){
1441 case TAG_PAD:
1442 proto_tree_add_item(tag_tree, hf_gquic_tag_pad, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1443 tag_offset += tag_len;
1444 break;
1445 case TAG_SNI:
1446 proto_tree_add_item_ret_string(tag_tree, hf_gquic_tag_sni, tvb, tag_offset_start + tag_offset, tag_len, ENC_ASCII|ENC_NA, pinfo->pool, &tag_str);
1447 proto_item_append_text(ti_tag, ": %s", tag_str);
1448 tag_offset += tag_len;
1449 break;
1450 case TAG_VER:
1451 num_iter = 1;
1452 while(offset_end - tag_offset >= 4){
1453 proto_tree_add_item_ret_string(tag_tree, hf_gquic_tag_ver, tvb, tag_offset_start + tag_offset, 4, ENC_ASCII|ENC_NA, pinfo->pool, &tag_str);
1454 proto_item_append_text(ti_tag, "%s %s", num_iter == 1 ? ":" : ",", tag_str);
1455 tag_offset += 4;
1456 num_iter++;
1458 break;
1459 case TAG_CCS:
1460 while(offset_end - tag_offset >= 8){
1461 proto_tree_add_item(tag_tree, hf_gquic_tag_ccs, tvb, tag_offset_start + tag_offset, 8, ENC_NA);
1462 tag_offset += 8;
1464 break;
1465 case TAG_PDMD:
1466 proto_tree_add_item_ret_string(tag_tree, hf_gquic_tag_pdmd, tvb, tag_offset_start + tag_offset, tag_len, ENC_ASCII|ENC_NA, pinfo->pool, &tag_str);
1467 proto_item_append_text(ti_tag, ": %s", tag_str);
1468 tag_offset += tag_len;
1469 break;
1470 case TAG_UAID:
1471 proto_tree_add_item_ret_string(tag_tree, hf_gquic_tag_uaid, tvb, tag_offset_start + tag_offset, tag_len, ENC_ASCII|ENC_NA, pinfo->pool, &tag_str);
1472 proto_item_append_text(ti_tag, ": %s", tag_str);
1473 tag_offset += tag_len;
1474 break;
1475 case TAG_STK:
1476 proto_tree_add_item(tag_tree, hf_gquic_tag_stk, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1477 tag_offset += tag_len;
1478 break;
1479 case TAG_SNO:
1480 proto_tree_add_item(tag_tree, hf_gquic_tag_sno, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1481 tag_offset += tag_len;
1482 break;
1483 case TAG_PROF:
1484 proto_tree_add_item(tag_tree, hf_gquic_tag_prof, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1485 tag_offset += tag_len;
1486 break;
1487 case TAG_SCFG:{
1488 uint32_t scfg_tag_number;
1490 proto_tree_add_item(tag_tree, hf_gquic_tag_scfg, tvb, tag_offset_start + tag_offset, 4, ENC_ASCII);
1491 tag_offset += 4;
1492 proto_tree_add_item(tag_tree, hf_gquic_tag_scfg_number, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1493 scfg_tag_number = tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN);
1494 tag_offset += 4;
1496 dissect_gquic_tag(tvb, pinfo, tag_tree, tag_offset_start + tag_offset, scfg_tag_number);
1497 tag_offset += tag_len - 4 - 4;
1499 break;
1500 case TAG_RREJ:
1501 while(offset_end - tag_offset >= 4){
1502 proto_tree_add_item(tag_tree, hf_gquic_tag_rrej, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1503 proto_item_append_text(ti_tag, ", Code %s", val_to_str_ext_const(tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN),
1504 &handshake_failure_reason_vals_ext,
1505 "Unknown"));
1506 tag_offset += 4;
1508 break;
1509 case TAG_CRT:
1510 proto_tree_add_item(tag_tree, hf_gquic_tag_crt, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1511 tag_offset += tag_len;
1512 break;
1513 case TAG_AEAD:
1514 while(offset_end - tag_offset >= 4){
1515 proto_tree *ti_aead;
1516 ti_aead = proto_tree_add_item(tag_tree, hf_gquic_tag_aead, tvb, tag_offset_start + tag_offset, 4, ENC_ASCII);
1517 proto_item_append_text(ti_aead, " (%s)", val_to_str_const(tvb_get_ntohl(tvb, tag_offset_start + tag_offset), tag_aead_vals, "Unknown"));
1518 proto_item_append_text(ti_tag, ", %s", val_to_str_const(tvb_get_ntohl(tvb, tag_offset_start + tag_offset), tag_aead_vals, "Unknown"));
1519 tag_offset += 4;
1521 break;
1522 case TAG_SCID:
1523 proto_tree_add_item(tag_tree, hf_gquic_tag_scid, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1524 tag_offset += tag_len;
1525 break;
1526 case TAG_PUBS:
1527 /*TODO FIX: 24 Length + Pubs key?.. ! */
1528 proto_tree_add_item(tag_tree, hf_gquic_tag_pubs, tvb, tag_offset_start + tag_offset, 2, ENC_LITTLE_ENDIAN);
1529 tag_offset += 2;
1530 while(offset_end - tag_offset >= 3){
1531 proto_tree_add_item(tag_tree, hf_gquic_tag_pubs, tvb, tag_offset_start + tag_offset, 3, ENC_LITTLE_ENDIAN);
1532 tag_offset += 3;
1534 break;
1535 case TAG_KEXS:
1536 while(offset_end - tag_offset >= 4){
1537 proto_tree *ti_kexs;
1538 ti_kexs = proto_tree_add_item(tag_tree, hf_gquic_tag_kexs, tvb, tag_offset_start + tag_offset, 4, ENC_ASCII);
1539 proto_item_append_text(ti_kexs, " (%s)", val_to_str_const(tvb_get_ntohl(tvb, tag_offset_start + tag_offset), tag_kexs_vals, "Unknown"));
1540 proto_item_append_text(ti_tag, ", %s", val_to_str_const(tvb_get_ntohl(tvb, tag_offset_start + tag_offset), tag_kexs_vals, "Unknown"));
1541 tag_offset += 4;
1543 break;
1544 case TAG_OBIT:
1545 proto_tree_add_item(tag_tree, hf_gquic_tag_obit, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1546 tag_offset += tag_len;
1547 break;
1548 case TAG_EXPY:
1549 proto_tree_add_item(tag_tree, hf_gquic_tag_expy, tvb, tag_offset_start + tag_offset, 8, ENC_LITTLE_ENDIAN);
1550 tag_offset += 8;
1551 break;
1552 case TAG_NONC:
1553 /*TODO: Enhance display: 32 bytes consisting of 4 bytes of timestamp (big-endian, UNIX epoch seconds), 8 bytes of server orbit and 20 bytes of random data. */
1554 proto_tree_add_item(tag_tree, hf_gquic_tag_nonc, tvb, tag_offset_start + tag_offset, 32, ENC_NA);
1555 tag_offset += 32;
1556 break;
1557 case TAG_MSPC:
1558 proto_tree_add_item(tag_tree, hf_gquic_tag_mspc, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1559 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1560 tag_offset += 4;
1561 break;
1562 case TAG_TCID:
1563 proto_tree_add_item(tag_tree, hf_gquic_tag_tcid, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1564 tag_offset += 4;
1565 break;
1566 case TAG_SRBF:
1567 proto_tree_add_item(tag_tree, hf_gquic_tag_srbf, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1568 tag_offset += 4;
1569 break;
1570 case TAG_ICSL:
1571 proto_tree_add_item(tag_tree, hf_gquic_tag_icsl, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1572 tag_offset += 4;
1573 break;
1574 case TAG_SCLS:
1575 proto_tree_add_item(tag_tree, hf_gquic_tag_scls, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1576 tag_offset += 4;
1577 break;
1578 case TAG_COPT:
1579 while(offset_end - tag_offset >= 4){
1580 proto_tree_add_item(tag_tree, hf_gquic_tag_copt, tvb, tag_offset_start + tag_offset, 4, ENC_ASCII);
1581 tag_offset += 4;
1583 break;
1584 case TAG_CCRT:
1585 proto_tree_add_item(tag_tree, hf_gquic_tag_ccrt, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1586 tag_offset += tag_len;
1587 break;
1588 case TAG_IRTT:
1589 proto_tree_add_item(tag_tree, hf_gquic_tag_irtt, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1590 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1591 tag_offset += 4;
1592 break;
1593 case TAG_CFCW:
1594 proto_tree_add_item(tag_tree, hf_gquic_tag_cfcw, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1595 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1596 tag_offset += 4;
1597 break;
1598 case TAG_SFCW:
1599 proto_tree_add_item(tag_tree, hf_gquic_tag_sfcw, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1600 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1601 tag_offset += 4;
1602 break;
1603 case TAG_CETV:
1604 proto_tree_add_item(tag_tree, hf_gquic_tag_cetv, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1605 tag_offset += tag_len;
1606 break;
1607 case TAG_XLCT:
1608 proto_tree_add_item(tag_tree, hf_gquic_tag_xlct, tvb, tag_offset_start + tag_offset, 8, ENC_NA);
1609 tag_offset += 8;
1610 break;
1611 case TAG_NONP:
1612 proto_tree_add_item(tag_tree, hf_gquic_tag_nonp, tvb, tag_offset_start + tag_offset, 32, ENC_NA);
1613 tag_offset += 32;
1614 break;
1615 case TAG_CSCT:
1616 proto_tree_add_item(tag_tree, hf_gquic_tag_csct, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1617 tag_offset += tag_len;
1618 break;
1619 case TAG_CTIM:
1620 proto_tree_add_item(tag_tree, hf_gquic_tag_ctim, tvb, tag_offset_start + tag_offset, 8, ENC_LITTLE_ENDIAN|ENC_TIME_SECS_NSECS);
1621 tag_offset += 8;
1622 break;
1623 case TAG_RNON: /* Public Reset Tag */
1624 proto_tree_add_item(tag_tree, hf_gquic_tag_rnon, tvb, tag_offset_start + tag_offset, 8, ENC_LITTLE_ENDIAN);
1625 tag_offset += 8;
1626 break;
1627 case TAG_RSEQ: /* Public Reset Tag */
1628 proto_tree_add_item(tag_tree, hf_gquic_tag_rseq, tvb, tag_offset_start + tag_offset, 8, ENC_LITTLE_ENDIAN);
1629 tag_offset += 8;
1630 break;
1631 case TAG_CADR: /* Public Reset Tag */{
1632 uint32_t addr_type;
1633 proto_tree_add_item_ret_uint(tag_tree, hf_gquic_tag_cadr_addr_type, tvb, tag_offset_start + tag_offset, 2, ENC_LITTLE_ENDIAN, &addr_type);
1634 tag_offset += 2;
1635 switch(addr_type){
1636 case 2: /* IPv4 */
1637 proto_tree_add_item(tag_tree, hf_gquic_tag_cadr_addr_ipv4, tvb, tag_offset_start + tag_offset, 4, ENC_NA);
1638 tag_offset += 4;
1639 break;
1640 case 10: /* IPv6 */
1641 proto_tree_add_item(tag_tree, hf_gquic_tag_cadr_addr_ipv6, tvb, tag_offset_start + tag_offset, 16, ENC_NA);
1642 tag_offset += 16;
1643 break;
1644 default: /* Unknown */
1645 proto_tree_add_item(tag_tree, hf_gquic_tag_cadr_addr, tvb, tag_offset_start + tag_offset, tag_len - 2 - 2, ENC_NA);
1646 tag_offset += tag_len + 2 + 2 ;
1647 break;
1649 proto_tree_add_item(tag_tree, hf_gquic_tag_cadr_port, tvb, tag_offset_start + tag_offset, 2, ENC_LITTLE_ENDIAN);
1650 tag_offset += 2;
1652 break;
1653 case TAG_MIDS:
1654 proto_tree_add_item(tag_tree, hf_gquic_tag_mids, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1655 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1656 tag_offset += 4;
1657 break;
1658 case TAG_FHOL:
1659 proto_tree_add_item(tag_tree, hf_gquic_tag_fhol, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1660 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1661 tag_offset += 4;
1662 break;
1663 case TAG_STTL:
1664 proto_tree_add_item(tag_tree, hf_gquic_tag_sttl, tvb, tag_offset_start + tag_offset, 8, ENC_LITTLE_ENDIAN);
1665 tag_offset += 8;
1666 break;
1667 case TAG_SMHL:
1668 proto_tree_add_item(tag_tree, hf_gquic_tag_smhl, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1669 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1670 tag_offset += 4;
1671 break;
1672 case TAG_TBKP:
1673 proto_tree_add_item_ret_string(tag_tree, hf_gquic_tag_tbkp, tvb, tag_offset_start + tag_offset, 4, ENC_ASCII|ENC_NA, pinfo->pool, &tag_str);
1674 proto_item_append_text(ti_tag, ": %s", tag_str);
1675 tag_offset += 4;
1676 break;
1677 case TAG_MAD0:
1678 proto_tree_add_item(tag_tree, hf_gquic_tag_mad0, tvb, tag_offset_start + tag_offset, 4, ENC_LITTLE_ENDIAN);
1679 proto_item_append_text(ti_tag, ": %u", tvb_get_uint32(tvb, tag_offset_start + tag_offset, ENC_LITTLE_ENDIAN));
1680 tag_offset += 4;
1681 break;
1682 case TAG_QLVE:
1684 proto_tree_add_item(tag_tree, hf_gquic_tag_qlve, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1686 /* Newest GQUIC versions (usually Q050) encapsulate their first flight in Q043 packets.
1687 * (Q050 is handled by QUIC dissector) */
1688 tvbuff_t *next_tvb = tvb_new_subset_length(tvb, tag_offset_start + tag_offset, tag_len);
1689 call_dissector_with_data(quic_handle, next_tvb, pinfo, tag_tree, NULL);
1691 tag_offset += tag_len;
1693 break;
1694 case TAG_CGST:
1695 proto_tree_add_item(tag_tree, hf_gquic_tag_cgst, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1696 tag_offset += tag_len;
1697 break;
1698 case TAG_EPID:
1699 proto_tree_add_item_ret_string(tag_tree, hf_gquic_tag_epid, tvb, tag_offset_start + tag_offset, tag_len, ENC_ASCII|ENC_NA, pinfo->pool, &tag_str);
1700 proto_item_append_text(ti_tag, ": %s", tag_str);
1701 tag_offset += tag_len;
1702 break;
1703 case TAG_SRST:
1704 proto_tree_add_item(tag_tree, hf_gquic_tag_srst, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1705 tag_offset += tag_len;
1706 break;
1707 default:
1708 proto_tree_add_item(tag_tree, hf_gquic_tag_unknown, tvb, tag_offset_start + tag_offset, tag_len, ENC_NA);
1709 expert_add_info_format(pinfo, ti_tag, &ei_gquic_tag_undecoded,
1710 "Dissector for (Google) QUIC Tag"
1711 " %s (%s) code not implemented, Contact"
1712 " Wireshark developers if you want this supported",
1713 tvb_get_string_enc(pinfo->pool, tvb, offset-8, 4, ENC_ASCII|ENC_NA),
1714 val_to_str_const(tag, tag_vals, "Unknown"));
1715 tag_offset += tag_len;
1716 break;
1718 decrement_dissection_depth(pinfo);
1720 if(tag_offset != offset_end){
1721 /* Wrong Tag len... */
1722 proto_tree_add_expert(tag_tree, pinfo, &ei_gquic_tag_unknown, tvb, tag_offset_start + tag_offset, tag_len);
1723 tag_offset = offset_end;
1726 tag_number--;
1729 if (offset + total_tag_len <= offset) {
1730 expert_add_info_format(pinfo, gquic_tree, &ei_gquic_length_invalid,
1731 "Invalid total tag length: %u", total_tag_len);
1732 return offset + tvb_reported_length_remaining(tvb, offset);
1734 return offset + total_tag_len;
1738 uint32_t
1739 dissect_gquic_tags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ft_tree, unsigned offset){
1740 uint32_t tag_number;
1742 proto_tree_add_item(ft_tree, hf_gquic_tag_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1743 tag_number = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
1744 offset += 2;
1746 proto_tree_add_item(ft_tree, hf_gquic_padding, tvb, offset, 2, ENC_NA);
1747 offset += 2;
1749 offset = dissect_gquic_tag(tvb, pinfo, ft_tree, offset, tag_number);
1751 return offset;
1755 dissect_gquic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gquic_tree, unsigned offset, uint8_t len_pkn, gquic_info_data_t *gquic_info){
1756 if (!gquic_info) {
1757 expert_add_info(pinfo, gquic_tree, &ei_gquic_data_invalid);
1758 return offset + tvb_reported_length_remaining(tvb, offset);
1761 proto_item *ti, *ti_ft, *ti_ftflags /*, *expert_ti*/;
1762 proto_tree *ft_tree, *ftflags_tree;
1763 uint8_t frame_type;
1764 uint8_t num_ranges, num_revived, num_blocks = 0, num_timestamp;
1765 uint32_t len_stream = 0, len_offset = 0, len_data = 0, len_largest_observed = 1, len_missing_packet = 1;
1767 ti_ft = proto_tree_add_item(gquic_tree, hf_gquic_frame, tvb, offset, 1, ENC_NA);
1768 ft_tree = proto_item_add_subtree(ti_ft, ett_gquic_ft);
1770 /* Frame type */
1771 ti_ftflags = proto_tree_add_item(ft_tree, hf_gquic_frame_type, tvb, offset, 1, ENC_NA);
1772 frame_type = tvb_get_uint8(tvb, offset);
1773 proto_item_set_text(ti_ft, "%s", rval_to_str_const(frame_type, frame_type_vals, "Unknown"));
1775 if((frame_type & FTFLAGS_SPECIAL) == 0 && frame_type != FT_CRYPTO){ /* Regular Stream Flags */
1776 offset += 1;
1777 switch(frame_type){
1778 case FT_PADDING:{
1779 proto_item *ti_pad_len;
1780 uint32_t pad_len = tvb_reported_length_remaining(tvb, offset);
1782 ti_pad_len = proto_tree_add_uint(ft_tree, hf_gquic_frame_type_padding_length, tvb, offset, 0, pad_len);
1783 proto_item_set_generated(ti_pad_len);
1784 proto_item_append_text(ti_ft, " Length: %u", pad_len);
1785 if(pad_len > 0) /* Avoid Malformed Exception with pad_len == 0 */
1786 proto_tree_add_item(ft_tree, hf_gquic_frame_type_padding, tvb, offset, -1, ENC_NA);
1787 offset += pad_len;
1789 break;
1790 case FT_RST_STREAM:{
1791 uint32_t stream_id, error_code;
1792 proto_tree_add_item_ret_uint(ft_tree, hf_gquic_frame_type_rsts_stream_id, tvb, offset, 4, gquic_info->encoding, &stream_id);
1793 offset += 4;
1794 proto_tree_add_item(ft_tree, hf_gquic_frame_type_rsts_byte_offset, tvb, offset, 8, gquic_info->encoding);
1795 offset += 8;
1796 proto_tree_add_item_ret_uint(ft_tree, hf_gquic_frame_type_rsts_error_code, tvb, offset, 4, gquic_info->encoding, &error_code);
1797 offset += 4;
1798 proto_item_append_text(ti_ft, " Stream ID: %u, Error code: %s", stream_id, val_to_str_ext(error_code, &rststream_error_code_vals_ext, "Unknown (%d)"));
1799 col_set_str(pinfo->cinfo, COL_INFO, "RST STREAM");
1801 break;
1802 case FT_CONNECTION_CLOSE:{
1803 uint16_t len_reason;
1804 uint32_t error_code;
1806 proto_tree_add_item_ret_uint(ft_tree, hf_gquic_frame_type_cc_error_code, tvb, offset, 4, gquic_info->encoding, &error_code);
1807 offset += 4;
1808 proto_tree_add_item(ft_tree, hf_gquic_frame_type_cc_reason_phrase_length, tvb, offset, 2, gquic_info->encoding);
1809 len_reason = tvb_get_uint16(tvb, offset, gquic_info->encoding);
1810 offset += 2;
1811 proto_tree_add_item(ft_tree, hf_gquic_frame_type_cc_reason_phrase, tvb, offset, len_reason, ENC_ASCII);
1812 offset += len_reason;
1813 proto_item_append_text(ti_ft, " Error code: %s", val_to_str_ext(error_code, &error_code_vals_ext, "Unknown (%d)"));
1814 col_set_str(pinfo->cinfo, COL_INFO, "Connection Close");
1816 break;
1817 case FT_GOAWAY:{
1818 uint16_t len_reason;
1819 uint32_t error_code, last_good_stream_id;
1821 proto_tree_add_item_ret_uint(ft_tree, hf_gquic_frame_type_goaway_error_code, tvb, offset, 4, gquic_info->encoding, &error_code);
1822 offset += 4;
1823 proto_tree_add_item_ret_uint(ft_tree, hf_gquic_frame_type_goaway_last_good_stream_id, tvb, offset, 4, gquic_info->encoding, &last_good_stream_id);
1824 offset += 4;
1825 proto_tree_add_item(ft_tree, hf_gquic_frame_type_goaway_reason_phrase_length, tvb, offset, 2, gquic_info->encoding);
1826 len_reason = tvb_get_uint16(tvb, offset, gquic_info->encoding);
1827 offset += 2;
1828 proto_tree_add_item(ft_tree, hf_gquic_frame_type_goaway_reason_phrase, tvb, offset, len_reason, ENC_ASCII);
1829 offset += len_reason;
1830 proto_item_append_text(ti_ft, " Stream ID: %u, Error code: %s", last_good_stream_id, val_to_str_ext(error_code, &error_code_vals_ext, "Unknown (%d)"));
1831 col_set_str(pinfo->cinfo, COL_INFO, "GOAWAY");
1833 break;
1834 case FT_WINDOW_UPDATE:{
1835 uint32_t stream_id;
1837 proto_tree_add_item_ret_uint(ft_tree, hf_gquic_frame_type_wu_stream_id, tvb, offset, 4, gquic_info->encoding, &stream_id);
1838 offset += 4;
1839 proto_tree_add_item(ft_tree, hf_gquic_frame_type_wu_byte_offset, tvb, offset, 8, gquic_info->encoding);
1840 offset += 8;
1841 proto_item_append_text(ti_ft, " Stream ID: %u", stream_id);
1843 break;
1844 case FT_BLOCKED:{
1845 uint32_t stream_id;
1847 proto_tree_add_item_ret_uint(ft_tree, hf_gquic_frame_type_blocked_stream_id, tvb, offset, 4, gquic_info->encoding, &stream_id);
1848 offset += 4;
1849 proto_item_append_text(ti_ft, " Stream ID: %u", stream_id);
1851 break;
1852 case FT_STOP_WAITING:{
1853 uint8_t send_entropy;
1854 if(gquic_info->version_valid && gquic_info->version < 34){ /* No longer Entropy after Q034 */
1855 proto_tree_add_item(ft_tree, hf_gquic_frame_type_sw_send_entropy, tvb, offset, 1, ENC_NA);
1856 send_entropy = tvb_get_uint8(tvb, offset);
1857 proto_item_append_text(ti_ft, " Send Entropy: %u", send_entropy);
1858 offset += 1;
1860 proto_tree_add_item(ft_tree, hf_gquic_frame_type_sw_least_unacked_delta, tvb, offset, len_pkn, gquic_info->encoding);
1861 offset += len_pkn;
1864 break;
1865 case FT_PING: /* No Payload */
1866 default: /* No default */
1867 break;
1870 else { /* Special Frame Types */
1871 uint32_t stream_id, message_tag;
1872 const uint8_t* message_tag_str;
1873 proto_item *ti_stream;
1875 ftflags_tree = proto_item_add_subtree(ti_ftflags, ett_gquic_ftflags);
1876 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_stream , tvb, offset, 1, ENC_NA);
1878 if(frame_type == FT_CRYPTO) {
1879 uint64_t crypto_offset, crypto_length;
1880 int32_t lenvar;
1882 DISSECTOR_ASSERT(gquic_info->version_valid && gquic_info->version >= 50);
1884 col_append_str(pinfo->cinfo, COL_INFO, ", CRYPTO");
1885 offset += 1;
1886 proto_tree_add_item_ret_varint(ft_tree, hf_gquic_crypto_offset, tvb, offset, -1, ENC_VARINT_QUIC, &crypto_offset, &lenvar);
1887 offset += lenvar;
1888 proto_tree_add_item_ret_varint(ft_tree, hf_gquic_crypto_length, tvb, offset, -1, ENC_VARINT_QUIC, &crypto_length, &lenvar);
1889 offset += lenvar;
1890 proto_tree_add_item(ft_tree, hf_gquic_crypto_crypto_data, tvb, offset, (uint32_t)crypto_length, ENC_NA);
1892 if (gquic_info->version == 50) {
1893 message_tag = tvb_get_ntohl(tvb, offset);
1894 ti = proto_tree_add_item_ret_string(ft_tree, hf_gquic_tag, tvb, offset, 4, ENC_ASCII|ENC_NA, pinfo->pool, &message_tag_str);
1895 proto_item_append_text(ti, " (%s)", val_to_str_const(message_tag, message_tag_vals, "Unknown Tag"));
1896 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(message_tag, message_tag_vals, "Unknown"));
1897 offset += 4;
1899 offset = dissect_gquic_tags(tvb, pinfo, ft_tree, offset);
1900 } else { /* T050 and T051 */
1901 tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset, (int)crypto_length);
1902 col_set_writable(pinfo->cinfo, -1, false);
1903 call_dissector_with_data(tls13_handshake_handle, next_tvb, pinfo, ft_tree, GUINT_TO_POINTER(crypto_offset));
1904 col_set_writable(pinfo->cinfo, -1, true);
1905 offset += (uint32_t)crypto_length;
1908 } else if(frame_type & FTFLAGS_STREAM){ /* Stream Flags */
1909 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_stream_f, tvb, offset, 1, ENC_NA);
1910 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_stream_d, tvb, offset, 1, ENC_NA);
1911 if(frame_type & FTFLAGS_STREAM_D){
1912 len_data = 2;
1914 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_stream_ooo, tvb, offset, 1, ENC_NA);
1916 len_offset = get_len_offset(frame_type);
1918 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_stream_ss, tvb, offset, 1, ENC_NA);
1919 len_stream = get_len_stream(frame_type);
1920 offset += 1;
1922 ti_stream = proto_tree_add_item_ret_uint(ft_tree, hf_gquic_stream_id, tvb, offset, len_stream, gquic_info->encoding, &stream_id);
1923 offset += len_stream;
1925 proto_item_append_text(ti_ft, " Stream ID: %u", stream_id);
1927 if(len_offset) {
1928 proto_tree_add_item(ft_tree, hf_gquic_offset, tvb, offset, len_offset, gquic_info->encoding);
1929 offset += len_offset;
1932 if(len_data) {
1933 proto_tree_add_item(ft_tree, hf_gquic_data_len, tvb, offset, len_data, gquic_info->encoding);
1934 offset += len_data;
1937 /* Check if there is some reserved streams (Chapiter 6.1 of draft-shade-gquic-http2-mapping-00) */
1939 switch(stream_id) {
1940 case 1: { /* Reserved (G)QUIC (handshake, crypto, config updates...) */
1941 message_tag = tvb_get_ntohl(tvb, offset);
1942 ti = proto_tree_add_item_ret_string(ft_tree, hf_gquic_tag, tvb, offset, 4, ENC_ASCII|ENC_NA, pinfo->pool, &message_tag_str);
1944 proto_item_append_text(ti_stream, " (Reserved for (G)QUIC handshake, crypto, config updates...)");
1945 proto_item_append_text(ti, " (%s)", val_to_str_const(message_tag, message_tag_vals, "Unknown Tag"));
1946 proto_item_append_text(ti_ft, ", Type: %s (%s)", message_tag_str, val_to_str_const(message_tag, message_tag_vals, "Unknown Tag"));
1947 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(message_tag, message_tag_vals, "Unknown"));
1948 offset += 4;
1950 offset = dissect_gquic_tags(tvb, pinfo, ft_tree, offset);
1951 break;
1953 case 3: { /* Reserved H2 HEADERS (or PUSH_PROMISE..) */
1954 tvbuff_t* tvb_h2;
1956 proto_item_append_text(ti_stream, " (Reserved for H2 HEADERS)");
1958 col_set_str(pinfo->cinfo, COL_INFO, "H2");
1960 tvb_h2 = tvb_new_subset_remaining(tvb, offset);
1962 offset += dissect_http2_pdu(tvb_h2, pinfo, ft_tree, NULL);
1964 break;
1965 default: { /* Data... */
1966 int data_len = tvb_reported_length_remaining(tvb, offset);
1968 col_set_str(pinfo->cinfo, COL_INFO, "DATA");
1970 proto_tree_add_item(ft_tree, hf_gquic_stream_data, tvb, offset, data_len, ENC_NA);
1971 offset += data_len;
1973 break;
1975 } else if (frame_type & FTFLAGS_ACK) { /* ACK Flags */
1977 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_ack, tvb, offset, 1, ENC_NA);
1979 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_ack_n, tvb, offset, 1, ENC_NA);
1981 if(gquic_info->version_valid && gquic_info->version < 34){ /* No longer NACK after Q034 */
1982 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_ack_t, tvb, offset, 1, ENC_NA);
1983 } else {
1984 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_ack_u, tvb, offset, 1, ENC_NA);
1986 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_ack_ll, tvb, offset, 1, ENC_NA);
1988 len_largest_observed = get_len_largest_observed(frame_type);
1990 proto_tree_add_item(ftflags_tree, hf_gquic_frame_type_ack_mm, tvb, offset, 1, ENC_NA);
1991 len_missing_packet = get_len_missing_packet(frame_type);
1992 offset += 1;
1994 if(gquic_info->version_valid && gquic_info->version < 34){ /* Big change after Q034 */
1995 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_received_entropy, tvb, offset, 1, ENC_NA);
1996 offset += 1;
1998 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_largest_observed, tvb, offset, len_largest_observed, gquic_info->encoding);
1999 offset += len_largest_observed;
2001 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_ack_delay_time, tvb, offset, 2, gquic_info->encoding);
2002 offset += 2;
2004 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_num_timestamp, tvb, offset, 1, ENC_NA);
2005 num_timestamp = tvb_get_uint8(tvb, offset);
2006 offset += 1;
2008 if(num_timestamp){
2010 /* Delta Largest Observed */
2011 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_delta_largest_observed, tvb, offset, 1, ENC_NA);
2012 offset += 1;
2014 /* First Timestamp */
2015 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_first_timestamp, tvb, offset, 4, gquic_info->encoding);
2016 offset += 4;
2018 num_timestamp -= 1;
2019 /* Num Timestamp (-1) x (Delta Largest Observed + Time Since Previous Timestamp) */
2020 while(num_timestamp){
2021 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_delta_largest_observed, tvb, offset, 1, ENC_NA);
2022 offset += 1;
2024 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_time_since_previous_timestamp, tvb, offset, 2, gquic_info->encoding);
2025 offset += 2;
2027 num_timestamp--;
2031 if(frame_type & FTFLAGS_ACK_N){
2032 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_num_ranges, tvb, offset, 1, ENC_NA);
2033 num_ranges = tvb_get_uint8(tvb, offset);
2034 offset += 1;
2035 while(num_ranges){
2037 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_missing_packet, tvb, offset, len_missing_packet, gquic_info->encoding);
2038 offset += len_missing_packet;
2040 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_range_length, tvb, offset, 1, ENC_NA);
2041 offset += 1;
2042 num_ranges--;
2045 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_num_revived, tvb, offset, 1, ENC_NA);
2046 num_revived = tvb_get_uint8(tvb, offset);
2047 offset += 1;
2048 while(num_revived){
2050 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_revived_packet, tvb, offset, len_largest_observed, gquic_info->encoding);
2051 offset += len_largest_observed;
2052 num_revived--;
2058 } else {
2060 /* Largest Acked */
2061 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_largest_acked, tvb, offset, len_largest_observed, gquic_info->encoding);
2062 offset += len_largest_observed;
2064 /* Largest Acked Delta Time*/
2065 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_largest_acked_delta_time, tvb, offset, 2, gquic_info->encoding);
2066 offset += 2;
2068 /* Ack Block */
2069 if(frame_type & FTFLAGS_ACK_N){
2070 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_num_blocks, tvb, offset, 1, ENC_NA);
2071 num_blocks = tvb_get_uint8(tvb, offset);
2072 offset += 1;
2075 /* First Ack Block Length */
2076 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_first_ack_block_length, tvb, offset, len_missing_packet, gquic_info->encoding);
2077 offset += len_missing_packet;
2079 while(num_blocks){
2080 /* Gap to next block */
2081 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_gap_to_next_block, tvb, offset, 1, ENC_NA);
2082 offset += 1;
2084 /* Ack Block Length */
2085 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_ack_block_length, tvb, offset, len_missing_packet, gquic_info->encoding);
2086 offset += len_missing_packet;
2088 num_blocks--;
2091 /* Timestamp */
2092 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_num_timestamp, tvb, offset, 1, ENC_NA);
2093 num_timestamp = tvb_get_uint8(tvb, offset);
2094 offset += 1;
2096 if(num_timestamp){
2098 /* Delta Largest Acked */
2099 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_delta_largest_acked, tvb, offset, 1, ENC_NA);
2100 offset += 1;
2102 /* Time Since Largest Acked */
2103 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_time_since_largest_acked, tvb, offset, 4, gquic_info->encoding);
2104 offset += 4;
2106 num_timestamp -= 1;
2107 /* Num Timestamp x (Delta Largest Acked + Time Since Previous Timestamp) */
2108 while(num_timestamp){
2109 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_delta_largest_acked, tvb, offset, 1, ENC_NA);
2110 offset += 1;
2112 proto_tree_add_item(ft_tree, hf_gquic_frame_type_ack_time_since_previous_timestamp, tvb, offset, 2, gquic_info->encoding);
2113 offset += 2;
2115 num_timestamp--;
2121 } else { /* Other ...*/
2122 offset += 1;
2125 return offset;
2129 static int
2130 dissect_gquic_unencrypt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gquic_tree, unsigned offset, uint8_t len_pkn, gquic_info_data_t *gquic_info){
2131 proto_item *ti_prflags;
2132 proto_tree *prflags_tree;
2134 /* Message Authentication Hash */
2135 proto_tree_add_item(gquic_tree, hf_gquic_message_authentication_hash, tvb, offset, 12, ENC_NA);
2136 offset += 12;
2138 if(gquic_info->version_valid && gquic_info->version < 34){ /* No longer Private Flags after Q034 */
2139 /* Private Flags */
2140 ti_prflags = proto_tree_add_item(gquic_tree, hf_gquic_prflags, tvb, offset, 1, ENC_NA);
2141 prflags_tree = proto_item_add_subtree(ti_prflags, ett_gquic_prflags);
2142 proto_tree_add_item(prflags_tree, hf_gquic_prflags_entropy, tvb, offset, 1, ENC_NA);
2143 proto_tree_add_item(prflags_tree, hf_gquic_prflags_fecg, tvb, offset, 1, ENC_NA);
2144 proto_tree_add_item(prflags_tree, hf_gquic_prflags_fec, tvb, offset, 1, ENC_NA);
2145 proto_tree_add_item(prflags_tree, hf_gquic_prflags_rsv, tvb, offset, 1, ENC_NA);
2146 offset += 1;
2149 while(tvb_reported_length_remaining(tvb, offset) > 0){
2150 offset = dissect_gquic_frame_type(tvb, pinfo, gquic_tree, offset, len_pkn, gquic_info);
2153 return offset;
2157 static int
2158 dissect_gquic_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2159 void *data _U_)
2161 proto_item *ti, *ti_puflags; /*, *expert_ti*/
2162 proto_tree *gquic_tree, *puflags_tree;
2163 unsigned offset = 0;
2164 uint8_t puflags, len_cid = 0, len_pkn;
2165 uint64_t cid = 0, pkn;
2166 conversation_t *conv;
2167 gquic_info_data_t *gquic_info;
2169 if (tvb_captured_length(tvb) < GQUIC_MIN_LENGTH)
2170 return 0;
2173 /* get conversation, create if necessary*/
2174 conv = find_or_create_conversation(pinfo);
2176 /* get associated state information, create if necessary */
2177 gquic_info = (gquic_info_data_t *)conversation_get_proto_data(conv, proto_gquic);
2179 if (!gquic_info) {
2180 gquic_info = wmem_new(wmem_file_scope(), gquic_info_data_t);
2181 gquic_info->version = 0;
2182 gquic_info->encoding = ENC_LITTLE_ENDIAN;
2183 gquic_info->version_valid = true;
2184 gquic_info->server_port = 443;
2185 conversation_add_proto_data(conv, proto_gquic, gquic_info);
2188 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GQUIC");
2190 ti = proto_tree_add_item(tree, proto_gquic, tvb, 0, -1, ENC_NA);
2191 gquic_tree = proto_item_add_subtree(ti, ett_gquic);
2193 /* Public Flags */
2194 puflags = tvb_get_uint8(tvb, offset);
2196 /* Get len of CID */
2197 if(puflags & PUFLAGS_CID){
2198 len_cid = 8;
2200 /* check and get (and store) version */
2201 if(puflags & PUFLAGS_VRSN){
2202 gquic_info->version_valid = ws_strtou8(tvb_get_string_enc(pinfo->pool, tvb,
2203 offset + 1 + len_cid + 1, 3, ENC_ASCII), NULL, &gquic_info->version);
2204 if (!gquic_info->version_valid)
2205 expert_add_info(pinfo, gquic_tree, &ei_gquic_version_invalid);
2208 if(gquic_info->version >= 39){ /* After Q039, Integers and floating numbers are written in big endian*/
2209 gquic_info->encoding = ENC_BIG_ENDIAN;
2211 ti_puflags = proto_tree_add_item(gquic_tree, hf_gquic_puflags, tvb, offset, 1, ENC_NA);
2212 puflags_tree = proto_item_add_subtree(ti_puflags, ett_gquic_puflags);
2213 proto_tree_add_item(puflags_tree, hf_gquic_puflags_vrsn, tvb, offset, 1, ENC_NA);
2214 proto_tree_add_item(puflags_tree, hf_gquic_puflags_rst, tvb, offset, 1, ENC_NA);
2215 if (gquic_info->version_valid) {
2216 if(gquic_info->version < 33){
2217 proto_tree_add_item(puflags_tree, hf_gquic_puflags_cid_old, tvb, offset, 1, ENC_NA);
2218 } else {
2219 proto_tree_add_item(puflags_tree, hf_gquic_puflags_dnonce, tvb, offset, 1, ENC_NA);
2220 proto_tree_add_item(puflags_tree, hf_gquic_puflags_cid, tvb, offset, 1, ENC_NA);
2223 proto_tree_add_item(puflags_tree, hf_gquic_puflags_pkn, tvb, offset, 1, ENC_NA);
2224 proto_tree_add_item(puflags_tree, hf_gquic_puflags_mpth, tvb, offset, 1, ENC_NA);
2225 proto_tree_add_item(puflags_tree, hf_gquic_puflags_rsv, tvb, offset, 1, ENC_NA);
2226 offset += 1;
2228 /* CID */
2229 if (len_cid) {
2230 cid = tvb_get_uint64(tvb, offset, gquic_info->encoding);
2231 proto_tree_add_item(gquic_tree, hf_gquic_cid, tvb, offset, len_cid, gquic_info->encoding);
2232 offset += len_cid;
2235 /* Version */
2236 if(puflags & PUFLAGS_VRSN){
2237 if(pinfo->srcport == gquic_info->server_port){ /* Version Negotiation Packet */
2238 while(tvb_reported_length_remaining(tvb, offset) > 0){
2239 proto_tree_add_item(gquic_tree, hf_gquic_version, tvb, offset, 4, ENC_ASCII);
2240 offset += 4;
2242 col_add_fstr(pinfo->cinfo, COL_INFO, "Version Negotiation, CID: %" PRIu64, cid);
2243 return offset;
2245 else{
2246 proto_tree_add_item(gquic_tree, hf_gquic_version, tvb, offset, 4, ENC_ASCII);
2247 offset += 4;
2251 /* Public Reset Packet */
2252 if(puflags & PUFLAGS_RST){
2253 uint32_t tag_number, message_tag;
2255 ti = proto_tree_add_item(gquic_tree, hf_gquic_tag, tvb, offset, 4, ENC_ASCII);
2256 message_tag = tvb_get_ntohl(tvb, offset);
2257 proto_item_append_text(ti, " (%s)", val_to_str_const(message_tag, message_tag_vals, "Unknown Tag"));
2258 offset += 4;
2260 proto_tree_add_item(gquic_tree, hf_gquic_tag_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2261 tag_number = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
2262 offset += 2;
2264 proto_tree_add_item(gquic_tree, hf_gquic_padding, tvb, offset, 2, ENC_NA);
2265 offset += 2;
2267 offset = dissect_gquic_tag(tvb, pinfo, gquic_tree, offset, tag_number);
2269 col_add_fstr(pinfo->cinfo, COL_INFO, "Public Reset, CID: %" PRIu64, cid);
2271 return offset;
2274 /* Diversification Nonce */
2275 if(gquic_info->version_valid && (puflags & PUFLAGS_DNONCE) && (gquic_info->version >= 33)){
2276 if(pinfo->srcport == gquic_info->server_port){ /* Diversification nonce is only present from server to client */
2277 proto_tree_add_item(gquic_tree, hf_gquic_diversification_nonce, tvb, offset, 32, ENC_NA);
2278 offset += 32;
2282 /* Packet Number */
2284 /* Get len of packet number */
2285 len_pkn = get_len_packet_number(puflags);
2286 proto_tree_add_item_ret_uint64(gquic_tree, hf_gquic_packet_number, tvb, offset, len_pkn, gquic_info->encoding, &pkn);
2287 offset += len_pkn;
2289 /* Unencrypt Message (Handshake or Connection Close...) */
2290 if (is_gquic_unencrypt(tvb, pinfo, offset, len_pkn, gquic_info) || g_gquic_debug){
2291 offset = dissect_gquic_unencrypt(tvb, pinfo, gquic_tree, offset, len_pkn, gquic_info);
2292 }else { /* Payload... (encrypted... TODO FIX !) */
2293 col_set_str(pinfo->cinfo, COL_INFO, "Payload (Encrypted)");
2294 proto_tree_add_item(gquic_tree, hf_gquic_payload, tvb, offset, -1, ENC_NA);
2298 col_append_fstr(pinfo->cinfo, COL_INFO, ", PKN: %" PRIu64, pkn);
2300 if(cid){
2301 col_append_fstr(pinfo->cinfo, COL_INFO, ", CID: %" PRIu64, cid);
2305 return offset;
2308 static int
2309 dissect_gquic_q046(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2310 void *data _U_)
2312 proto_item *ti, *ti_firstbyte; /*, *expert_ti*/
2313 proto_tree *gquic_tree, *firstbyte_tree;
2314 unsigned offset = 0;
2315 uint8_t first_byte, len_cid, cil, len_pkn;
2316 uint64_t cid = 0, pkn = 0;
2317 conversation_t *conv;
2318 gquic_info_data_t *gquic_info;
2320 /* get conversation, create if necessary*/
2321 conv = find_or_create_conversation(pinfo);
2323 /* get associated state information, create if necessary */
2324 gquic_info = (gquic_info_data_t *)conversation_get_proto_data(conv, proto_gquic);
2326 if (!gquic_info) {
2327 gquic_info = wmem_new(wmem_file_scope(), gquic_info_data_t);
2328 gquic_info->version = 0;
2329 gquic_info->encoding = ENC_BIG_ENDIAN;
2330 gquic_info->version_valid = true;
2331 gquic_info->server_port = 443;
2332 conversation_add_proto_data(conv, proto_gquic, gquic_info);
2335 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GQUIC");
2337 ti = proto_tree_add_item(tree, proto_gquic, tvb, 0, -1, ENC_NA);
2338 gquic_tree = proto_item_add_subtree(ti, ett_gquic);
2340 /* First byte */
2341 first_byte = tvb_get_uint8(tvb, offset);
2342 len_pkn = (first_byte & 0x03) + 1;
2344 ti_firstbyte = proto_tree_add_item(gquic_tree, hf_gquic_puflags, tvb, offset, 1, ENC_NA);
2345 firstbyte_tree = proto_item_add_subtree(ti_firstbyte, ett_gquic_puflags);
2346 proto_tree_add_item(firstbyte_tree, hf_gquic_header_form, tvb, offset, 1, ENC_NA);
2347 proto_tree_add_item(firstbyte_tree, hf_gquic_fixed_bit, tvb, offset, 1, ENC_NA);
2349 if((first_byte & PUFLAGS_MPTH) && (first_byte & PUFLAGS_RSV)) {
2350 /* Long Header. We handle only Q046 */
2352 gquic_info->version_valid = ws_strtou8(tvb_get_string_enc(pinfo->pool, tvb,
2353 offset + 2, 3, ENC_ASCII), NULL, &gquic_info->version);
2354 if (!gquic_info->version_valid) {
2355 expert_add_info(pinfo, gquic_tree, &ei_gquic_version_invalid);
2358 cil = tvb_get_uint8(tvb, offset + 5);
2359 if(pinfo->srcport == gquic_info->server_port) { /* Server to client */
2360 len_cid = (cil & 0x0F) + 3;
2361 } else {
2362 len_cid = ((cil & 0xF0) >> 4) + 3;
2364 if (len_cid != 8) {
2365 expert_add_info(pinfo, gquic_tree, &ei_gquic_invalid_parameter);
2368 proto_tree_add_item(firstbyte_tree, hf_gquic_long_packet_type, tvb, offset, 1, ENC_NA);
2369 proto_tree_add_item(firstbyte_tree, hf_gquic_long_reserved, tvb, offset, 1, ENC_NA);
2370 proto_tree_add_item(firstbyte_tree, hf_gquic_packet_number_length, tvb, offset, 1, ENC_NA);
2371 offset += 1;
2373 proto_tree_add_item(gquic_tree, hf_gquic_version, tvb, offset, 4, ENC_ASCII);
2374 offset += 4;
2376 proto_tree_add_item(gquic_tree, hf_gquic_dcil, tvb, offset, 1, ENC_NA);
2377 proto_tree_add_item(gquic_tree, hf_gquic_scil, tvb, offset, 1, ENC_NA);
2378 offset += 1;
2380 /* CID */
2381 if (len_cid > 0) {
2382 cid = tvb_get_uint64(tvb, offset, gquic_info->encoding);
2383 proto_tree_add_item(gquic_tree, hf_gquic_cid, tvb, offset, len_cid, gquic_info->encoding);
2385 offset += len_cid;
2387 } else {
2388 /* Short Header. We handle only Q046 */
2390 proto_tree_add_uint(firstbyte_tree, hf_gquic_packet_number_length, tvb, offset, 1, first_byte);
2392 offset += 1;
2394 if(pinfo->srcport == gquic_info->server_port) { /* Server to client */
2395 len_cid = 0;
2396 } else {
2397 len_cid = 8;
2398 cid = tvb_get_uint64(tvb, offset, gquic_info->encoding);
2399 proto_tree_add_item(gquic_tree, hf_gquic_cid, tvb, offset, len_cid, gquic_info->encoding);
2401 offset += len_cid;
2404 /* Packet Number */
2405 proto_tree_add_item_ret_uint64(gquic_tree, hf_gquic_packet_number, tvb, offset, len_pkn, gquic_info->encoding, &pkn);
2406 offset += len_pkn;
2408 /* Unencrypt Message (Handshake or Connection Close...) */
2409 if (is_gquic_unencrypt(tvb, pinfo, offset, len_pkn, gquic_info) || g_gquic_debug){
2410 offset = dissect_gquic_unencrypt(tvb, pinfo, gquic_tree, offset, len_pkn, gquic_info);
2411 }else { /* Payload... (encrypted... TODO FIX !) */
2412 col_set_str(pinfo->cinfo, COL_INFO, "Payload (Encrypted)");
2413 proto_tree_add_item(gquic_tree, hf_gquic_payload, tvb, offset, -1, ENC_NA);
2417 col_append_fstr(pinfo->cinfo, COL_INFO, ", PKN: %" PRIu64, pkn);
2419 if(cid){
2420 col_append_fstr(pinfo->cinfo, COL_INFO, ", CID: %" PRIu64, cid);
2423 return offset;
2426 static int
2427 dissect_gquic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2428 void *data _U_)
2430 uint8_t flags;
2432 flags = tvb_get_uint8(tvb, 0);
2433 if((flags & PUFLAGS_RSV) == 0 && (flags & PUFLAGS_MPTH) == 0)
2434 return dissect_gquic_common(tvb, pinfo, tree, NULL);
2435 return dissect_gquic_q046(tvb, pinfo, tree, NULL);
2438 static bool dissect_gquic_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2441 conversation_t *conversation = NULL;
2442 int offset = 0;
2443 uint8_t flags;
2444 uint32_t version;
2446 if (tvb_captured_length(tvb) < 1) {
2447 return false;
2449 flags = tvb_get_uint8(tvb, offset);
2450 offset += 1;
2452 if((flags & PUFLAGS_RSV) == 0 && (flags & PUFLAGS_MPTH) == 0) {
2453 /* It may be <= Q043 */
2455 /* Verify packet size (Flag (1 byte) + Connection ID (8 bytes) + Version (4 bytes)) */
2456 if (tvb_captured_length(tvb) < 13) {
2457 return false;
2460 /* Check if flags version is set */
2461 if((flags & PUFLAGS_VRSN) == 0) {
2462 return false;
2465 /* Connection ID is always set to "long" (8bytes) too */
2466 if((flags & PUFLAGS_CID) == 0){
2467 return false;
2469 offset += 8;
2471 /* Check if version start with Q02... (0x51 0x30 0x32), Q03... (0x51 0x30 0x33) or Q04... (0x51 0x30 0x34) */
2472 version = tvb_get_ntoh24(tvb, offset);
2473 if ( version == GQUIC_MAGIC2 || version == GQUIC_MAGIC3 || version == GQUIC_MAGIC4) {
2474 conversation = find_or_create_conversation(pinfo);
2475 conversation_set_dissector(conversation, gquic_handle);
2476 dissect_gquic(tvb, pinfo, tree, data);
2477 return true;
2479 } else if((flags & PUFLAGS_MPTH) && (flags & PUFLAGS_RSV)) {
2480 /* It may be > Q043, Long Header. We handle only Q046 */
2482 /* Verify packet size (Flag (1 byte) + Version (4) + DCIL/SCIL (1) + Dest Connection ID (8 bytes)) */
2483 if (tvb_captured_length(tvb) < 14) {
2484 return false;
2487 version = tvb_get_ntohl(tvb, offset);
2488 if (version != GQUIC_VERSION_Q046) {
2489 return false;
2492 conversation = find_or_create_conversation(pinfo);
2493 conversation_set_dissector(conversation, gquic_handle);
2494 dissect_gquic(tvb, pinfo, tree, data);
2495 return true;
2498 return false;
2501 void
2502 proto_register_gquic(void)
2504 module_t *gquic_module;
2506 static hf_register_info hf[] = {
2507 /* Long/Short header for Q046 */
2508 { &hf_gquic_header_form,
2509 { "Header Form", "gquic.header_form",
2510 FT_UINT8, BASE_DEC, VALS(gquic_short_long_header_vals), 0x80,
2511 "The most significant bit (0x80) of the first octet is set to 1 for long headers and 0 for short headers.", HFILL }
2513 { &hf_gquic_fixed_bit,
2514 { "Fixed Bit", "gquic.fixed_bit",
2515 FT_BOOLEAN, 8, NULL, 0x40,
2516 "Must be 1", HFILL }
2518 { &hf_gquic_long_packet_type,
2519 { "Packet Type", "gquic.long.packet_type",
2520 FT_UINT8, BASE_DEC, VALS(gquic_long_packet_type_vals), 0x30,
2521 "Long Header Packet Type", HFILL }
2523 { &hf_gquic_long_reserved,
2524 { "Reserved", "gquic.long.reserved",
2525 FT_UINT8, BASE_DEC, NULL, 0x0c,
2526 "Reserved bits", HFILL }
2528 { &hf_gquic_packet_number_length,
2529 { "Packet Number Length", "gquic.packet_number_length",
2530 FT_UINT8, BASE_DEC, VALS(gquic_packet_number_lengths), 0x03,
2531 "Packet Number field length", HFILL }
2533 { &hf_gquic_dcil,
2534 { "Destination Connection ID Length", "gquic.dcil",
2535 FT_UINT8, BASE_DEC, VALS(quic_cid_lengths), 0xF0,
2536 NULL, HFILL }
2538 { &hf_gquic_scil,
2539 { "Source Connection ID Length", "gquic.scil",
2540 FT_UINT8, BASE_DEC, VALS(quic_cid_lengths), 0x0F,
2541 NULL, HFILL }
2544 /* Public header for < Q046 */
2545 { &hf_gquic_puflags,
2546 { "Public Flags", "gquic.puflags",
2547 FT_UINT8, BASE_HEX, NULL, 0x0,
2548 "Specifying per-packet public flags", HFILL }
2550 { &hf_gquic_puflags_vrsn,
2551 { "Version", "gquic.puflags.version",
2552 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PUFLAGS_VRSN,
2553 "Signifies that this packet also contains the version of the (Google)QUIC protocol", HFILL }
2555 { &hf_gquic_puflags_rst,
2556 { "Reset", "gquic.puflags.reset",
2557 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PUFLAGS_RST,
2558 "Signifies that this packet is a public reset packet", HFILL }
2560 { &hf_gquic_puflags_dnonce,
2561 { "Diversification nonce", "gquic.puflags.nonce",
2562 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PUFLAGS_DNONCE,
2563 "Indicates the presence of a 32 byte diversification nonce", HFILL }
2565 { &hf_gquic_puflags_cid,
2566 { "CID Length", "gquic.puflags.cid",
2567 FT_BOOLEAN, 8, TFS(&puflags_cid_tfs), PUFLAGS_CID,
2568 "Indicates the full 8 byte Connection ID is present", HFILL }
2570 { &hf_gquic_puflags_cid_old,
2571 { "CID Length", "gquic.puflags.cid.old",
2572 FT_UINT8, BASE_HEX, VALS(puflags_cid_old_vals), PUFLAGS_CID_OLD,
2573 "Signifies the Length of CID", HFILL }
2575 { &hf_gquic_puflags_pkn,
2576 { "Packet Number Length", "gquic.puflags.pkn",
2577 FT_UINT8, BASE_HEX, VALS(puflags_pkn_vals), PUFLAGS_PKN,
2578 "Signifies the Length of packet number", HFILL }
2580 { &hf_gquic_puflags_mpth,
2581 { "Multipath", "gquic.puflags.mpth",
2582 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PUFLAGS_MPTH,
2583 "Reserved for multipath use", HFILL }
2585 { &hf_gquic_puflags_rsv,
2586 { "Reserved", "gquic.puflags.rsv",
2587 FT_UINT8, BASE_HEX, NULL, PUFLAGS_RSV,
2588 "Must be Zero", HFILL }
2590 { &hf_gquic_cid,
2591 { "CID", "gquic.cid",
2592 FT_UINT64, BASE_DEC, NULL, 0x0,
2593 "Connection ID 64 bit pseudo random number", HFILL }
2595 { &hf_gquic_version,
2596 { "Version", "gquic.version",
2597 FT_STRING, BASE_NONE, NULL, 0x0,
2598 "32 bit opaque tag that represents the version of the (Google)QUIC", HFILL }
2600 { &hf_gquic_diversification_nonce,
2601 { "Diversification nonce", "gquic.diversification_nonce",
2602 FT_BYTES, BASE_NONE, NULL, 0x0,
2603 NULL, HFILL }
2605 { &hf_gquic_packet_number,
2606 { "Packet Number", "gquic.packet_number",
2607 FT_UINT64, BASE_DEC, NULL, 0x0,
2608 "The lower 8, 16, 32, or 48 bits of the packet number", HFILL }
2611 { &hf_gquic_prflags,
2612 { "Private Flags", "gquic.prflags",
2613 FT_UINT8, BASE_HEX, NULL, 0x0,
2614 "Specifying per-packet Private flags", HFILL }
2617 { &hf_gquic_prflags_entropy,
2618 { "Entropy", "gquic.prflags.entropy",
2619 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PRFLAGS_ENTROPY,
2620 "For data packets, signifies that this packet contains the 1 bit of entropy, for fec packets, contains the xor of the entropy of protected packets", HFILL }
2622 { &hf_gquic_prflags_fecg,
2623 { "FEC Group", "gquic.prflags.fecg",
2624 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PRFLAGS_FECG,
2625 "Indicates whether the fec byte is present.", HFILL }
2627 { &hf_gquic_prflags_fec,
2628 { "FEC", "gquic.prflags.fec",
2629 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PRFLAGS_FEC,
2630 "Signifies that this packet represents an FEC packet", HFILL }
2632 { &hf_gquic_prflags_rsv,
2633 { "Reserved", "gquic.prflags.rsv",
2634 FT_UINT8, BASE_HEX, NULL, PRFLAGS_RSV,
2635 "Must be Zero", HFILL }
2638 { &hf_gquic_message_authentication_hash,
2639 { "Message Authentication Hash", "gquic.message_authentication_hash",
2640 FT_BYTES, BASE_NONE, NULL, 0x0,
2641 "The hash is an FNV1a-128 hash, serialized in little endian order", HFILL }
2643 { &hf_gquic_frame,
2644 { "Frame", "gquic.frame",
2645 FT_NONE, BASE_NONE, NULL, 0x0,
2646 NULL, HFILL }
2648 { &hf_gquic_frame_type,
2649 { "Frame Type", "gquic.frame_type",
2650 FT_UINT8 ,BASE_RANGE_STRING | BASE_HEX, RVALS(frame_type_vals), 0x0,
2651 NULL, HFILL }
2653 { &hf_gquic_frame_type_padding_length,
2654 { "Padding Length", "gquic.frame_type.padding.length",
2655 FT_UINT32, BASE_DEC, NULL, 0x0,
2656 NULL, HFILL }
2658 { &hf_gquic_frame_type_padding,
2659 { "Padding", "gquic.frame_type.padding",
2660 FT_BYTES, BASE_NONE, NULL, 0x0,
2661 "Must be zero", HFILL }
2663 { &hf_gquic_frame_type_rsts_stream_id,
2664 { "Stream ID", "gquic.frame_type.rsts.stream_id",
2665 FT_UINT32, BASE_DEC, NULL, 0x0,
2666 "Stream ID of the stream being terminated", HFILL }
2668 { &hf_gquic_frame_type_rsts_byte_offset,
2669 { "Byte offset", "gquic.frame_type.rsts.byte_offset",
2670 FT_UINT64, BASE_DEC, NULL, 0x0,
2671 "Indicating the absolute byte offset of the end of data for this stream", HFILL }
2673 { &hf_gquic_frame_type_rsts_error_code,
2674 { "Error code", "gquic.frame_type.rsts.error_code",
2675 FT_UINT32, BASE_DEC|BASE_EXT_STRING, &rststream_error_code_vals_ext, 0x0,
2676 "Indicates why the stream is being closed", HFILL }
2678 { &hf_gquic_frame_type_cc_error_code,
2679 { "Error code", "gquic.frame_type.cc.error_code",
2680 FT_UINT32, BASE_DEC|BASE_EXT_STRING, &error_code_vals_ext, 0x0,
2681 "Indicates the reason for closing this connection", HFILL }
2683 { &hf_gquic_frame_type_cc_reason_phrase_length,
2684 { "Reason phrase Length", "gquic.frame_type.cc.reason_phrase.length",
2685 FT_UINT16, BASE_DEC, NULL, 0x0,
2686 "Specifying the length of the reason phrase", HFILL }
2688 { &hf_gquic_frame_type_cc_reason_phrase,
2689 { "Reason phrase", "gquic.frame_type.cc.reason_phrase",
2690 FT_STRING, BASE_NONE, NULL, 0x0,
2691 "An optional human-readable explanation for why the connection was closed", HFILL }
2693 { &hf_gquic_frame_type_goaway_error_code,
2694 { "Error code", "gquic.frame_type.goaway.error_code",
2695 FT_UINT32, BASE_DEC|BASE_EXT_STRING, &error_code_vals_ext, 0x0,
2696 "Indicates the reason for closing this connection", HFILL }
2698 { &hf_gquic_frame_type_goaway_last_good_stream_id,
2699 { "Last Good Stream ID", "gquic.frame_type.goaway.last_good_stream_id",
2700 FT_UINT32, BASE_DEC, NULL, 0x0,
2701 "last Stream ID which was accepted by the sender of the GOAWAY message", HFILL }
2703 { &hf_gquic_frame_type_goaway_reason_phrase_length,
2704 { "Reason phrase Length", "gquic.frame_type.goaway.reason_phrase.length",
2705 FT_UINT16, BASE_DEC, NULL, 0x0,
2706 "Specifying the length of the reason phrase", HFILL }
2708 { &hf_gquic_frame_type_goaway_reason_phrase,
2709 { "Reason phrase", "gquic.frame_type.goaway.reason_phrase",
2710 FT_STRING, BASE_NONE, NULL, 0x0,
2711 "An optional human-readable explanation for why the connection was closed", HFILL }
2713 { &hf_gquic_frame_type_wu_stream_id,
2714 { "Stream ID", "gquic.frame_type.wu.stream_id",
2715 FT_UINT32, BASE_DEC, NULL, 0x0,
2716 "ID of the stream whose flow control windows is begin updated, or 0 to specify the connection-level flow control window", HFILL }
2718 { &hf_gquic_frame_type_wu_byte_offset,
2719 { "Byte offset", "gquic.frame_type.wu.byte_offset",
2720 FT_UINT64, BASE_DEC, NULL, 0x0,
2721 "Indicating the absolute byte offset of data which can be sent on the given stream", HFILL }
2723 { &hf_gquic_frame_type_blocked_stream_id,
2724 { "Stream ID", "gquic.frame_type.blocked.stream_id",
2725 FT_UINT32, BASE_DEC, NULL, 0x0,
2726 "Indicating the stream which is flow control blocked", HFILL }
2728 { &hf_gquic_frame_type_sw_send_entropy,
2729 { "Send Entropy", "gquic.frame_type.sw.send_entropy",
2730 FT_UINT8, BASE_DEC, NULL, 0x0,
2731 "Specifying the cumulative hash of entropy in all sent packets up to the packet with packet number one less than the least unacked packet", HFILL }
2733 { &hf_gquic_frame_type_sw_least_unacked_delta,
2734 { "Least unacked delta", "gquic.frame_type.sw.least_unacked_delta",
2735 FT_UINT64, BASE_DEC, NULL, 0x0,
2736 "A variable length packet number delta with the same length as the packet header's packet number", HFILL }
2738 { &hf_gquic_crypto_offset,
2739 { "Offset", "gquic.crypto.offset",
2740 FT_UINT64, BASE_DEC, NULL, 0x0,
2741 "Byte offset into the stream", HFILL }
2743 { &hf_gquic_crypto_length,
2744 { "Length", "gquic.crypto.length",
2745 FT_UINT64, BASE_DEC, NULL, 0x0,
2746 "Length of the Crypto Data field", HFILL }
2748 { &hf_gquic_crypto_crypto_data,
2749 { "Crypto Data", "gquic.crypto.crypto_data",
2750 FT_NONE, BASE_NONE, NULL, 0x0,
2751 "The cryptographic message data", HFILL }
2753 { &hf_gquic_frame_type_stream,
2754 { "Stream", "gquic.frame_type.stream",
2755 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM,
2756 NULL, HFILL }
2758 { &hf_gquic_frame_type_stream_f,
2759 { "FIN", "gquic.frame_type.stream.f",
2760 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM_F,
2761 NULL, HFILL }
2763 { &hf_gquic_frame_type_stream_d,
2764 { "Data Length", "gquic.frame_type.stream.d",
2765 FT_BOOLEAN, 8, TFS(&len_data_vals), FTFLAGS_STREAM_D,
2766 NULL, HFILL }
2768 { &hf_gquic_frame_type_stream_ooo,
2769 { "Offset Length", "gquic.frame_type.stream.ooo",
2770 FT_UINT8, BASE_DEC, VALS(len_offset_vals), FTFLAGS_STREAM_OOO,
2771 NULL, HFILL }
2773 { &hf_gquic_frame_type_stream_ss,
2774 { "Stream Length", "gquic.frame_type.stream.ss",
2775 FT_UINT8, BASE_DEC, VALS(len_stream_vals), FTFLAGS_STREAM_SS,
2776 NULL, HFILL }
2778 { &hf_gquic_frame_type_ack,
2779 { "ACK", "gquic.frame_type.ack",
2780 FT_BOOLEAN, 8, NULL, FTFLAGS_ACK,
2781 NULL, HFILL }
2783 { &hf_gquic_frame_type_ack_n,
2784 { "NACK", "gquic.frame_type.ack.n",
2785 FT_BOOLEAN, 8, NULL, FTFLAGS_ACK_N,
2786 NULL, HFILL }
2788 { &hf_gquic_frame_type_ack_u,
2789 { "Unused", "gquic.frame_type.ack.u",
2790 FT_BOOLEAN, 8, NULL, FTFLAGS_ACK_U,
2791 NULL, HFILL }
2793 { &hf_gquic_frame_type_ack_t,
2794 { "Truncated", "gquic.frame_type.ack.t",
2795 FT_BOOLEAN, 8, NULL, FTFLAGS_ACK_T,
2796 NULL, HFILL }
2798 { &hf_gquic_frame_type_ack_ll,
2799 { "Largest Observed Length", "gquic.frame_type.ack.ll",
2800 FT_UINT8, BASE_DEC, VALS(len_largest_observed_vals), FTFLAGS_ACK_LL,
2801 "Length of the Largest Observed field as 1, 2, 4, or 6 bytes long", HFILL }
2803 { &hf_gquic_frame_type_ack_mm,
2804 { "Missing Packet Length", "gquic.frame_type.ack.mm",
2805 FT_UINT8, BASE_DEC, VALS(len_missing_packet_vals), FTFLAGS_ACK_MM,
2806 "Length of the Missing Packet Number Delta field as 1, 2, 4, or 6 bytes long", HFILL }
2808 /* ACK before Q034 */
2809 { &hf_gquic_frame_type_ack_received_entropy,
2810 { "Received Entropy", "gquic.frame_type.ack.received_entropy",
2811 FT_UINT8, BASE_DEC, NULL, 0x0,
2812 "Specifying the cumulative hash of entropy in all received packets up to the largest observed packet", HFILL }
2814 { &hf_gquic_frame_type_ack_largest_observed,
2815 { "Largest Observed", "gquic.frame_type.ack.largest_observed",
2816 FT_UINT64, BASE_DEC, NULL, 0x0,
2817 "Representing the largest packet number the peer has observed", HFILL }
2819 { &hf_gquic_frame_type_ack_ack_delay_time,
2820 { "Ack Delay time", "gquic.frame_type.ack.ack_delay_time",
2821 FT_UINT16, BASE_DEC, NULL, 0x0,
2822 "Specifying the time elapsed in microseconds from when largest observed was received until this Ack frame was sent", HFILL }
2824 { &hf_gquic_frame_type_ack_num_timestamp,
2825 { "Num Timestamp", "gquic.frame_type.ack.num_timestamp",
2826 FT_UINT8, BASE_DEC, NULL, 0x0,
2827 "Specifying the number of TCP timestamps that are included in this frame", HFILL }
2829 { &hf_gquic_frame_type_ack_delta_largest_observed,
2830 { "Delta Largest Observed", "gquic.frame_type.ack.delta_largest_observed",
2831 FT_UINT8, BASE_DEC, NULL, 0x0,
2832 "Specifying the packet number delta from the first timestamp to the largest observed", HFILL }
2834 { &hf_gquic_frame_type_ack_first_timestamp,
2835 { "First Timestamp", "gquic.frame_type.ack.first_timestamp",
2836 FT_UINT32, BASE_DEC, NULL, 0x0,
2837 "Specifying the time delta in microseconds, from the beginning of the connection of the arrival of the packet specified by Largest Observed minus Delta Largest Observed", HFILL }
2839 { &hf_gquic_frame_type_ack_time_since_previous_timestamp,
2840 { "Time since Previous timestamp", "gquic.frame_type.ack.time_since_previous_timestamp",
2841 FT_UINT16, BASE_DEC, NULL, 0x0,
2842 "This is the time delta from the previous timestamp", HFILL }
2844 { &hf_gquic_frame_type_ack_num_ranges,
2845 { "Num Ranges", "gquic.frame_type.ack.num_ranges",
2846 FT_UINT8, BASE_DEC, NULL, 0x0,
2847 "Specifying the number of missing packet ranges between largest observed and least unacked", HFILL }
2849 { &hf_gquic_frame_type_ack_missing_packet,
2850 { "Missing Packet Number Delta", "gquic.frame_type.ack.missing_packet",
2851 FT_UINT64, BASE_DEC, NULL, 0x0,
2852 NULL, HFILL }
2854 { &hf_gquic_frame_type_ack_range_length,
2855 { "Range Length", "gquic.frame_type.ack.range_length",
2856 FT_UINT8, BASE_DEC, NULL, 0x0,
2857 "Specifying one less than the number of sequential nacks in the range", HFILL }
2859 { &hf_gquic_frame_type_ack_num_revived,
2860 { "Num Revived", "gquic.frame_type.ack.num_revived",
2861 FT_UINT8, BASE_DEC, NULL, 0x0,
2862 "Specifying the number of revived packets, recovered via FEC", HFILL }
2864 { &hf_gquic_frame_type_ack_revived_packet,
2865 { "Revived Packet Number", "gquic.frame_type.ack.revived_packet",
2866 FT_UINT64, BASE_DEC, NULL, 0x0,
2867 "Representing a packet the peer has revived via FEC", HFILL }
2869 /* ACK after Q034 */
2870 { &hf_gquic_frame_type_ack_largest_acked,
2871 { "Largest Acked", "gquic.frame_type.ack.largest_acked",
2872 FT_UINT64, BASE_DEC, NULL, 0x0,
2873 "Representing the largest packet number the peer has observed", HFILL }
2875 { &hf_gquic_frame_type_ack_largest_acked_delta_time,
2876 { "Largest Acked Delta Time", "gquic.frame_type.ack.largest_acked_delta_time",
2877 FT_UINT16, BASE_DEC, NULL, 0x0,
2878 "Specifying the time elapsed in microseconds from when largest acked was received until this Ack frame was sent", HFILL }
2880 { &hf_gquic_frame_type_ack_num_blocks,
2881 { "Num blocks", "gquic.frame_type.ack.num_blocks",
2882 FT_UINT8, BASE_DEC, NULL, 0x0,
2883 "Specifying one less than the number of ack blocks", HFILL }
2885 { &hf_gquic_frame_type_ack_first_ack_block_length,
2886 { "First Ack block length", "gquic.frame_type.ack.first_ack_block_length",
2887 FT_UINT64, BASE_DEC, NULL, 0x0,
2888 NULL, HFILL }
2890 { &hf_gquic_frame_type_ack_gap_to_next_block,
2891 { "Gap to next block", "gquic.frame_type.ack.gap_to_next_block",
2892 FT_UINT8, BASE_DEC, NULL, 0x0,
2893 "Specifying the number of packets between ack blocks", HFILL }
2895 { &hf_gquic_frame_type_ack_ack_block_length,
2896 { "Ack block length", "gquic.frame_type.ack.ack_block_length",
2897 FT_UINT64, BASE_DEC, NULL, 0x0,
2898 NULL, HFILL }
2900 { &hf_gquic_frame_type_ack_delta_largest_acked,
2901 { "Delta Largest Observed", "gquic.frame_type.ack.delta_largest_acked",
2902 FT_UINT8, BASE_DEC, NULL, 0x0,
2903 "Specifying the packet number delta from the first timestamp to the largest observed", HFILL }
2905 { &hf_gquic_frame_type_ack_time_since_largest_acked,
2906 { "Time Since Largest Acked", "gquic.frame_type.ack.time_since_largest_acked",
2907 FT_UINT32, BASE_DEC, NULL, 0x0,
2908 "Specifying the time delta in microseconds, from the beginning of the connection of the arrival of the packet specified by Largest Observed minus Delta Largest Observed", HFILL }
2913 { &hf_gquic_stream_id,
2914 { "Stream ID", "gquic.stream_id",
2915 FT_UINT32, BASE_DEC, NULL, 0x0,
2916 NULL, HFILL }
2918 { &hf_gquic_offset,
2919 { "Offset", "gquic.offset",
2920 FT_UINT64, BASE_DEC, NULL, 0x0,
2921 NULL, HFILL }
2923 { &hf_gquic_data_len,
2924 { "Data Length", "gquic.data_len",
2925 FT_UINT32, BASE_DEC, NULL, 0x0,
2926 NULL, HFILL }
2928 { &hf_gquic_tag,
2929 { "Tag", "gquic.tag",
2930 FT_STRING, BASE_NONE, NULL, 0x0,
2931 NULL, HFILL }
2933 { &hf_gquic_tag_number,
2934 { "Tag Number", "gquic.tag_number",
2935 FT_UINT16, BASE_DEC, NULL, 0x0,
2936 NULL, HFILL }
2938 { &hf_gquic_tags,
2939 { "Tag/value", "gquic.tags",
2940 FT_NONE, BASE_NONE, NULL, 0x0,
2941 NULL, HFILL }
2943 { &hf_gquic_tag_type,
2944 { "Tag Type", "gquic.tag_type",
2945 FT_STRING, BASE_NONE, NULL, 0x0,
2946 NULL, HFILL }
2948 { &hf_gquic_tag_offset_end,
2949 { "Tag offset end", "gquic.tag_offset_end",
2950 FT_UINT32, BASE_DEC, NULL, 0x0,
2951 NULL, HFILL }
2953 { &hf_gquic_tag_length,
2954 { "Tag length", "gquic.tag_offset_length",
2955 FT_UINT32, BASE_DEC, NULL, 0x0,
2956 NULL, HFILL }
2958 { &hf_gquic_tag_value,
2959 { "Tag/value", "gquic.tag_value",
2960 FT_BYTES, BASE_NONE, NULL, 0x0,
2961 NULL, HFILL }
2963 { &hf_gquic_tag_sni,
2964 { "Server Name Indication", "gquic.tag.sni",
2965 FT_STRING, BASE_NONE, NULL, 0x0,
2966 "The fully qualified DNS name of the server, canonicalised to lowercase with no trailing period", HFILL }
2968 { &hf_gquic_tag_pad,
2969 { "Padding", "gquic.tag.pad",
2970 FT_BYTES, BASE_NONE, NULL, 0x0,
2971 "Pad.....", HFILL }
2973 { &hf_gquic_tag_ver,
2974 { "Version", "gquic.tag.version",
2975 FT_STRING, BASE_NONE, NULL, 0x0,
2976 "Version of gquic supported", HFILL }
2978 { &hf_gquic_tag_pdmd,
2979 { "Proof demand", "gquic.tag.pdmd",
2980 FT_STRING, BASE_NONE, NULL, 0x0,
2981 "a list of tags describing the types of proof acceptable to the client, in preference order", HFILL }
2983 { &hf_gquic_tag_ccs,
2984 { "Common certificate sets", "gquic.tag.ccs",
2985 FT_UINT64, BASE_HEX, NULL, 0x0,
2986 "A series of 64-bit, FNV-1a hashes of sets of common certificates that the client possesses", HFILL }
2988 { &hf_gquic_tag_uaid,
2989 { "Client's User Agent ID", "gquic.tag.uaid",
2990 FT_STRING, BASE_NONE, NULL, 0x0,
2991 NULL, HFILL }
2993 { &hf_gquic_tag_stk,
2994 { "Source-address token", "gquic.tag.stk",
2995 FT_BYTES, BASE_NONE, NULL, 0x0,
2996 NULL, HFILL }
2998 { &hf_gquic_tag_sno,
2999 { "Server nonce", "gquic.tag.sno",
3000 FT_BYTES, BASE_NONE, NULL, 0x0,
3001 NULL, HFILL }
3003 { &hf_gquic_tag_prof,
3004 { "Proof (Signature)", "gquic.tag.prof",
3005 FT_BYTES, BASE_NONE, NULL, 0x0,
3006 NULL, HFILL }
3008 { &hf_gquic_tag_scfg,
3009 { "Server Config Tag", "gquic.tag.scfg",
3010 FT_STRING, BASE_NONE, NULL, 0x0,
3011 NULL, HFILL }
3013 { &hf_gquic_tag_scfg_number,
3014 { "Number Server Config Tag", "gquic.tag.scfg.number",
3015 FT_UINT32, BASE_DEC, NULL, 0x0,
3016 NULL, HFILL }
3018 { &hf_gquic_tag_rrej,
3019 { "Reasons for server sending", "gquic.tag.rrej",
3020 FT_UINT32, BASE_DEC|BASE_EXT_STRING, &handshake_failure_reason_vals_ext, 0x0,
3021 NULL, HFILL }
3023 { &hf_gquic_tag_crt,
3024 { "Certificate chain", "gquic.tag.crt",
3025 FT_BYTES, BASE_NONE, NULL, 0x0,
3026 NULL, HFILL }
3028 { &hf_gquic_tag_aead,
3029 { "Authenticated encryption algorithms", "gquic.tag.aead",
3030 FT_STRING, BASE_NONE, NULL, 0x0,
3031 "A list of tags, in preference order, specifying the AEAD primitives supported by the server", HFILL }
3033 { &hf_gquic_tag_scid,
3034 { "Server Config ID", "gquic.tag.scid",
3035 FT_BYTES, BASE_NONE, NULL, 0x0,
3036 "An opaque, 16-byte identifier for this server config", HFILL }
3038 { &hf_gquic_tag_pubs,
3039 { "Public value", "gquic.tag.pubs",
3040 FT_UINT24, BASE_DEC_HEX, NULL, 0x0,
3041 "A list of public values, 24-bit, little-endian length prefixed", HFILL }
3043 { &hf_gquic_tag_kexs,
3044 { "Key exchange algorithms", "gquic.tag.kexs",
3045 FT_STRING, BASE_NONE, NULL, 0x0,
3046 "A list of tags, in preference order, specifying the key exchange algorithms that the server supports", HFILL }
3048 { &hf_gquic_tag_obit,
3049 { "Server orbit", "gquic.tag.obit",
3050 FT_BYTES, BASE_NONE, NULL, 0x0,
3051 NULL, HFILL }
3053 { &hf_gquic_tag_expy,
3054 { "Expiry", "gquic.tag.expy",
3055 FT_UINT64, BASE_DEC, NULL, 0x0,
3056 "a 64-bit expiry time for the server config in UNIX epoch seconds", HFILL }
3058 { &hf_gquic_tag_nonc,
3059 { "Client nonce", "gquic.tag.nonc",
3060 FT_BYTES, BASE_NONE, NULL, 0x0,
3061 "32 bytes consisting of 4 bytes of timestamp (big-endian, UNIX epoch seconds), 8 bytes of server orbit and 20 bytes of random data", HFILL }
3063 { &hf_gquic_tag_mspc,
3064 { "Max streams per connection", "gquic.tag.mspc",
3065 FT_UINT32, BASE_DEC, NULL, 0x0,
3066 NULL, HFILL }
3068 { &hf_gquic_tag_tcid,
3069 { "Connection ID truncation", "gquic.tag.tcid",
3070 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
3071 NULL, HFILL }
3073 { &hf_gquic_tag_srbf,
3074 { "Socket receive buffer", "gquic.tag.srbf",
3075 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
3076 NULL, HFILL }
3078 { &hf_gquic_tag_icsl,
3079 { "Idle connection state", "gquic.tag.icsl",
3080 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
3081 NULL, HFILL }
3083 { &hf_gquic_tag_scls,
3084 { "Silently close on timeout", "gquic.tag.scls",
3085 FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
3086 NULL, HFILL }
3088 { &hf_gquic_tag_copt,
3089 { "Connection options", "gquic.tag.copt",
3090 FT_STRING, BASE_NONE, NULL, 0x0,
3091 NULL, HFILL }
3093 { &hf_gquic_tag_ccrt,
3094 { "Cached certificates", "gquic.tag.ccrt",
3095 FT_BYTES, BASE_NONE, NULL, 0x0,
3096 NULL, HFILL }
3098 { &hf_gquic_tag_irtt,
3099 { "Estimated initial RTT", "gquic.tag.irtt",
3100 FT_UINT32, BASE_DEC, NULL, 0x0,
3101 "in us", HFILL }
3103 { &hf_gquic_tag_cfcw,
3104 { "Initial session/connection", "gquic.tag.cfcw",
3105 FT_UINT32, BASE_DEC, NULL, 0x0,
3106 NULL, HFILL }
3108 { &hf_gquic_tag_sfcw,
3109 { "Initial stream flow control", "gquic.tag.sfcw",
3110 FT_UINT32, BASE_DEC, NULL, 0x0,
3111 NULL, HFILL }
3113 { &hf_gquic_tag_cetv,
3114 { "Client encrypted tag-value", "gquic.tag.cetv",
3115 FT_BYTES, BASE_NONE, NULL, 0x0,
3116 NULL, HFILL }
3118 { &hf_gquic_tag_xlct,
3119 { "Expected leaf certificate", "gquic.tag.xlct",
3120 FT_BYTES, BASE_NONE, NULL, 0x0,
3121 NULL, HFILL }
3123 { &hf_gquic_tag_nonp,
3124 { "Client Proof nonce", "gquic.tag.nonp",
3125 FT_BYTES, BASE_NONE, NULL, 0x0,
3126 NULL, HFILL }
3128 { &hf_gquic_tag_csct,
3129 { "Signed cert timestamp", "gquic.tag.csct",
3130 FT_BYTES, BASE_NONE, NULL, 0x0,
3131 NULL, HFILL }
3133 { &hf_gquic_tag_ctim,
3134 { "Client Timestamp", "gquic.tag.ctim",
3135 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
3136 NULL, HFILL }
3138 { &hf_gquic_tag_rnon,
3139 { "Public reset nonce proof", "gquic.tag.rnon",
3140 FT_UINT64, BASE_DEC, NULL, 0x0,
3141 NULL, HFILL }
3143 { &hf_gquic_tag_rseq,
3144 { "Rejected Packet Number", "gquic.tag.rseq",
3145 FT_UINT64, BASE_DEC, NULL, 0x0,
3146 "a 64-bit packet number", HFILL }
3148 { &hf_gquic_tag_cadr_addr_type,
3149 { "Client IP Address Type", "gquic.tag.caddr.addr.type",
3150 FT_UINT16, BASE_DEC, VALS(cadr_type_vals), 0x0,
3151 NULL, HFILL }
3153 { &hf_gquic_tag_cadr_addr_ipv4,
3154 { "Client IP Address", "gquic.tag.caddr.addr.ipv4",
3155 FT_IPv4, BASE_NONE, NULL, 0x0,
3156 NULL, HFILL }
3158 { &hf_gquic_tag_cadr_addr_ipv6,
3159 { "Client IP Address", "gquic.tag.caddr.addr.ipv6",
3160 FT_IPv6, BASE_NONE, NULL, 0x0,
3161 NULL, HFILL }
3163 { &hf_gquic_tag_cadr_addr,
3164 { "Client IP Address", "gquic.tag.caddr.addr",
3165 FT_BYTES, BASE_NONE, NULL, 0x0,
3166 NULL, HFILL }
3168 { &hf_gquic_tag_cadr_port,
3169 { "Client Port (Source)", "gquic.tag.caddr.port",
3170 FT_UINT16, BASE_DEC, NULL, 0x0,
3171 NULL, HFILL }
3173 { &hf_gquic_tag_mids,
3174 { "Max incoming dynamic streams", "gquic.tag.mids",
3175 FT_UINT32, BASE_DEC, NULL, 0x0,
3176 NULL, HFILL }
3178 { &hf_gquic_tag_fhol,
3179 { "Force Head Of Line blocking", "gquic.tag.fhol",
3180 FT_UINT32, BASE_DEC, NULL, 0x0,
3181 NULL, HFILL }
3183 { &hf_gquic_tag_sttl,
3184 { "Server Config TTL", "gquic.tag.sttl",
3185 FT_UINT64, BASE_DEC, NULL, 0x0,
3186 NULL, HFILL }
3188 { &hf_gquic_tag_smhl,
3189 { "Support Max Header List (size)", "gquic.tag.smhl",
3190 FT_UINT64, BASE_DEC, NULL, 0x0,
3191 NULL, HFILL }
3193 { &hf_gquic_tag_tbkp,
3194 { "Token Binding Key Params.", "gquic.tag.tbkp",
3195 FT_STRING, BASE_NONE, NULL, 0x0,
3196 NULL, HFILL }
3198 { &hf_gquic_tag_mad0,
3199 { "Max Ack Delay", "gquic.tag.mad0",
3200 FT_UINT32, BASE_DEC, NULL, 0x0,
3201 NULL, HFILL }
3203 { &hf_gquic_tag_qlve,
3204 { "Legacy Version Encapsulation", "gquic.tag.qlve",
3205 FT_BYTES, BASE_NONE, NULL, 0x0,
3206 NULL, HFILL }
3208 { &hf_gquic_tag_cgst,
3209 { "Congestion Control Feedback Type", "gquic.tag.cgst",
3210 FT_BYTES, BASE_NONE, NULL, 0x0,
3211 NULL, HFILL }
3213 { &hf_gquic_tag_epid,
3214 { "Endpoint identifier", "gquic.tag.epid",
3215 FT_STRING, BASE_NONE, NULL, 0x0,
3216 NULL, HFILL }
3218 { &hf_gquic_tag_srst,
3219 { "Stateless Reset Token", "gquic.tag.srst",
3220 FT_BYTES, BASE_NONE, NULL, 0x0,
3221 NULL, HFILL }
3224 { &hf_gquic_tag_unknown,
3225 { "Unknown tag", "gquic.tag.unknown",
3226 FT_BYTES, BASE_NONE, NULL, 0x0,
3227 NULL, HFILL }
3229 { &hf_gquic_padding,
3230 { "Padding", "gquic.padding",
3231 FT_BYTES, BASE_NONE, NULL, 0x0,
3232 NULL, HFILL }
3234 { &hf_gquic_stream_data,
3235 { "Stream Data", "gquic.stream_data",
3236 FT_BYTES, BASE_NONE, NULL, 0x0,
3237 NULL, HFILL }
3239 { &hf_gquic_payload,
3240 { "Payload", "gquic.payload",
3241 FT_BYTES, BASE_NONE, NULL, 0x0,
3242 "(Google) QUIC Payload..", HFILL }
3247 static int *ett[] = {
3248 &ett_gquic,
3249 &ett_gquic_puflags,
3250 &ett_gquic_prflags,
3251 &ett_gquic_ft,
3252 &ett_gquic_ftflags,
3253 &ett_gquic_tag_value
3256 static ei_register_info ei[] = {
3257 { &ei_gquic_tag_undecoded, { "gquic.tag.undecoded", PI_UNDECODED, PI_NOTE, "Dissector for (Google)QUIC Tag code not implemented, Contact Wireshark developers if you want this supported", EXPFILL }},
3258 { &ei_gquic_tag_length, { "gquic.tag.length.truncated", PI_MALFORMED, PI_NOTE, "Truncated Tag Length...", EXPFILL }},
3259 { &ei_gquic_tag_unknown, { "gquic.tag.unknown.data", PI_UNDECODED, PI_NOTE, "Unknown Data", EXPFILL }},
3260 { &ei_gquic_version_invalid, { "gquic.version.invalid", PI_MALFORMED, PI_ERROR, "Invalid Version", EXPFILL }},
3261 { &ei_gquic_invalid_parameter, { "gquic.invalid.parameter", PI_MALFORMED, PI_ERROR, "Invalid Parameter", EXPFILL }},
3262 { &ei_gquic_length_invalid, { "gquic.length.invalid", PI_PROTOCOL, PI_WARN, "Invalid Length", EXPFILL }},
3263 { &ei_gquic_data_invalid, { "gquic.data.invalid", PI_PROTOCOL, PI_WARN, "Invalid Data", EXPFILL }},
3266 expert_module_t *expert_gquic;
3268 proto_gquic = proto_register_protocol("GQUIC (Google Quick UDP Internet Connections)", "GQUIC", "gquic");
3270 proto_register_field_array(proto_gquic, hf, array_length(hf));
3271 proto_register_subtree_array(ett, array_length(ett));
3273 gquic_module = prefs_register_protocol(proto_gquic, NULL);
3275 prefs_register_bool_preference(gquic_module, "debug.quic",
3276 "Force decode of all (Google) QUIC Payload",
3277 "Help for debug...",
3278 &g_gquic_debug);
3280 expert_gquic = expert_register_protocol(proto_gquic);
3281 expert_register_field_array(expert_gquic, ei, array_length(ei));
3283 gquic_handle = register_dissector("gquic", dissect_gquic, proto_gquic);
3286 void
3287 proto_reg_handoff_gquic(void)
3289 tls13_handshake_handle = find_dissector("tls13-handshake");
3290 quic_handle = find_dissector("quic");
3291 dissector_add_uint_range_with_preference("udp.port", "", gquic_handle);
3292 heur_dissector_add("udp", dissect_gquic_heur, "Google QUIC", "gquic", proto_gquic, HEURISTIC_ENABLE);
3297 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3299 * Local variables:
3300 * c-basic-offset: 4
3301 * tab-width: 8
3302 * indent-tabs-mode: nil
3303 * End:
3305 * vi: set shiftwidth=4 tabstop=8 expandtab:
3306 * :indentSize=4:tabSize=8:noTabs=true: