diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 678b581a9041b..e761b41befe1b 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -427,6 +427,13 @@ impl Ipv6Addr { _ => None } } + + /// Returns the sixteen eight-bit integers the IPv6 address consists of. + #[unstable(feature = "ipv6_to_octets", reason = "needs some testing", + issue = "32313")] + pub fn octets(&self) -> [u8; 16] { + self.inner.s6_addr + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -553,6 +560,15 @@ impl FromInner for Ipv6Addr { } } +#[stable(feature = "ipv6_from_octets", since = "1.9.0")] +impl From<[u8; 16]> for Ipv6Addr { + fn from(octets: [u8; 16]) -> Ipv6Addr { + let mut inner: c::in6_addr = unsafe { mem::zeroed() }; + inner.s6_addr = octets; + Ipv6Addr::from_inner(inner) + } +} + // Tests for this module #[cfg(test)] mod tests { @@ -739,7 +755,7 @@ mod tests { // address unspec loopbk privt linloc global multicast brdcast doc check(&[0, 0, 0, 0], true, false, false, false, false, false, false, false); check(&[0, 0, 0, 1], false, false, false, false, true, false, false, false); - check(&[1, 0, 0, 0], false, false, false, false, true, false, false, false); + check(&[0, 1, 0, 0], false, false, false, false, true, false, false, false); check(&[10, 9, 8, 7], false, false, true, false, false, false, false, false); check(&[127, 1, 2, 3], false, true, false, false, false, false, false, false); check(&[172, 31, 254, 253], false, false, true, false, false, false, false, false); @@ -757,12 +773,14 @@ mod tests { #[test] fn ipv6_properties() { - fn check(str_addr: &str, unspec: bool, loopback: bool, + fn check(str_addr: &str, octets: &[u8; 16], unspec: bool, loopback: bool, unique_local: bool, global: bool, u_link_local: bool, u_site_local: bool, u_global: bool, u_doc: bool, m_scope: Option) { let ip: Ipv6Addr = str_addr.parse().unwrap(); assert_eq!(str_addr, ip.to_string()); + assert_eq!(&ip.octets(), octets); + assert_eq!(Ipv6Addr::from(*octets), ip); assert_eq!(ip.is_unspecified(), unspec); assert_eq!(ip.is_loopback(), loopback); @@ -776,41 +794,45 @@ mod tests { assert_eq!(ip.is_multicast(), m_scope.is_some()); } - // unspec loopbk uniqlo global unill unisl uniglo doc mscope - check("::", - true, false, false, false, false, false, false, false, None); - check("::1", - false, true, false, false, false, false, false, false, None); - check("::0.0.0.2", + // unspec loopbk uniqlo global unill unisl uniglo doc mscope + check("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + true, false, false, false, false, false, false, false, None); + check("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], + false, true, false, false, false, false, false, false, None); + check("::0.0.0.2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], false, false, false, true, false, false, true, false, None); - check("1::", + check("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, true, false, false, true, false, None); - check("fc00::", + check("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, true, false, false, false, false, false, None); - check("fdff:ffff::", + check("fdff:ffff::", &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, true, false, false, false, false, false, None); - check("fe80:ffff::", + check("fe80:ffff::", &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, true, false, false, false, None); - check("febf:ffff::", + check("febf:ffff::", &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, true, false, false, false, None); - check("fec0::", + check("fec0::", &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, false, true, false, false, None); - check("ff01::", + check("ff01::", &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, false, false, false, false, Some(InterfaceLocal)); - check("ff02::", + check("ff02::", &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, false, false, false, false, Some(LinkLocal)); - check("ff03::", + check("ff03::", &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, false, false, false, false, Some(RealmLocal)); - check("ff04::", + check("ff04::", &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, false, false, false, false, Some(AdminLocal)); - check("ff05::", + check("ff05::", &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, false, false, false, false, Some(SiteLocal)); - check("ff08::", + check("ff08::", &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, false, false, false, false, false, Some(OrganizationLocal)); - check("ff0e::", + check("ff0e::", &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], false, false, false, true, false, false, false, false, Some(Global)); check("2001:db8:85a3::8a2e:370:7334", + &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34], false, false, false, false, false, false, false, true, None); + check("102:304:506:708:90a:b0c:d0e:f10", + &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + false, false, false, true, false, false, true, false, None); } #[test]