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_receiver_is_total_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> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match (self, other) {
(IpNet::V4(__self_0), IpNet::V4(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
(IpNet::V6(__self_0), IpNet::V6(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
_ =>
::core::cmp::PartialOrd::partial_cmp(&__self_discr,
&__arg1_discr),
}
}
}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_receiver_is_total_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> {
match ::core::cmp::PartialOrd::partial_cmp(&self.addr, &other.addr) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
::core::cmp::PartialOrd::partial_cmp(&self.prefix_len,
&other.prefix_len),
cmp => cmp,
}
}
}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_receiver_is_total_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> {
match ::core::cmp::PartialOrd::partial_cmp(&self.addr, &other.addr) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
::core::cmp::PartialOrd::partial_cmp(&self.prefix_len,
&other.prefix_len),
cmp => cmp,
}
}
}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_receiver_is_total_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 then or equal to 32 for Ipv4Net")
};assert!(prefix_len <= 32, "PREFIX_LEN must be less then 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 then or equal to 128 for Ipv6Net")
};assert!(prefix_len <= 128, "PREFIX_LEN must be less then 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_receiver_is_total_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> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match (self, other) {
(IpSubnets::V4(__self_0), IpSubnets::V4(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
(IpSubnets::V6(__self_0), IpSubnets::V6(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
_ =>
::core::cmp::PartialOrd::partial_cmp(&__self_discr,
&__arg1_discr),
}
}
}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_receiver_is_total_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> {
match ::core::cmp::PartialOrd::partial_cmp(&self.start, &other.start)
{
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
match ::core::cmp::PartialOrd::partial_cmp(&self.end,
&other.end) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
::core::cmp::PartialOrd::partial_cmp(&self.min_prefix_len,
&other.min_prefix_len),
cmp => cmp,
},
cmp => cmp,
}
}
}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_receiver_is_total_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> {
match ::core::cmp::PartialOrd::partial_cmp(&self.start, &other.start)
{
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
match ::core::cmp::PartialOrd::partial_cmp(&self.end,
&other.end) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
::core::cmp::PartialOrd::partial_cmp(&self.min_prefix_len,
&other.min_prefix_len),
cmp => cmp,
},
cmp => cmp,
}
}
}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 = end.saturating_sub(start).saturating_add(1);
1614 if range == core::u32::MAX && min_prefix_len == 0 {
1615 Ipv4Net::new(start, min_prefix_len).unwrap()
1616 }
1617 else {
1618 let range_bits = 32u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1619 let start_tz = u32::from(start).trailing_zeros();
1620 let new_prefix_len = 32 - min(range_bits, start_tz);
1621 let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
1622 Ipv4Net::new(start, next_prefix_len).unwrap()
1623 }
1624}
1625
1626fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
1627 let range = end.saturating_sub(start).saturating_add(1);
1628 if range == core::u128::MAX && min_prefix_len == 0 {
1629 Ipv6Net::new(start, min_prefix_len).unwrap()
1630 }
1631 else {
1632 let range = end.saturating_sub(start).saturating_add(1);
1633 let range_bits = 128u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1634 let start_tz = u128::from(start).trailing_zeros();
1635 let new_prefix_len = 128 - min(range_bits, start_tz);
1636 let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
1637 Ipv6Net::new(start, next_prefix_len).unwrap()
1638 }
1639}
1640
1641impl Iterator for Ipv4Subnets {
1642 type Item = Ipv4Net;
1643
1644 fn next(&mut self) -> Option<Self::Item> {
1645 match self.start.partial_cmp(&self.end) {
1646 Some(Less) => {
1647 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1648 self.start = next.broadcast().saturating_add(1);
1649
1650 if self.start == next.broadcast() {
1655 self.end.replace_zero();
1656 }
1657 Some(next)
1658 },
1659 Some(Equal) => {
1660 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1661 self.start = next.broadcast().saturating_add(1);
1662 self.end.replace_zero();
1663 Some(next)
1664 },
1665 _ => None,
1666 }
1667 }
1668}
1669
1670impl Iterator for Ipv6Subnets {
1671 type Item = Ipv6Net;
1672
1673 fn next(&mut self) -> Option<Self::Item> {
1674 match self.start.partial_cmp(&self.end) {
1675 Some(Less) => {
1676 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1677 self.start = next.broadcast().saturating_add(1);
1678
1679 if self.start == next.broadcast() {
1684 self.end.replace_zero();
1685 }
1686 Some(next)
1687 },
1688 Some(Equal) => {
1689 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1690 self.start = next.broadcast().saturating_add(1);
1691 self.end.replace_zero();
1692 Some(next)
1693 },
1694 _ => None,
1695 }
1696 }
1697}
1698
1699impl FusedIterator for IpSubnets {}
1700impl FusedIterator for Ipv4Subnets {}
1701impl FusedIterator for Ipv6Subnets {}
1702
1703fn merge_intervals<T: Copy + Ord>(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> {
1705 if intervals.len() == 0 {
1706 return intervals;
1707 }
1708
1709 intervals.sort();
1710 let mut res: Vec<(T, T)> = Vec::new();
1711 let (mut start, mut end) = intervals[0];
1712
1713 let mut i = 1;
1714 let len = intervals.len();
1715 while i < len {
1716 let (next_start, next_end) = intervals[i];
1717 if end >= next_start {
1718 start = min(start, next_start);
1719 end = max(end, next_end);
1720 }
1721 else {
1722 res.push((start, end));
1723 start = next_start;
1724 end = next_end;
1725 }
1726 i += 1;
1727 }
1728
1729 res.push((start, end));
1730 res
1731}
1732
1733#[cfg(test)]
1734mod tests {
1735 use super::*;
1736
1737 macro_rules! make_ipnet_vec {
1738 ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
1739 ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
1740 }
1741
1742 #[test]
1743 fn test_make_ipnet_vec() {
1744 assert_eq!(
1745 make_ipnet_vec![
1746 "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
1747 "fd00::1/128", "fd00::2/127", "fd00::3/126",
1748 ],
1749 vec![
1750 "10.1.1.1/32".parse().unwrap(),
1751 "10.2.2.2/24".parse().unwrap(),
1752 "10.3.3.3/16".parse().unwrap(),
1753 "fd00::1/128".parse().unwrap(),
1754 "fd00::2/127".parse().unwrap(),
1755 "fd00::3/126".parse().unwrap(),
1756 ]
1757 );
1758 }
1759
1760 #[test]
1761 fn test_merge_intervals() {
1762 let v = vec![
1763 (0, 1), (1, 2), (2, 3),
1764 (11, 12), (13, 14), (10, 15), (11, 13),
1765 (20, 25), (24, 29),
1766 ];
1767
1768 let v_ok = vec![
1769 (0, 3),
1770 (10, 15),
1771 (20, 29),
1772 ];
1773
1774 let vv = vec![
1775 ([0, 1], [0, 2]), ([0, 2], [0, 3]), ([0, 0], [0, 1]),
1776 ([10, 15], [11, 0]), ([10, 0], [10, 16]),
1777 ];
1778
1779 let vv_ok = vec![
1780 ([0, 0], [0, 3]),
1781 ([10, 0], [11, 0]),
1782 ];
1783
1784 assert_eq!(merge_intervals(v), v_ok);
1785 assert_eq!(merge_intervals(vv), vv_ok);
1786 }
1787
1788 macro_rules! make_ipv4_subnets_test {
1789 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1790 #[test]
1791 fn $name() {
1792 let subnets = IpSubnets::from(Ipv4Subnets::new(
1793 $start.parse().unwrap(),
1794 $end.parse().unwrap(),
1795 $min_prefix_len,
1796 ));
1797 let results = make_ipnet_vec![$($x),*];
1798 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1799 }
1800 );
1801 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1802 make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1803 );
1804 }
1805
1806 macro_rules! make_ipv6_subnets_test {
1807 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1808 #[test]
1809 fn $name() {
1810 let subnets = IpSubnets::from(Ipv6Subnets::new(
1811 $start.parse().unwrap(),
1812 $end.parse().unwrap(),
1813 $min_prefix_len,
1814 ));
1815 let results = make_ipnet_vec![$($x),*];
1816 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1817 }
1818 );
1819 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1820 make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1821 );
1822 }
1823
1824 make_ipv4_subnets_test!(
1825 test_ipv4_subnets_zero_zero,
1826 "0.0.0.0", "0.0.0.0", 0,
1827 "0.0.0.0/32",
1828 );
1829
1830 make_ipv4_subnets_test!(
1831 test_ipv4_subnets_zero_max,
1832 "0.0.0.0", "255.255.255.255", 0,
1833 "0.0.0.0/0",
1834 );
1835
1836 make_ipv4_subnets_test!(
1837 test_ipv4_subnets_max_max,
1838 "255.255.255.255", "255.255.255.255", 0,
1839 "255.255.255.255/32",
1840 );
1841
1842 make_ipv4_subnets_test!(
1843 test_ipv4_subnets_none,
1844 "0.0.0.1", "0.0.0.0", 0,
1845 );
1846
1847 make_ipv4_subnets_test!(
1848 test_ipv4_subnets_one,
1849 "0.0.0.0", "0.0.0.1", 0,
1850 "0.0.0.0/31",
1851 );
1852
1853 make_ipv4_subnets_test!(
1854 test_ipv4_subnets_two,
1855 "0.0.0.0", "0.0.0.2", 0,
1856 "0.0.0.0/31",
1857 "0.0.0.2/32",
1858 );
1859
1860 make_ipv4_subnets_test!(
1861 test_ipv4_subnets_taper,
1862 "0.0.0.0", "0.0.0.10", 30,
1863 "0.0.0.0/30",
1864 "0.0.0.4/30",
1865 "0.0.0.8/31",
1866 "0.0.0.10/32",
1867 );
1868
1869 make_ipv6_subnets_test!(
1870 test_ipv6_subnets_zero_zero,
1871 "::", "::", 0,
1872 "::/128",
1873 );
1874
1875 make_ipv6_subnets_test!(
1876 test_ipv6_subnets_zero_max,
1877 "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1878 "::/0",
1879 );
1880
1881 make_ipv6_subnets_test!(
1882 test_ipv6_subnets_max_max,
1883 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1884 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
1885 );
1886
1887 make_ipv6_subnets_test!(
1888 test_ipv6_subnets_none,
1889 "::1", "::", 0,
1890 );
1891
1892 make_ipv6_subnets_test!(
1893 test_ipv6_subnets_one,
1894 "::", "::1", 0,
1895 "::/127",
1896 );
1897
1898 make_ipv6_subnets_test!(
1899 test_ipv6_subnets_two,
1900 "::", "::2", 0,
1901 "::/127",
1902 "::2/128",
1903 );
1904
1905 make_ipv6_subnets_test!(
1906 test_ipv6_subnets_taper,
1907 "::", "::a", 126,
1908 "::/126",
1909 "::4/126",
1910 "::8/127",
1911 "::a/128",
1912 );
1913
1914 #[test]
1915 fn test_aggregate() {
1916 let ip_nets = make_ipnet_vec![
1917 "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
1918 "10.0.2.0/24",
1919 "10.1.0.0/24", "10.1.1.0/24",
1920 "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
1921 "fd00::/32", "fd00:1::/32",
1922 "fd00:2::/32",
1923 ];
1924
1925 let ip_aggs = make_ipnet_vec![
1926 "10.0.0.0/23",
1927 "10.0.2.0/24",
1928 "10.1.0.0/23",
1929 "192.168.0.0/22",
1930 "fd00::/31",
1931 "fd00:2::/32",
1932 ];
1933
1934 let ipv4_nets: Vec<Ipv4Net> = ip_nets.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1935 let ipv4_aggs: Vec<Ipv4Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1936 let ipv6_nets: Vec<Ipv6Net> = ip_nets.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1937 let ipv6_aggs: Vec<Ipv6Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1938
1939 assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
1940 assert_eq!(Ipv4Net::aggregate(&ipv4_nets), ipv4_aggs);
1941 assert_eq!(Ipv6Net::aggregate(&ipv6_nets), ipv6_aggs);
1942 }
1943
1944 #[test]
1945 fn test_aggregate_issue44() {
1946 let nets: Vec<Ipv4Net> = vec!["128.0.0.0/1".parse().unwrap()];
1947 assert_eq!(Ipv4Net::aggregate(&nets), nets);
1948
1949 let nets: Vec<Ipv4Net> = vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()];
1950 assert_eq!(Ipv4Net::aggregate(&nets), vec!["0.0.0.0/0".parse().unwrap()]);
1951
1952 let nets: Vec<Ipv6Net> = vec!["8000::/1".parse().unwrap()];
1953 assert_eq!(Ipv6Net::aggregate(&nets), nets);
1954
1955 let nets: Vec<Ipv6Net> = vec!["::/1".parse().unwrap(), "8000::/1".parse().unwrap()];
1956 assert_eq!(Ipv6Net::aggregate(&nets), vec!["::/0".parse().unwrap()]);
1957 }
1958
1959 #[test]
1960 fn ipnet_default() {
1961 let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
1962 assert_eq!(ipnet, IpNet::default());
1963 }
1964
1965 #[test]
1966 fn ipv4net_default() {
1967 let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
1968 assert_eq!(ipnet, Ipv4Net::default());
1969 }
1970
1971 #[test]
1972 fn ipv6net_default() {
1973 let ipnet: Ipv6Net = "::/0".parse().unwrap();
1974 assert_eq!(ipnet, Ipv6Net::default());
1975 }
1976
1977 #[test]
1978 fn new_assert() {
1979 const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1980 const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1981 const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1982 const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1983
1984 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1985 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1986 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1987 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1988 }
1989
1990 #[test]
1991 #[should_panic]
1992 fn ipv4net_new_assert_panics() {
1993 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 33);
1994 }
1995
1996 #[test]
1997 #[should_panic]
1998 fn ipv6net_new_assert_panics() {
1999 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 129);
2000 }
2001}