Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ipv6 to ipv4 #37932

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions src/libstd/net/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,14 @@ impl Ipv6Addr {
/// Creates a new IPv6 address from eight 16-bit segments.
///
/// The result will represent the IP address a:b:c:d:e:f:g:h.
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
h: u16) -> Ipv6Addr {
Expand All @@ -538,6 +546,15 @@ impl Ipv6Addr {
}

/// Returns the eight 16-bit segments that make up this address.
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
/// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn segments(&self) -> [u16; 8] {
let arr = &self.inner.s6_addr;
Expand All @@ -558,6 +575,15 @@ impl Ipv6Addr {
/// This property is defined in [RFC 4291].
///
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true);
/// ```
#[stable(since = "1.7.0", feature = "ip_17")]
pub fn is_unspecified(&self) -> bool {
self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
Expand All @@ -568,6 +594,15 @@ impl Ipv6Addr {
/// This property is defined in [RFC 4291].
///
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true);
/// ```
#[stable(since = "1.7.0", feature = "ip_17")]
pub fn is_loopback(&self) -> bool {
self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
Expand All @@ -580,6 +615,20 @@ impl Ipv6Addr {
/// - the loopback address
/// - link-local, site-local, and unique local unicast addresses
/// - interface-, link-, realm-, admin- and site-local multicast addresses
///
/// # Examples
///
/// ```
/// #![feature(ip)]
///
/// use std::net::Ipv6Addr;
///
/// fn main() {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
/// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
/// }
/// ```
pub fn is_global(&self) -> bool {
match self.multicast_scope() {
Some(Ipv6MulticastScope::Global) => true,
Expand All @@ -593,6 +642,15 @@ impl Ipv6Addr {
/// This property is defined in [RFC 4193].
///
/// [RFC 4193]: https://tools.ietf.org/html/rfc4193
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(), false);
/// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
/// ```
pub fn is_unique_local(&self) -> bool {
(self.segments()[0] & 0xfe00) == 0xfc00
}
Expand All @@ -602,12 +660,32 @@ impl Ipv6Addr {
/// This property is defined in [RFC 4291].
///
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_link_local(),
/// false);
/// assert_eq!(Ipv6Addr::new(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);
/// ```
pub fn is_unicast_link_local(&self) -> bool {
(self.segments()[0] & 0xffc0) == 0xfe80
}

/// Returns true if this is a deprecated unicast site-local address
/// (fec0::/10).
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local(),
/// false);
/// assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true);
/// ```
pub fn is_unicast_site_local(&self) -> bool {
(self.segments()[0] & 0xffc0) == 0xfec0
}
Expand All @@ -618,6 +696,15 @@ impl Ipv6Addr {
/// This property is defined in [RFC 3849].
///
/// [RFC 3849]: https://tools.ietf.org/html/rfc3849
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(), false);
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
/// ```
pub fn is_documentation(&self) -> bool {
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
}
Expand All @@ -632,6 +719,15 @@ impl Ipv6Addr {
/// - unique local addresses
/// - the unspecified address
/// - the address range reserved for documentation
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true);
/// ```
pub fn is_unicast_global(&self) -> bool {
!self.is_multicast()
&& !self.is_loopback() && !self.is_unicast_link_local()
Expand All @@ -640,6 +736,16 @@ impl Ipv6Addr {
}

/// Returns the address's multicast scope if the address is multicast.
///
/// # Examples
///
/// ```
/// use std::net::{Ipv6Addr, Ipv6MulticastScope};
///
/// assert_eq!(Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0).multicast_scope(),
/// Some(Ipv6MulticastScope::Global));
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
/// ```
pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
if self.is_multicast() {
match self.segments()[0] & 0x000f {
Expand All @@ -662,6 +768,14 @@ impl Ipv6Addr {
/// This property is defined by [RFC 4291].
///
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false);
/// ```
#[stable(since = "1.7.0", feature = "ip_17")]
pub fn is_multicast(&self) -> bool {
(self.segments()[0] & 0xff00) == 0xff00
Expand All @@ -671,9 +785,21 @@ impl Ipv6Addr {
/// neither IPv4-compatible or IPv4-mapped.
///
/// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
///
/// ```
/// use std::net::{Ipv4Addr, Ipv6Addr};
///
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).to_ipv4(), None);
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).to_ipv4(),
/// Some(Ipv4Addr::new(192, 10, 2, 255)));
/// // ::1 is localhost in IPv6, equivalent to 127.0.0.0/8 in IPv4:
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(),
/// Some(Ipv4Addr::new(127, 0, 0, 1)));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
match self.segments() {
[0, 0, 0, 0, 0, 0, 0, 1] => Some(Ipv4Addr::new(127, 0, 0, 1)),
[0, 0, 0, 0, 0, f, g, h] if f == 0 || f == 0xffff => {
Some(Ipv4Addr::new((g >> 8) as u8, g as u8,
(h >> 8) as u8, h as u8))
Expand All @@ -683,6 +809,13 @@ impl Ipv6Addr {
}

/// Returns the sixteen eight-bit integers the IPv6 address consists of.
///
/// ```
/// use std::net::Ipv6Addr;
///
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).octets(),
/// [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// ```
#[stable(feature = "ipv6_to_octets", since = "1.12.0")]
pub fn octets(&self) -> [u8; 16] {
self.inner.s6_addr
Expand Down