use crate::*;
use ipnet::{Ipv4Net, Ipv6Net};
use std::net::{Ipv4Addr, Ipv6Addr};
pub trait IpPrivatePrefix {
fn is_private(&self) -> bool;
}
impl IpPrivatePrefix for Ipv6Prefix {
#[inline]
fn is_private(&self) -> bool {
(self.bitslot() >> 121 == 0xfc >> 1 && self.len() >= 7) || (self.bitslot() >> 80 == 0x64ff9b0001 && self.len() >= 48) }
}
impl IpPrivatePrefix for Ipv4Prefix {
#[inline]
fn is_private(&self) -> bool {
Ipv4Net::from(*self).is_private()
}
}
impl IpPrivatePrefix for Ipv6Net {
#[inline]
fn is_private(&self) -> bool {
match self.addr().octets() {
[0xfc, ..] | [0xfd, ..] => self.len() >= 7, [0, 0x64, 0xff, 0x9b, 0, 1, ..] => self.len() >= 48, _ => false,
}
}
}
impl IpPrivatePrefix for Ipv4Net {
#[inline]
fn is_private(&self) -> bool {
match self.addr().octets() {
[10, ..] => self.len() >= 8, [172, b, ..] if (16..=31).contains(&b) => self.len() >= 12, [192, 168, ..] => self.len() >= 16, _ => false,
}
}
}
impl IpPrivatePrefix for Ipv4Addr {
#[inline]
fn is_private(&self) -> bool {
match self.octets() {
[10, ..] => true, [172, b, ..] if (16..=31).contains(&b) => true, [192, 168, ..] => true, _ => false,
}
}
}
impl IpPrivatePrefix for Ipv6Addr {
#[inline]
fn is_private(&self) -> bool {
match self.octets() {
[0xfc, ..] | [0xfd, ..] => true, [0, 0x64, 0xff, 0x9b, 0, 1, ..] => true, _ => false,
}
}
}
#[cfg(test)]
mod tests {
use crate::*;
use ipnet::*;
use std::net::*;
use std::str::FromStr;
#[test]
fn private_ipv4() {
assert!(Ipv4Addr::from_str("172.31.255.255").unwrap().is_private());
assert!(Ipv4Prefix::from_str("172.28.0.0/14").unwrap().is_private());
assert!(Ipv4Net::from_str("172.29.0.0/12").unwrap().is_private());
}
#[test]
fn private_ipv6() {
assert!(Ipv6Addr::from_str("64:ff9b:1::42").unwrap().is_private());
assert!(Ipv6Prefix::from_str("64:ff9b:1:42::/96")
.unwrap()
.is_private());
assert!(Ipv6Net::from_str("64:ff9b:1:42::/96").unwrap().is_private());
assert!(Ipv6NetPrefix::from_str("64:ff9b:1::42/55")
.unwrap()
.is_private());
assert!(Ipv6NetPrefix::from_str("64:ff9b:1:42::/64")
.unwrap()
.is_private());
assert!(Ipv6Addr::from_str("fcc0:ff9b:1::42").unwrap().is_private());
assert!(Ipv6Prefix::from_str("fcc0:ff9b:1:42::/96")
.unwrap()
.is_private());
assert!(Ipv6Net::from_str("fcc0:ff9b:1:42::/96")
.unwrap()
.is_private());
assert!(Ipv6NetPrefix::from_str("fcc0:ff9b:1::42/55")
.unwrap()
.is_private());
assert!(Ipv6NetPrefix::from_str("fcc0:ff9b:1:42::/64")
.unwrap()
.is_private());
}
}