1use std::net::{Ipv4Addr, Ipv6Addr};
7
8use crate::packet::ether::EthAddr;
9
10use super::arp::ArpHeaderFull;
11use super::ether::EtherHeaderVlan;
12use super::icmp::IcmpHeader;
13use super::icmp6::Icmp6Header;
14use super::ipv4::Ipv4HeaderOpt;
15use super::ipv6::Ipv6HeaderExt;
16use super::null::NullHeader;
17use super::protocol::{EtherProto, IpProto};
18use super::sctp::SctpHeader;
19use super::sll::{SllHeader, Sllv2Header};
20use super::tcp::TcpHeaderOpt;
21use super::tunnel::geneve::GeneveHeaderOpt;
22use super::tunnel::gre::GreHeaderOpt;
23use super::tunnel::gtpv1::Gtpv1HeaderOpt;
24use super::tunnel::gtpv2::Gtpv2HeaderOpt;
25use super::tunnel::ipip::IpipTunnel;
26use super::tunnel::l2tp::{L2tpv2HeaderOpt, L2tpv3SessionHeaderCookie};
27use super::tunnel::mpls::MplsLabelStack;
28use super::tunnel::nvgre::NvgreHeader;
29use super::tunnel::pbb::PbbHeader;
30use super::tunnel::pptp::PptpGreHeaderOpt;
31use super::tunnel::stt::SttPacket;
32use super::tunnel::teredo::TeredoPacket;
33use super::tunnel::vxlan::VxlanHeader;
34use super::udp::UdpHeader;
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub enum UnknownProto {
39 Ether(EtherProto),
41 Ip(IpProto),
43 Tunnel(&'static str),
45}
46
47impl std::fmt::Display for UnknownProto {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 match self {
50 UnknownProto::Ether(p) => write!(f, "EtherType(0x{:04x})", p.0.get()),
51 UnknownProto::Ip(p) => write!(f, "IpProto({})", u8::from(*p)),
52 UnknownProto::Tunnel(name) => write!(f, "Tunnel({})", name),
53 }
54 }
55}
56
57pub enum Header<'a> {
62 Ethernet(EtherHeaderVlan<'a>),
64
65 Sll(&'a SllHeader),
67
68 Sllv2(&'a Sllv2Header),
70
71 Null(&'a NullHeader),
73
74 Ipv4(Ipv4HeaderOpt<'a>),
76
77 Ipv6(Ipv6HeaderExt<'a>),
79
80 Arp(ArpHeaderFull<'a>),
82
83 Tcp(TcpHeaderOpt<'a>),
85
86 Udp(&'a UdpHeader),
88
89 Sctp(&'a SctpHeader),
91
92 Icmp(&'a IcmpHeader),
94
95 Icmp6(&'a Icmp6Header),
97
98 Vxlan(&'a VxlanHeader),
100
101 Geneve(GeneveHeaderOpt<'a>),
103
104 Gre(GreHeaderOpt<'a>),
106
107 Mpls(MplsLabelStack<'a>),
109
110 Teredo(Box<TeredoPacket<'a>>),
113
114 Gtpv1(Gtpv1HeaderOpt<'a>),
116
117 Gtpv2(Gtpv2HeaderOpt<'a>),
119
120 L2tpv2(L2tpv2HeaderOpt<'a>),
122
123 L2tpv3(L2tpv3SessionHeaderCookie<'a>),
125
126 Nvgre(&'a NvgreHeader),
128
129 Pbb(PbbHeader<'a>),
131
132 Stt(SttPacket<'a>),
134
135 Pptp(PptpGreHeaderOpt<'a>),
137
138 Ipip(IpipTunnel<'a>),
140
141 Unknown {
145 proto: UnknownProto,
147 data: &'a [u8],
149 },
150}
151
152impl<'a> Header<'a> {
153 pub fn name(&self) -> &'static str {
155 match self {
156 Header::Ethernet(_) => "Ethernet",
157 Header::Sll(_) => "SLL",
158 Header::Sllv2(_) => "SLLv2",
159 Header::Null(_) => "Null/Loopback",
160 Header::Ipv4(_) => "IPv4",
161 Header::Ipv6(_) => "IPv6",
162 Header::Arp(_) => "ARP",
163 Header::Tcp(_) => "TCP",
164 Header::Udp(_) => "UDP",
165 Header::Sctp(_) => "SCTP",
166 Header::Icmp(_) => "ICMP",
167 Header::Icmp6(_) => "ICMPv6",
168 Header::Vxlan(_) => "VXLAN",
169 Header::Geneve(_) => "Geneve",
170 Header::Gre(_) => "GRE",
171 Header::Mpls(_) => "MPLS",
172 Header::Teredo(_) => "Teredo",
173 Header::Gtpv1(_) => "GTPv1",
174 Header::Gtpv2(_) => "GTPv2",
175 Header::L2tpv2(_) => "L2TPv2",
176 Header::L2tpv3(_) => "L2TPv3",
177 Header::Nvgre(_) => "NVGRE",
178 Header::Pbb(_) => "PBB",
179 Header::Stt(_) => "STT",
180 Header::Pptp(_) => "PPTP",
181 Header::Ipip(t) => t.name(),
182 Header::Unknown { .. } => "Unknown",
183 }
184 }
185
186 pub fn is_link_layer(&self) -> bool {
188 matches!(
189 self,
190 Header::Ethernet(_) | Header::Sll(_) | Header::Sllv2(_) | Header::Null(_)
191 )
192 }
193
194 pub fn is_network_layer(&self) -> bool {
196 matches!(self, Header::Ipv4(_) | Header::Ipv6(_) | Header::Arp(_))
197 }
198
199 pub fn is_transport_layer(&self) -> bool {
201 matches!(
202 self,
203 Header::Tcp(_) | Header::Udp(_) | Header::Sctp(_) | Header::Icmp(_) | Header::Icmp6(_)
204 )
205 }
206
207 pub fn is_tunnel(&self) -> bool {
209 matches!(
210 self,
211 Header::Vxlan(_)
212 | Header::Geneve(_)
213 | Header::Gre(_)
214 | Header::Mpls(_)
215 | Header::Teredo(_)
216 | Header::Gtpv1(_)
217 | Header::Gtpv2(_)
218 | Header::L2tpv2(_)
219 | Header::L2tpv3(_)
220 | Header::Nvgre(_)
221 | Header::Pbb(_)
222 | Header::Stt(_)
223 | Header::Pptp(_)
224 | Header::Ipip(_)
225 )
226 }
227
228 pub fn is_unknown(&self) -> bool {
230 matches!(self, Header::Unknown { .. })
231 }
232}
233
234impl std::fmt::Debug for Header<'_> {
235 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
236 match self {
237 Header::Ethernet(h) => f.debug_tuple("Ethernet").field(h).finish(),
238 Header::Sll(h) => f.debug_tuple("Sll").field(h).finish(),
239 Header::Sllv2(h) => f.debug_tuple("Sllv2").field(h).finish(),
240 Header::Null(h) => f.debug_tuple("Null").field(h).finish(),
241 Header::Ipv4(h) => f.debug_tuple("Ipv4").field(h).finish(),
242 Header::Ipv6(h) => f.debug_tuple("Ipv6").field(h).finish(),
243 Header::Arp(h) => f.debug_tuple("Arp").field(h).finish(),
244 Header::Tcp(h) => f.debug_tuple("Tcp").field(h).finish(),
245 Header::Udp(h) => f.debug_tuple("Udp").field(h).finish(),
246 Header::Sctp(h) => f.debug_tuple("Sctp").field(h).finish(),
247 Header::Icmp(h) => f.debug_tuple("Icmp").field(h).finish(),
248 Header::Icmp6(h) => f.debug_tuple("Icmp6").field(h).finish(),
249 Header::Vxlan(h) => f.debug_tuple("Vxlan").field(h).finish(),
250 Header::Geneve(h) => f.debug_tuple("Geneve").field(h).finish(),
251 Header::Gre(h) => f.debug_tuple("Gre").field(h).finish(),
252 Header::Mpls(h) => f.debug_tuple("Mpls").field(h).finish(),
253 Header::Teredo(h) => f.debug_tuple("Teredo").field(h).finish(),
254 Header::Gtpv1(h) => f.debug_tuple("Gtpv1").field(h).finish(),
255 Header::Gtpv2(h) => f.debug_tuple("Gtpv2").field(h).finish(),
256 Header::L2tpv2(h) => f.debug_tuple("L2tpv2").field(h).finish(),
257 Header::L2tpv3(h) => f.debug_tuple("L2tpv3").field(h).finish(),
258 Header::Nvgre(h) => f.debug_tuple("Nvgre").field(h).finish(),
259 Header::Pbb(h) => f.debug_tuple("Pbb").field(h).finish(),
260 Header::Stt(h) => f.debug_tuple("Stt").field(h).finish(),
261 Header::Pptp(h) => f.debug_tuple("Pptp").field(h).finish(),
262 Header::Ipip(h) => f.debug_tuple("Ipip").field(h).finish(),
263 Header::Unknown { proto, data } => f
264 .debug_struct("Unknown")
265 .field("proto", proto)
266 .field("data_len", &data.len())
267 .finish(),
268 }
269 }
270}
271
272impl std::fmt::Display for Header<'_> {
273 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274 match self {
275 Header::Ethernet(h) => write!(f, "{}", h),
276 Header::Sll(h) => write!(f, "{}", h),
277 Header::Sllv2(h) => write!(f, "{}", h),
278 Header::Null(h) => write!(f, "{}", h),
279 Header::Ipv4(h) => write!(f, "{}", h),
280 Header::Ipv6(h) => write!(f, "{}", h),
281 Header::Arp(h) => write!(f, "{}", h),
282 Header::Tcp(h) => write!(f, "{}", h),
283 Header::Udp(h) => write!(f, "{}", h),
284 Header::Sctp(h) => write!(f, "{}", h),
285 Header::Icmp(h) => write!(f, "{}", h),
286 Header::Icmp6(h) => write!(f, "{}", h),
287 Header::Vxlan(h) => write!(f, "{}", h),
288 Header::Geneve(h) => write!(f, "{}", h),
289 Header::Gre(h) => write!(f, "{}", h),
290 Header::Mpls(h) => write!(f, "{}", h),
291 Header::Teredo(h) => write!(f, "{}", h),
292 Header::Gtpv1(h) => write!(f, "{}", h),
293 Header::Gtpv2(h) => write!(f, "{}", h),
294 Header::L2tpv2(h) => write!(f, "{}", h),
295 Header::L2tpv3(h) => write!(f, "{}", h),
296 Header::Nvgre(h) => write!(f, "{}", h),
297 Header::Pbb(h) => write!(f, "{}", h),
298 Header::Stt(h) => write!(f, "{}", h),
299 Header::Pptp(h) => write!(f, "{}", h),
300 Header::Ipip(t) => write!(f, "{}", t),
301 Header::Unknown { proto, data } => {
302 write!(f, "Unknown({}, {} bytes)", proto, data.len())
303 }
304 }
305 }
306}
307
308#[derive(Debug, Clone)]
309pub enum LinkLayer<'a> {
310 Ethernet(EtherHeaderVlan<'a>),
311 Sll(&'a SllHeader),
312 Sllv2(&'a Sllv2Header),
313 Null(&'a NullHeader),
314}
315
316impl LinkLayer<'_> {
317 #[inline]
318 pub fn protocol(&self) -> EtherProto {
319 match self {
320 LinkLayer::Ethernet(h) => h.protocol(),
321 LinkLayer::Sll(h) => h.protocol(),
322 LinkLayer::Sllv2(h) => h.protocol(),
323 LinkLayer::Null(h) => h.protocol(),
324 }
325 }
326
327 #[inline]
328 pub fn source(&self) -> EthAddr {
329 match self {
330 crate::packet::header::LinkLayer::Ethernet(ether) => *ether.source(),
331 _ => EthAddr::default(),
332 }
333 }
334
335 #[inline]
336 pub fn dest(&self) -> EthAddr {
337 match self {
338 crate::packet::header::LinkLayer::Ethernet(ether) => *ether.dest(),
339 _ => EthAddr::default(),
340 }
341 }
342}
343
344impl std::fmt::Display for LinkLayer<'_> {
345 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
346 match self {
347 LinkLayer::Ethernet(h) => write!(f, "{}", h),
348 LinkLayer::Sll(h) => write!(f, "{}", h),
349 LinkLayer::Sllv2(h) => write!(f, "{}", h),
350 LinkLayer::Null(h) => write!(f, "{}", h),
351 }
352 }
353}
354
355#[derive(Debug, Clone)]
356pub enum NetworkLayer<'a> {
357 Ipv4(Ipv4HeaderOpt<'a>),
358 Ipv6(Ipv6HeaderExt<'a>),
359 Mpls(MplsLabelStack<'a>),
360}
361
362impl std::fmt::Display for NetworkLayer<'_> {
363 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
364 match self {
365 NetworkLayer::Ipv4(h) => write!(f, "{}", h),
366 NetworkLayer::Ipv6(h) => write!(f, "{}", h),
367 NetworkLayer::Mpls(h) => write!(f, "{}", h),
368 }
369 }
370}
371
372pub trait SourceDestLayer<T> {
381 fn source(&self) -> Option<T>;
386
387 fn dest(&self) -> Option<T>;
392}
393
394impl SourceDestLayer<EthAddr> for LinkLayer<'_> {
395 #[inline]
404 fn source(&self) -> Option<EthAddr> {
405 match self {
406 LinkLayer::Ethernet(h) => Some(*h.source()),
407 _ => None,
408 }
409 }
410
411 #[inline]
420 fn dest(&self) -> Option<EthAddr> {
421 match self {
422 LinkLayer::Ethernet(h) => Some(*h.dest()),
423 _ => None,
424 }
425 }
426}
427
428impl SourceDestLayer<Ipv4Addr> for NetworkLayer<'_> {
429 #[inline]
434 fn source(&self) -> Option<Ipv4Addr> {
435 match self {
436 NetworkLayer::Ipv4(h) => Some(h.header.src_ip()),
437 _ => None,
438 }
439 }
440
441 #[inline]
446 fn dest(&self) -> Option<Ipv4Addr> {
447 match self {
448 NetworkLayer::Ipv4(h) => Some(h.header.dst_ip()),
449 _ => None,
450 }
451 }
452}
453
454impl SourceDestLayer<Ipv6Addr> for NetworkLayer<'_> {
455 #[inline]
460 fn source(&self) -> Option<Ipv6Addr> {
461 match self {
462 NetworkLayer::Ipv6(h) => Some(h.header.src_ip()),
463 _ => None,
464 }
465 }
466
467 #[inline]
472 fn dest(&self) -> Option<Ipv6Addr> {
473 match self {
474 NetworkLayer::Ipv6(h) => Some(h.header.dst_ip()),
475 _ => None,
476 }
477 }
478}
479
480#[derive(Debug, Clone)]
481pub enum TransportLayer<'a> {
482 Tcp(TcpHeaderOpt<'a>),
483 Udp(&'a UdpHeader),
484 Sctp(&'a SctpHeader),
485 Icmp(&'a IcmpHeader),
486 Icmp6(&'a Icmp6Header),
487}
488
489impl TransportLayer<'_> {
490 #[inline]
499 pub fn ports(&self) -> (u16, u16) {
500 match self {
501 TransportLayer::Tcp(h) => {
502 (h.source().unwrap_or_default(), h.dest().unwrap_or_default())
503 }
504 TransportLayer::Udp(h) => {
505 (h.source().unwrap_or_default(), h.dest().unwrap_or_default())
506 }
507 TransportLayer::Sctp(h) => {
508 (h.source().unwrap_or_default(), h.dest().unwrap_or_default())
509 }
510 TransportLayer::Icmp(_) => (0, 0),
511 TransportLayer::Icmp6(_) => (0, 0),
512 }
513 }
514}
515
516impl SourceDestLayer<u16> for TcpHeaderOpt<'_> {
517 #[inline]
522 fn source(&self) -> Option<u16> {
523 Some(self.header.src_port())
524 }
525
526 #[inline]
531 fn dest(&self) -> Option<u16> {
532 Some(self.header.dst_port())
533 }
534}
535
536impl SourceDestLayer<u16> for UdpHeader {
537 #[inline]
542 fn source(&self) -> Option<u16> {
543 Some(self.src_port())
544 }
545
546 #[inline]
551 fn dest(&self) -> Option<u16> {
552 Some(self.dst_port())
553 }
554}
555
556impl SourceDestLayer<u16> for SctpHeader {
557 #[inline]
562 fn source(&self) -> Option<u16> {
563 Some(self.src_port())
564 }
565
566 #[inline]
571 fn dest(&self) -> Option<u16> {
572 Some(self.dst_port())
573 }
574}
575
576impl SourceDestLayer<u16> for TransportLayer<'_> {
577 #[inline]
582 fn source(&self) -> Option<u16> {
583 match self {
584 TransportLayer::Tcp(h) => Some(h.src_port()),
585 TransportLayer::Udp(h) => Some(h.src_port()),
586 TransportLayer::Sctp(h) => Some(h.src_port()),
587 TransportLayer::Icmp(_) => None,
588 TransportLayer::Icmp6(_) => None,
589 }
590 }
591
592 #[inline]
597 fn dest(&self) -> Option<u16> {
598 match self {
599 TransportLayer::Tcp(h) => Some(h.dst_port()),
600 TransportLayer::Udp(h) => Some(h.dst_port()),
601 TransportLayer::Sctp(h) => Some(h.dst_port()),
602 TransportLayer::Icmp(_) => None,
603 TransportLayer::Icmp6(_) => None,
604 }
605 }
606}
607
608impl std::fmt::Display for TransportLayer<'_> {
609 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
610 match self {
611 TransportLayer::Tcp(h) => write!(f, "{}", h),
612 TransportLayer::Udp(h) => write!(f, "{}", h),
613 TransportLayer::Sctp(h) => write!(f, "{}", h),
614 TransportLayer::Icmp(h) => write!(f, "{}", h),
615 TransportLayer::Icmp6(h) => write!(f, "{}", h),
616 }
617 }
618}
619
620#[derive(Debug, Clone)]
621pub enum TunnelLayer<'a> {
622 Vxlan(&'a VxlanHeader),
623 Geneve(GeneveHeaderOpt<'a>),
624 Gre(GreHeaderOpt<'a>),
625 Teredo(Box<TeredoPacket<'a>>),
626 Gtpv1(Gtpv1HeaderOpt<'a>),
627 Gtpv2(Gtpv2HeaderOpt<'a>),
628 L2tpv2(L2tpv2HeaderOpt<'a>),
629 L2tpv3(L2tpv3SessionHeaderCookie<'a>),
630 Nvgre(&'a NvgreHeader),
631 Pbb(PbbHeader<'a>),
632 Stt(SttPacket<'a>),
633 Pptp(PptpGreHeaderOpt<'a>),
634 Ipip(IpipTunnel<'a>),
635}
636
637#[derive(Debug, Clone)]
645pub struct NetworkTunnelLayer<'a> {
646 pub outer: Option<NetworkLayer<'a>>,
649 pub tunnel: TunnelLayer<'a>,
651}
652
653impl<'a> NetworkTunnelLayer<'a> {
654 #[inline]
663 pub fn new(outer: NetworkLayer<'a>, tunnel: TunnelLayer<'a>) -> Self {
664 Self {
665 outer: Some(outer),
666 tunnel,
667 }
668 }
669
670 #[inline]
678 pub fn new_l2(tunnel: TunnelLayer<'a>) -> Self {
679 Self {
680 outer: None,
681 tunnel,
682 }
683 }
684
685 #[inline]
694 pub fn outer(&self) -> Option<&NetworkLayer<'a>> {
695 self.outer.as_ref()
696 }
697
698 #[inline]
705 pub fn tunnel(&self) -> &TunnelLayer<'a> {
706 &self.tunnel
707 }
708}
709
710impl std::fmt::Display for NetworkTunnelLayer<'_> {
711 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
712 if let Some(ref outer) = self.outer {
713 write!(f, "{} > {}", outer, self.tunnel)
714 } else {
715 write!(f, "{}", self.tunnel)
716 }
717 }
718}
719
720impl std::fmt::Display for TunnelLayer<'_> {
721 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
722 match self {
723 TunnelLayer::Vxlan(h) => write!(f, "{}", h),
724 TunnelLayer::Geneve(h) => write!(f, "{}", h),
725 TunnelLayer::Gre(h) => write!(f, "{}", h),
726 TunnelLayer::Teredo(h) => write!(f, "{}", h),
727 TunnelLayer::Gtpv1(h) => write!(f, "{}", h),
728 TunnelLayer::Gtpv2(h) => write!(f, "{}", h),
729 TunnelLayer::L2tpv2(h) => write!(f, "{}", h),
730 TunnelLayer::L2tpv3(h) => write!(f, "{}", h),
731 TunnelLayer::Nvgre(h) => write!(f, "{}", h),
732 TunnelLayer::Pbb(h) => write!(f, "{}", h),
733 TunnelLayer::Stt(h) => write!(f, "{}", h),
734 TunnelLayer::Pptp(h) => write!(f, "{}", h),
735 TunnelLayer::Ipip(h) => write!(f, "{}", h),
736 }
737 }
738}