Skip to main content

netip/
net.rs

1//! IPv4/IPv6 network primitives.
2//!
3//! This module provides types for IP networks by extending the standard
4//! library.
5//!
6//! Unlike most open-source libraries, this module is designed to support
7//! non-contiguous masks.
8
9use core::{
10    convert::TryFrom,
11    error::Error,
12    fmt::{Debug, Display, Formatter},
13    net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr},
14    num::ParseIntError,
15    ops::{Deref, Range},
16    str::FromStr,
17};
18
19const IPV4_ALL_BITS: Ipv4Addr = Ipv4Addr::new(0xff, 0xff, 0xff, 0xff);
20const IPV6_ALL_BITS: Ipv6Addr = Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff);
21
22/// An error that is returned during IP network conversion from address and CIDR
23/// when the CIDR is too large.
24#[derive(Debug, PartialEq, Eq)]
25pub struct CidrOverflowError(u8, u8);
26
27impl Display for CidrOverflowError {
28    fn fmt(&self, fmt: &mut Formatter) -> Result<(), core::fmt::Error> {
29        let Self(from, to) = self;
30        write!(fmt, "invalid CIDR: {from} must be <= {to}")
31    }
32}
33
34/// An error that is returned during IP network parsing.
35#[derive(Debug, PartialEq)]
36pub enum IpNetParseError {
37    /// Expected IP network, but got something malformed instead.
38    ExpectedIpNetwork,
39    /// Expected IP address.
40    ExpectedIpAddr,
41    /// Failed to parse IP address.
42    AddrParseError(AddrParseError),
43    /// Expected CIDR number after `/`.
44    ExpectedIpCidr,
45    /// Failed to parse CIDR mask.
46    CidrParseError(ParseIntError),
47    /// CIDR mask is too large.
48    CidrOverflow(CidrOverflowError),
49}
50
51impl Display for IpNetParseError {
52    fn fmt(&self, fmt: &mut Formatter) -> Result<(), core::fmt::Error> {
53        match self {
54            Self::ExpectedIpNetwork => {
55                write!(fmt, "expected IP network")
56            }
57            Self::ExpectedIpAddr => {
58                write!(fmt, "expected IP address")
59            }
60            Self::AddrParseError(err) => {
61                write!(fmt, "IP address parse error: {err}")
62            }
63            Self::ExpectedIpCidr => {
64                write!(fmt, "expected IP CIDR")
65            }
66            Self::CidrParseError(err) => {
67                write!(fmt, "CIDR parse error: {err}")
68            }
69            Self::CidrOverflow(err) => {
70                write!(fmt, "CIDR overflow: {err}")
71            }
72        }
73    }
74}
75
76impl Error for IpNetParseError {}
77
78impl From<AddrParseError> for IpNetParseError {
79    #[inline]
80    fn from(err: AddrParseError) -> Self {
81        Self::AddrParseError(err)
82    }
83}
84
85impl From<CidrOverflowError> for IpNetParseError {
86    #[inline]
87    fn from(err: CidrOverflowError) -> Self {
88        Self::CidrOverflow(err)
89    }
90}
91
92/// Returns an [`Ipv4Addr`] that will have exact `cidr` leading bits set to
93/// one.
94///
95/// This function is used to construct IP masks for the given network prefix
96/// size.
97#[inline]
98pub fn ipv4_mask_from_cidr(cidr: u8) -> Result<Ipv4Addr, CidrOverflowError> {
99    if cidr <= 32 {
100        let mask = !(u32::MAX.checked_shr(cidr as u32).unwrap_or_default());
101        Ok(mask.into())
102    } else {
103        Err(CidrOverflowError(cidr, 32))
104    }
105}
106
107/// Returns an [`Ipv6Addr`] that will have exact `cidr` leading bits set to
108/// one.
109///
110/// This function is used to construct IP masks for the given network prefix
111/// size.
112#[inline]
113pub fn ipv6_mask_from_cidr(cidr: u8) -> Result<Ipv6Addr, CidrOverflowError> {
114    if cidr <= 128 {
115        let mask = !(u128::MAX.checked_shr(cidr as u32).unwrap_or_default());
116        Ok(mask.into())
117    } else {
118        Err(CidrOverflowError(cidr, 128))
119    }
120}
121
122/// An IP network, either IPv4 or IPv6.
123///
124/// This enum can contain either an [`Ipv4Network`] or an [`Ipv6Network`], see
125/// their respective documentation for more details.
126#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
127pub enum IpNetwork {
128    /// An IPv4 network.
129    V4(Ipv4Network),
130    /// An IPv6 network.
131    V6(Ipv6Network),
132}
133
134impl IpNetwork {
135    /// Parses specified buffer into an extended IP network.
136    ///
137    /// The following formats are supported:
138    ///
139    /// | Format                   | Example                           |
140    /// |--------------------------|-----------------------------------|
141    /// | IPv4                     | `77.88.55.242`                    |
142    /// | IPv4/CIDR                | `77.88.0.0/16`                    |
143    /// | IPv4/IPv4                | `77.88.0.0/255.255.0.0`           |
144    /// | IPv6                     | `2a02:6b8::2:242`                 |
145    /// | IPv6/CIDR                | `2a02:6b8:c00::/40`               |
146    /// | IPv6/IPv6                | `2a02:6b8:c00::/ffff:ffff:ff00::` |
147    ///
148    /// # Note
149    ///
150    /// During construction, the address is normalized using mask, for example
151    /// the network `77.88.55.242/16` becomes `77.88.0.0/16`.
152    ///
153    /// # Examples
154    ///
155    /// ```
156    /// use core::net::{Ipv4Addr, Ipv6Addr};
157    ///
158    /// use netip::{IpNetwork, Ipv4Network, Ipv6Network};
159    ///
160    /// // Here are some examples to show supported formats and the output of this function.
161    ///
162    /// // We can parse IPv4 addresses without explicit `/32` mask.
163    /// assert_eq!(
164    ///     IpNetwork::V4(Ipv4Network::new(
165    ///         Ipv4Addr::new(77, 88, 55, 242),
166    ///         Ipv4Addr::new(255, 255, 255, 255),
167    ///     ),),
168    ///     // IPv4 address.
169    ///     IpNetwork::parse("77.88.55.242").unwrap(),
170    /// );
171    ///
172    /// // When a mask can be represented in common CIDR format, like `/16`,
173    /// // which means "leading 16 bits on the mask is set to one".
174    /// assert_eq!(
175    ///     IpNetwork::V4(Ipv4Network::new(
176    ///         Ipv4Addr::new(77, 88, 0, 0),
177    ///         Ipv4Addr::new(255, 255, 0, 0),
178    ///     ),),
179    ///     // IPv4 CIDR network.
180    ///     IpNetwork::parse("77.88.0.0/16").unwrap(),
181    /// );
182    ///
183    /// // But we can also specify mask explicitly. This is useful when we
184    /// // want non-contiguous mask.
185    /// assert_eq!(
186    ///     IpNetwork::V4(Ipv4Network::new(
187    ///         Ipv4Addr::new(77, 88, 0, 0),
188    ///         Ipv4Addr::new(255, 255, 0, 0),
189    ///     ),),
190    ///     // IPv4 network with explicit mask.
191    ///     IpNetwork::parse("77.88.0.0/255.255.0.0").unwrap(),
192    /// );
193    ///
194    /// // Parse IPv6 addresses without explicit `/128` mask.
195    /// assert_eq!(
196    ///     IpNetwork::V6(Ipv6Network::new(
197    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x2, 0x242),
198    ///         Ipv6Addr::new(
199    ///             0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
200    ///         ),
201    ///     ),),
202    ///     // IPv6 address.
203    ///     IpNetwork::parse("2a02:6b8::2:242").unwrap(),
204    /// );
205    ///
206    /// // CIDR format.
207    /// assert_eq!(
208    ///     IpNetwork::V6(Ipv6Network::new(
209    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
210    ///         Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
211    ///     ),),
212    ///     // IPv6 CIDR network.
213    ///     IpNetwork::parse("2a02:6b8:c00::/40").unwrap(),
214    /// );
215    ///
216    /// // Network with explicit mask (contiguous in this case).
217    /// assert_eq!(
218    ///     IpNetwork::V6(Ipv6Network::new(
219    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
220    ///         Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
221    ///     ),),
222    ///     // IPv6 network with explicit mask.
223    ///     IpNetwork::parse("2a02:6b8:c00::/ffff:ffff:ff00::").unwrap(),
224    /// );
225    ///
226    /// // Network with explicit non-contiguous mask.
227    /// assert_eq!(
228    ///     IpNetwork::V6(Ipv6Network::new(
229    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0),
230    ///         Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0xffff, 0xffff, 0, 0),
231    ///     ),),
232    ///     // The same network as above, but specified explicitly.
233    ///     IpNetwork::parse("2a02:6b8:c00::1234:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap(),
234    /// );
235    /// ```
236    pub fn parse(buf: &str) -> Result<Self, IpNetParseError> {
237        match Ipv4Network::parse(buf) {
238            Ok(net) => {
239                return Ok(Self::V4(net));
240            }
241            Err(IpNetParseError::AddrParseError(..)) => {}
242            Err(err) => {
243                return Err(err);
244            }
245        }
246
247        let net = Ipv6Network::parse(buf)?;
248        Ok(Self::V6(net))
249    }
250
251    /// Checks whether this network is a contiguous, i.e. contains mask with
252    /// only leading bits set to one contiguously.
253    #[inline]
254    pub const fn is_contiguous(&self) -> bool {
255        match self {
256            Self::V4(net) => net.is_contiguous(),
257            Self::V6(net) => net.is_contiguous(),
258        }
259    }
260
261    /// Returns the mask prefix, i.e. the number of leading bits set, if this
262    /// network is a contiguous one, `None` otherwise.
263    ///
264    /// # Examples
265    ///
266    /// ```
267    /// use netip::IpNetwork;
268    ///
269    /// assert_eq!(
270    ///     Some(24),
271    ///     IpNetwork::parse("192.168.1.0/24").unwrap().prefix()
272    /// );
273    ///
274    /// assert_eq!(
275    ///     Some(40),
276    ///     IpNetwork::parse("2a02:6b8::/40").unwrap().prefix()
277    /// );
278    /// assert_eq!(Some(128), IpNetwork::parse("2a02:6b8::1").unwrap().prefix());
279    /// ```
280    #[inline]
281    pub const fn prefix(&self) -> Option<u8> {
282        match self {
283            Self::V4(net) => net.prefix(),
284            Self::V6(net) => net.prefix(),
285        }
286    }
287
288    /// Returns the last address in this IP network.
289    ///
290    /// For contiguous networks, this is the broadcast address.
291    ///
292    /// For non-contiguous networks, this is the highest address within the
293    /// network range defined by the mask.
294    ///
295    /// # Examples
296    ///
297    /// ```
298    /// use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
299    ///
300    /// use netip::IpNetwork;
301    ///
302    /// // IPv4 contiguous network.
303    /// assert_eq!(
304    ///     IpAddr::V4(Ipv4Addr::new(192, 168, 1, 255)),
305    ///     IpNetwork::parse("192.168.1.0/24").unwrap().last_addr()
306    /// );
307    ///
308    /// // IPv6 contiguous network.
309    /// assert_eq!(
310    ///     IpAddr::V6(Ipv6Addr::new(
311    ///         0x2001, 0xdb8, 0x1, 0, 0xffff, 0xffff, 0xffff, 0xffff
312    ///     )),
313    ///     IpNetwork::parse("2001:db8:1::/64").unwrap().last_addr()
314    /// );
315    /// ```
316    #[inline]
317    pub fn last_addr(&self) -> IpAddr {
318        match self {
319            Self::V4(net) => IpAddr::V4(net.last_addr()),
320            Self::V6(net) => IpAddr::V6(net.last_addr()),
321        }
322    }
323}
324
325impl Display for IpNetwork {
326    fn fmt(&self, fmt: &mut Formatter) -> Result<(), core::fmt::Error> {
327        match self {
328            IpNetwork::V4(net) => Display::fmt(&net, fmt),
329            IpNetwork::V6(net) => Display::fmt(&net, fmt),
330        }
331    }
332}
333
334impl From<Ipv4Addr> for IpNetwork {
335    #[inline]
336    fn from(addr: Ipv4Addr) -> Self {
337        // Construct network directly, because no address mutation occurs.
338        Self::V4(Ipv4Network(addr, IPV4_ALL_BITS))
339    }
340}
341
342impl TryFrom<(Ipv4Addr, u8)> for IpNetwork {
343    type Error = CidrOverflowError;
344
345    fn try_from((addr, cidr): (Ipv4Addr, u8)) -> Result<Self, Self::Error> {
346        Ok(Self::V4(Ipv4Network::new(addr, ipv4_mask_from_cidr(cidr)?)))
347    }
348}
349
350impl From<(Ipv4Addr, Ipv4Addr)> for IpNetwork {
351    fn from((addr, mask): (Ipv4Addr, Ipv4Addr)) -> Self {
352        Self::V4(Ipv4Network::new(addr, mask))
353    }
354}
355
356impl From<Ipv4Network> for IpNetwork {
357    #[inline]
358    fn from(net: Ipv4Network) -> Self {
359        Self::V4(net)
360    }
361}
362
363impl From<Ipv6Addr> for IpNetwork {
364    fn from(addr: Ipv6Addr) -> Self {
365        // Construct network directly, because no address mutation occurs.
366        Self::V6(Ipv6Network(addr, IPV6_ALL_BITS))
367    }
368}
369
370impl TryFrom<(Ipv6Addr, u8)> for IpNetwork {
371    type Error = CidrOverflowError;
372
373    fn try_from((addr, cidr): (Ipv6Addr, u8)) -> Result<Self, Self::Error> {
374        Ok(Self::V6(Ipv6Network::new(addr, ipv6_mask_from_cidr(cidr)?)))
375    }
376}
377
378impl From<(Ipv6Addr, Ipv6Addr)> for IpNetwork {
379    fn from((addr, mask): (Ipv6Addr, Ipv6Addr)) -> Self {
380        Self::V6(Ipv6Network::new(addr, mask))
381    }
382}
383
384impl From<Ipv6Network> for IpNetwork {
385    #[inline]
386    fn from(net: Ipv6Network) -> Self {
387        Self::V6(net)
388    }
389}
390
391impl From<IpAddr> for IpNetwork {
392    #[inline]
393    fn from(addr: IpAddr) -> Self {
394        match addr {
395            IpAddr::V4(addr) => Self::from(addr),
396            IpAddr::V6(addr) => Self::from(addr),
397        }
398    }
399}
400
401impl FromStr for IpNetwork {
402    type Err = IpNetParseError;
403
404    #[inline]
405    fn from_str(s: &str) -> Result<Self, Self::Err> {
406        IpNetwork::parse(s)
407    }
408}
409
410/// Represents the network range in which IP addresses are IPv4.
411///
412/// IPv4 networks are defined as pair of two [`Ipv4Addr`]. One for IP address
413/// and the second one - for mask.
414///
415/// See [`IpNetwork`] for a type encompassing both IPv4 and IPv6 networks.
416///
417/// # Note
418///
419/// An IPv4 network represents a range of IPv4 addresses. The most common way to
420/// represent an IP network is through CIDR notation. See [IETF RFC 4632] for
421/// CIDR notation.
422///
423/// An example of such notation is `77.152.124.0/24`.
424///
425/// In CIDR notation, a prefix is shown as a 4-octet quantity, just like a
426/// traditional IPv4 address or network number, followed by the "/" (slash)
427/// character, followed by a decimal value between 0 and 32 that describes the
428/// number of significant bits.
429///
430/// Here, the "/24" indicates that the mask to extract the network portion of
431/// the prefix is a 32-bit value where the most significant 24 bits are
432/// ones and the least significant 8 bits are zeros.
433///
434/// The other way to represent the network above is to use explicit notation,
435/// such as `77.152.124.0/255.255.255.0`.
436///
437/// However, this struct supports non-contiguous masks, i.e. masks with
438/// non-contiguous bits set to one, like `77.152.0.55/255.255.0.255`.
439///
440/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
441#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
442pub struct Ipv4Network(Ipv4Addr, Ipv4Addr);
443
444impl Ipv4Network {
445    /// An IPv4 network representing the unspecified network: `0.0.0.0/0`
446    ///
447    /// # Examples
448    ///
449    /// ```
450    /// use core::net::Ipv4Addr;
451    ///
452    /// use netip::Ipv4Network;
453    ///
454    /// let net = Ipv4Network::UNSPECIFIED;
455    /// assert_eq!(
456    ///     Ipv4Network::new(Ipv4Addr::new(0, 0, 0, 0), Ipv4Addr::new(0, 0, 0, 0)),
457    ///     net
458    /// );
459    /// ```
460    pub const UNSPECIFIED: Self = Self(Ipv4Addr::UNSPECIFIED, Ipv4Addr::UNSPECIFIED);
461
462    /// Initializes a new [`Ipv4Network`] using specified address and mask.
463    ///
464    /// During construction the address is normalized using mask, i.e. in case
465    /// of `192.168.1.1/255.255.255.0` the result will be transformed
466    /// to `192.168.1.0/255.255.255.0`.
467    ///
468    /// # Examples
469    ///
470    /// ```
471    /// use core::net::Ipv4Addr;
472    ///
473    /// use netip::Ipv4Network;
474    ///
475    /// let net = Ipv4Network::new(
476    ///     Ipv4Addr::new(192, 168, 1, 1),
477    ///     Ipv4Addr::new(255, 255, 255, 0),
478    /// );
479    ///
480    /// assert_eq!(Ipv4Addr::new(192, 168, 1, 0), *net.addr());
481    /// assert_eq!(Ipv4Addr::new(255, 255, 255, 0), *net.mask());
482    /// ```
483    #[inline]
484    pub const fn new(addr: Ipv4Addr, mask: Ipv4Addr) -> Self {
485        let addr = u32::from_be_bytes(addr.octets()) & u32::from_be_bytes(mask.octets());
486
487        Self(Ipv4Addr::from_bits(addr), mask)
488    }
489
490    /// Parses the specified buffer into an IPv4 network.
491    ///
492    /// The following formats are supported:
493    /// - IPv4
494    /// - IPv4/CIDR
495    /// - IPv4/IPv4
496    ///
497    /// # Examples
498    ///
499    /// ```
500    /// use core::net::Ipv4Addr;
501    ///
502    /// use netip::Ipv4Network;
503    ///
504    /// let expected = Ipv4Network::new(
505    ///     Ipv4Addr::new(192, 168, 1, 1),
506    ///     Ipv4Addr::new(255, 255, 255, 255),
507    /// );
508    ///
509    /// assert_eq!(expected, Ipv4Network::parse("192.168.1.1").unwrap());
510    /// assert_eq!(expected, Ipv4Network::parse("192.168.1.1/32").unwrap());
511    /// assert_eq!(
512    ///     expected,
513    ///     Ipv4Network::parse("192.168.1.1/255.255.255.255").unwrap()
514    /// );
515    /// ```
516    pub fn parse(buf: &str) -> Result<Self, IpNetParseError> {
517        let mut parts = buf.splitn(2, '/');
518        let addr = parts.next().ok_or(IpNetParseError::ExpectedIpAddr)?;
519        let addr: Ipv4Addr = addr.parse()?;
520        match parts.next() {
521            Some(mask) => match mask.parse::<u8>() {
522                Ok(cidr) => Ok(Self::try_from((addr, cidr))?),
523                Err(..) => {
524                    // Maybe explicit mask.
525                    let mask: Ipv4Addr = mask.parse()?;
526                    Ok(Self::new(addr, mask))
527                }
528            },
529            None => Ok(Self(addr, IPV4_ALL_BITS)),
530        }
531    }
532
533    /// Returns the IP address of this IPv4 network.
534    #[inline]
535    pub const fn addr(&self) -> &Ipv4Addr {
536        match self {
537            Self(addr, ..) => addr,
538        }
539    }
540
541    /// Returns the IP mask of this IPv4 network.
542    #[inline]
543    pub const fn mask(&self) -> &Ipv4Addr {
544        match self {
545            Self(.., mask) => mask,
546        }
547    }
548
549    /// Converts a pair of IPv4 address and mask represented as a pair of host
550    /// byte order `u32` into an IPv4 network.
551    ///
552    /// # Note
553    ///
554    /// During conversion, the address is normalized using mask.
555    ///
556    /// # Examples
557    ///
558    /// ```
559    /// use core::net::Ipv4Addr;
560    ///
561    /// use netip::Ipv4Network;
562    ///
563    /// let expected = Ipv4Network::new(
564    ///     Ipv4Addr::new(192, 168, 1, 0),
565    ///     Ipv4Addr::new(255, 255, 255, 0),
566    /// );
567    ///
568    /// assert_eq!(expected, Ipv4Network::from_bits(3232235776, 4294967040));
569    /// ```
570    #[inline]
571    pub const fn from_bits(addr: u32, mask: u32) -> Self {
572        Self::new(Ipv4Addr::from_bits(addr), Ipv4Addr::from_bits(mask))
573    }
574
575    /// Converts this IPv4 network's address and mask into pair of host byte
576    /// order `u32`.
577    ///
578    /// # Examples
579    ///
580    /// ```
581    /// use core::net::Ipv4Addr;
582    ///
583    /// use netip::Ipv4Network;
584    ///
585    /// let net = Ipv4Network::new(
586    ///     Ipv4Addr::new(192, 168, 1, 0),
587    ///     Ipv4Addr::new(255, 255, 255, 0),
588    /// );
589    /// assert_eq!((3232235776, 4294967040), net.to_bits());
590    /// ```
591    #[inline]
592    pub const fn to_bits(&self) -> (u32, u32) {
593        match self {
594            Self(addr, mask) => (u32::from_be_bytes(addr.octets()), u32::from_be_bytes(mask.octets())),
595        }
596    }
597
598    /// Returns `true` if this IPv4 network fully contains the specified one.
599    #[inline]
600    pub const fn contains(&self, other: &Ipv4Network) -> bool {
601        let (a1, m1) = self.to_bits();
602        let (a2, m2) = other.to_bits();
603
604        (a2 & m1 == a1) && (m2 & m1 == m1)
605    }
606
607    /// Checks whether this network is a contiguous, i.e. contains mask with
608    /// only leading bits set to one contiguously.
609    ///
610    /// # Examples
611    ///
612    /// ```
613    /// use netip::Ipv4Network;
614    ///
615    /// assert!(Ipv4Network::parse("0.0.0.0/0").unwrap().is_contiguous());
616    /// assert!(
617    ///     Ipv4Network::parse("213.180.192.0/19")
618    ///         .unwrap()
619    ///         .is_contiguous()
620    /// );
621    ///
622    /// assert!(
623    ///     !Ipv4Network::parse("213.180.0.192/255.255.0.255")
624    ///         .unwrap()
625    ///         .is_contiguous()
626    /// );
627    /// ```
628    #[inline]
629    pub const fn is_contiguous(&self) -> bool {
630        let mask = u32::from_be_bytes(self.mask().octets());
631        mask.count_zeros() == mask.trailing_zeros()
632    }
633
634    /// Returns the mask prefix, i.e. the number of leading bits set, if this
635    /// network is a contiguous one, `None` otherwise.
636    ///
637    /// # Examples
638    ///
639    /// ```
640    /// use core::net::Ipv4Addr;
641    ///
642    /// use netip::Ipv4Network;
643    ///
644    /// assert_eq!(
645    ///     Some(24),
646    ///     Ipv4Network::new(
647    ///         Ipv4Addr::new(192, 168, 1, 0),
648    ///         Ipv4Addr::new(255, 255, 255, 0)
649    ///     )
650    ///     .prefix()
651    /// );
652    /// assert_eq!(
653    ///     Some(32),
654    ///     Ipv4Network::new(
655    ///         Ipv4Addr::new(192, 168, 1, 1),
656    ///         Ipv4Addr::new(255, 255, 255, 255)
657    ///     )
658    ///     .prefix()
659    /// );
660    ///
661    /// assert_eq!(
662    ///     None,
663    ///     Ipv4Network::new(Ipv4Addr::new(192, 0, 1, 0), Ipv4Addr::new(255, 0, 255, 0)).prefix()
664    /// );
665    /// ```
666    #[inline]
667    pub const fn prefix(&self) -> Option<u8> {
668        let mask = u32::from_be_bytes(self.mask().octets());
669        let ones = mask.leading_ones();
670
671        if mask.count_ones() == ones {
672            Some(ones as u8)
673        } else {
674            None
675        }
676    }
677
678    /// Converts this network to a contiguous network by clearing mask bits set
679    /// to one after the first zero bit.
680    ///
681    /// # Examples
682    ///
683    /// ```
684    /// use core::net::Ipv4Addr;
685    ///
686    /// use netip::Ipv4Network;
687    ///
688    /// let net = Ipv4Network::new(
689    ///     Ipv4Addr::new(192, 168, 0, 1),
690    ///     Ipv4Addr::new(255, 255, 0, 255),
691    /// );
692    /// let expected = Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 0), Ipv4Addr::new(255, 255, 0, 0));
693    ///
694    /// assert_eq!(expected, net.to_contiguous());
695    /// ```
696    pub fn to_contiguous(&self) -> Self {
697        let (addr, mask) = self.to_bits();
698
699        Self::try_from((addr.into(), mask.leading_ones() as u8)).expect("CIDR must be in range [0; 32]")
700    }
701
702    /// Calculates and returns the [`Ipv4Network`], which will be a supernet,
703    /// i.e. the shortest common network both for this network and the
704    /// specified ones.
705    ///
706    /// # Note
707    ///
708    /// This function works fine for both contiguous and non-contiguous
709    /// networks.
710    ///
711    /// Use [`Ipv4Network::to_contiguous`] method if you need to convert the
712    /// output network.
713    ///
714    /// # Examples
715    ///
716    /// ```
717    /// use core::net::Ipv4Addr;
718    ///
719    /// use netip::Ipv4Network;
720    ///
721    /// let net0 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 25)).unwrap();
722    /// let net1 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 128), 25)).unwrap();
723    ///
724    /// assert_eq!(
725    ///     Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 24)).unwrap(),
726    ///     net0.supernet_for(&[net1])
727    /// );
728    /// ```
729    pub fn supernet_for(&self, nets: &[Ipv4Network]) -> Ipv4Network {
730        let (addr, mask) = self.to_bits();
731
732        let mut min = addr;
733        let mut max = addr;
734
735        for net in nets {
736            let (addr, ..) = net.to_bits();
737            if addr < min {
738                min = addr;
739            } else if addr > max {
740                max = addr;
741            }
742        }
743
744        let common_addr = min ^ max;
745        let common_addr_len = common_addr.leading_zeros();
746        let mask = mask & !(u32::MAX.checked_shr(common_addr_len).unwrap_or_default());
747
748        Self::new(addr.into(), mask.into())
749    }
750
751    /// Converts this network to an IPv4-mapped IPv6 network.
752    ///
753    /// # Examples
754    ///
755    /// ```
756    /// use core::net::{Ipv4Addr, Ipv6Addr};
757    ///
758    /// use netip::{Ipv4Network, Ipv6Network};
759    ///
760    /// let net = Ipv4Network::new(
761    ///     Ipv4Addr::new(192, 168, 1, 42),
762    ///     Ipv4Addr::new(255, 255, 252, 0),
763    /// );
764    /// let expected =
765    ///     Ipv6Network::parse("::ffff:c0a8:0/ffff:ffff:ffff:ffff:ffff:ffff:ffff:fc00").unwrap();
766    /// assert_eq!(expected, net.to_ipv6_mapped());
767    /// ```
768    #[inline]
769    pub const fn to_ipv6_mapped(&self) -> Ipv6Network {
770        match self {
771            Ipv4Network(addr, mask) => {
772                let [a, b, c, d] = mask.octets();
773                let [a, b, c, d]: [u16; 4] = [a as u16, b as u16, c as u16, d as u16];
774                Ipv6Network(
775                    addr.to_ipv6_mapped(),
776                    Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, a << 8 | b, c << 8 | d),
777                )
778            }
779        }
780    }
781
782    /// Returns the last address in this IPv4 network.
783    ///
784    /// For contiguous networks, this is the broadcast address.
785    ///
786    /// For non-contiguous networks, this is the highest address within the
787    /// network range defined by the mask.
788    ///
789    /// # Examples
790    ///
791    /// ```
792    /// use core::net::Ipv4Addr;
793    ///
794    /// use netip::Ipv4Network;
795    ///
796    /// // Contiguous network.
797    /// let net = Ipv4Network::new(
798    ///     Ipv4Addr::new(192, 168, 1, 0),
799    ///     Ipv4Addr::new(255, 255, 255, 0),
800    /// );
801    /// assert_eq!(Ipv4Addr::new(192, 168, 1, 255), net.last_addr());
802    ///
803    /// // Single address network.
804    /// let net = Ipv4Network::new(
805    ///     Ipv4Addr::new(10, 0, 0, 1),
806    ///     Ipv4Addr::new(255, 255, 255, 255),
807    /// );
808    /// assert_eq!(Ipv4Addr::new(10, 0, 0, 1), net.last_addr());
809    ///
810    /// // Non-contiguous network.
811    /// let net = Ipv4Network::new(
812    ///     Ipv4Addr::new(192, 168, 0, 1),
813    ///     Ipv4Addr::new(255, 255, 0, 255),
814    /// );
815    /// assert_eq!(Ipv4Addr::new(192, 168, 255, 1), net.last_addr());
816    /// ```
817    ///
818    /// # Formal Proof of Correctness
819    ///
820    /// ## Given
821    /// - Network address: `addr`.
822    /// - Network mask: `mask` (may be non-contiguous).
823    /// - Algorithm: `last_addr = addr | !mask`.
824    ///
825    /// ## Definitions
826    /// Let:
827    /// - `N = addr & mask` (network address with host bits zeroed).
828    /// - `H = !mask` (bitmask of host positions).
829    /// - Address `X` belongs to the network iff `(X & mask) = N`.
830    ///
831    /// ## Lemma 1: Contiguous Mask Case
832    ///
833    /// For contiguous masks (standard CIDR), the algorithm is well-established:
834    /// - ` mask` format: `111...100...0`.
835    /// - `!mask` format: `000...011...1`.
836    /// - `addr | !mask` sets all host bits to 1, yielding the broadcast
837    ///   address.
838    ///
839    /// ## Lemma 2: Generalization to Non-Contiguous Masks
840    ///
841    /// **Theorem**: `X = addr | !mask` is the maximum address satisfying `(X &
842    /// mask) = N`.
843    ///
844    /// ### Proof:
845    ///
846    /// 1. **Membership**: ```(X & mask) = ((addr | !mask) & mask) = (addr &
847    ///    mask) | (!mask & mask) = N | 0 = N ```
848    ///
849    ///    Thus, `X` belongs to the network.
850    ///
851    /// 2. **Maximality**:
852    ///    - Any network address can be expressed as `X = N | H_val` where
853    ///      `H_val` has ones only in host positions
854    ///    - The maximum possible `H_val` is `H = !mask` (all host bits set to
855    ///      1)
856    ///    - Thus `X_max = N | H = (addr & mask) | !mask`
857    ///
858    /// 3. **Simplification**: since `addr & mask` zeros all host bits: ```
859    ///    (addr & mask) | !mask = addr | !mask ```
860    ///    - For mask bits = 1: `addr_bit | 0 = addr_bit`
861    ///    - For mask bits = 0: `0 | 1 = 1`
862    ///
863    /// ## Edge Case Verification
864    ///
865    /// - **Full mask** (255.255.255.255): `last_addr = addr | 0 = addr` (single
866    ///   address network).
867    ///
868    /// - **Zero mask** (0.0.0.0): `last_addr = addr | 0xFFFFFFFF =
869    ///   255.255.255.255` (entire address space).
870    ///
871    /// - **Non-contiguous mask** (e.g., 255.0.255.0): Correctly sets all host
872    ///   bits to 1 while preserving network bits.
873    ///
874    /// ## ∴
875    ///
876    /// The algorithm `addr | !mask` correctly computes the maximum address in
877    /// any IPv4 network, including those with non-contiguous masks.
878    #[inline]
879    pub const fn last_addr(&self) -> Ipv4Addr {
880        let (addr, mask) = self.to_bits();
881        Ipv4Addr::from_bits(addr | !mask)
882    }
883
884    /// Returns a double-ended iterator over every address in this network.
885    ///
886    /// The iterator yields addresses in **host-index order**: the *k* host
887    /// positions (bits where the mask is zero) are filled with successive
888    /// values `0 ..= 2^k - 1`, starting from the least-significant host bit.
889    ///
890    /// For a standard (contiguous) CIDR mask this is equivalent to ascending
891    /// numeric order from [`addr()`](Ipv4Network::addr) to
892    /// [`last_addr()`](Ipv4Network::last_addr).
893    ///
894    /// For a non-contiguous mask the numeric order of the produced addresses
895    /// may differ from the iteration order.
896    ///
897    /// The iterator implements [`DoubleEndedIterator`] and
898    /// [`ExactSizeIterator`].
899    ///
900    /// # Examples
901    ///
902    /// ```
903    /// use core::net::Ipv4Addr;
904    ///
905    /// use netip::Ipv4Network;
906    ///
907    /// let net = Ipv4Network::parse("192.168.1.0/24").unwrap();
908    /// let mut addrs = net.addrs();
909    ///
910    /// assert_eq!(256, addrs.len());
911    ///
912    /// assert_eq!(Some(Ipv4Addr::new(192, 168, 1, 0)), addrs.next());
913    /// assert_eq!(Some(Ipv4Addr::new(192, 168, 1, 1)), addrs.next());
914    /// assert_eq!(Some(Ipv4Addr::new(192, 168, 1, 2)), addrs.next());
915    ///
916    /// // It is important to note that both back and forth work on the same
917    /// // range, and do not cross: iteration is over when they meet in the
918    /// // middle.
919    ///
920    /// assert_eq!(Some(Ipv4Addr::new(192, 168, 1, 255)), addrs.next_back());
921    /// assert_eq!(Some(Ipv4Addr::new(192, 168, 1, 254)), addrs.next_back());
922    ///
923    /// assert_eq!(Some(Ipv4Addr::new(192, 168, 1, 3)), addrs.next());
924    /// ```
925    #[inline]
926    pub fn addrs(self) -> Ipv4NetworkAddrs {
927        let (addr, mask) = self.to_bits();
928        let host_bits = (!mask).count_ones();
929        let back = u32::MAX.checked_shr(32 - host_bits).unwrap_or(0);
930
931        Ipv4NetworkAddrs { base: addr, mask, front: 0, back }
932    }
933}
934
935impl Display for Ipv4Network {
936    /// Formats this IPv4 network using the given formatter.
937    ///
938    /// The idea is to format using **the most compact** representation, except
939    /// for non-contiguous networks, which are formatted explicitly.
940    fn fmt(&self, fmt: &mut Formatter) -> Result<(), core::fmt::Error> {
941        match self {
942            Self(addr, mask) => {
943                match self.prefix() {
944                    Some(prefix) => fmt.write_fmt(format_args!("{}/{}", addr, prefix)),
945                    None => {
946                        // This is a non-contiguous network, expand the mask.
947                        fmt.write_fmt(format_args!("{}/{}", addr, mask))
948                    }
949                }
950            }
951        }
952    }
953}
954
955impl From<Ipv4Addr> for Ipv4Network {
956    fn from(addr: Ipv4Addr) -> Self {
957        Self(addr, IPV4_ALL_BITS)
958    }
959}
960
961impl TryFrom<(Ipv4Addr, u8)> for Ipv4Network {
962    type Error = CidrOverflowError;
963
964    fn try_from((addr, cidr): (Ipv4Addr, u8)) -> Result<Self, Self::Error> {
965        let mask = ipv4_mask_from_cidr(cidr)?;
966        Ok(Self::new(addr, mask))
967    }
968}
969
970impl FromStr for Ipv4Network {
971    type Err = IpNetParseError;
972
973    #[inline]
974    fn from_str(s: &str) -> Result<Self, Self::Err> {
975        Ipv4Network::parse(s)
976    }
977}
978
979impl AsRef<Ipv4Network> for Ipv4Network {
980    #[inline]
981    fn as_ref(&self) -> &Ipv4Network {
982        self
983    }
984}
985
986/// Bidirectional iterator over [`Ipv4Addr`] in an [`Ipv4Network`].
987///
988/// Created by [`Ipv4Network::addrs`].
989///
990/// Yields addresses in host-index order: the *k* host positions (bits where the
991/// mask is zero) are filled with successive values `0 ..= 2^k - 1`, starting
992/// from the least-significant host bit.
993///
994/// When the iterator is exhausted it enters a sentinel state where
995/// `front > back`, so every subsequent call to [`next`](Iterator::next) or
996/// [`next_back`](DoubleEndedIterator::next_back) returns [`None`].
997#[derive(Debug, Clone, Copy, PartialEq, Eq)]
998pub struct Ipv4NetworkAddrs {
999    base: u32,
1000    mask: u32,
1001    front: u32,
1002    back: u32,
1003}
1004
1005impl Iterator for Ipv4NetworkAddrs {
1006    type Item = Ipv4Addr;
1007
1008    #[inline]
1009    fn next(&mut self) -> Option<Self::Item> {
1010        if self.front > self.back {
1011            return None;
1012        }
1013
1014        let index = self.front;
1015        self.front = self.front.wrapping_add(1);
1016
1017        // Wrap-around means front was u32::MAX — only possible for a /0
1018        // network.
1019        //
1020        // Enter sentinel state so the next call returns None.
1021        if self.front == 0 {
1022            self.front = 1;
1023            self.back = 0;
1024        }
1025
1026        Some(Ipv4Addr::from_bits(ipv4_bits_from_host_index(
1027            self.base, self.mask, index,
1028        )))
1029    }
1030
1031    #[inline]
1032    fn size_hint(&self) -> (usize, Option<usize>) {
1033        if self.front > self.back {
1034            return (0, Some(0));
1035        }
1036
1037        let rem = self.back.wrapping_sub(self.front).wrapping_add(1);
1038
1039        if rem == 0 {
1040            (usize::MAX, None)
1041        } else {
1042            let n = rem as usize;
1043            (n, Some(n))
1044        }
1045    }
1046}
1047
1048impl DoubleEndedIterator for Ipv4NetworkAddrs {
1049    #[inline]
1050    fn next_back(&mut self) -> Option<Self::Item> {
1051        if self.front > self.back {
1052            return None;
1053        }
1054
1055        let index = self.back;
1056
1057        if self.front == self.back {
1058            self.front = 1;
1059            self.back = 0;
1060        } else {
1061            self.back = self.back.wrapping_sub(1);
1062        }
1063
1064        Some(Ipv4Addr::from_bits(ipv4_bits_from_host_index(
1065            self.base, self.mask, index,
1066        )))
1067    }
1068}
1069
1070impl ExactSizeIterator for Ipv4NetworkAddrs {
1071    #[inline]
1072    fn len(&self) -> usize {
1073        if self.front > self.back {
1074            return 0;
1075        }
1076
1077        let rem = self.back.wrapping_sub(self.front).wrapping_add(1);
1078
1079        if rem == 0 { 1usize << 32 } else { rem as usize }
1080    }
1081}
1082
1083#[inline]
1084const fn ipv4_bits_from_host_index(base: u32, mask: u32, index: u32) -> u32 {
1085    let host_mask = !mask;
1086
1087    // For contiguous masks (trailing ones only) pdep is identity.
1088    if host_mask & host_mask.wrapping_add(1) == 0 {
1089        base | index
1090    } else {
1091        base | pdep_u32(index, host_mask)
1092    }
1093}
1094
1095#[inline]
1096const fn pdep_u32(mut src: u32, mut mask: u32) -> u32 {
1097    let mut out = 0u32;
1098
1099    while mask != 0 {
1100        let t = mask & mask.wrapping_neg();
1101
1102        if src & 1 != 0 {
1103            out |= t;
1104        }
1105
1106        src >>= 1;
1107        mask ^= t;
1108    }
1109
1110    out
1111}
1112
1113/// Represents the network range in which IP addresses are IPv6.
1114///
1115/// IPv6 networks are defined as pair of two [`Ipv6Addr`]. One for IP address
1116/// and the second one - for mask.
1117///
1118/// See [`IpNetwork`] for a type encompassing both IPv4 and IPv6 networks.
1119///
1120/// # Note
1121///
1122/// An IPv6 network represents a range of IPv6 addresses. The most common way to
1123/// represent an IP network is through CIDR notation. See [IETF RFC 4632] for
1124/// CIDR notation.
1125///
1126/// An example of such notation is `2a02:6b8:c00::/40`.
1127///
1128/// In CIDR notation, a prefix is shown as a 8-hextet quantity, just like a
1129/// traditional IPv6 address or network number, followed by the "/" (slash)
1130/// character, followed by a decimal value between 0 and 128 that describes the
1131/// number of significant bits.
1132///
1133/// Here, the "/40" indicates that the mask to extract the network portion of
1134/// the prefix is a 128-bit value where the most significant 40 bits are
1135/// ones and the least significant 88 bits are zeros.
1136///
1137/// The other way to represent the network above is to use explicit notation,
1138/// such as `2a02:6b8:c00::/ffff:ffff:ff00::`.
1139///
1140/// However, this struct supports non-contiguous masks, i.e. masks with
1141/// non-contiguous bits set to one, like the following one:
1142/// `2a02:6b8:c00::1234:0:0/ffff:ffff:ff00::ffff:ffff:0:0`.
1143///
1144/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
1145#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1146pub struct Ipv6Network(Ipv6Addr, Ipv6Addr);
1147
1148impl Ipv6Network {
1149    /// An IPv6 network representing the unspecified network: `::/0`
1150    ///
1151    /// # Examples
1152    ///
1153    /// ```
1154    /// use core::net::Ipv6Addr;
1155    ///
1156    /// use netip::Ipv6Network;
1157    ///
1158    /// let net = Ipv6Network::UNSPECIFIED;
1159    /// assert_eq!(
1160    ///     Ipv6Network::new(
1161    ///         Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
1162    ///         Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)
1163    ///     ),
1164    ///     net
1165    /// );
1166    /// ```
1167    pub const UNSPECIFIED: Self = Self(Ipv6Addr::UNSPECIFIED, Ipv6Addr::UNSPECIFIED);
1168
1169    /// Initializes a new [`Ipv6Network`] using specified address and mask.
1170    ///
1171    /// During construction, the address is normalized using mask.
1172    #[inline]
1173    pub const fn new(addr: Ipv6Addr, mask: Ipv6Addr) -> Self {
1174        let addr = u128::from_be_bytes(addr.octets()) & u128::from_be_bytes(mask.octets());
1175
1176        Self(Ipv6Addr::from_bits(addr), mask)
1177    }
1178
1179    /// Parses the specified buffer into an IPv6 network.
1180    ///
1181    /// The following formats are supported:
1182    ///
1183    /// | Format                   | Example                           |
1184    /// |--------------------------|-----------------------------------|
1185    /// | IPv6                     | `2a02:6b8::2:242`                 |
1186    /// | IPv6/CIDR                | `2a02:6b8:c00::/40`               |
1187    /// | IPv6/IPv6                | `2a02:6b8:c00::/ffff:ffff:ff00::` |
1188    ///
1189    /// # Examples
1190    ///
1191    /// ```
1192    /// use core::net::Ipv6Addr;
1193    ///
1194    /// use netip::Ipv6Network;
1195    ///
1196    /// // Here are some examples to show supported formats and the output of this function.
1197    ///
1198    /// // Parse IPv6 addresses without explicit `/128` mask.
1199    /// assert_eq!(
1200    ///     Ipv6Network::new(
1201    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x2, 0x242),
1202    ///         Ipv6Addr::new(
1203    ///             0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
1204    ///         ),
1205    ///     ),
1206    ///     // IPv6 address.
1207    ///     Ipv6Network::parse("2a02:6b8::2:242").unwrap(),
1208    /// );
1209    ///
1210    /// // CIDR format.
1211    /// assert_eq!(
1212    ///     Ipv6Network::new(
1213    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
1214    ///         Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
1215    ///     ),
1216    ///     // IPv6 CIDR network.
1217    ///     Ipv6Network::parse("2a02:6b8:c00::/40").unwrap(),
1218    /// );
1219    ///
1220    /// // Network with explicit mask (contiguous in this case).
1221    /// assert_eq!(
1222    ///     Ipv6Network::new(
1223    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
1224    ///         Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
1225    ///     ),
1226    ///     // IPv6 network with explicit mask.
1227    ///     Ipv6Network::parse("2a02:6b8:c00::/ffff:ffff:ff00::").unwrap(),
1228    /// );
1229    ///
1230    /// // Network with explicit non-contiguous mask.
1231    /// assert_eq!(
1232    ///     Ipv6Network::new(
1233    ///         Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0),
1234    ///         Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0xffff, 0xffff, 0, 0),
1235    ///     ),
1236    ///     // The same network as above, but specified explicitly.
1237    ///     Ipv6Network::parse("2a02:6b8:c00::1234:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap(),
1238    /// );
1239    /// ```
1240    pub fn parse(buf: &str) -> Result<Self, IpNetParseError> {
1241        let mut parts = buf.splitn(2, '/');
1242        let addr = parts.next().ok_or(IpNetParseError::ExpectedIpNetwork)?;
1243        let addr: Ipv6Addr = addr.parse()?;
1244        match parts.next() {
1245            Some(mask) => match mask.parse::<u8>() {
1246                Ok(mask) => Ok(Self::try_from((addr, mask))?),
1247                Err(..) => {
1248                    // Maybe explicit mask.
1249                    let mask: Ipv6Addr = mask.parse()?;
1250                    Ok(Self::new(addr, mask))
1251                }
1252            },
1253            None => Ok(Self(addr, IPV6_ALL_BITS)),
1254        }
1255    }
1256
1257    /// Returns the IP address of this IPv6 network.
1258    #[inline]
1259    pub const fn addr(&self) -> &Ipv6Addr {
1260        match self {
1261            Ipv6Network(addr, ..) => addr,
1262        }
1263    }
1264
1265    /// Returns the IP mask of this IPv6 network.
1266    #[inline]
1267    pub const fn mask(&self) -> &Ipv6Addr {
1268        match self {
1269            Ipv6Network(.., mask) => mask,
1270        }
1271    }
1272
1273    /// Converts a pair of IPv6 address and mask represented as a pair of host
1274    /// byte order `u128` into an IPv6 network.
1275    ///
1276    /// # Note
1277    ///
1278    /// During conversion, the address is normalized using mask.
1279    ///
1280    /// # Examples
1281    ///
1282    /// ```
1283    /// use core::net::Ipv6Addr;
1284    ///
1285    /// use netip::Ipv6Network;
1286    ///
1287    /// let addr = 0x2a0206b8b0817228000000000001000b_u128;
1288    /// let mask = 0xffffffffffffffffffffffffffffffff_u128;
1289    ///
1290    /// let expected = Ipv6Network::new(
1291    ///     Ipv6Addr::new(
1292    ///         0x2a02, 0x06b8, 0xb081, 0x7228, 0x0000, 0x0000, 0x0001, 0x000b,
1293    ///     ),
1294    ///     Ipv6Addr::new(
1295    ///         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1296    ///     ),
1297    /// );
1298    ///
1299    /// assert_eq!(expected, Ipv6Network::from_bits(addr, mask));
1300    /// ```
1301    #[inline]
1302    pub const fn from_bits(addr: u128, mask: u128) -> Self {
1303        Self::new(Ipv6Addr::from_bits(addr), Ipv6Addr::from_bits(mask))
1304    }
1305
1306    /// Converts this IPv6 network's address and mask into pair of host byte
1307    /// order `u128`.
1308    ///
1309    /// # Examples
1310    ///
1311    /// ```
1312    /// use core::net::Ipv6Addr;
1313    ///
1314    /// use netip::Ipv6Network;
1315    ///
1316    /// let net = Ipv6Network::new(
1317    ///     Ipv6Addr::new(
1318    ///         0x2a02, 0x06b8, 0xb081, 0x7228, 0x0000, 0x0000, 0x0001, 0x000b,
1319    ///     ),
1320    ///     Ipv6Addr::new(
1321    ///         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1322    ///     ),
1323    /// );
1324    /// assert_eq!(
1325    ///     (
1326    ///         0x2a0206b8b0817228000000000001000b_u128,
1327    ///         0xffffffffffffffffffffffffffffffff_u128,
1328    ///     ),
1329    ///     net.to_bits(),
1330    /// );
1331    /// ```
1332    #[inline]
1333    pub const fn to_bits(&self) -> (u128, u128) {
1334        match self {
1335            Self(addr, mask) => (u128::from_be_bytes(addr.octets()), u128::from_be_bytes(mask.octets())),
1336        }
1337    }
1338
1339    /// Returns `true` if this IPv6 network fully contains the specified one.
1340    #[inline]
1341    pub const fn contains(&self, other: &Ipv6Network) -> bool {
1342        let (a1, m1) = self.to_bits();
1343        let (a2, m2) = other.to_bits();
1344
1345        (a2 & m1 == a1) && (m2 & m1 == m1)
1346    }
1347
1348    /// Checks whether this network is a contiguous, i.e. contains mask with
1349    /// only leading bits set to one contiguously.
1350    ///
1351    /// # Examples
1352    ///
1353    /// ```
1354    /// use netip::Ipv6Network;
1355    ///
1356    /// assert!(Ipv6Network::parse("::/0").unwrap().is_contiguous());
1357    /// assert!(
1358    ///     Ipv6Network::parse("2a02:6b8:c00::/40")
1359    ///         .unwrap()
1360    ///         .is_contiguous()
1361    /// );
1362    ///
1363    /// assert!(
1364    ///     !Ipv6Network::parse("2a02:6b8:c00::f800:0:0/ffff:ffff:0:0:ffff:ffff::")
1365    ///         .unwrap()
1366    ///         .is_contiguous()
1367    /// );
1368    /// ```
1369    #[inline]
1370    pub const fn is_contiguous(&self) -> bool {
1371        let mask = u128::from_be_bytes(self.mask().octets());
1372        mask.count_zeros() == mask.trailing_zeros()
1373    }
1374
1375    /// Checks whether this network is an IPv4-mapped IPv6 network.
1376    ///
1377    /// # Examples
1378    ///
1379    /// ```
1380    /// use netip::{Ipv4Network, Ipv6Network};
1381    ///
1382    /// assert!(
1383    ///     Ipv4Network::parse("8.8.8.0/24")
1384    ///         .unwrap()
1385    ///         .to_ipv6_mapped()
1386    ///         .is_ipv4_mapped_ipv6()
1387    /// );
1388    ///
1389    /// assert!(
1390    ///     !Ipv6Network::parse("2a02:6b8::/40")
1391    ///         .unwrap()
1392    ///         .is_ipv4_mapped_ipv6()
1393    /// );
1394    /// ```
1395    #[inline]
1396    pub const fn is_ipv4_mapped_ipv6(&self) -> bool {
1397        let (addr, mask) = self.to_bits();
1398
1399        // Suppress clippy a bit, because with return we have a nice aligning.
1400        #[allow(clippy::needless_return)]
1401        return addr & 0xffffffffffffffffffffffff00000000 == 0x00000000000000000000ffff00000000
1402            && mask & 0xffffffffffffffffffffffff00000000 == 0xffffffffffffffffffffffff00000000;
1403    }
1404
1405    /// Converts this network to a contiguous network by clearing mask bits set
1406    /// to one after the first zero bit.
1407    ///
1408    /// # Examples
1409    ///
1410    /// ```
1411    /// use core::net::Ipv6Addr;
1412    ///
1413    /// use netip::Ipv6Network;
1414    ///
1415    /// let net = Ipv6Network::new(
1416    ///     Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0xf800, 0, 0),
1417    ///     Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0, 0xffff, 0xffff, 0, 0),
1418    /// );
1419    /// let expected = Ipv6Network::new(
1420    ///     Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
1421    ///     Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0),
1422    /// );
1423    ///
1424    /// assert_eq!(expected, net.to_contiguous());
1425    /// ```
1426    pub fn to_contiguous(&self) -> Self {
1427        let (addr, mask) = self.to_bits();
1428
1429        Self::try_from((addr.into(), mask.leading_ones() as u8)).expect("CIDR must be in range [0; 128]")
1430    }
1431
1432    /// Converts this network to an [`IPv4` network] if it's an IPv4-mapped
1433    /// network, as defined in [IETF RFC 4291 section 2.5.5.2], otherwise
1434    /// returns [`None`].
1435    ///
1436    /// `::ffff:a.b.c.d/N` becomes `a.b.c.d/M`, where `M = N - 96`.
1437    /// All networks with their addresses *not* starting with `::ffff` will
1438    /// return `None`.
1439    ///
1440    /// [`IPv4` network]: Ipv4Network
1441    /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
1442    ///
1443    /// # Examples
1444    ///
1445    /// ```
1446    /// use core::net::{Ipv4Addr, Ipv6Addr};
1447    ///
1448    /// use netip::{Ipv4Network, Ipv6Network};
1449    ///
1450    /// let net = Ipv6Network::new(
1451    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff),
1452    ///     Ipv6Addr::new(
1453    ///         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xff00,
1454    ///     ),
1455    /// );
1456    /// let expected = Ipv4Network::new(
1457    ///     Ipv4Addr::new(192, 10, 2, 0),
1458    ///     Ipv4Addr::new(255, 255, 255, 0),
1459    /// );
1460    /// assert_eq!(Some(expected), net.to_ipv4_mapped());
1461    ///
1462    /// // This networks is IPv4-compatible, but not the IPv4-mapped one.
1463    /// let net = Ipv6Network::new(
1464    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc00a, 0x2ff),
1465    ///     Ipv6Addr::new(
1466    ///         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xff00,
1467    ///     ),
1468    /// );
1469    /// assert_eq!(None, net.to_ipv4_mapped());
1470    /// ```
1471    #[inline]
1472    pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Network> {
1473        if self.is_ipv4_mapped_ipv6() {
1474            let (addr, mask) = self.to_bits();
1475            let addr: u32 = (addr & 0xffffffff) as u32;
1476            let mask: u32 = (mask & 0xffffffff) as u32;
1477
1478            Some(Ipv4Network::from_bits(addr, mask))
1479        } else {
1480            None
1481        }
1482    }
1483
1484    /// Returns the mask prefix, i.e. the number of leading bits set, if this
1485    /// network is a contiguous one, `None` otherwise.
1486    ///
1487    /// # Examples
1488    ///
1489    /// ```
1490    /// use netip::{Ipv4Network, Ipv6Network};
1491    ///
1492    /// assert_eq!(
1493    ///     Some(40),
1494    ///     Ipv6Network::parse("2a02:6b8::/40").unwrap().prefix()
1495    /// );
1496    /// assert_eq!(
1497    ///     Some(128),
1498    ///     Ipv6Network::parse("2a02:6b8::1").unwrap().prefix()
1499    /// );
1500    ///
1501    /// // The IPv4-mapped IPv6 equivalent is `::ffff:8.8.8.0/120`.
1502    /// assert_eq!(
1503    ///     Some(120),
1504    ///     Ipv4Network::parse("8.8.8.0/24")
1505    ///         .unwrap()
1506    ///         .to_ipv6_mapped()
1507    ///         .prefix()
1508    /// );
1509    /// ```
1510    #[inline]
1511    pub const fn prefix(&self) -> Option<u8> {
1512        let mask = u128::from_be_bytes(self.mask().octets());
1513        let ones = mask.leading_ones();
1514
1515        if mask.count_ones() == ones {
1516            Some(ones as u8)
1517        } else {
1518            None
1519        }
1520    }
1521
1522    /// Calculates and returns the `Ipv6Network`, which will be a supernet, i.e.
1523    /// the shortest common network both for this network and the specified
1524    /// ones.
1525    ///
1526    /// # Note
1527    ///
1528    /// This function works fine for both contiguous and non-contiguous
1529    /// networks.
1530    ///
1531    /// Use [`Ipv6Network::to_contiguous`] method if you need to convert the
1532    /// output network.
1533    ///
1534    /// # Examples
1535    ///
1536    /// ```
1537    /// use core::net::Ipv6Addr;
1538    ///
1539    /// use netip::Ipv6Network;
1540    ///
1541    /// // 2013:db8:1::1/64
1542    /// let net0 = Ipv6Network::new(
1543    ///     Ipv6Addr::new(0x2013, 0xdb8, 0x1, 0, 0, 0, 0, 0x1),
1544    ///     Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0),
1545    /// );
1546    ///
1547    /// // 2013:db8:2::1/64
1548    /// let net1 = Ipv6Network::new(
1549    ///     Ipv6Addr::new(0x2013, 0xdb8, 0x2, 0, 0, 0, 0, 0x1),
1550    ///     Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0),
1551    /// );
1552    ///
1553    /// // 2013:db8::/46
1554    /// let expected = Ipv6Network::new(
1555    ///     Ipv6Addr::new(0x2013, 0xdb8, 0, 0, 0, 0, 0, 0),
1556    ///     Ipv6Addr::new(0xffff, 0xffff, 0xfffc, 0, 0, 0, 0, 0),
1557    /// );
1558    /// assert_eq!(expected, net0.supernet_for(&[net1]));
1559    /// ```
1560    pub fn supernet_for(&self, nets: &[Ipv6Network]) -> Ipv6Network {
1561        let (addr, mask) = self.to_bits();
1562
1563        let mut min = addr;
1564        let mut max = addr;
1565
1566        for net in nets {
1567            let (addr, ..) = net.to_bits();
1568            if addr < min {
1569                min = addr;
1570            } else if addr > max {
1571                max = addr;
1572            }
1573        }
1574
1575        let common_addr = min ^ max;
1576        let common_addr_len = common_addr.leading_zeros();
1577        let mask = mask & !(u128::MAX.checked_shr(common_addr_len).unwrap_or_default());
1578
1579        Self::new(addr.into(), mask.into())
1580    }
1581
1582    /// Returns the last address in this IPv6 network.
1583    ///
1584    /// For contiguous networks, this is the broadcast address.
1585    ///
1586    /// For non-contiguous networks, this is the highest address within the
1587    /// network range defined by the mask.
1588    ///
1589    /// # Examples
1590    ///
1591    /// ```
1592    /// use core::net::Ipv6Addr;
1593    ///
1594    /// use netip::Ipv6Network;
1595    ///
1596    /// // Contiguous network.
1597    /// let net = Ipv6Network::new(
1598    ///     Ipv6Addr::new(0x2001, 0xdb8, 0x1, 0, 0, 0, 0, 0),
1599    ///     Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0, 0),
1600    /// );
1601    /// assert_eq!(
1602    ///     Ipv6Addr::new(0x2001, 0xdb8, 0x1, 0, 0, 0, 0xffff, 0xffff),
1603    ///     net.last_addr()
1604    /// );
1605    ///
1606    /// // Single address network.
1607    /// let net = Ipv6Network::new(
1608    ///     Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1),
1609    ///     Ipv6Addr::new(
1610    ///         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1611    ///     ),
1612    /// );
1613    /// assert_eq!(
1614    ///     Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1),
1615    ///     net.last_addr()
1616    /// );
1617    ///
1618    /// // Non-contiguous network.
1619    /// let net = Ipv6Network::new(
1620    ///     Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0),
1621    ///     Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0xffff, 0xffff, 0, 0),
1622    /// );
1623    /// assert_eq!(
1624    ///     Ipv6Addr::new(0x2a02, 0x6b8, 0x0cff, 0xffff, 0, 0x1234, 0xffff, 0xffff),
1625    ///     net.last_addr()
1626    /// );
1627    /// ```
1628    ///
1629    /// # Formal Proof of Correctness
1630    ///
1631    /// The algorithm follows the same logic as [`Ipv4Network::last_addr`].
1632    /// See [`Ipv4Network::last_addr`] for the formal proof.
1633    #[inline]
1634    pub const fn last_addr(&self) -> Ipv6Addr {
1635        let (addr, mask) = self.to_bits();
1636        Ipv6Addr::from_bits(addr | !mask)
1637    }
1638
1639    /// Returns a bidirectional iterator over all addresses in this network.
1640    ///
1641    /// The iterator yields addresses in **host-index order**: the *k* host
1642    /// positions (bits where the mask is zero) are filled with successive
1643    /// values `0 ..= 2^k - 1`, starting from the least-significant host bit.
1644    ///
1645    /// For a standard (contiguous) CIDR mask this is equivalent to ascending
1646    /// numeric order from [`addr()`](Ipv6Network::addr) to
1647    /// [`last_addr()`](Ipv6Network::last_addr).
1648    ///
1649    /// For a non-contiguous mask the numeric order of the produced addresses
1650    /// may differ from the iteration order.
1651    ///
1652    /// The iterator implements [`DoubleEndedIterator`].
1653    ///
1654    /// # Examples
1655    ///
1656    /// ```
1657    /// use core::net::Ipv6Addr;
1658    ///
1659    /// use netip::Ipv6Network;
1660    ///
1661    /// let net = Ipv6Network::parse("2a02:6b8:c00::1234:0:0/120").unwrap();
1662    /// let mut addrs = net.addrs();
1663    ///
1664    /// assert_eq!(
1665    ///     Some(Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0)),
1666    ///     addrs.next()
1667    /// );
1668    /// assert_eq!(
1669    ///     Some(Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 1)),
1670    ///     addrs.next()
1671    /// );
1672    ///
1673    /// // Both directions work on the same range and do not cross: iteration
1674    /// // is over when they meet in the middle.
1675    ///
1676    /// assert_eq!(
1677    ///     Some(Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0xff)),
1678    ///     addrs.next_back()
1679    /// );
1680    ///
1681    /// assert_eq!(
1682    ///     Some(Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 2)),
1683    ///     addrs.next()
1684    /// );
1685    /// ```
1686    #[inline]
1687    pub fn addrs(self) -> Ipv6NetworkAddrs {
1688        let (addr, mask) = self.to_bits();
1689        let host_bits = (!mask).count_ones();
1690        let back = u128::MAX.checked_shr(128 - host_bits).unwrap_or(0);
1691
1692        Ipv6NetworkAddrs { base: addr, mask, front: 0, back }
1693    }
1694}
1695
1696/// Bidirectional iterator over [`Ipv6Addr`] in an [`Ipv6Network`].
1697///
1698/// Created by [`Ipv6Network::addrs`].
1699///
1700/// Yields addresses in host-index order: the *k* host positions (bits where the
1701/// mask is zero) are filled with successive values `0 ..= 2^k - 1`, starting
1702/// from the least-significant host bit.
1703///
1704/// When the iterator is exhausted it enters a sentinel state where
1705/// `front > back`, so every subsequent call to [`next`](Iterator::next) or
1706/// [`next_back`](DoubleEndedIterator::next_back) returns [`None`].
1707#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1708pub struct Ipv6NetworkAddrs {
1709    base: u128,
1710    mask: u128,
1711    front: u128,
1712    back: u128,
1713}
1714
1715impl Iterator for Ipv6NetworkAddrs {
1716    type Item = Ipv6Addr;
1717
1718    #[inline]
1719    fn next(&mut self) -> Option<Self::Item> {
1720        if self.front > self.back {
1721            return None;
1722        }
1723
1724        let index = self.front;
1725        self.front = self.front.wrapping_add(1);
1726
1727        // Wrap-around means front was u128::MAX — only possible for a /0
1728        // network.
1729        //
1730        // Enter sentinel state so the next call returns None.
1731        if self.front == 0 {
1732            self.front = 1;
1733            self.back = 0;
1734        }
1735
1736        Some(Ipv6Addr::from_bits(ipv6_bits_from_host_index(
1737            self.base, self.mask, index,
1738        )))
1739    }
1740
1741    #[inline]
1742    fn size_hint(&self) -> (usize, Option<usize>) {
1743        if self.front > self.back {
1744            return (0, Some(0));
1745        }
1746
1747        let rem = self.back.wrapping_sub(self.front).wrapping_add(1);
1748
1749        if rem == 0 {
1750            (usize::MAX, None)
1751        } else {
1752            match usize::try_from(rem) {
1753                Ok(n) => (n, Some(n)),
1754                Err(..) => (usize::MAX, None),
1755            }
1756        }
1757    }
1758}
1759
1760impl DoubleEndedIterator for Ipv6NetworkAddrs {
1761    #[inline]
1762    fn next_back(&mut self) -> Option<Self::Item> {
1763        if self.front > self.back {
1764            return None;
1765        }
1766
1767        let bits = ipv6_bits_from_host_index(self.base, self.mask, self.back);
1768
1769        if self.front == self.back {
1770            self.front = 1;
1771            self.back = 0;
1772        } else {
1773            self.back = self.back.wrapping_sub(1);
1774        }
1775
1776        Some(Ipv6Addr::from_bits(bits))
1777    }
1778}
1779
1780#[inline]
1781const fn ipv6_bits_from_host_index(base: u128, mask: u128, index: u128) -> u128 {
1782    let host_mask = !mask;
1783
1784    // For contiguous masks (trailing ones only) pdep is identity.
1785    if host_mask & host_mask.wrapping_add(1) == 0 {
1786        base | index
1787    } else {
1788        base | pdep_u128(index, host_mask)
1789    }
1790}
1791
1792#[inline]
1793const fn pdep_u128(mut src: u128, mut mask: u128) -> u128 {
1794    let mut out = 0u128;
1795
1796    while mask != 0 {
1797        let t = mask & mask.wrapping_neg();
1798
1799        if src & 1 != 0 {
1800            out |= t;
1801        }
1802
1803        src >>= 1;
1804        mask ^= t;
1805    }
1806
1807    out
1808}
1809
1810impl Display for Ipv6Network {
1811    /// Formats this IPv6 network using the given formatter.
1812    ///
1813    /// The idea is to format using **the most compact** representation, except
1814    /// for non-contiguous networks, which are formatted explicitly.
1815    fn fmt(&self, fmt: &mut Formatter) -> Result<(), core::fmt::Error> {
1816        match self {
1817            Ipv6Network(addr, mask) => {
1818                match self.prefix() {
1819                    Some(prefix) => fmt.write_fmt(format_args!("{}/{}", addr, prefix)),
1820                    None => {
1821                        // This is a non-contiguous network, expand the mask.
1822                        fmt.write_fmt(format_args!("{}/{}", addr, mask))
1823                    }
1824                }
1825            }
1826        }
1827    }
1828}
1829
1830impl From<Ipv4Network> for Ipv6Network {
1831    #[inline]
1832    fn from(net: Ipv4Network) -> Self {
1833        net.to_ipv6_mapped()
1834    }
1835}
1836
1837impl From<Ipv6Addr> for Ipv6Network {
1838    fn from(addr: Ipv6Addr) -> Self {
1839        Ipv6Network(addr, IPV6_ALL_BITS)
1840    }
1841}
1842
1843impl TryFrom<(Ipv6Addr, u8)> for Ipv6Network {
1844    type Error = CidrOverflowError;
1845
1846    fn try_from((addr, cidr): (Ipv6Addr, u8)) -> Result<Self, Self::Error> {
1847        let mask = ipv6_mask_from_cidr(cidr)?;
1848        Ok(Ipv6Network::new(addr, mask))
1849    }
1850}
1851
1852impl FromStr for Ipv6Network {
1853    type Err = IpNetParseError;
1854
1855    #[inline]
1856    fn from_str(s: &str) -> Result<Self, Self::Err> {
1857        Ipv6Network::parse(s)
1858    }
1859}
1860
1861impl AsRef<Ipv6Network> for Ipv6Network {
1862    #[inline]
1863    fn as_ref(&self) -> &Ipv6Network {
1864        self
1865    }
1866}
1867
1868/// Finds the shortest common network for the given slice of networks that
1869/// covers at least half of slice.
1870///
1871/// Shortest means that it will have the shortest segment of subnets, or the
1872/// largest mask.
1873///
1874/// Imagine that you are building a radix tree or graph from networks and at
1875/// some point you need to split one of the nodes into two parts.
1876///
1877/// In other words, it is necessary to find the shortest network that contains
1878/// at least half of the child networks.
1879///
1880/// This function implements such an algorithm.
1881///
1882/// For example, suppose we have the following tree:
1883/// ```text
1884/// .
1885/// ├─ 127.0.0.1
1886/// ├─ 127.0.0.2
1887/// └─ 127.0.0.3
1888/// ```
1889///
1890/// After splitting:
1891///
1892/// ```text
1893/// .
1894/// ├─ 127.0.0.1
1895/// └─ 127.0.0.2/31
1896///   ├─ 127.0.0.2
1897///   └─ 127.0.0.3
1898/// ```
1899///
1900/// Another more interesting example:
1901///
1902/// ```text
1903/// .
1904/// ├─ 10.204.46.54/31
1905/// ├─ 10.204.46.68/31
1906/// ├─ 10.204.49.12/31
1907/// ├─ 10.204.49.14/31
1908/// ├─ 10.204.49.18/31
1909/// ├─ 10.204.49.32/31
1910/// ├─ 10.204.49.34/31
1911/// ├─ 10.204.49.36/31
1912/// ├─ 10.204.49.38/31
1913/// └─ 10.204.49.40/31
1914/// ```
1915///
1916/// After splitting:
1917///
1918/// ```text
1919/// .
1920/// ├─ 10.204.46.50/31
1921/// ├─ 10.204.46.54/31
1922/// ├─ 10.204.47.22/31
1923/// ├─ 10.204.49.0/26 [*]
1924/// │ ├─ 10.204.49.24/31
1925/// │ ├─ 10.204.49.26/31
1926/// │ ├─ 10.204.49.28/31
1927/// │ ├─ 10.204.49.32/31
1928/// │ ├─ 10.204.49.34/31
1929/// │ └─ 10.204.49.36/31
1930/// ├─ 10.204.50.38/31
1931/// └─ 10.204.50.40/31
1932/// ```
1933///
1934/// # Complexity
1935///
1936/// This function runs in `O(N)` and requires `O(1)` memory.
1937///
1938/// # Warning
1939///
1940/// The specified slice must be sorted, otherwise the result is unspecified and
1941/// meaningless.
1942///
1943/// Specified networks must not overlap.
1944///
1945/// # Examples
1946///
1947/// ```
1948/// use netip::{Ipv4Network, ipv4_binary_split};
1949///
1950/// let nets = &["127.0.0.1", "127.0.0.2", "127.0.0.3"];
1951/// let mut nets: Vec<_> = nets
1952///     .iter()
1953///     .map(|net| Ipv4Network::parse(net).unwrap())
1954///     .collect();
1955/// nets.sort();
1956/// nets.dedup();
1957///
1958/// let (supernet, range) = ipv4_binary_split(&nets).unwrap();
1959/// // 127.0.0.2/31 in binary is "0b...10/0b...10", which contains both "127.0.0.2" and "127.0.0.3".
1960/// assert_eq!(Ipv4Network::parse("127.0.0.2/31").unwrap(), supernet);
1961///
1962/// for (idx, net) in nets.iter().enumerate() {
1963///     assert_eq!(range.contains(&idx), supernet.contains(net));
1964/// }
1965///
1966/// // For the second example above.
1967///
1968/// let nets = &[
1969///     "10.204.46.50/31",
1970///     "10.204.46.54/31",
1971///     "10.204.47.22/31",
1972///     "10.204.49.24/31",
1973///     "10.204.49.26/31",
1974///     "10.204.49.28/31",
1975///     "10.204.49.32/31",
1976///     "10.204.49.34/31",
1977///     "10.204.49.36/31",
1978///     "10.204.50.38/31",
1979///     "10.204.50.40/31",
1980/// ];
1981/// let mut nets: Vec<_> = nets
1982///     .iter()
1983///     .map(|net| Ipv4Network::parse(net).unwrap())
1984///     .collect();
1985/// nets.sort();
1986/// nets.dedup();
1987///
1988/// let (supernet, range) = ipv4_binary_split(&nets).unwrap();
1989///
1990/// assert_eq!(Ipv4Network::parse("10.204.49.0/26").unwrap(), supernet);
1991///
1992/// for (idx, net) in nets.iter().enumerate() {
1993///     assert_eq!(range.contains(&idx), supernet.contains(net));
1994/// }
1995/// ```
1996pub fn ipv4_binary_split<T>(nets: &[T]) -> Option<(Ipv4Network, Range<usize>)>
1997where
1998    T: AsRef<Ipv4Network>,
1999{
2000    ip_binary_split(nets)
2001}
2002
2003/// Finds the shortest common network for the given slice of networks that
2004/// covers at least half of slice.
2005///
2006/// Shortest means that it will have the shortest segment of subnets, or the
2007/// largest mask.
2008///
2009/// Imagine that you are building a radix tree or graph from networks and at
2010/// some point you need to split one of the nodes into two parts.
2011///
2012/// In other words, it is necessary to find the shortest network that contains
2013/// at least half of the child networks.
2014///
2015/// This function implements such an algorithm.
2016///
2017/// For example, suppose we have the following tree:
2018/// ```text
2019/// .
2020/// ├─ ::1
2021/// ├─ ::2
2022/// └─ ::3
2023/// ```
2024///
2025/// After splitting:
2026///
2027/// ```text
2028/// .
2029/// ├─ ::1
2030/// └─ ::2/127
2031///   ├─ ::2
2032///   └─ ::3
2033/// ```
2034///
2035/// Another more interesting example:
2036///
2037/// ```text
2038/// .
2039/// ├─ 2a02:6b8:0:2302::/64
2040/// ├─ 2a02:6b8:0:2303::/64
2041/// ├─ 2a02:6b8:0:2305::/64
2042/// ├─ 2a02:6b8:0:2308::/64
2043/// ├─ 2a02:6b8:0:2309::/64
2044/// ├─ 2a02:6b8:0:230a::/64
2045/// ├─ 2a02:6b8:0:230b::/64
2046/// ├─ 2a02:6b8:0:230c::/64
2047/// ├─ 2a02:6b8:0:230d::/64
2048/// ├─ 2a02:6b8:0:2314::/64
2049/// └─ 2a02:6b8:0:231f::/64
2050/// ```
2051///
2052/// After splitting:
2053///
2054/// ```text
2055/// .
2056/// ├─ 2a02:6b8:0:2302::/64
2057/// ├─ 2a02:6b8:0:2303::/64
2058/// ├─ 2a02:6b8:0:2305::/64
2059/// └─ 2a02:6b8:0:2308::/61
2060/// │ ├─ 2a02:6b8:0:2308::/64
2061/// │ ├─ 2a02:6b8:0:2309::/64
2062/// │ ├─ 2a02:6b8:0:230a::/64
2063/// │ ├─ 2a02:6b8:0:230b::/64
2064/// │ ├─ 2a02:6b8:0:230c::/64
2065/// │ └─ 2a02:6b8:0:230d::/64
2066/// ├─ 2a02:6b8:0:2314::/64
2067/// └─ 2a02:6b8:0:231f::/64
2068/// ```
2069///
2070/// # Complexity
2071///
2072/// This function runs in `O(N)` and requires `O(1)` memory.
2073///
2074/// # Warning
2075///
2076/// The specified slice must be sorted, otherwise the result is unspecified and
2077/// meaningless.
2078///
2079/// Specified networks must not overlap.
2080///
2081/// # Examples
2082///
2083/// ```
2084/// use netip::{Ipv6Network, ipv6_binary_split};
2085///
2086/// let nets = &["::1", "::2", "::3"];
2087/// let mut nets: Vec<_> = nets
2088///     .iter()
2089///     .map(|net| Ipv6Network::parse(net).unwrap())
2090///     .collect();
2091///
2092/// // The input must be sorted.
2093/// nets.sort();
2094///
2095/// let (supernet, range) = ipv6_binary_split(&nets).unwrap();
2096/// // ::2/127 in binary is "0b...10/0b...10", which contains both "::2" and "::3".
2097/// assert_eq!(Ipv6Network::parse("::2/127").unwrap(), supernet);
2098///
2099/// for (idx, net) in nets.iter().enumerate() {
2100///     assert_eq!(range.contains(&idx), supernet.contains(net));
2101/// }
2102///
2103/// // For the second example above.
2104///
2105/// let nets = &[
2106///     "2a02:6b8:0:2302::/64",
2107///     "2a02:6b8:0:2303::/64",
2108///     "2a02:6b8:0:2305::/64",
2109///     "2a02:6b8:0:2308::/64",
2110///     "2a02:6b8:0:2309::/64",
2111///     "2a02:6b8:0:230a::/64",
2112///     "2a02:6b8:0:230b::/64",
2113///     "2a02:6b8:0:230c::/64",
2114///     "2a02:6b8:0:230d::/64",
2115///     "2a02:6b8:0:2314::/64",
2116///     "2a02:6b8:0:231f::/64",
2117/// ];
2118/// let mut nets: Vec<_> = nets
2119///     .iter()
2120///     .map(|net| Ipv6Network::parse(net).unwrap())
2121///     .collect();
2122/// nets.sort();
2123///
2124/// let (supernet, range) = ipv6_binary_split(&nets).unwrap();
2125/// assert_eq!(
2126///     Ipv6Network::parse("2a02:6b8:0:2308::/61").unwrap(),
2127///     supernet
2128/// );
2129///
2130/// for (idx, net) in nets.iter().enumerate() {
2131///     assert_eq!(range.contains(&idx), supernet.contains(net));
2132/// }
2133/// ```
2134pub fn ipv6_binary_split<T>(nets: &[T]) -> Option<(Ipv6Network, Range<usize>)>
2135where
2136    T: AsRef<Ipv6Network>,
2137{
2138    ip_binary_split(nets)
2139}
2140
2141#[inline]
2142fn ip_binary_split<T, U>(nets: &[T]) -> Option<(U, Range<usize>)>
2143where
2144    T: AsRef<U>,
2145    U: BinarySplit + Copy,
2146{
2147    if nets.len() < 3 {
2148        return None;
2149    }
2150
2151    // Window size.
2152    let size = nets.len().div_ceil(2);
2153
2154    // We start with supernet that covers all given networks.
2155    let mut range = 0..nets.len() - 1;
2156    let mut candidate = nets[range.start].as_ref().supernet_for(&[*nets[range.end].as_ref()]);
2157
2158    for (idx, window) in nets.windows(size).enumerate() {
2159        let supernet = window[0].as_ref().supernet_for(&[*window[size - 1].as_ref()]);
2160
2161        if supernet.mask() > candidate.mask() {
2162            range = idx..(idx + size);
2163            candidate = supernet;
2164        }
2165    }
2166
2167    // Adjust range from both sides, since our supernet may cover more networks.
2168    while range.start > 0 {
2169        if candidate.contains(nets[range.start - 1].as_ref()) {
2170            range.start -= 1;
2171        } else {
2172            break;
2173        }
2174    }
2175    while range.end < nets.len() {
2176        // Remember, range end is exclusive.
2177        if candidate.contains(nets[range.end].as_ref()) {
2178            range.end += 1;
2179        } else {
2180            break;
2181        }
2182    }
2183
2184    Some((candidate, range))
2185}
2186
2187trait BinarySplit: Sized {
2188    type Mask: PartialOrd;
2189
2190    fn mask(&self) -> &Self::Mask;
2191    fn contains(&self, other: &Self) -> bool;
2192    fn supernet_for(&self, nets: &[Self]) -> Self;
2193}
2194
2195impl BinarySplit for Ipv4Network {
2196    type Mask = Ipv4Addr;
2197
2198    #[inline]
2199    fn mask(&self) -> &Self::Mask {
2200        self.mask()
2201    }
2202
2203    #[inline]
2204    fn contains(&self, other: &Self) -> bool {
2205        self.contains(other)
2206    }
2207
2208    #[inline]
2209    fn supernet_for(&self, nets: &[Self]) -> Ipv4Network {
2210        self.supernet_for(nets)
2211    }
2212}
2213
2214impl BinarySplit for Ipv6Network {
2215    type Mask = Ipv6Addr;
2216
2217    #[inline]
2218    fn mask(&self) -> &Self::Mask {
2219        self.mask()
2220    }
2221
2222    #[inline]
2223    fn contains(&self, other: &Self) -> bool {
2224        self.contains(other)
2225    }
2226
2227    #[inline]
2228    fn supernet_for(&self, nets: &[Self]) -> Ipv6Network {
2229        self.supernet_for(nets)
2230    }
2231}
2232
2233/// An error that occurs when parsing a contiguous IP network.
2234#[derive(Debug, PartialEq)]
2235pub enum ContiguousIpNetParseError {
2236    /// The network is not contiguous.
2237    NonContiguousNetwork,
2238    /// An error occurred while parsing the IP network.
2239    IpNetParseError(IpNetParseError),
2240}
2241
2242impl From<IpNetParseError> for ContiguousIpNetParseError {
2243    #[inline]
2244    fn from(err: IpNetParseError) -> Self {
2245        ContiguousIpNetParseError::IpNetParseError(err)
2246    }
2247}
2248
2249impl Display for ContiguousIpNetParseError {
2250    fn fmt(&self, fmt: &mut Formatter) -> Result<(), core::fmt::Error> {
2251        match self {
2252            Self::NonContiguousNetwork => write!(fmt, "non-contiguous network"),
2253            Self::IpNetParseError(err) => write!(fmt, "{}", err),
2254        }
2255    }
2256}
2257
2258impl Error for ContiguousIpNetParseError {}
2259
2260/// A contiguous IP network.
2261///
2262/// Represents a wrapper around an IP network that is **guaranteed to be
2263/// contiguous**.
2264#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2265pub struct Contiguous<T>(T);
2266
2267impl Contiguous<IpNetwork> {
2268    /// Parses an IP network from a string and returns a contiguous network.
2269    pub fn parse(buf: &str) -> Result<Self, ContiguousIpNetParseError> {
2270        let net = IpNetwork::parse(buf)?;
2271
2272        if net.is_contiguous() {
2273            Ok(Self(net))
2274        } else {
2275            Err(ContiguousIpNetParseError::NonContiguousNetwork)
2276        }
2277    }
2278
2279    /// Returns the prefix length of the network.
2280    ///
2281    /// # Examples
2282    ///
2283    /// ```
2284    /// use netip::{Contiguous, IpNetwork};
2285    ///
2286    /// let net = Contiguous::<IpNetwork>::parse("192.168.1.0/24").unwrap();
2287    /// assert_eq!(24, net.prefix());
2288    /// ```
2289    #[inline]
2290    pub const fn prefix(&self) -> u8 {
2291        match self {
2292            Self(IpNetwork::V4(net)) => Contiguous(*net).prefix(),
2293            Self(IpNetwork::V6(net)) => Contiguous(*net).prefix(),
2294        }
2295    }
2296}
2297
2298impl Contiguous<Ipv4Network> {
2299    /// Parses an IPv4 network from a string and returns a contiguous network.
2300    pub fn parse(buf: &str) -> Result<Self, ContiguousIpNetParseError> {
2301        let net = Ipv4Network::parse(buf)?;
2302
2303        if net.is_contiguous() {
2304            Ok(Self(net))
2305        } else {
2306            Err(ContiguousIpNetParseError::NonContiguousNetwork)
2307        }
2308    }
2309
2310    /// Returns the prefix length of the network.
2311    ///
2312    /// # Examples
2313    ///
2314    /// ```
2315    /// use netip::{Contiguous, Ipv4Network};
2316    ///
2317    /// let net = Contiguous::<Ipv4Network>::parse("172.16.0.0/12").unwrap();
2318    /// assert_eq!(12, net.prefix());
2319    /// ```
2320    #[inline]
2321    pub const fn prefix(&self) -> u8 {
2322        match self {
2323            Self(net) => {
2324                let mask = u32::from_be_bytes(net.mask().octets());
2325                let ones = mask.leading_ones();
2326                ones as u8
2327            }
2328        }
2329    }
2330}
2331
2332impl Contiguous<Ipv6Network> {
2333    /// Parses an IPv6 network from a string and returns a contiguous network.
2334    pub fn parse(buf: &str) -> Result<Self, ContiguousIpNetParseError> {
2335        let net = Ipv6Network::parse(buf)?;
2336
2337        if net.is_contiguous() {
2338            Ok(Self(net))
2339        } else {
2340            Err(ContiguousIpNetParseError::NonContiguousNetwork)
2341        }
2342    }
2343
2344    /// Returns the prefix length of the network.
2345    ///
2346    /// # Examples
2347    ///
2348    /// ```
2349    /// use netip::{Contiguous, Ipv6Network};
2350    ///
2351    /// let net = Contiguous::<Ipv6Network>::parse("2a02:6b8:c00::/40").unwrap();
2352    /// assert_eq!(40, net.prefix());
2353    /// ```
2354    #[inline]
2355    pub const fn prefix(&self) -> u8 {
2356        match self {
2357            Self(net) => {
2358                let mask = u128::from_be_bytes(net.mask().octets());
2359                let ones = mask.leading_ones();
2360                ones as u8
2361            }
2362        }
2363    }
2364}
2365
2366impl<T> Deref for Contiguous<T> {
2367    type Target = T;
2368
2369    #[inline]
2370    fn deref(&self) -> &Self::Target {
2371        match self {
2372            Self(net) => net,
2373        }
2374    }
2375}
2376
2377impl<T> Display for Contiguous<T>
2378where
2379    T: Display,
2380{
2381    #[inline]
2382    fn fmt(&self, fmt: &mut Formatter) -> Result<(), core::fmt::Error> {
2383        match self {
2384            Self(net) => Display::fmt(net, fmt),
2385        }
2386    }
2387}
2388
2389impl FromStr for Contiguous<IpNetwork> {
2390    type Err = ContiguousIpNetParseError;
2391
2392    fn from_str(s: &str) -> Result<Self, Self::Err> {
2393        Self::parse(s)
2394    }
2395}
2396
2397impl FromStr for Contiguous<Ipv4Network> {
2398    type Err = ContiguousIpNetParseError;
2399
2400    fn from_str(s: &str) -> Result<Self, Self::Err> {
2401        Self::parse(s)
2402    }
2403}
2404
2405impl FromStr for Contiguous<Ipv6Network> {
2406    type Err = ContiguousIpNetParseError;
2407
2408    fn from_str(s: &str) -> Result<Self, Self::Err> {
2409        Self::parse(s)
2410    }
2411}
2412
2413#[cfg(test)]
2414mod test {
2415    use super::*;
2416
2417    #[test]
2418    fn test_ipv4_mask_from_cidr() {
2419        let masks = &[
2420            0u32,
2421            0b10000000000000000000000000000000,
2422            0b11000000000000000000000000000000,
2423            0b11100000000000000000000000000000,
2424            0b11110000000000000000000000000000,
2425            0b11111000000000000000000000000000,
2426            0b11111100000000000000000000000000,
2427            0b11111110000000000000000000000000,
2428            0b11111111000000000000000000000000,
2429            0b11111111100000000000000000000000,
2430            0b11111111110000000000000000000000,
2431            0b11111111111000000000000000000000,
2432            0b11111111111100000000000000000000,
2433            0b11111111111110000000000000000000,
2434            0b11111111111111000000000000000000,
2435            0b11111111111111100000000000000000,
2436            0b11111111111111110000000000000000,
2437            0b11111111111111111000000000000000,
2438            0b11111111111111111100000000000000,
2439            0b11111111111111111110000000000000,
2440            0b11111111111111111111000000000000,
2441            0b11111111111111111111100000000000,
2442            0b11111111111111111111110000000000,
2443            0b11111111111111111111111000000000,
2444            0b11111111111111111111111100000000,
2445            0b11111111111111111111111110000000,
2446            0b11111111111111111111111111000000,
2447            0b11111111111111111111111111100000,
2448            0b11111111111111111111111111110000,
2449            0b11111111111111111111111111111000,
2450            0b11111111111111111111111111111100,
2451            0b11111111111111111111111111111110,
2452            0b11111111111111111111111111111111,
2453        ];
2454
2455        for (idx, &mask) in masks.iter().enumerate() {
2456            assert_eq!(Ipv4Addr::from(mask), ipv4_mask_from_cidr(idx as u8).unwrap());
2457        }
2458
2459        assert!(ipv4_mask_from_cidr(33).is_err());
2460    }
2461
2462    #[test]
2463    fn test_ipv6_mask_from_cidr() {
2464        assert_eq!(Ipv6Addr::UNSPECIFIED, ipv6_mask_from_cidr(0).unwrap());
2465        assert_eq!(
2466            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x8000, 0),
2467            ipv6_mask_from_cidr(97).unwrap()
2468        );
2469        assert_eq!(
2470            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
2471            ipv6_mask_from_cidr(128).unwrap()
2472        );
2473
2474        assert!(ipv6_mask_from_cidr(129).is_err());
2475    }
2476
2477    #[test]
2478    fn parse_ipv4() {
2479        assert_eq!(
2480            Ipv4Network::new("127.0.0.1".parse().unwrap(), "255.255.255.255".parse().unwrap()),
2481            Ipv4Network::parse("127.0.0.1").unwrap()
2482        );
2483    }
2484
2485    #[test]
2486    fn parse_ipv4_cidr() {
2487        assert_eq!(
2488            Ipv4Network::new("192.168.0.0".parse().unwrap(), "255.255.255.0".parse().unwrap()),
2489            Ipv4Network::parse("192.168.0.1/24").unwrap()
2490        );
2491
2492        assert_eq!(
2493            Ipv4Network::new("192.168.0.1".parse().unwrap(), "255.255.255.255".parse().unwrap()),
2494            Ipv4Network::parse("192.168.0.1/32").unwrap()
2495        );
2496    }
2497
2498    #[test]
2499    fn parse_ipv4_explicit_mask() {
2500        assert_eq!(
2501            Ipv4Network::new("192.168.0.0".parse().unwrap(), "255.255.255.0".parse().unwrap()),
2502            Ipv4Network::parse("192.168.0.1/255.255.255.0").unwrap()
2503        );
2504    }
2505
2506    #[test]
2507    fn ipv4_contains() {
2508        assert!(
2509            Ipv4Network::parse("0.0.0.0/0")
2510                .unwrap()
2511                .contains(&Ipv4Network::parse("127.0.0.1").unwrap())
2512        );
2513        assert!(
2514            Ipv4Network::parse("0.0.0.0/8")
2515                .unwrap()
2516                .contains(&Ipv4Network::parse("0.0.0.0/9").unwrap())
2517        );
2518    }
2519
2520    #[test]
2521    fn ipv4_not_contains() {
2522        assert!(
2523            !Ipv4Network::parse("0.0.0.0/9")
2524                .unwrap()
2525                .contains(&Ipv4Network::parse("0.0.0.0/8").unwrap())
2526        );
2527    }
2528
2529    #[test]
2530    fn ipv4_contains_self() {
2531        assert!(
2532            Ipv4Network::parse("127.0.0.1")
2533                .unwrap()
2534                .contains(&Ipv4Network::parse("127.0.0.1").unwrap())
2535        );
2536    }
2537
2538    #[test]
2539    fn ipv4_addrs_non_contiguous_matches_expected_grid() {
2540        let net = Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 1), Ipv4Addr::new(255, 255, 0, 255));
2541        let mut expected: Vec<_> = (0u16..256).map(|a| Ipv4Addr::new(192, 168, a as u8, 1)).collect();
2542        let mut actual: Vec<_> = net.addrs().collect();
2543        expected.sort();
2544        actual.sort();
2545
2546        assert_eq!(expected, actual);
2547    }
2548
2549    #[test]
2550    fn ipv4_addrs_slash24_matches_incrementing_u32() {
2551        let net = Ipv4Network::parse("192.168.1.0/24").unwrap();
2552        let mut ip = net.addr().to_bits();
2553        for a in net.addrs() {
2554            assert_eq!(a.to_bits(), ip);
2555            ip = ip.wrapping_add(1);
2556        }
2557
2558        assert_eq!(256, net.addrs().count());
2559    }
2560
2561    #[test]
2562    fn ipv4_addrs_slash32_single() {
2563        let net = Ipv4Network::parse("10.0.0.1/32").unwrap();
2564        assert_eq!(net.addrs().next(), net.addrs().next_back());
2565
2566        let mut addrs = net.addrs();
2567        assert_eq!(addrs.next(), Some(Ipv4Addr::new(10, 0, 0, 1)));
2568        assert_eq!(addrs.next(), None);
2569        assert_eq!(addrs.next_back(), None);
2570    }
2571
2572    #[test]
2573    fn ipv4_addrs_non_contiguous_unique_and_endpoints() {
2574        let net = Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 1), Ipv4Addr::new(255, 255, 0, 255));
2575
2576        let addrs: Vec<_> = net.addrs().collect();
2577        assert_eq!(256, addrs.len());
2578
2579        let mut sorted = addrs.clone();
2580        sorted.sort();
2581        sorted.dedup();
2582
2583        assert_eq!(sorted.len(), addrs.len());
2584        assert_eq!(addrs.first().copied(), Some(*net.addr()));
2585        assert_eq!(addrs.last().copied(), Some(net.last_addr()));
2586    }
2587
2588    #[test]
2589    fn ipv4_addrs_interleaved_exhausts_uniquely() {
2590        let net = Ipv4Network::parse("192.168.1.0/24").unwrap();
2591        let mut addrs = net.addrs();
2592        let mut seen = Vec::new();
2593        loop {
2594            match (addrs.next(), addrs.next_back()) {
2595                (Some(a), Some(b)) => {
2596                    seen.push(a);
2597                    seen.push(b);
2598                }
2599                (Some(a), None) => seen.push(a),
2600                (None, Some(b)) => seen.push(b),
2601                (None, None) => break,
2602            }
2603        }
2604
2605        assert_eq!(256, seen.len());
2606        seen.sort();
2607        seen.dedup();
2608        assert_eq!(256, seen.len());
2609    }
2610
2611    #[test]
2612    fn ipv4_addrs_unspecified_both_ends() {
2613        let net = Ipv4Network::UNSPECIFIED;
2614        let mut addrs = net.addrs();
2615        assert_eq!(addrs.next(), Some(Ipv4Addr::new(0, 0, 0, 0)));
2616        assert_eq!(addrs.next_back(), Some(Ipv4Addr::new(255, 255, 255, 255)));
2617    }
2618
2619    #[test]
2620    fn ipv6_addrs_slash120_matches_incrementing_u128() {
2621        let net = Ipv6Network::parse("2a02:6b8:c00::1234:0:0/120").unwrap();
2622        let mut ip = net.addr().to_bits();
2623
2624        for addr in net.addrs() {
2625            assert_eq!(addr.to_bits(), ip);
2626            ip = ip.wrapping_add(1);
2627        }
2628
2629        assert_eq!(256, net.addrs().count());
2630    }
2631
2632    #[test]
2633    fn ipv6_addrs_slash128_single() {
2634        let net = Ipv6Network::parse("::1/128").unwrap();
2635        assert_eq!(net.addrs().next(), net.addrs().next_back());
2636
2637        let mut addrs = net.addrs();
2638        assert_eq!(addrs.next(), Some(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)));
2639        assert_eq!(addrs.next(), None);
2640        assert_eq!(addrs.next_back(), None);
2641    }
2642
2643    #[test]
2644    fn ipv6_addrs_non_contiguous_unique_and_endpoints() {
2645        let net = Ipv6Network::new(
2646            Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0),
2647            Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
2648        );
2649
2650        let addrs: Vec<_> = net.addrs().collect();
2651        assert_eq!(256, addrs.len());
2652
2653        let mut sorted = addrs.clone();
2654        sorted.sort();
2655        sorted.dedup();
2656        assert_eq!(sorted.len(), addrs.len());
2657        assert_eq!(addrs.first().copied(), Some(*net.addr()));
2658        assert_eq!(addrs.last().copied(), Some(net.last_addr()));
2659    }
2660
2661    #[test]
2662    fn ipv6_addrs_interleaved_exhausts_uniquely() {
2663        let net = Ipv6Network::parse("2a02:6b8:c00::1234:0:0/120").unwrap();
2664        let mut addrs = net.addrs();
2665        let mut seen = Vec::new();
2666
2667        loop {
2668            match (addrs.next(), addrs.next_back()) {
2669                (Some(a), Some(b)) => {
2670                    seen.push(a);
2671                    seen.push(b);
2672                }
2673                (Some(a), None) => seen.push(a),
2674                (None, Some(b)) => seen.push(b),
2675                (None, None) => break,
2676            }
2677        }
2678
2679        assert_eq!(256, seen.len());
2680        seen.sort();
2681        seen.dedup();
2682        assert_eq!(256, seen.len());
2683    }
2684
2685    #[test]
2686    fn ipv6_addrs_unspecified_both_ends() {
2687        let net = Ipv6Network::UNSPECIFIED;
2688        let mut addrs = net.addrs();
2689        assert_eq!(addrs.next(), Some(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)));
2690        assert_eq!(
2691            addrs.next_back(),
2692            Some(Ipv6Addr::new(
2693                0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
2694            ))
2695        );
2696    }
2697
2698    #[test]
2699    fn ipv6_addrs_non_contiguous_matches_expected_grid() {
2700        let net = Ipv6Network::new(
2701            Ipv6Addr::new(0x2a02, 0x6b8, 0x0c00, 0, 0, 0, 0, 1),
2702            Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
2703        );
2704
2705        let mut expected: Vec<_> = (0u16..256)
2706            .map(|a| Ipv6Addr::new(0x2a02, 0x6b8, 0x0c00 | a, 0, 0, 0, 0, 1))
2707            .collect();
2708        let mut actual: Vec<_> = net.addrs().collect();
2709        expected.sort();
2710        actual.sort();
2711        assert_eq!(expected, actual);
2712    }
2713
2714    #[test]
2715    fn ipv4_supernet_for() {
2716        let net0 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 25)).unwrap();
2717        let net1 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 128), 25)).unwrap();
2718
2719        let expected = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 24)).unwrap();
2720        assert_eq!(expected, net0.supernet_for(&[net1]));
2721        assert_eq!(expected, net1.supernet_for(&[net0]));
2722    }
2723
2724    #[test]
2725    fn ipv4_supernet_for_equal_nets() {
2726        let net0 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 128), 25)).unwrap();
2727        let net1 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 128), 25)).unwrap();
2728
2729        let expected = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 128), 25)).unwrap();
2730        assert_eq!(expected, net0.supernet_for(&[net1]));
2731        assert_eq!(expected, net1.supernet_for(&[net0]));
2732    }
2733
2734    #[test]
2735    fn ipv4_supernet_for_many() {
2736        let net0 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 27)).unwrap();
2737        let net1 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 32), 27)).unwrap();
2738        let net2 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 64), 27)).unwrap();
2739        let net3 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 96), 27)).unwrap();
2740        let net4 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 128), 27)).unwrap();
2741        let net5 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 160), 27)).unwrap();
2742        let net6 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 192), 27)).unwrap();
2743        let net7 = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 224), 27)).unwrap();
2744
2745        let expected = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 24)).unwrap();
2746        assert_eq!(expected, net0.supernet_for(&[net1, net2, net3, net4, net5, net6, net7]));
2747        assert_eq!(expected, net1.supernet_for(&[net0, net2, net3, net4, net5, net6, net7]));
2748        assert_eq!(expected, net2.supernet_for(&[net0, net1, net3, net4, net5, net6, net7]));
2749        assert_eq!(expected, net3.supernet_for(&[net0, net1, net2, net4, net5, net6, net7]));
2750        assert_eq!(expected, net4.supernet_for(&[net0, net1, net2, net3, net5, net6, net7]));
2751        assert_eq!(expected, net5.supernet_for(&[net0, net1, net2, net3, net4, net6, net7]));
2752        assert_eq!(expected, net6.supernet_for(&[net0, net1, net2, net3, net4, net5, net7]));
2753        assert_eq!(expected, net7.supernet_for(&[net0, net1, net2, net3, net4, net5, net6]));
2754    }
2755
2756    #[test]
2757    fn ipv4_supernet_for_many_more() {
2758        let nets = &[
2759            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 28)).unwrap(),
2760            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 16), 28)).unwrap(),
2761            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 32), 28)).unwrap(),
2762            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 48), 28)).unwrap(),
2763            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 64), 28)).unwrap(),
2764            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 80), 28)).unwrap(),
2765            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 96), 28)).unwrap(),
2766            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 112), 28)).unwrap(),
2767            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 128), 28)).unwrap(),
2768            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 144), 28)).unwrap(),
2769            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 160), 28)).unwrap(),
2770            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 176), 28)).unwrap(),
2771            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 192), 28)).unwrap(),
2772            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 208), 28)).unwrap(),
2773            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 224), 28)).unwrap(),
2774            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 240), 28)).unwrap(),
2775        ];
2776
2777        let expected = Ipv4Network::try_from((Ipv4Addr::new(192, 0, 2, 0), 24)).unwrap();
2778        assert_eq!(expected, nets[0].supernet_for(&nets[1..]).to_contiguous());
2779    }
2780
2781    #[test]
2782    fn ipv4_supernet_for_wide() {
2783        let nets = &[
2784            Ipv4Network::try_from((Ipv4Addr::new(10, 40, 101, 1), 32)).unwrap(),
2785            Ipv4Network::try_from((Ipv4Addr::new(10, 40, 102, 1), 32)).unwrap(),
2786            Ipv4Network::try_from((Ipv4Addr::new(10, 40, 103, 1), 32)).unwrap(),
2787        ];
2788
2789        let expected = Ipv4Network::try_from((Ipv4Addr::new(10, 40, 100, 0), 22)).unwrap();
2790        assert_eq!(expected, nets[0].supernet_for(&nets[1..]).to_contiguous());
2791    }
2792
2793    #[test]
2794    fn ipv4_supernet_for_wide_more() {
2795        let nets = &[
2796            Ipv4Network::try_from((Ipv4Addr::new(10, 40, 101, 1), 32)).unwrap(),
2797            Ipv4Network::try_from((Ipv4Addr::new(10, 40, 102, 1), 32)).unwrap(),
2798            Ipv4Network::try_from((Ipv4Addr::new(11, 40, 103, 1), 32)).unwrap(),
2799        ];
2800
2801        let expected = Ipv4Network::try_from((Ipv4Addr::new(10, 0, 0, 0), 7)).unwrap();
2802        assert_eq!(expected, nets[0].supernet_for(&nets[1..]).to_contiguous());
2803    }
2804
2805    #[test]
2806    fn ipv4_supernet_for_min() {
2807        let nets = &[
2808            Ipv4Network::try_from((Ipv4Addr::new(192, 168, 0, 0), 24)).unwrap(),
2809            Ipv4Network::try_from((Ipv4Addr::new(192, 168, 1, 0), 24)).unwrap(),
2810            Ipv4Network::try_from((Ipv4Addr::new(192, 168, 2, 0), 24)).unwrap(),
2811            Ipv4Network::try_from((Ipv4Addr::new(192, 168, 100, 0), 24)).unwrap(),
2812            Ipv4Network::try_from((Ipv4Addr::new(192, 168, 200, 0), 24)).unwrap(),
2813        ];
2814
2815        let expected = Ipv4Network::try_from((Ipv4Addr::new(192, 168, 0, 0), 16)).unwrap();
2816        assert_eq!(expected, nets[0].supernet_for(&nets[1..]).to_contiguous());
2817    }
2818
2819    #[test]
2820    fn ipv4_supernet_for_unspecified() {
2821        let nets = &[
2822            Ipv4Network::try_from((Ipv4Addr::new(128, 0, 0, 0), 24)).unwrap(),
2823            Ipv4Network::try_from((Ipv4Addr::new(192, 0, 0, 0), 24)).unwrap(),
2824            Ipv4Network::try_from((Ipv4Addr::new(65, 0, 0, 0), 24)).unwrap(),
2825        ];
2826
2827        let expected = Ipv4Network::try_from((Ipv4Addr::new(0, 0, 0, 0), 0)).unwrap();
2828        assert_eq!(expected, nets[0].supernet_for(&nets[1..]).to_contiguous());
2829    }
2830
2831    #[test]
2832    fn ipv4_supernet_for_non_contiguous() {
2833        let nets = &[
2834            Ipv4Network::new(Ipv4Addr::new(10, 40, 0, 1), Ipv4Addr::new(255, 255, 0, 255)),
2835            Ipv4Network::new(Ipv4Addr::new(10, 40, 0, 2), Ipv4Addr::new(255, 255, 0, 255)),
2836            Ipv4Network::new(Ipv4Addr::new(11, 40, 0, 3), Ipv4Addr::new(255, 255, 0, 255)),
2837        ];
2838
2839        let expected = Ipv4Network::try_from((Ipv4Addr::new(10, 0, 0, 0), 7)).unwrap();
2840        assert_eq!(expected, nets[0].supernet_for(&nets[1..]).to_contiguous());
2841    }
2842
2843    #[test]
2844    fn ipv4_last_addr() {
2845        // Contiguous networks (broadcast addresses).
2846        let net = Ipv4Network::new(Ipv4Addr::new(192, 168, 1, 0), Ipv4Addr::new(255, 255, 255, 0));
2847        assert_eq!(Ipv4Addr::new(192, 168, 1, 255), net.last_addr());
2848
2849        let net = Ipv4Network::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(255, 255, 255, 0));
2850        assert_eq!(Ipv4Addr::new(10, 0, 0, 255), net.last_addr());
2851
2852        let net = Ipv4Network::new(Ipv4Addr::new(172, 16, 0, 0), Ipv4Addr::new(255, 255, 0, 0));
2853        assert_eq!(Ipv4Addr::new(172, 16, 255, 255), net.last_addr());
2854
2855        // Single address networks.
2856        let net = Ipv4Network::new(Ipv4Addr::new(10, 0, 0, 1), Ipv4Addr::new(255, 255, 255, 255));
2857        assert_eq!(Ipv4Addr::new(10, 0, 0, 1), net.last_addr());
2858
2859        // Unspecified network.
2860        let net = Ipv4Network::UNSPECIFIED;
2861        assert_eq!(Ipv4Addr::new(255, 255, 255, 255), net.last_addr());
2862
2863        // Non-contiguous networks.
2864        let net = Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 1), Ipv4Addr::new(255, 255, 0, 255));
2865        assert_eq!(Ipv4Addr::new(192, 168, 255, 1), net.last_addr());
2866
2867        let net = Ipv4Network::new(Ipv4Addr::new(10, 0, 0, 42), Ipv4Addr::new(255, 0, 255, 255));
2868        assert_eq!(Ipv4Addr::new(10, 255, 0, 42), net.last_addr());
2869
2870        // Edge cases.
2871        let net = Ipv4Network::new(Ipv4Addr::new(255, 255, 255, 255), Ipv4Addr::new(255, 255, 255, 255));
2872        assert_eq!(Ipv4Addr::new(255, 255, 255, 255), net.last_addr());
2873
2874        let net = Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), Ipv4Addr::new(255, 0, 0, 0));
2875        assert_eq!(Ipv4Addr::new(127, 255, 255, 255), net.last_addr());
2876    }
2877
2878    #[test]
2879    fn parse_ipv6_explicit_mask_normalizes_addr() {
2880        // Address bits outside the mask should be cleared.
2881        assert_eq!(
2882            Ipv6Network::new(
2883                Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
2884                Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
2885            ),
2886            Ipv6Network::parse("2a02:6b8:c00:1:2:3:4:5/ffff:ffff:ff00::").unwrap()
2887        );
2888    }
2889
2890    #[test]
2891    fn test_ipv6_addr_as_u128() {
2892        assert_eq!(
2893            0x2a02_06b8_0c00_0000_0000_f800_0000_0000u128,
2894            (*Ipv6Network::parse("2a02:6b8:c00::f800:0:0/ffff:ffff:ff00:0:ffff:f800::")
2895                .unwrap()
2896                .addr())
2897            .into()
2898        );
2899    }
2900
2901    #[test]
2902    fn test_net_ipv6_contains() {
2903        assert!(
2904            Ipv6Network::parse("::/0")
2905                .unwrap()
2906                .contains(&Ipv6Network::parse("::1").unwrap())
2907        );
2908        assert!(
2909            Ipv6Network::parse("::/32")
2910                .unwrap()
2911                .contains(&Ipv6Network::parse("::/33").unwrap())
2912        );
2913
2914        assert!(
2915            !Ipv6Network::parse("::/33")
2916                .unwrap()
2917                .contains(&Ipv6Network::parse("::/32").unwrap())
2918        );
2919    }
2920
2921    #[test]
2922    fn test_net_ipv6_contains_self() {
2923        assert!(
2924            Ipv6Network::parse("::1")
2925                .unwrap()
2926                .contains(&Ipv6Network::parse("::1").unwrap())
2927        );
2928    }
2929
2930    #[test]
2931    fn test_net_ipv6_non_contiguous_contains_contiguous() {
2932        assert!(
2933            Ipv6Network::parse("2a02:6b8:c00::4d71:0:0/ffff:ffff:ff00::ffff:ffff:0:0")
2934                .unwrap()
2935                .contains(&Ipv6Network::parse("2a02:6b8:c00:1234:0:4d71::1").unwrap())
2936        );
2937    }
2938
2939    #[test]
2940    fn test_net_ipv6_is_contiguous() {
2941        assert!(Ipv6Network::parse("::/0").unwrap().is_contiguous());
2942        assert!(Ipv6Network::parse("::1").unwrap().is_contiguous());
2943        assert!(Ipv6Network::parse("2a02:6b8:c00::/40").unwrap().is_contiguous());
2944        assert!(
2945            Ipv6Network::parse("2a02:6b8:c00:1:2:3:4:1/127")
2946                .unwrap()
2947                .is_contiguous()
2948        );
2949        assert!(
2950            Ipv6Network::parse("2a02:6b8:c00:1:2:3:4:1/128")
2951                .unwrap()
2952                .is_contiguous()
2953        );
2954        assert!(Ipv6Network::parse("2a02:6b8:c00:1:2:3:4:1").unwrap().is_contiguous());
2955
2956        assert!(
2957            !Ipv6Network::parse("2a02:6b8:c00::f800:0:0/ffff:ffff:ff00::ffff:ffff:0:0")
2958                .unwrap()
2959                .is_contiguous()
2960        );
2961        assert!(
2962            !Ipv6Network::parse("2a02:6b8:c00::f800:0:0/ffff:ffff:ff00:0:ffff:f800::")
2963                .unwrap()
2964                .is_contiguous()
2965        );
2966        assert!(
2967            !Ipv6Network::parse("2a02:6b8:0:0:1234:5678::/ffff:ffff:0:0:ffff:ffff:0:0")
2968                .unwrap()
2969                .is_contiguous()
2970        );
2971        assert!(
2972            !Ipv6Network::parse("2a02:6b8:0:0:1234:5678::/ffff:ffff:0:0:f0f0:f0f0:f0f0:f0f0")
2973                .unwrap()
2974                .is_contiguous()
2975        );
2976    }
2977
2978    #[test]
2979    fn ipv6_supernet_for() {
2980        let nets = &[
2981            Ipv6Network::parse("2001:db8:1::/32").unwrap(),
2982            Ipv6Network::parse("2001:db8:2::/39").unwrap(),
2983        ];
2984
2985        let expected = Ipv6Network::parse("2001:db8::/32").unwrap();
2986        assert_eq!(expected, nets[0].supernet_for(&nets[1..]));
2987    }
2988
2989    #[test]
2990    fn ipv6_supernet_for_wide() {
2991        let nets = &[
2992            Ipv6Network::parse("2013:db8:1::1/64").unwrap(),
2993            Ipv6Network::parse("2013:db8:2::1/64").unwrap(),
2994        ];
2995
2996        let expected = Ipv6Network::parse("2013:db8::/46").unwrap();
2997        assert_eq!(expected, nets[0].supernet_for(&nets[1..]));
2998    }
2999
3000    #[test]
3001    fn ipv6_supernet_for_unspecified() {
3002        let nets = &[
3003            Ipv6Network::parse("8001:db8:1::/34").unwrap(),
3004            Ipv6Network::parse("2013:db8:2::/32").unwrap(),
3005        ];
3006
3007        let expected = Ipv6Network::parse("::/0").unwrap();
3008        assert_eq!(expected, nets[0].supernet_for(&nets[1..]));
3009    }
3010
3011    #[test]
3012    fn ipv6_supernet_for_non_contiguous() {
3013        let nets = &[
3014            Ipv6Network::parse("2a02:6b8:c00::48aa:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap(),
3015            Ipv6Network::parse("2a02:6b8:c00::4707:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap(),
3016        ];
3017
3018        let expected = Ipv6Network::parse("2a02:6b8:c00::4000:0:0/ffff:ffff:ff00::ffff:f000:0:0").unwrap();
3019        assert_eq!(expected, nets[0].supernet_for(&nets[1..]));
3020    }
3021
3022    #[test]
3023    fn ipv6_supernet_for_non_contiguous_different_aggregates() {
3024        let nets = &[
3025            Ipv6Network::parse("2a02:6b8:c00::48aa:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap(),
3026            Ipv6Network::parse("2a02:6b8:fc00::4707:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap(),
3027        ];
3028
3029        let expected = Ipv6Network::parse("2a02:6b8::/32").unwrap();
3030        assert_eq!(expected, nets[0].supernet_for(&nets[1..]));
3031    }
3032
3033    #[test]
3034    fn test_net_display_addr() {
3035        let net = Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 1), Ipv4Addr::new(255, 255, 255, 255));
3036        assert_eq!("127.0.0.1/32", &format!("{net}"));
3037
3038        let net = Ipv6Network::new(
3039            Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0, 1),
3040            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
3041        );
3042        assert_eq!("2a02:6b8::1/128", &format!("{net}"));
3043    }
3044
3045    #[test]
3046    fn test_net_display_cidr() {
3047        let net = Ipv4Network::parse("10.0.0.0/24").unwrap();
3048        assert_eq!("10.0.0.0/24", &format!("{net}"));
3049
3050        let net = Ipv6Network::parse("2a02:6b8:c00:0:1:2::/96").unwrap();
3051        assert_eq!("2a02:6b8:c00:0:1:2::/96", &format!("{net}"));
3052    }
3053
3054    #[test]
3055    fn test_net_display_non_contiguous() {
3056        let net = Ipv4Network::parse("10.0.1.0/255.0.255.0").unwrap();
3057        assert_eq!("10.0.1.0/255.0.255.0", &format!("{net}"));
3058
3059        let net = Ipv6Network(
3060            "2a02:6b8:0:0:0:1234::".parse().unwrap(),
3061            "ffff:ffff:0:0:ffff:ffff:0:0".parse().unwrap(),
3062        );
3063        assert_eq!("2a02:6b8::1234:0:0/ffff:ffff::ffff:ffff:0:0", &format!("{net}"));
3064
3065        let net = Ipv6Network(
3066            "2a02:6b8:0:0:1234:5678::".parse().unwrap(),
3067            "ffff:ffff:0:0:ffff:ffff:0:0".parse().unwrap(),
3068        );
3069        assert_eq!("2a02:6b8::1234:5678:0:0/ffff:ffff::ffff:ffff:0:0", &format!("{net}"));
3070    }
3071
3072    #[test]
3073    fn test_ipv4_binary_split_empty() {
3074        assert!(ipv4_binary_split::<Ipv4Network>(&[]).is_none());
3075    }
3076
3077    #[test]
3078    fn test_ipv4_binary_split_less_than_required_networks() {
3079        let nets = &["127.0.0.1", "127.0.0.2"];
3080        let mut nets: Vec<_> = nets.iter().map(|net| Ipv4Network::parse(net).unwrap()).collect();
3081        nets.sort();
3082        nets.dedup();
3083
3084        assert!(ipv4_binary_split(&nets).is_none());
3085    }
3086
3087    #[test]
3088    fn test_ipv4_binary_split_three_nets() {
3089        let nets = &["127.0.0.1", "127.0.0.2", "127.0.0.3"];
3090        let mut nets: Vec<_> = nets.iter().map(|net| Ipv4Network::parse(net).unwrap()).collect();
3091        nets.sort();
3092        nets.dedup();
3093
3094        let (supernet, range) = ipv4_binary_split(&nets).unwrap();
3095        // 127.0.0.2/31 in binary is "0b...10/0b...10", which contains both "127.0.0.2"
3096        // and "127.0.0.3".
3097        assert_eq!(Ipv4Network::parse("127.0.0.2/31").unwrap(), supernet);
3098
3099        for (idx, net) in nets.iter().enumerate() {
3100            assert_eq!(range.contains(&idx), supernet.contains(net));
3101        }
3102    }
3103
3104    #[test]
3105    fn test_ipv4_binary_split_more_nets() {
3106        // .
3107        // ├─ 10.204.46.68/31
3108        // ├─ 10.204.49.12/31
3109        // ├─ 10.204.49.14/31
3110        // ├─ 10.204.49.18/31
3111        // └─ 10.204.49.32/28 [*]
3112        //   ├─ 10.204.49.32/31
3113        //   ├─ 10.204.49.34/31
3114        //   ├─ 10.204.49.36/31
3115        //   ├─ 10.204.49.38/31
3116        //   └─ 10.204.49.40/31
3117
3118        let nets = &[
3119            "10.204.46.68/31",
3120            "10.204.49.12/31",
3121            "10.204.49.14/31",
3122            "10.204.49.18/31",
3123            "10.204.49.32/31",
3124            "10.204.49.34/31",
3125            "10.204.49.36/31",
3126            "10.204.49.38/31",
3127            "10.204.49.40/31",
3128        ];
3129        let mut nets: Vec<_> = nets.iter().map(|net| Ipv4Network::parse(net).unwrap()).collect();
3130        nets.sort();
3131        nets.dedup();
3132
3133        let (supernet, range) = ipv4_binary_split(&nets).unwrap();
3134
3135        assert_eq!(Ipv4Network::parse("10.204.49.32/28").unwrap(), supernet);
3136
3137        for (idx, net) in nets.iter().enumerate() {
3138            assert_eq!(range.contains(&idx), supernet.contains(net));
3139        }
3140    }
3141
3142    #[test]
3143    fn test_ipv4_binary_split_even_number_of_nets() {
3144        // .
3145        // ├─ 10.204.46.54/31
3146        // ├─ 10.204.46.68/31
3147        // ├─ 10.204.49.12/31
3148        // ├─ 10.204.49.14/31
3149        // ├─ 10.204.49.18/31
3150        // └─ 10.204.49.32/28 [*]
3151        //   ├─ 10.204.49.32/31
3152        //   ├─ 10.204.49.34/31
3153        //   ├─ 10.204.49.36/31
3154        //   ├─ 10.204.49.38/31
3155        //   └─ 10.204.49.40/31
3156
3157        let nets = &[
3158            "10.204.46.54/31",
3159            "10.204.46.68/31",
3160            "10.204.49.12/31",
3161            "10.204.49.14/31",
3162            "10.204.49.18/31",
3163            "10.204.49.32/31",
3164            "10.204.49.34/31",
3165            "10.204.49.36/31",
3166            "10.204.49.38/31",
3167            "10.204.49.40/31",
3168        ];
3169        let mut nets: Vec<_> = nets.iter().map(|net| Ipv4Network::parse(net).unwrap()).collect();
3170        nets.sort();
3171        nets.dedup();
3172
3173        let (supernet, range) = ipv4_binary_split(&nets).unwrap();
3174
3175        assert_eq!(Ipv4Network::parse("10.204.49.32/28").unwrap(), supernet);
3176
3177        for (idx, net) in nets.iter().enumerate() {
3178            assert_eq!(range.contains(&idx), supernet.contains(net));
3179        }
3180    }
3181
3182    #[test]
3183    fn test_ipv4_binary_split_in_the_middle() {
3184        // .
3185        // ├─ 10.204.46.50/31
3186        // ├─ 10.204.46.54/31
3187        // ├─ 10.204.47.22/31
3188        // ├─ 10.204.49.0/26 [*]
3189        // │ ├─ 10.204.49.24/31
3190        // │ ├─ 10.204.49.26/31
3191        // │ ├─ 10.204.49.28/31
3192        // │ ├─ 10.204.49.32/31
3193        // │ ├─ 10.204.49.34/31
3194        // │ └─ 10.204.49.36/31
3195        // ├─ 10.204.50.38/31
3196        // └─ 10.204.50.40/31
3197
3198        let nets = &[
3199            "10.204.46.50/31",
3200            "10.204.46.54/31",
3201            "10.204.47.22/31",
3202            "10.204.49.24/31",
3203            "10.204.49.26/31",
3204            "10.204.49.28/31",
3205            "10.204.49.32/31",
3206            "10.204.49.34/31",
3207            "10.204.49.36/31",
3208            "10.204.50.38/31",
3209            "10.204.50.40/31",
3210        ];
3211        let mut nets: Vec<_> = nets.iter().map(|net| Ipv4Network::parse(net).unwrap()).collect();
3212        nets.sort();
3213        nets.dedup();
3214
3215        let (supernet, range) = ipv4_binary_split(&nets).unwrap();
3216
3217        assert_eq!(Ipv4Network::parse("10.204.49.0/26").unwrap(), supernet);
3218
3219        for (idx, net) in nets.iter().enumerate() {
3220            assert_eq!(range.contains(&idx), supernet.contains(net));
3221        }
3222    }
3223
3224    #[test]
3225    fn test_ipv6_binary_split_empty() {
3226        assert!(ipv6_binary_split::<Ipv6Network>(&[]).is_none());
3227    }
3228
3229    #[test]
3230    fn test_ipv6_binary_split_less_than_required_networks() {
3231        let nets = &["::1", "::2"];
3232        let mut nets: Vec<_> = nets.iter().map(|net| Ipv6Network::parse(net).unwrap()).collect();
3233        nets.sort();
3234        nets.dedup();
3235
3236        assert!(ipv6_binary_split(&nets).is_none());
3237    }
3238
3239    #[test]
3240    fn test_ipv6_binary_split_three_nets() {
3241        let nets = &["::1", "::2", "::3"];
3242        let mut nets: Vec<_> = nets.iter().map(|net| Ipv6Network::parse(net).unwrap()).collect();
3243        nets.sort();
3244        nets.dedup();
3245
3246        let (supernet, range) = ipv6_binary_split(&nets).unwrap();
3247        // ::2/127 in binary is "0b...10/0b...10", which contains both "::2" and "::3".
3248        assert_eq!(Ipv6Network::parse("::2/127").unwrap(), supernet);
3249
3250        for (idx, net) in nets.iter().enumerate() {
3251            assert_eq!(range.contains(&idx), supernet.contains(net));
3252        }
3253    }
3254
3255    #[test]
3256    fn test_ipv6_binary_split_more_nets() {
3257        let nets = &[
3258            "2a02:6b8:0:2a03::/64",
3259            "2a02:6b8:0:2a13::/64",
3260            "2a02:6b8:0:2a16::/64",
3261            "2a02:6b8:0:2a18::/64",
3262            "2a02:6b8:0:2a19::/64",
3263            "2a02:6b8:0:2a1c::/64",
3264            "2a02:6b8:0:2a1d::/64",
3265            "2a02:6b8:0:2a24::/64",
3266            "2a02:6b8:0:2800::/55",
3267        ];
3268        let mut nets: Vec<_> = nets.iter().map(|net| Ipv6Network::parse(net).unwrap()).collect();
3269        nets.sort();
3270        nets.dedup();
3271
3272        let (supernet, range) = ipv6_binary_split(&nets).unwrap();
3273
3274        assert_eq!(Ipv6Network::parse("2a02:6b8:0:2a10::/60").unwrap(), supernet);
3275
3276        for (idx, net) in nets.iter().enumerate() {
3277            assert_eq!(range.contains(&idx), supernet.contains(net));
3278        }
3279    }
3280
3281    #[test]
3282    fn test_ipv6_binary_split_even_number_of_nets() {
3283        let nets = &[
3284            "2a02:6b8:0:2318::/64",
3285            "2a02:6b8:0:231e::/64",
3286            "2a02:6b8:0:231f::/64",
3287            "2a02:6b8:0:2302::/64",
3288            "2a02:6b8:0:2303::/64",
3289            "2a02:6b8:0:2305::/64",
3290            "2a02:6b8:0:2306::/64",
3291            "2a02:6b8:0:2307::/64",
3292            "2a02:6b8:0:2311::/64",
3293            "2a02:6b8:0:2314::/64",
3294        ];
3295        let mut nets: Vec<_> = nets.iter().map(|net| Ipv6Network::parse(net).unwrap()).collect();
3296        nets.sort();
3297        nets.dedup();
3298
3299        let (supernet, range) = ipv6_binary_split(&nets).unwrap();
3300
3301        assert_eq!(Ipv6Network::parse("2a02:6b8:0:2300::/61").unwrap(), supernet);
3302
3303        for (idx, net) in nets.iter().enumerate() {
3304            assert_eq!(range.contains(&idx), supernet.contains(net));
3305        }
3306    }
3307
3308    #[test]
3309    fn test_ipv6_binary_split_in_the_middle() {
3310        let nets = &[
3311            "2a02:6b8:0:2302::/64",
3312            "2a02:6b8:0:2303::/64",
3313            "2a02:6b8:0:2305::/64",
3314            "2a02:6b8:0:2308::/64",
3315            "2a02:6b8:0:2309::/64",
3316            "2a02:6b8:0:230a::/64",
3317            "2a02:6b8:0:230b::/64",
3318            "2a02:6b8:0:230c::/64",
3319            "2a02:6b8:0:230d::/64",
3320            "2a02:6b8:0:2314::/64",
3321            "2a02:6b8:0:231f::/64",
3322        ];
3323        let mut nets: Vec<_> = nets.iter().map(|net| Ipv6Network::parse(net).unwrap()).collect();
3324        nets.sort();
3325        nets.dedup();
3326
3327        let (supernet, range) = ipv6_binary_split(&nets).unwrap();
3328
3329        assert_eq!(Ipv6Network::parse("2a02:6b8:0:2308::/61").unwrap(), supernet);
3330
3331        for (idx, net) in nets.iter().enumerate() {
3332            assert_eq!(range.contains(&idx), supernet.contains(net));
3333        }
3334    }
3335
3336    #[test]
3337    fn test_ipv6_binary_split_non_contiguous() {
3338        let nets = &[
3339            "2a02:6b8:c00::4510:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3340            "2a02:6b8:c00::4511:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3341            "2a02:6b8:c00::4512:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3342            "2a02:6b8:c00::4513:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3343            "2a02:6b8:c00::4514:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3344            "2a02:6b8:c00::4515:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3345            "2a02:6b8:c00::4516:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3346            "2a02:6b8:c00::4517:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3347            "2a02:6b8:c00::4518:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3348            "2a02:6b8:c00::4519:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3349            "2a02:6b8:c00::451a:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3350        ];
3351        let mut nets: Vec<_> = nets.iter().map(|net| Ipv6Network::parse(net).unwrap()).collect();
3352        nets.sort();
3353        nets.dedup();
3354
3355        let (supernet, range) = ipv6_binary_split(&nets).unwrap();
3356
3357        assert_eq!(
3358            Ipv6Network::parse("2a02:6b8:c00::4510:0:0/ffff:ffff:ff00:0:ffff:fff8::").unwrap(),
3359            supernet
3360        );
3361
3362        for (idx, net) in nets.iter().enumerate() {
3363            assert_eq!(range.contains(&idx), supernet.contains(net));
3364        }
3365    }
3366
3367    #[test]
3368    fn test_ipv6_binary_split_non_contiguous_in_the_middle() {
3369        let nets = &[
3370            "2a02:6b8:c00::2302:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3371            "2a02:6b8:c00::2303:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3372            "2a02:6b8:c00::2305:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3373            "2a02:6b8:c00::2308:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3374            "2a02:6b8:c00::2309:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3375            "2a02:6b8:c00::230a:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3376            "2a02:6b8:c00::230b:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3377            "2a02:6b8:c00::230c:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3378            "2a02:6b8:c00::230d:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3379            "2a02:6b8:c00::2314:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3380            "2a02:6b8:c00::231f:0:0/ffff:ffff:ff00::ffff:ffff:0:0",
3381        ];
3382        let mut nets: Vec<_> = nets.iter().map(|net| Ipv6Network::parse(net).unwrap()).collect();
3383        nets.sort();
3384        nets.dedup();
3385
3386        let (supernet, range) = ipv6_binary_split(&nets).unwrap();
3387
3388        assert_eq!(
3389            Ipv6Network::parse("2a02:6b8:c00::2308:0:0/ffff:ffff:ff00:0:ffff:fff8::").unwrap(),
3390            supernet
3391        );
3392
3393        for (idx, net) in nets.iter().enumerate() {
3394            assert_eq!(range.contains(&idx), supernet.contains(net));
3395        }
3396    }
3397
3398    #[test]
3399    fn test_ipnetwork_parse_v4() {
3400        let expected = IpNetwork::V4(Ipv4Network::new(
3401            Ipv4Addr::new(192, 168, 1, 0),
3402            Ipv4Addr::new(255, 255, 255, 0),
3403        ));
3404
3405        assert_eq!(expected, IpNetwork::parse("192.168.1.0/24").unwrap());
3406    }
3407
3408    #[test]
3409    fn test_ipnetwork_parse_v6() {
3410        let expected = IpNetwork::V6(Ipv6Network::new(
3411            Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
3412            Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
3413        ));
3414
3415        assert_eq!(expected, IpNetwork::parse("2a02:6b8:c00::/40").unwrap());
3416    }
3417
3418    #[test]
3419    fn test_ipnetwork_parse_invalid() {
3420        assert_eq!(
3421            IpNetParseError::CidrOverflow(CidrOverflowError(33, 32)),
3422            IpNetwork::parse("192.168.1.0/33").unwrap_err(),
3423        );
3424    }
3425
3426    #[test]
3427    fn test_ipnetwork_parse_invalid_v6() {
3428        assert_eq!(
3429            IpNetParseError::CidrOverflow(CidrOverflowError(129, 128)),
3430            IpNetwork::parse("2a02:6b8:c00::/129").unwrap_err(),
3431        );
3432    }
3433
3434    #[test]
3435    fn test_contiguous_ip_network_parse_v4() {
3436        let expected = Contiguous(Ipv4Network::new(
3437            Ipv4Addr::new(192, 168, 1, 0),
3438            Ipv4Addr::new(255, 255, 255, 0),
3439        ));
3440
3441        assert_eq!(expected, Contiguous::<Ipv4Network>::parse("192.168.1.0/24").unwrap(),);
3442    }
3443
3444    #[test]
3445    fn test_contiguous_ip_network_parse_v4_invalid() {
3446        assert_eq!(
3447            ContiguousIpNetParseError::NonContiguousNetwork,
3448            Contiguous::<Ipv4Network>::parse("192.168.0.1/255.255.0.255").unwrap_err(),
3449        );
3450    }
3451
3452    #[test]
3453    fn test_contiguous_ip_network_parse_v6() {
3454        let expected = Contiguous(Ipv6Network::new(
3455            Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
3456            Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
3457        ));
3458
3459        assert_eq!(expected, Contiguous::<Ipv6Network>::parse("2a02:6b8:c00::/40").unwrap(),);
3460    }
3461
3462    #[test]
3463    fn test_contiguous_ip_network_parse_v6_invalid() {
3464        assert_eq!(
3465            ContiguousIpNetParseError::NonContiguousNetwork,
3466            Contiguous::<Ipv6Network>::parse("2a02:6b8:c00::1234:0:0/ffff:ffff:ff00::ffff:ffff:0:0").unwrap_err(),
3467        );
3468    }
3469
3470    #[test]
3471    fn ipv6_last_addr() {
3472        // Contiguous networks (broadcast-like addresses).
3473        let net = Ipv6Network::new(
3474            Ipv6Addr::new(0x2001, 0xdb8, 0x1, 0, 0, 0, 0, 0),
3475            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0, 0),
3476        );
3477        assert_eq!(
3478            Ipv6Addr::new(0x2001, 0xdb8, 0x1, 0, 0, 0, 0xffff, 0xffff),
3479            net.last_addr()
3480        );
3481
3482        let net = Ipv6Network::new(
3483            Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
3484            Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
3485        );
3486        assert_eq!(
3487            Ipv6Addr::new(0x2a02, 0x6b8, 0x0cff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
3488            net.last_addr()
3489        );
3490
3491        let net = Ipv6Network::new(
3492            Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0, 0),
3493            Ipv6Addr::new(0xffff, 0xffff, 0, 0, 0, 0, 0, 0),
3494        );
3495        assert_eq!(
3496            Ipv6Addr::new(0x2a02, 0x6b8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
3497            net.last_addr()
3498        );
3499
3500        // Single address networks.
3501        let net = Ipv6Network::new(
3502            Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1),
3503            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
3504        );
3505        assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x1), net.last_addr());
3506
3507        // Unspecified network.
3508        let net = Ipv6Network::UNSPECIFIED;
3509        assert_eq!(
3510            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
3511            net.last_addr()
3512        );
3513
3514        // Non-contiguous networks.
3515        let net = Ipv6Network::new(
3516            Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0x1234, 0, 0),
3517            Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0xffff, 0xffff, 0, 0),
3518        );
3519        assert_eq!(
3520            Ipv6Addr::new(0x2a02, 0x6b8, 0x0cff, 0xffff, 0, 0x1234, 0xffff, 0xffff),
3521            net.last_addr()
3522        );
3523
3524        // Edge cases.
3525        let net = Ipv6Network::new(
3526            Ipv6Addr::new(0x2a02, 0x6b8, 0xc00, 0, 0, 0, 0, 0),
3527            Ipv6Addr::new(0xffff, 0xffff, 0xff00, 0, 0, 0, 0, 0),
3528        );
3529        assert_eq!(
3530            Ipv6Addr::new(0x2a02, 0x6b8, 0x0cff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff),
3531            net.last_addr()
3532        );
3533
3534        let net = Ipv6Network::new(
3535            Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0, 0),
3536            Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0),
3537        );
3538        assert_eq!(
3539            Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff),
3540            net.last_addr()
3541        );
3542    }
3543
3544    #[test]
3545    fn ipnetwork_last_addr() {
3546        use core::net::IpAddr;
3547
3548        // IPv4 networks.
3549        let net = IpNetwork::parse("192.168.1.0/24").unwrap();
3550        assert_eq!(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 255)), net.last_addr());
3551
3552        let net = IpNetwork::parse("10.0.0.1").unwrap();
3553        assert_eq!(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), net.last_addr());
3554
3555        let net = IpNetwork::parse("0.0.0.0/0").unwrap();
3556        assert_eq!(IpAddr::V4(Ipv4Addr::new(255, 255, 255, 255)), net.last_addr());
3557
3558        // IPv6 networks.
3559        let net = IpNetwork::parse("2001:db8:1::/64").unwrap();
3560        assert_eq!(
3561            IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0x1, 0, 0xffff, 0xffff, 0xffff, 0xffff)),
3562            net.last_addr()
3563        );
3564
3565        let net = IpNetwork::parse("2a02:6b8::1").unwrap();
3566        assert_eq!(
3567            IpAddr::V6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0, 0x1)),
3568            net.last_addr()
3569        );
3570
3571        let net = IpNetwork::parse("::/0").unwrap();
3572        assert_eq!(
3573            IpAddr::V6(Ipv6Addr::new(
3574                0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
3575            )),
3576            net.last_addr()
3577        );
3578    }
3579}