1#![allow(missing_docs)]
2fn main() {
11 let packet = rfc9001_client_initial();
13
14 let header = match quic_parser::parse_initial(&packet) {
15 Ok(h) => h,
16 Err(e) => {
17 eprintln!("header parse error: {e}");
18 return;
19 }
20 };
21
22 println!("Parsed header:");
23 println!(" version: {:#010x}", header.version);
24 println!(" dcid: {}", hex(header.dcid));
25 println!(" scid: {}", hex(header.scid));
26 println!(" payload: {} bytes", header.payload.len());
27
28 let decrypted = match quic_parser::decrypt_initial(&packet, &header) {
29 Ok(d) => d,
30 Err(e) => {
31 eprintln!("decryption error: {e}");
32 return;
33 }
34 };
35
36 println!("Decrypted {} bytes of frame data", decrypted.len());
37
38 let frames = match quic_parser::parse_crypto_frames(&decrypted) {
39 Ok(f) => f,
40 Err(e) => {
41 eprintln!("frame parse error: {e}");
42 return;
43 }
44 };
45
46 println!("Found {} CRYPTO frame(s)", frames.len());
47 for (i, f) in frames.iter().enumerate() {
48 println!(" frame {i}: offset={}, len={}", f.offset, f.data.len());
49 }
50
51 let stream = quic_parser::reassemble_crypto_stream(&frames);
52 println!("Reassembled crypto stream: {} bytes", stream.len());
53
54 if stream.len() >= 6 {
55 let msg_type = stream[0];
56 let length = u32::from_be_bytes([0, stream[1], stream[2], stream[3]]);
57 let tls_version = u16::from_be_bytes([stream[4], stream[5]]);
58 println!("TLS handshake: type={msg_type:#04x} length={length} version={tls_version:#06x}");
59 }
60}
61
62fn hex(bytes: &[u8]) -> String {
63 bytes.iter().map(|b| format!("{b:02x}")).collect()
64}
65
66fn rfc9001_client_initial() -> Vec<u8> {
67 hex_decode(concat!(
70 "c000000001088394c8f03e515708",
71 "0000449e",
72 "7b9aec34d1b1c98dd7689fb8ec11",
73 "d242b123dc9bd8bab936b47d92ec356c",
74 "0bab7df5976d27cd449f63300099f399",
75 "1c260ec4c60d17b31f8429157bb35a12",
76 "82a643a8d2262cad67500cadb8e7378c",
77 "8eb7539ec4d4905fed1bee1fc8aafba1",
78 "7c750e2c7ace01e6005f80fcb7df6212",
79 "30c83711b39343fa028cea7f7fb5ff89",
80 "eac2308249a02252155e2347b63d58c5",
81 "457afd84d05dfffdb20392844ae81215",
82 "4682e9cf012f9021a6f0be17ddd0c208",
83 "4dce25ff9b06cde535d0f920a2db1bf3",
84 "62c23e596dee38f5a6cf3948838a3aec",
85 "4e15daf8500a6ef69ec4e3feb6b1d98e",
86 "610ac8b7ec3faf6ad760b7bad1db4ba3",
87 "485e8a94dc250ae3fdb41ed15fb6a8e5",
88 "eba0fc3dd60bc8e30c5c4287e53805db",
89 "059ae0648db2f64264ed5e39be2e20d8",
90 "2df566da8dd5998ccabdae053060ae6c",
91 "7b4378e846d29f37ed7b4ea9ec5d82e7",
92 "961b7f25a9323851f681d582363aa5f8",
93 "9937f5a67258bf63ad6f1a0b1d96dbd4",
94 "faddfcefc5266ba6611722395c906556",
95 "be52afe3f565636ad1b17d508b73d874",
96 "3eeb524be22b3dcbc2c7468d54119c74",
97 "68449a13d8e3b95811a198f3491de3e7",
98 "fe942b330407abf82a4ed7c1b311663a",
99 "c69890f4157015853d91e923037c227a",
100 "33cdd5ec281ca3f79c44546b9d90ca00",
101 "f064c99e3dd97911d39fe9c5d0b23a22",
102 "9a234cb36186c4819e8b9c592772663229",
103 "1d6a418211cc2962e20fe47feb3edf33",
104 "0f2c603a9d48c0fcb5699dbfe5896425",
105 "c5bac4aee82e57a85aaf4e2513e4f057",
106 "96b07ba2ee47d80506f8d2c25e50fd14",
107 "de71e6c418559302f939b0e1abd576f2",
108 "79c4b2e0feb85c1f28ff18f58891ffef",
109 "132eef2fa09346aee33c28eb130ff28f",
110 "5b766953334113211996d20011a198e3",
111 "fc433f9f2541010ae17c1bf202580f60",
112 "47472fb36857fe843b19f5984009ddc3",
113 "24044e847a4f4a0ab34f719595de3725",
114 "2d6235365e9b84392b061085349d7320",
115 "3a4a13e96f5432ec0fd4a1ee65accdd5",
116 "e3904df54c1da510b0ff20dcc0c77fcb",
117 "2c0e0eb605cb0504db87632cf3d8b4da",
118 "e6e705769d1de354270123cb11450efc",
119 "60ac47683d7b8d0f811365565fd98c4c",
120 "8eb936bcab8d069fc33bd801b03adea2",
121 "e1fbc5aa463d08ca19896d2bf59a071b",
122 "851e6c239052172f296bfb5e72404790",
123 "a2181014f3b94a4e97d117b438130368",
124 "cc39dbb2d198065ae3986547926cd216",
125 "2f40a29f0c3c8745c0f50fba3852e566",
126 "d44575c29d39a03f0cda721984b6f440",
127 "591f355e12d439ff150aab7613499dbd",
128 "49adabc8676eef023b15b65bfc5ca069",
129 "48109f23f350db82123535eb8a7433bd",
130 "abcb909271a6ecbcb58b936a88cd4e8f",
131 "2e6ff5800175f113253d8fa9ca8885c2",
132 "f552e657dc603f252e1a8e308f76f0be",
133 "79e2fb8f5d5fbbe2e30ecadd220723c8",
134 "c0aea8078cdfcb3868263ff8f0940054",
135 "da48781893a7e49ad5aff4af300cd804",
136 "a6b6279ab3ff3afb64491c85194aab76",
137 "0d58a606654f9f4400e8b38591356fbf",
138 "6425aca26dc85244259ff2b19c41b9f9",
139 "6f3ca9ec1dde434da7d2d392b905ddf3",
140 "d1f9af93d1af5950bd493f5aa731b405",
141 "6df31bd267b6b90a079831aaf579be0a",
142 "39013137aac6d404f518cfd46840647e",
143 "78bfe706ca4cf5e9c5453e9f7cfd2b8b",
144 "4c8d169a44e55c88d4a9a7f947424110",
145 "92abbdf8b889e5c199d096e3f24788",
146 ))
147}
148
149fn hex_decode(s: &str) -> Vec<u8> {
150 (0..s.len())
151 .step_by(2)
152 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid hex"))
153 .collect()
154}