ipnet/
ipnet.rs

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/// An IP network address, either IPv4 or IPv6.
21///
22/// This enum can contain either an [`Ipv4Net`] or an [`Ipv6Net`]. A
23/// [`From`] implementation is provided to convert these into an
24/// `IpNet`.
25///
26/// # Textual representation
27///
28/// `IpNet` provides a [`FromStr`] implementation for parsing network
29/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
30/// CIDR notation.
31///
32/// [`Ipv4Net`]: struct.Ipv4Net.html
33/// [`Ipv6Net`]: struct.Ipv6Net.html
34/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
35/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
36/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
37///
38/// # Examples
39///
40/// ```
41/// use std::net::IpAddr;
42/// use ipnet::IpNet;
43///
44/// let net: IpNet = "10.1.1.0/24".parse().unwrap();
45/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
46///
47/// let net: IpNet = "fd00::/32".parse().unwrap();
48/// assert_eq!(Ok(net.network()), "fd00::".parse());
49/// ```
50#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
51pub enum IpNet {
52    V4(Ipv4Net),
53    V6(Ipv6Net),
54}
55
56/// An IPv4 network address.
57///
58/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
59/// addresses.
60///
61/// # Textual representation
62///
63/// `Ipv4Net` provides a [`FromStr`] implementation for parsing network
64/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
65/// CIDR notation.
66///
67/// [`IpNet`]: enum.IpNet.html
68/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
69/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
70///
71/// # Examples
72///
73/// ```
74/// # #[cfg(feature = "std")]
75/// # use std::net::Ipv6Addr;
76/// # #[cfg(not(feature = "std"))]
77/// # use core::net::Ipv6Addr;
78/// use ipnet::Ipv4Net;
79///
80/// let net: Ipv4Net = "10.1.1.0/24".parse().unwrap();
81/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
82/// ```
83#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
84pub struct Ipv4Net {
85    addr: Ipv4Addr,
86    prefix_len: u8,
87}
88
89/// An IPv6 network address.
90///
91/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
92/// addresses.
93///
94/// # Textual representation
95///
96/// `Ipv6Net` provides a [`FromStr`] implementation for parsing network
97/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
98/// CIDR notation.
99///
100/// [`IpNet`]: enum.IpNet.html
101/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
102/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
103///
104/// # Examples
105///
106/// ```
107/// use std::net::Ipv6Addr;
108/// use ipnet::Ipv6Net;
109///
110/// let net: Ipv6Net = "fd00::/32".parse().unwrap();
111/// assert_eq!(Ok(net.network()), "fd00::".parse());
112/// ```
113#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
114pub struct Ipv6Net {
115    addr: Ipv6Addr,
116    prefix_len: u8,
117}
118
119/// An error which can be returned when the prefix length is invalid.
120///
121/// Valid prefix lengths are 0 to 32 for IPv4 and 0 to 128 for IPv6.
122#[derive(Debug, Clone, PartialEq, 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    /// Creates a new IP network address from an `IpAddr` and prefix
135    /// length.
136    ///
137    /// # Examples
138    ///
139    /// ```
140    /// use std::net::Ipv6Addr;
141    /// use ipnet::{IpNet, PrefixLenError};
142    ///
143    /// let net = IpNet::new(Ipv6Addr::LOCALHOST.into(), 48);
144    /// assert!(net.is_ok());
145    /// 
146    /// let bad_prefix_len = IpNet::new(Ipv6Addr::LOCALHOST.into(), 129);
147    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
148    /// ```
149    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    /// Creates a new IP network address from an `IpAddr` and prefix
157    /// length. If called from a const context it will verify prefix length
158    /// at compile time. Otherwise it will panic at runtime if prefix length
159    /// is incorrect for a given IpAddr type.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
165    /// use ipnet::{IpNet};
166    ///
167    /// // This code is verified at compile time:
168    /// const NET: IpNet = IpNet::new_assert(IpAddr::V4(Ipv4Addr::new(10, 1, 1, 0)), 24);
169    /// assert_eq!(NET.prefix_len(), 24);
170    ///
171    /// // This code is verified at runtime:
172    /// let net = IpNet::new_assert(Ipv6Addr::LOCALHOST.into(), 24);
173    /// assert_eq!(net.prefix_len(), 24);
174    ///
175    /// // This code does not compile:
176    /// // const BAD_PREFIX_LEN: IpNet = IpNet::new_assert(IpAddr::V4(Ipv4Addr::new(10, 1, 1, 0)), 33);
177    ///
178    /// // This code panics at runtime:
179    /// // let bad_prefix_len = IpNet::new_assert(Ipv6Addr::LOCALHOST.into(), 129);
180    /// ```
181    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    /// Creates a new IP network address from an `IpAddr` and netmask.
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// use std::net::Ipv6Addr;
194    /// use ipnet::{IpNet, PrefixLenError};
195    ///
196    /// let net = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0000_0000_0000_0000).into());
197    /// assert!(net.is_ok());
198    ///
199    /// let bad_prefix_len = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0001_0000_0000_0000).into());
200    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
201    /// ```
202    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    /// Returns a copy of the network with the address truncated to the
208    /// prefix length.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// # use ipnet::IpNet;
214    /// #
215    /// assert_eq!(
216    ///     "192.168.12.34/16".parse::<IpNet>().unwrap().trunc(),
217    ///     "192.168.0.0/16".parse().unwrap()
218    /// );
219    ///
220    /// assert_eq!(
221    ///     "fd00::1:2:3:4/16".parse::<IpNet>().unwrap().trunc(),
222    ///     "fd00::/16".parse().unwrap()
223    /// );
224    /// ```
225    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    /// Returns the address.
233    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    /// Returns the prefix length.
241    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    /// Returns the maximum valid prefix length.
249    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    /// Returns the network mask.
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// # use std::net::IpAddr;
262    /// # use ipnet::IpNet;
263    /// #
264    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
265    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
266    ///
267    /// let net: IpNet = "fd00::/24".parse().unwrap();
268    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
269    /// ```
270    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    /// Returns the host mask.
278    ///
279    /// # Examples
280    ///
281    /// ```
282    /// # use std::net::IpAddr;
283    /// # use ipnet::IpNet;
284    /// #
285    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
286    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
287    ///
288    /// let net: IpNet = "fd00::/24".parse().unwrap();
289    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
290    /// ```
291    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    /// Returns the network address.
299    ///
300    /// # Examples
301    ///
302    /// ```
303    /// # use std::net::IpAddr;
304    /// # use ipnet::IpNet;
305    /// #
306    /// let net: IpNet = "172.16.123.123/16".parse().unwrap();
307    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
308    ///
309    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
310    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
311    /// ```
312    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    /// Returns the broadcast address.
320    ///
321    /// # Examples
322    ///
323    /// ```
324    /// # use std::net::IpAddr;
325    /// # use ipnet::IpNet;
326    /// #
327    /// let net: IpNet = "172.16.0.0/22".parse().unwrap();
328    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
329    ///
330    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
331    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
332    /// ```
333    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    /// Returns the `IpNet` that contains this one.
341    ///
342    /// # Examples
343    ///
344    /// ```
345    /// # use ipnet::IpNet;
346    /// #
347    /// let n1: IpNet = "172.16.1.0/24".parse().unwrap();
348    /// let n2: IpNet = "172.16.0.0/23".parse().unwrap();
349    /// let n3: IpNet = "172.16.0.0/0".parse().unwrap();
350    ///
351    /// assert_eq!(n1.supernet().unwrap(), n2);
352    /// assert_eq!(n3.supernet(), None);
353    ///
354    /// let n1: IpNet = "fd00:ff00::/24".parse().unwrap();
355    /// let n2: IpNet = "fd00:fe00::/23".parse().unwrap();
356    /// let n3: IpNet = "fd00:fe00::/0".parse().unwrap();
357    ///
358    /// assert_eq!(n1.supernet().unwrap(), n2);
359    /// assert_eq!(n3.supernet(), None);
360    /// ```
361    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    /// Returns `true` if this network and the given network are 
369    /// children of the same supernet.
370    ///
371    /// # Examples
372    ///
373    /// ```
374    /// # use ipnet::IpNet;
375    /// #
376    /// let n4_1: IpNet = "10.1.0.0/24".parse().unwrap();
377    /// let n4_2: IpNet = "10.1.1.0/24".parse().unwrap();
378    /// let n4_3: IpNet = "10.1.2.0/24".parse().unwrap();
379    /// let n6_1: IpNet = "fd00::/18".parse().unwrap();
380    /// let n6_2: IpNet = "fd00:4000::/18".parse().unwrap();
381    /// let n6_3: IpNet = "fd00:8000::/18".parse().unwrap();
382    ///
383    /// assert!( n4_1.is_sibling(&n4_2));
384    /// assert!(!n4_2.is_sibling(&n4_3));
385    /// assert!( n6_1.is_sibling(&n6_2));
386    /// assert!(!n6_2.is_sibling(&n6_3));
387    /// assert!(!n4_1.is_sibling(&n6_2));
388    /// ```
389    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    /// Return an `Iterator` over the host addresses in this network.
398    ///
399    /// # Examples
400    ///
401    /// ```
402    /// # use std::net::IpAddr;
403    /// # use ipnet::IpNet;
404    /// #
405    /// let net: IpNet = "10.0.0.0/30".parse().unwrap();
406    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
407    ///     "10.0.0.1".parse::<IpAddr>().unwrap(),
408    ///     "10.0.0.2".parse().unwrap(),
409    /// ]);
410    ///
411    /// let net: IpNet = "10.0.0.0/31".parse().unwrap();
412    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
413    ///     "10.0.0.0".parse::<IpAddr>().unwrap(),
414    ///     "10.0.0.1".parse().unwrap(),
415    /// ]);
416    ///
417    /// let net: IpNet = "fd00::/126".parse().unwrap();
418    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
419    ///     "fd00::".parse::<IpAddr>().unwrap(),
420    ///     "fd00::1".parse().unwrap(),
421    ///     "fd00::2".parse().unwrap(),
422    ///     "fd00::3".parse().unwrap(),
423    /// ]);
424    /// ```
425    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    /// Returns an `Iterator` over the subnets of this network with the
433    /// given prefix length.
434    ///
435    /// # Examples
436    ///
437    /// ```
438    /// # use ipnet::{IpNet, PrefixLenError};
439    /// #
440    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
441    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<IpNet>>(), vec![
442    ///     "10.0.0.0/26".parse::<IpNet>().unwrap(),
443    ///     "10.0.0.64/26".parse().unwrap(),
444    ///     "10.0.0.128/26".parse().unwrap(),
445    ///     "10.0.0.192/26".parse().unwrap(),
446    /// ]);
447    ///
448    /// let net: IpNet = "fd00::/16".parse().unwrap();
449    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<IpNet>>(), vec![
450    ///     "fd00::/18".parse::<IpNet>().unwrap(),
451    ///     "fd00:4000::/18".parse().unwrap(),
452    ///     "fd00:8000::/18".parse().unwrap(),
453    ///     "fd00:c000::/18".parse().unwrap(),
454    /// ]);
455    ///
456    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
457    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
458    ///
459    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
460    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
461    ///
462    /// let net: IpNet = "fd00::/16".parse().unwrap();
463    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
464    ///
465    /// let net: IpNet = "fd00::/16".parse().unwrap();
466    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
467    /// ```
468    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    /// Test if a network address contains either another network
476    /// address or an IP address.
477    ///
478    /// # Examples
479    ///
480    /// ```
481    /// # use std::net::IpAddr;
482    /// # use ipnet::IpNet;
483    /// #
484    /// let net4: IpNet = "192.168.0.0/24".parse().unwrap();
485    /// let net4_yes: IpNet = "192.168.0.0/25".parse().unwrap();
486    /// let net4_no: IpNet = "192.168.0.0/23".parse().unwrap();
487    /// let ip4_yes: IpAddr = "192.168.0.1".parse().unwrap();
488    /// let ip4_no: IpAddr = "192.168.1.0".parse().unwrap();
489    ///
490    /// assert!(net4.contains(&net4));
491    /// assert!(net4.contains(&net4_yes));
492    /// assert!(!net4.contains(&net4_no));
493    /// assert!(net4.contains(&ip4_yes));
494    /// assert!(!net4.contains(&ip4_no));
495    ///
496    ///
497    /// let net6: IpNet = "fd00::/16".parse().unwrap();
498    /// let net6_yes: IpNet = "fd00::/17".parse().unwrap();
499    /// let net6_no: IpNet = "fd00::/15".parse().unwrap();
500    /// let ip6_yes: IpAddr = "fd00::1".parse().unwrap();
501    /// let ip6_no: IpAddr = "fd01::".parse().unwrap();
502    ///
503    /// assert!(net6.contains(&net6));
504    /// assert!(net6.contains(&net6_yes));
505    /// assert!(!net6.contains(&net6_no));
506    /// assert!(net6.contains(&ip6_yes));
507    /// assert!(!net6.contains(&ip6_no));
508    ///
509    /// assert!(!net4.contains(&net6));
510    /// assert!(!net6.contains(&net4));
511    /// assert!(!net4.contains(&ip6_no));
512    /// assert!(!net6.contains(&ip4_no));
513    /// ```
514    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
515        Contains::contains(self, other)
516    }
517
518    /// Aggregate a `Vec` of `IpNet`s and return the result as a new
519    /// `Vec`.
520    ///
521    /// # Examples
522    ///
523    /// ```
524    /// # use ipnet::IpNet;
525    /// #
526    /// let nets = vec![
527    ///     "10.0.0.0/24".parse::<IpNet>().unwrap(),
528    ///     "10.0.1.0/24".parse().unwrap(),
529    ///     "10.0.2.0/24".parse().unwrap(),
530    ///     "fd00::/18".parse().unwrap(),
531    ///     "fd00:4000::/18".parse().unwrap(),
532    ///     "fd00:8000::/18".parse().unwrap(),
533    /// ];
534    ///
535    /// assert_eq!(IpNet::aggregate(&nets), vec![
536    ///     "10.0.0.0/23".parse::<IpNet>().unwrap(),
537    ///     "10.0.2.0/24".parse().unwrap(),
538    ///     "fd00::/17".parse().unwrap(),
539    ///     "fd00:8000::/18".parse().unwrap(),
540    /// ]);
541    /// ```
542    pub fn aggregate(networks: &Vec<IpNet>) -> Vec<IpNet> {
543        // It's 2.5x faster to split the input up and run them using the
544        // specific IPv4 and IPV6 implementations. merge_intervals() and
545        // the comparisons are much faster running over integers.
546        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    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
609    /// length.
610    ///
611    /// # Examples
612    ///
613    /// ```
614    /// use std::net::Ipv4Addr;
615    /// use ipnet::{Ipv4Net, PrefixLenError};
616    ///
617    /// let net = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 24);
618    /// assert!(net.is_ok());
619    ///
620    /// let bad_prefix_len = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 33);
621    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
622    /// ```
623    #[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    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
632    /// length. If called from a const context it will verify prefix length
633    /// at compile time. Otherwise it will panic at runtime if prefix length
634    /// is not less then or equal to 32.
635    ///
636    /// # Examples
637    ///
638    /// ```
639    /// use std::net::Ipv4Addr;
640    /// use ipnet::{Ipv4Net};
641    ///
642    /// // This code is verified at compile time:
643    /// const NET: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
644    /// assert_eq!(NET.prefix_len(), 24);
645    ///
646    /// // This code is verified at runtime:
647    /// let net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
648    /// assert_eq!(NET.prefix_len(), 24);
649    ///
650    /// // This code does not compile:
651    /// // const BAD_PREFIX_LEN: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
652    ///
653    /// // This code panics at runtime:
654    /// // let bad_prefix_len = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
655    /// ```
656    #[inline]
657    pub const fn new_assert(ip: Ipv4Addr, prefix_len: u8) -> Ipv4Net {
658        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    /// Creates a new IPv4 network address from an `Ipv4Addr` and netmask.
663    ///
664    /// # Examples
665    ///
666    /// ```
667    /// use std::net::Ipv4Addr;
668    /// use ipnet::{Ipv4Net, PrefixLenError};
669    ///
670    /// let net = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 255, 0));
671    /// assert!(net.is_ok());
672    ///
673    /// let bad_prefix_len = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 0, 1));
674    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
675    /// ```
676    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    /// Returns a copy of the network with the address truncated to the
682    /// prefix length.
683    ///
684    /// # Examples
685    ///
686    /// ```
687    /// # use ipnet::Ipv4Net;
688    /// #
689    /// assert_eq!(
690    ///     "192.168.12.34/16".parse::<Ipv4Net>().unwrap().trunc(),
691    ///     "192.168.0.0/16".parse().unwrap()
692    /// );
693    /// ```
694    pub fn trunc(&self) -> Ipv4Net {
695        Ipv4Net::new(self.network(), self.prefix_len).unwrap()
696    }
697
698    /// Returns the address.
699    #[inline]
700    pub const fn addr(&self) -> Ipv4Addr {
701        self.addr
702    }
703
704    /// Returns the prefix length.
705    #[inline]
706    pub const fn prefix_len(&self) -> u8 {
707        self.prefix_len
708    }
709
710    /// Returns the maximum valid prefix length.
711    #[inline]
712    pub const fn max_prefix_len(&self) -> u8 {
713        32
714    }
715    
716    /// Returns the network mask.
717    ///
718    /// # Examples
719    ///
720    /// ```
721    /// # use std::net::Ipv4Addr;
722    /// # use ipnet::Ipv4Net;
723    /// #
724    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
725    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
726    /// ```
727    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    /// Returns the host mask.
736    ///
737    /// # Examples
738    ///
739    /// ```
740    /// # use std::net::Ipv4Addr;
741    /// # use ipnet::Ipv4Net;
742    /// #
743    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
744    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
745    /// ```
746    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    /// Returns the network address.
755    ///
756    /// # Examples
757    ///
758    /// ```
759    /// # use std::net::Ipv4Addr;
760    /// # use ipnet::Ipv4Net;
761    /// #
762    /// let net: Ipv4Net = "172.16.123.123/16".parse().unwrap();
763    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
764    /// ```
765    pub fn network(&self) -> Ipv4Addr {
766        Ipv4Addr::from(u32::from(self.addr) & self.netmask_u32())
767    }
768
769    /// Returns the broadcast address.
770    ///
771    /// # Examples
772    ///
773    /// ```
774    /// # use std::net::Ipv4Addr;
775    /// # use ipnet::Ipv4Net;
776    /// #
777    /// let net: Ipv4Net = "172.16.0.0/22".parse().unwrap();
778    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
779    /// ```
780    pub fn broadcast(&self) -> Ipv4Addr {
781        Ipv4Addr::from(u32::from(self.addr) | self.hostmask_u32())
782    }
783
784    /// Returns the `Ipv4Net` that contains this one.
785    ///
786    /// # Examples
787    ///
788    /// ```
789    /// # use ipnet::Ipv4Net;
790    /// #
791    /// let n1: Ipv4Net = "172.16.1.0/24".parse().unwrap();
792    /// let n2: Ipv4Net = "172.16.0.0/23".parse().unwrap();
793    /// let n3: Ipv4Net = "172.16.0.0/0".parse().unwrap();
794    ///
795    /// assert_eq!(n1.supernet().unwrap(), n2);
796    /// assert_eq!(n3.supernet(), None);
797    /// ```
798    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    /// Returns `true` if this network and the given network are 
803    /// children of the same supernet.
804    ///
805    /// # Examples
806    ///
807    /// ```
808    /// # use ipnet::Ipv4Net;
809    /// #
810    /// let n1: Ipv4Net = "10.1.0.0/24".parse().unwrap();
811    /// let n2: Ipv4Net = "10.1.1.0/24".parse().unwrap();
812    /// let n3: Ipv4Net = "10.1.2.0/24".parse().unwrap();
813    ///
814    /// assert!(n1.is_sibling(&n2));
815    /// assert!(!n2.is_sibling(&n3));
816    /// ```
817    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    /// Return an `Iterator` over the host addresses in this network.
824    ///
825    /// If the prefix length is less than 31 both the network address
826    /// and broadcast address are excluded. These are only valid host
827    /// addresses when the prefix length is 31.
828    ///
829    /// # Examples
830    ///
831    /// ```
832    /// # use std::net::Ipv4Addr;
833    /// # use ipnet::Ipv4Net;
834    /// #
835    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
836    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
837    ///     "10.0.0.1".parse::<Ipv4Addr>().unwrap(),
838    ///     "10.0.0.2".parse().unwrap(),
839    /// ]);
840    ///
841    /// let net: Ipv4Net = "10.0.0.0/31".parse().unwrap();
842    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
843    ///     "10.0.0.0".parse::<Ipv4Addr>().unwrap(),
844    ///     "10.0.0.1".parse().unwrap(),
845    /// ]);
846    /// ```
847    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    /// Returns an `Iterator` over the subnets of this network with the
860    /// given prefix length.
861    ///
862    /// # Examples
863    ///
864    /// ```
865    /// # use ipnet::{Ipv4Net, PrefixLenError};
866    /// #
867    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
868    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<Ipv4Net>>(), vec![
869    ///     "10.0.0.0/26".parse::<Ipv4Net>().unwrap(),
870    ///     "10.0.0.64/26".parse().unwrap(),
871    ///     "10.0.0.128/26".parse().unwrap(),
872    ///     "10.0.0.192/26".parse().unwrap(),
873    /// ]);
874    ///
875    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
876    /// assert_eq!(net.subnets(32).unwrap().collect::<Vec<Ipv4Net>>(), vec![
877    ///     "10.0.0.0/32".parse::<Ipv4Net>().unwrap(),
878    ///     "10.0.0.1/32".parse().unwrap(),
879    ///     "10.0.0.2/32".parse().unwrap(),
880    ///     "10.0.0.3/32".parse().unwrap(),
881    /// ]);
882    ///
883    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
884    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
885    ///
886    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
887    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
888    /// ```
889    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    /// Test if a network address contains either another network
902    /// address or an IP address.
903    ///
904    /// # Examples
905    ///
906    /// ```
907    /// # use std::net::Ipv4Addr;
908    /// # use ipnet::Ipv4Net;
909    /// #
910    /// let net: Ipv4Net = "192.168.0.0/24".parse().unwrap();
911    /// let net_yes: Ipv4Net = "192.168.0.0/25".parse().unwrap();
912    /// let net_no: Ipv4Net = "192.168.0.0/23".parse().unwrap();
913    /// let ip_yes: Ipv4Addr = "192.168.0.1".parse().unwrap();
914    /// let ip_no: Ipv4Addr = "192.168.1.0".parse().unwrap();
915    ///
916    /// assert!(net.contains(&net));
917    /// assert!(net.contains(&net_yes));
918    /// assert!(!net.contains(&net_no));
919    /// assert!(net.contains(&ip_yes));
920    /// assert!(!net.contains(&ip_no));
921    /// ```
922    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
923        Contains::contains(self, other)
924    }
925
926    // It is significantly faster to work on u32 than Ipv4Addr.
927    fn interval(&self) -> (u32, u32) {
928        (
929            u32::from(self.network()),
930            u32::from(self.broadcast()).saturating_add(1),
931        )
932    }
933
934    /// Aggregate a `Vec` of `Ipv4Net`s and return the result as a new
935    /// `Vec`.
936    ///
937    /// # Examples
938    ///
939    /// ```
940    /// # use ipnet::Ipv4Net;
941    /// #
942    /// let nets = vec![
943    ///     "10.0.0.0/24".parse::<Ipv4Net>().unwrap(),
944    ///     "10.0.1.0/24".parse().unwrap(),
945    ///     "10.0.2.0/24".parse().unwrap(),
946    /// ];
947    ///
948    /// assert_eq!(Ipv4Net::aggregate(&nets), vec![
949    ///     "10.0.0.0/23".parse::<Ipv4Net>().unwrap(),
950    ///     "10.0.2.0/24".parse().unwrap(),
951    /// ]);
952    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        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    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
997    /// length.
998    ///
999    /// # Examples
1000    ///
1001    /// ```
1002    /// use std::net::Ipv6Addr;
1003    /// use ipnet::{Ipv6Net, PrefixLenError};
1004    ///
1005    /// let net = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1006    /// assert!(net.is_ok());
1007    ///
1008    /// let bad_prefix_len = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1009    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1010    /// ```
1011    #[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    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
1020    /// length. If called from a const context it will verify prefix length
1021    /// at compile time. Otherwise it will panic at runtime if prefix length
1022    /// is not less then or equal to 128.
1023    ///
1024    /// # Examples
1025    ///
1026    /// ```
1027    /// use std::net::Ipv6Addr;
1028    /// use ipnet::{Ipv6Net};
1029    ///
1030    /// // This code is verified at compile time:
1031    /// const NET: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1032    /// assert_eq!(NET.prefix_len(), 24);
1033    ///
1034    /// // This code is verified at runtime:
1035    /// let net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1036    /// assert_eq!(net.prefix_len(), 24);
1037    ///
1038    /// // This code does not compile:
1039    /// // const BAD_PREFIX_LEN: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1040    ///
1041    /// // This code panics at runtime:
1042    /// // let bad_prefix_len = Ipv6Addr::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1043    /// ```
1044    #[inline]
1045    pub const fn new_assert(ip: Ipv6Addr, prefix_len: u8) -> Ipv6Net {
1046        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    /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask.
1051    ///
1052    /// # Examples
1053    ///
1054    /// ```
1055    /// use std::net::Ipv6Addr;
1056    /// use ipnet::{Ipv6Net, PrefixLenError};
1057    ///
1058    /// let net = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0000_0000_0000_0000));
1059    /// assert!(net.is_ok());
1060    ///
1061    /// let bad_prefix_len = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0001_0000_0000_0000));
1062    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1063    /// ```
1064    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    /// Returns a copy of the network with the address truncated to the
1070    /// prefix length.
1071    ///
1072    /// # Examples
1073    ///
1074    /// ```
1075    /// # use ipnet::Ipv6Net;
1076    /// #
1077    /// assert_eq!(
1078    ///     "fd00::1:2:3:4/16".parse::<Ipv6Net>().unwrap().trunc(),
1079    ///     "fd00::/16".parse().unwrap()
1080    /// );
1081    /// ```
1082    pub fn trunc(&self) -> Ipv6Net {
1083        Ipv6Net::new(self.network(), self.prefix_len).unwrap()
1084    }
1085    
1086    /// Returns the address.
1087    #[inline]
1088    pub const fn addr(&self) -> Ipv6Addr {
1089        self.addr
1090    }
1091
1092    /// Returns the prefix length.
1093    #[inline]
1094    pub const fn prefix_len(&self) -> u8 {
1095        self.prefix_len
1096    }
1097    
1098    /// Returns the maximum valid prefix length.
1099    #[inline]
1100    pub const fn max_prefix_len(&self) -> u8 {
1101        128
1102    }
1103
1104    /// Returns the network mask.
1105    ///
1106    /// # Examples
1107    ///
1108    /// ```
1109    /// # use std::net::Ipv6Addr;
1110    /// # use ipnet::Ipv6Net;
1111    /// #
1112    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1113    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
1114    /// ```
1115    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    /// Returns the host mask.
1124    ///
1125    /// # Examples
1126    ///
1127    /// ```
1128    /// # use std::net::Ipv6Addr;
1129    /// # use ipnet::Ipv6Net;
1130    /// #
1131    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1132    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1133    /// ```
1134    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    /// Returns the network address.
1143    ///
1144    /// # Examples
1145    ///
1146    /// ```
1147    /// # use std::net::Ipv6Addr;
1148    /// # use ipnet::Ipv6Net;
1149    /// #
1150    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1151    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
1152    /// ```
1153    pub fn network(&self) -> Ipv6Addr {
1154        (u128::from(self.addr) & self.netmask_u128()).into()
1155    }
1156    
1157    /// Returns the last address.
1158    ///
1159    /// Technically there is no such thing as a broadcast address for
1160    /// IPv6. The name is used for consistency with colloquial usage.
1161    ///
1162    /// # Examples
1163    ///
1164    /// ```
1165    /// # use std::net::Ipv6Addr;
1166    /// # use ipnet::Ipv6Net;
1167    /// #
1168    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1169    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1170    /// ```
1171    pub fn broadcast(&self) -> Ipv6Addr {
1172        (u128::from(self.addr) | self.hostmask_u128()).into()
1173    }
1174
1175    /// Returns the `Ipv6Net` that contains this one.
1176    ///
1177    /// # Examples
1178    ///
1179    /// ```
1180    /// # use std::str::FromStr;
1181    /// # use ipnet::Ipv6Net;
1182    /// #
1183    /// let n1: Ipv6Net = "fd00:ff00::/24".parse().unwrap();
1184    /// let n2: Ipv6Net = "fd00:fe00::/23".parse().unwrap();
1185    /// let n3: Ipv6Net = "fd00:fe00::/0".parse().unwrap();
1186    ///
1187    /// assert_eq!(n1.supernet().unwrap(), n2);
1188    /// assert_eq!(n3.supernet(), None);
1189    /// ```
1190    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    /// Returns `true` if this network and the given network are 
1195    /// children of the same supernet.
1196    ///
1197    /// # Examples
1198    ///
1199    /// ```
1200    /// # use ipnet::Ipv6Net;
1201    /// #
1202    /// let n1: Ipv6Net = "fd00::/18".parse().unwrap();
1203    /// let n2: Ipv6Net = "fd00:4000::/18".parse().unwrap();
1204    /// let n3: Ipv6Net = "fd00:8000::/18".parse().unwrap();
1205    ///
1206    /// assert!(n1.is_sibling(&n2));
1207    /// assert!(!n2.is_sibling(&n3));
1208    /// ```
1209    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    /// Return an `Iterator` over the host addresses in this network.
1216    ///
1217    /// # Examples
1218    ///
1219    /// ```
1220    /// # use std::net::Ipv6Addr;
1221    /// # use ipnet::Ipv6Net;
1222    /// #
1223    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1224    /// assert_eq!(net.hosts().collect::<Vec<Ipv6Addr>>(), vec![
1225    ///     "fd00::".parse::<Ipv6Addr>().unwrap(),
1226    ///     "fd00::1".parse().unwrap(),
1227    ///     "fd00::2".parse().unwrap(),
1228    ///     "fd00::3".parse().unwrap(),
1229    /// ]);
1230    /// ```
1231    pub fn hosts(&self) -> Ipv6AddrRange {
1232        Ipv6AddrRange::new(self.network(), self.broadcast())
1233    }
1234
1235    /// Returns an `Iterator` over the subnets of this network with the
1236    /// given prefix length.
1237    ///
1238    /// # Examples
1239    ///
1240    /// ```
1241    /// # use ipnet::{Ipv6Net, PrefixLenError};
1242    /// #
1243    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1244    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1245    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1246    ///     "fd00:4000::/18".parse().unwrap(),
1247    ///     "fd00:8000::/18".parse().unwrap(),
1248    ///     "fd00:c000::/18".parse().unwrap(),
1249    /// ]);
1250    ///
1251    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1252    /// assert_eq!(net.subnets(128).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1253    ///     "fd00::/128".parse::<Ipv6Net>().unwrap(),
1254    ///     "fd00::1/128".parse().unwrap(),
1255    ///     "fd00::2/128".parse().unwrap(),
1256    ///     "fd00::3/128".parse().unwrap(),
1257    /// ]);
1258    ///
1259    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1260    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
1261    ///
1262    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1263    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
1264    /// ```
1265    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    /// Test if a network address contains either another network
1278    /// address or an IP address.
1279    ///
1280    /// # Examples
1281    ///
1282    /// ```
1283    /// # use std::net::Ipv6Addr;
1284    /// # use ipnet::Ipv6Net;
1285    /// #
1286    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1287    /// let net_yes: Ipv6Net = "fd00::/17".parse().unwrap();
1288    /// let net_no: Ipv6Net = "fd00::/15".parse().unwrap();
1289    /// let ip_yes: Ipv6Addr = "fd00::1".parse().unwrap();
1290    /// let ip_no: Ipv6Addr = "fd01::".parse().unwrap();
1291    ///
1292    /// assert!(net.contains(&net));
1293    /// assert!(net.contains(&net_yes));
1294    /// assert!(!net.contains(&net_no));
1295    /// assert!(net.contains(&ip_yes));
1296    /// assert!(!net.contains(&ip_no));
1297    /// ```
1298    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
1299        Contains::contains(self, other)
1300    }
1301
1302    // It is significantly faster to work on u128 that Ipv6Addr.
1303    fn interval(&self) -> (u128, u128) {
1304        (
1305            u128::from(self.network()),
1306            u128::from(self.broadcast()).saturating_add(1),
1307        )
1308    }
1309
1310    /// Aggregate a `Vec` of `Ipv6Net`s and return the result as a new
1311    /// `Vec`.
1312    ///
1313    /// # Examples
1314    ///
1315    /// ```
1316    /// # use ipnet::Ipv6Net;
1317    /// #
1318    /// let nets = vec![
1319    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1320    ///     "fd00:4000::/18".parse().unwrap(),
1321    ///     "fd00:8000::/18".parse().unwrap(),
1322    /// ];
1323    /// assert_eq!(Ipv6Net::aggregate(&nets), vec![
1324    ///     "fd00::/17".parse::<Ipv6Net>().unwrap(),
1325    ///     "fd00:8000::/18".parse().unwrap(),
1326    /// ]);
1327    /// ```
1328    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        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
1371/// Provides a method to test if a network address contains either
1372/// another network address or an IP address.
1373///
1374/// # Examples
1375///
1376/// ```
1377/// # use std::net::IpAddr;
1378/// # use ipnet::IpNet;
1379/// #
1380/// let n4_1: IpNet = "10.1.1.0/24".parse().unwrap();
1381/// let n4_2: IpNet = "10.1.1.0/26".parse().unwrap();
1382/// let n4_3: IpNet = "10.1.2.0/26".parse().unwrap();
1383/// let ip4_1: IpAddr = "10.1.1.1".parse().unwrap();
1384/// let ip4_2: IpAddr = "10.1.2.1".parse().unwrap();
1385///
1386/// let n6_1: IpNet = "fd00::/16".parse().unwrap();
1387/// let n6_2: IpNet = "fd00::/17".parse().unwrap();
1388/// let n6_3: IpNet = "fd01::/17".parse().unwrap();
1389/// let ip6_1: IpAddr = "fd00::1".parse().unwrap();
1390/// let ip6_2: IpAddr = "fd01::1".parse().unwrap();
1391///
1392/// assert!(n4_1.contains(&n4_2));
1393/// assert!(!n4_1.contains(&n4_3));
1394/// assert!(n4_1.contains(&ip4_1));
1395/// assert!(!n4_1.contains(&ip4_2));
1396///
1397/// assert!(n6_1.contains(&n6_2));
1398/// assert!(!n6_1.contains(&n6_3));
1399/// assert!(n6_1.contains(&ip6_1));
1400/// assert!(!n6_1.contains(&ip6_2));
1401///
1402/// assert!(!n4_1.contains(&n6_1) && !n6_1.contains(&n4_1));
1403/// assert!(!n4_1.contains(&ip6_1) && !n6_1.contains(&ip4_1));
1404/// ```
1405pub 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/// An `Iterator` that generates IP network addresses, either IPv4 or
1454/// IPv6.
1455///
1456/// Generates the subnets between the provided `start` and `end` IP
1457/// addresses inclusive of `end`. Each iteration generates the next
1458/// network address of the largest valid size it can, while using a
1459/// prefix length not less than `min_prefix_len`.
1460///
1461/// # Examples
1462///
1463/// ```
1464/// # use std::net::{Ipv4Addr, Ipv6Addr};
1465/// # use std::str::FromStr;
1466/// # use ipnet::{IpNet, IpSubnets, Ipv4Subnets, Ipv6Subnets};
1467/// let subnets = IpSubnets::from(Ipv4Subnets::new(
1468///     "10.0.0.0".parse().unwrap(),
1469///     "10.0.0.239".parse().unwrap(),
1470///     26,
1471/// ));
1472/// 
1473/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1474///     "10.0.0.0/26".parse().unwrap(),
1475///     "10.0.0.64/26".parse().unwrap(),
1476///     "10.0.0.128/26".parse().unwrap(),
1477///     "10.0.0.192/27".parse().unwrap(),
1478///     "10.0.0.224/28".parse().unwrap(),
1479/// ]);
1480///
1481/// let subnets = IpSubnets::from(Ipv6Subnets::new(
1482///     "fd00::".parse().unwrap(),
1483///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1484///     26,
1485/// ));
1486/// 
1487/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1488///     "fd00::/26".parse().unwrap(),
1489///     "fd00:40::/26".parse().unwrap(),
1490///     "fd00:80::/26".parse().unwrap(),
1491///     "fd00:c0::/27".parse().unwrap(),
1492///     "fd00:e0::/28".parse().unwrap(),
1493/// ]);
1494/// ```
1495#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1496pub enum IpSubnets {
1497    V4(Ipv4Subnets),
1498    V6(Ipv6Subnets),
1499}
1500
1501/// An `Iterator` that generates IPv4 network addresses.
1502///
1503/// Generates the subnets between the provided `start` and `end` IP
1504/// addresses inclusive of `end`. Each iteration generates the next
1505/// network address of the largest valid size it can, while using a
1506/// prefix length not less than `min_prefix_len`.
1507///
1508/// # Examples
1509///
1510/// ```
1511/// # use std::net::Ipv4Addr;
1512/// # use std::str::FromStr;
1513/// # use ipnet::{Ipv4Net, Ipv4Subnets};
1514/// let subnets = Ipv4Subnets::new(
1515///     "10.0.0.0".parse().unwrap(),
1516///     "10.0.0.239".parse().unwrap(),
1517///     26,
1518/// );
1519/// 
1520/// assert_eq!(subnets.collect::<Vec<Ipv4Net>>(), vec![
1521///     "10.0.0.0/26".parse().unwrap(),
1522///     "10.0.0.64/26".parse().unwrap(),
1523///     "10.0.0.128/26".parse().unwrap(),
1524///     "10.0.0.192/27".parse().unwrap(),
1525///     "10.0.0.224/28".parse().unwrap(),
1526/// ]);
1527/// ```
1528#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1529pub struct Ipv4Subnets {
1530    start: Ipv4Addr,
1531    end: Ipv4Addr, // end is inclusive
1532    min_prefix_len: u8,
1533}
1534
1535/// An `Iterator` that generates IPv6 network addresses.
1536///
1537/// Generates the subnets between the provided `start` and `end` IP
1538/// addresses inclusive of `end`. Each iteration generates the next
1539/// network address of the largest valid size it can, while using a
1540/// prefix length not less than `min_prefix_len`.
1541///
1542/// # Examples
1543///
1544/// ```
1545/// # use std::net::Ipv6Addr;
1546/// # use std::str::FromStr;
1547/// # use ipnet::{Ipv6Net, Ipv6Subnets};
1548/// let subnets = Ipv6Subnets::new(
1549///     "fd00::".parse().unwrap(),
1550///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1551///     26,
1552/// );
1553/// 
1554/// assert_eq!(subnets.collect::<Vec<Ipv6Net>>(), vec![
1555///     "fd00::/26".parse().unwrap(),
1556///     "fd00:40::/26".parse().unwrap(),
1557///     "fd00:80::/26".parse().unwrap(),
1558///     "fd00:c0::/27".parse().unwrap(),
1559///     "fd00:e0::/28".parse().unwrap(),
1560/// ]);
1561/// ```
1562#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1563pub struct Ipv6Subnets {
1564    start: Ipv6Addr,
1565    end: Ipv6Addr, // end is inclusive
1566    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                // Stop the iterator if we saturated self.start. This
1651                // check worsens performance slightly but overall this
1652                // approach of operating on Ipv4Addr types is faster
1653                // than what we were doing before using Ipv4Net.
1654                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                // Stop the iterator if we saturated self.start. This
1680                // check worsens performance slightly but overall this
1681                // approach of operating on Ipv6Addr types is faster
1682                // than what we were doing before using Ipv6Net.
1683                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
1703// Generic function for merging a vector of intervals.
1704fn 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}