use std::collections::HashMap; use std::net::Ipv4Addr; use std::net::Ipv6Addr; use std::str::FromStr; #[cfg(test)] mod test { use super::*; use ripcalc::*; #[test] fn test_broadcast_num() { assert_eq!( broadcast(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("192.168.0.255").unwrap()) ); assert_eq!( broadcast(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.255.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("192.168.255.255").unwrap()) ); assert_eq!( broadcast(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:8a2e:0370:7334").unwrap() ), cidr: 64, }) .address, Addr::V6(Ipv6Addr::from_str("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff").unwrap()) ); } #[test] fn test_network_num() { assert_eq!( network(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()) ); assert_eq!( network(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.255.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("192.168.255.0").unwrap()) ); assert_eq!( network(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:8a2e:0370:7334").unwrap() ), cidr: 64, }) .address, Addr::V6(Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap()) ); } #[test] fn test_subnet_num() { assert_eq!( subnet(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("255.255.255.0").unwrap()) ); assert_eq!( subnet(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.255.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("255.255.255.0").unwrap()) ); } #[test] fn test_wildcard_num() { assert_eq!( wildcard(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("0.0.0.255").unwrap()) ); assert_eq!( wildcard(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.255.1").unwrap()), cidr: 24, }) .address, Addr::V4(Ipv4Addr::from_str("0.0.0.255").unwrap()) ); } #[test] fn test_network_size() { assert_eq!( network_size(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 32, }), 1 ); assert_eq!( network_size(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 31, }), 2 ); assert_eq!( network_size(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }), 4 ); assert_eq!( network_size(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 29, }), 8 ); assert_eq!( network_size(&Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 28, }), 16 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 128, }), 1 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 127, }), 2 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 126, }), 4 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 125, }), 8 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 124, }), 16 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 123, }), 32 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 122, }), 64 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 121, }), 128 ); assert_eq!( network_size(&Ip { address: Addr::V6( Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:0000:0000:0000").unwrap() ), cidr: 120, }), 256 ); } #[test] fn test_network_iter() { let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }; let mut i = addresses(&net, None, None); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.1").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.2").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.3").unwrap()) ); assert_eq!(i.next(), None); } #[test] fn test_format_ng_ip() { let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }; let f = format_details(&net, "%a".to_string(), &None); assert_eq!(f, Some("192.168.0.0".to_string())); } #[test] fn test_format_ng_percent() { let f = format_details( &Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }, "%".to_string(), &None, ); assert_eq!(f, Some("%".to_string())); let f = format_details( &Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }, "%%".to_string(), &None, ); assert_eq!(f, Some("%".to_string())); let f = format_details( &Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }, "%%%".to_string(), &None, ); assert_eq!(f, Some("%%".to_string())); let f = format_details( &Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }, "%%%%".to_string(), &None, ); assert_eq!(f, Some("%%".to_string())); } #[test] fn test_format_ng_boilerplate() { let net = Ip { address: Addr::V6(Ipv6Addr::from_str("2001:ba8:1f1:f1cb::4").unwrap()), cidr: 64, }; let f = format_details(&net, "select * from IP6 where (ip >= %ln and ip <= %lb) and active = 1;\nupdate IP6 set active = 0 where (ip >= %ln and ip <= %lb) and active = 1;".to_string(), &None); assert_eq!(f, Some("select * from IP6 where (ip >= 42540724579414763292693624807812497408 and ip <= 42540724579414763311140368881522049023) and active = 1; update IP6 set active = 0 where (ip >= 42540724579414763292693624807812497408 and ip <= 42540724579414763311140368881522049023) and active = 1;".to_string())); } #[test] fn test_format_ng_percent_marker() { let net = Ip { address: Addr::V6(Ipv6Addr::from_str("2001:ba8:1f1:f1cb::4").unwrap()), cidr: 64, }; let f = format_details(&net, "%%b".to_string(), &None); assert_eq!(f, Some("%b".to_string())); } #[test] fn test_format_ng_long_broadcast() { let net = Ip { address: Addr::V6(Ipv6Addr::from_str("2001:ba8:1f1:f1cb::4").unwrap()), cidr: 64, }; let f = format_details(&net, "%lb".to_string(), &None); assert_eq!( f, Some("42540724579414763311140368881522049023".to_string()) ); } #[test] fn test_format_ng_long_broadcast_backslash() { let net = Ip { address: Addr::V6(Ipv6Addr::from_str("2001:ba8:1f1:f1cb::4").unwrap()), cidr: 64, }; let f = format_details(&net, "%lb\n\n\n%%".to_string(), &None); assert_eq!( f, Some("42540724579414763311140368881522049023\n\n\n%".to_string()) ); } #[test] fn test_format_ng_backslash() { let net = Ip { address: Addr::V6(Ipv6Addr::from_str("2001:ba8:1f1:f1cb::4").unwrap()), cidr: 64, }; let f = format_details(&net, "\n".to_string(), &None); assert_eq!(f, Some("\n".to_string())); let f = format_details(&net, "\\".to_string(), &None); assert_eq!(f, Some('\\'.to_string())); let f = format_details(&net, "\\i".to_string(), &None); assert_eq!(f, Some("i".to_string())); let f = format_details(&net, "\\t".to_string(), &None); assert_eq!(f, Some("\t".to_string())); } #[test] fn test_address_space_use() { let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }; let mut hm: HashMap = HashMap::new(); hm.insert(Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), true); hm.insert(Addr::V4(Ipv4Addr::from_str("192.168.0.1").unwrap()), true); hm.insert(Addr::V4(Ipv4Addr::from_str("192.168.0.2").unwrap()), true); let mut i = addresses(&net, Some(&hm), None); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.3").unwrap()) ); assert_eq!(i.next(), None); let mut hm: HashMap = HashMap::new(); hm.insert(Addr::V4(Ipv4Addr::from_str("192.168.1.0").unwrap()), true); hm.insert(Addr::V4(Ipv4Addr::from_str("192.168.1.1").unwrap()), true); hm.insert(Addr::V4(Ipv4Addr::from_str("192.168.1.2").unwrap()), true); let mut i = addresses(&net, Some(&hm), None); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()) ); } #[test] fn test_smallest_network() { let mut hm: HashMap = HashMap::new(); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.1.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.2.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.3.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.4.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.5.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.2.0").unwrap()), cidr: 24, }; hm.insert(net, true); assert_eq!( smallest_group_network(&hm), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 21, }) ); let mut hm: HashMap = HashMap::new(); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.1.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.20.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.40.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.70.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.90.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.200.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.255.0").unwrap()), cidr: 24, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.220.0").unwrap()), cidr: 24, }; hm.insert(net, true); assert_eq!( smallest_group_network(&hm), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 16, }) ); let mut hm: HashMap = HashMap::new(); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.1").unwrap()), cidr: 30, }; hm.insert(net, true); let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.2").unwrap()), cidr: 30, }; hm.insert(net, true); assert_eq!( smallest_group_network(&hm), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 30, }) ); } #[test] fn test_base_hex() { assert_eq!( parse_address_mask("192.168.1.1", None, None, Some(10), false), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.1.1").unwrap()), cidr: 24, }) ); assert_eq!( parse_address_mask("192.168.1.1", None, None, None, false), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.1.1").unwrap()), cidr: 24, }) ); assert_eq!( parse_address_mask("D4166001", None, None, Some(16), false), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("212.22.96.1").unwrap()), cidr: 24, }) ); assert_eq!( parse_address_mask("177.0.0.1", None, None, Some(8), false), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("127.0.0.1").unwrap()), cidr: 24, }) ); } #[test] fn test_reverse() { assert_eq!( parse_address_mask("0101A8C0", None, None, Some(16), true), Some(Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.1.1").unwrap()), cidr: 24, }) ); } #[test] fn test_signed_ints() { let net = Ip { address: Addr::V4(Ipv4Addr::from_str("147.147.137.206").unwrap()), cidr: 30, }; let f = format_details(&net, "%La".to_string(), &None); assert_eq!(f, Some("-1819047474".to_string())); let f = format_details(&net, "%la".to_string(), &None); assert_eq!(f, Some("2475919822".to_string())); let net = Ip { address: Addr::V6(Ipv6Addr::from_str("ffff::ffff").unwrap()), cidr: 30, }; let f = format_details(&net, "%La".to_string(), &None); assert_eq!(f, Some("-5192296858534827628530496329154561".to_string())); let f = format_details(&net, "%la".to_string(), &None); assert_eq!( f, Some("340277174624079928635746076935439056895".to_string()) ); } #[test] fn test_within_ipv4() { assert_eq!( within( &Ip { address: Addr::V4(Ipv4Addr::from_str("127.0.0.1").unwrap()), cidr: 8 }, &Ip { address: Addr::V4(Ipv4Addr::from_str("10.0.0.0").unwrap()), cidr: 8 }, ), false ); assert_eq!( within( &Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 24 }, &Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 16 }, ), false ); assert_eq!( within( &Ip { address: Addr::V4(Ipv4Addr::from_str("127.0.0.1").unwrap()), cidr: 8 }, &Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 16 }, ), false ); assert_eq!( within( &Ip { address: Addr::V4(Ipv4Addr::from_str("127.0.0.1").unwrap()), cidr: 8 }, &Ip { address: Addr::V4(Ipv4Addr::from_str("127.1.1.1").unwrap()), cidr: 16 }, ), true ); } #[test] fn test_within_ipv6() { assert_eq!( within( &Ip { address: Addr::V6(Ipv6Addr::from_str("::1").unwrap()), cidr: 48 }, &Ip { address: Addr::V6(Ipv6Addr::from_str("f::1").unwrap()), cidr: 48 }, ), false ); assert_eq!( within( &Ip { address: Addr::V6(Ipv6Addr::from_str("::1").unwrap()), cidr: 48 }, &Ip { address: Addr::V6(Ipv6Addr::from_str("dead:beef::cafe").unwrap()), cidr: 48 }, ), false ); assert_eq!( within( &Ip { address: Addr::V6(Ipv6Addr::from_str("1::1").unwrap()), cidr: 48 }, &Ip { address: Addr::V6(Ipv6Addr::from_str("::f:f:f:f:f").unwrap()), cidr: 48 }, ), false ); } #[test] fn test_network_divide_iter() { let net = Ip { address: Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()), cidr: 24, }; let mut i = addresses(&net, None, Some(25)); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.128").unwrap()) ); assert_eq!(i.next(), None,); let mut i = addresses(&net, None, Some(26)); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.0").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.64").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.128").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V4(Ipv4Addr::from_str("192.168.0.192").unwrap()) ); assert_eq!(i.next(), None,); } #[test] fn test_network_divide_iter_v6() { let net = Ip { address: Addr::V6(Ipv6Addr::from_str("::1").unwrap()), cidr: 48, }; let mut i = addresses(&net, None, Some(64)); assert_eq!( i.next().as_ref().unwrap().address, Addr::V6(Ipv6Addr::from_str("::").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V6(Ipv6Addr::from_str("0:0:0:1::").unwrap()) ); assert_eq!( i.next().as_ref().unwrap().address, Addr::V6(Ipv6Addr::from_str("0:0:0:2::").unwrap()) ); let i = addresses(&net, None, Some(64)); let v: Vec = i.collect(); assert_eq!(v.len(), 65536); } }