Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscellaneous cleanups and small changes #165

Merged
merged 6 commits into from
Apr 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 10 additions & 8 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ pub fn cidr_parts(cidr: &str) -> Result<(&str, Option<&str>), IpNetworkError> {
}

pub fn parse_prefix(prefix: &str, max: u8) -> Result<u8, IpNetworkError> {
let mask = prefix
.parse::<u8>()
.map_err(|_| IpNetworkError::InvalidPrefix)?;
if mask > max {
Err(IpNetworkError::InvalidPrefix)
} else {
Ok(mask)
}
prefix
.parse()
.map_err(|_| IpNetworkError::InvalidPrefix)
.and_then(|mask| {
if mask > max {
Err(IpNetworkError::InvalidPrefix)
} else {
Ok(mask)
}
})
}
18 changes: 8 additions & 10 deletions src/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,10 @@ impl Ipv4Network {
/// let net: Ipv4Network = "127.0.0.0/16".parse().unwrap();
/// assert_eq!(net.mask(), Ipv4Addr::new(255, 255, 0, 0));
/// ```
pub fn mask(self) -> Ipv4Addr {
let prefix = self.prefix;
let mask = !(0xffff_ffff as u64 >> prefix) as u32;
pub fn mask(&self) -> Ipv4Addr {
let mask = !(0xffff_ffff_u64 >> u64::from(self.prefix)) as u32;
Ipv4Addr::from(mask)
}
}

/// Returns the address of the network denoted by this `Ipv4Network`.
/// This means the lowest possible IPv4 address inside of the network.
Expand All @@ -157,7 +156,7 @@ impl Ipv4Network {
/// let net: Ipv4Network = "10.1.9.32/16".parse().unwrap();
/// assert_eq!(net.network(), Ipv4Addr::new(10, 1, 0, 0));
/// ```
pub fn network(self) -> Ipv4Addr {
pub fn network(&self) -> Ipv4Addr {
let mask = u32::from(self.mask());
let ip = u32::from(self.addr) & mask;
Ipv4Addr::from(ip)
Expand All @@ -175,7 +174,7 @@ impl Ipv4Network {
/// let net: Ipv4Network = "10.9.0.32/16".parse().unwrap();
/// assert_eq!(net.broadcast(), Ipv4Addr::new(10, 9, 255, 255));
/// ```
pub fn broadcast(self) -> Ipv4Addr {
pub fn broadcast(&self) -> Ipv4Addr {
let mask = u32::from(self.mask());
let broadcast = u32::from(self.addr) | !mask;
Ipv4Addr::from(broadcast)
Expand All @@ -194,7 +193,7 @@ impl Ipv4Network {
/// assert!(!net.contains(Ipv4Addr::new(127, 0, 1, 70)));
/// ```
#[inline]
pub fn contains(self, ip: Ipv4Addr) -> bool {
pub fn contains(&self, ip: Ipv4Addr) -> bool {
let mask = !(0xffff_ffff as u64 >> self.prefix) as u32;
let net = u32::from(self.addr) & mask;
(u32::from(ip) & mask) == net
Expand All @@ -215,9 +214,8 @@ impl Ipv4Network {
/// assert_eq!(tinynet.size(), 1);
/// ```
pub fn size(self) -> u32 {
let host_bits = u32::from(IPV4_BITS - self.prefix);
(2 as u32).pow(host_bits)
}
1 << (u32::from(IPV4_BITS - self.prefix))
}

/// Returns the `n`:th address within this network.
/// The adresses are indexed from 0 and `n` must be smaller than the size of the network.
Expand Down
26 changes: 13 additions & 13 deletions src/ipv6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,17 @@ impl Ipv6Network {
/// assert_eq!(net.mask(), Ipv6Addr::new(0xffff, 0xffff, 0, 0, 0, 0, 0, 0));
/// ```
pub fn mask(&self) -> Ipv6Addr {
// Ipv6Addr::from is only implemented for [u8; 16]
let mut segments = [0; 16];
for (i, segment) in segments.iter_mut().enumerate() {
let bits_remaining = self.prefix.saturating_sub(i as u8 * 8);
let set_bits = cmp::min(bits_remaining, 8);
*segment = !(0xff as u16 >> set_bits) as u8;
for (i, chunk) in segments.chunks_mut(2).enumerate() {
let bits_remaining = self.prefix.saturating_sub(i as u8 * 16);
let set_bits = cmp::min(bits_remaining, 16);
let mask = !(0xffff >> set_bits) as u16;
chunk[0] = (mask >> 8) as u8;
chunk[1] = mask as u8;
}
Ipv6Addr::from(segments)
}


/// Checks if a given `Ipv6Addr` is in this `Ipv6Network`
///
Expand Down Expand Up @@ -242,7 +244,7 @@ impl Ipv6Network {
/// ```
pub fn size(&self) -> u128 {
let host_bits = u32::from(IPV6_BITS - self.prefix);
(2 as u128).pow(host_bits)
2u128.pow(host_bits)
}
}

Expand All @@ -263,16 +265,14 @@ impl FromStr for Ipv6Network {
type Err = IpNetworkError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (addr_str, prefix_str) = cidr_parts(s)?;
let addr = Ipv6Addr::from_str(addr_str)
.map_err(|_| IpNetworkError::InvalidAddr(addr_str.to_string()))?;
let prefix = match prefix_str {
Some(v) => parse_prefix(v, IPV6_BITS)?,
None => IPV6_BITS,
};
Ipv6Network::new(addr, prefix)
let addr = Ipv6Addr::from_str(addr_str).map_err(|e| IpNetworkError::InvalidAddr(e.to_string()))?;
let prefix = parse_prefix(prefix_str.unwrap_or(&IPV6_BITS.to_string()), IPV6_BITS)?;
Ok(Ipv6Network::new(addr, prefix)?)
}
}



impl TryFrom<&str> for Ipv6Network {
type Error = IpNetworkError;

Expand Down