Skip to content

Commit b814104

Browse files
committed
Add IpAddr common methods
1 parent 4114b68 commit b814104

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

src/libstd/net/ip.rs

+103
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,48 @@ pub enum Ipv6MulticastScope {
5959
Global
6060
}
6161

62+
impl IpAddr {
63+
/// Returns true for the special 'unspecified' address (0.0.0.0 in IPv4, :: in IPv6).
64+
pub fn is_unspecified(&self) -> bool {
65+
match *self {
66+
IpAddr::V4(ref a) => a.is_unspecified(),
67+
IpAddr::V6(ref a) => a.is_unspecified(),
68+
}
69+
}
70+
71+
/// Returns true if this is a loopback address (127.0.0.0/8 in IPv4, ::1 in IPv6).
72+
pub fn is_loopback(&self) -> bool {
73+
match *self {
74+
IpAddr::V4(ref a) => a.is_loopback(),
75+
IpAddr::V6(ref a) => a.is_loopback(),
76+
}
77+
}
78+
79+
/// Returns true if the address appears to be globally routable.
80+
pub fn is_global(&self) -> bool {
81+
match *self {
82+
IpAddr::V4(ref a) => a.is_global(),
83+
IpAddr::V6(ref a) => a.is_global(),
84+
}
85+
}
86+
87+
/// Returns true if this is a multicast address (224.0.0.0/4 in IPv4, ff00::/8 in IPv6)
88+
pub fn is_multicast(&self) -> bool {
89+
match *self {
90+
IpAddr::V4(ref a) => a.is_multicast(),
91+
IpAddr::V6(ref a) => a.is_multicast(),
92+
}
93+
}
94+
95+
/// Returns true if this address is in a range designated for documentation.
96+
pub fn is_documentation(&self) -> bool {
97+
match *self {
98+
IpAddr::V4(ref a) => a.is_documentation(),
99+
IpAddr::V6(ref a) => a.is_documentation(),
100+
}
101+
}
102+
}
103+
62104
impl Ipv4Addr {
63105
/// Creates a new IPv4 address from four eight-bit octets.
64106
///
@@ -756,6 +798,67 @@ mod tests {
756798
None);
757799
}
758800

801+
#[test]
802+
fn ip_properties() {
803+
fn check4(octets: &[u8; 4], unspec: bool, loopback: bool,
804+
global: bool, multicast: bool, documentation: bool) {
805+
let ip = IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]));
806+
assert_eq!(ip.is_unspecified(), unspec);
807+
assert_eq!(ip.is_loopback(), loopback);
808+
assert_eq!(ip.is_global(), global);
809+
assert_eq!(ip.is_multicast(), multicast);
810+
assert_eq!(ip.is_documentation(), documentation);
811+
}
812+
813+
fn check6(str_addr: &str, unspec: bool, loopback: bool,
814+
global: bool, u_doc: bool, mcast: bool) {
815+
let ip = IpAddr::V6(str_addr.parse().unwrap());
816+
assert_eq!(ip.is_unspecified(), unspec);
817+
assert_eq!(ip.is_loopback(), loopback);
818+
assert_eq!(ip.is_global(), global);
819+
assert_eq!(ip.is_documentation(), u_doc);
820+
assert_eq!(ip.is_multicast(), mcast);
821+
}
822+
823+
// address unspec loopbk global multicast doc
824+
check4(&[0, 0, 0, 0], true, false, false, false, false);
825+
check4(&[0, 0, 0, 1], false, false, true, false, false);
826+
check4(&[0, 1, 0, 0], false, false, true, false, false);
827+
check4(&[10, 9, 8, 7], false, false, false, false, false);
828+
check4(&[127, 1, 2, 3], false, true, false, false, false);
829+
check4(&[172, 31, 254, 253], false, false, false, false, false);
830+
check4(&[169, 254, 253, 242], false, false, false, false, false);
831+
check4(&[192, 0, 2, 183], false, false, false, false, true);
832+
check4(&[192, 1, 2, 183], false, false, true, false, false);
833+
check4(&[192, 168, 254, 253], false, false, false, false, false);
834+
check4(&[198, 51, 100, 0], false, false, false, false, true);
835+
check4(&[203, 0, 113, 0], false, false, false, false, true);
836+
check4(&[203, 2, 113, 0], false, false, true, false, false);
837+
check4(&[224, 0, 0, 0], false, false, true, true, false);
838+
check4(&[239, 255, 255, 255], false, false, true, true, false);
839+
check4(&[255, 255, 255, 255], false, false, false, false, false);
840+
841+
// address unspec loopbk global doc mcast
842+
check6("::", true, false, false, false, false);
843+
check6("::1", false, true, false, false, false);
844+
check6("::0.0.0.2", false, false, true, false, false);
845+
check6("1::", false, false, true, false, false);
846+
check6("fc00::", false, false, false, false, false);
847+
check6("fdff:ffff::", false, false, false, false, false);
848+
check6("fe80:ffff::", false, false, false, false, false);
849+
check6("febf:ffff::", false, false, false, false, false);
850+
check6("fec0::", false, false, false, false, false);
851+
check6("ff01::", false, false, false, false, true);
852+
check6("ff02::", false, false, false, false, true);
853+
check6("ff03::", false, false, false, false, true);
854+
check6("ff04::", false, false, false, false, true);
855+
check6("ff05::", false, false, false, false, true);
856+
check6("ff08::", false, false, false, false, true);
857+
check6("ff0e::", false, false, true, false, true);
858+
check6("2001:db8:85a3::8a2e:370:7334", false, false, false, true, false);
859+
check6("102:304:506:708:90a:b0c:d0e:f10", false, false, true, false, false);
860+
}
861+
759862
#[test]
760863
fn ipv4_properties() {
761864
fn check(octets: &[u8; 4], unspec: bool, loopback: bool,

0 commit comments

Comments
 (0)