use core::net::Ipv4Addr;
pub const IGMP_ALL_SYSTEMS_GROUP: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 1);
pub const IGMP_ALL_ROUTERS_GROUP: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 2);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum IgmpGroupAddressClass {
Zero,
AllSystems,
AllRouters,
Multicast,
NonMulticast,
}
impl IgmpGroupAddressClass {
pub const fn name(self) -> &'static str {
match self {
Self::Zero => "zero",
Self::AllSystems => "all-systems",
Self::AllRouters => "all-routers",
Self::Multicast => "multicast",
Self::NonMulticast => "non-multicast",
}
}
pub const fn is_multicast(self) -> bool {
match self {
Self::AllSystems | Self::AllRouters | Self::Multicast => true,
Self::Zero | Self::NonMulticast => false,
}
}
}
pub fn igmp_group_address_class(address: Ipv4Addr) -> IgmpGroupAddressClass {
if address == Ipv4Addr::UNSPECIFIED {
IgmpGroupAddressClass::Zero
} else if address == IGMP_ALL_SYSTEMS_GROUP {
IgmpGroupAddressClass::AllSystems
} else if address == IGMP_ALL_ROUTERS_GROUP {
IgmpGroupAddressClass::AllRouters
} else if address.is_multicast() {
IgmpGroupAddressClass::Multicast
} else {
IgmpGroupAddressClass::NonMulticast
}
}
pub fn igmp_group_address_class_name(address: Ipv4Addr) -> &'static str {
igmp_group_address_class(address).name()
}
#[cfg(test)]
mod igmp_group_address {
use super::*;
#[test]
fn classifies_source_backed_group_addresses() {
assert_eq!(
igmp_group_address_class(Ipv4Addr::UNSPECIFIED),
IgmpGroupAddressClass::Zero
);
assert_eq!(
igmp_group_address_class(IGMP_ALL_SYSTEMS_GROUP),
IgmpGroupAddressClass::AllSystems
);
assert_eq!(
igmp_group_address_class(IGMP_ALL_ROUTERS_GROUP),
IgmpGroupAddressClass::AllRouters
);
assert_eq!(
igmp_group_address_class(Ipv4Addr::new(233, 252, 0, 42)),
IgmpGroupAddressClass::Multicast
);
assert_eq!(
igmp_group_address_class(Ipv4Addr::new(192, 0, 2, 42)),
IgmpGroupAddressClass::NonMulticast
);
}
#[test]
fn exposes_stable_diagnostic_names() {
assert_eq!(IgmpGroupAddressClass::Zero.name(), "zero");
assert_eq!(IgmpGroupAddressClass::AllSystems.name(), "all-systems");
assert_eq!(IgmpGroupAddressClass::AllRouters.name(), "all-routers");
assert_eq!(IgmpGroupAddressClass::Multicast.name(), "multicast");
assert_eq!(IgmpGroupAddressClass::NonMulticast.name(), "non-multicast");
assert!(!IgmpGroupAddressClass::Zero.is_multicast());
assert!(IgmpGroupAddressClass::AllSystems.is_multicast());
assert!(IgmpGroupAddressClass::AllRouters.is_multicast());
assert!(IgmpGroupAddressClass::Multicast.is_multicast());
assert!(!IgmpGroupAddressClass::NonMulticast.is_multicast());
}
}