tproxy_config/
private_ip.rs

1use regex::Regex;
2
3pub fn is_private_ip(ip: std::net::IpAddr) -> bool {
4    if let std::net::IpAddr::V4(addr) = ip
5        && ip_v4_is_private(&addr)
6    {
7        return true;
8    }
9
10    let patterns = [
11        r"^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$",
12        r"^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$",
13        r"^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$",
14        r"^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$",
15        r"^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$",
16        r"^f[cd][0-9a-f]{2}:",
17        r"^fe80:",
18        r"^::1$",
19        r"^::$",
20    ];
21
22    let ip = ip.to_string();
23
24    for pattern in &patterns {
25        let re = Regex::new(pattern).unwrap();
26        if re.is_match(&ip) {
27            return true;
28        }
29    }
30
31    false
32}
33
34fn is_benchmarking(addr: &std::net::Ipv4Addr) -> bool {
35    addr.octets()[0] == 198 && (addr.octets()[1] & 0xfe) == 18
36}
37
38fn ip_v4_is_private(addr: &std::net::Ipv4Addr) -> bool {
39    is_benchmarking(addr) || addr.is_private() || addr.is_loopback() || addr.is_link_local()
40}
41
42/*
43// FIXME: use IpAddr::is_global() instead when it's stable
44pub fn is_private_ip(addr: std::net::IpAddr) -> bool {
45    match addr {
46        std::net::IpAddr::V4(addr) => ip_v4_is_private(&addr),
47        std::net::IpAddr::V6(_) => false,
48    }
49}
50// */