Skip to content

Commit

Permalink
Add functions to convert IPv6 addresses from and to octets
Browse files Browse the repository at this point in the history
See also #32313.
  • Loading branch information
tbu- committed Mar 19, 2016
1 parent 2de6ddd commit e3146d7
Showing 1 changed file with 43 additions and 21 deletions.
64 changes: 43 additions & 21 deletions src/libstd/net/ip.rs
Expand Up @@ -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")]
Expand Down Expand Up @@ -553,6 +560,15 @@ impl FromInner<c::in6_addr> 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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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<Ipv6MulticastScope>) {
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);
Expand All @@ -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]
Expand Down

0 comments on commit e3146d7

Please sign in to comment.