Skip to main content

sniffnet_packet_parser/
protocol.rs

1use std::fmt::{Display, Formatter};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4// `repr` makes the derived `Hash` write a fixed-width discriminant:
5// `SERVICES` is built by the host in build.rs, but looked up by the target at runtime
6#[repr(u8)]
7/// The protocol of the network packet.
8pub enum Protocol {
9    Tcp,
10    Udp,
11    Icmpv4,
12    Icmpv6,
13    Igmp,
14    Arp,
15}
16
17impl Protocol {
18    #[must_use]
19    /// IANA IP protocol number, or `None` for ARP (which is not carried over IP).
20    pub fn number(self) -> Option<u8> {
21        match self {
22            Protocol::Tcp => Some(6),
23            Protocol::Udp => Some(17),
24            Protocol::Icmpv4 => Some(1),
25            Protocol::Icmpv6 => Some(58),
26            Protocol::Igmp => Some(2),
27            Protocol::Arp => None,
28        }
29    }
30
31    #[must_use]
32    /// Get the `Protocol` given its IANA IP protocol number.
33    pub fn from_number(number: u8) -> Option<Self> {
34        match number {
35            6 => Some(Protocol::Tcp),
36            17 => Some(Protocol::Udp),
37            1 => Some(Protocol::Icmpv4),
38            58 => Some(Protocol::Icmpv6),
39            2 => Some(Protocol::Igmp),
40            _ => None,
41        }
42    }
43
44    #[must_use]
45    /// Whether the protocol is portless.
46    pub fn is_portless(self) -> bool {
47        !matches!(self, Protocol::Tcp | Protocol::Udp)
48    }
49
50    #[must_use]
51    /// Whether the protocol is `ICMPv4` or `ICMPv6`.
52    pub fn is_icmp(self) -> bool {
53        matches!(self, Protocol::Icmpv4 | Protocol::Icmpv6)
54    }
55}
56
57impl Display for Protocol {
58    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
59        write!(
60            f,
61            "{}",
62            match self {
63                Protocol::Tcp => "TCP",
64                Protocol::Udp => "UDP",
65                Protocol::Icmpv4 => "ICMPv4",
66                Protocol::Icmpv6 => "ICMPv6",
67                Protocol::Igmp => "IGMP",
68                Protocol::Arp => "ARP",
69            }
70        )
71    }
72}