extern crate ipaddress; extern crate num; #[cfg(test)] mod tests { use ipaddress::ipv4; use ipaddress::IPAddress; use num::bigint::BigUint; use num::ToPrimitive; use std::collections::HashMap; use std::ops::Deref; use std::str::FromStr; use std::sync::{Arc, Mutex}; #[derive(Debug)] struct IPv4Prefix { pub ip: String, pub prefix: usize, } struct IPv4Test { pub valid_ipv4: HashMap<&'static str, IPv4Prefix>, pub invalid_ipv4: Vec<&'static str>, #[allow(dead_code)] pub valid_ipv4_range: Vec<&'static str>, pub netmask_values: HashMap<&'static str, &'static str>, pub decimal_values: HashMap<&'static str, u32>, pub ip: IPAddress, pub network: IPAddress, pub networks: HashMap<&'static str, &'static str>, pub broadcast: HashMap<&'static str, &'static str>, pub class_a: IPAddress, pub class_b: IPAddress, pub class_c: IPAddress, pub classful: HashMap<&'static str, usize>, } fn setup() -> IPv4Test { let mut ipv4t = IPv4Test { valid_ipv4: HashMap::new(), // , "10.0.0", "10.0" invalid_ipv4: vec!["10.0.0.256", "10.0.0.0.0"], valid_ipv4_range: vec!["10.0.0.1-254", "10.0.1-254.0", "10.1-254.0.0"], netmask_values: HashMap::new(), decimal_values: HashMap::new(), ip: ipv4::new("172.16.10.1/24").unwrap(), network: ipv4::new("172.16.10.0/24").unwrap(), networks: HashMap::new(), broadcast: HashMap::new(), class_a: ipv4::new("10.0.0.1/8").unwrap(), class_b: ipv4::new("172.16.0.1/16").unwrap(), class_c: ipv4::new("192.168.0.1/24").unwrap(), classful: HashMap::new(), }; ipv4t.valid_ipv4.insert( "9.9/17", IPv4Prefix { ip: String::from_str("9.0.0.9").unwrap(), prefix: 17, }, ); ipv4t.valid_ipv4.insert( "100.1.100", IPv4Prefix { ip: String::from_str("100.1.0.100").unwrap(), prefix: 32, }, ); ipv4t.valid_ipv4.insert( "0.0.0.0/0", IPv4Prefix { ip: String::from_str("0.0.0.0").unwrap(), prefix: 0, }, ); ipv4t.valid_ipv4.insert( "10.0.0.0", IPv4Prefix { ip: String::from_str("10.0.0.0").unwrap(), prefix: 32, }, ); ipv4t.valid_ipv4.insert( "10.0.0.1", IPv4Prefix { ip: String::from_str("10.0.0.1").unwrap(), prefix: 32, }, ); ipv4t.valid_ipv4.insert( "10.0.0.1/24", IPv4Prefix { ip: String::from_str("10.0.0.1").unwrap(), prefix: 24, }, ); ipv4t.valid_ipv4.insert( "10.0.0.9/255.255.255.0", IPv4Prefix { ip: String::from_str("10.0.0.9").unwrap(), prefix: 24, }, ); ipv4t.netmask_values.insert("0.0.0.0/0", "0.0.0.0"); ipv4t.netmask_values.insert("10.0.0.0/8", "255.0.0.0"); ipv4t.netmask_values.insert("172.16.0.0/16", "255.255.0.0"); ipv4t .netmask_values .insert("192.168.0.0/24", "255.255.255.0"); ipv4t .netmask_values .insert("192.168.100.4/30", "255.255.255.252"); ipv4t.decimal_values.insert("0.0.0.0/0", 0); ipv4t.decimal_values.insert("10.0.0.0/8", 167772160); ipv4t.decimal_values.insert("172.16.0.0/16", 2886729728); ipv4t.decimal_values.insert("192.168.0.0/24", 3232235520); ipv4t.decimal_values.insert("192.168.100.4/30", 3232261124); ipv4t.ip = IPAddress::parse("172.16.10.1/24").unwrap(); ipv4t.network = IPAddress::parse("172.16.10.0/24").unwrap(); ipv4t.broadcast.insert("10.0.0.0/8", "10.255.255.255/8"); ipv4t.broadcast.insert("172.16.0.0/16", "172.16.255.255/16"); ipv4t.broadcast.insert("192.168.0.0/24", "192.168.0.255/24"); ipv4t .broadcast .insert("192.168.100.4/30", "192.168.100.7/30"); ipv4t.networks.insert("10.5.4.3/8", "10.0.0.0/8"); ipv4t.networks.insert("172.16.5.4/16", "172.16.0.0/16"); ipv4t.networks.insert("192.168.4.3/24", "192.168.4.0/24"); ipv4t .networks .insert("192.168.100.5/30", "192.168.100.4/30"); ipv4t.class_a = IPAddress::parse("10.0.0.1/8").unwrap(); ipv4t.class_b = IPAddress::parse("172.16.0.1/16").unwrap(); ipv4t.class_c = IPAddress::parse("192.168.0.1/24").unwrap(); ipv4t.classful.insert("10.1.1.1", 8); ipv4t.classful.insert("150.1.1.1", 16); ipv4t.classful.insert("200.1.1.1", 24); return ipv4t; } #[test] pub fn test_initialize() { let setup = setup(); for i in setup.valid_ipv4.keys() { let ip = IPAddress::parse(i.to_string()).unwrap(); assert!(ip.is_ipv4() && !ip.is_ipv6()); } assert_eq!(32, setup.ip.prefix.ip_bits.bits); assert!(IPAddress::parse("1.f.13.1/-3").is_err()); assert!(IPAddress::parse("10.0.0.0/8").is_ok()); } #[test] pub fn test_initialize_format_error() { for i in setup().invalid_ipv4 { assert!(IPAddress::parse(i).is_err()); } assert!(IPAddress::parse("10.0.0.0/asd").is_err()); } #[test] pub fn test_initialize_without_prefix() { assert!(IPAddress::parse("10.10.0.0").is_ok()); let ip = IPAddress::parse("10.10.0.0").unwrap(); assert!(!ip.is_ipv6() && ip.is_ipv4()); assert_eq!(32, ip.prefix.num); } #[test] pub fn test_attributes() { for (arg, attr) in setup().valid_ipv4 { let ip = IPAddress::parse(arg).unwrap(); // println!("test_attributes:{}:{:?}", arg, attr); assert_eq!(attr.ip, ip.to_s()); assert_eq!(attr.prefix, ip.prefix.num); } } #[test] pub fn test_octets() { let ip = IPAddress::parse("10.1.2.3/8").unwrap(); assert_eq!(ip.parts(), [10, 1, 2, 3]); } #[test] pub fn test_method_to_string() { for (arg, attr) in setup().valid_ipv4 { let ip = IPAddress::parse(arg).unwrap(); assert_eq!(format!("{}/{}", attr.ip, attr.prefix), ip.to_string()); } } #[test] pub fn test_method_to_s() { for (arg, attr) in setup().valid_ipv4 { let ip = IPAddress::parse(arg).unwrap(); assert_eq!(attr.ip, ip.to_s()); // let ip_c = IPAddress::parse(arg).unwrap(); // assert_eq!(attr.ip, ip.to_s()); } } #[test] pub fn test_netmask() { for (addr, mask) in setup().netmask_values { let ip = IPAddress::parse(addr).unwrap(); assert_eq!(ip.netmask().to_s(), mask); } } #[test] pub fn test_method_to_u32() { for (addr, int) in setup().decimal_values { let ip = IPAddress::parse(addr).unwrap(); assert_eq!(ip.host_address.to_u32().unwrap(), int); } } #[test] pub fn test_method_is_network() { assert_eq!(true, setup().network.is_network()); assert_eq!(false, setup().ip.is_network()); } #[test] pub fn test_one_address_network() { let network = IPAddress::parse("172.16.10.1/32").unwrap(); assert_eq!(false, network.is_network()); } #[test] pub fn test_method_broadcast() { for (addr, bcast) in setup().broadcast { let ip = IPAddress::parse(addr).unwrap(); assert_eq!(bcast, ip.broadcast().to_string()); } } #[test] pub fn test_method_network() { for (addr, net) in setup().networks { let ip = IPAddress::parse(addr).unwrap(); assert_eq!(net, ip.network().to_string()); } } #[test] pub fn test_method_bits() { let ip = IPAddress::parse("127.0.0.1").unwrap(); assert_eq!("01111111000000000000000000000001", ip.bits()); } #[test] pub fn test_method_first() { let mut ip = IPAddress::parse("192.168.100.0/24").unwrap(); assert_eq!("192.168.100.1", ip.first().to_s()); ip = IPAddress::parse("192.168.100.50/24").unwrap(); assert_eq!("192.168.100.1", ip.first().to_s()); } #[test] pub fn test_method_last() { let mut ip = IPAddress::parse("192.168.100.0/24").unwrap(); assert_eq!("192.168.100.254", ip.last().to_s()); ip = IPAddress::parse("192.168.100.50/24").unwrap(); assert_eq!("192.168.100.254", ip.last().to_s()); } #[test] pub fn test_method_each_host() { let ip = IPAddress::parse("10.0.0.1/29").unwrap(); let arr = Arc::new(Mutex::new(Vec::new())); ip.each_host(|i| arr.lock().unwrap().push(i.to_s())); assert_eq!( *arr.lock().unwrap().deref(), ["10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4", "10.0.0.5", "10.0.0.6"] ); } #[test] pub fn test_method_each() { let ip = IPAddress::parse("10.0.0.1/29").unwrap(); let arr = Arc::new(Mutex::new(Vec::new())); ip.each(|i| arr.lock().unwrap().push(i.to_s())); assert_eq!( *arr.lock().unwrap().deref(), [ "10.0.0.0", "10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4", "10.0.0.5", "10.0.0.6", "10.0.0.7" ] ); } #[test] pub fn test_method_size() { let ip = IPAddress::parse("10.0.0.1/29").unwrap(); assert_eq!(ip.size(), BigUint::from_str("8").unwrap()); } #[test] pub fn test_method_network_u32() { assert_eq!( 2886732288, setup().ip.network().host_address.to_u32().unwrap() ); } #[test] pub fn test_method_broadcast_u32() { assert_eq!( 2886732543, setup().ip.broadcast().host_address.to_u32().unwrap() ); } #[test] pub fn test_method_include() { let mut ip = IPAddress::parse("192.168.10.100/24").unwrap(); let addr = IPAddress::parse("192.168.10.102/24").unwrap(); assert_eq!(true, ip.includes(&addr)); assert_eq!( false, ip.includes(&IPAddress::parse("172.16.0.48").unwrap()) ); ip = IPAddress::parse("10.0.0.0/8").unwrap(); assert_eq!(true, ip.includes(&IPAddress::parse("10.0.0.0/9").unwrap())); assert_eq!(true, ip.includes(&IPAddress::parse("10.1.1.1/32").unwrap())); assert_eq!(true, ip.includes(&IPAddress::parse("10.1.1.1/9").unwrap())); assert_eq!( false, ip.includes(&IPAddress::parse("172.16.0.0/16").unwrap()) ); assert_eq!(false, ip.includes(&IPAddress::parse("10.0.0.0/7").unwrap())); assert_eq!(false, ip.includes(&IPAddress::parse("5.5.5.5/32").unwrap())); assert_eq!(false, ip.includes(&IPAddress::parse("11.0.0.0/8").unwrap())); ip = IPAddress::parse("13.13.0.0/13").unwrap(); assert_eq!( false, ip.includes(&IPAddress::parse("13.16.0.0/32").unwrap()) ); } #[test] pub fn test_method_include_all() { let ip = IPAddress::parse("192.168.10.100/24").unwrap(); let addr1 = IPAddress::parse("192.168.10.102/24").unwrap(); let addr2 = IPAddress::parse("192.168.10.103/24").unwrap(); assert_eq!(true, ip.includes_all(&[addr1.clone(), addr2])); assert_eq!( false, ip.includes_all(&[addr1, IPAddress::parse("13.16.0.0/32").unwrap()]) ); } #[test] pub fn test_method_ipv4() { assert_eq!(true, setup().ip.is_ipv4()); } #[test] pub fn test_method_ipv6() { assert_eq!(false, setup().ip.is_ipv6()); } #[test] pub fn test_method_private() { assert_eq!( true, IPAddress::parse("169.254.10.50/24").unwrap().is_private() ); assert_eq!( true, IPAddress::parse("192.168.10.50/24").unwrap().is_private() ); assert_eq!( true, IPAddress::parse("192.168.10.50/16").unwrap().is_private() ); assert_eq!( true, IPAddress::parse("172.16.77.40/24").unwrap().is_private() ); assert_eq!( true, IPAddress::parse("172.16.10.50/14").unwrap().is_private() ); assert_eq!( true, IPAddress::parse("10.10.10.10/10").unwrap().is_private() ); assert_eq!(true, IPAddress::parse("10.0.0.0/8").unwrap().is_private()); assert_eq!( false, IPAddress::parse("192.168.10.50/12").unwrap().is_private() ); assert_eq!(false, IPAddress::parse("3.3.3.3").unwrap().is_private()); assert_eq!(false, IPAddress::parse("10.0.0.0/7").unwrap().is_private()); assert_eq!( false, IPAddress::parse("172.32.0.0/12").unwrap().is_private() ); assert_eq!( false, IPAddress::parse("172.16.0.0/11").unwrap().is_private() ); assert_eq!( false, IPAddress::parse("192.0.0.2/24").unwrap().is_private() ); } #[test] pub fn test_method_octet() { assert_eq!(*setup().ip.parts().get(0).unwrap(), 172); assert_eq!(*setup().ip.parts().get(1).unwrap(), 16); assert_eq!(*setup().ip.parts().get(2).unwrap(), 10); assert_eq!(*setup().ip.parts().get(3).unwrap(), 1); } #[test] pub fn test_method_a() { assert_eq!(true, ipv4::is_class_a(&setup().class_a)); assert_eq!(false, ipv4::is_class_a(&setup().class_b)); assert_eq!(false, ipv4::is_class_a(&setup().class_c)); } #[test] pub fn test_method_b() { assert_eq!(true, ipv4::is_class_b(&setup().class_b)); assert_eq!(false, ipv4::is_class_b(&setup().class_a)); assert_eq!(false, ipv4::is_class_b(&setup().class_c)); } #[test] pub fn test_method_c() { assert_eq!(true, ipv4::is_class_c(&setup().class_c)); assert_eq!(false, ipv4::is_class_c(&setup().class_a)); assert_eq!(false, ipv4::is_class_c(&setup().class_b)); } #[test] pub fn test_method_to_ipv6() { assert_eq!("::ac10:a01", setup().ip.to_ipv6().to_s()); } #[test] pub fn test_method_reverse() { assert_eq!(setup().ip.dns_reverse(), "10.16.172.in-addr.arpa"); } #[test] pub fn test_method_dns_rev_domains() { assert_eq!( IPAddress::parse("173.17.5.1/23").unwrap().dns_rev_domains(), ["4.17.173.in-addr.arpa", "5.17.173.in-addr.arpa"] ); assert_eq!( IPAddress::parse("173.17.1.1/15").unwrap().dns_rev_domains(), ["16.173.in-addr.arpa", "17.173.in-addr.arpa"] ); assert_eq!( IPAddress::parse("173.17.1.1/7").unwrap().dns_rev_domains(), ["172.in-addr.arpa", "173.in-addr.arpa"] ); assert_eq!( IPAddress::parse("173.17.1.1/29").unwrap().dns_rev_domains(), [ "0.1.17.173.in-addr.arpa", "1.1.17.173.in-addr.arpa", "2.1.17.173.in-addr.arpa", "3.1.17.173.in-addr.arpa", "4.1.17.173.in-addr.arpa", "5.1.17.173.in-addr.arpa", "6.1.17.173.in-addr.arpa", "7.1.17.173.in-addr.arpa" ] ); assert_eq!( IPAddress::parse("174.17.1.1/24").unwrap().dns_rev_domains(), ["1.17.174.in-addr.arpa"] ); assert_eq!( IPAddress::parse("175.17.1.1/16").unwrap().dns_rev_domains(), ["17.175.in-addr.arpa"] ); assert_eq!( IPAddress::parse("176.17.1.1/8").unwrap().dns_rev_domains(), ["176.in-addr.arpa"] ); assert_eq!( IPAddress::parse("177.17.1.1/0").unwrap().dns_rev_domains(), ["in-addr.arpa"] ); assert_eq!( IPAddress::parse("178.17.1.1/32").unwrap().dns_rev_domains(), ["1.1.17.178.in-addr.arpa"] ); } #[test] pub fn test_method_compare() { let mut ip1 = IPAddress::parse("10.1.1.1/8").unwrap(); let mut ip2 = IPAddress::parse("10.1.1.1/16").unwrap(); let mut ip3 = IPAddress::parse("172.16.1.1/14").unwrap(); let ip4 = IPAddress::parse("10.1.1.1/8").unwrap(); // ip2 should be greater than ip1 assert_eq!(true, ip1 < ip2); assert_eq!(false, ip1 > ip2); assert_eq!(false, ip2 < ip1); // ip2 should be less than ip3 assert_eq!(true, ip2 < ip3); assert_eq!(false, ip2 > ip3); // ip1 should be less than ip3 assert_eq!(true, ip1 < ip3); assert_eq!(false, ip1 > ip3); assert_eq!(false, ip3 < ip1); // ip1 should be equal to itself assert_eq!(true, ip1 == ip1); // ip1 should be equal to ip4 assert_eq!(true, ip1 == ip4); // test sorting let mut res = [ip1, ip2, ip3]; res.sort(); assert_eq!( IPAddress::to_string_vec(&res.to_vec()), ["10.1.1.1/8", "10.1.1.1/16", "172.16.1.1/14"] ); // test same prefix ip1 = IPAddress::parse("10.0.0.0/24").unwrap(); ip2 = IPAddress::parse("10.0.0.0/16").unwrap(); ip3 = IPAddress::parse("10.0.0.0/8").unwrap(); { let mut res = [ip1, ip2, ip3]; res.sort(); assert_eq!( IPAddress::to_string_vec(&res.to_vec()), ["10.0.0.0/8", "10.0.0.0/16", "10.0.0.0/24"] ); } } #[test] pub fn test_method_minus() { let ip1 = IPAddress::parse("10.1.1.1/8").unwrap(); let ip2 = IPAddress::parse("10.1.1.10/8").unwrap(); assert_eq!(9, ip2.sub(&ip1).to_u32().unwrap()); assert_eq!(9, ip1.sub(&ip2).to_u32().unwrap()); } #[test] pub fn test_method_plus() { let mut ip1 = IPAddress::parse("172.16.10.1/24").unwrap(); let mut ip2 = IPAddress::parse("172.16.11.2/24").unwrap(); assert_eq!(IPAddress::to_string_vec(&ip1.add(&ip2)), ["172.16.10.0/23"]); ip2 = IPAddress::parse("172.16.12.2/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&ip1.add(&ip2)), [ip1.network().to_string(), ip2.network().to_string()] ); ip1 = IPAddress::parse("10.0.0.0/23").unwrap(); ip2 = IPAddress::parse("10.0.2.0/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&ip1.add(&ip2)), ["10.0.0.0/23", "10.0.2.0/24"] ); ip1 = IPAddress::parse("10.0.0.0/23").unwrap(); ip2 = IPAddress::parse("10.0.2.0/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&ip1.add(&ip2)), ["10.0.0.0/23", "10.0.2.0/24"] ); ip1 = IPAddress::parse("10.0.0.0/16").unwrap(); ip2 = IPAddress::parse("10.0.2.0/24").unwrap(); assert_eq!(IPAddress::to_string_vec(&ip1.add(&ip2)), ["10.0.0.0/16"]); ip1 = IPAddress::parse("10.0.0.0/23").unwrap(); ip2 = IPAddress::parse("10.1.0.0/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&ip1.add(&ip2)), ["10.0.0.0/23", "10.1.0.0/24"] ); } #[test] pub fn test_method_netmask_equal() { let ip = IPAddress::parse("10.1.1.1/16").unwrap(); assert_eq!(16, ip.prefix.num); let ip2 = ip.change_netmask("255.255.255.0").unwrap(); assert_eq!(24, ip2.prefix.num); } #[test] pub fn test_method_split() { assert!(setup().ip.split(0).is_err()); assert!(setup().ip.split(257).is_err()); assert_eq!(setup().ip.split(1).unwrap(), [setup().ip.network()]); assert_eq!( IPAddress::to_string_vec(&setup().network.split(8).unwrap()), [ "172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27", "172.16.10.96/27", "172.16.10.128/27", "172.16.10.160/27", "172.16.10.192/27", "172.16.10.224/27" ] ); assert_eq!( IPAddress::to_string_vec(&setup().network.split(7).unwrap()), [ "172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27", "172.16.10.96/27", "172.16.10.128/27", "172.16.10.160/27", "172.16.10.192/26" ] ); assert_eq!( IPAddress::to_string_vec(&setup().network.split(6).unwrap()), [ "172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27", "172.16.10.96/27", "172.16.10.128/26", "172.16.10.192/26" ] ); assert_eq!( IPAddress::to_string_vec(&setup().network.split(5).unwrap()), [ "172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27", "172.16.10.96/27", "172.16.10.128/25" ] ); assert_eq!( IPAddress::to_string_vec(&setup().network.split(4).unwrap()), [ "172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/26", "172.16.10.192/26" ] ); assert_eq!( IPAddress::to_string_vec(&setup().network.split(3).unwrap()), ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/25"] ); assert_eq!( IPAddress::to_string_vec(&setup().network.split(2).unwrap()), ["172.16.10.0/25", "172.16.10.128/25"] ); assert_eq!( IPAddress::to_string_vec(&setup().network.split(1).unwrap()), ["172.16.10.0/24"] ); } #[test] pub fn test_method_subnet() { assert!(setup().network.subnet(23).is_err()); assert!(setup().network.subnet(33).is_err()); assert!(setup().ip.subnet(30).is_ok()); assert_eq!( IPAddress::to_string_vec(&setup().network.subnet(26).unwrap()), [ "172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/26", "172.16.10.192/26" ] ); assert_eq!( IPAddress::to_string_vec(&setup().network.subnet(25).unwrap()), ["172.16.10.0/25", "172.16.10.128/25"] ); assert_eq!( IPAddress::to_string_vec(&setup().network.subnet(24).unwrap()), ["172.16.10.0/24"] ); } #[test] pub fn test_method_supernet() { assert!(setup().ip.supernet(24).is_err()); assert_eq!("0.0.0.0/0", setup().ip.supernet(0).unwrap().to_string()); // assert_eq!("0.0.0.0/0", setup().ip.supernet(-2).unwrap().to_string()); assert_eq!( "172.16.10.0/23", setup().ip.supernet(23).unwrap().to_string() ); assert_eq!( "172.16.8.0/22", setup().ip.supernet(22).unwrap().to_string() ); } #[test] pub fn test_classmethod_parse_u32() { for (addr, int) in setup().decimal_values { let ip = ipv4::from_u32(int, 32).unwrap(); let splitted: Vec<&str> = addr.split("/").collect(); let ip2 = ip .change_prefix(splitted[1].parse::().unwrap()) .unwrap(); assert_eq!(ip2.to_string(), addr); } } // pub fn test_classhmethod_extract() { // let str = "foobar172.16.10.1barbaz"; // assert_eq!("172.16.10.1", IPAddress::extract(str).to_s // } #[test] pub fn test_classmethod_summarize() { // Should return self if only one network given assert_eq!( IPAddress::summarize(&vec![setup().ip]), [setup().ip.network()] ); // Summarize homogeneous networks let mut ip1 = IPAddress::parse("172.16.10.1/24").unwrap(); let mut ip2 = IPAddress::parse("172.16.11.2/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2])), ["172.16.10.0/23"] ); { let ip1 = IPAddress::parse("10.0.0.1/24").unwrap(); let ip2 = IPAddress::parse("10.0.1.1/24").unwrap(); let ip3 = IPAddress::parse("10.0.2.1/24").unwrap(); let ip4 = IPAddress::parse("10.0.3.1/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2, ip3, ip4])), ["10.0.0.0/22"] ); } { let ip1 = IPAddress::parse("10.0.0.1/24").unwrap(); let ip2 = IPAddress::parse("10.0.1.1/24").unwrap(); let ip3 = IPAddress::parse("10.0.2.1/24").unwrap(); let ip4 = IPAddress::parse("10.0.3.1/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip4, ip3, ip2, ip1])), ["10.0.0.0/22"] ); } // Summarize non homogeneous networks ip1 = IPAddress::parse("10.0.0.0/23").unwrap(); ip2 = IPAddress::parse("10.0.2.0/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2])), ["10.0.0.0/23", "10.0.2.0/24"] ); ip1 = IPAddress::parse("10.0.0.0/16").unwrap(); ip2 = IPAddress::parse("10.0.2.0/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2])), ["10.0.0.0/16"] ); ip1 = IPAddress::parse("10.0.0.0/23").unwrap(); ip2 = IPAddress::parse("10.1.0.0/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2])), ["10.0.0.0/23", "10.1.0.0/24"] ); ip1 = IPAddress::parse("10.0.0.0/23").unwrap(); ip2 = IPAddress::parse("10.0.2.0/23").unwrap(); let mut ip3 = IPAddress::parse("10.0.4.0/24").unwrap(); let mut ip4 = IPAddress::parse("10.0.6.0/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2, ip3, ip4])), ["10.0.0.0/22", "10.0.4.0/24", "10.0.6.0/24"] ); { let ip1 = IPAddress::parse("10.0.1.1/24").unwrap(); let ip2 = IPAddress::parse("10.0.2.1/24").unwrap(); let ip3 = IPAddress::parse("10.0.3.1/24").unwrap(); let ip4 = IPAddress::parse("10.0.4.1/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2, ip3, ip4])), ["10.0.1.0/24", "10.0.2.0/23", "10.0.4.0/24"] ); } { let ip1 = IPAddress::parse("10.0.1.1/24").unwrap(); let ip2 = IPAddress::parse("10.0.2.1/24").unwrap(); let ip3 = IPAddress::parse("10.0.3.1/24").unwrap(); let ip4 = IPAddress::parse("10.0.4.1/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip4, ip3, ip2, ip1])), ["10.0.1.0/24", "10.0.2.0/23", "10.0.4.0/24"] ); } ip1 = IPAddress::parse("10.0.1.1/24").unwrap(); ip2 = IPAddress::parse("10.10.2.1/24").unwrap(); ip3 = IPAddress::parse("172.16.0.1/24").unwrap(); ip4 = IPAddress::parse("172.16.1.1/24").unwrap(); assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&vec![ip1, ip2, ip3, ip4])), ["10.0.1.0/24", "10.10.2.0/24", "172.16.0.0/23"] ); let mut ips = vec![ IPAddress::parse("10.0.0.12/30").unwrap(), IPAddress::parse("10.0.100.0/24").unwrap(), ]; assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&ips)), ["10.0.0.12/30", "10.0.100.0/24"] ); ips = vec![ IPAddress::parse("172.16.0.0/31").unwrap(), IPAddress::parse("10.10.2.1/32").unwrap(), ]; assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&ips)), ["10.10.2.1/32", "172.16.0.0/31"] ); ips = vec![ IPAddress::parse("172.16.0.0/32").unwrap(), IPAddress::parse("10.10.2.1/32").unwrap(), ]; assert_eq!( IPAddress::to_string_vec(&IPAddress::summarize(&ips)), ["10.10.2.1/32", "172.16.0.0/32"] ); } #[test] pub fn test_classmethod_parse_classful() { for (ip, prefix) in setup().classful { let res = ipv4::parse_classful(ip).unwrap(); assert_eq!(prefix, res.prefix.num); assert_eq!(format!("{}/{}", ip, prefix), res.to_string()); } assert!(ipv4::parse_classful("192.168.256.257").is_err()); } }