1use alloc::vec::Vec;
2use core::cmp::{min, max};
3use core::cmp::Ordering::{Less, Equal};
4use core::convert::From;
5use core::fmt;
6use core::iter::FusedIterator;
7use core::option::Option::{Some, None};
8#[cfg(not(feature = "std"))]
9use core::error::Error;
10#[cfg(feature = "std")]
11use std::error::Error;
12#[cfg(not(feature = "std"))]
13use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
14#[cfg(feature = "std")]
15use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
16
17use crate::ipext::{IpAdd, IpSub, IpStep, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
18use crate::mask::{ip_mask_to_prefix, ipv4_mask_to_prefix, ipv6_mask_to_prefix};
19
20#[derive(#[automatically_derived]
impl ::core::marker::Copy for IpNet { }Copy, #[automatically_derived]
impl ::core::clone::Clone for IpNet {
#[inline]
fn clone(&self) -> IpNet {
let _: ::core::clone::AssertParamIsClone<Ipv4Net>;
let _: ::core::clone::AssertParamIsClone<Ipv6Net>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for IpNet {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ipv4Net>;
let _: ::core::cmp::AssertParamIsEq<Ipv6Net>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for IpNet {
#[inline]
fn eq(&self, other: &IpNet) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(IpNet::V4(__self_0), IpNet::V4(__arg1_0)) =>
__self_0 == __arg1_0,
(IpNet::V6(__self_0), IpNet::V6(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for IpNet {
#[inline]
fn cmp(&self, other: &IpNet) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
::core::cmp::Ordering::Equal =>
match (self, other) {
(IpNet::V4(__self_0), IpNet::V4(__arg1_0)) =>
::core::cmp::Ord::cmp(__self_0, __arg1_0),
(IpNet::V6(__self_0), IpNet::V6(__arg1_0)) =>
::core::cmp::Ord::cmp(__self_0, __arg1_0),
_ => unsafe { ::core::intrinsics::unreachable() }
},
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for IpNet {
#[inline]
fn partial_cmp(&self, other: &IpNet)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for IpNet {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
IpNet::V4(__self_0) => ::core::hash::Hash::hash(__self_0, state),
IpNet::V6(__self_0) => ::core::hash::Hash::hash(__self_0, state),
}
}
}Hash)]
51pub enum IpNet {
52 V4(Ipv4Net),
53 V6(Ipv6Net),
54}
55
56#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv4Net { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Ipv4Net {
#[inline]
fn clone(&self) -> Ipv4Net {
let _: ::core::clone::AssertParamIsClone<Ipv4Addr>;
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv4Net {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ipv4Addr>;
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for Ipv4Net {
#[inline]
fn eq(&self, other: &Ipv4Net) -> bool {
self.prefix_len == other.prefix_len && self.addr == other.addr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv4Net {
#[inline]
fn cmp(&self, other: &Ipv4Net) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.addr, &other.addr) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.prefix_len, &other.prefix_len),
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv4Net {
#[inline]
fn partial_cmp(&self, other: &Ipv4Net)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv4Net {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.addr, state);
::core::hash::Hash::hash(&self.prefix_len, state)
}
}Hash)]
84pub struct Ipv4Net {
85 addr: Ipv4Addr,
86 prefix_len: u8,
87}
88
89#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv6Net { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Ipv6Net {
#[inline]
fn clone(&self) -> Ipv6Net {
let _: ::core::clone::AssertParamIsClone<Ipv6Addr>;
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv6Net {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ipv6Addr>;
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for Ipv6Net {
#[inline]
fn eq(&self, other: &Ipv6Net) -> bool {
self.prefix_len == other.prefix_len && self.addr == other.addr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv6Net {
#[inline]
fn cmp(&self, other: &Ipv6Net) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.addr, &other.addr) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.prefix_len, &other.prefix_len),
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv6Net {
#[inline]
fn partial_cmp(&self, other: &Ipv6Net)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv6Net {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.addr, state);
::core::hash::Hash::hash(&self.prefix_len, state)
}
}Hash)]
114pub struct Ipv6Net {
115 addr: Ipv6Addr,
116 prefix_len: u8,
117}
118
119#[derive(#[automatically_derived]
impl ::core::fmt::Debug for PrefixLenError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "PrefixLenError")
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for PrefixLenError {
#[inline]
fn clone(&self) -> PrefixLenError { PrefixLenError }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PrefixLenError {
#[inline]
fn eq(&self, other: &PrefixLenError) -> bool { true }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PrefixLenError {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq)]
123pub struct PrefixLenError;
124
125impl fmt::Display for PrefixLenError {
126 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
127 fmt.write_str("invalid IP prefix length")
128 }
129}
130
131impl Error for PrefixLenError {}
132
133impl IpNet {
134 pub fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError> {
150 Ok(match ip {
151 IpAddr::V4(a) => Ipv4Net::new(a, prefix_len)?.into(),
152 IpAddr::V6(a) => Ipv6Net::new(a, prefix_len)?.into(),
153 })
154 }
155
156 pub const fn new_assert(ip: IpAddr, prefix_len: u8) -> IpNet {
182 match ip {
183 IpAddr::V4(a) => IpNet::V4(Ipv4Net::new_assert(a, prefix_len)),
184 IpAddr::V6(a) => IpNet::V6(Ipv6Net::new_assert(a, prefix_len)),
185 }
186 }
187
188 pub fn with_netmask(ip: IpAddr, netmask: IpAddr) -> Result<IpNet, PrefixLenError> {
203 let prefix = ip_mask_to_prefix(netmask)?;
204 Self::new(ip, prefix)
205 }
206
207 pub fn trunc(&self) -> IpNet {
226 match *self {
227 IpNet::V4(ref a) => IpNet::V4(a.trunc()),
228 IpNet::V6(ref a) => IpNet::V6(a.trunc()),
229 }
230 }
231
232 pub fn addr(&self) -> IpAddr {
234 match *self {
235 IpNet::V4(ref a) => IpAddr::V4(a.addr),
236 IpNet::V6(ref a) => IpAddr::V6(a.addr),
237 }
238 }
239
240 pub fn prefix_len(&self) -> u8 {
242 match *self {
243 IpNet::V4(ref a) => a.prefix_len(),
244 IpNet::V6(ref a) => a.prefix_len(),
245 }
246 }
247
248 pub fn max_prefix_len(&self) -> u8 {
250 match *self {
251 IpNet::V4(ref a) => a.max_prefix_len(),
252 IpNet::V6(ref a) => a.max_prefix_len(),
253 }
254 }
255
256 pub fn netmask(&self) -> IpAddr {
271 match *self {
272 IpNet::V4(ref a) => IpAddr::V4(a.netmask()),
273 IpNet::V6(ref a) => IpAddr::V6(a.netmask()),
274 }
275 }
276
277 pub fn hostmask(&self) -> IpAddr {
292 match *self {
293 IpNet::V4(ref a) => IpAddr::V4(a.hostmask()),
294 IpNet::V6(ref a) => IpAddr::V6(a.hostmask()),
295 }
296 }
297
298 pub fn network(&self) -> IpAddr {
313 match *self {
314 IpNet::V4(ref a) => IpAddr::V4(a.network()),
315 IpNet::V6(ref a) => IpAddr::V6(a.network()),
316 }
317 }
318
319 pub fn broadcast(&self) -> IpAddr {
334 match *self {
335 IpNet::V4(ref a) => IpAddr::V4(a.broadcast()),
336 IpNet::V6(ref a) => IpAddr::V6(a.broadcast()),
337 }
338 }
339
340 pub fn supernet(&self) -> Option<IpNet> {
362 match *self {
363 IpNet::V4(ref a) => a.supernet().map(IpNet::V4),
364 IpNet::V6(ref a) => a.supernet().map(IpNet::V6),
365 }
366 }
367
368 pub fn is_sibling(&self, other: &IpNet) -> bool {
390 match (*self, *other) {
391 (IpNet::V4(ref a), IpNet::V4(ref b)) => a.is_sibling(b),
392 (IpNet::V6(ref a), IpNet::V6(ref b)) => a.is_sibling(b),
393 _ => false,
394 }
395 }
396
397 pub fn hosts(&self) -> IpAddrRange {
426 match *self {
427 IpNet::V4(ref a) => IpAddrRange::V4(a.hosts()),
428 IpNet::V6(ref a) => IpAddrRange::V6(a.hosts()),
429 }
430 }
431
432 pub fn subnets(&self, new_prefix_len: u8) -> Result<IpSubnets, PrefixLenError> {
469 match *self {
470 IpNet::V4(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V4),
471 IpNet::V6(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V6),
472 }
473 }
474
475 pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
515 Contains::contains(self, other)
516 }
517
518 pub fn aggregate(networks: &Vec<IpNet>) -> Vec<IpNet> {
543 let mut ipv4nets: Vec<Ipv4Net> = Vec::new();
547 let mut ipv6nets: Vec<Ipv6Net> = Vec::new();
548
549 for n in networks {
550 match *n {
551 IpNet::V4(x) => ipv4nets.push(x),
552 IpNet::V6(x) => ipv6nets.push(x),
553 }
554 }
555
556 let mut res: Vec<IpNet> = Vec::new();
557 let ipv4aggs = Ipv4Net::aggregate(&ipv4nets);
558 let ipv6aggs = Ipv6Net::aggregate(&ipv6nets);
559 res.extend::<Vec<IpNet>>(ipv4aggs.into_iter().map(IpNet::V4).collect::<Vec<IpNet>>());
560 res.extend::<Vec<IpNet>>(ipv6aggs.into_iter().map(IpNet::V6).collect::<Vec<IpNet>>());
561 res
562 }
563}
564
565impl Default for IpNet {
566 fn default() -> Self {
567 Self::V4(Ipv4Net::default())
568 }
569}
570
571impl fmt::Debug for IpNet {
572 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
573 fmt::Display::fmt(self, fmt)
574 }
575}
576
577impl fmt::Display for IpNet {
578 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
579 match *self {
580 IpNet::V4(ref a) => a.fmt(fmt),
581 IpNet::V6(ref a) => a.fmt(fmt),
582 }
583 }
584}
585
586impl From<Ipv4Net> for IpNet {
587 fn from(net: Ipv4Net) -> IpNet {
588 IpNet::V4(net)
589 }
590}
591
592impl From<Ipv6Net> for IpNet {
593 fn from(net: Ipv6Net) -> IpNet {
594 IpNet::V6(net)
595 }
596}
597
598impl From<IpAddr> for IpNet {
599 fn from(addr: IpAddr) -> IpNet {
600 match addr {
601 IpAddr::V4(a) => IpNet::V4(a.into()),
602 IpAddr::V6(a) => IpNet::V6(a.into()),
603 }
604 }
605}
606
607impl Ipv4Net {
608 #[inline]
624 pub const fn new(ip: Ipv4Addr, prefix_len: u8) -> Result<Ipv4Net, PrefixLenError> {
625 if prefix_len > 32 {
626 return Err(PrefixLenError);
627 }
628 Ok(Ipv4Net { addr: ip, prefix_len: prefix_len })
629 }
630
631 #[inline]
657 pub const fn new_assert(ip: Ipv4Addr, prefix_len: u8) -> Ipv4Net {
658 if !(prefix_len <= 32) {
::core::panicking::panic("prefix_len must be less than or equal to 32 for Ipv4Net")
};assert!(prefix_len <= 32, "prefix_len must be less than or equal to 32 for Ipv4Net");
659 Ipv4Net { addr: ip, prefix_len: prefix_len }
660 }
661
662 pub fn with_netmask(ip: Ipv4Addr, netmask: Ipv4Addr) -> Result<Ipv4Net, PrefixLenError> {
677 let prefix = ipv4_mask_to_prefix(netmask)?;
678 Self::new(ip, prefix)
679 }
680
681 pub fn trunc(&self) -> Ipv4Net {
695 Ipv4Net::new(self.network(), self.prefix_len).unwrap()
696 }
697
698 #[inline]
700 pub const fn addr(&self) -> Ipv4Addr {
701 self.addr
702 }
703
704 #[inline]
706 pub const fn prefix_len(&self) -> u8 {
707 self.prefix_len
708 }
709
710 #[inline]
712 pub const fn max_prefix_len(&self) -> u8 {
713 32
714 }
715
716 pub fn netmask(&self) -> Ipv4Addr {
728 Ipv4Addr::from(self.netmask_u32())
729 }
730
731 fn netmask_u32(&self) -> u32 {
732 u32::max_value().checked_shl(32 - self.prefix_len as u32).unwrap_or(0)
733 }
734
735 pub fn hostmask(&self) -> Ipv4Addr {
747 Ipv4Addr::from(self.hostmask_u32())
748 }
749
750 fn hostmask_u32(&self) -> u32 {
751 u32::max_value().checked_shr(self.prefix_len as u32).unwrap_or(0)
752 }
753
754 pub fn network(&self) -> Ipv4Addr {
766 Ipv4Addr::from(u32::from(self.addr) & self.netmask_u32())
767 }
768
769 pub fn broadcast(&self) -> Ipv4Addr {
781 Ipv4Addr::from(u32::from(self.addr) | self.hostmask_u32())
782 }
783
784 pub fn supernet(&self) -> Option<Ipv4Net> {
799 Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
800 }
801
802 pub fn is_sibling(&self, other: &Ipv4Net) -> bool {
818 self.prefix_len > 0 &&
819 self.prefix_len == other.prefix_len &&
820 self.supernet().unwrap().contains(other)
821 }
822
823 pub fn hosts(&self) -> Ipv4AddrRange {
848 let mut start = self.network();
849 let mut end = self.broadcast();
850
851 if self.prefix_len < 31 {
852 start = start.saturating_add(1);
853 end = end.saturating_sub(1);
854 }
855
856 Ipv4AddrRange::new(start, end)
857 }
858
859 pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv4Subnets, PrefixLenError> {
890 if self.prefix_len > new_prefix_len || new_prefix_len > 32 {
891 return Err(PrefixLenError);
892 }
893
894 Ok(Ipv4Subnets::new(
895 self.network(),
896 self.broadcast(),
897 new_prefix_len,
898 ))
899 }
900
901 pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
923 Contains::contains(self, other)
924 }
925
926 fn interval(&self) -> (u32, u32) {
928 (
929 u32::from(self.network()),
930 u32::from(self.broadcast()).saturating_add(1),
931 )
932 }
933
934 pub fn aggregate(networks: &Vec<Ipv4Net>) -> Vec<Ipv4Net> {
953 let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
954 intervals = merge_intervals(intervals);
955 let mut res: Vec<Ipv4Net> = Vec::new();
956
957 for (start, mut end) in intervals {
958 if end != core::u32::MAX {
959 end = end.saturating_sub(1)
960 }
961 let iter = Ipv4Subnets::new(start.into(), end.into(), 0);
962 res.extend(iter);
963 }
964 res
965 }
966}
967
968impl Default for Ipv4Net {
969 fn default() -> Self {
970 Self {
971 addr: Ipv4Addr::from(0),
972 prefix_len: 0,
973 }
974 }
975}
976
977impl fmt::Debug for Ipv4Net {
978 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
979 fmt::Display::fmt(self, fmt)
980 }
981}
982
983impl fmt::Display for Ipv4Net {
984 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
985 fmt.write_fmt(format_args!("{0}/{1}", self.addr, self.prefix_len))write!(fmt, "{}/{}", self.addr, self.prefix_len)
986 }
987}
988
989impl From<Ipv4Addr> for Ipv4Net {
990 fn from(addr: Ipv4Addr) -> Ipv4Net {
991 Ipv4Net { addr, prefix_len: 32 }
992 }
993}
994
995impl Ipv6Net {
996 #[inline]
1012 pub const fn new(ip: Ipv6Addr, prefix_len: u8) -> Result<Ipv6Net, PrefixLenError> {
1013 if prefix_len > 128 {
1014 return Err(PrefixLenError);
1015 }
1016 Ok(Ipv6Net { addr: ip, prefix_len: prefix_len })
1017 }
1018
1019 #[inline]
1045 pub const fn new_assert(ip: Ipv6Addr, prefix_len: u8) -> Ipv6Net {
1046 if !(prefix_len <= 128) {
::core::panicking::panic("prefix_len must be less than or equal to 128 for Ipv6Net")
};assert!(prefix_len <= 128, "prefix_len must be less than or equal to 128 for Ipv6Net");
1047 Ipv6Net { addr: ip, prefix_len: prefix_len }
1048 }
1049
1050 pub fn with_netmask(ip: Ipv6Addr, netmask: Ipv6Addr) -> Result<Ipv6Net, PrefixLenError> {
1065 let prefix = ipv6_mask_to_prefix(netmask)?;
1066 Self::new(ip, prefix)
1067 }
1068
1069 pub fn trunc(&self) -> Ipv6Net {
1083 Ipv6Net::new(self.network(), self.prefix_len).unwrap()
1084 }
1085
1086 #[inline]
1088 pub const fn addr(&self) -> Ipv6Addr {
1089 self.addr
1090 }
1091
1092 #[inline]
1094 pub const fn prefix_len(&self) -> u8 {
1095 self.prefix_len
1096 }
1097
1098 #[inline]
1100 pub const fn max_prefix_len(&self) -> u8 {
1101 128
1102 }
1103
1104 pub fn netmask(&self) -> Ipv6Addr {
1116 self.netmask_u128().into()
1117 }
1118
1119 fn netmask_u128(&self) -> u128 {
1120 u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value())
1121 }
1122
1123 pub fn hostmask(&self) -> Ipv6Addr {
1135 self.hostmask_u128().into()
1136 }
1137
1138 fn hostmask_u128(&self) -> u128 {
1139 u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value())
1140 }
1141
1142 pub fn network(&self) -> Ipv6Addr {
1154 (u128::from(self.addr) & self.netmask_u128()).into()
1155 }
1156
1157 pub fn broadcast(&self) -> Ipv6Addr {
1172 (u128::from(self.addr) | self.hostmask_u128()).into()
1173 }
1174
1175 pub fn supernet(&self) -> Option<Ipv6Net> {
1191 Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
1192 }
1193
1194 pub fn is_sibling(&self, other: &Ipv6Net) -> bool {
1210 self.prefix_len > 0 &&
1211 self.prefix_len == other.prefix_len &&
1212 self.supernet().unwrap().contains(other)
1213 }
1214
1215 pub fn hosts(&self) -> Ipv6AddrRange {
1232 Ipv6AddrRange::new(self.network(), self.broadcast())
1233 }
1234
1235 pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv6Subnets, PrefixLenError> {
1266 if self.prefix_len > new_prefix_len || new_prefix_len > 128 {
1267 return Err(PrefixLenError);
1268 }
1269
1270 Ok(Ipv6Subnets::new(
1271 self.network(),
1272 self.broadcast(),
1273 new_prefix_len,
1274 ))
1275 }
1276
1277 pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
1299 Contains::contains(self, other)
1300 }
1301
1302 fn interval(&self) -> (u128, u128) {
1304 (
1305 u128::from(self.network()),
1306 u128::from(self.broadcast()).saturating_add(1),
1307 )
1308 }
1309
1310 pub fn aggregate(networks: &Vec<Ipv6Net>) -> Vec<Ipv6Net> {
1329 let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
1330 intervals = merge_intervals(intervals);
1331 let mut res: Vec<Ipv6Net> = Vec::new();
1332
1333 for (start, mut end) in intervals {
1334 if end != core::u128::MAX {
1335 end = end.saturating_sub(1)
1336 }
1337 let iter = Ipv6Subnets::new(start.into(), end.into(), 0);
1338 res.extend(iter);
1339 }
1340 res
1341 }
1342}
1343
1344impl Default for Ipv6Net {
1345 fn default() -> Self {
1346 Self {
1347 addr: Ipv6Addr::from(0),
1348 prefix_len: 0,
1349 }
1350 }
1351}
1352
1353impl fmt::Debug for Ipv6Net {
1354 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1355 fmt::Display::fmt(self, fmt)
1356 }
1357}
1358
1359impl fmt::Display for Ipv6Net {
1360 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1361 fmt.write_fmt(format_args!("{0}/{1}", self.addr, self.prefix_len))write!(fmt, "{}/{}", self.addr, self.prefix_len)
1362 }
1363}
1364
1365impl From<Ipv6Addr> for Ipv6Net {
1366 fn from(addr: Ipv6Addr) -> Ipv6Net {
1367 Ipv6Net { addr, prefix_len: 128 }
1368 }
1369}
1370
1371pub trait Contains<T> {
1406 fn contains(&self, other: T) -> bool;
1407}
1408
1409impl<'a> Contains<&'a IpNet> for IpNet {
1410 fn contains(&self, other: &IpNet) -> bool {
1411 match (*self, *other) {
1412 (IpNet::V4(ref a), IpNet::V4(ref b)) => a.contains(b),
1413 (IpNet::V6(ref a), IpNet::V6(ref b)) => a.contains(b),
1414 _ => false,
1415 }
1416 }
1417}
1418
1419impl<'a> Contains<&'a IpAddr> for IpNet {
1420 fn contains(&self, other: &IpAddr) -> bool {
1421 match (*self, *other) {
1422 (IpNet::V4(ref a), IpAddr::V4(ref b)) => a.contains(b),
1423 (IpNet::V6(ref a), IpAddr::V6(ref b)) => a.contains(b),
1424 _ => false,
1425 }
1426 }
1427}
1428
1429impl<'a> Contains<&'a Ipv4Net> for Ipv4Net {
1430 fn contains(&self, other: &'a Ipv4Net) -> bool {
1431 self.network() <= other.network() && other.broadcast() <= self.broadcast()
1432 }
1433}
1434
1435impl<'a> Contains<&'a Ipv4Addr> for Ipv4Net {
1436 fn contains(&self, other: &'a Ipv4Addr) -> bool {
1437 self.network() <= *other && *other <= self.broadcast()
1438 }
1439}
1440
1441impl<'a> Contains<&'a Ipv6Net> for Ipv6Net {
1442 fn contains(&self, other: &'a Ipv6Net) -> bool {
1443 self.network() <= other.network() && other.broadcast() <= self.broadcast()
1444 }
1445}
1446
1447impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net {
1448 fn contains(&self, other: &'a Ipv6Addr) -> bool {
1449 self.network() <= *other && *other <= self.broadcast()
1450 }
1451}
1452
1453#[derive(#[automatically_derived]
impl ::core::marker::Copy for IpSubnets { }Copy, #[automatically_derived]
impl ::core::clone::Clone for IpSubnets {
#[inline]
fn clone(&self) -> IpSubnets {
let _: ::core::clone::AssertParamIsClone<Ipv4Subnets>;
let _: ::core::clone::AssertParamIsClone<Ipv6Subnets>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for IpSubnets {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ipv4Subnets>;
let _: ::core::cmp::AssertParamIsEq<Ipv6Subnets>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for IpSubnets {
#[inline]
fn eq(&self, other: &IpSubnets) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(IpSubnets::V4(__self_0), IpSubnets::V4(__arg1_0)) =>
__self_0 == __arg1_0,
(IpSubnets::V6(__self_0), IpSubnets::V6(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for IpSubnets {
#[inline]
fn cmp(&self, other: &IpSubnets) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
::core::cmp::Ordering::Equal =>
match (self, other) {
(IpSubnets::V4(__self_0), IpSubnets::V4(__arg1_0)) =>
::core::cmp::Ord::cmp(__self_0, __arg1_0),
(IpSubnets::V6(__self_0), IpSubnets::V6(__arg1_0)) =>
::core::cmp::Ord::cmp(__self_0, __arg1_0),
_ => unsafe { ::core::intrinsics::unreachable() }
},
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for IpSubnets {
#[inline]
fn partial_cmp(&self, other: &IpSubnets)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for IpSubnets {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
IpSubnets::V4(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
IpSubnets::V6(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for IpSubnets {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
IpSubnets::V4(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "V4",
&__self_0),
IpSubnets::V6(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "V6",
&__self_0),
}
}
}Debug)]
1496pub enum IpSubnets {
1497 V4(Ipv4Subnets),
1498 V6(Ipv6Subnets),
1499}
1500
1501#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv4Subnets { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Ipv4Subnets {
#[inline]
fn clone(&self) -> Ipv4Subnets {
let _: ::core::clone::AssertParamIsClone<Ipv4Addr>;
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv4Subnets {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ipv4Addr>;
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for Ipv4Subnets {
#[inline]
fn eq(&self, other: &Ipv4Subnets) -> bool {
self.min_prefix_len == other.min_prefix_len &&
self.start == other.start && self.end == other.end
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv4Subnets {
#[inline]
fn cmp(&self, other: &Ipv4Subnets) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.start, &other.start) {
::core::cmp::Ordering::Equal =>
match ::core::cmp::Ord::cmp(&self.end, &other.end) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.min_prefix_len,
&other.min_prefix_len),
cmp => cmp,
},
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv4Subnets {
#[inline]
fn partial_cmp(&self, other: &Ipv4Subnets)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv4Subnets {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.start, state);
::core::hash::Hash::hash(&self.end, state);
::core::hash::Hash::hash(&self.min_prefix_len, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Ipv4Subnets {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "Ipv4Subnets",
"start", &self.start, "end", &self.end, "min_prefix_len",
&&self.min_prefix_len)
}
}Debug)]
1529pub struct Ipv4Subnets {
1530 start: Ipv4Addr,
1531 end: Ipv4Addr, min_prefix_len: u8,
1533}
1534
1535#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv6Subnets { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Ipv6Subnets {
#[inline]
fn clone(&self) -> Ipv6Subnets {
let _: ::core::clone::AssertParamIsClone<Ipv6Addr>;
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv6Subnets {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ipv6Addr>;
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for Ipv6Subnets {
#[inline]
fn eq(&self, other: &Ipv6Subnets) -> bool {
self.min_prefix_len == other.min_prefix_len &&
self.start == other.start && self.end == other.end
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv6Subnets {
#[inline]
fn cmp(&self, other: &Ipv6Subnets) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.start, &other.start) {
::core::cmp::Ordering::Equal =>
match ::core::cmp::Ord::cmp(&self.end, &other.end) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.min_prefix_len,
&other.min_prefix_len),
cmp => cmp,
},
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv6Subnets {
#[inline]
fn partial_cmp(&self, other: &Ipv6Subnets)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv6Subnets {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.start, state);
::core::hash::Hash::hash(&self.end, state);
::core::hash::Hash::hash(&self.min_prefix_len, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Ipv6Subnets {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "Ipv6Subnets",
"start", &self.start, "end", &self.end, "min_prefix_len",
&&self.min_prefix_len)
}
}Debug)]
1563pub struct Ipv6Subnets {
1564 start: Ipv6Addr,
1565 end: Ipv6Addr, min_prefix_len: u8,
1567}
1568
1569impl Ipv4Subnets {
1570 pub fn new(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Self {
1571 Ipv4Subnets {
1572 start: start,
1573 end: end,
1574 min_prefix_len: min_prefix_len,
1575 }
1576 }
1577}
1578
1579impl Ipv6Subnets {
1580 pub fn new(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Self {
1581 Ipv6Subnets {
1582 start: start,
1583 end: end,
1584 min_prefix_len: min_prefix_len,
1585 }
1586 }
1587}
1588
1589impl From<Ipv4Subnets> for IpSubnets {
1590 fn from(i: Ipv4Subnets) -> IpSubnets {
1591 IpSubnets::V4(i)
1592 }
1593}
1594
1595impl From<Ipv6Subnets> for IpSubnets {
1596 fn from(i: Ipv6Subnets) -> IpSubnets {
1597 IpSubnets::V6(i)
1598 }
1599}
1600
1601impl Iterator for IpSubnets {
1602 type Item = IpNet;
1603
1604 fn next(&mut self) -> Option<Self::Item> {
1605 match *self {
1606 IpSubnets::V4(ref mut a) => a.next().map(IpNet::V4),
1607 IpSubnets::V6(ref mut a) => a.next().map(IpNet::V6),
1608 }
1609 }
1610}
1611
1612fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
1613 let range = u32::from(end) - u32::from(start);
1614 let range_lz = range.leading_zeros();
1615 let range_pl = if range_lz + range.trailing_ones() == u32::BITS { range_lz } else { range_lz + 1 };
1616 let start_pl = 32 - u32::from(start).trailing_zeros();
1617 let new_prefix_len = max(max(range_pl as u8, start_pl as u8), min_prefix_len);
1618 Ipv4Net::new(start, new_prefix_len).unwrap()
1619}
1620
1621fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
1622 let range = u128::from(end) - u128::from(start);
1623 let range_lz = range.leading_zeros();
1624 let range_pl = if range_lz + range.trailing_ones() == u128::BITS { range_lz } else { range_lz + 1 };
1625 let start_pl = 128 - u128::from(start).trailing_zeros();
1626 let new_prefix_len = max(max(range_pl as u8, start_pl as u8), min_prefix_len);
1627 Ipv6Net::new(start, new_prefix_len).unwrap()
1628}
1629
1630impl Iterator for Ipv4Subnets {
1631 type Item = Ipv4Net;
1632
1633 fn next(&mut self) -> Option<Self::Item> {
1634 match self.start.partial_cmp(&self.end) {
1635 Some(Less) => {
1636 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1637 self.start = next.broadcast().saturating_add(1);
1638
1639 if self.start == next.broadcast() {
1641 self.end.replace_zero();
1642 }
1643 Some(next)
1644 },
1645 Some(Equal) => {
1646 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1647 self.start = next.broadcast().saturating_add(1);
1648 self.end.replace_zero();
1649 Some(next)
1650 },
1651 _ => None,
1652 }
1653 }
1654}
1655
1656impl Iterator for Ipv6Subnets {
1657 type Item = Ipv6Net;
1658
1659 fn next(&mut self) -> Option<Self::Item> {
1660 match self.start.partial_cmp(&self.end) {
1661 Some(Less) => {
1662 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1663 self.start = next.broadcast().saturating_add(1);
1664
1665 if self.start == next.broadcast() {
1667 self.end.replace_zero();
1668 }
1669 Some(next)
1670 },
1671 Some(Equal) => {
1672 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1673 self.start = next.broadcast().saturating_add(1);
1674 self.end.replace_zero();
1675 Some(next)
1676 },
1677 _ => None,
1678 }
1679 }
1680}
1681
1682impl FusedIterator for IpSubnets {}
1683impl FusedIterator for Ipv4Subnets {}
1684impl FusedIterator for Ipv6Subnets {}
1685
1686fn merge_intervals<T: Copy + Ord>(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> {
1688 if intervals.len() == 0 {
1689 return intervals;
1690 }
1691
1692 intervals.sort();
1693 let mut res: Vec<(T, T)> = Vec::new();
1694 let (mut start, mut end) = intervals[0];
1695
1696 let mut i = 1;
1697 let len = intervals.len();
1698 while i < len {
1699 let (next_start, next_end) = intervals[i];
1700 if end >= next_start {
1701 start = min(start, next_start);
1702 end = max(end, next_end);
1703 }
1704 else {
1705 res.push((start, end));
1706 start = next_start;
1707 end = next_end;
1708 }
1709 i += 1;
1710 }
1711
1712 res.push((start, end));
1713 res
1714}
1715
1716#[cfg(test)]
1717mod tests {
1718 use super::*;
1719
1720 macro_rules! make_ipnet_vec {
1721 ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
1722 ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
1723 }
1724
1725 #[test]
1726 fn test_make_ipnet_vec() {
1727 assert_eq!(
1728 make_ipnet_vec![
1729 "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
1730 "fd00::1/128", "fd00::2/127", "fd00::3/126",
1731 ],
1732 vec![
1733 "10.1.1.1/32".parse().unwrap(),
1734 "10.2.2.2/24".parse().unwrap(),
1735 "10.3.3.3/16".parse().unwrap(),
1736 "fd00::1/128".parse().unwrap(),
1737 "fd00::2/127".parse().unwrap(),
1738 "fd00::3/126".parse().unwrap(),
1739 ]
1740 );
1741 }
1742
1743 #[test]
1744 fn test_merge_intervals() {
1745 let v = vec![
1746 (0, 1), (1, 2), (2, 3),
1747 (11, 12), (13, 14), (10, 15), (11, 13),
1748 (20, 25), (24, 29),
1749 ];
1750
1751 let v_ok = vec![
1752 (0, 3),
1753 (10, 15),
1754 (20, 29),
1755 ];
1756
1757 let vv = vec![
1758 ([0, 1], [0, 2]), ([0, 2], [0, 3]), ([0, 0], [0, 1]),
1759 ([10, 15], [11, 0]), ([10, 0], [10, 16]),
1760 ];
1761
1762 let vv_ok = vec![
1763 ([0, 0], [0, 3]),
1764 ([10, 0], [11, 0]),
1765 ];
1766
1767 assert_eq!(merge_intervals(v), v_ok);
1768 assert_eq!(merge_intervals(vv), vv_ok);
1769 }
1770
1771 macro_rules! make_ipv4_subnets_test {
1772 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1773 #[test]
1774 fn $name() {
1775 let subnets = IpSubnets::from(Ipv4Subnets::new(
1776 $start.parse().unwrap(),
1777 $end.parse().unwrap(),
1778 $min_prefix_len,
1779 ));
1780 let results = make_ipnet_vec![$($x),*];
1781 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1782 }
1783 );
1784 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1785 make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1786 );
1787 }
1788
1789 macro_rules! make_ipv6_subnets_test {
1790 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1791 #[test]
1792 fn $name() {
1793 let subnets = IpSubnets::from(Ipv6Subnets::new(
1794 $start.parse().unwrap(),
1795 $end.parse().unwrap(),
1796 $min_prefix_len,
1797 ));
1798 let results = make_ipnet_vec![$($x),*];
1799 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1800 }
1801 );
1802 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1803 make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1804 );
1805 }
1806
1807 make_ipv4_subnets_test!(
1808 test_ipv4_subnets_zero_zero,
1809 "0.0.0.0", "0.0.0.0", 0,
1810 "0.0.0.0/32",
1811 );
1812
1813 make_ipv4_subnets_test!(
1814 test_ipv4_subnets_zero_max,
1815 "0.0.0.0", "255.255.255.255", 0,
1816 "0.0.0.0/0",
1817 );
1818
1819 make_ipv4_subnets_test!(
1820 test_ipv4_subnets_max_max,
1821 "255.255.255.255", "255.255.255.255", 0,
1822 "255.255.255.255/32",
1823 );
1824
1825 make_ipv4_subnets_test!(
1826 test_ipv4_subnets_none,
1827 "0.0.0.1", "0.0.0.0", 0,
1828 );
1829
1830 make_ipv4_subnets_test!(
1831 test_ipv4_subnets_one,
1832 "0.0.0.0", "0.0.0.1", 0,
1833 "0.0.0.0/31",
1834 );
1835
1836 make_ipv4_subnets_test!(
1837 test_ipv4_subnets_two,
1838 "0.0.0.0", "0.0.0.2", 0,
1839 "0.0.0.0/31",
1840 "0.0.0.2/32",
1841 );
1842
1843 make_ipv4_subnets_test!(
1844 test_ipv4_subnets_taper,
1845 "0.0.0.0", "0.0.0.10", 30,
1846 "0.0.0.0/30",
1847 "0.0.0.4/30",
1848 "0.0.0.8/31",
1849 "0.0.0.10/32",
1850 );
1851
1852 make_ipv6_subnets_test!(
1853 test_ipv6_subnets_zero_zero,
1854 "::", "::", 0,
1855 "::/128",
1856 );
1857
1858 make_ipv6_subnets_test!(
1859 test_ipv6_subnets_zero_max,
1860 "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1861 "::/0",
1862 );
1863
1864 make_ipv6_subnets_test!(
1865 test_ipv6_subnets_max_max,
1866 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1867 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
1868 );
1869
1870 make_ipv6_subnets_test!(
1871 test_ipv6_subnets_none,
1872 "::1", "::", 0,
1873 );
1874
1875 make_ipv6_subnets_test!(
1876 test_ipv6_subnets_one,
1877 "::", "::1", 0,
1878 "::/127",
1879 );
1880
1881 make_ipv6_subnets_test!(
1882 test_ipv6_subnets_two,
1883 "::", "::2", 0,
1884 "::/127",
1885 "::2/128",
1886 );
1887
1888 make_ipv6_subnets_test!(
1889 test_ipv6_subnets_taper,
1890 "::", "::a", 126,
1891 "::/126",
1892 "::4/126",
1893 "::8/127",
1894 "::a/128",
1895 );
1896
1897 #[test]
1899 fn test_ipv4_subnets_zero_max_minus_one() {
1900 let subnets: Vec<Ipv4Net> = Ipv4Subnets::new(Ipv4Addr::from(0u32), Ipv4Addr::from(u32::MAX-1), 0).collect();
1901 assert!(!subnets[0].contains(&Ipv4Addr::from(u32::MAX)));
1902 }
1903
1904 #[test]
1906 fn test_ipv6_subnets_zero_max_minus_one() {
1907 let subnets: Vec<Ipv6Net> = Ipv6Subnets::new(Ipv6Addr::from(0u128), Ipv6Addr::from(u128::MAX-1), 0).collect();
1908 assert!(!subnets[0].contains(&Ipv6Addr::from(u128::MAX)));
1909 }
1910
1911 #[test]
1912 fn test_aggregate() {
1913 let ip_nets = make_ipnet_vec![
1914 "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
1915 "10.0.2.0/24",
1916 "10.1.0.0/24", "10.1.1.0/24",
1917 "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
1918 "fd00::/32", "fd00:1::/32",
1919 "fd00:2::/32",
1920 ];
1921
1922 let ip_aggs = make_ipnet_vec![
1923 "10.0.0.0/23",
1924 "10.0.2.0/24",
1925 "10.1.0.0/23",
1926 "192.168.0.0/22",
1927 "fd00::/31",
1928 "fd00:2::/32",
1929 ];
1930
1931 let ipv4_nets: Vec<Ipv4Net> = ip_nets.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1932 let ipv4_aggs: Vec<Ipv4Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1933 let ipv6_nets: Vec<Ipv6Net> = ip_nets.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1934 let ipv6_aggs: Vec<Ipv6Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1935
1936 assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
1937 assert_eq!(Ipv4Net::aggregate(&ipv4_nets), ipv4_aggs);
1938 assert_eq!(Ipv6Net::aggregate(&ipv6_nets), ipv6_aggs);
1939 }
1940
1941 #[test]
1942 fn test_aggregate_issue44() {
1943 let nets: Vec<Ipv4Net> = vec!["128.0.0.0/1".parse().unwrap()];
1944 assert_eq!(Ipv4Net::aggregate(&nets), nets);
1945
1946 let nets: Vec<Ipv4Net> = vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()];
1947 assert_eq!(Ipv4Net::aggregate(&nets), vec!["0.0.0.0/0".parse().unwrap()]);
1948
1949 let nets: Vec<Ipv6Net> = vec!["8000::/1".parse().unwrap()];
1950 assert_eq!(Ipv6Net::aggregate(&nets), nets);
1951
1952 let nets: Vec<Ipv6Net> = vec!["::/1".parse().unwrap(), "8000::/1".parse().unwrap()];
1953 assert_eq!(Ipv6Net::aggregate(&nets), vec!["::/0".parse().unwrap()]);
1954 }
1955
1956 #[test]
1957 fn ipnet_default() {
1958 let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
1959 assert_eq!(ipnet, IpNet::default());
1960 }
1961
1962 #[test]
1963 fn ipv4net_default() {
1964 let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
1965 assert_eq!(ipnet, Ipv4Net::default());
1966 }
1967
1968 #[test]
1969 fn ipv6net_default() {
1970 let ipnet: Ipv6Net = "::/0".parse().unwrap();
1971 assert_eq!(ipnet, Ipv6Net::default());
1972 }
1973
1974 #[test]
1975 fn new_assert() {
1976 const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1977 const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1978 const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1979 const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1980
1981 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1982 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1983 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1984 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1985 }
1986
1987 #[test]
1988 #[should_panic]
1989 fn ipv4net_new_assert_panics() {
1990 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 33);
1991 }
1992
1993 #[test]
1994 #[should_panic]
1995 fn ipv6net_new_assert_panics() {
1996 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 129);
1997 }
1998}