diff options
| author | bors <bors@rust-lang.org> | 2020-08-12 16:30:46 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-08-12 16:30:46 +0000 |
| commit | 3df25ae186e89c885d9a71cd37fbd7a37e39fc85 (patch) | |
| tree | 9b52046f5e87a28f9c4da32fc80810cfe041eff0 /library/std/src | |
| parent | ded20c98be8585b2a9fe4eeadd1be5524f6ffb17 (diff) | |
| parent | d892a07c67dfa4f347b62ecf96de184c41dae5dd (diff) | |
| download | rust-3df25ae186e89c885d9a71cd37fbd7a37e39fc85.tar.gz rust-3df25ae186e89c885d9a71cd37fbd7a37e39fc85.zip | |
Auto merge of #75019 - nanpuyue:to_ipv4_mapped, r=LukasKalbertodt
Add Ipv6Addr::to_ipv4_mapped * add Ipv6Addr::to_ipv4_mapped * ~~deprecate Ipv4Addr::to_ipv6_compatible & Ipv6Addr::to_ipv4~~ reference: #75150 According to [IETF RFC 4291](https://tools.ietf.org/html/rfc4291#page-10), the "IPv4-Compatible IPv6 address" is deprecated. > 2.5.5.1. IPv4-Compatible IPv6 Address > > The "IPv4-Compatible IPv6 address" was defined to assist in the IPv6 > transition. The format of the "IPv4-Compatible IPv6 address" is as > follows: > > | 80 bits | 16 | 32 bits | > +--------------------------------------+--------------------------+ > |0000..............................0000|0000| IPv4 address | > +--------------------------------------+----+---------------------+ > > Note: The IPv4 address used in the "IPv4-Compatible IPv6 address" > must be a globally-unique IPv4 unicast address. > > The "IPv4-Compatible IPv6 address" is now deprecated because the > current IPv6 transition mechanisms no longer use these addresses. > New or updated implementations are not required to support this > address type. And the current implementation of `Ipv4Addr::to_ipv6_compatible`is incorrect: it does not check whether the IPv4 address is a globally-unique IPv4 unicast address. Please let me know if there are any issues with this pull request.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/net/ip.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index ccaacbf1a58..2c0025bcba0 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1473,6 +1473,37 @@ impl Ipv6Addr { (self.segments()[0] & 0xff00) == 0xff00 } + /// Converts this address to an [IPv4 address] if it's an "IPv4-mapped IPv6 address" + /// defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`]. + /// + /// `::ffff:a.b.c.d` becomes `a.b.c.d`. + /// All addresses *not* starting with `::ffff` will return `None`. + /// + /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html + /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2 + /// + /// # Examples + /// + /// ``` + /// #![feature(ip)] + /// + /// use std::net::{Ipv4Addr, Ipv6Addr}; + /// + /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).to_ipv4_mapped(), None); + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).to_ipv4_mapped(), + /// Some(Ipv4Addr::new(192, 10, 2, 255))); + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None); + /// ``` + pub fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> { + match self.octets() { + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => { + Some(Ipv4Addr::new(a, b, c, d)) + } + _ => None, + } + } + /// Converts this address to an [IPv4 address]. Returns [`None`] if this address is /// neither IPv4-compatible or IPv4-mapped. /// @@ -2071,6 +2102,15 @@ mod tests { } #[test] + fn ipv6_to_ipv4_mapped() { + assert_eq!( + Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4_mapped(), + Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)) + ); + assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4_mapped(), None); + } + + #[test] fn ipv6_to_ipv4() { assert_eq!( Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4(), |
