use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
fn is_private_ipv4(ipv4: Ipv4Addr) -> bool {
ipv4.is_private()
|| ipv4.is_loopback()
|| ipv4.is_link_local()
|| ipv4.is_unspecified()
|| ipv4.is_broadcast()
|| ipv4.is_documentation()
|| (ipv4.octets()[0] == 100 && (ipv4.octets()[1] & 0xc0) == 64)
}
fn is_private_ipv6(ipv6: &Ipv6Addr) -> bool {
ipv6.is_unspecified()
|| ipv6.is_loopback()
|| (ipv6.segments()[0] & 0xfe00) == 0xfc00
|| (ipv6.segments()[0] & 0xffc0) == 0xfe80
|| (ipv6.segments()[0] == 0x2001 && ipv6.segments()[1] == 0x0db8)
}
#[must_use]
pub fn is_private_ip(ip: &IpAddr) -> bool {
match ip {
IpAddr::V4(ipv4) => is_private_ipv4(*ipv4),
IpAddr::V6(ipv6) => is_private_ipv6(ipv6),
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::net::{Ipv4Addr, Ipv6Addr};
#[test]
fn test_ipv4_private_ranges() {
assert!(is_private_ipv4(Ipv4Addr::new(10, 0, 0, 1)));
assert!(is_private_ipv4(Ipv4Addr::new(172, 16, 0, 1)));
assert!(is_private_ipv4(Ipv4Addr::new(192, 168, 1, 1)));
assert!(is_private_ipv4(Ipv4Addr::new(127, 0, 0, 1))); assert!(is_private_ipv4(Ipv4Addr::new(169, 254, 0, 1))); assert!(is_private_ipv4(Ipv4Addr::new(0, 0, 0, 0))); assert!(is_private_ipv4(Ipv4Addr::new(192, 0, 2, 1))); assert!(is_private_ipv4(Ipv4Addr::new(255, 255, 255, 255))); assert!(is_private_ipv4(Ipv4Addr::new(100, 64, 0, 1)));
assert!(!is_private_ipv4(Ipv4Addr::new(8, 8, 8, 8)));
}
#[test]
fn test_ipv6_private_ranges() {
assert!(is_private_ipv6(&Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0))); assert!(is_private_ipv6(&Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))); assert!(is_private_ipv6(&Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 1))); assert!(is_private_ipv6(&Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1))); assert!(is_private_ipv6(&Ipv6Addr::new(
0x2001, 0x0db8, 0, 0, 0, 0, 0, 1
)));
assert!(!is_private_ipv6(&Ipv6Addr::new(
0x2001, 0x4860, 0x4860, 0, 0, 0, 0, 0x8888
)));
}
#[test]
fn test_is_private_ip_delegation() {
let private_ipv4 = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100));
let public_ipv4 = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1));
assert!(is_private_ip(&private_ipv4));
assert!(!is_private_ip(&public_ipv4));
let private_ipv6 = IpAddr::V6(Ipv6Addr::new(0xfd12, 0x3456, 0x789a, 0, 0, 0, 0, 1));
let public_ipv6 = IpAddr::V6(Ipv6Addr::new(0x2606, 0x4700, 0x4700, 0, 0, 0, 0, 1111));
assert!(is_private_ip(&private_ipv6));
assert!(!is_private_ip(&public_ipv6));
}
}