///|
// Special-address registry prefixes matching the selected CPython ipaddress
// reference. Data only; lookup and address operations are independently implemented.
///|
fn ip_private_networks(family : Family) -> Array[Cidr] {
if family == V4 {
ip_private_v4
} else {
ip_private_v6
}
}
///|
fn ip_private_exceptions(family : Family) -> Array[Cidr] {
if family == V4 {
ip_exceptions_v4
} else {
ip_exceptions_v6
}
}
///|
fn ip_in_cidr(address : Address, network : Cidr) -> Bool {
address.family() == network.network().family() &&
address >= network.network() &&
address <= network.last()
}
///|
pub fn IpAddress::ipv4_mapped(self : IpAddress) -> IpAddress? {
let a = self.address_
if a.family_ == V6 && a.a == 0U && a.b == 0U && a.c == 65535U {
Some(IpAddress::from_address({ family_: V4, a: 0U, b: 0U, c: 0U, d: a.d, }))
} else {
None
}
}
///|
pub fn IpAddress::ipv6_mapped(self : IpAddress) -> IpAddress? {
if self.family() == V4 {
Some(
IpAddress::from_address({
family_: V6,
a: 0U,
b: 0U,
c: 65535U,
d: self.address_.d,
}),
)
} else {
None
}
}
///|
pub fn IpAddress::sixtofour(self : IpAddress) -> IpAddress? {
let a = self.address_
if a.family_ == V6 && a.a >> 16 == 8194U {
Some(
IpAddress::from_address({
family_: V4,
a: 0U,
b: 0U,
c: 0U,
d: (a.a << 16) | (a.b >> 16),
}),
)
} else {
None
}
}
///|
pub fn IpAddress::teredo(self : IpAddress) -> (IpAddress, IpAddress)? {
let a = self.address_
if a.family_ == V6 && a.a == 536936448U {
Some(
(
IpAddress::from_address({ family_: V4, a: 0U, b: 0U, c: 0U, d: a.b, }),
IpAddress::from_address({
family_: V4,
a: 0U,
b: 0U,
c: 0U,
d: a.d.lnot(),
}),
),
)
} else {
None
}
}
///|
pub fn IpAddress::is_private(self : IpAddress) -> Bool {
match self.ipv4_mapped() {
Some(mapped) => return mapped.is_private()
None => ()
}
ip_private_networks(self.family()).any(fn(n) { ip_in_cidr(self.address_, n) }) &&
!ip_private_exceptions(self.family()).any(fn(n) {
ip_in_cidr(self.address_, n)
})
}
///|
pub fn IpAddress::is_global(self : IpAddress) -> Bool {
match self.ipv4_mapped() {
Some(mapped) => return mapped.is_global()
None => ()
}
if self.family() == V4 && (self.address_.d & 4290772992U) == 1681915904U {
// Shared CGNAT 100.64.0.0/10 is neither private nor global.
false
} else {
!self.is_private()
}
}
///|
pub fn IpAddress::is_reserved(self : IpAddress) -> Bool {
match self.ipv4_mapped() {
Some(mapped) => return mapped.is_reserved()
None => ()
}
if self.family() == V4 {
self.address_.d >> 28 == 15U
} else {
ip_reserved_v6.any(fn(n) { ip_in_cidr(self.address_, n) })
}
}
///|
pub fn IpAddress::is_multicast(self : IpAddress) -> Bool {
match self.ipv4_mapped() {
Some(mapped) => return mapped.is_multicast()
None => ()
}
if self.family() == V4 {
self.address_.d >> 28 == 14U
} else {
self.address_.a >> 24 == 255U
}
}
///|
pub fn IpAddress::is_unspecified(self : IpAddress) -> Bool {
match self.ipv4_mapped() {
Some(mapped) => return mapped.is_unspecified()
None => ()
}
self.address_.a == 0U &&
self.address_.b == 0U &&
self.address_.c == 0U &&
self.address_.d == 0U
}
///|
pub fn IpAddress::is_loopback(self : IpAddress) -> Bool {
match self.ipv4_mapped() {
Some(mapped) => return mapped.is_loopback()
None => ()
}
if self.family() == V4 {
self.address_.d >> 24 == 127U
} else {
self.address_.a == 0U &&
self.address_.b == 0U &&
self.address_.c == 0U &&
self.address_.d == 1U
}
}
///|
pub fn IpAddress::is_link_local(self : IpAddress) -> Bool {
match self.ipv4_mapped() {
Some(mapped) => return mapped.is_link_local()
None => ()
}
if self.family() == V4 {
self.address_.d >> 16 == 43518U
} else {
self.address_.a >> 22 == 1018U
}
}
///|
pub fn IpAddress::is_site_local(self : IpAddress) -> Bool {
self.family() == V6 && self.address_.a >> 22 == 1019U
}
///|
let ip_private_v4 : Array[Cidr] = [
cidr_from_normalized({ family_: V4, a: 0U, b: 0U, c: 0U, d: 0U, }, 8),
cidr_from_normalized({ family_: V4, a: 0U, b: 0U, c: 0U, d: 167772160U, }, 8),
cidr_from_normalized({ family_: V4, a: 0U, b: 0U, c: 0U, d: 2130706432U, }, 8),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 2851995648U, },
16,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 2886729728U, },
12,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3221225472U, },
24,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3221225642U, },
31,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3221225984U, },
24,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3232235520U, },
16,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3323068416U, },
15,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3325256704U, },
24,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3405803776U, },
24,
),
cidr_from_normalized({ family_: V4, a: 0U, b: 0U, c: 0U, d: 4026531840U, }, 4),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 4294967295U, },
32,
),
]
///|
let ip_exceptions_v4 : Array[Cidr] = [
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3221225481U, },
32,
),
cidr_from_normalized(
{ family_: V4, a: 0U, b: 0U, c: 0U, d: 3221225482U, },
32,
),
]
///|
let ip_private_v6 : Array[Cidr] = [
cidr_from_normalized({ family_: V6, a: 0U, b: 0U, c: 0U, d: 1U, }, 128),
cidr_from_normalized({ family_: V6, a: 0U, b: 0U, c: 0U, d: 0U, }, 128),
cidr_from_normalized({ family_: V6, a: 0U, b: 0U, c: 65535U, d: 0U, }, 96),
cidr_from_normalized(
{ family_: V6, a: 6619035U, b: 65536U, c: 0U, d: 0U, },
48,
),
cidr_from_normalized({ family_: V6, a: 16777216U, b: 0U, c: 0U, d: 0U, }, 64),
cidr_from_normalized({ family_: V6, a: 536936448U, b: 0U, c: 0U, d: 0U, }, 23),
cidr_from_normalized({ family_: V6, a: 536939960U, b: 0U, c: 0U, d: 0U, }, 32),
cidr_from_normalized({ family_: V6, a: 537001984U, b: 0U, c: 0U, d: 0U, }, 16),
cidr_from_normalized(
{ family_: V6, a: 1073676288U, b: 0U, c: 0U, d: 0U, },
20,
),
cidr_from_normalized({ family_: V6, a: 4227858432U, b: 0U, c: 0U, d: 0U, }, 7),
cidr_from_normalized(
{ family_: V6, a: 4269801472U, b: 0U, c: 0U, d: 0U, },
10,
),
]
///|
let ip_exceptions_v6 : Array[Cidr] = [
cidr_from_normalized(
{ family_: V6, a: 536936449U, b: 0U, c: 0U, d: 1U, },
128,
),
cidr_from_normalized(
{ family_: V6, a: 536936449U, b: 0U, c: 0U, d: 2U, },
128,
),
cidr_from_normalized({ family_: V6, a: 536936451U, b: 0U, c: 0U, d: 0U, }, 32),
cidr_from_normalized(
{ family_: V6, a: 536936452U, b: 17956864U, c: 0U, d: 0U, },
48,
),
cidr_from_normalized({ family_: V6, a: 536936480U, b: 0U, c: 0U, d: 0U, }, 28),
cidr_from_normalized({ family_: V6, a: 536936496U, b: 0U, c: 0U, d: 0U, }, 28),
]
///|
let ip_reserved_v6 : Array[Cidr] = [
cidr_from_normalized({ family_: V6, a: 0U, b: 0U, c: 0U, d: 0U, }, 8),
cidr_from_normalized({ family_: V6, a: 16777216U, b: 0U, c: 0U, d: 0U, }, 8),
cidr_from_normalized({ family_: V6, a: 33554432U, b: 0U, c: 0U, d: 0U, }, 7),
cidr_from_normalized({ family_: V6, a: 67108864U, b: 0U, c: 0U, d: 0U, }, 6),
cidr_from_normalized({ family_: V6, a: 134217728U, b: 0U, c: 0U, d: 0U, }, 5),
cidr_from_normalized({ family_: V6, a: 268435456U, b: 0U, c: 0U, d: 0U, }, 4),
cidr_from_normalized({ family_: V6, a: 1073741824U, b: 0U, c: 0U, d: 0U, }, 3),
cidr_from_normalized({ family_: V6, a: 1610612736U, b: 0U, c: 0U, d: 0U, }, 3),
cidr_from_normalized({ family_: V6, a: 2147483648U, b: 0U, c: 0U, d: 0U, }, 3),
cidr_from_normalized({ family_: V6, a: 2684354560U, b: 0U, c: 0U, d: 0U, }, 3),
cidr_from_normalized({ family_: V6, a: 3221225472U, b: 0U, c: 0U, d: 0U, }, 3),
cidr_from_normalized({ family_: V6, a: 3758096384U, b: 0U, c: 0U, d: 0U, }, 4),
cidr_from_normalized({ family_: V6, a: 4026531840U, b: 0U, c: 0U, d: 0U, }, 5),
cidr_from_normalized({ family_: V6, a: 4160749568U, b: 0U, c: 0U, d: 0U, }, 6),
cidr_from_normalized({ family_: V6, a: 4261412864U, b: 0U, c: 0U, d: 0U, }, 9),
]