use core::fmt; /// A four-octet IPv4 address. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)] pub struct Address(pub [u8; 4]); impl Address { pub const BROADCAST: Address = Address([255; 4]); /// Construct an IPv4 address from a sequence of octets, in big-endian. /// /// # Panics /// The function panics if `data` is not four octets long. pub fn from_bytes(data: &[u8]) -> Address { let mut bytes = [0; 4]; bytes.copy_from_slice(data); Address(bytes) } /// Return an IPv4 address as a sequence of octets, in big-endian. pub fn as_bytes(&self) -> &[u8] { &self.0 } /// Query whether the address is an unicast address. pub fn is_unicast(&self) -> bool { !(self.is_broadcast() || self.is_multicast() || self.is_unspecified()) } /// Query whether the address is the broadcast address. pub fn is_broadcast(&self) -> bool { self.0[0..4] == [255; 4] } /// Query whether the address is a multicast address. pub fn is_multicast(&self) -> bool { self.0[0] & 0xf0 == 224 } /// Query whether the address falls into the "unspecified" range. pub fn is_unspecified(&self) -> bool { self.0[0] == 0 } /// Query whether the address falls into the "link-local" range. pub fn is_link_local(&self) -> bool { self.0[0..2] == [169, 254] } /// Query whether the address falls into the "loopback" range. pub fn is_loopback(&self) -> bool { self.0[0] == 127 } } impl fmt::Display for Address { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let bytes = self.0; write!(f, "{}.{}.{}.{}", bytes[0], bytes[1], bytes[2], bytes[3]) } }