Skip to content

Commit

Permalink
Add function to turn AddressRange into set of prefixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Koenvh1 committed Oct 17, 2024
1 parent 1426c08 commit bbe8a87
Showing 1 changed file with 49 additions and 1 deletion.
50 changes: 49 additions & 1 deletion src/repository/resources/ipres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::fmt::Display;
use std::net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr};
use std::num::ParseIntError;
use std::str::FromStr;
use std::cmp;
use bcder::{decode, encode};
use bcder::{BitString, Mode, OctetString, Tag};
use bcder::decode::{ContentError, DecodeError};
Expand Down Expand Up @@ -1037,6 +1038,41 @@ impl AddressRange {
}
}

/// Convert a range into a set of prefixes
///
/// Algorithm is based on that by ARIN
pub fn to_prefixes(self) -> Vec<Prefix> {
let mut start = self.min.to_bits();
let end = self.max.to_bits();

let mut prefixes: Vec<Prefix> = vec![];

loop {
let addr_host_bits = start.trailing_zeros();
let mut max_allowed = 128 - (start ^ end).leading_zeros();
if end.trailing_ones() < max_allowed {
max_allowed -= 1;
}

let same_bits = cmp::min(addr_host_bits, max_allowed);
let prefix_len = 128 - same_bits;

assert!(prefix_len <= 128);
let prefix = Prefix::new(Addr::from(start), prefix_len as u8);
prefixes.push(prefix);

let new_start = start + 2_u128.pow(same_bits);

if new_start - 1 >= end {

Check failure on line 1066 in src/repository/resources/ipres.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, stable)

unnecessary `>= y + 1` or `x - 1 >=`

Check failure on line 1066 in src/repository/resources/ipres.rs

View workflow job for this annotation

GitHub Actions / test (macOS-latest, stable)

unnecessary `>= y + 1` or `x - 1 >=`
break;
}

start = new_start;
}

prefixes
}

/// Formats the range as an IPv4 range.
pub fn fmt_v4(self, f: &mut fmt::Formatter) -> fmt::Result {
let min = self.min.to_v4();
Expand Down Expand Up @@ -2207,7 +2243,7 @@ impl From<OverclaimedIpv6Resources> for VerificationError {
//============ Tests =========================================================

#[cfg(test)]
mod test {
mod tests {
use bcder::encode::Values;
use super::*;

Expand Down Expand Up @@ -2658,6 +2694,18 @@ mod test {
0x123f_ffff_ffff_ffff_ffff_ffff_ffff_ffff
);
}

#[test]
fn to_prefixes() {
let range = AddressRange::new(
Addr::from(0x0000_0000_0000_0000_0000_0000_0000_0001),
Addr::from(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFE)
);

let prefixes = range.to_prefixes();

assert_eq!(254, prefixes.len())
}
}

#[cfg(all(test, feature="compat"))]
Expand Down

0 comments on commit bbe8a87

Please sign in to comment.