-
Notifications
You must be signed in to change notification settings - Fork 29
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
Iterator for supernets. #23
Comments
Hi @jcgruenhage -- out of curiosity how are you using that? I'm happy to include it if you want to keep implementing it. 👍 |
I'm not using that myself, but my flatmate is. The usecase is a list of CIDRs, where some have a flag set and some don't, and the goal is to find the number of IPs that have (or don't have? not sure right now) that bit set. So, for counting, you check the bigger nets first, but if a smaller net is included in a bigger net, you need to change the count. For that to work, you need to look up whether a supernet is included in that list, so you need to iterate over the supernets. Right now, their code is doing For the actual counting of IPs in an They also likely need an |
+1! My use case is to find a set of "parent" CIDR networks for a given network (v4 / v6) up to a desired minimum prefix length and return an iterator. Here's a minimum working example that will supernet Happy to fork + send a PR, it would be my first upstream commit for a Rust project! use ipnet::IpNet;
use std::cmp::Ordering::{Equal, Greater};
struct Supernets {
network: IpNet,
min_prefix_len: u8,
}
impl Supernets {
fn new(network: IpNet, min_prefix_len: u8) -> Self {
Supernets {
network: network,
min_prefix_len: min_prefix_len,
}
}
}
impl Iterator for Supernets {
type Item = IpNet;
fn next(&mut self) -> Option<Self::Item> {
match self.network.prefix_len().partial_cmp(&self.min_prefix_len) {
Some(Greater) => {
// calc next, return current
let current = self.network;
self.network = current.supernet().unwrap();
Some(current)
}
Some(Equal) => {
// calc next, return current
let current = self.network;
self.network = current.supernet().unwrap();
Some(current)
}
_ => {
// handle end condition
None
}
}
}
}
fn main() {
let start_net = "10.224.195.200/29".parse::<IpNet>().unwrap();
let supernets = Supernets::new(start_net, 4);
for net in supernets {
println!("{:?}", net);
}
} Produces the following:
For ipv6: fn main() {
let start_net = "2406:3600:25b:c500::/56".parse::<IpNet>().unwrap();
let supernets = Supernets::new(start_net, 48);
for net in supernets {
println!("{:?}", net);
}
} Output:
|
That code looks good to me, except for the one match where you have branches with the same content. Maybe you should put |
Hi Jan, Nice catch. I've sent a PR with your recommendation in it. |
It'd be useful if it was possible to iterate over the supernets of a net. This can already be done with something like
Doing this here instead would obv be a lot cleaner:
I've started implementing this, but wanted to post an issue before I sink more than a few minutes into it, to make sure this is something that would get merged if implemented.
The text was updated successfully, but these errors were encountered: