Skip to content

Commit d892a07

Browse files
committed
add Ipv6Addr::to_ipv4_mapped
1 parent cfdf9d3 commit d892a07

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

library/std/src/net/ip.rs

+40
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,37 @@ impl Ipv6Addr {
14881488
(self.segments()[0] & 0xff00) == 0xff00
14891489
}
14901490

1491+
/// Converts this address to an [IPv4 address] if it's an "IPv4-mapped IPv6 address"
1492+
/// defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
1493+
///
1494+
/// `::ffff:a.b.c.d` becomes `a.b.c.d`.
1495+
/// All addresses *not* starting with `::ffff` will return `None`.
1496+
///
1497+
/// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
1498+
/// [`None`]: ../../std/option/enum.Option.html#variant.None
1499+
/// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
1500+
///
1501+
/// # Examples
1502+
///
1503+
/// ```
1504+
/// #![feature(ip)]
1505+
///
1506+
/// use std::net::{Ipv4Addr, Ipv6Addr};
1507+
///
1508+
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).to_ipv4_mapped(), None);
1509+
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).to_ipv4_mapped(),
1510+
/// Some(Ipv4Addr::new(192, 10, 2, 255)));
1511+
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None);
1512+
/// ```
1513+
pub fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
1514+
match self.octets() {
1515+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
1516+
Some(Ipv4Addr::new(a, b, c, d))
1517+
}
1518+
_ => None,
1519+
}
1520+
}
1521+
14911522
/// Converts this address to an [IPv4 address]. Returns [`None`] if this address is
14921523
/// neither IPv4-compatible or IPv4-mapped.
14931524
///
@@ -2084,6 +2115,15 @@ mod tests {
20842115
);
20852116
}
20862117

2118+
#[test]
2119+
fn ipv6_to_ipv4_mapped() {
2120+
assert_eq!(
2121+
Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4_mapped(),
2122+
Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78))
2123+
);
2124+
assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4_mapped(), None);
2125+
}
2126+
20872127
#[test]
20882128
fn ipv6_to_ipv4() {
20892129
assert_eq!(

0 commit comments

Comments
 (0)