diff --git a/src/ipv4_network.rs b/src/ipv4_network.rs index e12a3b2..d51c11d 100644 --- a/src/ipv4_network.rs +++ b/src/ipv4_network.rs @@ -179,6 +179,27 @@ impl Ipv4Network { u32::from(ip) & helpers::bite_mask(self.netmask) == u32::from(self.network_address) } + /// Returns [`true`] if given [`Ipv4Network`] is inside this network. + /// + /// [`true`]: https://doc.rust-lang.org/std/primitive.bool.html + /// + /// # Examples + /// ``` + /// use std::net::Ipv4Addr; + /// use ip_network::Ipv4Network; + /// + /// let ip_network = Ipv4Network::new(Ipv4Addr::new(192, 168, 1, 0), 24)?; + /// assert!(ip_network.overlaps(Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 0), 16)?)); + /// assert!(!ip_network.overlaps(Ipv4Network::new(Ipv4Addr::new(192, 169, 0, 0), 16)?)); + /// # Ok::<(), ip_network::IpNetworkError>(()) + /// ```` + pub fn overlaps(&self, other: Ipv4Network) -> bool { + other.contains(self.network_address()) + || other.contains(self.broadcast_address()) + || self.contains(other.network_address()) + || self.contains(other.broadcast_address()) + } + /// Returns iterator over host IP addresses in range (without network and broadcast address). You /// can also use this method to check how much hosts address are in range by calling [`len()`] method /// on iterator (see Examples). @@ -952,6 +973,15 @@ mod tests { assert!(!ip_network.contains(Ipv4Addr::new(192, 169, 0, 0))); } + #[test] + fn overlaps() { + let ip_network = return_test_ipv4_network(); + assert!(!ip_network.overlaps(Ipv4Network::new(Ipv4Addr::new(192, 167, 0, 0), 16).unwrap())); + assert!(ip_network.overlaps(Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 0), 32).unwrap())); + assert!(ip_network.overlaps(Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 0), 16).unwrap())); + assert!(!ip_network.overlaps(Ipv4Network::new(Ipv4Addr::new(192, 169, 0, 0), 16).unwrap())); + } + #[test] fn subnets() { let ip_network = return_test_ipv4_network(); diff --git a/src/ipv6_network.rs b/src/ipv6_network.rs index ae75ac3..51d6cce 100644 --- a/src/ipv6_network.rs +++ b/src/ipv6_network.rs @@ -180,6 +180,27 @@ impl Ipv6Network { truncated_ip == u128::from(self.network_address) } + /// Returns [`true`] if given [`Ipv6Network`] is inside this network. + /// + /// [`true`]: https://doc.rust-lang.org/std/primitive.bool.html + /// + /// # Examples + /// ``` + /// use std::net::Ipv6Addr; + /// use ip_network::Ipv6Network; + /// + /// let ip_network = Ipv6Network::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), 32)?; + /// assert!(ip_network.overlaps(Ipv6Network::new(Ipv6Addr::new(0x2001, 0, 0, 0, 0, 0, 0, 0), 16)?)); + /// assert!(!ip_network.overlaps(Ipv6Network::new(Ipv6Addr::new(0x2001, 0x0db9, 0, 0, 0, 0, 0, 0), 32)?)); + /// # Ok::<(), ip_network::IpNetworkError>(()) + /// ```` + pub fn overlaps(&self, other: Ipv6Network) -> bool { + other.contains(self.network_address()) + || other.contains(self.last_address()) + || self.contains(other.network_address()) + || self.contains(other.last_address()) + } + /// Returns network with smaller netmask by one. If netmask is already zero, `None` will be returned. /// /// # Examples @@ -720,6 +741,22 @@ mod tests { assert!(!ip_network.contains(Ipv6Addr::new(0x2001, 0x0db9, 0, 0, 0, 0, 0, 0))); } + #[test] + fn overlaps() { + let ip_network = return_test_ipv6_network(); + assert!(!ip_network.overlaps( + Ipv6Network::new(Ipv6Addr::new(0x2001, 0x0db7, 0, 0, 0, 0, 0, 0), 32).unwrap() + )); + assert!(ip_network.overlaps( + Ipv6Network::new(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 0), 32).unwrap() + )); + assert!(ip_network + .overlaps(Ipv6Network::new(Ipv6Addr::new(0x2001, 0, 0, 0, 0, 0, 0, 0), 16).unwrap())); + assert!(!ip_network.overlaps( + Ipv6Network::new(Ipv6Addr::new(0x2001, 0x0db9, 0, 0, 0, 0, 0, 0), 32).unwrap() + )); + } + #[test] fn supernet() { let ip_network = return_test_ipv6_network();