1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
use super::Address;
use crate::{
concrete::{Ipv4, Ipv6},
traits::{primitive::Address as _, Afi},
};
// TODO: make methods `const fn`
impl Address<Ipv4> {
/// The IPv4 subnet-local broadcast address `255.255.255.255`.
pub const BROADCAST: Self = {
if let Some(inner) = <Ipv4 as Afi>::Primitive::BROADCAST {
Self::new(inner)
} else {
panic!("failed to get BROADCAST address value")
}
};
/// Converts this [`Address<Ipv4>`] to an IPv4-compatible
/// [`Address<Ipv6>`].
///
/// IPv4-compatible IPv6 addresses are of the form `::a.b.c.d`, where
/// `a.b.c.d` is the corresponding IPv4 address. See [RFC 4291].
///
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
///
/// # Examples
///
/// ``` rust
/// use ip::{Address, Ipv4, Ipv6};
///
/// assert_eq!(
/// "172.16.12.1".parse::<Address<Ipv4>>()?.to_ipv6_compatible(),
/// "::172.16.12.1".parse::<Address<Ipv6>>()?,
/// );
/// # Ok::<(), ip::Error>(())
/// ```
#[allow(clippy::wrong_self_convention)]
#[must_use]
pub fn to_ipv6_compatible(&self) -> Address<Ipv6> {
Address::from_octets(self.to_ipv6_lo_octets())
}
/// Converts this [`Address<Ipv4>`] to an IPv4-mapped [`Address<Ipv6>`].
///
/// IPv4-mapped IPv6 addresses are of the form `::ffff:a.b.c.d`, where
/// `a.b.c.d` is the corresponding IPv4 address. See [RFC 4291].
///
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
///
/// # Examples
///
/// ``` rust
/// use ip::{Address, Ipv4, Ipv6};
///
/// assert_eq!(
/// "172.16.12.1".parse::<Address<Ipv4>>()?.to_ipv6_mapped(),
/// "::ffff:172.16.12.1".parse::<Address<Ipv6>>()?,
/// );
/// # Ok::<(), ip::Error>(())
/// ```
#[allow(clippy::wrong_self_convention)]
#[must_use]
pub fn to_ipv6_mapped(&self) -> Address<Ipv6> {
let mut octets = self.to_ipv6_lo_octets();
octets[10..12].copy_from_slice(&[0xffu8, 0xffu8]);
Address::from_octets(octets)
}
fn to_ipv6_lo_octets(self) -> <Ipv6 as Afi>::Octets {
let mut octets = <Ipv6 as Afi>::Octets::default();
octets[12..].copy_from_slice(&self.octets());
octets
}
}