ipnet/
ipnet.rs

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