#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[derive(Serialize, Deserialize)]
#[repr(packed)]
pub struct InternetProtocolVersion6HostAddress(pub [u8; InternetProtocolVersion6HostAddress::Size]);
impl Display for InternetProtocolVersion6HostAddress
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result
{
write!(f, "{}", self.to_rust_address())
}
}
impl Debug for InternetProtocolVersion6HostAddress
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result
{
write!(f, "{:?}", self.to_rust_address())
}
}
impl Default for InternetProtocolVersion6HostAddress
{
#[inline(always)]
fn default() -> Self
{
Self::Unspecified
}
}
impl NetworkEndian for InternetProtocolVersion6HostAddress
{
#[inline(always)]
fn bytes(&self) -> &[u8]
{
&self.0
}
#[inline(always)]
fn write_to_hash<H: Hasher>(&self, hasher: &mut H)
{
hasher.write_u128(unsafe { transmute_copy(&self.0) })
}
}
impl InternetProtocolHostAddress for InternetProtocolVersion6HostAddress
{
type BigEndianValue = u128;
type RustAddress = Ipv6Addr;
type LibCAddress = in6_addr;
type Octets = [u8; 16];
const Size: usize = 16;
const SizeU8: u8 = 16;
type MaskBits = InternetProtocolVersion6MaskBits;
#[inline(always)]
fn from_network_endian(big_endian_value: Self::BigEndianValue) -> Self
{
Self::from_octets(unsafe { transmute(big_endian_value) })
}
#[inline(always)]
fn from_octets(octets: Self::Octets) -> Self
{
InternetProtocolVersion6HostAddress(octets)
}
#[inline(always)]
fn from_rust_address_to_libc_address(rust_address: &Self::RustAddress) -> Self::LibCAddress
{
unsafe { transmute_copy(rust_address) }
}
#[inline(always)]
fn from_rust_address(rust_address: &Self::RustAddress) -> Self
{
unsafe { transmute_copy(rust_address) }
}
#[inline(always)]
fn to_rust_address(&self) -> Self::RustAddress
{
unsafe { transmute_copy(self) }
}
#[inline(always)]
fn to_libc_address(self) -> Self::LibCAddress
{
unsafe { transmute(self.0) }
}
#[inline(always)]
fn as_native_endian(&self) -> Self::BigEndianValue
{
u128::from_be(self.as_network_endian())
}
#[inline(always)]
fn as_network_endian(&self) -> Self::BigEndianValue
{
unsafe { transmute(self.0) }
}
#[inline(always)]
fn to_media_access_control_address(&self) -> Result<MediaAccessControlAddress, ()>
{
MediaAccessControlAddress::from_internet_protocol_version_6_host_address(*self)
}
}
impl InternetProtocolVersion6HostAddress
{
pub const Unspecified: Self = InternetProtocolVersion6HostAddress([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
pub const Loopback: Self = InternetProtocolVersion6HostAddress([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
pub const MulticastAllNodesInterfaceLocal: Self = InternetProtocolVersion6HostAddress([0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
pub const MulticastAllNodesLinkLocal: Self = InternetProtocolVersion6HostAddress([0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
pub const MulticastAllRoutersInterfaceLocal: Self = InternetProtocolVersion6HostAddress([0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);
pub const MulticastAllRoutersLinkLocal: Self = InternetProtocolVersion6HostAddress([0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);
pub const MulticastAllRoutersSiteLocal: Self = InternetProtocolVersion6HostAddress([0xFF, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);
pub const PortControlProtocolAnycast: Self = InternetProtocolVersion6HostAddress([0x20, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
pub const TraversalUsingRelaysAroundNatAnycast: Self = InternetProtocolVersion6HostAddress([0x20, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02]);
#[inline(always)]
pub fn from_network_endian(big_endian_value: u128) -> Self
{
Self::from_octets(unsafe { transmute(big_endian_value) })
}
#[inline(always)]
pub fn is_not_valid_unicast(&self) -> bool
{
self.is_unspecified() || self.is_loopback() || self.is_multicast().is_some() || self.is_documentation()
}
#[inline(always)]
pub fn is_unspecified(&self) -> bool
{
self == &Self::Unspecified
}
#[inline(always)]
pub fn is_loopback(&self) -> bool
{
self == &Self::Loopback
}
#[inline(always)]
pub fn is_globally_routable_unicast(&self) -> bool
{
if InternetProtocolVersion6NetworkAddress::GloballyRoutablePrefix.contains(*self)
{
if self.is_documentation()
{
return false
}
if self.is_unique_local_unicast()
{
return false
}
true
}
else
{
false
}
}
#[inline(always)]
pub fn get_internet_protocol_version_4_embedded_rfc8215(&self) -> Option<InternetProtocolVersion4HostAddress>
{
if self.is_internet_protocol_version_4_embedded_rfc8215()
{
Some(self.internet_protocol_version_4_host_address())
}
else
{
None
}
}
#[inline(always)]
pub fn is_internet_protocol_version_4_embedded_rfc8215(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::GloballyRoutableRfc8215InternetProtocolVersion4AddressPrefix.contains(*self)
}
#[inline(always)]
pub fn get_internet_protocol_version_4_embedded_rfc6052(&self) -> Option<InternetProtocolVersion4HostAddress>
{
if self.is_internet_protocol_version_4_embedded_rfc6052()
{
Some(self.internet_protocol_version_4_host_address())
}
else
{
None
}
}
#[inline(always)]
pub fn is_internet_protocol_version_4_embedded_rfc6052(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::GloballyRoutableRfc6052InternetProtocolVersion4AddressPrefix.contains(*self)
}
#[inline(always)]
pub fn is_internet_protocol_version_4_mapped(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::MappedInternetProtocolVersion4AddressPrefix.contains(*self)
}
#[inline(always)]
pub fn get_internet_protocol_version_4_mapped(&self) -> Option<InternetProtocolVersion4HostAddress>
{
if self.is_internet_protocol_version_4_mapped()
{
Some(self.internet_protocol_version_4_host_address())
}
else
{
None
}
}
#[inline(always)]
pub fn get_deprecated_internet_protocol_version_4_compatible(&self) -> Option<InternetProtocolVersion4HostAddress>
{
if InternetProtocolVersion6NetworkAddress::DeprecatedEmbeddedInternetProtocolVersion4AddressPrefix.contains(*self)
{
let internet_protocol_version_4_host_address = self.internet_protocol_version_4_host_address();
if internet_protocol_version_4_host_address.is_not_globally_unicast_unique()
{
Some(internet_protocol_version_4_host_address)
}
else
{
None
}
}
else
{
None
}
}
#[inline(always)]
pub fn is_6to4(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::_6to4Prefix.contains(*self)
}
#[inline(always)]
pub fn get_6to4(&self) -> Option<(InternetProtocolVersion4HostAddress, &[u8; 2], &[u8; 8])>
{
if self.is_6to4()
{
let mut internet_protocol_version_4_host_address: InternetProtocolVersion4HostAddress = unsafe { uninitialized() };
unsafe { copy_nonoverlapping(self.0.get_unchecked(2), (&mut internet_protocol_version_4_host_address.0[..]).as_mut_ptr(), InternetProtocolVersion4HostAddress::Size) };
Some((internet_protocol_version_4_host_address, array_ref!(self.0, 6, 2), array_ref!(self.0, 8, 8)))
}
else
{
None
}
}
#[inline(always)]
pub fn get_6to4_prefix(&self) -> Option<InternetProtocolVersion6NetworkAddress>
{
const PrefixMaskBitsAsDepth: usize = 48 / 8;
if self.is_6to4()
{
let mut network: [u8; Self::Size] = [0x00; Self::Size];
unsafe { copy_nonoverlapping(&self.0 as *const u8, (&mut network[..]).as_mut_ptr(), PrefixMaskBitsAsDepth) };
Some
(
InternetProtocolVersion6NetworkAddress
{
network: InternetProtocolVersion6HostAddress(network),
mask_bits: InternetProtocolVersion6MaskBits::_48,
}
)
}
else
{
None
}
}
#[inline(always)]
pub fn is_direct_delegation_as112_service(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::DirectDelegationAs112ServicePrefix.contains(*self)
}
#[inline(always)]
pub fn is_discard_only(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::DiscardOnlyPrefix.contains(*self)
}
#[inline(always)]
pub fn is_unique_local_unicast(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::UniqueLocalUnicastPrefix.contains(*self)
}
#[inline(always)]
pub fn get_unique_local_unicast_l_bit_and_global_identifier_and_subnet_identifier_and_interface_identifier(&self) -> Option<(bool, &[u8; 5], &[u8; 2], &[u8; 8])>
{
if self.is_unique_local_unicast()
{
let l_bit = self.first_byte() & 0b0000_0001 == 0b0000_0001;
Some((l_bit, array_ref!(self.0, 1, 5), array_ref!(self.0, 6, 2), array_ref!(self.0, 8, 8)))
}
else
{
None
}
}
#[inline(always)]
pub fn is_link_local_unicast(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::LinkLocalUnicastPragmaticPrefix.contains(*self)
}
#[inline(always)]
pub fn get_link_local_unicast_interface_identifier(&self) -> Option<&[u8; 8]>
{
if self.is_link_local_unicast()
{
Some(array_ref!(self.0, 9, 8))
}
else
{
None
}
}
#[inline(always)]
pub fn is_assigned_ietf_protocol(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::AssignedIetfProtocolPrefix.contains(*self)
}
pub fn is_teredo(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::TeredoPrefix.contains(*self)
}
pub fn is_benchmarking(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::BenchmarkingPrefix.contains(*self)
}
pub fn is_amt(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::AmtPrefix.contains(*self)
}
pub fn is_as112_v6(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::As112V6Prefix.contains(*self)
}
pub fn is_eid_space_for_lisp(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::EidSpaceForLispPrefix.contains(*self)
}
pub fn is_deprecated_orchid(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::DeprecatedOrchidPrefix.contains(*self)
}
pub fn is_orchid_v2(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::OrchidV2Prefix.contains(*self)
}
#[inline(always)]
pub fn is_deprecated_site_local_unicast(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::DeprecatedSiteLocalUnicastPrefix.contains(*self)
}
#[inline(always)]
pub fn get_deprecated_site_local_unicast_interface_identifier(&self) -> Option<(u64, &[u8; 8])>
{
if self.is_deprecated_site_local_unicast()
{
let top_64_bits_network_endian: u64 = unsafe { *(self.0.as_ptr() as *const u64) };
#[cfg(target_endian = "big")] const Mask54Bits: u64 = !(0xFFC0000000000000);
#[cfg(target_endian = "little")] const Mask54Bits: u64 = !(0x000000000000C0FF);
let subnet_identifier = top_64_bits_network_endian | Mask54Bits;
let interface_identifier = array_ref!(self.0, 9, 8);
Some((subnet_identifier, interface_identifier))
}
else
{
None
}
}
#[inline(always)]
pub fn is_multicast(&self) -> Option<Result<(InternetProtocolVersion6MulticastAddressLifetime, InternetProtocolVersion6MulticastAddressScope), InternetProtocolVersion6MulticastAddressParseError>>
{
use self::InternetProtocolVersion6MulticastAddressLifetime::*;
use self::InternetProtocolVersion6MulticastAddressScope::*;
use self::InternetProtocolVersion6MulticastAddressParseError::*;
if self.has_multicast_prefix()
{
let flags_and_scope = self.second_byte();
let flags = flags_and_scope >> 4;
let reserved_high_order_flag = flags & 0b1000;
if reserved_high_order_flag == 0b1000
{
return Some(Err(ReservedHighOrderFlag));
}
let lifetime = match flags & 0b0001
{
0x0 => Permanent,
0x1 => Temporary,
_ => unreachable!(),
};
let scope = match flags_and_scope & 0xF0
{
0x1 => InterfaceLocal,
0x2 => LinkLocal,
0x3 => RealmLocal,
0x4 => AdminLocal,
0x5 => SiteLocal,
0x8 => OrganisationLocal,
0xE => Global,
invalid_scope @ _ => return Some(Err(ReservedOrUnassignedScope(invalid_scope))),
};
Some(Ok((lifetime, scope)))
}
else
{
None
}
}
#[inline(always)]
pub fn has_multicast_prefix(&self) -> bool
{
self.first_byte() == 0xFF
}
#[inline(always)]
pub fn does_not_have_multicast_prefix(&self) -> bool
{
self.first_byte() != 0xFF
}
#[inline(always)]
pub fn has_lower_32_bits(&self, lower_32_bits: &[u8; 4]) -> bool
{
&self.0[12 .. ] == lower_32_bits
}
#[inline(always)]
pub fn does_not_have_lower_32_bits(&self, lower_32_bits: &[u8; 4]) -> bool
{
&self.0[12 .. ] != lower_32_bits
}
#[inline(always)]
pub fn is_multicast_reserved(&self) -> bool
{
if self.has_multicast_prefix()
{
(self.second_byte() <= 0x0F) & (&self.0[2 .. 16] == &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
}
else
{
false
}
}
#[inline(always)]
pub fn is_multicast_all_nodes_interface_local(&self) -> bool
{
self == &Self::MulticastAllNodesInterfaceLocal
}
#[inline(always)]
pub fn is_multicast_all_nodes_link_local(&self) -> bool
{
self == &Self::MulticastAllNodesLinkLocal
}
#[inline(always)]
pub fn is_multicast_all_routers_interface_local(&self) -> bool
{
self == &Self::MulticastAllRoutersInterfaceLocal
}
#[inline(always)]
pub fn is_multicast_all_routers_link_local(&self) -> bool
{
self == &Self::MulticastAllRoutersLinkLocal
}
#[inline(always)]
pub fn is_multicast_all_routers_site_local(&self) -> bool
{
self == &Self::MulticastAllRoutersSiteLocal
}
#[inline(always)]
pub fn is_multicast_solicited_node(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::MulticastSolicitedNodePrefix.contains(*self)
}
#[inline(always)]
pub fn is_documentation(&self) -> bool
{
InternetProtocolVersion6NetworkAddress::DocumentationPrefix.contains(*self)
}
#[inline(always)]
fn internet_protocol_version_4_host_address(&self) -> InternetProtocolVersion4HostAddress
{
let mut internet_protocol_version_4_host_address: InternetProtocolVersion4HostAddress = unsafe { uninitialized() };
unsafe { copy_nonoverlapping(self.0.get_unchecked(12), (&mut internet_protocol_version_4_host_address.0[..]).as_mut_ptr(), InternetProtocolVersion4HostAddress::Size) };
internet_protocol_version_4_host_address
}
#[inline(always)]
fn first_byte(&self) -> u8
{
unsafe { *self.0.get_unchecked(0) }
}
#[inline(always)]
fn second_byte(&self) -> u8
{
unsafe { *self.0.get_unchecked(1) }
}
}