///|
pub fn Ipv4Address::zero() -> Ipv4Address {
{ value: 0U }
}
///|
pub fn Ipv4Address::max() -> Ipv4Address {
{ value: 4294967295U }
}
///|
pub fn Ipv4Address::from_uint(value : UInt) -> Ipv4Address {
{ value, }
}
///|
pub fn Ipv4Address::next(self : Ipv4Address) -> Ipv4Address? {
if self.value == 4294967295U {
None
} else {
Some({ value: self.value + 1U })
}
}
///|
pub fn Ipv4Address::previous(self : Ipv4Address) -> Ipv4Address? {
if self.value == 0U {
None
} else {
Some({ value: self.value - 1U })
}
}
///|
pub fn Ipv4Address::checked_add(
self : Ipv4Address,
step : UInt,
) -> Ipv4Address? {
if step > 4294967295U - self.value {
None
} else {
Some({ value: self.value + step })
}
}
///|
pub fn Ipv4Address::checked_sub(
self : Ipv4Address,
step : UInt,
) -> Ipv4Address? {
if step > self.value {
None
} else {
Some({ value: self.value - step })
}
}
///|
pub fn Ipv4Address::distance_to(
self : Ipv4Address,
other : Ipv4Address,
) -> UInt {
if self.value >= other.value {
self.value - other.value
} else {
other.value - self.value
}
}
///|
pub fn Ipv4Network::netmask(self : Ipv4Network) -> Ipv4Address {
{ value: ipv4_mask(self.prefix()) }
}
///|
pub fn Ipv4Network::wildcard_mask(self : Ipv4Network) -> Ipv4Address {
{ value: 4294967295U ^ ipv4_mask(self.prefix()) }
}
///|
pub fn Ipv4Network::host_count(self : Ipv4Network) -> UInt64 {
if self.prefix() == 0 {
4294967296UL
} else {
1UL << (32 - self.prefix())
}
}
///|
pub fn Ipv4Network::usable_host_count(self : Ipv4Network) -> UInt64 {
if self.prefix() >= 31 {
self.host_count()
} else {
self.host_count() - 2UL
}
}
///|
pub fn Ipv4Network::overlaps(self : Ipv4Network, other : Ipv4Network) -> Bool {
self.contains(other.first()) ||
self.contains(other.last()) ||
other.contains(self.first()) ||
other.contains(self.last())
}
///|
pub fn Ipv4Network::is_adjacent_to(
self : Ipv4Network,
other : Ipv4Network,
) -> Bool {
let left = Ipv4Range::from_network(self)
let right = Ipv4Range::from_network(other)
left.is_adjacent_to(right)
}
///|
pub fn Ipv4Network::supernet(
self : Ipv4Network,
new_prefix : Int,
) -> Result[Ipv4Network, CidrError] {
if new_prefix < 0 || new_prefix > self.prefix() {
Err(PrefixOutOfRange(new_prefix))
} else {
Ipv4Network::new(self.address(), new_prefix)
}
}
///|
pub fn Ipv4Network::parent(self : Ipv4Network) -> Ipv4Network? {
if self.prefix() == 0 {
None
} else {
Some(self.supernet(self.prefix() - 1).unwrap())
}
}
///|
pub fn Ipv4Network::sibling(self : Ipv4Network) -> Ipv4Network? {
if self.prefix() == 0 {
None
} else {
let block = self.host_count().to_uint()
let sibling_start = self.address().to_uint() ^ block
Some(
Ipv4Network::new(Ipv4Address::from_uint(sibling_start), self.prefix()).unwrap(),
)
}
}
///|
pub fn Ipv4Network::subnets(
self : Ipv4Network,
new_prefix : Int,
) -> Result[Array[Ipv4Network], CidrError] {
if new_prefix < self.prefix() || new_prefix > 32 {
return Err(PrefixOutOfRange(new_prefix))
}
let delta = new_prefix - self.prefix()
if delta > 12 {
return Err(TooManySubnets(4097))
}
let count = 1 << delta
let step = if new_prefix == 0 {
4294967296UL
} else {
1UL << (32 - new_prefix)
}
let result = Array::new()
let mut index = 0
while index < count {
let offset = (step * index.to_uint64()).to_uint()
let start = self.address().to_uint() + offset
result.push(
Ipv4Network::new(Ipv4Address::from_uint(start), new_prefix).unwrap(),
)
index = index + 1
}
Ok(result)
}
///|
pub fn Ipv4Network::split(
self : Ipv4Network,
) -> Result[(Ipv4Network, Ipv4Network), CidrError] {
if self.prefix() == 32 {
Err(PrefixOutOfRange(33))
} else {
let children = self.subnets(self.prefix() + 1).unwrap()
Ok((children[0], children[1]))
}
}
///|
pub fn Ipv4Network::nth_subnet(
self : Ipv4Network,
new_prefix : Int,
index : Int,
) -> Result[Ipv4Network, CidrError] {
if new_prefix < self.prefix() || new_prefix > 32 {
return Err(PrefixOutOfRange(new_prefix))
}
let count = 1UL << (new_prefix - self.prefix())
if index < 0 || index.to_uint64() >= count {
return Err(InvalidRange("subnet index out of range"))
}
let step = if new_prefix == 0 {
4294967296UL
} else {
1UL << (32 - new_prefix)
}
let start = self.address().to_uint() + (step * index.to_uint64()).to_uint()
Ipv4Network::new(Ipv4Address::from_uint(start), new_prefix)
}
///|
pub fn Ipv4Network::contains_range(
self : Ipv4Network,
range : Ipv4Range,
) -> Bool {
self.contains(range.start()) && self.contains(range.end())
}
///|
pub fn Ipv4Network::to_cisco_wildcard(self : Ipv4Network) -> String {
"\{self.address().to_string()} \{self.wildcard_mask().to_string()}"
}
///|
pub fn Ipv4Network::from_address_and_netmask(
address : Ipv4Address,
mask : Ipv4Address,
) -> Result[Ipv4Network, CidrError] {
match prefix_from_mask(mask) {
Err(error) => Err(error)
Ok(prefix) => Ipv4Network::new(address, prefix)
}
}
///|
pub fn Ipv4Network::from_address_and_wildcard(
address : Ipv4Address,
wildcard : Ipv4Address,
) -> Result[Ipv4Network, CidrError] {
let mask = Ipv4Address::from_uint(4294967295U ^ wildcard.to_uint())
Ipv4Network::from_address_and_netmask(address, mask)
}
///|
fn prefix_from_mask(mask : Ipv4Address) -> Result[Int, CidrError] {
let value = mask.to_uint()
let mut prefix = 0
let mut seen_zero = false
let mut bit = 31
while bit >= 0 {
let one = ((value >> bit) & 1U) == 1U
if one {
if seen_zero {
return Err(InvalidPrefix(mask.to_string()))
}
prefix = prefix + 1
} else {
seen_zero = true
}
bit = bit - 1
}
Ok(prefix)
}