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