1pub mod builder;
15pub mod frames;
16pub mod headers;
17pub mod varint;
18
19pub use builder::{QuicBuilder, QuicInitialBuilder};
20pub use frames::{FrameType, QuicFrame, parse_frames};
21pub use headers::{QuicLongHeader, QuicPacketType, QuicShortHeader, packet_type};
22pub use varint::{decode as varint_decode, encode as varint_encode};
23
24use crate::layer::field::{FieldDesc, FieldError, FieldType, FieldValue};
25use crate::layer::{Layer, LayerIndex, LayerKind};
26
27pub const QUIC_MIN_HEADER_LEN: usize = 1;
29
30pub static QUIC_FIELDS: &[FieldDesc] = &[
37 FieldDesc::new("header_form", 0, 1, FieldType::U8),
38 FieldDesc::new("fixed_bit", 0, 1, FieldType::U8),
39 FieldDesc::new("packet_type", 0, 1, FieldType::U8),
40 FieldDesc::new("long_packet_type", 0, 1, FieldType::U8),
41 FieldDesc::new("packet_number_len", 0, 1, FieldType::U8),
42 FieldDesc::new("version", 1, 4, FieldType::U32),
43 FieldDesc::new("dst_conn_id_len", 5, 1, FieldType::U8),
45 FieldDesc::new("src_conn_id_len", 5, 1, FieldType::U8),
46 FieldDesc::new("dst_conn_id", 6, 0, FieldType::Bytes),
47 FieldDesc::new("src_conn_id", 6, 0, FieldType::Bytes),
48 FieldDesc::new("length", 6, 8, FieldType::U64),
49 FieldDesc::new("packet_number", 6, 4, FieldType::U32),
50];
51
52#[derive(Debug, Clone)]
58pub struct QuicLayer {
59 pub index: LayerIndex,
60}
61
62impl QuicLayer {
63 #[must_use]
65 pub fn new(start: usize, end: usize) -> Self {
66 Self {
67 index: LayerIndex::new(LayerKind::Quic, start, end),
68 }
69 }
70
71 #[must_use]
73 pub fn from_index(index: LayerIndex) -> Self {
74 Self { index }
75 }
76
77 #[must_use]
83 pub fn is_long_header(&self, buf: &[u8]) -> bool {
84 let slice = self.index.slice(buf);
85 !slice.is_empty() && slice[0] & 0x80 != 0
86 }
87
88 #[must_use]
90 pub fn packet_type(&self, buf: &[u8]) -> Option<QuicPacketType> {
91 let slice = self.index.slice(buf);
92 if slice.is_empty() {
93 return None;
94 }
95 let first = slice[0];
96 let version = if slice.len() >= 5 {
97 u32::from_be_bytes([slice[1], slice[2], slice[3], slice[4]])
98 } else {
99 0
100 };
101 Some(headers::packet_type(first, version))
102 }
103
104 #[must_use]
107 pub fn version(&self, buf: &[u8]) -> Option<u32> {
108 if !self.is_long_header(buf) {
109 return None;
110 }
111 let slice = self.index.slice(buf);
112 if slice.len() < 5 {
113 return None;
114 }
115 Some(u32::from_be_bytes([slice[1], slice[2], slice[3], slice[4]]))
116 }
117
118 #[must_use]
120 pub fn summary(&self, buf: &[u8]) -> String {
121 match self.packet_type(buf) {
122 Some(pt) => format!("QUIC {}", pt.name()),
123 None => "QUIC".to_string(),
124 }
125 }
126
127 #[must_use]
133 pub fn header_len(&self, buf: &[u8]) -> usize {
134 let slice = self.index.slice(buf);
135 if slice.is_empty() {
136 return QUIC_MIN_HEADER_LEN;
137 }
138
139 if self.is_long_header(buf) {
140 match QuicLongHeader::parse(slice) {
141 Some(hdr) => hdr.header_len,
142 None => QUIC_MIN_HEADER_LEN,
143 }
144 } else {
145 QUIC_MIN_HEADER_LEN
147 }
148 }
149
150 #[must_use]
152 pub fn field_names() -> &'static [&'static str] {
153 &[
154 "header_form",
155 "fixed_bit",
156 "packet_type",
157 "long_packet_type",
158 "packet_number_len",
159 "version",
160 "dst_conn_id_len",
161 "src_conn_id_len",
162 "dst_conn_id",
163 "src_conn_id",
164 "length",
165 "packet_number",
166 ]
167 }
168
169 #[must_use]
171 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
172 let slice = self.index.slice(buf);
173 match name {
174 "header_form" => {
175 if slice.is_empty() {
176 return Some(Err(FieldError::BufferTooShort {
177 offset: self.index.start,
178 need: 1,
179 have: 0,
180 }));
181 }
182 let v = (slice[0] >> 7) & 0x01;
183 Some(Ok(FieldValue::U8(v)))
184 },
185 "fixed_bit" => {
186 if slice.is_empty() {
187 return Some(Err(FieldError::BufferTooShort {
188 offset: self.index.start,
189 need: 1,
190 have: 0,
191 }));
192 }
193 let v = (slice[0] >> 6) & 0x01;
194 Some(Ok(FieldValue::U8(v)))
195 },
196 "packet_type" => {
197 if slice.is_empty() {
198 return Some(Err(FieldError::BufferTooShort {
199 offset: self.index.start,
200 need: 1,
201 have: 0,
202 }));
203 }
204 let v = if slice[0] & 0x80 != 0 {
206 (slice[0] & 0x30) >> 4
207 } else {
208 0
209 };
210 Some(Ok(FieldValue::U8(v)))
211 },
212 "version" => {
213 if slice.len() < 5 {
214 return Some(Err(FieldError::BufferTooShort {
215 offset: self.index.start + 1,
216 need: 4,
217 have: slice.len().saturating_sub(1),
218 }));
219 }
220 let v = u32::from_be_bytes([slice[1], slice[2], slice[3], slice[4]]);
221 Some(Ok(FieldValue::U32(v)))
222 },
223 "long_packet_type" => {
224 if slice.is_empty() {
225 return Some(Err(FieldError::BufferTooShort {
226 offset: self.index.start,
227 need: 1,
228 have: 0,
229 }));
230 }
231 let v = (slice[0] & 0x30) >> 4;
233 Some(Ok(FieldValue::U8(v)))
234 },
235 "packet_number_len" => {
236 if slice.is_empty() {
237 return Some(Err(FieldError::BufferTooShort {
238 offset: self.index.start,
239 need: 1,
240 have: 0,
241 }));
242 }
243 let v = slice[0] & 0x03;
245 Some(Ok(FieldValue::U8(v)))
246 },
247 "dst_conn_id_len" => {
248 if slice.len() < 6 {
249 return Some(Err(FieldError::BufferTooShort {
250 offset: self.index.start + 5,
251 need: 1,
252 have: slice.len().saturating_sub(5),
253 }));
254 }
255 if slice[0] & 0x80 == 0 {
256 return Some(Ok(FieldValue::U8(0)));
258 }
259 Some(Ok(FieldValue::U8(slice[5])))
260 },
261 "src_conn_id_len" => {
262 if slice[0] & 0x80 == 0 {
263 return Some(Ok(FieldValue::U8(0)));
265 }
266 match QuicLongHeader::parse(slice) {
267 Some(hdr) => Some(Ok(FieldValue::U8(hdr.src_conn_id.len() as u8))),
268 None => Some(Err(FieldError::BufferTooShort {
269 offset: self.index.start,
270 need: 7,
271 have: slice.len(),
272 })),
273 }
274 },
275 "dst_conn_id" => {
276 if slice[0] & 0x80 == 0 {
277 return Some(Ok(FieldValue::Bytes(vec![])));
279 }
280 match QuicLongHeader::parse(slice) {
281 Some(hdr) => Some(Ok(FieldValue::Bytes(hdr.dst_conn_id))),
282 None => Some(Err(FieldError::BufferTooShort {
283 offset: self.index.start,
284 need: 7,
285 have: slice.len(),
286 })),
287 }
288 },
289 "src_conn_id" => {
290 if slice[0] & 0x80 == 0 {
291 return Some(Ok(FieldValue::Bytes(vec![])));
293 }
294 match QuicLongHeader::parse(slice) {
295 Some(hdr) => Some(Ok(FieldValue::Bytes(hdr.src_conn_id))),
296 None => Some(Err(FieldError::BufferTooShort {
297 offset: self.index.start,
298 need: 7,
299 have: slice.len(),
300 })),
301 }
302 },
303 "length" | "packet_number" => {
304 if slice[0] & 0x80 == 0 {
305 return None;
307 }
308 let hdr = match QuicLongHeader::parse(slice) {
309 Some(h) => h,
310 None => {
311 return Some(Err(FieldError::BufferTooShort {
312 offset: self.index.start,
313 need: 7,
314 have: slice.len(),
315 }));
316 },
317 };
318 let mut pos = hdr.header_len; if hdr.packet_type == headers::QuicPacketType::Initial {
322 match varint::decode(&slice[pos..]) {
323 Some((token_len, token_varint_bytes)) => {
324 pos += token_varint_bytes + token_len as usize;
325 },
326 None => {
327 return Some(Err(FieldError::BufferTooShort {
328 offset: self.index.start + pos,
329 need: 1,
330 have: slice.len().saturating_sub(pos),
331 }));
332 },
333 }
334 }
335
336 let (length_val, length_varint_bytes) = match varint::decode(&slice[pos..]) {
338 Some(v) => v,
339 None => {
340 return Some(Err(FieldError::BufferTooShort {
341 offset: self.index.start + pos,
342 need: 1,
343 have: slice.len().saturating_sub(pos),
344 }));
345 },
346 };
347
348 if name == "length" {
349 return Some(Ok(FieldValue::U64(length_val)));
350 }
351
352 pos += length_varint_bytes;
354 let pn_len = (slice[0] & 0x03) as usize + 1;
355 if pos + pn_len > slice.len() {
356 return Some(Err(FieldError::BufferTooShort {
357 offset: self.index.start + pos,
358 need: pn_len,
359 have: slice.len().saturating_sub(pos),
360 }));
361 }
362 let pn_bytes = &slice[pos..pos + pn_len];
363 let pn: u32 = match pn_len {
364 1 => u32::from(pn_bytes[0]),
365 2 => u32::from(u16::from_be_bytes([pn_bytes[0], pn_bytes[1]])),
366 3 => {
367 (u32::from(pn_bytes[0]) << 16)
368 | (u32::from(pn_bytes[1]) << 8)
369 | u32::from(pn_bytes[2])
370 },
371 4 => u32::from_be_bytes([pn_bytes[0], pn_bytes[1], pn_bytes[2], pn_bytes[3]]),
372 _ => unreachable!(),
373 };
374 Some(Ok(FieldValue::U32(pn)))
375 },
376 _ => None,
377 }
378 }
379
380 pub fn set_field(
382 &self,
383 buf: &mut [u8],
384 name: &str,
385 value: FieldValue,
386 ) -> Option<Result<(), FieldError>> {
387 let start = self.index.start;
388 match name {
389 "header_form" => {
390 let v = match value {
391 FieldValue::U8(v) => v,
392 other => {
393 return Some(Err(FieldError::InvalidValue(format!(
394 "header_form: expected U8, got {other:?}"
395 ))));
396 },
397 };
398 if buf.len() <= start {
399 return Some(Err(FieldError::BufferTooShort {
400 offset: start,
401 need: 1,
402 have: 0,
403 }));
404 }
405 if v != 0 {
406 buf[start] |= 0x80;
407 } else {
408 buf[start] &= !0x80;
409 }
410 Some(Ok(()))
411 },
412 "fixed_bit" => {
413 let v = match value {
414 FieldValue::U8(v) => v,
415 other => {
416 return Some(Err(FieldError::InvalidValue(format!(
417 "fixed_bit: expected U8, got {other:?}"
418 ))));
419 },
420 };
421 if buf.len() <= start {
422 return Some(Err(FieldError::BufferTooShort {
423 offset: start,
424 need: 1,
425 have: 0,
426 }));
427 }
428 if v != 0 {
429 buf[start] |= 0x40;
430 } else {
431 buf[start] &= !0x40;
432 }
433 Some(Ok(()))
434 },
435 "packet_type" => {
436 let v = match value {
437 FieldValue::U8(v) => v,
438 other => {
439 return Some(Err(FieldError::InvalidValue(format!(
440 "packet_type: expected U8, got {other:?}"
441 ))));
442 },
443 };
444 if buf.len() <= start {
445 return Some(Err(FieldError::BufferTooShort {
446 offset: start,
447 need: 1,
448 have: 0,
449 }));
450 }
451 buf[start] = (buf[start] & !0x30) | ((v & 0x03) << 4);
453 Some(Ok(()))
454 },
455 "version" => {
456 let v = match value {
457 FieldValue::U32(v) => v,
458 other => {
459 return Some(Err(FieldError::InvalidValue(format!(
460 "version: expected U32, got {other:?}"
461 ))));
462 },
463 };
464 if buf.len() < start + 5 {
465 return Some(Err(FieldError::BufferTooShort {
466 offset: start + 1,
467 need: 4,
468 have: buf.len().saturating_sub(start + 1),
469 }));
470 }
471 buf[start + 1..start + 5].copy_from_slice(&v.to_be_bytes());
472 Some(Ok(()))
473 },
474 _ => None,
475 }
476 }
477}
478
479impl Layer for QuicLayer {
480 fn kind(&self) -> LayerKind {
481 LayerKind::Quic
482 }
483
484 fn summary(&self, data: &[u8]) -> String {
485 self.summary(data)
486 }
487
488 fn header_len(&self, data: &[u8]) -> usize {
489 self.header_len(data)
490 }
491
492 fn field_names(&self) -> &'static [&'static str] {
493 QuicLayer::field_names()
494 }
495
496 fn hashret(&self, _data: &[u8]) -> Vec<u8> {
497 vec![]
498 }
499}
500
501#[cfg(test)]
502mod tests {
503 use super::*;
504
505 fn from_hex(s: &str) -> Vec<u8> {
507 (0..s.len())
508 .step_by(2)
509 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
510 .collect()
511 }
512
513 fn make_initial_buf() -> Vec<u8> {
514 QuicBuilder::initial()
515 .version(1)
516 .dst_conn_id(vec![0x01, 0x02])
517 .src_conn_id(vec![])
518 .payload(vec![])
519 .build()
520 }
521
522 #[test]
523 fn test_quic_layer_new() {
524 let buf = make_initial_buf();
525 let layer = QuicLayer::new(0, buf.len());
526 assert!(layer.is_long_header(&buf));
527 assert_eq!(layer.packet_type(&buf), Some(QuicPacketType::Initial));
528 assert_eq!(layer.version(&buf), Some(1));
529 }
530
531 #[test]
532 fn test_summary_initial() {
533 let buf = make_initial_buf();
534 let layer = QuicLayer::new(0, buf.len());
535 let s = layer.summary(&buf);
536 assert!(s.contains("Initial"), "summary: {}", s);
537 }
538
539 #[test]
540 fn test_get_field_header_form() {
541 let buf = make_initial_buf();
542 let layer = QuicLayer::new(0, buf.len());
543 let val = layer.get_field(&buf, "header_form").unwrap().unwrap();
544 assert_eq!(val, FieldValue::U8(1));
545 }
546
547 #[test]
548 fn test_get_field_fixed_bit() {
549 let buf = make_initial_buf();
550 let layer = QuicLayer::new(0, buf.len());
551 let val = layer.get_field(&buf, "fixed_bit").unwrap().unwrap();
552 assert_eq!(val, FieldValue::U8(1));
553 }
554
555 #[test]
556 fn test_get_field_packet_type() {
557 let buf = make_initial_buf();
558 let layer = QuicLayer::new(0, buf.len());
559 let val = layer.get_field(&buf, "packet_type").unwrap().unwrap();
560 assert_eq!(val, FieldValue::U8(0));
562 }
563
564 #[test]
565 fn test_get_field_version() {
566 let buf = make_initial_buf();
567 let layer = QuicLayer::new(0, buf.len());
568 let val = layer.get_field(&buf, "version").unwrap().unwrap();
569 assert_eq!(val, FieldValue::U32(1));
570 }
571
572 #[test]
573 fn test_get_field_unknown() {
574 let buf = make_initial_buf();
575 let layer = QuicLayer::new(0, buf.len());
576 assert!(layer.get_field(&buf, "nonexistent").is_none());
577 }
578
579 #[test]
580 fn test_set_field_version() {
581 let mut buf = make_initial_buf();
582 let layer = QuicLayer::new(0, buf.len());
583 layer
584 .set_field(&mut buf, "version", FieldValue::U32(2))
585 .unwrap()
586 .unwrap();
587 assert_eq!(layer.version(&buf), Some(2));
588 }
589
590 #[test]
591 fn test_one_rtt_is_short_header() {
592 let buf = QuicBuilder::one_rtt().payload(vec![0x01]).build();
593 let layer = QuicLayer::new(0, buf.len());
594 assert!(!layer.is_long_header(&buf));
595 assert_eq!(layer.packet_type(&buf), Some(QuicPacketType::OneRtt));
596 assert_eq!(layer.version(&buf), None);
597 }
598
599 #[test]
600 fn test_layer_kind() {
601 let buf = make_initial_buf();
602 let layer = QuicLayer::new(0, buf.len());
603 assert_eq!(layer.kind(), LayerKind::Quic);
604 }
605
606 #[test]
607 fn test_header_len_long() {
608 let buf = make_initial_buf();
609 let layer = QuicLayer::new(0, buf.len());
610 let h = layer.header_len(&buf);
613 assert!(h >= 6, "header_len={}", h);
614 }
615
616 #[test]
621 fn test_get_field_long_packet_type_initial() {
622 let buf = make_initial_buf();
623 let layer = QuicLayer::new(0, buf.len());
624 let val = layer.get_field(&buf, "long_packet_type").unwrap().unwrap();
625 assert_eq!(val, FieldValue::U8(0)); }
627
628 #[test]
629 fn test_get_field_long_packet_type_handshake() {
630 let buf = QuicBuilder::handshake().dst_conn_id(vec![0x01]).build();
631 let layer = QuicLayer::new(0, buf.len());
632 let val = layer.get_field(&buf, "long_packet_type").unwrap().unwrap();
633 assert_eq!(val, FieldValue::U8(2)); }
635
636 #[test]
637 fn test_get_field_packet_number_len_zero() {
638 let buf = make_initial_buf();
640 let layer = QuicLayer::new(0, buf.len());
641 let val = layer.get_field(&buf, "packet_number_len").unwrap().unwrap();
642 assert_eq!(val, FieldValue::U8(0));
643 }
644
645 #[test]
646 fn test_get_field_packet_number_len_one() {
647 let buf = QuicBuilder::initial().packet_number(0xFFFF).build();
649 let layer = QuicLayer::new(0, buf.len());
650 let val = layer.get_field(&buf, "packet_number_len").unwrap().unwrap();
651 assert_eq!(val, FieldValue::U8(1));
652 }
653
654 #[test]
655 fn test_get_field_dst_conn_id_len() {
656 let buf = make_initial_buf();
657 let layer = QuicLayer::new(0, buf.len());
658 let val = layer.get_field(&buf, "dst_conn_id_len").unwrap().unwrap();
659 assert_eq!(val, FieldValue::U8(2)); }
661
662 #[test]
663 fn test_get_field_src_conn_id_len_zero() {
664 let buf = make_initial_buf();
665 let layer = QuicLayer::new(0, buf.len());
666 let val = layer.get_field(&buf, "src_conn_id_len").unwrap().unwrap();
667 assert_eq!(val, FieldValue::U8(0)); }
669
670 #[test]
671 fn test_get_field_src_conn_id_len_nonzero() {
672 let buf = QuicBuilder::initial()
673 .dst_conn_id(vec![0xAA])
674 .src_conn_id(vec![0xBB, 0xCC])
675 .build();
676 let layer = QuicLayer::new(0, buf.len());
677 let val = layer.get_field(&buf, "src_conn_id_len").unwrap().unwrap();
678 assert_eq!(val, FieldValue::U8(2));
679 }
680
681 #[test]
682 fn test_get_field_dst_conn_id() {
683 let dcid = vec![0x01, 0x02];
684 let buf = QuicBuilder::initial().dst_conn_id(dcid.clone()).build();
685 let layer = QuicLayer::new(0, buf.len());
686 let val = layer.get_field(&buf, "dst_conn_id").unwrap().unwrap();
687 assert_eq!(val, FieldValue::Bytes(dcid));
688 }
689
690 #[test]
691 fn test_get_field_src_conn_id() {
692 let scid = vec![0xAA, 0xBB];
693 let buf = QuicBuilder::initial().src_conn_id(scid.clone()).build();
694 let layer = QuicLayer::new(0, buf.len());
695 let val = layer.get_field(&buf, "src_conn_id").unwrap().unwrap();
696 assert_eq!(val, FieldValue::Bytes(scid));
697 }
698
699 #[test]
700 fn test_get_field_length_initial() {
701 let buf = QuicBuilder::initial()
703 .dst_conn_id(vec![0x01])
704 .payload(vec![])
705 .build();
706 let layer = QuicLayer::new(0, buf.len());
707 let val = layer.get_field(&buf, "length").unwrap().unwrap();
708 assert_eq!(val, FieldValue::U64(1)); }
710
711 #[test]
712 fn test_get_field_packet_number_initial_zero() {
713 let buf = QuicBuilder::initial()
714 .dst_conn_id(vec![0x01])
715 .packet_number(0)
716 .build();
717 let layer = QuicLayer::new(0, buf.len());
718 let val = layer.get_field(&buf, "packet_number").unwrap().unwrap();
719 assert_eq!(val, FieldValue::U32(0));
720 }
721
722 #[test]
723 fn test_get_field_packet_number_initial_255() {
724 let buf = QuicBuilder::initial()
725 .dst_conn_id(vec![0x01])
726 .packet_number(0xFF)
727 .build();
728 let layer = QuicLayer::new(0, buf.len());
729 let val = layer.get_field(&buf, "packet_number").unwrap().unwrap();
730 assert_eq!(val, FieldValue::U32(0xFF));
731 }
732
733 #[test]
734 fn test_get_field_packet_number_initial_65535() {
735 let buf = QuicBuilder::initial()
736 .dst_conn_id(vec![0x01])
737 .packet_number(0xFFFF)
738 .build();
739 let layer = QuicLayer::new(0, buf.len());
740 let val = layer.get_field(&buf, "packet_number").unwrap().unwrap();
741 assert_eq!(val, FieldValue::U32(0xFFFF));
742 }
743
744 #[test]
745 fn test_get_field_packet_number_handshake() {
746 let buf = QuicBuilder::handshake()
747 .dst_conn_id(vec![0x01])
748 .packet_number(1)
749 .build();
750 let layer = QuicLayer::new(0, buf.len());
751 let val = layer.get_field(&buf, "packet_number").unwrap().unwrap();
752 assert_eq!(val, FieldValue::U32(1));
753 }
754
755 #[test]
756 fn test_uts_client_initial_fields() {
757 let data = from_hex(
759 "c00000000108000102030405060705635f636964004103001c36a7ed78716be9711ba498b7ed868443bb2e0c514d4d848eadcc7a00d25ce9f9afa483978088de836be68c0b32a24595d7813ea5414a9199329a6d9f7f760dd8bb249bf3f53d9a77fbb7b395b8d66d7879a51fe59ef9601f79998eb3568e1fdc789f640acab3858a82ef2930fa5ce14b5b9ea0bdb29f4572da85aa3def39b7efafffa074b9267070d50b5d07842e49bba3bc787ff295d6ae3b514305f102afe5a047b3fb4c99eb92a274d244d60492c0e2e6e212cef0f9e3f62efd0955e71c768aa6bb3cd80bbb3755c8b7ebee32712f40f2245119487021b4b84e1565e3ca31967ac8604d4032170dec280aeefa095d08b3b7241ef6646a6c86e5c62ce08be099",
760 );
761 let layer = QuicLayer::new(0, data.len());
762
763 let dcid = layer.get_field(&data, "dst_conn_id").unwrap().unwrap();
764 assert_eq!(
765 dcid,
766 FieldValue::Bytes(vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])
767 );
768
769 let scid = layer.get_field(&data, "src_conn_id").unwrap().unwrap();
770 assert_eq!(scid, FieldValue::Bytes(b"c_cid".to_vec()));
771
772 let lpt = layer.get_field(&data, "long_packet_type").unwrap().unwrap();
773 assert_eq!(lpt, FieldValue::U8(0)); let version = layer.get_field(&data, "version").unwrap().unwrap();
776 assert_eq!(version, FieldValue::U32(1));
777
778 let length = layer.get_field(&data, "length").unwrap().unwrap();
779 assert_eq!(length, FieldValue::U64(259));
780
781 let pn = layer.get_field(&data, "packet_number").unwrap().unwrap();
782 assert_eq!(pn, FieldValue::U32(0));
783 }
784
785 #[test]
786 fn test_uts_server_handshake_fields() {
787 let data = from_hex(
789 "e00000000105635f63696405735f63696440cf014420f919681c3f0f102a30f5e647a3399abf54bc8e80453134996ba33099056242f3b8e662bbfce42f3ef2b6ba87159147489f8479e849284e983fd905320a62fc7d67e9587797096ca60101d0b2685d8747811178133ad9172b7ff8ea83fd81a814bae27b953a97d57ebff4b4710dba8df82a6b49d7d7fa3d8179cbdb8683d4bfa832645401e5a56a76535f71c6fb3e616c241bb1f43bc147c296f591402997ed49aa0c55e31721d03e14114af2dc458ae03944de5126fe08d66a6ef3ba2ed1025f98fea6d6024998184687dc06",
790 );
791 let layer = QuicLayer::new(0, data.len());
792
793 let lpt = layer.get_field(&data, "long_packet_type").unwrap().unwrap();
794 assert_eq!(lpt, FieldValue::U8(2)); let dcid = layer.get_field(&data, "dst_conn_id").unwrap().unwrap();
797 assert_eq!(dcid, FieldValue::Bytes(b"c_cid".to_vec()));
798
799 let scid = layer.get_field(&data, "src_conn_id").unwrap().unwrap();
800 assert_eq!(scid, FieldValue::Bytes(b"s_cid".to_vec()));
801
802 let pn = layer.get_field(&data, "packet_number").unwrap().unwrap();
803 assert_eq!(pn, FieldValue::U32(1));
804 }
805
806 #[test]
807 fn test_uts_build_packet_fields() {
808 let data: &[u8] = b"\xc0\x00\x00\x00\x01\x0fp\xa2\x8e@\x96\xc5}\xd0\xff\xb6\xc3\xd8\x1b\xcaR\x03\xf7\x10Q\x00\x00\xff";
810 let layer = QuicLayer::new(0, data.len());
811
812 let dcil = layer.get_field(data, "dst_conn_id_len").unwrap().unwrap();
813 assert_eq!(dcil, FieldValue::U8(15));
814
815 let scil = layer.get_field(data, "src_conn_id_len").unwrap().unwrap();
816 assert_eq!(scil, FieldValue::U8(3));
817
818 let pnl = layer.get_field(data, "packet_number_len").unwrap().unwrap();
819 assert_eq!(pnl, FieldValue::U8(0)); let pn = layer.get_field(data, "packet_number").unwrap().unwrap();
822 assert_eq!(pn, FieldValue::U32(0xFF));
823 }
824}