diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 702b76e7d1c..05a3ca91948 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -615,7 +615,7 @@ mod tests { fn ipv4_properties() { fn check(octets: &[u8; 4], unspec: bool, loopback: bool, private: bool, link_local: bool, global: bool, - multicast: bool) { + multicast: bool, broadcast: bool, documentation: bool) { let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]); assert_eq!(octets, &ip.octets()); @@ -625,20 +625,23 @@ mod tests { assert_eq!(ip.is_link_local(), link_local); assert_eq!(ip.is_global(), global); assert_eq!(ip.is_multicast(), multicast); + assert_eq!(ip.is_broadcast(), broadcast); + assert_eq!(ip.is_documentation(), documentation); } - // address unspec loopbk privt linloc global multicast - check(&[0, 0, 0, 0], true, false, false, false, true, false); - check(&[0, 0, 0, 1], false, false, false, false, true, false); - check(&[1, 0, 0, 0], false, false, false, false, true, false); - check(&[10, 9, 8, 7], false, false, true, false, false, false); - check(&[127, 1, 2, 3], false, true, false, false, false, false); - check(&[172, 31, 254, 253], false, false, true, false, false, false); - check(&[169, 254, 253, 242], false, false, false, true, false, false); - check(&[192, 168, 254, 253], false, false, true, false, false, false); - check(&[224, 0, 0, 0], false, false, false, false, true, true); - check(&[239, 255, 255, 255], false, false, false, false, true, true); - check(&[255, 255, 255, 255], false, false, false, false, true, false); + // address unspec loopbk privt linloc global multicast brdcast doc + check(&[0, 0, 0, 0], true, false, false, false, true, 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(&[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); + check(&[169, 254, 253, 242], false, false, false, true, false, false, false, false); + check(&[192, 168, 254, 253], false, false, true, false, false, false, false, false); + check(&[224, 0, 0, 0], false, false, false, false, true, true, false, false); + check(&[239, 255, 255, 255], false, false, false, false, true, true, false, false); + check(&[255, 255, 255, 255], false, false, false, false, false, false, true, false); + check(&[198, 51, 100, 0], false, false, false, false, false, false, false, true); } #[test] diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index c8b19287477..a8608378e3f 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -115,9 +115,11 @@ impl Ipv4Addr { /// /// Non-globally-routable networks include the private networks (10.0.0.0/8, /// 172.16.0.0/12 and 192.168.0.0/16), the loopback network (127.0.0.0/8), - /// and the link-local network (169.254.0.0/16). + /// the link-local network (169.254.0.0/16), the broadcast address (255.255.255.255/32) and + /// the test networks used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24) pub fn is_global(&self) -> bool { - !self.is_private() && !self.is_loopback() && !self.is_link_local() + !self.is_private() && !self.is_loopback() && !self.is_link_local() && + !self.is_broadcast() && !self.is_documentation() } /// Returns true if this is a multicast address. @@ -127,6 +129,29 @@ impl Ipv4Addr { self.octets()[0] >= 224 && self.octets()[0] <= 239 } + /// Returns true if this is a broadcast address. + /// + /// A broadcast address has all octets set to 255 as defined in RFC 919 + pub fn is_broadcast(&self) -> bool { + self.octets()[0] == 255 && self.octets()[1] == 255 && + self.octets()[2] == 255 && self.octets()[3] == 255 + } + + /// Returns true if this address is in a range designated for documentation + /// + /// This is defined in RFC 5737 + /// - 192.0.2.0/24 (TEST-NET-1) + /// - 198.51.100.0/24 (TEST-NET-2) + /// - 203.0.113.0/24 (TEST-NET-3) + pub fn is_documentation(&self) -> bool { + match(self.octets()[0], self.octets()[1], self.octets()[2], self.octets()[3]) { + (192, _, 2, _) => true, + (198, 51, 100, _) => true, + (203, _, 113, _) => true, + _ => false + } + } + /// Convert this address to an IPv4-compatible IPv6 address /// /// a.b.c.d becomes ::a.b.c.d