packet_strata/packet/tunnel/
gre.rs1use std::fmt::{self, Formatter};
86
87use zerocopy::byteorder::{BigEndian, U16};
88use zerocopy::{FromBytes, IntoBytes, Unaligned};
89
90use crate::packet::protocol::EtherProto;
91use crate::packet::{HeaderParser, PacketHeader};
92
93#[repr(C, packed)]
109#[derive(
110 FromBytes, IntoBytes, Unaligned, Debug, Clone, Copy, zerocopy::KnownLayout, zerocopy::Immutable,
111)]
112pub struct GreHeader {
113 flags_version: U16<BigEndian>,
114 protocol_type: U16<BigEndian>,
115}
116
117impl GreHeader {
118 pub const FLAG_CHECKSUM: u16 = 0x8000; pub const FLAG_ROUTING: u16 = 0x4000; pub const FLAG_KEY: u16 = 0x2000; pub const FLAG_SEQUENCE: u16 = 0x1000; pub const FLAG_STRICT_ROUTE: u16 = 0x0800; pub const FLAG_ACK: u16 = 0x0080; pub const VERSION_MASK: u16 = 0x0007; pub const RECUR_MASK: u16 = 0x0700; pub const FLAGS_MASK: u16 = 0x00F8; pub const VERSION_0: u16 = 0x0000; pub const VERSION_1: u16 = 0x0001; #[allow(unused)]
134 const NAME: &'static str = "GreHeader";
135
136 #[inline]
138 pub fn flags_version(&self) -> u16 {
139 self.flags_version.get()
140 }
141
142 #[inline]
144 pub fn version(&self) -> u8 {
145 (self.flags_version() & Self::VERSION_MASK) as u8
146 }
147
148 #[inline]
150 pub fn protocol_type(&self) -> EtherProto {
151 self.protocol_type.get().into()
152 }
153
154 #[inline]
156 pub fn has_checksum(&self) -> bool {
157 self.flags_version() & Self::FLAG_CHECKSUM != 0
158 }
159
160 #[inline]
162 pub fn has_routing(&self) -> bool {
163 self.flags_version() & Self::FLAG_ROUTING != 0
164 }
165
166 #[inline]
168 pub fn has_key(&self) -> bool {
169 self.flags_version() & Self::FLAG_KEY != 0
170 }
171
172 #[inline]
174 pub fn has_sequence(&self) -> bool {
175 self.flags_version() & Self::FLAG_SEQUENCE != 0
176 }
177
178 #[inline]
180 pub fn has_strict_route(&self) -> bool {
181 self.flags_version() & Self::FLAG_STRICT_ROUTE != 0
182 }
183
184 #[inline]
186 pub fn has_ack(&self) -> bool {
187 self.flags_version() & Self::FLAG_ACK != 0
188 }
189
190 #[inline]
192 pub fn recursion_control(&self) -> u8 {
193 ((self.flags_version() & Self::RECUR_MASK) >> 8) as u8
194 }
195
196 #[inline]
198 fn is_valid(&self) -> bool {
199 let version = self.version();
200
201 if version > 1 {
203 return false;
204 }
205
206 if version == 0 {
210 let reserved = self.flags_version() & Self::FLAGS_MASK;
211 if reserved != 0 {
212 return false;
213 }
214 }
215
216 true
217 }
218
219 #[inline]
221 pub fn header_length(&self) -> usize {
222 let mut len = Self::FIXED_LEN; if self.has_checksum() || self.has_routing() {
226 len += 4;
227 }
228
229 if self.has_key() {
231 len += 4;
232 }
233
234 if self.has_sequence() {
236 len += 4;
237 }
238
239 if self.version() == 1 && self.has_ack() {
241 len += 4;
242 }
243
244 len
245 }
246
247 pub fn flags_string(&self) -> String {
249 let mut flags = Vec::new();
250
251 if self.has_checksum() {
252 flags.push("C");
253 }
254 if self.has_routing() {
255 flags.push("R");
256 }
257 if self.has_key() {
258 flags.push("K");
259 }
260 if self.has_sequence() {
261 flags.push("S");
262 }
263 if self.has_strict_route() {
264 flags.push("s");
265 }
266 if self.has_ack() {
267 flags.push("A");
268 }
269
270 if flags.is_empty() {
271 "none".to_string()
272 } else {
273 flags.join("")
274 }
275 }
276}
277
278#[derive(Debug, Clone)]
280pub struct GreHeaderOpt<'a> {
281 pub header: &'a GreHeader,
282 pub raw_options: &'a [u8],
283}
284
285impl<'a> GreHeaderOpt<'a> {
286 pub fn checksum(&self) -> Option<u16> {
288 if !self.header.has_checksum() && !self.header.has_routing() {
289 return None;
290 }
291
292 if self.raw_options.len() < 2 {
293 return None;
294 }
295
296 Some(u16::from_be_bytes([
297 self.raw_options[0],
298 self.raw_options[1],
299 ]))
300 }
301
302 pub fn offset(&self) -> Option<u16> {
304 if !self.header.has_checksum() && !self.header.has_routing() {
305 return None;
306 }
307
308 if self.raw_options.len() < 4 {
309 return None;
310 }
311
312 Some(u16::from_be_bytes([
313 self.raw_options[2],
314 self.raw_options[3],
315 ]))
316 }
317
318 pub fn key(&self) -> Option<u32> {
320 if !self.header.has_key() {
321 return None;
322 }
323
324 let mut offset = 0;
325 if self.header.has_checksum() || self.header.has_routing() {
326 offset += 4;
327 }
328
329 if self.raw_options.len() < offset + 4 {
330 return None;
331 }
332
333 let key_bytes = &self.raw_options[offset..offset + 4];
334 Some(u32::from_be_bytes([
335 key_bytes[0],
336 key_bytes[1],
337 key_bytes[2],
338 key_bytes[3],
339 ]))
340 }
341
342 pub fn sequence_number(&self) -> Option<u32> {
344 if !self.header.has_sequence() {
345 return None;
346 }
347
348 let mut offset = 0;
349 if self.header.has_checksum() || self.header.has_routing() {
350 offset += 4;
351 }
352 if self.header.has_key() {
353 offset += 4;
354 }
355
356 if self.raw_options.len() < offset + 4 {
357 return None;
358 }
359
360 let seq_bytes = &self.raw_options[offset..offset + 4];
361 Some(u32::from_be_bytes([
362 seq_bytes[0],
363 seq_bytes[1],
364 seq_bytes[2],
365 seq_bytes[3],
366 ]))
367 }
368
369 pub fn acknowledgment_number(&self) -> Option<u32> {
371 if self.header.version() != 1 || !self.header.has_ack() {
372 return None;
373 }
374
375 let mut offset = 0;
376 if self.header.has_checksum() || self.header.has_routing() {
377 offset += 4;
378 }
379 if self.header.has_key() {
380 offset += 4;
381 }
382 if self.header.has_sequence() {
383 offset += 4;
384 }
385
386 if self.raw_options.len() < offset + 4 {
387 return None;
388 }
389
390 let ack_bytes = &self.raw_options[offset..offset + 4];
391 Some(u32::from_be_bytes([
392 ack_bytes[0],
393 ack_bytes[1],
394 ack_bytes[2],
395 ack_bytes[3],
396 ]))
397 }
398}
399
400impl std::ops::Deref for GreHeaderOpt<'_> {
401 type Target = GreHeader;
402
403 #[inline]
404 fn deref(&self) -> &Self::Target {
405 self.header
406 }
407}
408
409impl PacketHeader for GreHeader {
410 const NAME: &'static str = "GreHeader";
411 type InnerType = EtherProto;
412
413 #[inline]
414 fn inner_type(&self) -> Self::InnerType {
415 self.protocol_type()
416 }
417
418 #[inline]
420 fn total_len(&self, _buf: &[u8]) -> usize {
421 self.header_length()
422 }
423
424 #[inline]
426 fn is_valid(&self) -> bool {
427 self.is_valid()
428 }
429}
430
431impl HeaderParser for GreHeader {
432 type Output<'a> = GreHeaderOpt<'a>;
433
434 #[inline]
435 fn into_view<'a>(header: &'a Self, raw_options: &'a [u8]) -> Self::Output<'a> {
436 GreHeaderOpt {
437 header,
438 raw_options,
439 }
440 }
441}
442
443impl fmt::Display for GreHeader {
444 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
445 write!(
446 f,
447 "GRE v{} proto={}(0x{:04x}) flags={}",
448 self.version(),
449 self.protocol_type(),
450 self.protocol_type().0,
451 self.flags_string()
452 )
453 }
454}
455
456impl fmt::Display for GreHeaderOpt<'_> {
457 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
458 write!(
459 f,
460 "GRE v{} proto={} flags={}",
461 self.version(),
462 self.protocol_type(),
463 self.flags_string()
464 )?;
465
466 if let Some(key) = self.key() {
467 write!(f, " key={}", key)?;
468 }
469
470 if let Some(seq) = self.sequence_number() {
471 write!(f, " seq={}", seq)?;
472 }
473
474 if let Some(ack) = self.acknowledgment_number() {
475 write!(f, " ack={}", ack)?;
476 }
477
478 Ok(())
479 }
480}
481
482#[cfg(test)]
483mod tests {
484 use super::*;
485
486 #[test]
487 fn test_gre_header_size() {
488 assert_eq!(std::mem::size_of::<GreHeader>(), 4);
489 assert_eq!(GreHeader::FIXED_LEN, 4);
490 }
491
492 #[test]
493 fn test_gre_basic_header() {
494 let header = GreHeader {
495 flags_version: U16::new(0x0000), protocol_type: U16::new(0x0800), };
498
499 assert_eq!(header.version(), 0);
500 assert_eq!(header.protocol_type(), EtherProto::IPV4);
501 assert!(!header.has_checksum());
502 assert!(!header.has_key());
503 assert!(!header.has_sequence());
504 assert!(header.is_valid());
505 assert_eq!(header.header_length(), 4);
506 }
507
508 #[test]
509 fn test_gre_with_key() {
510 let header = GreHeader {
511 flags_version: U16::new(0x2000), protocol_type: U16::new(0x0800), };
514
515 assert!(header.has_key());
516 assert!(!header.has_checksum());
517 assert!(!header.has_sequence());
518 assert_eq!(header.header_length(), 8); }
520
521 #[test]
522 fn test_gre_with_sequence() {
523 let header = GreHeader {
524 flags_version: U16::new(0x1000), protocol_type: U16::new(0x0800), };
527
528 assert!(header.has_sequence());
529 assert!(!header.has_checksum());
530 assert!(!header.has_key());
531 assert_eq!(header.header_length(), 8); }
533
534 #[test]
535 fn test_gre_with_checksum() {
536 let header = GreHeader {
537 flags_version: U16::new(0x8000), protocol_type: U16::new(0x0800), };
540
541 assert!(header.has_checksum());
542 assert!(!header.has_key());
543 assert!(!header.has_sequence());
544 assert_eq!(header.header_length(), 8); }
546
547 #[test]
548 fn test_gre_all_flags() {
549 let header = GreHeader {
550 flags_version: U16::new(0xB000), protocol_type: U16::new(0x0800), };
553
554 assert!(header.has_checksum());
555 assert!(header.has_key());
556 assert!(header.has_sequence());
557 assert_eq!(header.header_length(), 16); }
559
560 #[test]
561 fn test_gre_version_validation() {
562 let header_v0 = GreHeader {
564 flags_version: U16::new(0x0000),
565 protocol_type: U16::new(0x0800),
566 };
567 assert!(header_v0.is_valid());
568 assert_eq!(header_v0.version(), 0);
569
570 let header_v1 = GreHeader {
572 flags_version: U16::new(0x0001),
573 protocol_type: U16::new(0x880B), };
575 assert!(header_v1.is_valid());
576 assert_eq!(header_v1.version(), 1);
577
578 let header_invalid = GreHeader {
580 flags_version: U16::new(0x0002), protocol_type: U16::new(0x0800),
582 };
583 assert!(!header_invalid.is_valid());
584 }
585
586 #[test]
587 fn test_gre_parsing_basic() {
588 let mut packet = Vec::new();
589
590 packet.extend_from_slice(&0x0000u16.to_be_bytes()); packet.extend_from_slice(&0x0800u16.to_be_bytes()); packet.extend_from_slice(b"payload");
596
597 let result = GreHeader::from_bytes(&packet);
598 assert!(result.is_ok());
599
600 let (header, payload) = result.unwrap();
601 assert_eq!(header.version(), 0);
602 assert_eq!(header.protocol_type(), EtherProto::IPV4);
603 assert_eq!(payload, b"payload");
604 }
605
606 #[test]
607 fn test_gre_parsing_with_key() {
608 let mut packet = Vec::new();
609
610 packet.extend_from_slice(&0x2000u16.to_be_bytes()); packet.extend_from_slice(&0x0800u16.to_be_bytes()); packet.extend_from_slice(&0x12345678u32.to_be_bytes()); packet.extend_from_slice(b"test");
617
618 let result = GreHeader::from_bytes(&packet);
619 assert!(result.is_ok());
620
621 let (header, payload) = result.unwrap();
622 assert!(header.has_key());
623 assert_eq!(header.key().unwrap(), 0x12345678);
624 assert_eq!(payload, b"test");
625 }
626
627 #[test]
628 fn test_gre_parsing_with_sequence() {
629 let mut packet = Vec::new();
630
631 packet.extend_from_slice(&0x1000u16.to_be_bytes()); packet.extend_from_slice(&0x0800u16.to_be_bytes()); packet.extend_from_slice(&0x00000042u32.to_be_bytes()); let result = GreHeader::from_bytes(&packet);
637 assert!(result.is_ok());
638
639 let (header, _) = result.unwrap();
640 assert!(header.has_sequence());
641 assert_eq!(header.sequence_number().unwrap(), 0x42);
642 }
643
644 #[test]
645 fn test_gre_parsing_with_checksum() {
646 let mut packet = Vec::new();
647
648 packet.extend_from_slice(&0x8000u16.to_be_bytes()); packet.extend_from_slice(&0x0800u16.to_be_bytes()); packet.extend_from_slice(&0xABCDu16.to_be_bytes()); packet.extend_from_slice(&0x0000u16.to_be_bytes()); let result = GreHeader::from_bytes(&packet);
655 assert!(result.is_ok());
656
657 let (header, _) = result.unwrap();
658 assert!(header.has_checksum());
659 assert_eq!(header.checksum().unwrap(), 0xABCD);
660 }
661
662 #[test]
663 fn test_gre_parsing_all_options() {
664 let mut packet = Vec::new();
665
666 packet.extend_from_slice(&0xB000u16.to_be_bytes()); packet.extend_from_slice(&0x0800u16.to_be_bytes()); packet.extend_from_slice(&0x1234u16.to_be_bytes()); packet.extend_from_slice(&0x0000u16.to_be_bytes()); packet.extend_from_slice(&0xDEADBEEFu32.to_be_bytes()); packet.extend_from_slice(&0x00000100u32.to_be_bytes()); let result = GreHeader::from_bytes(&packet);
675 assert!(result.is_ok());
676
677 let (header, _) = result.unwrap();
678 assert!(header.has_checksum());
679 assert!(header.has_key());
680 assert!(header.has_sequence());
681 assert_eq!(header.checksum().unwrap(), 0x1234);
682 assert_eq!(header.key().unwrap(), 0xDEADBEEF);
683 assert_eq!(header.sequence_number().unwrap(), 0x100);
684 }
685
686 #[test]
687 fn test_gre_parsing_too_small() {
688 let packet = vec![0u8; 3]; let result = GreHeader::from_bytes(&packet);
691 assert!(result.is_err());
692 }
693
694 #[test]
695 fn test_gre_flags_string() {
696 let header1 = GreHeader {
697 flags_version: U16::new(0x0000),
698 protocol_type: U16::new(0x0800),
699 };
700 assert_eq!(header1.flags_string(), "none");
701
702 let header2 = GreHeader {
703 flags_version: U16::new(0x8000), protocol_type: U16::new(0x0800),
705 };
706 assert_eq!(header2.flags_string(), "C");
707
708 let header3 = GreHeader {
709 flags_version: U16::new(0xB000), protocol_type: U16::new(0x0800),
711 };
712 assert_eq!(header3.flags_string(), "CKS");
713 }
714
715 #[test]
716 fn test_gre_nvgre_scenario() {
717 let mut packet = Vec::new();
719
720 packet.extend_from_slice(&0x2000u16.to_be_bytes()); packet.extend_from_slice(&0x6558u16.to_be_bytes()); packet.extend_from_slice(&0x00010001u32.to_be_bytes()); let result = GreHeader::from_bytes(&packet);
725 assert!(result.is_ok());
726
727 let (header, _) = result.unwrap();
728 assert_eq!(header.protocol_type(), EtherProto::TEB);
729 assert!(header.has_key());
730 assert_eq!(header.key().unwrap(), 0x00010001);
731 }
732
733 #[test]
734 fn test_gre_enhanced_version_1() {
735 let mut packet = Vec::new();
737
738 packet.extend_from_slice(&0x3081u16.to_be_bytes()); packet.extend_from_slice(&0x880Bu16.to_be_bytes()); packet.extend_from_slice(&0x0004u16.to_be_bytes()); packet.extend_from_slice(&0x0001u16.to_be_bytes()); packet.extend_from_slice(&0x00000001u32.to_be_bytes()); packet.extend_from_slice(&0x00000000u32.to_be_bytes()); let result = GreHeader::from_bytes(&packet);
746 assert!(result.is_ok());
747
748 let (header, _) = result.unwrap();
749 assert_eq!(header.version(), 1);
750 assert!(header.has_key());
751 assert!(header.has_sequence());
752 assert!(header.has_ack());
753 }
754
755 #[test]
756 fn test_gre_protocol_types() {
757 let protocols = vec![
759 (EtherProto::IPV4, "IPv4"),
760 (EtherProto::IPV6, "IPv6"),
761 (EtherProto::TEB, "TEB"),
762 (EtherProto::PPP_MP, "PPP"),
763 (EtherProto::MPLS_UC, "MPLS unicast"),
764 ];
765
766 for (proto_type, _name) in protocols {
767 let header = GreHeader {
768 flags_version: U16::new(0x0000),
769 protocol_type: U16::new(proto_type.0.get()),
770 };
771
772 assert_eq!(header.protocol_type(), proto_type);
773 assert!(header.is_valid());
774 }
775 }
776
777 #[test]
778 fn test_gre_header_length_calculation() {
779 let h1 = GreHeader {
781 flags_version: U16::new(0x0000),
782 protocol_type: U16::new(0x0800),
783 };
784 assert_eq!(h1.header_length(), 4);
785
786 let h2 = GreHeader {
788 flags_version: U16::new(0x8000),
789 protocol_type: U16::new(0x0800),
790 };
791 assert_eq!(h2.header_length(), 8);
792
793 let h3 = GreHeader {
795 flags_version: U16::new(0x2000),
796 protocol_type: U16::new(0x0800),
797 };
798 assert_eq!(h3.header_length(), 8);
799
800 let h4 = GreHeader {
802 flags_version: U16::new(0x1000),
803 protocol_type: U16::new(0x0800),
804 };
805 assert_eq!(h4.header_length(), 8);
806
807 let h5 = GreHeader {
809 flags_version: U16::new(0xA000),
810 protocol_type: U16::new(0x0800),
811 };
812 assert_eq!(h5.header_length(), 12);
813
814 let h6 = GreHeader {
816 flags_version: U16::new(0xB000),
817 protocol_type: U16::new(0x0800),
818 };
819 assert_eq!(h6.header_length(), 16);
820 }
821}