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_attr(not(feature = "std"), feature(ip_in_core))]
75/// # #[cfg(feature = "std")]
76/// # use std::net::Ipv6Addr;
77/// # #[cfg(not(feature = "std"))]
78/// # use core::net::Ipv6Addr;
79/// use ipnet::Ipv4Net;
80///
81/// let net: Ipv4Net = "10.1.1.0/24".parse().unwrap();
82/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
83/// ```
84#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
85pub struct Ipv4Net {
86    addr: Ipv4Addr,
87    prefix_len: u8,
88}
89
90/// An IPv6 network address.
91///
92/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
93/// addresses.
94///
95/// # Textual representation
96///
97/// `Ipv6Net` provides a [`FromStr`] implementation for parsing network
98/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
99/// CIDR notation.
100///
101/// [`IpNet`]: enum.IpNet.html
102/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
103/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
104///
105/// # Examples
106///
107/// ```
108/// use std::net::Ipv6Addr;
109/// use ipnet::Ipv6Net;
110///
111/// let net: Ipv6Net = "fd00::/32".parse().unwrap();
112/// assert_eq!(Ok(net.network()), "fd00::".parse());
113/// ```
114#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
115pub struct Ipv6Net {
116    addr: Ipv6Addr,
117    prefix_len: u8,
118}
119
120/// An error which can be returned when the prefix length is invalid.
121///
122/// Valid prefix lengths are 0 to 32 for IPv4 and 0 to 128 for IPv6.
123#[derive(Debug, Clone, PartialEq, Eq)]
124pub struct PrefixLenError;
125
126impl fmt::Display for PrefixLenError {
127    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
128        fmt.write_str("invalid IP prefix length")
129    }
130}
131
132impl Error for PrefixLenError {}
133
134impl IpNet {
135    /// Creates a new IP network address from an `IpAddr` and prefix
136    /// length.
137    ///
138    /// # Examples
139    ///
140    /// ```
141    /// use std::net::Ipv6Addr;
142    /// use ipnet::{IpNet, PrefixLenError};
143    ///
144    /// let net = IpNet::new(Ipv6Addr::LOCALHOST.into(), 48);
145    /// assert!(net.is_ok());
146    /// 
147    /// let bad_prefix_len = IpNet::new(Ipv6Addr::LOCALHOST.into(), 129);
148    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
149    /// ```
150    pub fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError> {
151        Ok(match ip {
152            IpAddr::V4(a) => Ipv4Net::new(a, prefix_len)?.into(),
153            IpAddr::V6(a) => Ipv6Net::new(a, prefix_len)?.into(),
154        })
155    }
156
157    /// Creates a new IP network address from an `IpAddr` and prefix
158    /// length. If called from a const context it will verify prefix length
159    /// at compile time. Otherwise it will panic at runtime if prefix length
160    /// is incorrect for a given IpAddr type.
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
166    /// use ipnet::{IpNet};
167    ///
168    /// // This code is verified at compile time:
169    /// const NET: IpNet = IpNet::new_assert(IpAddr::V4(Ipv4Addr::new(10, 1, 1, 0)), 24);
170    /// assert_eq!(NET.prefix_len(), 24);
171    ///
172    /// // This code is verified at runtime:
173    /// let net = IpNet::new_assert(Ipv6Addr::LOCALHOST.into(), 24);
174    /// assert_eq!(net.prefix_len(), 24);
175    ///
176    /// // This code does not compile:
177    /// // const BAD_PREFIX_LEN: IpNet = IpNet::new_assert(IpAddr::V4(Ipv4Addr::new(10, 1, 1, 0)), 33);
178    ///
179    /// // This code panics at runtime:
180    /// // let bad_prefix_len = IpNet::new_assert(Ipv6Addr::LOCALHOST.into(), 129);
181    /// ```
182    pub const fn new_assert(ip: IpAddr, prefix_len: u8) -> IpNet {
183        match ip {
184            IpAddr::V4(a) => IpNet::V4(Ipv4Net::new_assert(a, prefix_len)),
185            IpAddr::V6(a) => IpNet::V6(Ipv6Net::new_assert(a, prefix_len)),
186        }
187    }
188
189    /// Creates a new IP network address from an `IpAddr` and netmask.
190    ///
191    /// # Examples
192    ///
193    /// ```
194    /// use std::net::Ipv6Addr;
195    /// use ipnet::{IpNet, PrefixLenError};
196    ///
197    /// let net = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0000_0000_0000_0000).into());
198    /// assert!(net.is_ok());
199    ///
200    /// let bad_prefix_len = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0001_0000_0000_0000).into());
201    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
202    /// ```
203    pub fn with_netmask(ip: IpAddr, netmask: IpAddr) -> Result<IpNet, PrefixLenError> {
204        let prefix = ip_mask_to_prefix(netmask)?;
205        Self::new(ip, prefix)
206    }
207
208    /// Returns a copy of the network with the address truncated to the
209    /// prefix length.
210    ///
211    /// # Examples
212    ///
213    /// ```
214    /// # use ipnet::IpNet;
215    /// #
216    /// assert_eq!(
217    ///     "192.168.12.34/16".parse::<IpNet>().unwrap().trunc(),
218    ///     "192.168.0.0/16".parse().unwrap()
219    /// );
220    ///
221    /// assert_eq!(
222    ///     "fd00::1:2:3:4/16".parse::<IpNet>().unwrap().trunc(),
223    ///     "fd00::/16".parse().unwrap()
224    /// );
225    /// ```
226    pub fn trunc(&self) -> IpNet {
227        match *self {
228            IpNet::V4(ref a) => IpNet::V4(a.trunc()),
229            IpNet::V6(ref a) => IpNet::V6(a.trunc()),
230        }
231    }
232
233    /// Returns the address.
234    pub fn addr(&self) -> IpAddr {
235        match *self {
236            IpNet::V4(ref a) => IpAddr::V4(a.addr),
237            IpNet::V6(ref a) => IpAddr::V6(a.addr),
238        }
239    }
240
241    /// Returns the prefix length.
242    pub fn prefix_len(&self) -> u8 {
243        match *self {
244            IpNet::V4(ref a) => a.prefix_len(),
245            IpNet::V6(ref a) => a.prefix_len(),
246        }
247    }
248
249    /// Returns the maximum valid prefix length.
250    pub fn max_prefix_len(&self) -> u8 {
251        match *self {
252            IpNet::V4(ref a) => a.max_prefix_len(),
253            IpNet::V6(ref a) => a.max_prefix_len(),
254        }
255    }
256
257    /// Returns the network mask.
258    ///
259    /// # Examples
260    ///
261    /// ```
262    /// # use std::net::IpAddr;
263    /// # use ipnet::IpNet;
264    /// #
265    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
266    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
267    ///
268    /// let net: IpNet = "fd00::/24".parse().unwrap();
269    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
270    /// ```
271    pub fn netmask(&self) -> IpAddr {
272        match *self {
273            IpNet::V4(ref a) => IpAddr::V4(a.netmask()),
274            IpNet::V6(ref a) => IpAddr::V6(a.netmask()),
275        }
276    }
277
278    /// Returns the host mask.
279    ///
280    /// # Examples
281    ///
282    /// ```
283    /// # use std::net::IpAddr;
284    /// # use ipnet::IpNet;
285    /// #
286    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
287    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
288    ///
289    /// let net: IpNet = "fd00::/24".parse().unwrap();
290    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
291    /// ```
292    pub fn hostmask(&self) -> IpAddr {
293        match *self {
294            IpNet::V4(ref a) => IpAddr::V4(a.hostmask()),
295            IpNet::V6(ref a) => IpAddr::V6(a.hostmask()),
296        }
297    }
298    
299    /// Returns the network address.
300    ///
301    /// # Examples
302    ///
303    /// ```
304    /// # use std::net::IpAddr;
305    /// # use ipnet::IpNet;
306    /// #
307    /// let net: IpNet = "172.16.123.123/16".parse().unwrap();
308    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
309    ///
310    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
311    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
312    /// ```
313    pub fn network(&self) -> IpAddr {
314        match *self {
315            IpNet::V4(ref a) => IpAddr::V4(a.network()),
316            IpNet::V6(ref a) => IpAddr::V6(a.network()),
317        }
318    }    
319    
320    /// Returns the broadcast address.
321    ///
322    /// # Examples
323    ///
324    /// ```
325    /// # use std::net::IpAddr;
326    /// # use ipnet::IpNet;
327    /// #
328    /// let net: IpNet = "172.16.0.0/22".parse().unwrap();
329    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
330    ///
331    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
332    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
333    /// ```
334    pub fn broadcast(&self) -> IpAddr {
335        match *self {
336            IpNet::V4(ref a) => IpAddr::V4(a.broadcast()),
337            IpNet::V6(ref a) => IpAddr::V6(a.broadcast()),
338        }
339    }
340    
341    /// Returns the `IpNet` that contains this one.
342    ///
343    /// # Examples
344    ///
345    /// ```
346    /// # use ipnet::IpNet;
347    /// #
348    /// let n1: IpNet = "172.16.1.0/24".parse().unwrap();
349    /// let n2: IpNet = "172.16.0.0/23".parse().unwrap();
350    /// let n3: IpNet = "172.16.0.0/0".parse().unwrap();
351    ///
352    /// assert_eq!(n1.supernet().unwrap(), n2);
353    /// assert_eq!(n3.supernet(), None);
354    ///
355    /// let n1: IpNet = "fd00:ff00::/24".parse().unwrap();
356    /// let n2: IpNet = "fd00:fe00::/23".parse().unwrap();
357    /// let n3: IpNet = "fd00:fe00::/0".parse().unwrap();
358    ///
359    /// assert_eq!(n1.supernet().unwrap(), n2);
360    /// assert_eq!(n3.supernet(), None);
361    /// ```
362    pub fn supernet(&self) -> Option<IpNet> {
363        match *self {
364            IpNet::V4(ref a) => a.supernet().map(IpNet::V4),
365            IpNet::V6(ref a) => a.supernet().map(IpNet::V6),
366        }
367    }
368
369    /// Returns `true` if this network and the given network are 
370    /// children of the same supernet.
371    ///
372    /// # Examples
373    ///
374    /// ```
375    /// # use ipnet::IpNet;
376    /// #
377    /// let n4_1: IpNet = "10.1.0.0/24".parse().unwrap();
378    /// let n4_2: IpNet = "10.1.1.0/24".parse().unwrap();
379    /// let n4_3: IpNet = "10.1.2.0/24".parse().unwrap();
380    /// let n6_1: IpNet = "fd00::/18".parse().unwrap();
381    /// let n6_2: IpNet = "fd00:4000::/18".parse().unwrap();
382    /// let n6_3: IpNet = "fd00:8000::/18".parse().unwrap();
383    ///
384    /// assert!( n4_1.is_sibling(&n4_2));
385    /// assert!(!n4_2.is_sibling(&n4_3));
386    /// assert!( n6_1.is_sibling(&n6_2));
387    /// assert!(!n6_2.is_sibling(&n6_3));
388    /// assert!(!n4_1.is_sibling(&n6_2));
389    /// ```
390    pub fn is_sibling(&self, other: &IpNet) -> bool {
391        match (*self, *other) {
392            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.is_sibling(b),
393            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.is_sibling(b),
394            _ => false,
395        }
396    }
397
398    /// Return an `Iterator` over the host addresses in this network.
399    ///
400    /// # Examples
401    ///
402    /// ```
403    /// # use std::net::IpAddr;
404    /// # use ipnet::IpNet;
405    /// #
406    /// let net: IpNet = "10.0.0.0/30".parse().unwrap();
407    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
408    ///     "10.0.0.1".parse::<IpAddr>().unwrap(),
409    ///     "10.0.0.2".parse().unwrap(),
410    /// ]);
411    ///
412    /// let net: IpNet = "10.0.0.0/31".parse().unwrap();
413    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
414    ///     "10.0.0.0".parse::<IpAddr>().unwrap(),
415    ///     "10.0.0.1".parse().unwrap(),
416    /// ]);
417    ///
418    /// let net: IpNet = "fd00::/126".parse().unwrap();
419    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
420    ///     "fd00::".parse::<IpAddr>().unwrap(),
421    ///     "fd00::1".parse().unwrap(),
422    ///     "fd00::2".parse().unwrap(),
423    ///     "fd00::3".parse().unwrap(),
424    /// ]);
425    /// ```
426    pub fn hosts(&self) -> IpAddrRange {
427        match *self {
428            IpNet::V4(ref a) => IpAddrRange::V4(a.hosts()),
429            IpNet::V6(ref a) => IpAddrRange::V6(a.hosts()),
430        }
431    }
432    
433    /// Returns an `Iterator` over the subnets of this network with the
434    /// given prefix length.
435    ///
436    /// # Examples
437    ///
438    /// ```
439    /// # use ipnet::{IpNet, PrefixLenError};
440    /// #
441    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
442    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<IpNet>>(), vec![
443    ///     "10.0.0.0/26".parse::<IpNet>().unwrap(),
444    ///     "10.0.0.64/26".parse().unwrap(),
445    ///     "10.0.0.128/26".parse().unwrap(),
446    ///     "10.0.0.192/26".parse().unwrap(),
447    /// ]);
448    ///
449    /// let net: IpNet = "fd00::/16".parse().unwrap();
450    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<IpNet>>(), vec![
451    ///     "fd00::/18".parse::<IpNet>().unwrap(),
452    ///     "fd00:4000::/18".parse().unwrap(),
453    ///     "fd00:8000::/18".parse().unwrap(),
454    ///     "fd00:c000::/18".parse().unwrap(),
455    /// ]);
456    ///
457    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
458    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
459    ///
460    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
461    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
462    ///
463    /// let net: IpNet = "fd00::/16".parse().unwrap();
464    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
465    ///
466    /// let net: IpNet = "fd00::/16".parse().unwrap();
467    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
468    /// ```
469    pub fn subnets(&self, new_prefix_len: u8) -> Result<IpSubnets, PrefixLenError> {
470        match *self {
471            IpNet::V4(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V4),
472            IpNet::V6(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V6),
473        }
474    }
475
476    /// Test if a network address contains either another network
477    /// address or an IP address.
478    ///
479    /// # Examples
480    ///
481    /// ```
482    /// # use std::net::IpAddr;
483    /// # use ipnet::IpNet;
484    /// #
485    /// let net4: IpNet = "192.168.0.0/24".parse().unwrap();
486    /// let net4_yes: IpNet = "192.168.0.0/25".parse().unwrap();
487    /// let net4_no: IpNet = "192.168.0.0/23".parse().unwrap();
488    /// let ip4_yes: IpAddr = "192.168.0.1".parse().unwrap();
489    /// let ip4_no: IpAddr = "192.168.1.0".parse().unwrap();
490    ///
491    /// assert!(net4.contains(&net4));
492    /// assert!(net4.contains(&net4_yes));
493    /// assert!(!net4.contains(&net4_no));
494    /// assert!(net4.contains(&ip4_yes));
495    /// assert!(!net4.contains(&ip4_no));
496    ///
497    ///
498    /// let net6: IpNet = "fd00::/16".parse().unwrap();
499    /// let net6_yes: IpNet = "fd00::/17".parse().unwrap();
500    /// let net6_no: IpNet = "fd00::/15".parse().unwrap();
501    /// let ip6_yes: IpAddr = "fd00::1".parse().unwrap();
502    /// let ip6_no: IpAddr = "fd01::".parse().unwrap();
503    ///
504    /// assert!(net6.contains(&net6));
505    /// assert!(net6.contains(&net6_yes));
506    /// assert!(!net6.contains(&net6_no));
507    /// assert!(net6.contains(&ip6_yes));
508    /// assert!(!net6.contains(&ip6_no));
509    ///
510    /// assert!(!net4.contains(&net6));
511    /// assert!(!net6.contains(&net4));
512    /// assert!(!net4.contains(&ip6_no));
513    /// assert!(!net6.contains(&ip4_no));
514    /// ```
515    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
516        Contains::contains(self, other)
517    }
518
519    /// Aggregate a `Vec` of `IpNet`s and return the result as a new
520    /// `Vec`.
521    ///
522    /// # Examples
523    ///
524    /// ```
525    /// # use ipnet::IpNet;
526    /// #
527    /// let nets = vec![
528    ///     "10.0.0.0/24".parse::<IpNet>().unwrap(),
529    ///     "10.0.1.0/24".parse().unwrap(),
530    ///     "10.0.2.0/24".parse().unwrap(),
531    ///     "fd00::/18".parse().unwrap(),
532    ///     "fd00:4000::/18".parse().unwrap(),
533    ///     "fd00:8000::/18".parse().unwrap(),
534    /// ];
535    ///
536    /// assert_eq!(IpNet::aggregate(&nets), vec![
537    ///     "10.0.0.0/23".parse::<IpNet>().unwrap(),
538    ///     "10.0.2.0/24".parse().unwrap(),
539    ///     "fd00::/17".parse().unwrap(),
540    ///     "fd00:8000::/18".parse().unwrap(),
541    /// ]);
542    /// ```
543    pub fn aggregate(networks: &Vec<IpNet>) -> Vec<IpNet> {
544        // It's 2.5x faster to split the input up and run them using the
545        // specific IPv4 and IPV6 implementations. merge_intervals() and
546        // the comparisons are much faster running over integers.
547        let mut ipv4nets: Vec<Ipv4Net> = Vec::new();
548        let mut ipv6nets: Vec<Ipv6Net> = Vec::new();
549
550        for n in networks {
551            match *n {
552                IpNet::V4(x) => ipv4nets.push(x),
553                IpNet::V6(x) => ipv6nets.push(x),
554            }
555        }
556
557        let mut res: Vec<IpNet> = Vec::new();
558        let ipv4aggs = Ipv4Net::aggregate(&ipv4nets);
559        let ipv6aggs = Ipv6Net::aggregate(&ipv6nets);
560        res.extend::<Vec<IpNet>>(ipv4aggs.into_iter().map(IpNet::V4).collect::<Vec<IpNet>>());
561        res.extend::<Vec<IpNet>>(ipv6aggs.into_iter().map(IpNet::V6).collect::<Vec<IpNet>>());
562        res
563    }
564}
565
566impl Default for IpNet {
567    fn default() -> Self {
568        Self::V4(Ipv4Net::default())
569    }
570}
571
572impl fmt::Debug for IpNet {
573    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
574        fmt::Display::fmt(self, fmt)
575    }
576}
577
578impl fmt::Display for IpNet {
579    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
580        match *self {
581            IpNet::V4(ref a) => a.fmt(fmt),
582            IpNet::V6(ref a) => a.fmt(fmt),
583        }
584    }
585}
586
587impl From<Ipv4Net> for IpNet {
588    fn from(net: Ipv4Net) -> IpNet {
589        IpNet::V4(net)
590    }
591}
592
593impl From<Ipv6Net> for IpNet {
594    fn from(net: Ipv6Net) -> IpNet {
595        IpNet::V6(net)
596    }
597}
598
599impl From<IpAddr> for IpNet {
600    fn from(addr: IpAddr) -> IpNet {
601        match addr {
602            IpAddr::V4(a) => IpNet::V4(a.into()),
603            IpAddr::V6(a) => IpNet::V6(a.into()),
604        }
605    }
606}
607
608impl Ipv4Net {
609    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
610    /// length.
611    ///
612    /// # Examples
613    ///
614    /// ```
615    /// use std::net::Ipv4Addr;
616    /// use ipnet::{Ipv4Net, PrefixLenError};
617    ///
618    /// let net = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 24);
619    /// assert!(net.is_ok());
620    ///
621    /// let bad_prefix_len = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 33);
622    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
623    /// ```
624    #[inline]
625    pub const fn new(ip: Ipv4Addr, prefix_len: u8) -> Result<Ipv4Net, PrefixLenError> {
626        if prefix_len > 32 {
627            return Err(PrefixLenError);
628        }
629        Ok(Ipv4Net { addr: ip, prefix_len: prefix_len })
630    }
631
632    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
633    /// length. If called from a const context it will verify prefix length
634    /// at compile time. Otherwise it will panic at runtime if prefix length
635    /// is not less then or equal to 32.
636    ///
637    /// # Examples
638    ///
639    /// ```
640    /// use std::net::Ipv4Addr;
641    /// use ipnet::{Ipv4Net};
642    ///
643    /// // This code is verified at compile time:
644    /// const NET: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
645    /// assert_eq!(NET.prefix_len(), 24);
646    ///
647    /// // This code is verified at runtime:
648    /// let net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
649    /// assert_eq!(NET.prefix_len(), 24);
650    ///
651    /// // This code does not compile:
652    /// // const BAD_PREFIX_LEN: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
653    ///
654    /// // This code panics at runtime:
655    /// // let bad_prefix_len = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
656    /// ```
657    #[inline]
658    pub const fn new_assert(ip: Ipv4Addr, prefix_len: u8) -> Ipv4Net {
659        assert!(prefix_len <= 32, "PREFIX_LEN must be less then or equal to 32 for Ipv4Net");
660        Ipv4Net { addr: ip, prefix_len: prefix_len }
661    }
662
663    /// Creates a new IPv4 network address from an `Ipv4Addr` and netmask.
664    ///
665    /// # Examples
666    ///
667    /// ```
668    /// use std::net::Ipv4Addr;
669    /// use ipnet::{Ipv4Net, PrefixLenError};
670    ///
671    /// let net = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 255, 0));
672    /// assert!(net.is_ok());
673    ///
674    /// let bad_prefix_len = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 0, 1));
675    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
676    /// ```
677    pub fn with_netmask(ip: Ipv4Addr, netmask: Ipv4Addr) -> Result<Ipv4Net, PrefixLenError> {
678        let prefix = ipv4_mask_to_prefix(netmask)?;
679        Self::new(ip, prefix)
680    }
681
682    /// Returns a copy of the network with the address truncated to the
683    /// prefix length.
684    ///
685    /// # Examples
686    ///
687    /// ```
688    /// # use ipnet::Ipv4Net;
689    /// #
690    /// assert_eq!(
691    ///     "192.168.12.34/16".parse::<Ipv4Net>().unwrap().trunc(),
692    ///     "192.168.0.0/16".parse().unwrap()
693    /// );
694    /// ```
695    pub fn trunc(&self) -> Ipv4Net {
696        Ipv4Net::new(self.network(), self.prefix_len).unwrap()
697    }
698
699    /// Returns the address.
700    #[inline]
701    pub const fn addr(&self) -> Ipv4Addr {
702        self.addr
703    }
704
705    /// Returns the prefix length.
706    #[inline]
707    pub const fn prefix_len(&self) -> u8 {
708        self.prefix_len
709    }
710
711    /// Returns the maximum valid prefix length.
712    #[inline]
713    pub const fn max_prefix_len(&self) -> u8 {
714        32
715    }
716    
717    /// Returns the network mask.
718    ///
719    /// # Examples
720    ///
721    /// ```
722    /// # use std::net::Ipv4Addr;
723    /// # use ipnet::Ipv4Net;
724    /// #
725    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
726    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
727    /// ```
728    pub fn netmask(&self) -> Ipv4Addr {
729        Ipv4Addr::from(self.netmask_u32())
730    }
731
732    fn netmask_u32(&self) -> u32 {
733        u32::max_value().checked_shl(32 - self.prefix_len as u32).unwrap_or(0)
734    }
735
736    /// Returns the host mask.
737    ///
738    /// # Examples
739    ///
740    /// ```
741    /// # use std::net::Ipv4Addr;
742    /// # use ipnet::Ipv4Net;
743    /// #
744    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
745    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
746    /// ```
747    pub fn hostmask(&self) -> Ipv4Addr {
748        Ipv4Addr::from(self.hostmask_u32())
749    }
750
751    fn hostmask_u32(&self) -> u32 {
752        u32::max_value().checked_shr(self.prefix_len as u32).unwrap_or(0)
753    }
754
755    /// Returns the network address.
756    ///
757    /// # Examples
758    ///
759    /// ```
760    /// # use std::net::Ipv4Addr;
761    /// # use ipnet::Ipv4Net;
762    /// #
763    /// let net: Ipv4Net = "172.16.123.123/16".parse().unwrap();
764    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
765    /// ```
766    pub fn network(&self) -> Ipv4Addr {
767        Ipv4Addr::from(u32::from(self.addr) & self.netmask_u32())
768    }
769
770    /// Returns the broadcast address.
771    ///
772    /// # Examples
773    ///
774    /// ```
775    /// # use std::net::Ipv4Addr;
776    /// # use ipnet::Ipv4Net;
777    /// #
778    /// let net: Ipv4Net = "172.16.0.0/22".parse().unwrap();
779    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
780    /// ```
781    pub fn broadcast(&self) -> Ipv4Addr {
782        Ipv4Addr::from(u32::from(self.addr) | self.hostmask_u32())
783    }
784
785    /// Returns the `Ipv4Net` that contains this one.
786    ///
787    /// # Examples
788    ///
789    /// ```
790    /// # use ipnet::Ipv4Net;
791    /// #
792    /// let n1: Ipv4Net = "172.16.1.0/24".parse().unwrap();
793    /// let n2: Ipv4Net = "172.16.0.0/23".parse().unwrap();
794    /// let n3: Ipv4Net = "172.16.0.0/0".parse().unwrap();
795    ///
796    /// assert_eq!(n1.supernet().unwrap(), n2);
797    /// assert_eq!(n3.supernet(), None);
798    /// ```
799    pub fn supernet(&self) -> Option<Ipv4Net> {
800        Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
801    }
802
803    /// Returns `true` if this network and the given network are 
804    /// children of the same supernet.
805    ///
806    /// # Examples
807    ///
808    /// ```
809    /// # use ipnet::Ipv4Net;
810    /// #
811    /// let n1: Ipv4Net = "10.1.0.0/24".parse().unwrap();
812    /// let n2: Ipv4Net = "10.1.1.0/24".parse().unwrap();
813    /// let n3: Ipv4Net = "10.1.2.0/24".parse().unwrap();
814    ///
815    /// assert!(n1.is_sibling(&n2));
816    /// assert!(!n2.is_sibling(&n3));
817    /// ```
818    pub fn is_sibling(&self, other: &Ipv4Net) -> bool {
819        self.prefix_len > 0 &&
820        self.prefix_len == other.prefix_len &&
821        self.supernet().unwrap().contains(other)
822    }
823    
824    /// Return an `Iterator` over the host addresses in this network.
825    ///
826    /// If the prefix length is less than 31 both the network address
827    /// and broadcast address are excluded. These are only valid host
828    /// addresses when the prefix length is 31.
829    ///
830    /// # Examples
831    ///
832    /// ```
833    /// # use std::net::Ipv4Addr;
834    /// # use ipnet::Ipv4Net;
835    /// #
836    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
837    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
838    ///     "10.0.0.1".parse::<Ipv4Addr>().unwrap(),
839    ///     "10.0.0.2".parse().unwrap(),
840    /// ]);
841    ///
842    /// let net: Ipv4Net = "10.0.0.0/31".parse().unwrap();
843    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
844    ///     "10.0.0.0".parse::<Ipv4Addr>().unwrap(),
845    ///     "10.0.0.1".parse().unwrap(),
846    /// ]);
847    /// ```
848    pub fn hosts(&self) -> Ipv4AddrRange {
849        let mut start = self.network();
850        let mut end = self.broadcast();
851        
852        if self.prefix_len < 31 {
853            start = start.saturating_add(1);
854            end = end.saturating_sub(1);
855        }
856        
857        Ipv4AddrRange::new(start, end)
858    }
859
860    /// Returns an `Iterator` over the subnets of this network with the
861    /// given prefix length.
862    ///
863    /// # Examples
864    ///
865    /// ```
866    /// # use ipnet::{Ipv4Net, PrefixLenError};
867    /// #
868    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
869    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<Ipv4Net>>(), vec![
870    ///     "10.0.0.0/26".parse::<Ipv4Net>().unwrap(),
871    ///     "10.0.0.64/26".parse().unwrap(),
872    ///     "10.0.0.128/26".parse().unwrap(),
873    ///     "10.0.0.192/26".parse().unwrap(),
874    /// ]);
875    ///
876    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
877    /// assert_eq!(net.subnets(32).unwrap().collect::<Vec<Ipv4Net>>(), vec![
878    ///     "10.0.0.0/32".parse::<Ipv4Net>().unwrap(),
879    ///     "10.0.0.1/32".parse().unwrap(),
880    ///     "10.0.0.2/32".parse().unwrap(),
881    ///     "10.0.0.3/32".parse().unwrap(),
882    /// ]);
883    ///
884    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
885    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
886    ///
887    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
888    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
889    /// ```
890    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv4Subnets, PrefixLenError> {
891        if self.prefix_len > new_prefix_len || new_prefix_len > 32 {
892            return Err(PrefixLenError);
893        }
894        
895        Ok(Ipv4Subnets::new(
896            self.network(),
897            self.broadcast(),
898            new_prefix_len,
899        ))
900    }
901
902    /// Test if a network address contains either another network
903    /// address or an IP address.
904    ///
905    /// # Examples
906    ///
907    /// ```
908    /// # use std::net::Ipv4Addr;
909    /// # use ipnet::Ipv4Net;
910    /// #
911    /// let net: Ipv4Net = "192.168.0.0/24".parse().unwrap();
912    /// let net_yes: Ipv4Net = "192.168.0.0/25".parse().unwrap();
913    /// let net_no: Ipv4Net = "192.168.0.0/23".parse().unwrap();
914    /// let ip_yes: Ipv4Addr = "192.168.0.1".parse().unwrap();
915    /// let ip_no: Ipv4Addr = "192.168.1.0".parse().unwrap();
916    ///
917    /// assert!(net.contains(&net));
918    /// assert!(net.contains(&net_yes));
919    /// assert!(!net.contains(&net_no));
920    /// assert!(net.contains(&ip_yes));
921    /// assert!(!net.contains(&ip_no));
922    /// ```
923    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
924        Contains::contains(self, other)
925    }
926
927    // It is significantly faster to work on u32 than Ipv4Addr.
928    fn interval(&self) -> (u32, u32) {
929        (
930            u32::from(self.network()),
931            u32::from(self.broadcast()).saturating_add(1),
932        )
933    }
934
935    /// Aggregate a `Vec` of `Ipv4Net`s and return the result as a new
936    /// `Vec`.
937    ///
938    /// # Examples
939    ///
940    /// ```
941    /// # use ipnet::Ipv4Net;
942    /// #
943    /// let nets = vec![
944    ///     "10.0.0.0/24".parse::<Ipv4Net>().unwrap(),
945    ///     "10.0.1.0/24".parse().unwrap(),
946    ///     "10.0.2.0/24".parse().unwrap(),
947    /// ];
948    ///
949    /// assert_eq!(Ipv4Net::aggregate(&nets), vec![
950    ///     "10.0.0.0/23".parse::<Ipv4Net>().unwrap(),
951    ///     "10.0.2.0/24".parse().unwrap(),
952    /// ]);
953    pub fn aggregate(networks: &Vec<Ipv4Net>) -> Vec<Ipv4Net> {
954        let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
955        intervals = merge_intervals(intervals);
956        let mut res: Vec<Ipv4Net> = Vec::new();
957        
958        for (start, mut end) in intervals {
959            if end != core::u32::MAX {
960                end = end.saturating_sub(1)
961            }
962            let iter = Ipv4Subnets::new(start.into(), end.into(), 0);
963            res.extend(iter);
964        }
965        res
966    }
967}
968
969impl Default for Ipv4Net {
970    fn default() -> Self {
971        Self {
972            addr: Ipv4Addr::from(0),
973            prefix_len: 0,
974        }
975    }
976}
977
978impl fmt::Debug for Ipv4Net {
979    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
980        fmt::Display::fmt(self, fmt)
981    }
982}
983
984impl fmt::Display for Ipv4Net {
985    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
986        write!(fmt, "{}/{}", self.addr, self.prefix_len)
987    }
988}
989
990impl From<Ipv4Addr> for Ipv4Net {
991    fn from(addr: Ipv4Addr) -> Ipv4Net {
992        Ipv4Net { addr, prefix_len: 32 }
993    }
994}
995
996impl Ipv6Net {    
997    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
998    /// length.
999    ///
1000    /// # Examples
1001    ///
1002    /// ```
1003    /// use std::net::Ipv6Addr;
1004    /// use ipnet::{Ipv6Net, PrefixLenError};
1005    ///
1006    /// let net = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1007    /// assert!(net.is_ok());
1008    ///
1009    /// let bad_prefix_len = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1010    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1011    /// ```
1012    #[inline]
1013    pub const fn new(ip: Ipv6Addr, prefix_len: u8) -> Result<Ipv6Net, PrefixLenError> {
1014        if prefix_len > 128 {
1015            return Err(PrefixLenError);
1016        }
1017        Ok(Ipv6Net { addr: ip, prefix_len: prefix_len })
1018    }
1019
1020    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
1021    /// length. If called from a const context it will verify prefix length
1022    /// at compile time. Otherwise it will panic at runtime if prefix length
1023    /// is not less then or equal to 128.
1024    ///
1025    /// # Examples
1026    ///
1027    /// ```
1028    /// use std::net::Ipv6Addr;
1029    /// use ipnet::{Ipv6Net};
1030    ///
1031    /// // This code is verified at compile time:
1032    /// const NET: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1033    /// assert_eq!(NET.prefix_len(), 24);
1034    ///
1035    /// // This code is verified at runtime:
1036    /// let net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1037    /// assert_eq!(net.prefix_len(), 24);
1038    ///
1039    /// // This code does not compile:
1040    /// // const BAD_PREFIX_LEN: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1041    ///
1042    /// // This code panics at runtime:
1043    /// // let bad_prefix_len = Ipv6Addr::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1044    /// ```
1045    #[inline]
1046    pub const fn new_assert(ip: Ipv6Addr, prefix_len: u8) -> Ipv6Net {
1047        assert!(prefix_len <= 128, "PREFIX_LEN must be less then or equal to 128 for Ipv6Net");
1048        Ipv6Net { addr: ip, prefix_len: prefix_len }
1049    }
1050
1051    /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask.
1052    ///
1053    /// # Examples
1054    ///
1055    /// ```
1056    /// use std::net::Ipv6Addr;
1057    /// use ipnet::{Ipv6Net, PrefixLenError};
1058    ///
1059    /// 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));
1060    /// assert!(net.is_ok());
1061    ///
1062    /// 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));
1063    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1064    /// ```
1065    pub fn with_netmask(ip: Ipv6Addr, netmask: Ipv6Addr) -> Result<Ipv6Net, PrefixLenError> {
1066        let prefix = ipv6_mask_to_prefix(netmask)?;
1067        Self::new(ip, prefix)
1068    }
1069
1070    /// Returns a copy of the network with the address truncated to the
1071    /// prefix length.
1072    ///
1073    /// # Examples
1074    ///
1075    /// ```
1076    /// # use ipnet::Ipv6Net;
1077    /// #
1078    /// assert_eq!(
1079    ///     "fd00::1:2:3:4/16".parse::<Ipv6Net>().unwrap().trunc(),
1080    ///     "fd00::/16".parse().unwrap()
1081    /// );
1082    /// ```
1083    pub fn trunc(&self) -> Ipv6Net {
1084        Ipv6Net::new(self.network(), self.prefix_len).unwrap()
1085    }
1086    
1087    /// Returns the address.
1088    #[inline]
1089    pub const fn addr(&self) -> Ipv6Addr {
1090        self.addr
1091    }
1092
1093    /// Returns the prefix length.
1094    #[inline]
1095    pub const fn prefix_len(&self) -> u8 {
1096        self.prefix_len
1097    }
1098    
1099    /// Returns the maximum valid prefix length.
1100    #[inline]
1101    pub const fn max_prefix_len(&self) -> u8 {
1102        128
1103    }
1104
1105    /// Returns the network mask.
1106    ///
1107    /// # Examples
1108    ///
1109    /// ```
1110    /// # use std::net::Ipv6Addr;
1111    /// # use ipnet::Ipv6Net;
1112    /// #
1113    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1114    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
1115    /// ```
1116    pub fn netmask(&self) -> Ipv6Addr {
1117        self.netmask_u128().into()
1118    }
1119
1120    fn netmask_u128(&self) -> u128 {
1121        u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value())
1122    }
1123
1124    /// Returns the host mask.
1125    ///
1126    /// # Examples
1127    ///
1128    /// ```
1129    /// # use std::net::Ipv6Addr;
1130    /// # use ipnet::Ipv6Net;
1131    /// #
1132    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1133    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1134    /// ```
1135    pub fn hostmask(&self) -> Ipv6Addr {
1136        self.hostmask_u128().into()
1137    }
1138
1139    fn hostmask_u128(&self) -> u128 {
1140        u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value())
1141    }
1142
1143    /// Returns the network address.
1144    ///
1145    /// # Examples
1146    ///
1147    /// ```
1148    /// # use std::net::Ipv6Addr;
1149    /// # use ipnet::Ipv6Net;
1150    /// #
1151    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1152    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
1153    /// ```
1154    pub fn network(&self) -> Ipv6Addr {
1155        (u128::from(self.addr) & self.netmask_u128()).into()
1156    }
1157    
1158    /// Returns the last address.
1159    ///
1160    /// Technically there is no such thing as a broadcast address for
1161    /// IPv6. The name is used for consistency with colloquial usage.
1162    ///
1163    /// # Examples
1164    ///
1165    /// ```
1166    /// # use std::net::Ipv6Addr;
1167    /// # use ipnet::Ipv6Net;
1168    /// #
1169    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1170    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1171    /// ```
1172    pub fn broadcast(&self) -> Ipv6Addr {
1173        (u128::from(self.addr) | self.hostmask_u128()).into()
1174    }
1175
1176    /// Returns the `Ipv6Net` that contains this one.
1177    ///
1178    /// # Examples
1179    ///
1180    /// ```
1181    /// # use std::str::FromStr;
1182    /// # use ipnet::Ipv6Net;
1183    /// #
1184    /// let n1: Ipv6Net = "fd00:ff00::/24".parse().unwrap();
1185    /// let n2: Ipv6Net = "fd00:fe00::/23".parse().unwrap();
1186    /// let n3: Ipv6Net = "fd00:fe00::/0".parse().unwrap();
1187    ///
1188    /// assert_eq!(n1.supernet().unwrap(), n2);
1189    /// assert_eq!(n3.supernet(), None);
1190    /// ```
1191    pub fn supernet(&self) -> Option<Ipv6Net> {
1192        Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
1193    }
1194
1195    /// Returns `true` if this network and the given network are 
1196    /// children of the same supernet.
1197    ///
1198    /// # Examples
1199    ///
1200    /// ```
1201    /// # use ipnet::Ipv6Net;
1202    /// #
1203    /// let n1: Ipv6Net = "fd00::/18".parse().unwrap();
1204    /// let n2: Ipv6Net = "fd00:4000::/18".parse().unwrap();
1205    /// let n3: Ipv6Net = "fd00:8000::/18".parse().unwrap();
1206    ///
1207    /// assert!(n1.is_sibling(&n2));
1208    /// assert!(!n2.is_sibling(&n3));
1209    /// ```
1210    pub fn is_sibling(&self, other: &Ipv6Net) -> bool {
1211        self.prefix_len > 0 &&
1212        self.prefix_len == other.prefix_len &&
1213        self.supernet().unwrap().contains(other)
1214    }
1215    
1216    /// Return an `Iterator` over the host addresses in this network.
1217    ///
1218    /// # Examples
1219    ///
1220    /// ```
1221    /// # use std::net::Ipv6Addr;
1222    /// # use ipnet::Ipv6Net;
1223    /// #
1224    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1225    /// assert_eq!(net.hosts().collect::<Vec<Ipv6Addr>>(), vec![
1226    ///     "fd00::".parse::<Ipv6Addr>().unwrap(),
1227    ///     "fd00::1".parse().unwrap(),
1228    ///     "fd00::2".parse().unwrap(),
1229    ///     "fd00::3".parse().unwrap(),
1230    /// ]);
1231    /// ```
1232    pub fn hosts(&self) -> Ipv6AddrRange {
1233        Ipv6AddrRange::new(self.network(), self.broadcast())
1234    }
1235
1236    /// Returns an `Iterator` over the subnets of this network with the
1237    /// given prefix length.
1238    ///
1239    /// # Examples
1240    ///
1241    /// ```
1242    /// # use ipnet::{Ipv6Net, PrefixLenError};
1243    /// #
1244    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1245    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1246    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1247    ///     "fd00:4000::/18".parse().unwrap(),
1248    ///     "fd00:8000::/18".parse().unwrap(),
1249    ///     "fd00:c000::/18".parse().unwrap(),
1250    /// ]);
1251    ///
1252    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1253    /// assert_eq!(net.subnets(128).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1254    ///     "fd00::/128".parse::<Ipv6Net>().unwrap(),
1255    ///     "fd00::1/128".parse().unwrap(),
1256    ///     "fd00::2/128".parse().unwrap(),
1257    ///     "fd00::3/128".parse().unwrap(),
1258    /// ]);
1259    ///
1260    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1261    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
1262    ///
1263    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1264    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
1265    /// ```
1266    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv6Subnets, PrefixLenError> {
1267        if self.prefix_len > new_prefix_len || new_prefix_len > 128 {
1268            return Err(PrefixLenError);
1269        }
1270        
1271        Ok(Ipv6Subnets::new(
1272            self.network(),
1273            self.broadcast(),
1274            new_prefix_len,
1275        ))
1276    }
1277
1278    /// Test if a network address contains either another network
1279    /// address or an IP address.
1280    ///
1281    /// # Examples
1282    ///
1283    /// ```
1284    /// # use std::net::Ipv6Addr;
1285    /// # use ipnet::Ipv6Net;
1286    /// #
1287    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1288    /// let net_yes: Ipv6Net = "fd00::/17".parse().unwrap();
1289    /// let net_no: Ipv6Net = "fd00::/15".parse().unwrap();
1290    /// let ip_yes: Ipv6Addr = "fd00::1".parse().unwrap();
1291    /// let ip_no: Ipv6Addr = "fd01::".parse().unwrap();
1292    ///
1293    /// assert!(net.contains(&net));
1294    /// assert!(net.contains(&net_yes));
1295    /// assert!(!net.contains(&net_no));
1296    /// assert!(net.contains(&ip_yes));
1297    /// assert!(!net.contains(&ip_no));
1298    /// ```
1299    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
1300        Contains::contains(self, other)
1301    }
1302
1303    // It is significantly faster to work on u128 that Ipv6Addr.
1304    fn interval(&self) -> (u128, u128) {
1305        (
1306            u128::from(self.network()),
1307            u128::from(self.broadcast()).saturating_add(1),
1308        )
1309    }
1310
1311    /// Aggregate a `Vec` of `Ipv6Net`s and return the result as a new
1312    /// `Vec`.
1313    ///
1314    /// # Examples
1315    ///
1316    /// ```
1317    /// # use ipnet::Ipv6Net;
1318    /// #
1319    /// let nets = vec![
1320    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1321    ///     "fd00:4000::/18".parse().unwrap(),
1322    ///     "fd00:8000::/18".parse().unwrap(),
1323    /// ];
1324    /// assert_eq!(Ipv6Net::aggregate(&nets), vec![
1325    ///     "fd00::/17".parse::<Ipv6Net>().unwrap(),
1326    ///     "fd00:8000::/18".parse().unwrap(),
1327    /// ]);
1328    /// ```
1329    pub fn aggregate(networks: &Vec<Ipv6Net>) -> Vec<Ipv6Net> {
1330        let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
1331        intervals = merge_intervals(intervals);
1332        let mut res: Vec<Ipv6Net> = Vec::new();
1333
1334        for (start, mut end) in intervals {
1335            if end != core::u128::MAX {
1336                end = end.saturating_sub(1)
1337            }
1338            let iter = Ipv6Subnets::new(start.into(), end.into(), 0);
1339            res.extend(iter);
1340        }
1341        res
1342    }
1343}
1344
1345impl Default for Ipv6Net {
1346    fn default() -> Self {
1347        Self {
1348            addr: Ipv6Addr::from(0),
1349            prefix_len: 0,
1350        }
1351    }
1352}
1353
1354impl fmt::Debug for Ipv6Net {
1355    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1356        fmt::Display::fmt(self, fmt)
1357    }
1358}
1359
1360impl fmt::Display for Ipv6Net {
1361    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1362        write!(fmt, "{}/{}", self.addr, self.prefix_len)
1363    }
1364}
1365
1366impl From<Ipv6Addr> for Ipv6Net {
1367    fn from(addr: Ipv6Addr) -> Ipv6Net {
1368        Ipv6Net { addr, prefix_len: 128 }
1369    }
1370}
1371
1372/// Provides a method to test if a network address contains either
1373/// another network address or an IP address.
1374///
1375/// # Examples
1376///
1377/// ```
1378/// # use std::net::IpAddr;
1379/// # use ipnet::IpNet;
1380/// #
1381/// let n4_1: IpNet = "10.1.1.0/24".parse().unwrap();
1382/// let n4_2: IpNet = "10.1.1.0/26".parse().unwrap();
1383/// let n4_3: IpNet = "10.1.2.0/26".parse().unwrap();
1384/// let ip4_1: IpAddr = "10.1.1.1".parse().unwrap();
1385/// let ip4_2: IpAddr = "10.1.2.1".parse().unwrap();
1386///
1387/// let n6_1: IpNet = "fd00::/16".parse().unwrap();
1388/// let n6_2: IpNet = "fd00::/17".parse().unwrap();
1389/// let n6_3: IpNet = "fd01::/17".parse().unwrap();
1390/// let ip6_1: IpAddr = "fd00::1".parse().unwrap();
1391/// let ip6_2: IpAddr = "fd01::1".parse().unwrap();
1392///
1393/// assert!(n4_1.contains(&n4_2));
1394/// assert!(!n4_1.contains(&n4_3));
1395/// assert!(n4_1.contains(&ip4_1));
1396/// assert!(!n4_1.contains(&ip4_2));
1397///
1398/// assert!(n6_1.contains(&n6_2));
1399/// assert!(!n6_1.contains(&n6_3));
1400/// assert!(n6_1.contains(&ip6_1));
1401/// assert!(!n6_1.contains(&ip6_2));
1402///
1403/// assert!(!n4_1.contains(&n6_1) && !n6_1.contains(&n4_1));
1404/// assert!(!n4_1.contains(&ip6_1) && !n6_1.contains(&ip4_1));
1405/// ```
1406pub trait Contains<T> {
1407    fn contains(&self, other: T) -> bool;
1408}
1409
1410impl<'a> Contains<&'a IpNet> for IpNet {
1411    fn contains(&self, other: &IpNet) -> bool {
1412        match (*self, *other) {
1413            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.contains(b),
1414            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.contains(b),
1415            _ => false,
1416        }
1417    }
1418}
1419
1420impl<'a> Contains<&'a IpAddr> for IpNet {
1421    fn contains(&self, other: &IpAddr) -> bool {
1422        match (*self, *other) {
1423            (IpNet::V4(ref a), IpAddr::V4(ref b)) => a.contains(b),
1424            (IpNet::V6(ref a), IpAddr::V6(ref b)) => a.contains(b),
1425            _ => false,
1426        }
1427    }
1428}
1429
1430impl<'a> Contains<&'a Ipv4Net> for Ipv4Net {
1431    fn contains(&self, other: &'a Ipv4Net) -> bool {
1432        self.network() <= other.network() && other.broadcast() <= self.broadcast()
1433    }
1434}
1435
1436impl<'a> Contains<&'a Ipv4Addr> for Ipv4Net {
1437    fn contains(&self, other: &'a Ipv4Addr) -> bool {
1438        self.network() <= *other && *other <= self.broadcast()
1439    }
1440}
1441
1442impl<'a> Contains<&'a Ipv6Net> for Ipv6Net {
1443    fn contains(&self, other: &'a Ipv6Net) -> bool {
1444        self.network() <= other.network() && other.broadcast() <= self.broadcast()
1445    }
1446}
1447
1448impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net {
1449    fn contains(&self, other: &'a Ipv6Addr) -> bool {
1450        self.network() <= *other && *other <= self.broadcast()
1451    }
1452}
1453
1454/// An `Iterator` that generates IP network addresses, either IPv4 or
1455/// IPv6.
1456///
1457/// Generates the subnets between the provided `start` and `end` IP
1458/// addresses inclusive of `end`. Each iteration generates the next
1459/// network address of the largest valid size it can, while using a
1460/// prefix length not less than `min_prefix_len`.
1461///
1462/// # Examples
1463///
1464/// ```
1465/// # use std::net::{Ipv4Addr, Ipv6Addr};
1466/// # use std::str::FromStr;
1467/// # use ipnet::{IpNet, IpSubnets, Ipv4Subnets, Ipv6Subnets};
1468/// let subnets = IpSubnets::from(Ipv4Subnets::new(
1469///     "10.0.0.0".parse().unwrap(),
1470///     "10.0.0.239".parse().unwrap(),
1471///     26,
1472/// ));
1473/// 
1474/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1475///     "10.0.0.0/26".parse().unwrap(),
1476///     "10.0.0.64/26".parse().unwrap(),
1477///     "10.0.0.128/26".parse().unwrap(),
1478///     "10.0.0.192/27".parse().unwrap(),
1479///     "10.0.0.224/28".parse().unwrap(),
1480/// ]);
1481///
1482/// let subnets = IpSubnets::from(Ipv6Subnets::new(
1483///     "fd00::".parse().unwrap(),
1484///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1485///     26,
1486/// ));
1487/// 
1488/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1489///     "fd00::/26".parse().unwrap(),
1490///     "fd00:40::/26".parse().unwrap(),
1491///     "fd00:80::/26".parse().unwrap(),
1492///     "fd00:c0::/27".parse().unwrap(),
1493///     "fd00:e0::/28".parse().unwrap(),
1494/// ]);
1495/// ```
1496#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1497pub enum IpSubnets {
1498    V4(Ipv4Subnets),
1499    V6(Ipv6Subnets),
1500}
1501
1502/// An `Iterator` that generates IPv4 network addresses.
1503///
1504/// Generates the subnets between the provided `start` and `end` IP
1505/// addresses inclusive of `end`. Each iteration generates the next
1506/// network address of the largest valid size it can, while using a
1507/// prefix length not less than `min_prefix_len`.
1508///
1509/// # Examples
1510///
1511/// ```
1512/// # use std::net::Ipv4Addr;
1513/// # use std::str::FromStr;
1514/// # use ipnet::{Ipv4Net, Ipv4Subnets};
1515/// let subnets = Ipv4Subnets::new(
1516///     "10.0.0.0".parse().unwrap(),
1517///     "10.0.0.239".parse().unwrap(),
1518///     26,
1519/// );
1520/// 
1521/// assert_eq!(subnets.collect::<Vec<Ipv4Net>>(), vec![
1522///     "10.0.0.0/26".parse().unwrap(),
1523///     "10.0.0.64/26".parse().unwrap(),
1524///     "10.0.0.128/26".parse().unwrap(),
1525///     "10.0.0.192/27".parse().unwrap(),
1526///     "10.0.0.224/28".parse().unwrap(),
1527/// ]);
1528/// ```
1529#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1530pub struct Ipv4Subnets {
1531    start: Ipv4Addr,
1532    end: Ipv4Addr, // end is inclusive
1533    min_prefix_len: u8,
1534}
1535
1536/// An `Iterator` that generates IPv6 network addresses.
1537///
1538/// Generates the subnets between the provided `start` and `end` IP
1539/// addresses inclusive of `end`. Each iteration generates the next
1540/// network address of the largest valid size it can, while using a
1541/// prefix length not less than `min_prefix_len`.
1542///
1543/// # Examples
1544///
1545/// ```
1546/// # use std::net::Ipv6Addr;
1547/// # use std::str::FromStr;
1548/// # use ipnet::{Ipv6Net, Ipv6Subnets};
1549/// let subnets = Ipv6Subnets::new(
1550///     "fd00::".parse().unwrap(),
1551///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1552///     26,
1553/// );
1554/// 
1555/// assert_eq!(subnets.collect::<Vec<Ipv6Net>>(), vec![
1556///     "fd00::/26".parse().unwrap(),
1557///     "fd00:40::/26".parse().unwrap(),
1558///     "fd00:80::/26".parse().unwrap(),
1559///     "fd00:c0::/27".parse().unwrap(),
1560///     "fd00:e0::/28".parse().unwrap(),
1561/// ]);
1562/// ```
1563#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1564pub struct Ipv6Subnets {
1565    start: Ipv6Addr,
1566    end: Ipv6Addr, // end is inclusive
1567    min_prefix_len: u8,
1568}
1569
1570impl Ipv4Subnets {
1571    pub fn new(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Self {
1572        Ipv4Subnets {
1573            start: start,
1574            end: end,
1575            min_prefix_len: min_prefix_len,
1576        }
1577    }
1578}
1579
1580impl Ipv6Subnets {
1581    pub fn new(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Self {
1582        Ipv6Subnets {
1583            start: start,
1584            end: end,
1585            min_prefix_len: min_prefix_len,
1586        }
1587    }
1588}
1589
1590impl From<Ipv4Subnets> for IpSubnets {
1591    fn from(i: Ipv4Subnets) -> IpSubnets {
1592        IpSubnets::V4(i)
1593    }
1594}
1595
1596impl From<Ipv6Subnets> for IpSubnets {
1597    fn from(i: Ipv6Subnets) -> IpSubnets {
1598        IpSubnets::V6(i)
1599    }
1600}
1601
1602impl Iterator for IpSubnets {
1603    type Item = IpNet;
1604
1605    fn next(&mut self) -> Option<Self::Item> {
1606        match *self {
1607            IpSubnets::V4(ref mut a) => a.next().map(IpNet::V4),
1608            IpSubnets::V6(ref mut a) => a.next().map(IpNet::V6),
1609        }
1610    }
1611}
1612
1613fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
1614    let range = end.saturating_sub(start).saturating_add(1);
1615    if range == core::u32::MAX && min_prefix_len == 0 {
1616        Ipv4Net::new(start, min_prefix_len).unwrap()
1617    }
1618    else {
1619        let range_bits = 32u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1620        let start_tz = u32::from(start).trailing_zeros();
1621        let new_prefix_len = 32 - min(range_bits, start_tz);
1622        let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
1623        Ipv4Net::new(start, next_prefix_len).unwrap()
1624    }
1625}
1626
1627fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
1628    let range = end.saturating_sub(start).saturating_add(1);
1629    if range == core::u128::MAX && min_prefix_len == 0 {
1630        Ipv6Net::new(start, min_prefix_len).unwrap()
1631    }
1632    else {
1633        let range = end.saturating_sub(start).saturating_add(1);
1634        let range_bits = 128u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1635        let start_tz = u128::from(start).trailing_zeros();
1636        let new_prefix_len = 128 - min(range_bits, start_tz);
1637        let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
1638        Ipv6Net::new(start, next_prefix_len).unwrap()
1639    }
1640}
1641
1642impl Iterator for Ipv4Subnets {
1643    type Item = Ipv4Net;
1644
1645    fn next(&mut self) -> Option<Self::Item> {
1646        match self.start.partial_cmp(&self.end) {
1647            Some(Less) => {
1648                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1649                self.start = next.broadcast().saturating_add(1);
1650
1651                // Stop the iterator if we saturated self.start. This
1652                // check worsens performance slightly but overall this
1653                // approach of operating on Ipv4Addr types is faster
1654                // than what we were doing before using Ipv4Net.
1655                if self.start == next.broadcast() {
1656                    self.end.replace_zero();
1657                }
1658                Some(next)
1659            },
1660            Some(Equal) => {
1661                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1662                self.start = next.broadcast().saturating_add(1);
1663                self.end.replace_zero();
1664                Some(next)
1665            },
1666            _ => None,
1667        }
1668    }
1669}
1670
1671impl Iterator for Ipv6Subnets {
1672    type Item = Ipv6Net;
1673
1674    fn next(&mut self) -> Option<Self::Item> {
1675        match self.start.partial_cmp(&self.end) {
1676            Some(Less) => {
1677                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1678                self.start = next.broadcast().saturating_add(1);
1679
1680                // Stop the iterator if we saturated self.start. This
1681                // check worsens performance slightly but overall this
1682                // approach of operating on Ipv6Addr types is faster
1683                // than what we were doing before using Ipv6Net.
1684                if self.start == next.broadcast() {
1685                    self.end.replace_zero();
1686                }
1687                Some(next)
1688            },
1689            Some(Equal) => {
1690                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1691                self.start = next.broadcast().saturating_add(1);
1692                self.end.replace_zero();
1693                Some(next)
1694            },
1695            _ => None,
1696        }
1697    }
1698}
1699
1700impl FusedIterator for IpSubnets {}
1701impl FusedIterator for Ipv4Subnets {}
1702impl FusedIterator for Ipv6Subnets {}
1703
1704// Generic function for merging a vector of intervals.
1705fn merge_intervals<T: Copy + Ord>(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> {
1706    if intervals.len() == 0 {
1707        return intervals;
1708    }
1709
1710    intervals.sort();
1711    let mut res: Vec<(T, T)> = Vec::new();
1712    let (mut start, mut end) = intervals[0];
1713    
1714    let mut i = 1;
1715    let len = intervals.len();
1716    while i < len {
1717        let (next_start, next_end) = intervals[i];
1718        if end >= next_start {
1719            start = min(start, next_start);
1720            end = max(end, next_end);
1721        }
1722        else {
1723            res.push((start, end));
1724            start = next_start;
1725            end = next_end;
1726        }
1727        i += 1;
1728    }
1729
1730    res.push((start, end));
1731    res
1732}
1733
1734#[cfg(test)]
1735mod tests {
1736    use super::*;
1737
1738    macro_rules! make_ipnet_vec {
1739        ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
1740        ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
1741    }
1742
1743    #[test]
1744    fn test_make_ipnet_vec() {
1745        assert_eq!(
1746            make_ipnet_vec![
1747                "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
1748                "fd00::1/128", "fd00::2/127", "fd00::3/126",
1749            ],
1750            vec![
1751                "10.1.1.1/32".parse().unwrap(),
1752                "10.2.2.2/24".parse().unwrap(),
1753                "10.3.3.3/16".parse().unwrap(),
1754                "fd00::1/128".parse().unwrap(),
1755                "fd00::2/127".parse().unwrap(),
1756                "fd00::3/126".parse().unwrap(),
1757            ]
1758        );
1759    }
1760
1761    #[test]
1762    fn test_merge_intervals() {
1763        let v = vec![
1764            (0, 1), (1, 2), (2, 3),
1765            (11, 12), (13, 14), (10, 15), (11, 13),
1766            (20, 25), (24, 29),
1767        ];
1768
1769        let v_ok = vec![
1770            (0, 3),
1771            (10, 15),
1772            (20, 29),
1773        ];
1774
1775        let vv = vec![
1776            ([0, 1], [0, 2]), ([0, 2], [0, 3]), ([0, 0], [0, 1]),
1777            ([10, 15], [11, 0]), ([10, 0], [10, 16]),
1778        ];
1779
1780        let vv_ok = vec![
1781            ([0, 0], [0, 3]),
1782            ([10, 0], [11, 0]),
1783        ];
1784
1785        assert_eq!(merge_intervals(v), v_ok);
1786        assert_eq!(merge_intervals(vv), vv_ok);
1787    }
1788
1789    macro_rules! make_ipv4_subnets_test {
1790        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1791            #[test]
1792            fn $name() {
1793                let subnets = IpSubnets::from(Ipv4Subnets::new(
1794                    $start.parse().unwrap(),
1795                    $end.parse().unwrap(),
1796                    $min_prefix_len,
1797                ));
1798                let results = make_ipnet_vec![$($x),*];
1799                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1800            }
1801        );
1802        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1803            make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1804        );
1805    }
1806
1807    macro_rules! make_ipv6_subnets_test {
1808        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1809            #[test]
1810            fn $name() {
1811                let subnets = IpSubnets::from(Ipv6Subnets::new(
1812                    $start.parse().unwrap(),
1813                    $end.parse().unwrap(),
1814                    $min_prefix_len,
1815                ));
1816                let results = make_ipnet_vec![$($x),*];
1817                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1818            }
1819        );
1820        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1821            make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1822        );
1823    }
1824
1825    make_ipv4_subnets_test!(
1826        test_ipv4_subnets_zero_zero,
1827        "0.0.0.0", "0.0.0.0", 0,
1828        "0.0.0.0/32",
1829    );
1830
1831    make_ipv4_subnets_test!(
1832        test_ipv4_subnets_zero_max,
1833        "0.0.0.0", "255.255.255.255", 0,
1834        "0.0.0.0/0",
1835    );
1836
1837    make_ipv4_subnets_test!(
1838        test_ipv4_subnets_max_max,
1839        "255.255.255.255", "255.255.255.255", 0,
1840        "255.255.255.255/32",
1841    );
1842    
1843    make_ipv4_subnets_test!(
1844        test_ipv4_subnets_none,
1845        "0.0.0.1", "0.0.0.0", 0,
1846    );
1847    
1848    make_ipv4_subnets_test!(
1849        test_ipv4_subnets_one,
1850        "0.0.0.0", "0.0.0.1", 0,
1851        "0.0.0.0/31",
1852    );
1853
1854    make_ipv4_subnets_test!(
1855        test_ipv4_subnets_two,
1856        "0.0.0.0", "0.0.0.2", 0,
1857        "0.0.0.0/31",
1858        "0.0.0.2/32",
1859    );
1860    
1861    make_ipv4_subnets_test!(
1862        test_ipv4_subnets_taper,
1863        "0.0.0.0", "0.0.0.10", 30,
1864        "0.0.0.0/30",
1865        "0.0.0.4/30",
1866        "0.0.0.8/31",
1867        "0.0.0.10/32",
1868    );
1869    
1870    make_ipv6_subnets_test!(
1871        test_ipv6_subnets_zero_zero,
1872        "::", "::", 0,
1873        "::/128",
1874    );
1875
1876    make_ipv6_subnets_test!(
1877        test_ipv6_subnets_zero_max,
1878        "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1879        "::/0",
1880    );
1881
1882    make_ipv6_subnets_test!(
1883        test_ipv6_subnets_max_max,
1884        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1885        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
1886    );
1887    
1888    make_ipv6_subnets_test!(
1889        test_ipv6_subnets_none,
1890        "::1", "::", 0,
1891    );
1892    
1893    make_ipv6_subnets_test!(
1894        test_ipv6_subnets_one,
1895        "::", "::1", 0,
1896        "::/127",
1897    );
1898
1899    make_ipv6_subnets_test!(
1900        test_ipv6_subnets_two,
1901        "::", "::2", 0,
1902        "::/127",
1903        "::2/128",
1904    );
1905
1906    make_ipv6_subnets_test!(
1907        test_ipv6_subnets_taper,
1908        "::", "::a", 126,
1909        "::/126",
1910        "::4/126",
1911        "::8/127",
1912        "::a/128",
1913    );
1914
1915    #[test]
1916    fn test_aggregate() {
1917        let ip_nets = make_ipnet_vec![
1918            "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
1919            "10.0.2.0/24",
1920            "10.1.0.0/24", "10.1.1.0/24",
1921            "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
1922            "fd00::/32", "fd00:1::/32",
1923            "fd00:2::/32",
1924        ];
1925
1926        let ip_aggs = make_ipnet_vec![
1927            "10.0.0.0/23",
1928            "10.0.2.0/24",
1929            "10.1.0.0/23",
1930            "192.168.0.0/22",
1931            "fd00::/31",
1932            "fd00:2::/32",
1933        ];
1934
1935        let ipv4_nets: Vec<Ipv4Net> = ip_nets.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1936        let ipv4_aggs: Vec<Ipv4Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1937        let ipv6_nets: Vec<Ipv6Net> = ip_nets.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1938        let ipv6_aggs: Vec<Ipv6Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1939
1940        assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
1941        assert_eq!(Ipv4Net::aggregate(&ipv4_nets), ipv4_aggs);
1942        assert_eq!(Ipv6Net::aggregate(&ipv6_nets), ipv6_aggs);
1943    }
1944    
1945    #[test]
1946    fn test_aggregate_issue44() {
1947        let nets: Vec<Ipv4Net> = vec!["128.0.0.0/1".parse().unwrap()];
1948        assert_eq!(Ipv4Net::aggregate(&nets), nets);
1949
1950        let nets: Vec<Ipv4Net> = vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()];
1951        assert_eq!(Ipv4Net::aggregate(&nets), vec!["0.0.0.0/0".parse().unwrap()]);
1952
1953        let nets: Vec<Ipv6Net> = vec!["8000::/1".parse().unwrap()];
1954        assert_eq!(Ipv6Net::aggregate(&nets), nets);
1955
1956        let nets: Vec<Ipv6Net> = vec!["::/1".parse().unwrap(), "8000::/1".parse().unwrap()];
1957        assert_eq!(Ipv6Net::aggregate(&nets), vec!["::/0".parse().unwrap()]);
1958    }
1959
1960    #[test]
1961    fn ipnet_default() {
1962        let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
1963        assert_eq!(ipnet, IpNet::default());
1964    }
1965
1966    #[test]
1967    fn ipv4net_default() {
1968        let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
1969        assert_eq!(ipnet, Ipv4Net::default());
1970    }
1971
1972    #[test]
1973    fn ipv6net_default() {
1974        let ipnet: Ipv6Net = "::/0".parse().unwrap();
1975        assert_eq!(ipnet, Ipv6Net::default());
1976    }
1977
1978    #[test]
1979    fn new_assert() {
1980        const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1981        const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1982        const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1983        const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1984
1985        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1986        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1987        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1988        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1989    }
1990
1991    #[test]
1992    #[should_panic]
1993    fn ipv4net_new_assert_panics() {
1994        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 33);
1995    }
1996
1997    #[test]
1998    #[should_panic]
1999    fn ipv6net_new_assert_panics() {
2000        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 129);
2001    }
2002}