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