1 //! Extensions to the standard IP address types for common operations.
2 //!
3 //! The [`IpAdd`], [`IpSub`], [`IpBitAnd`], [`IpBitOr`] traits extend
4 //! the `Ipv4Addr` and `Ipv6Addr` types with methods to perform these
5 //! operations.
6 
7 use std::cmp::Ordering::{Less, Equal};
8 use std::iter::{FusedIterator, DoubleEndedIterator};
9 use std::mem;
10 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
11 
12 /// Provides a `saturating_add()` method for `Ipv4Addr` and `Ipv6Addr`.
13 ///
14 /// Adding an integer to an IP address returns the modified IP address.
15 /// A `u32` may added to an IPv4 address and a `u128` may be added to
16 /// an IPv6 address.
17 ///
18 /// # Examples
19 ///
20 /// ```
21 /// use std::net::{Ipv4Addr, Ipv6Addr};
22 /// use ipnet::IpAdd;
23 ///
24 /// let ip0: Ipv4Addr = "192.168.0.0".parse().unwrap();
25 /// let ip1: Ipv4Addr = "192.168.0.5".parse().unwrap();
26 /// let ip2: Ipv4Addr = "255.255.255.254".parse().unwrap();
27 /// let max: Ipv4Addr = "255.255.255.255".parse().unwrap();
28 ///
29 /// assert_eq!(ip0.saturating_add(5), ip1);
30 /// assert_eq!(ip2.saturating_add(1), max);
31 /// assert_eq!(ip2.saturating_add(5), max);
32 ///
33 /// let ip0: Ipv6Addr = "fd00::".parse().unwrap();
34 /// let ip1: Ipv6Addr = "fd00::5".parse().unwrap();
35 /// let ip2: Ipv6Addr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe".parse().unwrap();
36 /// let max: Ipv6Addr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap();
37 ///
38 /// assert_eq!(ip0.saturating_add(5), ip1);
39 /// assert_eq!(ip2.saturating_add(1), max);
40 /// assert_eq!(ip2.saturating_add(5), max);
41 /// ```
42 pub trait IpAdd<RHS = Self> {
43     type Output;
saturating_add(self, rhs: RHS) -> Self::Output44     fn saturating_add(self, rhs: RHS) -> Self::Output;
45 }
46 
47 /// Provides a `saturating_sub()` method for `Ipv4Addr` and `Ipv6Addr`.
48 ///
49 /// Subtracting an integer from an IP address returns the modified IP
50 /// address. A `u32` may be subtracted from an IPv4 address and a `u128`
51 /// may be subtracted from an IPv6 address.
52 ///
53 /// Subtracting an IP address from another IP address of the same type
54 /// returns an integer of the appropriate width. A `u32` for IPv4 and a
55 /// `u128` for IPv6. Subtracting IP addresses is useful for getting
56 /// the range between two IP addresses.
57 ///
58 /// # Examples
59 ///
60 /// ```
61 /// use std::net::{Ipv4Addr, Ipv6Addr};
62 /// use ipnet::IpSub;
63 ///
64 /// let min: Ipv4Addr = "0.0.0.0".parse().unwrap();
65 /// let ip1: Ipv4Addr = "192.168.1.5".parse().unwrap();
66 /// let ip2: Ipv4Addr = "192.168.1.100".parse().unwrap();
67 ///
68 /// assert_eq!(min.saturating_sub(ip1), 0);
69 /// assert_eq!(ip2.saturating_sub(ip1), 95);
70 /// assert_eq!(min.saturating_sub(5), min);
71 /// assert_eq!(ip2.saturating_sub(95), ip1);
72 ///
73 /// let min: Ipv6Addr = "::".parse().unwrap();
74 /// let ip1: Ipv6Addr = "fd00::5".parse().unwrap();
75 /// let ip2: Ipv6Addr = "fd00::64".parse().unwrap();
76 ///
77 /// assert_eq!(min.saturating_sub(ip1), 0);
78 /// assert_eq!(ip2.saturating_sub(ip1), 95);
79 /// assert_eq!(min.saturating_sub(5u128), min);
80 /// assert_eq!(ip2.saturating_sub(95u128), ip1);
81 /// ```
82 pub trait IpSub<RHS = Self> {
83     type Output;
saturating_sub(self, rhs: RHS) -> Self::Output84     fn saturating_sub(self, rhs: RHS) -> Self::Output;
85 }
86 
87 /// Provides a `bitand()` method for `Ipv4Addr` and `Ipv6Addr`.
88 ///
89 /// # Examples
90 ///
91 /// ```
92 /// use std::net::{Ipv4Addr, Ipv6Addr};
93 /// use ipnet::IpBitAnd;
94 ///
95 /// let ip: Ipv4Addr = "192.168.1.1".parse().unwrap();
96 /// let mask: Ipv4Addr = "255.255.0.0".parse().unwrap();
97 /// let res: Ipv4Addr = "192.168.0.0".parse().unwrap();
98 ///
99 /// assert_eq!(ip.bitand(mask), res);
100 /// assert_eq!(ip.bitand(0xffff0000), res);
101 ///
102 /// let ip: Ipv6Addr = "fd00:1234::1".parse().unwrap();
103 /// let mask: Ipv6Addr = "ffff::".parse().unwrap();
104 /// let res: Ipv6Addr = "fd00::".parse().unwrap();
105 ///
106 /// assert_eq!(ip.bitand(mask), res);
107 /// assert_eq!(ip.bitand(0xffff_0000_0000_0000_0000_0000_0000_0000u128), res);
108 /// ```
109 pub trait IpBitAnd<RHS = Self> {
110     type Output;
bitand(self, rhs: RHS) -> Self::Output111     fn bitand(self, rhs: RHS) -> Self::Output;
112 }
113 
114 /// Provides a `bitor()` method for `Ipv4Addr` and `Ipv6Addr`.
115 ///
116 /// # Examples
117 ///
118 /// ```
119 /// use std::net::{Ipv4Addr, Ipv6Addr};
120 /// use ipnet::IpBitOr;
121 ///
122 /// let ip: Ipv4Addr = "10.1.1.1".parse().unwrap();
123 /// let mask: Ipv4Addr = "0.0.0.255".parse().unwrap();
124 /// let res: Ipv4Addr = "10.1.1.255".parse().unwrap();
125 ///
126 /// assert_eq!(ip.bitor(mask), res);
127 /// assert_eq!(ip.bitor(0x000000ff), res);
128 ///
129 /// let ip: Ipv6Addr = "fd00::1".parse().unwrap();
130 /// let mask: Ipv6Addr = "::ffff:ffff".parse().unwrap();
131 /// let res: Ipv6Addr = "fd00::ffff:ffff".parse().unwrap();
132 ///
133 /// assert_eq!(ip.bitor(mask), res);
134 /// assert_eq!(ip.bitor(u128::from(0xffffffffu32)), res);
135 /// ```
136 pub trait IpBitOr<RHS = Self> {
137     type Output;
bitor(self, rhs: RHS) -> Self::Output138     fn bitor(self, rhs: RHS) -> Self::Output;
139 }
140 
141 macro_rules! ip_add_impl {
142     ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => (
143         impl IpAdd<$rhs> for $lhs {
144             type Output = $output;
145 
146             fn saturating_add(self, rhs: $rhs) -> $output {
147                 let lhs: $inner = self.into();
148                 let rhs: $inner = rhs.into();
149                 (lhs.saturating_add(rhs.into())).into()
150             }
151         }
152     )
153 }
154 
155 macro_rules! ip_sub_impl {
156     ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => (
157         impl IpSub<$rhs> for $lhs {
158             type Output = $output;
159 
160             fn saturating_sub(self, rhs: $rhs) -> $output {
161                 let lhs: $inner = self.into();
162                 let rhs: $inner = rhs.into();
163                 (lhs.saturating_sub(rhs.into())).into()
164             }
165         }
166     )
167 }
168 
169 ip_add_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
170 ip_add_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
171 
172 ip_sub_impl!(Ipv4Addr, Ipv4Addr, u32, u32);
173 ip_sub_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
174 ip_sub_impl!(Ipv6Addr, Ipv6Addr, u128, u128);
175 ip_sub_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
176 
177 macro_rules! ip_bitops_impl {
178     ($(($lhs:ty, $rhs:ty, $t:ty),)*) => {
179     $(
180         impl IpBitAnd<$rhs> for $lhs {
181             type Output = $lhs;
182 
183             fn bitand(self, rhs: $rhs) -> $lhs {
184                 let lhs: $t = self.into();
185                 let rhs: $t = rhs.into();
186                 (lhs & rhs).into()
187             }
188         }
189 
190         impl IpBitOr<$rhs> for $lhs {
191             type Output = $lhs;
192 
193             fn bitor(self, rhs: $rhs) -> $lhs {
194                 let lhs: $t = self.into();
195                 let rhs: $t = rhs.into();
196                 (lhs | rhs).into()
197             }
198         }
199     )*
200     }
201 }
202 
203 ip_bitops_impl! {
204     (Ipv4Addr, Ipv4Addr, u32),
205     (Ipv4Addr, u32, u32),
206     (Ipv6Addr, Ipv6Addr, u128),
207     (Ipv6Addr, u128, u128),
208 }
209 
210 // A barebones copy of the current unstable Step trait used by the
211 // IpAddrRange, Ipv4AddrRange, and Ipv6AddrRange types below, and the
212 // Subnets types in ipnet.
213 pub trait IpStep {
replace_one(&mut self) -> Self214     fn replace_one(&mut self) -> Self;
replace_zero(&mut self) -> Self215     fn replace_zero(&mut self) -> Self;
add_one(&self) -> Self216     fn add_one(&self) -> Self;
sub_one(&self) -> Self217     fn sub_one(&self) -> Self;
218 }
219 
220 impl IpStep for Ipv4Addr {
replace_one(&mut self) -> Self221     fn replace_one(&mut self) -> Self {
222         mem::replace(self, Ipv4Addr::new(0, 0, 0, 1))
223     }
replace_zero(&mut self) -> Self224     fn replace_zero(&mut self) -> Self {
225         mem::replace(self, Ipv4Addr::new(0, 0, 0, 0))
226     }
add_one(&self) -> Self227     fn add_one(&self) -> Self {
228         self.saturating_add(1)
229     }
sub_one(&self) -> Self230     fn sub_one(&self) -> Self {
231         self.saturating_sub(1)
232     }
233 }
234 
235 impl IpStep for Ipv6Addr {
replace_one(&mut self) -> Self236     fn replace_one(&mut self) -> Self {
237         mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
238     }
replace_zero(&mut self) -> Self239     fn replace_zero(&mut self) -> Self {
240         mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0))
241     }
add_one(&self) -> Self242     fn add_one(&self) -> Self {
243         self.saturating_add(1)
244     }
sub_one(&self) -> Self245     fn sub_one(&self) -> Self {
246         self.saturating_sub(1)
247     }
248 }
249 
250 /// An `Iterator` over a range of IP addresses, either IPv4 or IPv6.
251 ///
252 /// # Examples
253 ///
254 /// ```
255 /// use std::net::IpAddr;
256 /// use ipnet::{IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
257 ///
258 /// let hosts = IpAddrRange::from(Ipv4AddrRange::new(
259 ///     "10.0.0.0".parse().unwrap(),
260 ///     "10.0.0.3".parse().unwrap(),
261 /// ));
262 ///
263 /// assert_eq!(hosts.collect::<Vec<IpAddr>>(), vec![
264 ///     "10.0.0.0".parse::<IpAddr>().unwrap(),
265 ///     "10.0.0.1".parse().unwrap(),
266 ///     "10.0.0.2".parse().unwrap(),
267 ///     "10.0.0.3".parse().unwrap(),
268 /// ]);
269 ///
270 /// let hosts = IpAddrRange::from(Ipv6AddrRange::new(
271 ///     "fd00::".parse().unwrap(),
272 ///     "fd00::3".parse().unwrap(),
273 /// ));
274 ///
275 /// assert_eq!(hosts.collect::<Vec<IpAddr>>(), vec![
276 ///     "fd00::0".parse::<IpAddr>().unwrap(),
277 ///     "fd00::1".parse().unwrap(),
278 ///     "fd00::2".parse().unwrap(),
279 ///     "fd00::3".parse().unwrap(),
280 /// ]);
281 /// ```
282 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
283 pub enum IpAddrRange {
284     V4(Ipv4AddrRange),
285     V6(Ipv6AddrRange),
286 }
287 
288 /// An `Iterator` over a range of IPv4 addresses.
289 ///
290 /// # Examples
291 ///
292 /// ```
293 /// use std::net::Ipv4Addr;
294 /// use ipnet::Ipv4AddrRange;
295 ///
296 /// let hosts = Ipv4AddrRange::new(
297 ///     "10.0.0.0".parse().unwrap(),
298 ///     "10.0.0.3".parse().unwrap(),
299 /// );
300 ///
301 /// assert_eq!(hosts.collect::<Vec<Ipv4Addr>>(), vec![
302 ///     "10.0.0.0".parse::<Ipv4Addr>().unwrap(),
303 ///     "10.0.0.1".parse().unwrap(),
304 ///     "10.0.0.2".parse().unwrap(),
305 ///     "10.0.0.3".parse().unwrap(),
306 /// ]);
307 /// ```
308 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
309 pub struct Ipv4AddrRange {
310     start: Ipv4Addr,
311     end: Ipv4Addr,
312 }
313 
314 /// An `Iterator` over a range of IPv6 addresses.
315 ///
316 /// # Examples
317 ///
318 /// ```
319 /// use std::net::Ipv6Addr;
320 /// use ipnet::Ipv6AddrRange;
321 ///
322 /// let hosts = Ipv6AddrRange::new(
323 ///     "fd00::".parse().unwrap(),
324 ///     "fd00::3".parse().unwrap(),
325 /// );
326 ///
327 /// assert_eq!(hosts.collect::<Vec<Ipv6Addr>>(), vec![
328 ///     "fd00::".parse::<Ipv6Addr>().unwrap(),
329 ///     "fd00::1".parse().unwrap(),
330 ///     "fd00::2".parse().unwrap(),
331 ///     "fd00::3".parse().unwrap(),
332 /// ]);
333 /// ```
334 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
335 pub struct Ipv6AddrRange {
336     start: Ipv6Addr,
337     end: Ipv6Addr,
338 }
339 
340 impl From<Ipv4AddrRange> for IpAddrRange {
from(i: Ipv4AddrRange) -> IpAddrRange341     fn from(i: Ipv4AddrRange) -> IpAddrRange {
342         IpAddrRange::V4(i)
343     }
344 }
345 
346 impl From<Ipv6AddrRange> for IpAddrRange {
from(i: Ipv6AddrRange) -> IpAddrRange347     fn from(i: Ipv6AddrRange) -> IpAddrRange {
348         IpAddrRange::V6(i)
349     }
350 }
351 
352 impl Ipv4AddrRange {
new(start: Ipv4Addr, end: Ipv4Addr) -> Self353     pub fn new(start: Ipv4Addr, end: Ipv4Addr) -> Self {
354         Ipv4AddrRange {
355             start: start,
356             end: end,
357         }
358     }
359     /// Counts the number of Ipv4Addr in this range.
360     /// This method will never overflow or panic.
count_u64(&self) -> u64361     fn count_u64(&self) -> u64 {
362         match self.start.partial_cmp(&self.end) {
363             Some(Less) => {
364                 let count: u32 = self.end.saturating_sub(self.start);
365                 let count = count as u64 + 1; // Never overflows
366                 count
367             },
368             Some(Equal) => 1,
369             _ => 0,
370         }
371     }
372 }
373 
374 impl Ipv6AddrRange {
new(start: Ipv6Addr, end: Ipv6Addr) -> Self375     pub fn new(start: Ipv6Addr, end: Ipv6Addr) -> Self {
376         Ipv6AddrRange {
377             start: start,
378             end: end,
379         }
380     }
381     /// Counts the number of Ipv6Addr in this range.
382     /// This method may overflow or panic if start
383     /// is 0 and end is u128::MAX
count_u128(&self) -> u128384     fn count_u128(&self) -> u128 {
385         match self.start.partial_cmp(&self.end) {
386             Some(Less) => {
387                 let count = self.end.saturating_sub(self.start);
388                 // May overflow or panic
389                 count + 1
390             },
391             Some(Equal) => 1,
392             _ => 0,
393         }
394     }
395     /// True only if count_u128 does not overflow
can_count_u128(&self) -> bool396     fn can_count_u128(&self) -> bool {
397         self.start != Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)
398         || self.end != Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
399     }
400 }
401 
402 impl Iterator for IpAddrRange {
403     type Item = IpAddr;
404 
next(&mut self) -> Option<Self::Item>405     fn next(&mut self) -> Option<Self::Item> {
406         match *self {
407             IpAddrRange::V4(ref mut a) => a.next().map(IpAddr::V4),
408             IpAddrRange::V6(ref mut a) => a.next().map(IpAddr::V6),
409         }
410     }
411 
count(self) -> usize412     fn count(self) -> usize {
413         match self {
414             IpAddrRange::V4(a) => a.count(),
415             IpAddrRange::V6(a) => a.count(),
416         }
417     }
418 
last(self) -> Option<Self::Item>419     fn last(self) -> Option<Self::Item> {
420         match self {
421             IpAddrRange::V4(a) => a.last().map(IpAddr::V4),
422             IpAddrRange::V6(a) => a.last().map(IpAddr::V6),
423         }
424     }
425 
max(self) -> Option<Self::Item>426     fn max(self) -> Option<Self::Item> {
427         match self {
428             IpAddrRange::V4(a) => Iterator::max(a).map(IpAddr::V4),
429             IpAddrRange::V6(a) => Iterator::max(a).map(IpAddr::V6),
430         }
431     }
432 
min(self) -> Option<Self::Item>433     fn min(self) -> Option<Self::Item> {
434         match self {
435             IpAddrRange::V4(a) => Iterator::min(a).map(IpAddr::V4),
436             IpAddrRange::V6(a) => Iterator::min(a).map(IpAddr::V6),
437         }
438     }
439 
nth(&mut self, n: usize) -> Option<Self::Item>440     fn nth(&mut self, n: usize) -> Option<Self::Item> {
441         match *self {
442             IpAddrRange::V4(ref mut a) => a.nth(n).map(IpAddr::V4),
443             IpAddrRange::V6(ref mut a) => a.nth(n).map(IpAddr::V6),
444         }
445     }
446 
size_hint(&self) -> (usize, Option<usize>)447     fn size_hint(&self) -> (usize, Option<usize>) {
448         match *self {
449             IpAddrRange::V4(ref a) => a.size_hint(),
450             IpAddrRange::V6(ref a) => a.size_hint(),
451         }
452     }
453 }
454 
455 impl Iterator for Ipv4AddrRange {
456     type Item = Ipv4Addr;
457 
next(&mut self) -> Option<Self::Item>458     fn next(&mut self) -> Option<Self::Item> {
459         match self.start.partial_cmp(&self.end) {
460             Some(Less) => {
461                 let next = self.start.add_one();
462                 Some(mem::replace(&mut self.start, next))
463             },
464             Some(Equal) => {
465                 self.end.replace_zero();
466                 Some(self.start.replace_one())
467             },
468             _ => None,
469         }
470     }
471 
472     #[allow(const_err)]
473     #[allow(arithmetic_overflow)]
count(self) -> usize474     fn count(self) -> usize {
475         match self.start.partial_cmp(&self.end) {
476             Some(Less) => {
477                 // Adding one here might overflow u32.
478                 // Instead, wait until after converted to usize
479                 let count: u32 = self.end.saturating_sub(self.start);
480 
481                 // usize might only be 16 bits,
482                 // so need to explicitely check for overflow.
483                 // 'usize::MAX as u32' is okay here - if usize is 64 bits,
484                 // value truncates to u32::MAX
485                 if count <= std::usize::MAX as u32 {
486                     count as usize + 1
487                 // count overflows usize
488                 } else {
489                     // emulate standard overflow/panic behavior
490                     std::usize::MAX + 2 + count as usize
491                 }
492             },
493             Some(Equal) => 1,
494             _ => 0
495         }
496     }
497 
last(self) -> Option<Self::Item>498     fn last(self) -> Option<Self::Item> {
499         match self.start.partial_cmp(&self.end) {
500             Some(Less) | Some(Equal) => Some(self.end),
501             _ => None,
502         }
503     }
504 
max(self) -> Option<Self::Item>505     fn max(self) -> Option<Self::Item> {
506         self.last()
507     }
508 
min(self) -> Option<Self::Item>509     fn min(self) -> Option<Self::Item> {
510         match self.start.partial_cmp(&self.end) {
511             Some(Less) | Some(Equal) => Some(self.start),
512             _ => None
513         }
514     }
515 
nth(&mut self, n: usize) -> Option<Self::Item>516     fn nth(&mut self, n: usize) -> Option<Self::Item> {
517         let n = n as u64;
518         let count = self.count_u64();
519         if n >= count {
520             self.end.replace_zero();
521             self.start.replace_one();
522             None
523         } else if n == count - 1 {
524             self.start.replace_one();
525             Some(self.end.replace_zero())
526         } else {
527             let nth = self.start.saturating_add(n as u32);
528             self.start = nth.add_one();
529             Some(nth)
530         }
531     }
532 
size_hint(&self) -> (usize, Option<usize>)533     fn size_hint(&self) -> (usize, Option<usize>) {
534         let count = self.count_u64();
535         if count > std::usize::MAX as u64 {
536             (std::usize::MAX, None)
537         } else {
538             let count = count as usize;
539             (count, Some(count))
540         }
541     }
542 }
543 
544 impl Iterator for Ipv6AddrRange {
545     type Item = Ipv6Addr;
546 
next(&mut self) -> Option<Self::Item>547     fn next(&mut self) -> Option<Self::Item> {
548         match self.start.partial_cmp(&self.end) {
549             Some(Less) => {
550                 let next = self.start.add_one();
551                 Some(mem::replace(&mut self.start, next))
552             },
553             Some(Equal) => {
554                 self.end.replace_zero();
555                 Some(self.start.replace_one())
556             },
557             _ => None,
558         }
559     }
560 
561     #[allow(const_err)]
562     #[allow(arithmetic_overflow)]
count(self) -> usize563     fn count(self) -> usize {
564         let count = self.count_u128();
565         // count fits in usize
566         if count <= std::usize::MAX as u128 {
567             count as usize
568         // count does not fit in usize
569         } else {
570             // emulate standard overflow/panic behavior
571             std::usize::MAX + 1 + count as usize
572         }
573     }
574 
last(self) -> Option<Self::Item>575     fn last(self) -> Option<Self::Item> {
576         match self.start.partial_cmp(&self.end) {
577             Some(Less) | Some(Equal) => Some(self.end),
578             _ => None,
579         }
580     }
581 
max(self) -> Option<Self::Item>582     fn max(self) -> Option<Self::Item> {
583         self.last()
584     }
585 
min(self) -> Option<Self::Item>586     fn min(self) -> Option<Self::Item> {
587         match self.start.partial_cmp(&self.end) {
588             Some(Less) | Some(Equal) => Some(self.start),
589             _ => None
590         }
591     }
592 
nth(&mut self, n: usize) -> Option<Self::Item>593     fn nth(&mut self, n: usize) -> Option<Self::Item> {
594         let n = n as u128;
595         if self.can_count_u128() {
596             let count = self.count_u128();
597             if n >= count {
598                 self.end.replace_zero();
599                 self.start.replace_one();
600                 None
601             } else if n == count - 1 {
602                 self.start.replace_one();
603                 Some(self.end.replace_zero())
604             } else {
605                 let nth = self.start.saturating_add(n);
606                 self.start = nth.add_one();
607                 Some(nth)
608             }
609         // count overflows u128; n is 64-bits at most.
610         // therefore, n can never exceed count
611         } else {
612             let nth = self.start.saturating_add(n);
613             self.start = nth.add_one();
614             Some(nth)
615         }
616     }
617 
size_hint(&self) -> (usize, Option<usize>)618     fn size_hint(&self) -> (usize, Option<usize>) {
619         if self.can_count_u128() {
620             let count = self.count_u128();
621             if count > std::usize::MAX as u128 {
622                 (std::usize::MAX, None)
623             } else {
624                 let count = count as usize;
625                 (count, Some(count))
626             }
627         } else {
628             (std::usize::MAX, None)
629         }
630     }
631 }
632 
633 impl DoubleEndedIterator for IpAddrRange {
next_back(&mut self) -> Option<Self::Item>634     fn next_back(&mut self) -> Option<Self::Item> {
635         match *self {
636             IpAddrRange::V4(ref mut a) => a.next_back().map(IpAddr::V4),
637             IpAddrRange::V6(ref mut a) => a.next_back().map(IpAddr::V6),
638         }
639     }
nth_back(&mut self, n: usize) -> Option<Self::Item>640     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
641         match *self {
642             IpAddrRange::V4(ref mut a) => a.nth_back(n).map(IpAddr::V4),
643             IpAddrRange::V6(ref mut a) => a.nth_back(n).map(IpAddr::V6),
644         }
645     }
646 }
647 
648 impl DoubleEndedIterator for Ipv4AddrRange {
next_back(&mut self) -> Option<Self::Item>649     fn next_back(&mut self) -> Option<Self::Item> {
650         match self.start.partial_cmp(&self.end) {
651             Some(Less) => {
652                 let next_back = self.end.sub_one();
653                 Some(mem::replace(&mut self.end, next_back))
654             },
655             Some(Equal) => {
656                 self.end.replace_zero();
657                 Some(self.start.replace_one())
658             },
659             _ => None
660         }
661     }
nth_back(&mut self, n: usize) -> Option<Self::Item>662     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
663         let n = n as u64;
664         let count = self.count_u64();
665         if n >= count {
666             self.end.replace_zero();
667             self.start.replace_one();
668             None
669         } else if n == count - 1 {
670             self.end.replace_zero();
671             Some(self.start.replace_one())
672         } else {
673             let nth_back = self.end.saturating_sub(n as u32);
674             self.end = nth_back.sub_one();
675             Some(nth_back)
676         }
677     }
678 }
679 
680 impl DoubleEndedIterator for Ipv6AddrRange {
next_back(&mut self) -> Option<Self::Item>681     fn next_back(&mut self) -> Option<Self::Item> {
682         match self.start.partial_cmp(&self.end) {
683             Some(Less) => {
684                 let next_back = self.end.sub_one();
685                 Some(mem::replace(&mut self.end, next_back))
686             },
687             Some(Equal) => {
688                 self.end.replace_zero();
689                 Some(self.start.replace_one())
690             },
691             _ => None
692         }
693     }
nth_back(&mut self, n: usize) -> Option<Self::Item>694     fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
695         let n = n as u128;
696         if self.can_count_u128() {
697             let count = self.count_u128();
698             if n >= count {
699                 self.end.replace_zero();
700                 self.start.replace_one();
701                 None
702             }
703             else if n == count - 1 {
704                 self.end.replace_zero();
705                 Some(self.start.replace_one())
706             } else {
707                 let nth_back = self.end.saturating_sub(n);
708                 self.end = nth_back.sub_one();
709                 Some(nth_back)
710             }
711         // count overflows u128; n is 64-bits at most.
712         // therefore, n can never exceed count
713         } else {
714             let nth_back = self.end.saturating_sub(n);
715             self.end = nth_back.sub_one();
716             Some(nth_back)
717         }
718     }
719 }
720 
721 impl FusedIterator for IpAddrRange {}
722 impl FusedIterator for Ipv4AddrRange {}
723 impl FusedIterator for Ipv6AddrRange {}
724 
725 #[cfg(test)]
726 mod tests {
727     use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
728     use std::str::FromStr;
729     use super::*;
730 
731     #[test]
test_ipaddrrange()732     fn test_ipaddrrange() {
733         // Next, Next-Back
734         let i = Ipv4AddrRange::new(
735             Ipv4Addr::from_str("10.0.0.0").unwrap(),
736             Ipv4Addr::from_str("10.0.0.3").unwrap()
737         );
738 
739         assert_eq!(i.collect::<Vec<Ipv4Addr>>(), vec![
740             Ipv4Addr::from_str("10.0.0.0").unwrap(),
741             Ipv4Addr::from_str("10.0.0.1").unwrap(),
742             Ipv4Addr::from_str("10.0.0.2").unwrap(),
743             Ipv4Addr::from_str("10.0.0.3").unwrap(),
744         ]);
745 
746         let mut v = i.collect::<Vec<_>>();
747         v.reverse();
748         assert_eq!(v, i.rev().collect::<Vec<_>>());
749 
750         let i = Ipv4AddrRange::new(
751             Ipv4Addr::from_str("255.255.255.254").unwrap(),
752             Ipv4Addr::from_str("255.255.255.255").unwrap()
753         );
754 
755         assert_eq!(i.collect::<Vec<Ipv4Addr>>(), vec![
756             Ipv4Addr::from_str("255.255.255.254").unwrap(),
757             Ipv4Addr::from_str("255.255.255.255").unwrap(),
758         ]);
759 
760         let i = Ipv6AddrRange::new(
761             Ipv6Addr::from_str("fd00::").unwrap(),
762             Ipv6Addr::from_str("fd00::3").unwrap(),
763         );
764 
765         assert_eq!(i.collect::<Vec<Ipv6Addr>>(), vec![
766             Ipv6Addr::from_str("fd00::").unwrap(),
767             Ipv6Addr::from_str("fd00::1").unwrap(),
768             Ipv6Addr::from_str("fd00::2").unwrap(),
769             Ipv6Addr::from_str("fd00::3").unwrap(),
770         ]);
771 
772         let mut v = i.collect::<Vec<_>>();
773         v.reverse();
774         assert_eq!(v, i.rev().collect::<Vec<_>>());
775 
776         let i = Ipv6AddrRange::new(
777             Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
778             Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
779         );
780 
781         assert_eq!(i.collect::<Vec<Ipv6Addr>>(), vec![
782             Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
783             Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
784         ]);
785 
786         let i = IpAddrRange::from(Ipv4AddrRange::new(
787             Ipv4Addr::from_str("10.0.0.0").unwrap(),
788             Ipv4Addr::from_str("10.0.0.3").unwrap(),
789         ));
790 
791         assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
792             IpAddr::from_str("10.0.0.0").unwrap(),
793             IpAddr::from_str("10.0.0.1").unwrap(),
794             IpAddr::from_str("10.0.0.2").unwrap(),
795             IpAddr::from_str("10.0.0.3").unwrap(),
796         ]);
797 
798         let mut v = i.collect::<Vec<_>>();
799         v.reverse();
800         assert_eq!(v, i.rev().collect::<Vec<_>>());
801 
802         let i = IpAddrRange::from(Ipv4AddrRange::new(
803             Ipv4Addr::from_str("255.255.255.254").unwrap(),
804             Ipv4Addr::from_str("255.255.255.255").unwrap()
805         ));
806 
807         assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
808             IpAddr::from_str("255.255.255.254").unwrap(),
809             IpAddr::from_str("255.255.255.255").unwrap(),
810         ]);
811 
812         let i = IpAddrRange::from(Ipv6AddrRange::new(
813             Ipv6Addr::from_str("fd00::").unwrap(),
814             Ipv6Addr::from_str("fd00::3").unwrap(),
815         ));
816 
817         assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
818             IpAddr::from_str("fd00::").unwrap(),
819             IpAddr::from_str("fd00::1").unwrap(),
820             IpAddr::from_str("fd00::2").unwrap(),
821             IpAddr::from_str("fd00::3").unwrap(),
822         ]);
823 
824         let mut v = i.collect::<Vec<_>>();
825         v.reverse();
826         assert_eq!(v, i.rev().collect::<Vec<_>>());
827 
828         let i = IpAddrRange::from(Ipv6AddrRange::new(
829             Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
830             Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
831         ));
832 
833         assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
834             IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
835             IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
836         ]);
837 
838         // #11 (infinite iterator when start and stop are 0)
839         let zero4 = Ipv4Addr::from_str("0.0.0.0").unwrap();
840         let zero6 = Ipv6Addr::from_str("::").unwrap();
841 
842         let mut i = Ipv4AddrRange::new(zero4, zero4);
843         assert_eq!(Some(zero4), i.next());
844         assert_eq!(None, i.next());
845 
846         let mut i = Ipv6AddrRange::new(zero6, zero6);
847         assert_eq!(Some(zero6), i.next());
848         assert_eq!(None, i.next());
849 
850         // Count
851         let i = Ipv4AddrRange::new(
852             Ipv4Addr::from_str("10.0.0.0").unwrap(),
853             Ipv4Addr::from_str("10.0.0.3").unwrap()
854         );
855         assert_eq!(i.count(), 4);
856 
857         let i = Ipv6AddrRange::new(
858             Ipv6Addr::from_str("fd00::").unwrap(),
859             Ipv6Addr::from_str("fd00::3").unwrap(),
860         );
861         assert_eq!(i.count(), 4);
862 
863         // Size Hint
864         let i = Ipv4AddrRange::new(
865             Ipv4Addr::from_str("10.0.0.0").unwrap(),
866             Ipv4Addr::from_str("10.0.0.3").unwrap()
867         );
868         assert_eq!(i.size_hint(), (4, Some(4)));
869 
870         let i = Ipv6AddrRange::new(
871             Ipv6Addr::from_str("fd00::").unwrap(),
872             Ipv6Addr::from_str("fd00::3").unwrap(),
873         );
874         assert_eq!(i.size_hint(), (4, Some(4)));
875 
876         // Size Hint: a range where size clearly overflows usize
877         let i = Ipv6AddrRange::new(
878             Ipv6Addr::from_str("::").unwrap(),
879             Ipv6Addr::from_str("8000::").unwrap(),
880         );
881         assert_eq!(i.size_hint(), (std::usize::MAX, None));
882 
883         // Min, Max, Last
884         let i = Ipv4AddrRange::new(
885             Ipv4Addr::from_str("10.0.0.0").unwrap(),
886             Ipv4Addr::from_str("10.0.0.3").unwrap()
887         );
888         assert_eq!(Iterator::min(i), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
889         assert_eq!(Iterator::max(i), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
890         assert_eq!(i.last(), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
891 
892         let i = Ipv6AddrRange::new(
893             Ipv6Addr::from_str("fd00::").unwrap(),
894             Ipv6Addr::from_str("fd00::3").unwrap(),
895         );
896         assert_eq!(Iterator::min(i), Some(Ipv6Addr::from_str("fd00::").unwrap()));
897         assert_eq!(Iterator::max(i), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
898         assert_eq!(i.last(), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
899 
900         // Nth
901         let i = Ipv4AddrRange::new(
902             Ipv4Addr::from_str("10.0.0.0").unwrap(),
903             Ipv4Addr::from_str("10.0.0.3").unwrap()
904         );
905         assert_eq!(i.clone().nth(0), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
906         assert_eq!(i.clone().nth(3), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
907         assert_eq!(i.clone().nth(4), None);
908         assert_eq!(i.clone().nth(99), None);
909         let mut i2 = i.clone();
910         assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.1").unwrap()));
911         assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
912         assert_eq!(i2.nth(0), None);
913         let mut i3 = i.clone();
914         assert_eq!(i3.nth(99), None);
915         assert_eq!(i3.next(), None);
916 
917         let i = Ipv6AddrRange::new(
918             Ipv6Addr::from_str("fd00::").unwrap(),
919             Ipv6Addr::from_str("fd00::3").unwrap(),
920         );
921         assert_eq!(i.clone().nth(0), Some(Ipv6Addr::from_str("fd00::").unwrap()));
922         assert_eq!(i.clone().nth(3), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
923         assert_eq!(i.clone().nth(4), None);
924         assert_eq!(i.clone().nth(99), None);
925         let mut i2 = i.clone();
926         assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::1").unwrap()));
927         assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
928         assert_eq!(i2.nth(0), None);
929         let mut i3 = i.clone();
930         assert_eq!(i3.nth(99), None);
931         assert_eq!(i3.next(), None);
932 
933         // Nth Back
934         let i = Ipv4AddrRange::new(
935             Ipv4Addr::from_str("10.0.0.0").unwrap(),
936             Ipv4Addr::from_str("10.0.0.3").unwrap()
937         );
938         assert_eq!(i.clone().nth_back(0), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
939         assert_eq!(i.clone().nth_back(3), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
940         assert_eq!(i.clone().nth_back(4), None);
941         assert_eq!(i.clone().nth_back(99), None);
942         let mut i2 = i.clone();
943         assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.2").unwrap()));
944         assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
945         assert_eq!(i2.nth_back(0), None);
946         let mut i3 = i.clone();
947         assert_eq!(i3.nth_back(99), None);
948         assert_eq!(i3.next(), None);
949 
950         let i = Ipv6AddrRange::new(
951             Ipv6Addr::from_str("fd00::").unwrap(),
952             Ipv6Addr::from_str("fd00::3").unwrap(),
953         );
954         assert_eq!(i.clone().nth_back(0), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
955         assert_eq!(i.clone().nth_back(3), Some(Ipv6Addr::from_str("fd00::").unwrap()));
956         assert_eq!(i.clone().nth_back(4), None);
957         assert_eq!(i.clone().nth_back(99), None);
958         let mut i2 = i.clone();
959         assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::2").unwrap()));
960         assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::").unwrap()));
961         assert_eq!(i2.nth_back(0), None);
962         let mut i3 = i.clone();
963         assert_eq!(i3.nth_back(99), None);
964         assert_eq!(i3.next(), None);
965     }
966 }