use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum LayerKind {
Ethernet,
Vlan,
Mpls,
Ipv4,
Ipv6,
Arp,
Tcp,
Udp,
Icmpv4,
Icmpv6,
Gre,
Vxlan,
GtpU,
Payload,
}
impl LayerKind {
pub fn layer_number(&self) -> u8 {
match self {
LayerKind::Ethernet | LayerKind::Vlan | LayerKind::Mpls => 2,
LayerKind::Ipv4 | LayerKind::Ipv6 | LayerKind::Arp => 3,
LayerKind::Tcp
| LayerKind::Udp
| LayerKind::Icmpv4
| LayerKind::Icmpv6
| LayerKind::Gre
| LayerKind::Vxlan
| LayerKind::GtpU => 4,
LayerKind::Payload => 7,
}
}
pub const fn is_l2(self) -> bool {
matches!(
self,
LayerKind::Ethernet | LayerKind::Vlan | LayerKind::Mpls
)
}
pub const fn is_l3(self) -> bool {
matches!(self, LayerKind::Ipv4 | LayerKind::Ipv6 | LayerKind::Arp)
}
pub const fn is_l4(self) -> bool {
matches!(
self,
LayerKind::Tcp | LayerKind::Udp | LayerKind::Icmpv4 | LayerKind::Icmpv6
)
}
pub const fn is_tunnel(self) -> bool {
matches!(self, LayerKind::Gre | LayerKind::Vxlan | LayerKind::GtpU)
}
}
impl fmt::Display for LayerKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
LayerKind::Ethernet => "ethernet",
LayerKind::Vlan => "vlan",
LayerKind::Mpls => "mpls",
LayerKind::Ipv4 => "ipv4",
LayerKind::Ipv6 => "ipv6",
LayerKind::Arp => "arp",
LayerKind::Tcp => "tcp",
LayerKind::Udp => "udp",
LayerKind::Icmpv4 => "icmpv4",
LayerKind::Icmpv6 => "icmpv6",
LayerKind::Gre => "gre",
LayerKind::Vxlan => "vxlan",
LayerKind::GtpU => "gtpu",
LayerKind::Payload => "payload",
};
f.write_str(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn layer_numbers() {
assert_eq!(LayerKind::Ethernet.layer_number(), 2);
assert_eq!(LayerKind::Vlan.layer_number(), 2);
assert_eq!(LayerKind::Mpls.layer_number(), 2);
assert_eq!(LayerKind::Ipv4.layer_number(), 3);
assert_eq!(LayerKind::Ipv6.layer_number(), 3);
assert_eq!(LayerKind::Arp.layer_number(), 3);
assert_eq!(LayerKind::Tcp.layer_number(), 4);
assert_eq!(LayerKind::Udp.layer_number(), 4);
assert_eq!(LayerKind::Icmpv4.layer_number(), 4);
assert_eq!(LayerKind::Icmpv6.layer_number(), 4);
assert_eq!(LayerKind::Gre.layer_number(), 4);
assert_eq!(LayerKind::Vxlan.layer_number(), 4);
assert_eq!(LayerKind::GtpU.layer_number(), 4);
assert_eq!(LayerKind::Payload.layer_number(), 7);
}
#[test]
fn display_lowercase() {
assert_eq!(LayerKind::Tcp.to_string(), "tcp");
assert_eq!(LayerKind::Ethernet.to_string(), "ethernet");
}
}