pub enum IpNetwork {
V4(Ipv4Network),
V6(Ipv6Network),
}Expand description
An IP network, either IPv4 or IPv6.
This enum can contain either an Ipv4Network or an Ipv6Network, see
their respective documentation for more details.
Variants§
Implementations§
Source§impl IpNetwork
impl IpNetwork
Sourcepub fn parse(buf: &str) -> Result<Self, IpNetParseError>
pub fn parse(buf: &str) -> Result<Self, IpNetParseError>
Parses specified buffer into an extended IP network.
The following formats are supported:
| Format | Example |
|---|---|
| IPv4 | 77.88.55.242 |
| IPv4/CIDR | 77.88.0.0/16 |
| IPv4/IPv4 | 77.88.0.0/255.255.0.0 |
| IPv6 | 2a02:6b8::2:242 |
| IPv6/CIDR | 2a02:6b8:c00::/40 |
| IPv6/IPv6 | 2a02:6b8:c00::/ffff:ffff:ff00:: |
§Note
During construction, the address is normalized using mask, for example
the network 77.88.55.242/16 becomes 77.88.0.0/16.
§Examples
use core::net::{Ipv4Addr, Ipv6Addr};
use netip::{IpNetwork, Ipv4Network, Ipv6Network};
// Here are some examples to show supported formats and the output of this function.
// We can parse IPv4 addresses without explicit `/32` mask.
assert_eq!(
IpNetwork::V4(Ipv4Network::new(
Ipv4Addr::new(77, 88, 55, 242),
Ipv4Addr::new(255, 255, 255, 255),
),),
// IPv4 address.
IpNetwork::parse("77.88.55.242").unwrap(),
);
// When a mask can be represented in common CIDR format, like `/16`,
// which means "leading 16 bits on the mask is set to one".
assert_eq!(
IpNetwork::V4(Ipv4Network::new(
Ipv4Addr::new(77, 88, 0, 0),
Ipv4Addr::new(255, 255, 0, 0),
),),
// IPv4 CIDR network.
IpNetwork::parse("77.88.0.0/16").unwrap(),
);
// But we can also specify mask explicitly. This is useful when we
// want non-contiguous mask.
assert_eq!(
IpNetwork::V4(Ipv4Network::new(
Ipv4Addr::new(77, 88, 0, 0),
Ipv4Addr::new(255, 255, 0, 0),
),),
// IPv4 network with explicit mask.
IpNetwork::parse("77.88.0.0/255.255.0.0").unwrap(),
);
// Parse IPv6 addresses without explicit `/128` mask.
assert_eq!(
IpNetwork::V6(Ipv6Network::new(
Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x2, 0x242),
Ipv6Addr::new(
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
),
),),
// IPv6 address.
IpNetwork::parse("2a02:6b8::2:242").unwrap(),
);
// CIDR format.
assert_eq!(
IpNetwork::V6(Ipv6Network::new(
Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
),),
// IPv6 CIDR network.
IpNetwork::parse("2a02:6b8:c00::/40").unwrap(),
);
// Network with explicit mask (contiguous in this case).
assert_eq!(
IpNetwork::V6(Ipv6Network::new(
Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
),),
// IPv6 network with explicit mask.
IpNetwork::parse("2a02:6b8:c00::/ffff:ffff:ff00::").unwrap(),
);
// Network with explicit non-contiguous mask.
assert_eq!(
IpNetwork::V6(Ipv6Network::new(
Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0),
Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0xffff, 0xffff, 0, 0),
),),
// The same network as above, but specified explicitly.
IpNetwork::parse("2a02:6b8:c00::1234:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap(),
);Sourcepub const fn addr(&self) -> IpAddr
pub const fn addr(&self) -> IpAddr
Returns the IP address of this network.
§Examples
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use netip::IpNetwork;
assert_eq!(
IpAddr::V4(Ipv4Addr::new(192, 168, 0, 0)),
IpNetwork::parse("192.168.0.0/24").unwrap().addr()
);
assert_eq!(
IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)),
IpNetwork::parse("2001:db8::/32").unwrap().addr()
);Sourcepub const fn mask(&self) -> IpAddr
pub const fn mask(&self) -> IpAddr
Returns the IP mask of this network.
§Examples
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use netip::IpNetwork;
assert_eq!(
IpAddr::V4(Ipv4Addr::new(255, 255, 255, 0)),
IpNetwork::parse("192.168.0.0/24").unwrap().mask()
);
assert_eq!(
IpAddr::V6(Ipv6Addr::new(0xffff, 0xffff, 0, 0, 0, 0, 0, 0)),
IpNetwork::parse("2001:db8::/32").unwrap().mask()
);Sourcepub const fn contains(&self, other: &Self) -> bool
pub const fn contains(&self, other: &Self) -> bool
Returns true if this IP network fully contains the specified one.
Returns false for networks of different address families.
§Examples
use netip::IpNetwork;
let a = IpNetwork::parse("192.168.0.0/16").unwrap();
let b = IpNetwork::parse("192.168.1.0/24").unwrap();
assert!(a.contains(&b));
assert!(!b.contains(&a));
// Different address families.
let v6 = IpNetwork::parse("2001:db8::/32").unwrap();
assert!(!a.contains(&v6));Sourcepub fn to_contiguous(&self) -> Self
pub fn to_contiguous(&self) -> Self
Converts this network to a contiguous network by clearing mask bits set to one after the first zero bit.
§Examples
use netip::IpNetwork;
let net = IpNetwork::parse("192.168.0.1/255.255.0.255").unwrap();
let expected = IpNetwork::parse("192.168.0.0/16").unwrap();
assert_eq!(expected, net.to_contiguous());
let net = IpNetwork::parse("2001:db8::1/ffff:ffff:ff00::ffff:ffff:0:0").unwrap();
let expected = IpNetwork::parse("2001:db8::/40").unwrap();
assert_eq!(expected, net.to_contiguous());Sourcepub const fn is_contiguous(&self) -> bool
pub const fn is_contiguous(&self) -> bool
Checks whether this network is a contiguous, i.e. contains mask with only leading bits set to one contiguously.
Sourcepub const fn prefix(&self) -> Option<u8>
pub const fn prefix(&self) -> Option<u8>
Returns the mask prefix, i.e. the number of leading bits set, if this
network is a contiguous one, None otherwise.
§Examples
use netip::IpNetwork;
assert_eq!(
Some(24),
IpNetwork::parse("192.168.1.0/24").unwrap().prefix()
);
assert_eq!(
Some(40),
IpNetwork::parse("2a02:6b8::/40").unwrap().prefix()
);
assert_eq!(Some(128), IpNetwork::parse("2a02:6b8::1").unwrap().prefix());Sourcepub fn last_addr(&self) -> IpAddr
pub fn last_addr(&self) -> IpAddr
Returns the last address in this IP network.
For contiguous networks, this is the broadcast address.
For non-contiguous networks, this is the highest address within the network range defined by the mask.
§Examples
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use netip::IpNetwork;
// IPv4 contiguous network.
assert_eq!(
IpAddr::V4(Ipv4Addr::new(192, 168, 1, 255)),
IpNetwork::parse("192.168.1.0/24").unwrap().last_addr()
);
// IPv6 contiguous network.
assert_eq!(
IpAddr::V6(Ipv6Addr::new(
0x2001, 0xdb8, 0x1, 0, 0xffff, 0xffff, 0xffff, 0xffff
)),
IpNetwork::parse("2001:db8:1::/64").unwrap().last_addr()
);Sourcepub const fn intersects(&self, other: &Self) -> bool
pub const fn intersects(&self, other: &Self) -> bool
Returns true if this IP network and the specified one share at
least one common address.
Returns false for networks of different address families.
§Examples
use netip::IpNetwork;
let a = IpNetwork::parse("192.168.0.0/16").unwrap();
let b = IpNetwork::parse("192.168.1.0/24").unwrap();
assert!(a.intersects(&b));
let c = IpNetwork::parse("10.0.0.0/8").unwrap();
assert!(!a.intersects(&c));
// Mixed address families are always disjoint.
let v6 = IpNetwork::parse("2001:db8::/32").unwrap();
assert!(!a.intersects(&v6));Sourcepub const fn is_disjoint(&self, other: &Self) -> bool
pub const fn is_disjoint(&self, other: &Self) -> bool
Returns true if this IP network and the specified one share no
common addresses.
Returns true for networks of different address families.
§Examples
use netip::IpNetwork;
let a = IpNetwork::parse("192.168.0.0/16").unwrap();
let b = IpNetwork::parse("10.0.0.0/8").unwrap();
assert!(a.is_disjoint(&b));
// Mixed address families are always disjoint.
let v6 = IpNetwork::parse("2001:db8::/32").unwrap();
assert!(a.is_disjoint(&v6));Sourcepub const fn intersection(&self, other: &Self) -> Option<Self>
pub const fn intersection(&self, other: &Self) -> Option<Self>
Returns the intersection of this IP network with the specified one,
or None if they are disjoint or belong to different address
families.
§Examples
use netip::IpNetwork;
let a = IpNetwork::parse("192.168.0.0/16").unwrap();
let b = IpNetwork::parse("192.168.1.0/24").unwrap();
assert_eq!(Some(b), a.intersection(&b));
// Disjoint.
let c = IpNetwork::parse("10.0.0.0/8").unwrap();
assert_eq!(None, a.intersection(&c));
// Mixed address families.
let v6 = IpNetwork::parse("2001:db8::/32").unwrap();
assert_eq!(None, a.intersection(&v6));Sourcepub const fn is_adjacent(&self, other: &Self) -> bool
pub const fn is_adjacent(&self, other: &Self) -> bool
Returns true if this network is adjacent to other.
Two networks are adjacent when they share the same mask and their addresses differ by exactly one masked bit, meaning they can be merged into a single network by dropping that bit from the mask.
Returns false for networks of different address families.
See Ipv4Network::is_adjacent and Ipv6Network::is_adjacent for
details.
§Examples
use netip::IpNetwork;
let a = IpNetwork::parse("192.168.0.0/24").unwrap();
let b = IpNetwork::parse("192.168.1.0/24").unwrap();
assert!(a.is_adjacent(&b));
let c = IpNetwork::parse("192.168.3.0/24").unwrap();
assert!(!a.is_adjacent(&c));Sourcepub const fn merge(&self, other: &Self) -> Option<Self>
pub const fn merge(&self, other: &Self) -> Option<Self>
Merges this IP network with another, returning Some(N) iff their
union is exactly representable as a single network.
Returns None for networks of different address families.
See Ipv4Network::merge and Ipv6Network::merge for the full
merging rules.
§Examples
use netip::IpNetwork;
// Adjacent /24 blocks merge into a /23.
let a = IpNetwork::parse("192.168.0.0/24").unwrap();
let b = IpNetwork::parse("192.168.1.0/24").unwrap();
assert_eq!(
Some(IpNetwork::parse("192.168.0.0/23").unwrap()),
a.merge(&b)
);
// Mixed address families cannot be merged.
let v4 = IpNetwork::parse("10.0.0.0/8").unwrap();
let v6 = IpNetwork::parse("2001:db8::/32").unwrap();
assert_eq!(None, v4.merge(&v6));