pub const IPPROTO_HOPOPTS: u8 = 0;
pub const IPPROTO_ICMP: u8 = 1;
pub const IPPROTO_IGMP: u8 = 2;
pub const IPPROTO_TCP: u8 = 6;
pub const IPPROTO_UDP: u8 = 17;
pub const IPPROTO_IPV6: u8 = 41;
pub const IPPROTO_ROUTE: u8 = 43;
pub const IPPROTO_FRAGMENT: u8 = 44;
pub const IPPROTO_GRE: u8 = 47;
pub const IPPROTO_ESP: u8 = 50;
pub const IPPROTO_AH: u8 = 51;
pub const IPPROTO_ICMPV6: u8 = 58;
pub const IPPROTO_NO_NEXT: u8 = 59;
pub const IPPROTO_DSTOPTS: u8 = 60;
pub const IPPROTO_OSPF: u8 = 89;
pub const IPPROTO_SCTP: u8 = 132;
pub const IPPROTO_MOBILITY: u8 = 135;
pub const IPPROTO_HIP: u8 = 139;
pub const IPPROTO_SHIM6: u8 = 140;
pub const IPPROTO_EXPERIMENTAL_1: u8 = 253;
pub const IPPROTO_EXPERIMENTAL_2: u8 = 254;
pub const IPPROTO_IPV6_HOPOPTS: u8 = IPPROTO_HOPOPTS;
pub const IPPROTO_IPV6_ROUTE: u8 = IPPROTO_ROUTE;
pub const IPPROTO_IPV6_FRAGMENT: u8 = IPPROTO_FRAGMENT;
pub const IPPROTO_IPV6_ESP: u8 = IPPROTO_ESP;
pub const IPPROTO_IPV6_AH: u8 = IPPROTO_AH;
pub const IPPROTO_IPV6_NO_NEXT: u8 = IPPROTO_NO_NEXT;
pub const IPPROTO_IPV6_DSTOPTS: u8 = IPPROTO_DSTOPTS;
pub const IPPROTO_IPV6_MOBILITY: u8 = IPPROTO_MOBILITY;
pub const IPPROTO_IPV6_HIP: u8 = IPPROTO_HIP;
pub const IPPROTO_IPV6_SHIM6: u8 = IPPROTO_SHIM6;
pub const IPPROTO_IPV6_EXPERIMENTAL_1: u8 = IPPROTO_EXPERIMENTAL_1;
pub const IPPROTO_IPV6_EXPERIMENTAL_2: u8 = IPPROTO_EXPERIMENTAL_2;
pub(crate) const fn ip_protocol_label(protocol: u8) -> Option<&'static str> {
match protocol {
IPPROTO_HOPOPTS => Some("hopopt"),
IPPROTO_ICMP => Some("icmp"),
IPPROTO_IGMP => Some("igmp"),
IPPROTO_TCP => Some("tcp"),
IPPROTO_UDP => Some("udp"),
IPPROTO_IPV6 => Some("ipv6"),
IPPROTO_GRE => Some("gre"),
IPPROTO_ESP => Some("esp"),
IPPROTO_AH => Some("ah"),
IPPROTO_ICMPV6 => Some("icmpv6"),
IPPROTO_OSPF => Some("ospf"),
IPPROTO_SCTP => Some("sctp"),
IPPROTO_EXPERIMENTAL_1 | IPPROTO_EXPERIMENTAL_2 => Some("experimental"),
_ => None,
}
}
pub(crate) fn ip_protocol_summary(protocol: u8) -> String {
match ip_protocol_label(protocol) {
Some(label) => format!("{label}({protocol})"),
None => protocol.to_string(),
}
}
pub(crate) const fn ipv6_next_header_label(next_header: u8) -> Option<&'static str> {
match next_header {
IPPROTO_IPV6_HOPOPTS => Some("hop-by-hop-options"),
IPPROTO_TCP => Some("tcp"),
IPPROTO_UDP => Some("udp"),
IPPROTO_IPV6_ROUTE => Some("routing"),
IPPROTO_IPV6_FRAGMENT => Some("fragment"),
IPPROTO_IPV6_ESP => Some("esp"),
IPPROTO_IPV6_AH => Some("ah"),
IPPROTO_ICMPV6 => Some("icmpv6"),
IPPROTO_IPV6_NO_NEXT => Some("no-next"),
IPPROTO_IPV6_DSTOPTS => Some("destination-options"),
IPPROTO_IPV6_MOBILITY => Some("mobility"),
IPPROTO_IPV6_HIP => Some("hip"),
IPPROTO_IPV6_SHIM6 => Some("shim6"),
IPPROTO_IPV6_EXPERIMENTAL_1 => Some("experimental-1"),
IPPROTO_IPV6_EXPERIMENTAL_2 => Some("experimental-2"),
255 => Some("reserved"),
_ => None,
}
}
pub(crate) fn ipv6_next_header_summary(next_header: u8) -> String {
match ipv6_next_header_label(next_header) {
Some(label) => format!("{label}({next_header})"),
None => format!("unknown({next_header})"),
}
}