pub struct IpnetTrie<T> { /* private fields */ }Expand description
Table holding IPv4 and IPv6 network prefixes with value.
Implementations§
Source§impl<T> IpnetTrie<T>
impl<T> IpnetTrie<T>
Sourcepub fn len(&self) -> (usize, usize)
pub fn len(&self) -> (usize, usize)
Returns the number of elements in the table. First value is number of IPv4 networks and second is number of IPv6 networks.
Sourcepub fn insert<N: Into<IpNet>>(&mut self, network: N, data: T) -> Option<T>
pub fn insert<N: Into<IpNet>>(&mut self, network: N, data: T) -> Option<T>
Insert a value for the IpNet. If prefix existed previously, the old value is returned.
§Examples
use ipnet_trie::IpnetTrie;
use ipnet::Ipv6Net;
use std::net::Ipv6Addr;
let mut table = IpnetTrie::new();
let network = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap();
assert_eq!(table.insert(network, "foo"), None);
// Insert duplicate
assert_eq!(table.insert(network, "bar"), Some("foo"));
// Value is replaced
assert_eq!(table.insert(network, "null"), Some("bar"));Sourcepub fn remove<N: Into<IpNet>>(&mut self, network: N) -> Option<T>
pub fn remove<N: Into<IpNet>>(&mut self, network: N) -> Option<T>
Remove a IpNet from table. If prefix existed, the value is returned.
§Examples
use ipnet_trie::IpnetTrie;
use std::net::Ipv6Addr;
use ipnet::Ipv6Net;
let mut table = IpnetTrie::new();
let network = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap();
assert_eq!(table.insert(network, "foo"), None);
// Remove network from table
assert_eq!(table.remove(network), Some("foo"));
// Network is removed
assert_eq!(table.exact_match(network), None);Sourcepub fn exact_match<N: Into<IpNet>>(&self, network: N) -> Option<&T>
pub fn exact_match<N: Into<IpNet>>(&self, network: N) -> Option<&T>
Get pointer to value from table based on exact network match.
If network is not in table, None is returned.
§Examples
use ipnet_trie::IpnetTrie;
use std::net::Ipv6Addr;
use ipnet::Ipv6Net;
let mut table = IpnetTrie::new();
let network_a = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap();
let network_b = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 128).unwrap();
assert_eq!(table.insert(network_a, "foo"), None);
// Get value for network from trie
assert_eq!(table.exact_match(network_a), Some(&"foo"));
// Network B doesn not exist in trie
assert_eq!(table.exact_match(network_b), None);Sourcepub fn exact_match_mut<N: Into<IpNet>>(&mut self, network: N) -> Option<&mut T>
pub fn exact_match_mut<N: Into<IpNet>>(&mut self, network: N) -> Option<&mut T>
Get mutable pointer to value from table based on exact network match.
If network is not in table, None is returned.
§Examples
use ipnet_trie::IpnetTrie;
use std::net::Ipv6Addr;
use ipnet::Ipv6Net;
let mut table = IpnetTrie::new();
let network_a = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap();
let network_b = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 128).unwrap();
assert_eq!(table.insert(network_a, "foo"), None);
// Get value for network from trie
assert_eq!(table.exact_match_mut(network_a), Some(&mut "foo"));
// Network B does not exist in trie
assert_eq!(table.exact_match(network_b), None);Sourcepub fn longest_match(&self, ipnet: &IpNet) -> Option<(IpNet, &T)>
pub fn longest_match(&self, ipnet: &IpNet) -> Option<(IpNet, &T)>
Find most specific IP network in table that contains given IP address. If no network in table contains
given IP address, None is returned.
§Examples
use ipnet_trie::IpnetTrie;
use ipnet::{IpNet, Ipv6Net};
use std::net::{IpAddr, Ipv6Addr};
let mut table = IpnetTrie::new();
let network = IpNet::new(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0)), 64).unwrap();
let ip_address = Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0x1);
assert_eq!(table.insert(network, "foo"), None);
// Get value for network from table
assert_eq!(table.longest_match(&IpNet::from(ip_address.to_canonical())), Some((network, &"foo")));Sourcepub fn longest_match_mut(&mut self, ipnet: &IpNet) -> Option<(IpNet, &mut T)>
pub fn longest_match_mut(&mut self, ipnet: &IpNet) -> Option<(IpNet, &mut T)>
Find most specific IP network in table that contains given IP address. If no network in table contains
given IP address, None is returned.
§Examples
use ipnet_trie::IpnetTrie;
use ipnet::{IpNet, Ipv6Net};
use std::net::{IpAddr, Ipv6Addr};
let mut table = IpnetTrie::new();
let network = IpNet::new(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0)), 64).unwrap();
let ip_address = Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0x1);
assert_eq!(table.insert(network, "foo"), None);
// Get value for network from table
assert_eq!(table.longest_match_mut(&IpNet::from(ip_address.to_canonical())), Some((network, &mut "foo")));Sourcepub fn longest_match_ipv4(&self, net: &Ipv4Net) -> Option<(&Ipv4Net, &T)>
pub fn longest_match_ipv4(&self, net: &Ipv4Net) -> Option<(&Ipv4Net, &T)>
Specific version of longest_match for IPv4 address.
Sourcepub fn longest_match_ipv6(&self, net: &Ipv6Net) -> Option<(&Ipv6Net, &T)>
pub fn longest_match_ipv6(&self, net: &Ipv6Net) -> Option<(&Ipv6Net, &T)>
Specific version of longest_match for IPv6 address.
Sourcepub fn longest_match_ipv4_mut(
&mut self,
net: &Ipv4Net,
) -> Option<(&Ipv4Net, &mut T)>
pub fn longest_match_ipv4_mut( &mut self, net: &Ipv4Net, ) -> Option<(&Ipv4Net, &mut T)>
Specific version of longest_match for IPv4 address.
Sourcepub fn longest_match_ipv6_mut(
&mut self,
net: &Ipv6Net,
) -> Option<(&Ipv6Net, &mut T)>
pub fn longest_match_ipv6_mut( &mut self, net: &Ipv6Net, ) -> Option<(&Ipv6Net, &mut T)>
Specific version of longest_match for IPv6 address.
Sourcepub fn matches(&self, ipnet: &IpNet) -> Vec<(IpNet, &T)>
pub fn matches(&self, ipnet: &IpNet) -> Vec<(IpNet, &T)>
Find all IP networks in table that contains given IP address.
Returns iterator of IpNet and reference to value.
§Examples
use ipnet_trie::IpnetTrie;
use ipnet::{IpNet, Ipv6Net};
use std::net::{IpAddr, Ipv6Addr};
let mut table = IpnetTrie::new();
let network = IpNet::new(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0)), 64).unwrap();
let ip_address = Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0x1);
assert_eq!(table.insert(network, "foo"), None);
// Get value for network from table
assert_eq!(table.matches(&IpNet::from(ip_address.to_canonical())).len(), 1);Sourcepub fn matches_ipv4(&self, net: &Ipv4Net) -> Vec<(&Ipv4Net, &T)>
pub fn matches_ipv4(&self, net: &Ipv4Net) -> Vec<(&Ipv4Net, &T)>
Specific version of matches for IPv4 address.
Sourcepub fn matches_ipv6(&self, net: &Ipv6Net) -> Vec<(&Ipv6Net, &T)>
pub fn matches_ipv6(&self, net: &Ipv6Net) -> Vec<(&Ipv6Net, &T)>
Specific version of matches for IPv6 address.
Sourcepub fn iter(&self) -> impl Iterator<Item = (IpNet, &T)>
pub fn iter(&self) -> impl Iterator<Item = (IpNet, &T)>
Iterator for all networks in table, first are iterated IPv4 and then IPv6 networks. Order is not guaranteed.
§Examples
use ipnet_trie::IpnetTrie;
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
let mut table: IpnetTrie<&str> = IpnetTrie::new();
let network_a = Ipv4Net::new(Ipv4Addr::new(192, 168, 0, 0), 24).unwrap();
assert_eq!(table.insert(network_a, "foo"), None);
let network_b = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap();
assert_eq!(table.insert(network_b, "foo"), None);
let mut iterator = table.iter();
assert_eq!(iterator.next(), Some((IpNet::V4(network_a), &"foo")));
assert_eq!(iterator.next(), Some((IpNet::V6(network_b), &"foo")));
assert_eq!(iterator.next(), None);Sourcepub fn iter_mut(&mut self) -> impl Iterator<Item = (IpNet, &mut T)>
pub fn iter_mut(&mut self) -> impl Iterator<Item = (IpNet, &mut T)>
Mutable iterator for all networks in table, first are iterated IPv4 and then IPv6 networks. Order is not guaranteed.
§Examples
use ipnet_trie::IpnetTrie;
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
let mut table: IpnetTrie<&str> = IpnetTrie::new();
let network_a = Ipv4Net::new(Ipv4Addr::new(192, 168, 0, 0), 24).unwrap();
assert_eq!(table.insert(network_a, "foo"), None);
let network_b = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap();
assert_eq!(table.insert(network_b, "foo"), None);
let mut iterator = table.iter_mut();
for (network, value) in iterator {
*value = "bar";
}
assert_eq!(table.exact_match(network_a), Some(&"bar"));
assert_eq!(table.exact_match(network_b), Some(&"bar"));Sourcepub fn iter_ipv4(&self) -> impl Iterator<Item = (&Ipv4Net, &T)>
pub fn iter_ipv4(&self) -> impl Iterator<Item = (&Ipv4Net, &T)>
Iterator for all IPv4 networks in table. Order is not guaranteed.
Sourcepub fn iter_ipv6(&self) -> impl Iterator<Item = (&Ipv6Net, &T)>
pub fn iter_ipv6(&self) -> impl Iterator<Item = (&Ipv6Net, &T)>
Iterator for all IPv6 networks in table. Order is not guaranteed.
Sourcepub fn retain<F>(&mut self, f: F)
pub fn retain<F>(&mut self, f: F)
Retains only the elements specified by the predicate.
In other words, remove all pairs (k, v) such that f(ip_network, &mut v) returns false.
§Examples
use ipnet_trie::IpnetTrie;
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
let mut table: IpnetTrie<&str> = IpnetTrie::new();
let network_a = Ipv4Net::new(Ipv4Addr::new(192, 168, 0, 0), 24).unwrap();
assert_eq!(table.insert(network_a, "foo"), None);
let network_b = Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap();
assert_eq!(table.insert(network_b, "foo"), None);
// Keep just IPv4 networks
table.retain(|network, _| network.network().is_ipv4());
assert_eq!(table.exact_match(network_a), Some(&"foo"));
assert_eq!(table.exact_match(network_b), None);Sourcepub fn ip_count(&self) -> IpCount
pub fn ip_count(&self) -> IpCount
Count the number of unique IPv4 and IPv6 addresses in the trie.
Returns an IpCount struct. The ipv4 field uses u64 and can represent
the entire IPv4 address space (2³²). The ipv6 field is Option<u128>:
Some(count) for any value up to 2¹²⁸−1, and None when the entire IPv6
address space (2¹²⁸ addresses) is covered, since that value cannot be
represented in a u128.
use std::str::FromStr;
use ipnet::{Ipv4Net, Ipv6Net};
use ipnet_trie::{IpnetTrie, IpCount};
let mut table = IpnetTrie::new();
table.insert(Ipv4Net::from_str("192.0.2.129/25").unwrap(), 1);
table.insert(Ipv4Net::from_str("192.0.2.0/24").unwrap(), 1);
table.insert(Ipv4Net::from_str("192.0.2.0/24").unwrap(), 1);
table.insert(Ipv4Net::from_str("192.0.2.0/24").unwrap(), 1);
assert_eq!(table.ip_count(), IpCount { ipv4: 256, ipv6: Some(0) });
table.insert(Ipv4Net::from_str("198.51.100.0/25").unwrap(), 1);
table.insert(Ipv4Net::from_str("198.51.100.64/26").unwrap(), 1);
assert_eq!(table.ip_count(), IpCount { ipv4: 384, ipv6: Some(0) });
table.insert(Ipv4Net::from_str("198.51.100.65/26").unwrap(), 1);
assert_eq!(table.ip_count(), IpCount { ipv4: 384, ipv6: Some(0) });
table.insert(Ipv6Net::from_str("2001:DB80::/48").unwrap(), 1);
assert_eq!(table.ip_count(), IpCount { ipv4: 384, ipv6: Some(2_u128.pow(80)) });
table.insert(Ipv6Net::from_str("2001:DB80::/49").unwrap(), 1);
assert_eq!(table.ip_count(), IpCount { ipv4: 384, ipv6: Some(2_u128.pow(80)) });
table.insert(Ipv6Net::from_str("2001:DB81::/48").unwrap(), 1);
assert_eq!(table.ip_count(), IpCount { ipv4: 384, ipv6: Some(2_u128.pow(81)) });
// Full IPv4 space (0.0.0.0/0) — 2^32 addresses, fits in u64
let mut v4_full = IpnetTrie::new();
v4_full.insert(Ipv4Net::from_str("0.0.0.0/0").unwrap(), 1);
assert_eq!(v4_full.ip_count(), IpCount { ipv4: 1u64 << 32, ipv6: Some(0) });
// Full IPv6 space (::/0) — 2^128 addresses, cannot fit in u128
let mut v6_full = IpnetTrie::new();
v6_full.insert(Ipv6Net::from_str("::/0").unwrap(), 1);
assert_eq!(v6_full.ip_count(), IpCount { ipv4: 0, ipv6: None });Sourcepub fn get_aggregated_prefixes(&self) -> (Vec<Ipv4Net>, Vec<Ipv6Net>)
pub fn get_aggregated_prefixes(&self) -> (Vec<Ipv4Net>, Vec<Ipv6Net>)
Retrieves the aggregated prefixes for both IPv4 and IPv6 from the given data.
§Returns
A tuple containing two vectors. The first vector contains the aggregated IPv4 prefixes, and the second vector contains the aggregated IPv6 prefixes.
Sourcepub fn diff(&self, other: &Self) -> (Vec<IpNet>, Vec<IpNet>)
pub fn diff(&self, other: &Self) -> (Vec<IpNet>, Vec<IpNet>)
Find the difference between two prefix tries, returning two vectors of IpNets, one for added prefixes, and one for removed prefixes.
- added prefixes: all prefixes in other that are not in self
- removed prefixes: all prefixes in self that are not in other