#cidr #ip #ipv4 #ipv6

cidr-utils

This crate provides data structures and functions to deal with IPv4 CIDRs and IPv6 CIDRs

28 releases

0.5.10 Dec 31, 2022
0.5.9 Nov 2, 2022
0.5.8 Oct 25, 2022
0.5.7 May 20, 2022
0.3.5 Jul 28, 2019

#332 in Network programming

Download history 11666/week @ 2023-02-03 13369/week @ 2023-02-10 13971/week @ 2023-02-17 14623/week @ 2023-02-24 11262/week @ 2023-03-03 14593/week @ 2023-03-10 15211/week @ 2023-03-17 18010/week @ 2023-03-24 16725/week @ 2023-03-31 14496/week @ 2023-04-07 12118/week @ 2023-04-14 13030/week @ 2023-04-21 12814/week @ 2023-04-28 13053/week @ 2023-05-05 12904/week @ 2023-05-12 14123/week @ 2023-05-19

55,075 downloads per month
Used in 17 crates (15 directly)

MIT license

87KB
2K SLoC

CIDR Utils

CI

This crate provides data structures and functions to deal with IPv4 CIDRs and IPv6 CIDRs.

Examples

The format of CIDRs.

use cidr_utils::cidr::IpCidr;

assert_eq!(true, IpCidr::is_ip_cidr("192.168.1.0/24"));
assert_eq!(true, IpCidr::is_ip_cidr("192.168.1.1/24"));
assert_eq!(true, IpCidr::is_ip_cidr("192.168.1.0/0"));
assert_eq!(false, IpCidr::is_ip_cidr("192.168.1.0/33"));

assert_eq!(true, IpCidr::is_ip_cidr("192.168.1.0/255.255.255.0"));
assert_eq!(true, IpCidr::is_ip_cidr("192.168.1.0/255.255.254.0"));
assert_eq!(false, IpCidr::is_ip_cidr("192.168.1.0/255.255.255.1"));

assert_eq!(true, IpCidr::is_ip_cidr("192.168.1.0")); // 192.168.1.0/32
assert_eq!(true, IpCidr::is_ip_cidr("192.168.1"));   // 192.168.1/24
assert_eq!(true, IpCidr::is_ip_cidr("192.168"));     // 192.168/16
assert_eq!(true, IpCidr::is_ip_cidr("192"));         // 192/8

assert_eq!(true, IpCidr::is_ip_cidr("192/8"));
assert_eq!(true, IpCidr::is_ip_cidr("192/255.0.0.0"));
assert_eq!(false, IpCidr::is_ip_cidr("192/16"));
assert_eq!(false, IpCidr::is_ip_cidr("192/255.255.0.0"));

assert_eq!(true, IpCidr::is_ip_cidr("2001:4f8:3:ba::/64"));
assert_eq!(true, IpCidr::is_ip_cidr("2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128"));
assert_eq!(true, IpCidr::is_ip_cidr("::ffff:1.2.3.0/120"));
assert_eq!(true, IpCidr::is_ip_cidr("::ffff:1.2.3.1/120"));
assert_eq!(false, IpCidr::is_ip_cidr("::ffff:1.2.3.0/129"));

assert_eq!(true, IpCidr::is_ip_cidr("2001:4f8:3:ba:2e0:81ff:fe22:d1f1")); // 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128
assert_eq!(true, IpCidr::is_ip_cidr("2001:4f8:3:ba::"));                  // 2001:4f8:3:ba::/128

Determine whether an IP is in a CIDR.

use std::net::IpAddr;
use std::str::FromStr;

use cidr_utils::cidr::IpCidr;

let cidr = IpCidr::from_str("192.168.51.0/24").unwrap();

assert_eq!(true, cidr.contains(IpAddr::from_str("192.168.51.103").unwrap()));
assert_eq!(false, cidr.contains(IpAddr::from_str("192.168.50.103").unwrap()));
use std::net::Ipv4Addr;

use cidr_utils::cidr::Ipv4Cidr;

let cidr = Ipv4Cidr::from_str("192.168.51.0/24").unwrap();

assert_eq!(true, cidr.contains([192, 168, 51, 103]));
assert_eq!(true, cidr.contains(Ipv4Addr::new(192, 168, 51, 103)));
assert_eq!(false, cidr.contains([192, 168, 50, 103]));

assert_eq!(256, cidr.size());

Combine subnetworks to supernetworks.

use cidr_utils::cidr::Ipv4Cidr;
use cidr_utils::utils::Ipv4CidrCombiner;

let mut combiner = Ipv4CidrCombiner::new();

combiner.push(Ipv4Cidr::from_str("192.168.51.100").unwrap());

assert_eq!(1, combiner.len());
assert_eq!("192.168.51.100/32".to_string(), combiner[0].to_string());

combiner.push(Ipv4Cidr::from_str("192.168.51.101").unwrap());

assert_eq!(1, combiner.len());
assert_eq!("192.168.51.100/31".to_string(), combiner[0].to_string());

combiner.push(Ipv4Cidr::from_str("192.168.51.102").unwrap());

assert_eq!(2, combiner.len());
assert_eq!("192.168.51.100/31".to_string(), combiner[0].to_string());
assert_eq!("192.168.51.102/32".to_string(), combiner[1].to_string());

combiner.push(Ipv4Cidr::from_str("192.168.51.103").unwrap());

assert_eq!(1, combiner.len());
assert_eq!("192.168.51.100/30".to_string(), combiner[0].to_string());

assert_eq!(true, combiner.contains([192, 168, 51, 102]));
assert_eq!(false, combiner.contains([192, 168, 51, 105]));

assert_eq!(4, combiner.size());

Separate a network into subnetworks.

use cidr_utils::cidr::Ipv4Cidr;
use cidr_utils::utils::Ipv4CidrSeparator;

let cidr = Ipv4Cidr::from_str("192.168.56.0/24").unwrap();

let result = Ipv4CidrSeparator::divide_by(&cidr, 4).unwrap();

assert_eq!(4, result.len());
assert_eq!(64, result[0].size());
assert_eq!(64, result[1].size());
assert_eq!(64, result[2].size());
assert_eq!(64, result[3].size());

assert_eq!("[192.168.56.0/26]".to_string(), result[0].to_string());
assert_eq!("[192.168.56.64/26]".to_string(), result[1].to_string());
assert_eq!("[192.168.56.128/26]".to_string(), result[2].to_string());
assert_eq!("[192.168.56.192/26]".to_string(), result[3].to_string());

let result = Ipv4CidrSeparator::divide_by(&cidr, 5).unwrap();

assert_eq!(5, result.len());
assert_eq!(51, result[0].size());
assert_eq!(51, result[1].size());
assert_eq!(51, result[2].size());
assert_eq!(51, result[3].size());
assert_eq!(52, result[4].size());

assert_eq!("[192.168.56.0/27, 192.168.56.32/28, 192.168.56.48/31, 192.168.56.50/32]".to_string(), result[0].to_string());
assert_eq!("[192.168.56.51/32, 192.168.56.52/30, 192.168.56.56/29, 192.168.56.64/27, 192.168.56.96/30, 192.168.56.100/31]".to_string(), result[1].to_string());
assert_eq!("[192.168.56.102/31, 192.168.56.104/29, 192.168.56.112/28, 192.168.56.128/28, 192.168.56.144/29, 192.168.56.152/32]".to_string(), result[2].to_string());
assert_eq!("[192.168.56.153/32, 192.168.56.154/31, 192.168.56.156/30, 192.168.56.160/27, 192.168.56.192/29, 192.168.56.200/30]".to_string(), result[3].to_string());
assert_eq!("[192.168.56.204/30, 192.168.56.208/28, 192.168.56.224/27]".to_string(), result[4].to_string());

let result = Ipv4CidrSeparator::sub_networks(&cidr, 26).unwrap();

assert_eq!(4, result.len());
assert_eq!(64, result[0].size());
assert_eq!(64, result[1].size());
assert_eq!(64, result[2].size());
assert_eq!(64, result[3].size());

assert_eq!("192.168.56.0/26".to_string(), result[0].to_string());
assert_eq!("192.168.56.64/26".to_string(), result[1].to_string());
assert_eq!("192.168.56.128/26".to_string(), result[2].to_string());
assert_eq!("192.168.56.192/26".to_string(), result[3].to_string());

Serde Support

Enable the serde feature to support the serde framework.

[dependencies.cidr-utils]
version = "*"
features = ["serde"]

Crates.io

https://crates.io/crates/cidr-utils

Documentation

https://docs.rs/cidr-utils

License

MIT

Dependencies

~1.4–2MB
~51K SLoC