net_types/
ip.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// TODO: Edit this doc comment (it's copy+pasted from the Netstack3 core)
6
7//! Internet Protocol (IP) types.
8//!
9//! This module provides support for various types and traits relating to IPv4
10//! and IPv6, including a number of mechanisms for abstracting over details
11//! which are shared between IPv4 and IPv6.
12//!
13//! # `Ip` and `IpAddress`
14//!
15//! The most important traits are [`Ip`] and [`IpAddress`].
16//!
17//! `Ip` represents a version of the IP protocol - either IPv4 or IPv6 - and is
18//! implemented by [`Ipv4`] and [`Ipv6`]. These types exist only at the type
19//! level - they cannot be constructed at runtime. They provide a place to put
20//! constants and functionality which are not associated with a particular type,
21//! and they allow code to be written which is generic over the version of the
22//! IP protocol. For example:
23//!
24//! ```rust
25//! # use net_types::ip::{Ip, IpAddress, Subnet};
26//! struct Entry<A: IpAddress> {
27//!     subnet: Subnet<A>,
28//!     dest: Destination<A>,
29//! }
30//!
31//! enum Destination<A: IpAddress> {
32//!     Local { device_id: usize },
33//!     Remote { dst: A },
34//! }
35//!
36//! struct ForwardingTable<I: Ip> {
37//!     entries: Vec<Entry<I::Addr>>,
38//! }
39//! ```
40//!
41//! See also [`IpVersionMarker`].
42//!
43//! The `IpAddress` trait is implemented by the concrete [`Ipv4Addr`] and
44//! [`Ipv6Addr`] types.
45//!
46//! # Runtime types
47//!
48//! Sometimes, it is not known at compile time which version of a given type -
49//! IPv4 or IPv6 - is present. For these cases, enums are provided with variants
50//! for both IPv4 and IPv6. These are [`IpAddr`], [`SubnetEither`], and
51//! [`AddrSubnetEither`].
52//!
53//! # Composite types
54//!
55//! This modules also provides composite types such as [`Subnet`] and
56//! [`AddrSubnet`].
57
58use core::fmt::{self, Debug, Display, Formatter};
59use core::hash::Hash;
60use core::mem;
61use core::ops::{Deref, DerefMut};
62
63#[cfg(feature = "std")]
64use std::net;
65#[cfg(feature = "std")]
66use std::sync::Arc;
67
68pub use net_types_macros::GenericOverIp;
69use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
70
71use crate::{
72    sealed, LinkLocalAddr, LinkLocalAddress, MappedAddress, MulticastAddr, MulticastAddress,
73    NonMappedAddr, NonMulticastAddr, Scope, ScopeableAddress, SpecifiedAddr, SpecifiedAddress,
74    UnicastAddr, UnicastAddress, Witness,
75};
76
77// NOTE on passing by reference vs by value: Clippy advises us to pass IPv4
78// addresses by value, and IPv6 addresses by reference. For concrete types, we
79// do the right thing. For the IpAddress trait, we use references in order to
80// optimize (albeit very slightly) for IPv6 performance.
81
82/// An IP protocol version.
83#[allow(missing_docs)]
84#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
85pub enum IpVersion {
86    V4,
87    V6,
88}
89
90/// Evaluates `expression` for any given `ip_version`.
91///
92/// `type_param` will be defined to be [`crate::ip::Ipv4`] for
93/// [`crate::ip::IpVersion::V4`], and [`crate::ip::Ipv6`] for
94/// [`crate::ip::IpVersion::V6`].
95///
96/// Example usage:
97///
98/// ```
99/// let ip_version: IpVersion = foo();
100/// for_any_ip_version!(ip_version, I, some_ip_generic_fn::<I>());
101/// ```
102#[macro_export]
103macro_rules! for_any_ip_version {
104    ($ip_version:expr, $type_param:ident, $expression:expr) => {
105        match $ip_version {
106            $crate::ip::IpVersion::V4 => {
107                type $type_param = $crate::ip::Ipv4;
108                $expression
109            }
110            $crate::ip::IpVersion::V6 => {
111                type $type_param = $crate::ip::Ipv6;
112                $expression
113            }
114        }
115    };
116}
117
118/// A zero-sized type that carries IP version information.
119///
120/// `IpVersionMarker` is typically used by types that are generic over IP
121/// version, but without any other associated data. In this sense,
122/// `IpVersionMarker` behaves similarly to [`PhantomData`].
123///
124/// [`PhantomData`]: core::marker::PhantomData
125#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, GenericOverIp)]
126#[generic_over_ip(I, Ip)]
127pub struct IpVersionMarker<I: Ip> {
128    _marker: core::marker::PhantomData<I>,
129}
130
131impl<I: Ip> IpVersionMarker<I> {
132    /// Creates a new `IpVersionMarker`.
133    // TODO(https://github.com/rust-lang/rust/issues/67792): Remove once
134    // `const_trait_impl` is stabilized.
135    pub const fn new() -> Self {
136        Self { _marker: core::marker::PhantomData }
137    }
138}
139
140impl<I: Ip> Default for IpVersionMarker<I> {
141    fn default() -> Self {
142        Self { _marker: core::marker::PhantomData }
143    }
144}
145
146impl<I: Ip> Debug for IpVersionMarker<I> {
147    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
148        write!(f, "IpVersionMarker<{}>", I::NAME)
149    }
150}
151
152/// An IP address.
153///
154/// By default, the contained address types are [`Ipv4Addr`] and [`Ipv6Addr`].
155/// However, any types can be provided. This is intended to support types like
156/// `IpAddr<SpecifiedAddr<Ipv4Addr>, SpecifiedAddr<Ipv6Addr>>`. `From` is
157/// implemented to support conversions in both directions between
158/// `IpAddr<SpecifiedAddr<Ipv4Addr>, SpecifiedAddr<Ipv6Addr>>` and
159/// `SpecifiedAddr<IpAddr>`, and similarly for other witness types.
160#[allow(missing_docs)]
161#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
162pub enum IpAddr<V4 = Ipv4Addr, V6 = Ipv6Addr> {
163    V4(V4),
164    V6(V6),
165}
166
167impl<V4: Display, V6: Display> Display for IpAddr<V4, V6> {
168    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
169        match self {
170            Self::V4(v4) => v4.fmt(f),
171            Self::V6(v6) => v6.fmt(f),
172        }
173    }
174}
175
176impl<V4, V6> IpAddr<V4, V6> {
177    /// Transposes an `IpAddr` of a witness type to a witness type of an
178    /// `IpAddr`.
179    ///
180    /// For example, `transpose` can be used to convert an
181    /// `IpAddr<SpecifiedAddr<Ipv4Addr>, SpecifiedAddr<Ipv6Addr>>` into a
182    /// `SpecifiedAddr<IpAddr<Ipv4Addr, Ipv6Addr>>`.
183    pub fn transpose<W: IpAddrWitness<V4 = V4, V6 = V6>>(self) -> W {
184        match self {
185            IpAddr::V4(addr) => W::from_v4(addr),
186            IpAddr::V6(addr) => W::from_v6(addr),
187        }
188    }
189}
190
191impl<A: IpAddress> From<A> for IpAddr {
192    #[inline]
193    fn from(addr: A) -> IpAddr {
194        addr.to_ip_addr()
195    }
196}
197
198impl<A: IpAddress, const N: usize> From<[A; N]> for IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]> {
199    #[inline]
200    fn from(addrs: [A; N]) -> Self {
201        A::array_into_ip_addr(addrs)
202    }
203}
204
205#[cfg(feature = "std")]
206impl From<net::IpAddr> for IpAddr {
207    #[inline]
208    fn from(addr: net::IpAddr) -> IpAddr {
209        match addr {
210            net::IpAddr::V4(addr) => IpAddr::V4(addr.into()),
211            net::IpAddr::V6(addr) => IpAddr::V6(addr.into()),
212        }
213    }
214}
215
216#[cfg(feature = "std")]
217impl From<IpAddr> for net::IpAddr {
218    fn from(addr: IpAddr) -> net::IpAddr {
219        match addr {
220            IpAddr::V4(addr) => net::IpAddr::V4(addr.into()),
221            IpAddr::V6(addr) => net::IpAddr::V6(addr.into()),
222        }
223    }
224}
225
226impl IpVersion {
227    /// The number for this IP protocol version.
228    ///
229    /// 4 for `V4` and 6 for `V6`.
230    #[inline]
231    pub fn version_number(self) -> u8 {
232        match self {
233            IpVersion::V4 => 4,
234            IpVersion::V6 => 6,
235        }
236    }
237
238    /// Is this IPv4?
239    #[inline]
240    pub fn is_v4(self) -> bool {
241        self == IpVersion::V4
242    }
243
244    /// Is this IPv6?
245    #[inline]
246    pub fn is_v6(self) -> bool {
247        self == IpVersion::V6
248    }
249}
250
251/// The maximum transmit unit, i.e., the maximum size of an entire IP packet
252/// one link can transmit.
253#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
254pub struct Mtu(u32);
255
256impl Mtu {
257    /// Creates MTU from the maximum size of an entire IP packet in bytes.
258    pub const fn new(mtu: u32) -> Self {
259        Self(mtu)
260    }
261
262    /// Gets the numeric value of the MTU.
263    pub const fn get(&self) -> u32 {
264        let Self(mtu) = self;
265        *mtu
266    }
267
268    /// Creates a new `Mtu` with the maximum possible representation.
269    pub const fn max() -> Self {
270        Self(u32::MAX)
271    }
272
273    /// Equivalent to [`Mtu::max`], but with a name more telling for usage in
274    /// contexts where many `Mtu` instances are composed to enforce a minimum
275    /// `Mtu` value.
276    pub const fn no_limit() -> Self {
277        Self::max()
278    }
279}
280
281impl From<Mtu> for u32 {
282    fn from(Mtu(mtu): Mtu) -> Self {
283        mtu
284    }
285}
286
287impl From<Mtu> for usize {
288    fn from(Mtu(mtu): Mtu) -> Self {
289        mtu.try_into().expect("mtu must fit usize")
290    }
291}
292
293/// A trait for IP protocol versions.
294///
295/// `Ip` encapsulates the details of a version of the IP protocol. It includes a
296/// runtime representation of the protocol version ([`VERSION`]), the type of
297/// addresses for this version ([`Addr`]), and a number of constants which exist
298/// in both protocol versions. This trait is sealed, and there are guaranteed to
299/// be no other implementors besides these. Code - including unsafe code - may
300/// rely on this assumption for its correctness and soundness.
301///
302/// Note that the implementors of this trait cannot be instantiated; they only
303/// exist at the type level.
304///
305/// [`VERSION`]: Ip::VERSION
306/// [`Addr`]: Ip::Addr
307pub trait Ip:
308    Sized
309    + Clone
310    + Copy
311    + Debug
312    + Default
313    + Eq
314    + Hash
315    + Ord
316    + PartialEq
317    + PartialOrd
318    + Send
319    + Sync
320    + sealed::Sealed
321    + 'static
322{
323    /// The IP version.
324    ///
325    /// `V4` for IPv4 and `V6` for IPv6.
326    const VERSION: IpVersion;
327
328    /// The zero-sized-type IP version marker.
329    const VERSION_MARKER: IpVersionMarker<Self>;
330
331    /// The unspecified address.
332    ///
333    /// This is 0.0.0.0 for IPv4 and :: for IPv6.
334    const UNSPECIFIED_ADDRESS: Self::Addr;
335
336    /// The default loopback address.
337    ///
338    /// When sending packets to a loopback interface, this address is used as
339    /// the source address. It is an address in the [`LOOPBACK_SUBNET`].
340    ///
341    /// [`LOOPBACK_SUBNET`]: Ip::LOOPBACK_SUBNET
342    const LOOPBACK_ADDRESS: SpecifiedAddr<Self::Addr>;
343
344    /// The subnet of loopback addresses.
345    ///
346    /// Addresses in this subnet must not appear outside a host, and may only be
347    /// used for loopback interfaces.
348    const LOOPBACK_SUBNET: Subnet<Self::Addr>;
349
350    /// The subnet of multicast addresses.
351    const MULTICAST_SUBNET: Subnet<Self::Addr>;
352
353    /// The subnet of link-local unicast addresses.
354    ///
355    /// Note that some multicast addresses are also link-local. In IPv4, these
356    /// are contained in the [link-local multicast subnet]. In IPv6, the
357    /// link-local multicast addresses are not organized into a single subnet;
358    /// instead, whether a multicast IPv6 address is link-local is a function of
359    /// its scope.
360    ///
361    /// [link-local multicast subnet]: Ipv4::LINK_LOCAL_MULTICAST_SUBNET
362    const LINK_LOCAL_UNICAST_SUBNET: Subnet<Self::Addr>;
363
364    /// "IPv4" or "IPv6".
365    const NAME: &'static str;
366
367    /// The minimum link MTU for this version.
368    ///
369    /// Every internet link supporting this IP version must have a maximum
370    /// transmission unit (MTU) of at least this many bytes. This MTU applies to
371    /// the size of an IP packet, and does not include any extra bytes used by
372    /// encapsulating packets (Ethernet frames, GRE packets, etc).
373    const MINIMUM_LINK_MTU: Mtu;
374
375    /// The address type for this IP version.
376    ///
377    /// [`Ipv4Addr`] for IPv4 and [`Ipv6Addr`] for IPv6.
378    type Addr: IpAddress<Version = Self>
379        + GenericOverIp<Self, Type = Self::Addr>
380        + GenericOverIp<Ipv4, Type = Ipv4Addr>
381        + GenericOverIp<Ipv6, Type = Ipv6Addr>;
382
383    /// Apply one of the given functions to the input and return the result.
384    ///
385    /// This makes it possible to implement specialized behavior for IPv4 and
386    /// IPv6 versions that is more versatile than matching on [`Ip::VERSION`].
387    /// With a `match` expression, all branches must produce a value of the
388    /// same type. `map_ip` relaxes that restriction by instead requiring that
389    /// inputs and outputs are [`GenericOverIp`].
390    ///
391    /// Using `map_ip`, you can write generic code with specialized
392    /// implementations for different IP versions where some or all of the input
393    /// and output arguments have a type parameter `I: Ip`. As an example,
394    /// consider the following:
395    ///
396    /// ```
397    /// // Swaps the order of the addresses only if `I=Ipv4`.
398    /// fn swap_only_if_ipv4<I: Ip>(addrs: (I::Addr, I::Addr)) -> (I::Addr, I::Addr) {
399    ///    I::map_ip::<(I::Addr, I::Addr), (I::Addr, I::Addr)>(
400    ///        addrs,
401    ///        |(a, b): (Ipv4Addr, Ipv4Addr)| (b, a),
402    ///        |ab: (Ipv6Addr, Ipv6Addr)| ab
403    ///    )
404    /// }
405    /// ```
406    ///
407    /// Note that the input and output arguments both depend on the type
408    /// parameter `I`, but the closures take an [`Ipv4Addr`] or [`Ipv6Addr`].
409    ///
410    /// Types that don't implement `GenericOverIp` can be wrapped in
411    /// [`IpInvariant`], which implements `GenericOverIp` assuming the type
412    /// inside doesn't have any IP-related components.
413    fn map_ip<
414        In: GenericOverIp<Self, Type = In> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
415        Out: GenericOverIp<Self, Type = Out> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
416    >(
417        input: In,
418        v4: impl FnOnce(<In as GenericOverIp<Ipv4>>::Type) -> <Out as GenericOverIp<Ipv4>>::Type,
419        v6: impl FnOnce(<In as GenericOverIp<Ipv6>>::Type) -> <Out as GenericOverIp<Ipv6>>::Type,
420    ) -> Out;
421
422    /// Apply one of the given functions to the input and return the result.
423    ///
424    /// This is similar to `map_ip`, except only the input type is required to
425    /// be [`GenericOverIp`], while the output type is invariant. This allows
426    /// callers to more conveniently write this use case without having to wrap
427    /// the result in a type like [`IpInvariant`].
428    fn map_ip_in<
429        In: GenericOverIp<Self, Type = In> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
430        Out,
431    >(
432        input: In,
433        v4: impl FnOnce(<In as GenericOverIp<Ipv4>>::Type) -> Out,
434        v6: impl FnOnce(<In as GenericOverIp<Ipv6>>::Type) -> Out,
435    ) -> Out {
436        Self::map_ip::<_, IpInvariant<_>>(
437            input,
438            |input| IpInvariant(v4(input)),
439            |input| IpInvariant(v6(input)),
440        )
441        .into_inner()
442    }
443
444    /// Apply one of the given functions to the input and return the result.
445    ///
446    /// This is similar to `map_ip`, except only the output type is required to
447    /// be [`GenericOverIp`], while the input type is invariant. This allows
448    /// callers to more conveniently write this use case without having to wrap
449    /// the input in a type like [`IpInvariant`].
450    fn map_ip_out<
451        In,
452        Out: GenericOverIp<Self, Type = Out> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
453    >(
454        input: In,
455        v4: impl FnOnce(In) -> <Out as GenericOverIp<Ipv4>>::Type,
456        v6: impl FnOnce(In) -> <Out as GenericOverIp<Ipv6>>::Type,
457    ) -> Out {
458        Self::map_ip(
459            IpInvariant(input),
460            |IpInvariant(input)| v4(input),
461            |IpInvariant(input)| v6(input),
462        )
463    }
464}
465
466/// Invokes `I::map_ip`, passing the same function body as both arguments.
467///
468/// The first argument is always the `I` on which to invoke `I::map_ip`.
469/// Optionally, this can include an alias (`I as IpAlias`) that should be bound
470/// to `Ipv4` and `Ipv6` for each instantiation of the function body. (If the
471/// `Ip` argument passed is a simple identifier, then it is automatically
472/// aliased in this way.)
473/// The next argument is the input to thread through `map_ip` to the function,
474/// and the final argument is the function to be duplicated to serve as the
475/// closures passed to `map_ip`.
476///
477/// This macro helps avoid code duplication when working with types that are
478/// _not_ GenericOverIp, but have identical shapes such that the actual text of
479/// the code you are writing is identical. This should be very rare, and is
480/// generally limited to cases where we are interfacing with code that we don't
481/// have the ability to make generic-over-IP -- when possible, it's better to
482/// push `I: Ip` generics further through the types you are working with instead
483/// so that you can avoid using `map_ip` entirely.
484///
485/// Example:
486///
487/// ```
488/// // Imagine that `IpExt` is implemented for concrete `Ipv4` and `Ipv6` but
489/// // not for blanket `I: Ip`.
490/// struct Foo<I: IpExt>;
491///
492/// struct FooFactory;
493/// impl FooFactory {
494///     fn get<I: IpExt>(&self) -> Foo<I> {
495///         unimplemented!()
496///     }
497/// }
498///
499/// struct FooSink<I: IpExt>;
500/// impl<I: IpExt> FooSink<I> {
501///     fn use_foo(&self, foo: Foo<I>) {
502///         unimplemented!()
503///     }
504/// }
505///
506/// fn do_something<I: Ip>(factory: FooFactory) -> Foo<I> {
507///     map_ip_twice!(
508///         I,
509///         (),
510///         |()| {
511///            // This works because even though the `I` from the function decl
512///            // doesn't have an `IpExt` bound, it's aliased to either `Ipv4`
513///            // or `Ipv6` here.
514///            factory.get::<I>()
515///         },
516///     )
517/// }
518///
519/// fn do_something_else<I: IpExt>(factory: FooFactory, foo_sink: FooSink<I>) {
520///     map_ip_twice!(
521///         // Introduce different alias to avoid shadowing `I`.
522///         I as IpAlias,
523///         (),
524///         |()| {
525///             let foo_with_orig_ip = factory.get::<I>();
526///             // The fact that `I` was not shadowed allows us to make use of
527///             // `foo_sink` by capture rather than needing to thread it
528///             // through the generic-over-IP input.
529///             foo_sink.use_foo(foo_with_orig_ip)
530///         },
531///     )
532/// }
533/// ```
534#[macro_export]
535macro_rules! map_ip_twice {
536    // This case triggers if we're passed an `Ip` implementor that is a simple
537    // identifier in-scope (e.g. `I`), which allows us to automatically alias it
538    // to `Ipv4` and `Ipv6` in each `$fn` instantiation.
539    ($ip:ident, $input:expr, $fn:expr $(,)?) => {
540        $crate::map_ip_twice!($ip as $ip, $input, $fn)
541    };
542    // This case triggers if we're passed an `Ip` implementor that is _not_ an
543    // identifier, and thus we can't use it as the left-hand-side of a type
544    // alias binding (e.g. `<A as IpAddress>::Version`).
545    ($ip:ty, $input:expr, $fn:expr $(,)?) => {
546        <$ip as $crate::ip::Ip>::map_ip($input, { $fn }, { $fn })
547    };
548    ($ip:ty as $iptypealias:ident, $input:expr, $fn:expr $(,)?) => {
549        <$ip as $crate::ip::Ip>::map_ip(
550            $input,
551            {
552                #[allow(dead_code)]
553                type $iptypealias = $crate::ip::Ipv4;
554                $fn
555            },
556            {
557                #[allow(dead_code)]
558                type $iptypealias = $crate::ip::Ipv6;
559                $fn
560            },
561        )
562    };
563}
564
565/// IPv4.
566///
567/// `Ipv4` implements [`Ip`] for IPv4.
568///
569/// Note that this type has no value constructor. It is used purely at the type
570/// level. Attempting to construct it by calling `Default::default` will panic.
571#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
572pub enum Ipv4 {}
573
574impl Default for Ipv4 {
575    fn default() -> Ipv4 {
576        panic!("Ipv4 default")
577    }
578}
579
580impl sealed::Sealed for Ipv4 {}
581
582impl Ip for Ipv4 {
583    const VERSION: IpVersion = IpVersion::V4;
584    const VERSION_MARKER: IpVersionMarker<Self> = IpVersionMarker::new();
585
586    // TODO(https://fxbug.dev/42163997): Document the standard in which this
587    // constant is defined.
588    const UNSPECIFIED_ADDRESS: Ipv4Addr = Ipv4Addr::new([0, 0, 0, 0]);
589    /// The default IPv4 address used for loopback, defined in [RFC 5735 Section
590    /// 3].
591    ///
592    /// Note that while this address is the most commonly used address for
593    /// loopback traffic, any address in the [`LOOPBACK_SUBNET`] may be used.
594    ///
595    /// [RFC 5735 Section 3]: https://datatracker.ietf.org/doc/html/rfc5735#section-3
596    /// [`LOOPBACK_SUBNET`]: Ipv4::LOOPBACK_SUBNET
597    const LOOPBACK_ADDRESS: SpecifiedAddr<Ipv4Addr> =
598        unsafe { SpecifiedAddr::new_unchecked(Ipv4Addr::new([127, 0, 0, 1])) };
599    /// The IPv4 loopback subnet, defined in [RFC 1122 Section 3.2.1.3].
600    ///
601    /// [RFC 1122 Section 3.2.1.3]: https://www.rfc-editor.org/rfc/rfc1122.html#section-3.2.1.3
602    const LOOPBACK_SUBNET: Subnet<Ipv4Addr> =
603        Subnet { network: Ipv4Addr::new([127, 0, 0, 0]), prefix: 8 };
604    /// The IPv4 Multicast subnet, defined in [RFC 1112 Section 4].
605    ///
606    /// [RFC 1112 Section 4]: https://www.rfc-editor.org/rfc/rfc1112.html#section-4
607    const MULTICAST_SUBNET: Subnet<Ipv4Addr> = Self::CLASS_D_SUBNET;
608    /// The subnet of link-local unicast IPv4 addresses, outlined in [RFC 3927
609    /// Section 2.1].
610    ///
611    /// [RFC 3927 Section 2.1]: https://tools.ietf.org/html/rfc3927#section-2.1
612    const LINK_LOCAL_UNICAST_SUBNET: Subnet<Ipv4Addr> =
613        Subnet { network: Ipv4Addr::new([169, 254, 0, 0]), prefix: 16 };
614    const NAME: &'static str = "IPv4";
615    /// The IPv4 minimum link MTU.
616    ///
617    /// Per [RFC 791 Section 3.2], "[\e\]very internet module must be able to
618    /// forward a datagram of 68 octets without further fragmentation."
619    ///
620    /// [RFC 791 Section 3.2]: https://tools.ietf.org/html/rfc791#section-3.2
621    const MINIMUM_LINK_MTU: Mtu = Mtu(68);
622    type Addr = Ipv4Addr;
623
624    fn map_ip<
625        In: GenericOverIp<Self, Type = In> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
626        Out: GenericOverIp<Self, Type = Out> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
627    >(
628        input: In,
629        v4: impl FnOnce(<In as GenericOverIp<Ipv4>>::Type) -> <Out as GenericOverIp<Ipv4>>::Type,
630        _v6: impl FnOnce(<In as GenericOverIp<Ipv6>>::Type) -> <Out as GenericOverIp<Ipv6>>::Type,
631    ) -> Out {
632        v4(input)
633    }
634}
635
636impl Ipv4 {
637    /// The limited broadcast address.
638    ///
639    /// The limited broadcast address is considered to be a broadcast address on
640    /// all networks regardless of subnet address. This is distinct from the
641    /// subnet-specific broadcast address (e.g., 192.168.255.255 on the subnet
642    /// 192.168.0.0/16). It is defined in the [IANA IPv4 Special-Purpose Address
643    /// Registry].
644    ///
645    /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
646    pub const LIMITED_BROADCAST_ADDRESS: SpecifiedAddr<Ipv4Addr> =
647        unsafe { SpecifiedAddr::new_unchecked(Ipv4Addr::new([255, 255, 255, 255])) };
648
649    /// The Class A subnet.
650    ///
651    /// The Class A subnet is defined in [RFC 1812 section 2.2.5.1].
652    ///
653    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
654    pub const CLASS_A_SUBNET: Subnet<Ipv4Addr> =
655        Subnet { network: Ipv4Addr::new([0, 0, 0, 0]), prefix: 1 };
656
657    /// The Class B subnet.
658    ///
659    /// The Class B subnet is defined in [RFC 1812 section 2.2.5.1].
660    ///
661    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
662    pub const CLASS_B_SUBNET: Subnet<Ipv4Addr> =
663        Subnet { network: Ipv4Addr::new([128, 0, 0, 0]), prefix: 2 };
664
665    /// The Class C subnet.
666    ///
667    /// The Class C subnet is defined in [RFC 1812 section 2.2.5.1].
668    ///
669    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
670    pub const CLASS_C_SUBNET: Subnet<Ipv4Addr> =
671        Subnet { network: Ipv4Addr::new([192, 0, 0, 0]), prefix: 3 };
672
673    /// The Class D subnet.
674    ///
675    /// This subnet is also known as the multicast subnet.
676    ///
677    /// The Class D subnet is defined in [RFC 1812 section 2.2.5.1].
678    ///
679    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
680    pub const CLASS_D_SUBNET: Subnet<Ipv4Addr> =
681        Subnet { network: Ipv4Addr::new([224, 0, 0, 0]), prefix: 4 };
682
683    /// The Class E subnet.
684    ///
685    /// The Class E subnet is meant for experimental purposes, and should not be
686    /// used on the general internet. [RFC 1812 Section 5.3.7] suggests that
687    /// routers SHOULD discard packets with a source address in the Class E
688    /// subnet. The Class E subnet is defined in [RFC 1112 Section 4].
689    ///
690    /// [RFC 1812 Section 5.3.7]: https://tools.ietf.org/html/rfc1812#section-5.3.7
691    /// [RFC 1112 Section 4]: https://datatracker.ietf.org/doc/html/rfc1112#section-4
692    pub const CLASS_E_SUBNET: Subnet<Ipv4Addr> =
693        Subnet { network: Ipv4Addr::new([240, 0, 0, 0]), prefix: 4 };
694
695    /// The subnet of link-local multicast addresses, outlined in [RFC 5771
696    /// Section 4].
697    ///
698    /// [RFC 5771 Section 4]: https://tools.ietf.org/html/rfc5771#section-4
699    pub const LINK_LOCAL_MULTICAST_SUBNET: Subnet<Ipv4Addr> =
700        Subnet { network: Ipv4Addr::new([224, 0, 0, 0]), prefix: 24 };
701
702    /// The multicast address subscribed to by all systems on the local network,
703    /// defined in the [IPv4 Multicast Address Space Registry].
704    ///
705    /// [IPv4 Multicast Address Space Registry]: https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
706    pub const ALL_SYSTEMS_MULTICAST_ADDRESS: MulticastAddr<Ipv4Addr> =
707        unsafe { MulticastAddr::new_unchecked(Ipv4Addr::new([224, 0, 0, 1])) };
708
709    /// The multicast address subscribed to by all routers on the local network,
710    /// defined in the [IPv4 Multicast Address Space Registry].
711    ///
712    /// [IPv4 Multicast Address Space Registry]: https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
713    pub const ALL_ROUTERS_MULTICAST_ADDRESS: MulticastAddr<Ipv4Addr> =
714        unsafe { MulticastAddr::new_unchecked(Ipv4Addr::new([224, 0, 0, 2])) };
715}
716
717/// IPv6.
718///
719/// `Ipv6` implements [`Ip`] for IPv6.
720///
721/// Note that this type has no value constructor. It is used purely at the type
722/// level. Attempting to construct it by calling `Default::default` will panic.
723#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
724pub enum Ipv6 {}
725
726impl Default for Ipv6 {
727    fn default() -> Ipv6 {
728        panic!("Ipv6 default")
729    }
730}
731
732impl sealed::Sealed for Ipv6 {}
733
734impl Ip for Ipv6 {
735    const VERSION: IpVersion = IpVersion::V6;
736    const VERSION_MARKER: IpVersionMarker<Self> = IpVersionMarker::new();
737    /// The unspecified IPv6 address, defined in [RFC 4291 Section 2.5.2].
738    ///
739    /// Per RFC 4291:
740    ///
741    /// > The address 0:0:0:0:0:0:0:0 is called the unspecified address.  It
742    /// > must never be assigned to any node.  It indicates the absence of an
743    /// > address.  One example of its use is in the Source Address field of any
744    /// > IPv6 packets sent by an initializing host before it has learned its
745    /// > own address.
746    /// >
747    /// > The unspecified address must not be used as the destination address of
748    /// > IPv6 packets or in IPv6 Routing headers.  An IPv6 packet with a source
749    /// > address of unspecified must never be forwarded by an IPv6 router.
750    ///
751    /// [RFC 4291 Section 2.5.2]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2
752    const UNSPECIFIED_ADDRESS: Ipv6Addr = Ipv6Addr::new([0; 8]);
753    /// The loopback IPv6 address, defined in [RFC 4291 Section 2.5.3].
754    ///
755    /// Per RFC 4291:
756    ///
757    /// > The unicast address 0:0:0:0:0:0:0:1 is called the loopback address.
758    /// > It may be used by a node to send an IPv6 packet to itself.  It must
759    /// > not be assigned to any physical interface.  It is treated as having
760    /// > Link-Local scope, and may be thought of as the Link-Local unicast
761    /// > address of a virtual interface (typically called the "loopback
762    /// > interface") to an imaginary link that goes nowhere.
763    /// >
764    /// > The loopback address must not be used as the source address in IPv6
765    /// > packets that are sent outside of a single node.  An IPv6 packet with
766    /// > a destination address of loopback must never be sent outside of a
767    /// > single node and must never be forwarded by an IPv6 router.  A packet
768    /// > received on an interface with a destination address of loopback must
769    /// > be dropped.
770    ///
771    /// [RFC 4291 Section 2.5.3]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3
772    const LOOPBACK_ADDRESS: SpecifiedAddr<Ipv6Addr> =
773        unsafe { SpecifiedAddr::new_unchecked(Ipv6Addr::new([0, 0, 0, 0, 0, 0, 0, 1])) };
774    /// The subnet of loopback IPv6 addresses, defined in [RFC 4291 Section 2.4].
775    ///
776    /// Note that the IPv6 loopback subnet is a /128, meaning that it contains
777    /// only one address - the [`LOOPBACK_ADDRESS`].
778    ///
779    /// [RFC 4291 Section 2.4]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
780    /// [`LOOPBACK_ADDRESS`]: Ipv6::LOOPBACK_ADDRESS
781    const LOOPBACK_SUBNET: Subnet<Ipv6Addr> =
782        Subnet { network: Ipv6Addr::new([0, 0, 0, 0, 0, 0, 0, 1]), prefix: 128 };
783    /// The subnet of multicast IPv6 addresses, defined in [RFC 4291 Section
784    /// 2.7].
785    ///
786    /// [RFC 4291 Section 2.7]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.7
787    const MULTICAST_SUBNET: Subnet<Ipv6Addr> =
788        Subnet { network: Ipv6Addr::new([0xff00, 0, 0, 0, 0, 0, 0, 0]), prefix: 8 };
789    /// The subnet of link-local unicast addresses, defined in [RFC 4291 Section
790    /// 2.4].
791    ///
792    /// Note that multicast addresses can also be link-local. However, there is
793    /// no single subnet of link-local multicast addresses. For more details on
794    /// link-local multicast addresses, see [RFC 4291 Section 2.7].
795    ///
796    /// [RFC 4291 Section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
797    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
798    const LINK_LOCAL_UNICAST_SUBNET: Subnet<Ipv6Addr> =
799        Subnet { network: Ipv6Addr::new([0xfe80, 0, 0, 0, 0, 0, 0, 0]), prefix: 10 };
800    const NAME: &'static str = "IPv6";
801    /// The IPv6 minimum link MTU, defined in [RFC 8200 Section 5].
802    ///
803    /// Per RFC 8200:
804    ///
805    /// > IPv6 requires that every link in the Internet have an MTU of 1280
806    /// > octets or greater. This is known as the IPv6 minimum link MTU. On any
807    /// > link that cannot convey a 1280-octet packet in one piece, link-
808    /// > specific fragmentation and reassembly must be provided at a layer
809    /// > below IPv6.
810    ///
811    /// [RFC 8200 Section 5]: https://tools.ietf.org/html/rfc8200#section-5
812    const MINIMUM_LINK_MTU: Mtu = Mtu(1280);
813    type Addr = Ipv6Addr;
814
815    fn map_ip<
816        In: GenericOverIp<Self, Type = In> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
817        Out: GenericOverIp<Self, Type = Out> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
818    >(
819        input: In,
820        _v4: impl FnOnce(<In as GenericOverIp<Ipv4>>::Type) -> <Out as GenericOverIp<Ipv4>>::Type,
821        v6: impl FnOnce(<In as GenericOverIp<Ipv6>>::Type) -> <Out as GenericOverIp<Ipv6>>::Type,
822    ) -> Out {
823        v6(input)
824    }
825}
826
827impl Ipv6 {
828    /// The loopback address represented as a [`UnicastAddr`].
829    ///
830    /// This is equivalent to [`LOOPBACK_ADDRESS`], except that it is a
831    /// [`UnicastAddr`] witness type.
832    ///
833    /// [`LOOPBACK_ADDRESS`]: Ipv6::LOOPBACK_ADDRESS
834    pub const LOOPBACK_IPV6_ADDRESS: UnicastAddr<Ipv6Addr> =
835        unsafe { UnicastAddr::new_unchecked(Ipv6::LOOPBACK_ADDRESS.0) };
836
837    /// The IPv6 All Nodes multicast address in link-local scope, defined in
838    /// [RFC 4291 Section 2.7.1].
839    ///
840    /// [RFC 4291 Section 2.7.1]: https://tools.ietf.org/html/rfc4291#section-2.7.1
841    pub const ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS: MulticastAddr<Ipv6Addr> =
842        unsafe { MulticastAddr::new_unchecked(Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0, 0, 1])) };
843
844    /// The IPv6 All Routers multicast address in link-local scope, defined in
845    /// [RFC 4291 Section 2.7.1].
846    ///
847    /// [RFC 4291 Section 2.7.1]: https://tools.ietf.org/html/rfc4291#section-2.7.1
848    pub const ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS: MulticastAddr<Ipv6Addr> =
849        unsafe { MulticastAddr::new_unchecked(Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0, 0, 2])) };
850
851    /// The (deprecated) subnet of site-local unicast addresses, defined in [RFC
852    /// 3513 Section 2.5.6].
853    ///
854    /// The site-local unicast subnet was deprecated in [RFC 3879]:
855    ///
856    /// > The special behavior of this prefix MUST no longer be supported in new
857    /// > implementations. The prefix MUST NOT be reassigned for other use
858    /// > except by a future IETF standards action... However, router
859    /// > implementations SHOULD be configured to prevent routing of this prefix
860    /// > by default.
861    ///
862    /// [RFC 3513 Section 2.5.6]: https://tools.ietf.org/html/rfc3513#section-2.5.6
863    /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
864    pub const SITE_LOCAL_UNICAST_SUBNET: Subnet<Ipv6Addr> =
865        Subnet { network: Ipv6Addr::new([0xfec0, 0, 0, 0, 0, 0, 0, 0]), prefix: 10 };
866
867    /// The length, in bits, of the interface identifier portion of unicast IPv6
868    /// addresses *except* for addresses which start with the binary value 000.
869    ///
870    /// According to [RFC 4291 Section 2.5.1], "\[f\]or all unicast addresses,
871    /// except those that start with the binary value 000, Interface IDs are
872    /// required to be 64 bits."
873    ///
874    /// Note that, per [RFC 4862 Section 5.5.3]:
875    ///
876    /// > a future revision of the address architecture \[RFC4291\] and a future
877    /// > link-type-specific document, which will still be consistent with each
878    /// > other, could potentially allow for an interface identifier of length
879    /// > other than the value defined in the current documents.  Thus, an
880    /// > implementation should not assume a particular constant.  Rather, it
881    /// > should expect any lengths of interface identifiers.
882    ///
883    /// In other words, this constant may be used to generate addresses or
884    /// subnet prefix lengths, but should *not* be used to validate addresses or
885    /// subnet prefix lengths generated by other software or other machines, as
886    /// it might be valid for other software or other machines to use an
887    /// interface identifier length different from this one.
888    ///
889    /// [RFC 4291 Section 2.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.1
890    /// [RFC 4862 Section 5.5.3]: https://tools.ietf.org/html/rfc4862#section-5.5.3
891    pub const UNICAST_INTERFACE_IDENTIFIER_BITS: u8 = 64;
892
893    /// The length, in bits, of an IPv6 flow label, defined in [RFC 6437 Section 2].
894    ///
895    /// [RFC 6437 Section 2]: https://tools.ietf.org/html/rfc6437#section-2
896    pub const FLOW_LABEL_BITS: u8 = 20;
897}
898
899/// An IPv4 or IPv6 address.
900///
901/// `IpAddress` is implemented by [`Ipv4Addr`] and [`Ipv6Addr`]. It is sealed,
902/// and there are guaranteed to be no other implementors besides these. Code -
903/// including unsafe code - may rely on this assumption for its correctness and
904/// soundness.
905pub trait IpAddress:
906    Sized
907    + Eq
908    + PartialEq
909    + PartialOrd
910    + Ord
911    + Hash
912    + Copy
913    + Display
914    + Debug
915    + Default
916    + Sync
917    + Send
918    + LinkLocalAddress
919    + ScopeableAddress
920    + GenericOverIp<Self::Version, Type = Self>
921    + GenericOverIp<Ipv4, Type = Ipv4Addr>
922    + GenericOverIp<Ipv6, Type = Ipv6Addr>
923    + sealed::Sealed
924    + 'static
925{
926    /// The number of bytes in an address of this type.
927    ///
928    /// 4 for IPv4 and 16 for IPv6.
929    const BYTES: u8;
930
931    /// The IP version type of this address.
932    ///
933    /// [`Ipv4`] for [`Ipv4Addr`] and [`Ipv6`] for [`Ipv6Addr`].
934    type Version: Ip<Addr = Self>;
935
936    /// Gets the underlying bytes of the address.
937    fn bytes(&self) -> &[u8];
938
939    /// Masks off the top bits of the address.
940    ///
941    /// Returns a copy of `self` where all but the top `bits` bits are set to
942    /// 0.
943    ///
944    /// # Panics
945    ///
946    /// `mask` panics if `bits` is out of range - if it is greater than 32 for
947    /// IPv4 or greater than 128 for IPv6.
948    fn mask(&self, bits: u8) -> Self;
949
950    /// Converts a statically-typed IP address into a dynamically-typed one.
951    fn to_ip_addr(&self) -> IpAddr;
952
953    /// Is this a loopback address?
954    ///
955    /// `is_loopback` returns `true` if this address is a member of the
956    /// [`LOOPBACK_SUBNET`].
957    ///
958    /// [`LOOPBACK_SUBNET`]: Ip::LOOPBACK_SUBNET
959    #[inline]
960    fn is_loopback(&self) -> bool {
961        Self::Version::LOOPBACK_SUBNET.contains(self)
962    }
963
964    /// Calculates the common prefix length between this address and `other`.
965    fn common_prefix_len(&self, other: &Self) -> u8;
966
967    /// Is this a unicast address contained in the given subnet?
968    ///
969    /// `is_unicast_in_subnet` returns `true` if the given subnet contains this
970    /// address and the address is none of:
971    /// - a multicast address
972    /// - the IPv4 limited broadcast address
973    /// - the IPv4 subnet-specific broadcast address for the given subnet
974    /// - an IPv4 address whose host bits (those bits following the network
975    ///   prefix) are all 0
976    /// - the unspecified address
977    /// - an IPv4 Class E address
978    ///
979    /// Note two exceptions to these rules: If `subnet` is an IPv4 /32, then the
980    /// single unicast address in the subnet is also technically the subnet
981    /// broadcast address. If `subnet` is an IPv4 /31, then both addresses in
982    /// that subnet are broadcast addresses. In either case, the "no
983    /// subnet-specific broadcast" and "no address with a host part of all
984    /// zeroes" rules don't apply. Note further that this exception *doesn't*
985    /// apply to the unspecified address, which is never considered a unicast
986    /// address regardless of what subnet it's in.
987    ///
988    /// # RFC Deep Dive
989    ///
990    /// ## IPv4 addresses ending in zeroes
991    ///
992    /// In this section, we justify the rule that IPv4 addresses whose host bits
993    /// are all 0 are not considered unicast addresses.
994    ///
995    /// In earlier standards, an IPv4 address whose bits were all 0 after the
996    /// network prefix (e.g., 192.168.0.0 in the subnet 192.168.0.0/16) were a
997    /// form of "network-prefix-directed" broadcast addresses. Similarly,
998    /// 0.0.0.0 was considered a form of "limited broadcast address" (equivalent
999    /// to 255.255.255.255). These have since been deprecated (in the case of
1000    /// 0.0.0.0, it is now considered the "unspecified" address).
1001    ///
1002    /// As evidence that this deprecation is official, consider [RFC 1812
1003    /// Section 5.3.5]. In reference to these types of addresses, it states that
1004    /// "packets addressed to any of these addresses SHOULD be silently
1005    /// discarded \[by routers\]". This not only deprecates them as broadcast
1006    /// addresses, but also as unicast addresses (after all, unicast addresses
1007    /// are not particularly useful if packets destined to them are discarded by
1008    /// routers).
1009    ///
1010    /// ## IPv4 /31 and /32 exceptions
1011    ///
1012    /// In this section, we justify the exceptions that all addresses in IPv4
1013    /// /31 and /32 subnets are considered unicast.
1014    ///
1015    /// For /31 subnets, the case is easy. [RFC 3021 Section 2.1] states that
1016    /// both addresses in a /31 subnet "MUST be interpreted as host addresses."
1017    ///
1018    /// For /32, the case is a bit more vague. RFC 3021 makes no mention of /32
1019    /// subnets. However, the same reasoning applies - if an exception is not
1020    /// made, then there do not exist any host addresses in a /32 subnet. [RFC
1021    /// 4632 Section 3.1] also vaguely implies this interpretation by referring
1022    /// to addresses in /32 subnets as "host routes."
1023    ///
1024    /// [RFC 1812 Section 5.3.5]: https://tools.ietf.org/html/rfc1812#page-92
1025    /// [RFC 4632 Section 3.1]: https://tools.ietf.org/html/rfc4632#section-3.1
1026    fn is_unicast_in_subnet(&self, subnet: &Subnet<Self>) -> bool;
1027
1028    // Functions used to implement internal types. These functions aren't
1029    // particularly useful to users, but allow us to implement certain
1030    // specialization-like behavior without actually relying on the unstable
1031    // `specialization` feature.
1032
1033    #[doc(hidden)]
1034    fn subnet_into_either(subnet: Subnet<Self>) -> SubnetEither;
1035
1036    #[doc(hidden)]
1037    fn array_into_ip_addr<const N: usize>(addrs: [Self; N])
1038        -> IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]>;
1039}
1040
1041impl<A: IpAddress> SpecifiedAddress for A {
1042    /// Is this an address other than the unspecified address?
1043    ///
1044    /// `is_specified` returns true if `self` is not equal to
1045    /// [`A::Version::UNSPECIFIED_ADDRESS`].
1046    ///
1047    /// [`A::Version::UNSPECIFIED_ADDRESS`]: Ip::UNSPECIFIED_ADDRESS
1048    #[inline]
1049    fn is_specified(&self) -> bool {
1050        self != &A::Version::UNSPECIFIED_ADDRESS
1051    }
1052}
1053
1054/// Maps a method over an `IpAddr`, calling it after matching on the type of IP
1055/// address.
1056macro_rules! map_ip_addr {
1057    ($val:expr, $method:ident) => {
1058        match $val {
1059            IpAddr::V4(a) => a.$method(),
1060            IpAddr::V6(a) => a.$method(),
1061        }
1062    };
1063}
1064
1065impl SpecifiedAddress for IpAddr {
1066    /// Is this an address other than the unspecified address?
1067    ///
1068    /// `is_specified` returns true if `self` is not equal to
1069    /// [`Ip::UNSPECIFIED_ADDRESS`] for the IP version of this address.
1070    #[inline]
1071    fn is_specified(&self) -> bool {
1072        map_ip_addr!(self, is_specified)
1073    }
1074}
1075
1076impl<A: IpAddress> MulticastAddress for A {
1077    /// Is this address in the multicast subnet?
1078    ///
1079    /// `is_multicast` returns true if `self` is in
1080    /// [`A::Version::MULTICAST_SUBNET`].
1081    ///
1082    /// [`A::Version::MULTICAST_SUBNET`]: Ip::MULTICAST_SUBNET
1083    #[inline]
1084    fn is_multicast(&self) -> bool {
1085        <A as IpAddress>::Version::MULTICAST_SUBNET.contains(self)
1086    }
1087}
1088
1089impl MulticastAddress for IpAddr {
1090    /// Is this an address in the multicast subnet?
1091    ///
1092    /// `is_multicast` returns true if `self` is in [`Ip::MULTICAST_SUBNET`] for
1093    /// the IP version of this address.
1094    #[inline]
1095    fn is_multicast(&self) -> bool {
1096        map_ip_addr!(self, is_multicast)
1097    }
1098}
1099
1100impl LinkLocalAddress for Ipv4Addr {
1101    /// Is this address in the link-local subnet?
1102    ///
1103    /// `is_link_local` returns true if `self` is in
1104    /// [`Ipv4::LINK_LOCAL_UNICAST_SUBNET`] or
1105    /// [`Ipv4::LINK_LOCAL_MULTICAST_SUBNET`].
1106    #[inline]
1107    fn is_link_local(&self) -> bool {
1108        Ipv4::LINK_LOCAL_UNICAST_SUBNET.contains(self)
1109            || Ipv4::LINK_LOCAL_MULTICAST_SUBNET.contains(self)
1110    }
1111}
1112
1113impl LinkLocalAddress for Ipv6Addr {
1114    /// Is this address in the link-local subnet?
1115    ///
1116    /// `is_link_local` returns true if `self` is in
1117    /// [`Ipv6::LINK_LOCAL_UNICAST_SUBNET`], is a multicast address whose scope
1118    /// is link-local, or is the address [`Ipv6::LOOPBACK_ADDRESS`] (per [RFC
1119    /// 4291 Section 2.5.3], the loopback address is considered to have
1120    /// link-local scope).
1121    ///
1122    /// [RFC 4291 Section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
1123    #[inline]
1124    fn is_link_local(&self) -> bool {
1125        Ipv6::LINK_LOCAL_UNICAST_SUBNET.contains(self)
1126            || (self.is_multicast() && self.scope() == Ipv6Scope::LinkLocal)
1127            || self == Ipv6::LOOPBACK_ADDRESS.deref()
1128    }
1129}
1130
1131impl LinkLocalAddress for IpAddr {
1132    /// Is this address link-local?
1133    #[inline]
1134    fn is_link_local(&self) -> bool {
1135        map_ip_addr!(self, is_link_local)
1136    }
1137}
1138
1139impl<A: IpAddress> MappedAddress for A {
1140    /// Is this address non-mapped?
1141    ///
1142    /// For IPv4 addresses, this always returns true because they do not have a
1143    /// mapped address space.
1144    ///
1145    /// For Ipv6 addresses, this returns true if `self` is outside of the IPv4
1146    /// mapped Ipv6 address subnet, as defined in [RFC 4291 Section 2.5.5.2]
1147    /// (e.g. `::FFFF:0:0/96`).
1148    ///
1149    /// [RFC 4291 Section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
1150    #[inline]
1151    fn is_non_mapped(&self) -> bool {
1152        A::Version::map_ip(self, |_addr_v4| true, |addr_v6| addr_v6.to_ipv4_mapped().is_none())
1153    }
1154}
1155
1156impl MappedAddress for IpAddr {
1157    /// Is this address non-mapped?
1158    #[inline]
1159    fn is_non_mapped(&self) -> bool {
1160        map_ip_addr!(self, is_non_mapped)
1161    }
1162}
1163
1164impl<I: Ip> GenericOverIp<I> for Ipv4Addr {
1165    type Type = I::Addr;
1166}
1167
1168impl<I: Ip> GenericOverIp<I> for Ipv6Addr {
1169    type Type = I::Addr;
1170}
1171
1172impl ScopeableAddress for Ipv4Addr {
1173    type Scope = ();
1174
1175    /// The scope of this address.
1176    ///
1177    /// Although IPv4 defines a link local subnet, IPv4 addresses are always
1178    /// considered to be in the global scope.
1179    fn scope(&self) {}
1180}
1181
1182/// The list of IPv6 scopes.
1183///
1184/// These scopes are defined by [RFC 4291 Section 2.7].
1185///
1186/// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1187#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1188pub enum Ipv6Scope {
1189    /// The interface-local scope.
1190    InterfaceLocal,
1191    /// The link-local scope.
1192    LinkLocal,
1193    /// The admin-local scope.
1194    AdminLocal,
1195    /// The (deprecated) site-local scope.
1196    ///
1197    /// The site-local scope was deprecated in [RFC 3879]. While this scope
1198    /// is returned for both site-local unicast and site-local multicast
1199    /// addresses, RFC 3879 says the following about site-local unicast addresses
1200    /// in particular ("this prefix" refers to the [site-local unicast subnet]):
1201    ///
1202    /// > The special behavior of this prefix MUST no longer be supported in new
1203    /// > implementations. The prefix MUST NOT be reassigned for other use
1204    /// > except by a future IETF standards action... However, router
1205    /// > implementations SHOULD be configured to prevent routing of this prefix
1206    /// > by default.
1207    ///
1208    /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
1209    /// [site-local unicast subnet]: Ipv6::SITE_LOCAL_UNICAST_SUBNET
1210    SiteLocal,
1211    /// The organization-local scope.
1212    OrganizationLocal,
1213    /// The global scope.
1214    Global,
1215    /// Scopes which are reserved for future use by [RFC 4291 Section 2.7].
1216    ///
1217    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1218    Reserved(Ipv6ReservedScope),
1219    /// Scopes which are available for local definition by administrators.
1220    Unassigned(Ipv6UnassignedScope),
1221}
1222
1223/// The list of IPv6 scopes which are reserved for future use by [RFC 4291
1224/// Section 2.7].
1225///
1226/// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1227#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1228pub enum Ipv6ReservedScope {
1229    /// The scope with numerical value 0.
1230    Scope0 = 0,
1231    /// The scope with numerical value 3.
1232    Scope3 = 3,
1233    /// The scope with numerical value 0xF.
1234    ScopeF = 0xF,
1235}
1236
1237/// The list of IPv6 scopes which are available for local definition by
1238/// administrators.
1239#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1240pub enum Ipv6UnassignedScope {
1241    /// The scope with numerical value 6.
1242    Scope6 = 6,
1243    /// The scope with numerical value 7.
1244    Scope7 = 7,
1245    /// The scope with numerical value 9.
1246    Scope9 = 9,
1247    /// The scope with numerical value 0xA.
1248    ScopeA = 0xA,
1249    /// The scope with numerical value 0xB.
1250    ScopeB = 0xB,
1251    /// The scope with numerical value 0xC.
1252    ScopeC = 0xC,
1253    /// The scope with numerical value 0xD.
1254    ScopeD = 0xD,
1255}
1256
1257impl Scope for Ipv6Scope {
1258    #[inline]
1259    fn can_have_zone(&self) -> bool {
1260        // Per RFC 6874 Section 4:
1261        //
1262        // > [I]mplementations MUST NOT allow use of this format except for
1263        // > well-defined usages, such as sending to link-local addresses under
1264        // > prefix fe80::/10.  At the time of writing, this is the only
1265        // > well-defined usage known.
1266        //
1267        // While this directive applies particularly to the human-readable
1268        // string representation of IPv6 addresses and zone identifiers, it
1269        // seems reasonable to limit the in-memory representation in the same
1270        // way.
1271        //
1272        // Note that, if interpreted literally, this quote would bar the use of
1273        // zone identifiers on link-local multicast addresses (they are not
1274        // under the prefix fe80::/10). However, it seems clear that this is not
1275        // the interpretation that was intended. Link-local multicast addresses
1276        // have the same need for a zone identifier as link-local unicast
1277        // addresses, and indeed, real systems like Linux allow link-local
1278        // multicast addresses to be accompanied by zone identifiers.
1279        matches!(self, Ipv6Scope::LinkLocal)
1280    }
1281}
1282
1283impl Ipv6Scope {
1284    /// The multicast scope ID of an interface-local address, defined in [RFC
1285    /// 4291 Section 2.7].
1286    ///
1287    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1288    pub const MULTICAST_SCOPE_ID_INTERFACE_LOCAL: u8 = 1;
1289
1290    /// The multicast scope ID of a link-local address, defined in [RFC 4291
1291    /// Section 2.7].
1292    ///
1293    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1294    pub const MULTICAST_SCOPE_ID_LINK_LOCAL: u8 = 2;
1295
1296    /// The multicast scope ID of an admin-local address, defined in [RFC 4291
1297    /// Section 2.7].
1298    ///
1299    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1300    pub const MULTICAST_SCOPE_ID_ADMIN_LOCAL: u8 = 4;
1301
1302    /// The multicast scope ID of a (deprecated) site-local address, defined in
1303    /// [RFC 4291 Section 2.7].
1304    ///
1305    /// Note that site-local addresses are deprecated.
1306    ///
1307    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1308    pub const MULTICAST_SCOPE_ID_SITE_LOCAL: u8 = 5;
1309
1310    /// The multicast scope ID of an organization-local address, defined in [RFC
1311    /// 4291 Section 2.7].
1312    ///
1313    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1314    pub const MULTICAST_SCOPE_ID_ORG_LOCAL: u8 = 8;
1315
1316    /// The multicast scope ID of global address, defined in [RFC 4291 Section
1317    /// 2.7].
1318    ///
1319    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1320    pub const MULTICAST_SCOPE_ID_GLOBAL: u8 = 0xE;
1321
1322    /// The ID used to indicate this scope in a multicast IPv6 address.
1323    ///
1324    /// Per [RFC 4291 Section 2.7], the bits of a multicast IPv6 address are
1325    /// laid out as follows:
1326    ///
1327    /// ```text
1328    /// |   8    |  4 |  4 |                  112 bits                   |
1329    /// +------ -+----+----+---------------------------------------------+
1330    /// |11111111|flgs|scop|                  group ID                   |
1331    /// +--------+----+----+---------------------------------------------+
1332    /// ```
1333    ///
1334    /// The 4-bit scop field encodes the scope of the address.
1335    /// `multicast_scope_id` returns the numerical value used to encode this
1336    /// scope in the scop field of a multicast address.
1337    ///
1338    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
1339    pub fn multicast_scope_id(&self) -> u8 {
1340        match self {
1341            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope0) => 0,
1342            Ipv6Scope::InterfaceLocal => Self::MULTICAST_SCOPE_ID_INTERFACE_LOCAL,
1343            Ipv6Scope::LinkLocal => Self::MULTICAST_SCOPE_ID_LINK_LOCAL,
1344            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope3) => 3,
1345            Ipv6Scope::AdminLocal => Self::MULTICAST_SCOPE_ID_ADMIN_LOCAL,
1346            Ipv6Scope::SiteLocal => Self::MULTICAST_SCOPE_ID_SITE_LOCAL,
1347            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope6) => 6,
1348            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope7) => 7,
1349            Ipv6Scope::OrganizationLocal => Self::MULTICAST_SCOPE_ID_ORG_LOCAL,
1350            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope9) => 9,
1351            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeA) => 0xA,
1352            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeB) => 0xB,
1353            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeC) => 0xC,
1354            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeD) => 0xD,
1355            Ipv6Scope::Global => Self::MULTICAST_SCOPE_ID_GLOBAL,
1356            Ipv6Scope::Reserved(Ipv6ReservedScope::ScopeF) => 0xF,
1357        }
1358    }
1359}
1360
1361impl ScopeableAddress for Ipv6Addr {
1362    type Scope = Ipv6Scope;
1363
1364    /// The scope of this address.
1365    #[inline]
1366    fn scope(&self) -> Ipv6Scope {
1367        if self.is_multicast() {
1368            use Ipv6ReservedScope::*;
1369            use Ipv6Scope::*;
1370            use Ipv6UnassignedScope::*;
1371
1372            // The "scop" field of a multicast address is the last 4 bits of the
1373            // second byte of the address (see
1374            // https://tools.ietf.org/html/rfc4291#section-2.7).
1375            match self.0[1] & 0xF {
1376                0 => Reserved(Scope0),
1377                Ipv6Scope::MULTICAST_SCOPE_ID_INTERFACE_LOCAL => InterfaceLocal,
1378                Ipv6Scope::MULTICAST_SCOPE_ID_LINK_LOCAL => LinkLocal,
1379                3 => Reserved(Scope3),
1380                Ipv6Scope::MULTICAST_SCOPE_ID_ADMIN_LOCAL => AdminLocal,
1381                Ipv6Scope::MULTICAST_SCOPE_ID_SITE_LOCAL => SiteLocal,
1382                6 => Unassigned(Scope6),
1383                7 => Unassigned(Scope7),
1384                Ipv6Scope::MULTICAST_SCOPE_ID_ORG_LOCAL => OrganizationLocal,
1385                9 => Unassigned(Scope9),
1386                0xA => Unassigned(ScopeA),
1387                0xB => Unassigned(ScopeB),
1388                0xC => Unassigned(ScopeC),
1389                0xD => Unassigned(ScopeD),
1390                Ipv6Scope::MULTICAST_SCOPE_ID_GLOBAL => Global,
1391                0xF => Reserved(ScopeF),
1392                _ => unreachable!(),
1393            }
1394        } else if self.is_link_local() {
1395            Ipv6Scope::LinkLocal
1396        } else if self.is_site_local() {
1397            Ipv6Scope::SiteLocal
1398        } else {
1399            Ipv6Scope::Global
1400        }
1401    }
1402}
1403
1404impl Scope for IpAddr<(), Ipv6Scope> {
1405    #[inline]
1406    fn can_have_zone(&self) -> bool {
1407        match self {
1408            IpAddr::V4(scope) => scope.can_have_zone(),
1409            IpAddr::V6(scope) => scope.can_have_zone(),
1410        }
1411    }
1412}
1413
1414impl ScopeableAddress for IpAddr {
1415    type Scope = IpAddr<(), Ipv6Scope>;
1416
1417    #[inline]
1418    fn scope(&self) -> IpAddr<(), Ipv6Scope> {
1419        match self {
1420            IpAddr::V4(_) => IpAddr::V4(()),
1421            IpAddr::V6(addr) => IpAddr::V6(addr.scope()),
1422        }
1423    }
1424}
1425
1426// The definition of each trait for `IpAddr` is equal to the definition of that
1427// trait for whichever of `Ipv4Addr` and `Ipv6Addr` is actually present in the
1428// enum. Thus, we can convert between `$witness<IpvXAddr>`, `$witness<IpAddr>`,
1429// and `IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>` arbitrarily.
1430
1431/// Provides various useful `From` impls for an IP address witness type.
1432///
1433/// `impl_from_witness!($witness)` implements:
1434/// - `From<IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>> for
1435///   $witness<IpAddr>`
1436/// - `From<$witness<IpAddr>> for IpAddr<$witness<Ipv4Addr>,
1437///   $witness<Ipv6Addr>>`
1438/// - `From<$witness<A>> for $witness<A>`
1439/// - `From<$witness<Ipv4Addr>> for IpAddr`
1440/// - `From<$witness<Ipv6Addr>> for IpAddr`
1441/// - `TryFrom<Ipv4Addr> for $witness<Ipv4Addr>`
1442/// - `TryFrom<Ipv6Addr> for $witness<Ipv6Addr>`
1443///
1444/// `impl_from_witness!($witness, $ipaddr, $new_unchecked)` implements:
1445/// - `From<$witness<$ipaddr>> for $witness<IpAddr>`
1446/// - `From<$witness<$ipaddr>> for $ipaddr`
1447/// - `TryFrom<$ipaddr> for $witness<$ipaddr>`
1448macro_rules! impl_from_witness {
1449    ($witness:ident, $witness_trait:ident) => {
1450        impl From<IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>> for $witness<IpAddr> {
1451            fn from(addr: IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>) -> $witness<IpAddr> {
1452                unsafe {
1453                    Witness::new_unchecked(match addr {
1454                        IpAddr::V4(addr) => IpAddr::V4(addr.get()),
1455                        IpAddr::V6(addr) => IpAddr::V6(addr.get()),
1456                    })
1457                }
1458            }
1459        }
1460        impl From<$witness<IpAddr>> for IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
1461            fn from(addr: $witness<IpAddr>) -> IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
1462                unsafe {
1463                    match addr.get() {
1464                        IpAddr::V4(addr) => IpAddr::V4(Witness::new_unchecked(addr)),
1465                        IpAddr::V6(addr) => IpAddr::V6(Witness::new_unchecked(addr)),
1466                    }
1467                }
1468            }
1469        }
1470        impl<A: IpAddress> From<$witness<A>> for $witness<IpAddr> {
1471            fn from(addr: $witness<A>) -> $witness<IpAddr> {
1472                unsafe { Witness::new_unchecked(addr.to_ip_addr()) }
1473            }
1474        }
1475        impl<A: IpAddress> From<$witness<A>> for IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
1476            fn from(addr: $witness<A>) -> IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
1477                let addr: $witness<IpAddr> = addr.into();
1478                addr.into()
1479            }
1480        }
1481        // NOTE: Orphan rules prevent implementing `From` for `A: IpAddress`.
1482        impl<A: Into<Ipv4Addr> + $witness_trait + Copy> From<$witness<A>> for Ipv4Addr {
1483            fn from(addr: $witness<A>) -> Ipv4Addr {
1484                let addr: A = addr.get();
1485                addr.into()
1486            }
1487        }
1488        impl<A: Into<Ipv6Addr> + $witness_trait + Copy> From<$witness<A>> for Ipv6Addr {
1489            fn from(addr: $witness<A>) -> Ipv6Addr {
1490                let addr: A = addr.get();
1491                addr.into()
1492            }
1493        }
1494        // NOTE: Orphan rules prevent implementing `TryFrom` for `A: IpAddress`.
1495        impl TryFrom<Ipv4Addr> for $witness<Ipv4Addr> {
1496            type Error = ();
1497            fn try_from(addr: Ipv4Addr) -> Result<$witness<Ipv4Addr>, ()> {
1498                Witness::new(addr).ok_or(())
1499            }
1500        }
1501        impl TryFrom<Ipv6Addr> for $witness<Ipv6Addr> {
1502            type Error = ();
1503            fn try_from(addr: Ipv6Addr) -> Result<$witness<Ipv6Addr>, ()> {
1504                Witness::new(addr).ok_or(())
1505            }
1506        }
1507    };
1508    ($witness:ident, $witness_trait:ident, $ipaddr:ident, $new_unchecked:expr) => {
1509        impl From<$witness<$ipaddr>> for $witness<IpAddr> {
1510            fn from(addr: $witness<$ipaddr>) -> $witness<IpAddr> {
1511                let addr: $ipaddr = addr.get();
1512                let addr: IpAddr = addr.into();
1513                #[allow(unused_unsafe)] // For when a closure is passed
1514                unsafe {
1515                    $new_unchecked(addr)
1516                }
1517            }
1518        }
1519        impl<A: Into<$ipaddr> + $witness_trait + Copy> From<$witness<A>> for $ipaddr {
1520            fn from(addr: $witness<A>) -> $ipaddr {
1521                let addr: A = addr.get();
1522                addr.into()
1523            }
1524        }
1525        impl TryFrom<$ipaddr> for $witness<$ipaddr> {
1526            type Error = ();
1527            fn try_from(addr: $ipaddr) -> Result<$witness<$ipaddr>, ()> {
1528                Witness::new(addr).ok_or(())
1529            }
1530        }
1531    };
1532}
1533
1534impl_from_witness!(SpecifiedAddr, SpecifiedAddress);
1535impl_from_witness!(MulticastAddr, MulticastAddress);
1536impl_from_witness!(LinkLocalAddr, LinkLocalAddress);
1537impl_from_witness!(NonMappedAddr, MappedAddress);
1538// Only add `From` conversions for `Ipv6Addr`, because `Ipv4Addr` does not
1539// implement `UnicastAddress`.
1540impl_from_witness!(UnicastAddr, UnicastAddress, Ipv6Addr, UnicastAddr::new_unchecked);
1541
1542/// The class of an IPv4 address.
1543///
1544/// The classful addressing scheme is obsoloted in favour of [CIDR] but is still
1545/// used on some systems. For more information, see [RFC 791 section 2.3] and
1546/// [RFC 1812 section 2.2.5.1].
1547///
1548/// [CIDR]: https://datatracker.ietf.org/doc/html/rfc1518
1549/// [RFC 791 section 2.3]: https://datatracker.ietf.org/doc/html/rfc791#section-2.3
1550/// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
1551#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1552pub enum Ipv4AddressClass {
1553    /// A Class A IPv4 address.
1554    A,
1555    /// A Class B IPv4 address.
1556    B,
1557    /// A Class C IPv4 address.
1558    C,
1559    /// A Class D IPv4 address.
1560    ///
1561    /// Class D addresses are also known as multicast.
1562    D,
1563    /// A Class E IPv4 address.
1564    ///
1565    /// Class E addresses are also known as experimental.
1566    E,
1567}
1568
1569impl Ipv4AddressClass {
1570    /// Returns the default prefix length for an IPv4 address class if the
1571    /// prefix is well-defined.
1572    pub const fn default_prefix_len(self) -> Option<u8> {
1573        // Per RFC 943 https://datatracker.ietf.org/doc/html/rfc943
1574        //
1575        //   The first type of address, or class A, has a 7-bit network number
1576        //   and a 24-bit local address.  The highest-order bit is set to 0.
1577        //   This allows 128 class A networks.
1578        //
1579        //                        1                   2                   3
1580        //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1581        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1582        //   |0|   NETWORK   |                Local Address                  |
1583        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1584        //
1585        //                          Class A Address
1586        //
1587        //   The second type of address, class B, has a 14-bit network number
1588        //   and a 16-bit local address.  The two highest-order bits are set to
1589        //   1-0.  This allows 16,384 class B networks.
1590        //
1591        //                        1                   2                   3
1592        //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1593        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1594        //   |1 0|           NETWORK         |          Local Address        |
1595        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1596        //
1597        //                          Class B Address
1598        //
1599        //   The third type of address, class C, has a 21-bit network number
1600        //   and a 8-bit local address.  The three highest-order bits are set
1601        //   to 1-1-0.  This allows 2,097,152 class C networks.
1602        //
1603        //                        1                   2                   3
1604        //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1605        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1606        //   |1 1 0|                    NETWORK              | Local Address |
1607        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1608        //
1609        //                          Class C Address
1610        match self {
1611            Ipv4AddressClass::A => Some(8),
1612            Ipv4AddressClass::B => Some(16),
1613            Ipv4AddressClass::C => Some(24),
1614            Ipv4AddressClass::D => None,
1615            Ipv4AddressClass::E => None,
1616        }
1617    }
1618}
1619
1620/// An IPv4 address.
1621///
1622/// # Layout
1623///
1624/// `Ipv4Addr` has the same layout as `[u8; 4]`, which is the layout that most
1625/// protocols use to represent an IPv4 address in their packet formats. This can
1626/// be useful when parsing an IPv4 address from a packet. For example:
1627///
1628/// ```rust
1629/// # use net_types::ip::Ipv4Addr;
1630/// /// An ICMPv4 Redirect Message header.
1631/// ///
1632/// /// `Icmpv4RedirectHeader` has the same layout as the header of an ICMPv4
1633/// /// Redirect Message.
1634/// #[repr(C)]
1635/// struct Icmpv4RedirectHeader {
1636///     typ: u8,
1637///     code: u8,
1638///     checksum: [u8; 2],
1639///     gateway: Ipv4Addr,
1640/// }
1641/// ```
1642#[derive(
1643    Copy,
1644    Clone,
1645    Default,
1646    PartialEq,
1647    Eq,
1648    PartialOrd,
1649    Ord,
1650    Hash,
1651    KnownLayout,
1652    FromBytes,
1653    IntoBytes,
1654    Immutable,
1655    Unaligned,
1656)]
1657#[repr(transparent)]
1658pub struct Ipv4Addr([u8; 4]);
1659
1660impl Ipv4Addr {
1661    /// Creates a new IPv4 address.
1662    #[inline]
1663    pub const fn new(bytes: [u8; 4]) -> Self {
1664        Ipv4Addr(bytes)
1665    }
1666
1667    /// Gets the bytes of the IPv4 address.
1668    #[inline]
1669    pub const fn ipv4_bytes(self) -> [u8; 4] {
1670        self.0
1671    }
1672
1673    /// Is this the limited broadcast address?
1674    ///
1675    /// `is_limited_broadcast` is a shorthand for comparing against
1676    /// [`Ipv4::LIMITED_BROADCAST_ADDRESS`].
1677    #[inline]
1678    pub fn is_limited_broadcast(self) -> bool {
1679        self == Ipv4::LIMITED_BROADCAST_ADDRESS.get()
1680    }
1681
1682    /// Is this a Class E address?
1683    ///
1684    /// `is_class_e` is a shorthand for checking membership in
1685    /// [`Ipv4::CLASS_E_SUBNET`].
1686    #[inline]
1687    pub fn is_class_e(self) -> bool {
1688        Ipv4::CLASS_E_SUBNET.contains(&self)
1689    }
1690
1691    /// Converts the address to an IPv4-compatible IPv6 address according to
1692    /// [RFC 4291 Section 2.5.5.1].
1693    ///
1694    /// IPv4-compatible IPv6 addresses were defined to assist in the IPv6
1695    /// transition, and are now specified in [RFC 4291 Section 2.5.5.1]. The
1696    /// lowest-order 32 bits carry an IPv4 address, while the highest-order 96
1697    /// bits are all set to 0 as in this diagram from the RFC:
1698    ///
1699    /// ```text
1700    /// |                80 bits               | 16 |      32 bits        |
1701    /// +--------------------------------------+--------------------------+
1702    /// |0000..............................0000|0000|    IPv4 address     |
1703    /// +--------------------------------------+----+---------------------+
1704    /// ```
1705    ///
1706    /// Per RFC 4291:
1707    ///
1708    /// > The 'IPv4-Compatible IPv6 address' is now deprecated because the
1709    /// > current IPv6 transition mechanisms no longer use these addresses. New
1710    /// > or updated implementations are not required to support this address
1711    /// > type.
1712    ///
1713    /// The more modern embedding format is IPv4-mapped IPv6 addressing - see
1714    /// [`to_ipv6_mapped`].
1715    ///
1716    /// [RFC 4291 Section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1
1717    /// [`to_ipv6_mapped`]: Ipv4Addr::to_ipv6_mapped
1718    #[inline]
1719    pub fn to_ipv6_compatible(self) -> Ipv6Addr {
1720        let Self([a, b, c, d]) = self;
1721        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d])
1722    }
1723
1724    /// Converts the address to an IPv4-mapped IPv6 address according to [RFC
1725    /// 4291 Section 2.5.5.2].
1726    ///
1727    /// IPv4-mapped IPv6 addresses are used to represent the addresses of IPv4
1728    /// nodes as IPv6 addresses, and are defined in [RFC 4291 Section 2.5.5.2].
1729    /// The lowest-order 32 bits carry an IPv4 address, the middle order 16 bits
1730    /// carry the literal 0xFFFF, and the highest order 80 bits are set to 0 as
1731    /// in this diagram from the RFC:
1732    ///
1733    /// ```text
1734    /// |                80 bits               | 16 |      32 bits        |
1735    /// +--------------------------------------+--------------------------+
1736    /// |0000..............................0000|FFFF|    IPv4 address     |
1737    /// +--------------------------------------+----+---------------------+
1738    /// ```
1739    ///
1740    /// [RFC 4291 Section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
1741    #[inline]
1742    pub fn to_ipv6_mapped(self) -> SpecifiedAddr<Ipv6Addr> {
1743        let Self([a, b, c, d]) = self;
1744        SpecifiedAddr::new(Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d]))
1745            .unwrap()
1746    }
1747
1748    /// Returns the address's class according to the obsoleted classful
1749    /// addressing architecture.
1750    pub fn class(&self) -> Ipv4AddressClass {
1751        for (subnet, class) in [
1752            (Ipv4::CLASS_A_SUBNET, Ipv4AddressClass::A),
1753            (Ipv4::CLASS_B_SUBNET, Ipv4AddressClass::B),
1754            (Ipv4::CLASS_C_SUBNET, Ipv4AddressClass::C),
1755            (Ipv4::CLASS_D_SUBNET, Ipv4AddressClass::D),
1756            (Ipv4::CLASS_E_SUBNET, Ipv4AddressClass::E),
1757        ] {
1758            if subnet.contains(self) {
1759                return class;
1760            }
1761        }
1762
1763        unreachable!("{} should fit into a class", self)
1764    }
1765}
1766
1767impl sealed::Sealed for Ipv4Addr {}
1768
1769impl IpAddress for Ipv4Addr {
1770    const BYTES: u8 = 4;
1771
1772    type Version = Ipv4;
1773
1774    #[inline]
1775    fn mask(&self, bits: u8) -> Self {
1776        assert!(bits <= 32);
1777        // Need to perform a checked shift left in case `bits == 32`, in which
1778        // case an unchecked shift left (`u32::MAX << bits`) would overflow,
1779        // causing a panic in debug mode.
1780        let mask = u32::MAX.checked_shl((32 - bits).into()).unwrap_or(0);
1781        Ipv4Addr((u32::from_be_bytes(self.0) & mask).to_be_bytes())
1782    }
1783
1784    #[inline]
1785    fn bytes(&self) -> &[u8] {
1786        &self.0
1787    }
1788
1789    #[inline]
1790    fn to_ip_addr(&self) -> IpAddr {
1791        IpAddr::V4(*self)
1792    }
1793
1794    #[inline]
1795    fn common_prefix_len(&self, other: &Ipv4Addr) -> u8 {
1796        let me = u32::from_be_bytes(self.0);
1797        let other = u32::from_be_bytes(other.0);
1798        // `same_bits` has a 0 wherever `me` and `other` have the same bit in a
1799        // given position, and a 1 wherever they have opposite bits.
1800        let same_bits = me ^ other;
1801        same_bits.leading_zeros() as u8
1802    }
1803
1804    #[inline]
1805    fn is_unicast_in_subnet(&self, subnet: &Subnet<Self>) -> bool {
1806        !self.is_multicast()
1807            && !self.is_limited_broadcast()
1808            // This clause implements the rules that (the subnet broadcast is
1809            // not unicast AND the address with an all-zeroes host part is not
1810            // unicast) UNLESS the prefix length is 31 or 32.
1811            && (subnet.prefix() == 32
1812            || subnet.prefix() == 31
1813            || (*self != subnet.broadcast() && *self != subnet.network()))
1814            && self.is_specified()
1815            && !self.is_class_e()
1816            && subnet.contains(self)
1817    }
1818
1819    fn subnet_into_either(subnet: Subnet<Ipv4Addr>) -> SubnetEither {
1820        SubnetEither::V4(subnet)
1821    }
1822
1823    #[inline]
1824    fn array_into_ip_addr<const N: usize>(
1825        addrs: [Self; N],
1826    ) -> IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]> {
1827        IpAddr::V4(addrs)
1828    }
1829}
1830
1831impl From<[u8; 4]> for Ipv4Addr {
1832    #[inline]
1833    fn from(bytes: [u8; 4]) -> Ipv4Addr {
1834        Ipv4Addr(bytes)
1835    }
1836}
1837
1838#[cfg(feature = "std")]
1839impl From<net::Ipv4Addr> for Ipv4Addr {
1840    #[inline]
1841    fn from(ip: net::Ipv4Addr) -> Ipv4Addr {
1842        Ipv4Addr::new(ip.octets())
1843    }
1844}
1845
1846#[cfg(feature = "std")]
1847impl From<Ipv4Addr> for net::Ipv4Addr {
1848    #[inline]
1849    fn from(ip: Ipv4Addr) -> net::Ipv4Addr {
1850        net::Ipv4Addr::from(ip.0)
1851    }
1852}
1853
1854impl Display for Ipv4Addr {
1855    #[inline]
1856    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
1857        write!(f, "{}.{}.{}.{}", self.0[0], self.0[1], self.0[2], self.0[3])
1858    }
1859}
1860
1861impl Debug for Ipv4Addr {
1862    #[inline]
1863    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
1864        Display::fmt(self, f)
1865    }
1866}
1867
1868/// The source address from an IPv4 packet.
1869///
1870/// An `Ipv4SourceAddr` represents the source address from an IPv4 packet which
1871/// may only be either:
1872///   * specified and non-multicast, or
1873///   * unspecified.
1874#[allow(missing_docs)]
1875#[derive(Copy, Clone, Eq, PartialEq)]
1876pub enum Ipv4SourceAddr {
1877    Specified(NonMulticastAddr<SpecifiedAddr<Ipv4Addr>>),
1878    Unspecified,
1879}
1880
1881impl crate::sealed::Sealed for Ipv4SourceAddr {}
1882
1883impl Ipv4SourceAddr {
1884    /// Constructs a new `Ipv4SourceAddr`.
1885    ///
1886    /// Returns `None` if `addr` does not satisfy the properties required of an
1887    /// `Ipv4SourceAddr`.
1888    #[inline]
1889    pub fn new(addr: Ipv4Addr) -> Option<Ipv4SourceAddr> {
1890        match SpecifiedAddr::new(addr) {
1891            Some(addr) => NonMulticastAddr::new(addr).map(Ipv4SourceAddr::Specified),
1892            None => Some(Ipv4SourceAddr::Unspecified),
1893        }
1894    }
1895}
1896
1897impl Witness<Ipv4Addr> for Ipv4SourceAddr {
1898    #[inline]
1899    fn new(addr: Ipv4Addr) -> Option<Ipv4SourceAddr> {
1900        Ipv4SourceAddr::new(addr)
1901    }
1902
1903    #[inline]
1904    unsafe fn new_unchecked(addr: Ipv4Addr) -> Ipv4SourceAddr {
1905        Ipv4SourceAddr::new(addr).unwrap()
1906    }
1907
1908    #[inline]
1909    fn into_addr(self) -> Ipv4Addr {
1910        match self {
1911            Ipv4SourceAddr::Specified(addr) => **addr,
1912            Ipv4SourceAddr::Unspecified => Ipv4::UNSPECIFIED_ADDRESS,
1913        }
1914    }
1915}
1916
1917impl From<Ipv4SourceAddr> for Ipv4Addr {
1918    fn from(addr: Ipv4SourceAddr) -> Ipv4Addr {
1919        addr.get()
1920    }
1921}
1922
1923impl AsRef<Ipv4Addr> for Ipv4SourceAddr {
1924    fn as_ref(&self) -> &Ipv4Addr {
1925        match self {
1926            Ipv4SourceAddr::Specified(addr) => addr,
1927            Ipv4SourceAddr::Unspecified => &Ipv4::UNSPECIFIED_ADDRESS,
1928        }
1929    }
1930}
1931
1932impl Deref for Ipv4SourceAddr {
1933    type Target = Ipv4Addr;
1934
1935    fn deref(&self) -> &Ipv4Addr {
1936        self.as_ref()
1937    }
1938}
1939
1940impl Display for Ipv4SourceAddr {
1941    #[inline]
1942    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
1943        write!(f, "{}", self.get())
1944    }
1945}
1946
1947impl Debug for Ipv4SourceAddr {
1948    #[inline]
1949    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
1950        Display::fmt(self, f)
1951    }
1952}
1953
1954/// An IPv6 address.
1955///
1956/// # Layout
1957///
1958/// `Ipv6Addr` has the same layout as `[u8; 16]`, which is the layout that most
1959/// protocols use to represent an IPv6 address in their packet formats. This can
1960/// be useful when parsing an IPv6 address from a packet. For example:
1961///
1962/// ```rust
1963/// # use net_types::ip::Ipv6Addr;
1964/// /// The fixed part of an IPv6 packet header.
1965/// ///
1966/// /// `FixedHeader` has the same layout as the fixed part of an IPv6 packet
1967/// /// header.
1968/// #[repr(C)]
1969/// pub struct FixedHeader {
1970///     version_tc_flowlabel: [u8; 4],
1971///     payload_len: [u8; 2],
1972///     next_hdr: u8,
1973///     hop_limit: u8,
1974///     src_ip: Ipv6Addr,
1975///     dst_ip: Ipv6Addr,
1976/// }
1977/// ```
1978///
1979/// # `Display`
1980///
1981/// The [`Display`] impl for `Ipv6Addr` formats according to [RFC 5952].
1982///
1983/// Where RFC 5952 leaves decisions up to the implementation, `Ipv6Addr` matches
1984/// the behavior of [`std::net::Ipv6Addr`] - all IPv6 addresses are formatted
1985/// the same by `Ipv6Addr` as by `<std::net::Ipv6Addr as Display>::fmt`.
1986///
1987/// [RFC 5952]: https://datatracker.ietf.org/doc/html/rfc5952
1988#[derive(
1989    Copy,
1990    Clone,
1991    Default,
1992    PartialEq,
1993    Eq,
1994    PartialOrd,
1995    Ord,
1996    Hash,
1997    KnownLayout,
1998    FromBytes,
1999    IntoBytes,
2000    Immutable,
2001    Unaligned,
2002)]
2003#[repr(transparent)]
2004pub struct Ipv6Addr([u8; 16]);
2005
2006impl Ipv6Addr {
2007    /// Creates a new IPv6 address from 16-bit segments.
2008    #[inline]
2009    pub const fn new(segments: [u16; 8]) -> Ipv6Addr {
2010        #![allow(clippy::many_single_char_names)]
2011        let [a, b, c, d, e, f, g, h] = segments;
2012        let [aa, ab] = a.to_be_bytes();
2013        let [ba, bb] = b.to_be_bytes();
2014        let [ca, cb] = c.to_be_bytes();
2015        let [da, db] = d.to_be_bytes();
2016        let [ea, eb] = e.to_be_bytes();
2017        let [fa, fb] = f.to_be_bytes();
2018        let [ga, gb] = g.to_be_bytes();
2019        let [ha, hb] = h.to_be_bytes();
2020        Ipv6Addr([aa, ab, ba, bb, ca, cb, da, db, ea, eb, fa, fb, ga, gb, ha, hb])
2021    }
2022
2023    /// Creates a new IPv6 address from bytes.
2024    #[inline]
2025    pub const fn from_bytes(bytes: [u8; 16]) -> Ipv6Addr {
2026        Ipv6Addr(bytes)
2027    }
2028
2029    /// Gets the bytes of the IPv6 address.
2030    #[inline]
2031    pub const fn ipv6_bytes(&self) -> [u8; 16] {
2032        self.0
2033    }
2034
2035    /// Gets the 16-bit segments of the IPv6 address.
2036    #[inline]
2037    pub fn segments(&self) -> [u16; 8] {
2038        #![allow(clippy::many_single_char_names)]
2039        let [a, b, c, d, e, f, g, h]: [zerocopy::network_endian::U16; 8] =
2040            zerocopy::transmute!(self.ipv6_bytes());
2041        [a.into(), b.into(), c.into(), d.into(), e.into(), f.into(), g.into(), h.into()]
2042    }
2043
2044    /// Converts this `Ipv6Addr` to the IPv6 Solicited-Node Address, used in
2045    /// Neighbor Discovery, defined in [RFC 4291 Section 2.7.1].
2046    ///
2047    /// [RFC 4291 Section 2.7.1]: https://tools.ietf.org/html/rfc4291#section-2.7.1
2048    #[inline]
2049    pub const fn to_solicited_node_address(&self) -> MulticastAddr<Ipv6Addr> {
2050        // TODO(brunodalbo) benchmark this generation and evaluate if using
2051        //  bit operations with u128 could be faster. This is very likely
2052        //  going to be on a hot path.
2053
2054        // We know we are not breaking the guarantee that `MulticastAddr` provides
2055        // when calling `new_unchecked` because the address we provide it is
2056        // a multicast address as defined by RFC 4291 section 2.7.1.
2057        unsafe {
2058            MulticastAddr::new_unchecked(Ipv6Addr::from_bytes([
2059                0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, self.0[13], self.0[14],
2060                self.0[15],
2061            ]))
2062        }
2063    }
2064
2065    /// Is this a valid unicast address?
2066    ///
2067    /// A valid unicast address is any unicast address that can be bound to an
2068    /// interface (not the unspecified or loopback addresses).
2069    /// `addr.is_valid_unicast()` is equivalent to `!(addr.is_loopback() ||
2070    /// !addr.is_specified() || addr.is_multicast())`.
2071    #[inline]
2072    pub fn is_valid_unicast(&self) -> bool {
2073        !(self.is_loopback() || !self.is_specified() || self.is_multicast())
2074    }
2075
2076    /// Is this address in the (deprecated) site-local unicast subnet?
2077    ///
2078    /// `is_site_local` returns true if `self` is in the (deprecated)
2079    /// [`Ipv6::SITE_LOCAL_UNICAST_SUBNET`]. See that constant's documentation
2080    /// for more details on deprecation and how the subnet should be used in
2081    /// light of deprecation.
2082    #[inline]
2083    pub fn is_site_local(&self) -> bool {
2084        Ipv6::SITE_LOCAL_UNICAST_SUBNET.contains(self)
2085    }
2086
2087    /// Is this a unicast link-local address?
2088    ///
2089    /// `addr.is_unicast_link_local()` is equivalent to
2090    /// `addr.is_unicast_in_subnet(&Ipv6::LINK_LOCAL_UNICAST_SUBNET)`.
2091    #[inline]
2092    pub fn is_unicast_link_local(&self) -> bool {
2093        self.is_unicast_in_subnet(&Ipv6::LINK_LOCAL_UNICAST_SUBNET)
2094    }
2095
2096    /// Tries to extract the IPv4 address from an IPv4-compatible IPv6 address.
2097    ///
2098    /// IPv4-compatible IPv6 addresses were defined to assist in the IPv6
2099    /// transition, and are now specified in [RFC 4291 Section 2.5.5.1]. The
2100    /// lowest-order 32 bits carry an IPv4 address, while the highest-order 96
2101    /// bits are all set to 0 as in this diagram from the RFC:
2102    ///
2103    /// ```text
2104    /// |                80 bits               | 16 |      32 bits        |
2105    /// +--------------------------------------+--------------------------+
2106    /// |0000..............................0000|0000|    IPv4 address     |
2107    /// +--------------------------------------+----+---------------------+
2108    /// ```
2109    ///
2110    /// `to_ipv4_compatible` checks to see if `self` is an IPv4-compatible
2111    /// IPv6 address. If it is, the IPv4 address is extracted and returned.
2112    ///
2113    /// Per RFC 4291:
2114    ///
2115    /// > The 'IPv4-Compatible IPv6 address' is now deprecated because the
2116    /// > current IPv6 transition mechanisms no longer use these addresses. New
2117    /// > or updated implementations are not required to support this address
2118    /// > type.
2119    ///
2120    /// The more modern embedding format is IPv4-mapped IPv6 addressing - see
2121    /// [`to_ipv4_mapped`].
2122    ///
2123    /// [RFC 4291 Section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1
2124    /// [`to_ipv4_mapped`]: Ipv6Addr::to_ipv4_mapped
2125    pub fn to_ipv4_compatible(&self) -> Option<Ipv4Addr> {
2126        if let [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] = self.0 {
2127            Some(Ipv4Addr::new([a, b, c, d]))
2128        } else {
2129            None
2130        }
2131    }
2132
2133    /// Tries to extract the IPv4 address from an IPv4-mapped IPv6 address.
2134    ///
2135    /// IPv4-mapped IPv6 addresses are used to represent the addresses of IPv4
2136    /// nodes as IPv6 addresses, and are defined in [RFC 4291 Section 2.5.5.2].
2137    /// The lowest-order 32 bits carry an IPv4 address, the middle order 16 bits
2138    /// carry the literal 0xFFFF, and the highest order 80 bits are set to 0 as
2139    /// in this diagram from the RFC:
2140    ///
2141    /// ```text
2142    /// |                80 bits               | 16 |      32 bits        |
2143    /// +--------------------------------------+--------------------------+
2144    /// |0000..............................0000|FFFF|    IPv4 address     |
2145    /// +--------------------------------------+----+---------------------+
2146    /// ```
2147    ///
2148    /// `to_ipv4_mapped` checks to see if `self` is an IPv4-mapped
2149    /// IPv6 address. If it is, the IPv4 address is extracted and returned.
2150    ///
2151    /// [RFC 4291 Section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
2152    pub fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
2153        if let [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] = self.0 {
2154            Some(Ipv4Addr::new([a, b, c, d]))
2155        } else {
2156            None
2157        }
2158    }
2159}
2160
2161impl sealed::Sealed for Ipv6Addr {}
2162
2163/// [`Ipv4Addr`] is convertible into [`Ipv6Addr`] through
2164/// [`Ipv4Addr::to_ipv6_mapped`].
2165impl From<Ipv4Addr> for Ipv6Addr {
2166    fn from(addr: Ipv4Addr) -> Ipv6Addr {
2167        *addr.to_ipv6_mapped()
2168    }
2169}
2170
2171impl IpAddress for Ipv6Addr {
2172    const BYTES: u8 = 16;
2173
2174    type Version = Ipv6;
2175
2176    #[inline]
2177    fn mask(&self, bits: u8) -> Ipv6Addr {
2178        assert!(bits <= 128);
2179        // Need to perform a checked shift left in case `bits == 128`, in which
2180        // case an unchecked shift left (`u128::MAX << bits`) would overflow,
2181        // causing a panic in debug mode.
2182        let mask = u128::MAX.checked_shl((128 - bits).into()).unwrap_or(0);
2183        Ipv6Addr((u128::from_be_bytes(self.0) & mask).to_be_bytes())
2184    }
2185
2186    #[inline]
2187    fn bytes(&self) -> &[u8] {
2188        &self.0
2189    }
2190
2191    #[inline]
2192    fn to_ip_addr(&self) -> IpAddr {
2193        IpAddr::V6(*self)
2194    }
2195
2196    #[inline]
2197    fn common_prefix_len(&self, other: &Ipv6Addr) -> u8 {
2198        let me = u128::from_be_bytes(self.0);
2199        let other = u128::from_be_bytes(other.0);
2200        // `same_bits` has a 0 wherever `me` and `other` have the same bit in a
2201        // given position, and a 1 wherever they have opposite bits.
2202        let same_bits = me ^ other;
2203        same_bits.leading_zeros() as u8
2204    }
2205
2206    #[inline]
2207    fn is_unicast_in_subnet(&self, subnet: &Subnet<Self>) -> bool {
2208        !self.is_multicast() && self.is_specified() && subnet.contains(self)
2209    }
2210
2211    fn subnet_into_either(subnet: Subnet<Ipv6Addr>) -> SubnetEither {
2212        SubnetEither::V6(subnet)
2213    }
2214
2215    #[inline]
2216    fn array_into_ip_addr<const N: usize>(
2217        addrs: [Self; N],
2218    ) -> IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]> {
2219        IpAddr::V6(addrs)
2220    }
2221}
2222
2223impl UnicastAddress for Ipv6Addr {
2224    /// Is this a unicast address?
2225    ///
2226    /// `addr.is_unicast()` is equivalent to `!addr.is_multicast() &&
2227    /// addr.is_specified()`.
2228    #[inline]
2229    fn is_unicast(&self) -> bool {
2230        !self.is_multicast() && self.is_specified()
2231    }
2232}
2233
2234impl From<[u8; 16]> for Ipv6Addr {
2235    #[inline]
2236    fn from(bytes: [u8; 16]) -> Ipv6Addr {
2237        Ipv6Addr::from_bytes(bytes)
2238    }
2239}
2240
2241#[cfg(feature = "std")]
2242impl From<net::Ipv6Addr> for Ipv6Addr {
2243    #[inline]
2244    fn from(addr: net::Ipv6Addr) -> Ipv6Addr {
2245        Ipv6Addr::from_bytes(addr.octets())
2246    }
2247}
2248
2249#[cfg(feature = "std")]
2250impl From<Ipv6Addr> for net::Ipv6Addr {
2251    #[inline]
2252    fn from(addr: Ipv6Addr) -> net::Ipv6Addr {
2253        net::Ipv6Addr::from(addr.ipv6_bytes())
2254    }
2255}
2256
2257impl Display for Ipv6Addr {
2258    /// Formats an IPv6 address according to [RFC 5952].
2259    ///
2260    /// Where RFC 5952 leaves decisions up to the implementation, this function
2261    /// matches the behavior of [`std::net::Ipv6Addr`] - all IPv6 addresses are
2262    /// formatted the same by this function as by `<std::net::Ipv6Addr as
2263    /// Display>::fmt`.
2264    ///
2265    /// [RFC 5952]: https://datatracker.ietf.org/doc/html/rfc5952
2266    #[inline]
2267    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2268        // `fmt_inner` implements the core of the formatting algorithm, but does
2269        // not handle precision or width requirements. Those are handled below
2270        // by creating a scratch buffer, calling `fmt_inner` on that scratch
2271        // buffer, and then satisfying those requirements.
2272        fn fmt_inner<W: fmt::Write>(addr: &Ipv6Addr, w: &mut W) -> Result<(), fmt::Error> {
2273            // We special-case the unspecified address, localhost address, and
2274            // IPv4-mapped addresses, but not IPv4-compatible addresses. We
2275            // follow Rust's behavior here: https://github.com/rust-lang/rust/pull/112606
2276            if !addr.is_specified() {
2277                write!(w, "::")
2278            } else if addr.is_loopback() {
2279                write!(w, "::1")
2280            } else if let Some(v4) = addr.to_ipv4_mapped() {
2281                write!(w, "::ffff:{}", v4)
2282            } else {
2283                let segments = addr.segments();
2284
2285                let longest_zero_span = {
2286                    let mut longest_zero_span = 0..0;
2287                    let mut current_zero_span = 0..0;
2288                    for (i, seg) in segments.iter().enumerate() {
2289                        if *seg == 0 {
2290                            current_zero_span.end = i + 1;
2291                            if current_zero_span.len() > longest_zero_span.len() {
2292                                longest_zero_span = current_zero_span.clone();
2293                            }
2294                        } else {
2295                            let next_idx = i + 1;
2296                            current_zero_span = next_idx..next_idx;
2297                        }
2298                    }
2299                    longest_zero_span
2300                };
2301
2302                let write_slice = |w: &mut W, slice: &[u16]| {
2303                    if let [head, tail @ ..] = slice {
2304                        write!(w, "{:x}", head)?;
2305                        for seg in tail {
2306                            write!(w, ":{:x}", seg)?;
2307                        }
2308                    }
2309                    Ok(())
2310                };
2311
2312                // Note that RFC 5952 gives us a choice of when to compress a
2313                // run of zeroes:
2314                //
2315                //   It is possible to select whether or not to omit just one
2316                //   16-bit 0 field.
2317                //
2318                // Given this choice, we opt to match the stdlib's behavior.
2319                // This makes it easier to write tests (we can simply check to
2320                // see whether our behavior matches `std`'s behavior on a range
2321                // of inputs), and makes it so that our `Ipv6Addr` type is,
2322                // behaviorally, more of a drop-in for `std::net::Ipv6Addr` than
2323                // it would be if we were to diverge on formatting. This makes
2324                // replacing `std::net::Ipv6Addr` with our `Ipv6Addr` easier for
2325                // clients, and also makes it an easier choice since they don't
2326                // have to weigh whether the difference in behavior is
2327                // acceptable for them.
2328                if longest_zero_span.len() > 1 {
2329                    write_slice(w, &segments[..longest_zero_span.start])?;
2330                    w.write_str("::")?;
2331                    write_slice(w, &segments[longest_zero_span.end..])
2332                } else {
2333                    write_slice(w, &segments)
2334                }
2335            }
2336        }
2337
2338        if f.precision().is_none() && f.width().is_none() {
2339            // Fast path: No precision or width requirements, so write directly
2340            // to `f`.
2341            fmt_inner(self, f)
2342        } else {
2343            // Slow path: Precision or width requirement(s), so construct a
2344            // scratch buffer, use the `fmt_inner` to fill it, then use `f.pad`
2345            // to satisfy precision/width requirement(s).
2346
2347            // `[u8]` does not implement `core::fmt::Write`, so we provide our
2348            // own wrapper which does.
2349            struct ByteSlice<'a>(&'a mut [u8]);
2350
2351            impl<'a> fmt::Write for ByteSlice<'a> {
2352                fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
2353                    let from = s.as_bytes();
2354
2355                    if from.len() > self.0.len() {
2356                        return Err(fmt::Error);
2357                    }
2358
2359                    // Temporarily replace `self.0` with an empty slice and move
2360                    // the old value of `self.0` into our scope so that we can
2361                    // operate on it by value. This allows us to split it in two
2362                    // (`to` and `remaining`) and then overwrite `self.0` with
2363                    // `remaining`.
2364                    let to = mem::replace(&mut self.0, &mut [][..]);
2365                    let (to, remaining) = to.split_at_mut(from.len());
2366                    to.copy_from_slice(from);
2367
2368                    self.0 = remaining;
2369                    Ok(())
2370                }
2371            }
2372
2373            // The maximum length for an IPv6 address displays all 8 pairs of
2374            // bytes in hexadecimal representation (4 characters per two bytes
2375            // of IPv6 address), each separated with colons (7 colons total).
2376            const MAX_DISPLAY_LEN: usize = (4 * 8) + 7;
2377            let mut scratch = [0u8; MAX_DISPLAY_LEN];
2378            let mut scratch_slice = ByteSlice(&mut scratch[..]);
2379            // `fmt_inner` only returns an error if a method on `w` returns an
2380            // error. Since, in this call to `fmt_inner`, `w` is
2381            // `scratch_slice`, the only error that could happen would be if we
2382            // run out of space, but we know we won't because `scratch_slice`
2383            // has `MAX_DISPLAY_LEN` bytes, which is enough to hold any
2384            // formatted IPv6 address.
2385            fmt_inner(self, &mut scratch_slice)
2386                .expect("<Ipv6Addr as Display>::fmt: fmt_inner should have succeeded because the scratch buffer was long enough");
2387            let unwritten = scratch_slice.0.len();
2388            let len = MAX_DISPLAY_LEN - unwritten;
2389            // `fmt_inner` only writes valid UTF-8.
2390            let str = core::str::from_utf8(&scratch[..len])
2391                .expect("<Ipv6Addr as Display>::fmt: scratch buffer should contain valid UTF-8");
2392            f.pad(str)
2393        }
2394    }
2395}
2396
2397impl Debug for Ipv6Addr {
2398    #[inline]
2399    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2400        Display::fmt(self, f)
2401    }
2402}
2403
2404/// The source address from an IPv6 packet.
2405///
2406/// An `Ipv6SourceAddr` represents the source address from an IPv6 packet, which
2407/// may only be either:
2408///   * unicast and non-mapped (e.g. not an ipv4-mapped-ipv6 address), or
2409///   * unspecified.
2410#[allow(missing_docs)]
2411#[derive(Copy, Clone, Eq, PartialEq)]
2412pub enum Ipv6SourceAddr {
2413    Unicast(NonMappedAddr<UnicastAddr<Ipv6Addr>>),
2414    Unspecified,
2415}
2416
2417impl crate::sealed::Sealed for Ipv6SourceAddr {}
2418
2419impl Ipv6SourceAddr {
2420    /// Constructs a new `Ipv6SourceAddr`.
2421    ///
2422    /// Returns `None` if `addr` does not satisfy the properties required of an
2423    /// `Ipv6SourceAddr`.
2424    #[inline]
2425    pub fn new(addr: Ipv6Addr) -> Option<Ipv6SourceAddr> {
2426        if let Some(addr) = UnicastAddr::new(addr) {
2427            NonMappedAddr::new(addr).map(Ipv6SourceAddr::Unicast)
2428        } else if !addr.is_specified() {
2429            Some(Ipv6SourceAddr::Unspecified)
2430        } else {
2431            None
2432        }
2433    }
2434}
2435
2436impl Witness<Ipv6Addr> for Ipv6SourceAddr {
2437    #[inline]
2438    fn new(addr: Ipv6Addr) -> Option<Ipv6SourceAddr> {
2439        Ipv6SourceAddr::new(addr)
2440    }
2441
2442    #[inline]
2443    unsafe fn new_unchecked(addr: Ipv6Addr) -> Ipv6SourceAddr {
2444        Ipv6SourceAddr::new(addr).unwrap()
2445    }
2446
2447    #[inline]
2448    fn into_addr(self) -> Ipv6Addr {
2449        match self {
2450            Ipv6SourceAddr::Unicast(addr) => **addr,
2451            Ipv6SourceAddr::Unspecified => Ipv6::UNSPECIFIED_ADDRESS,
2452        }
2453    }
2454}
2455
2456impl SpecifiedAddress for Ipv6SourceAddr {
2457    fn is_specified(&self) -> bool {
2458        self != &Ipv6SourceAddr::Unspecified
2459    }
2460}
2461
2462impl UnicastAddress for Ipv6SourceAddr {
2463    fn is_unicast(&self) -> bool {
2464        matches!(self, Ipv6SourceAddr::Unicast(_))
2465    }
2466}
2467
2468impl LinkLocalAddress for Ipv6SourceAddr {
2469    fn is_link_local(&self) -> bool {
2470        let addr: Ipv6Addr = self.into();
2471        addr.is_link_local()
2472    }
2473}
2474
2475impl MappedAddress for Ipv6SourceAddr {
2476    fn is_non_mapped(&self) -> bool {
2477        let addr: Ipv6Addr = self.into();
2478        addr.is_non_mapped()
2479    }
2480}
2481
2482impl From<Ipv6SourceAddr> for Ipv6Addr {
2483    fn from(addr: Ipv6SourceAddr) -> Ipv6Addr {
2484        addr.get()
2485    }
2486}
2487
2488impl From<&'_ Ipv6SourceAddr> for Ipv6Addr {
2489    fn from(addr: &Ipv6SourceAddr) -> Ipv6Addr {
2490        match addr {
2491            Ipv6SourceAddr::Unicast(addr) => addr.get(),
2492            Ipv6SourceAddr::Unspecified => Ipv6::UNSPECIFIED_ADDRESS,
2493        }
2494    }
2495}
2496
2497impl TryFrom<Ipv6Addr> for Ipv6SourceAddr {
2498    type Error = ();
2499    fn try_from(addr: Ipv6Addr) -> Result<Ipv6SourceAddr, ()> {
2500        Ipv6SourceAddr::new(addr).ok_or(())
2501    }
2502}
2503
2504impl AsRef<Ipv6Addr> for Ipv6SourceAddr {
2505    fn as_ref(&self) -> &Ipv6Addr {
2506        match self {
2507            Ipv6SourceAddr::Unicast(addr) => addr,
2508            Ipv6SourceAddr::Unspecified => &Ipv6::UNSPECIFIED_ADDRESS,
2509        }
2510    }
2511}
2512
2513impl Deref for Ipv6SourceAddr {
2514    type Target = Ipv6Addr;
2515
2516    fn deref(&self) -> &Ipv6Addr {
2517        self.as_ref()
2518    }
2519}
2520
2521impl Display for Ipv6SourceAddr {
2522    #[inline]
2523    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2524        match self {
2525            Ipv6SourceAddr::Unicast(addr) => write!(f, "{}", addr),
2526            Ipv6SourceAddr::Unspecified => write!(f, "::"),
2527        }
2528    }
2529}
2530
2531impl Debug for Ipv6SourceAddr {
2532    #[inline]
2533    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2534        Display::fmt(self, f)
2535    }
2536}
2537
2538/// An IPv6 address stored as a unicast or multicast witness type.
2539///
2540/// `UnicastOrMulticastIpv6Addr` is either a [`UnicastAddr`] or a
2541/// [`MulticastAddr`]. It allows the user to match on the unicast-ness or
2542/// multicast-ness of an IPv6 address and obtain a statically-typed witness in
2543/// each case. This is useful if the user needs to call different functions
2544/// which each take a witness type.
2545#[allow(missing_docs)]
2546#[derive(Copy, Clone, Eq, PartialEq)]
2547pub enum UnicastOrMulticastIpv6Addr {
2548    Unicast(UnicastAddr<Ipv6Addr>),
2549    Multicast(MulticastAddr<Ipv6Addr>),
2550}
2551
2552impl UnicastOrMulticastIpv6Addr {
2553    /// Constructs a new `UnicastOrMulticastIpv6Addr`.
2554    ///
2555    /// Returns `None` if `addr` is the unspecified address.
2556    pub fn new(addr: Ipv6Addr) -> Option<UnicastOrMulticastIpv6Addr> {
2557        SpecifiedAddr::new(addr).map(UnicastOrMulticastIpv6Addr::from_specified)
2558    }
2559
2560    /// Constructs a new `UnicastOrMulticastIpv6Addr` from a specified address.
2561    pub fn from_specified(addr: SpecifiedAddr<Ipv6Addr>) -> UnicastOrMulticastIpv6Addr {
2562        if addr.is_unicast() {
2563            UnicastOrMulticastIpv6Addr::Unicast(UnicastAddr(addr.get()))
2564        } else {
2565            UnicastOrMulticastIpv6Addr::Multicast(MulticastAddr(addr.get()))
2566        }
2567    }
2568}
2569
2570impl crate::sealed::Sealed for UnicastOrMulticastIpv6Addr {}
2571
2572impl Witness<Ipv6Addr> for UnicastOrMulticastIpv6Addr {
2573    #[inline]
2574    fn new(addr: Ipv6Addr) -> Option<UnicastOrMulticastIpv6Addr> {
2575        UnicastOrMulticastIpv6Addr::new(addr)
2576    }
2577
2578    #[inline]
2579    unsafe fn new_unchecked(addr: Ipv6Addr) -> UnicastOrMulticastIpv6Addr {
2580        UnicastOrMulticastIpv6Addr::new(addr).unwrap()
2581    }
2582
2583    #[inline]
2584    fn into_addr(self) -> Ipv6Addr {
2585        match self {
2586            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr.get(),
2587            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr.get(),
2588        }
2589    }
2590}
2591
2592impl UnicastAddress for UnicastOrMulticastIpv6Addr {
2593    fn is_unicast(&self) -> bool {
2594        matches!(self, UnicastOrMulticastIpv6Addr::Unicast(_))
2595    }
2596}
2597
2598impl MulticastAddress for UnicastOrMulticastIpv6Addr {
2599    fn is_multicast(&self) -> bool {
2600        matches!(self, UnicastOrMulticastIpv6Addr::Multicast(_))
2601    }
2602}
2603
2604impl LinkLocalAddress for UnicastOrMulticastIpv6Addr {
2605    fn is_link_local(&self) -> bool {
2606        match self {
2607            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr.is_link_local(),
2608            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr.is_link_local(),
2609        }
2610    }
2611}
2612
2613impl MappedAddress for UnicastOrMulticastIpv6Addr {
2614    fn is_non_mapped(&self) -> bool {
2615        match self {
2616            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr.is_non_mapped(),
2617            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr.is_non_mapped(),
2618        }
2619    }
2620}
2621
2622impl From<UnicastOrMulticastIpv6Addr> for Ipv6Addr {
2623    fn from(addr: UnicastOrMulticastIpv6Addr) -> Ipv6Addr {
2624        addr.get()
2625    }
2626}
2627
2628impl From<&'_ UnicastOrMulticastIpv6Addr> for Ipv6Addr {
2629    fn from(addr: &UnicastOrMulticastIpv6Addr) -> Ipv6Addr {
2630        addr.get()
2631    }
2632}
2633
2634impl From<UnicastAddr<Ipv6Addr>> for UnicastOrMulticastIpv6Addr {
2635    fn from(addr: UnicastAddr<Ipv6Addr>) -> UnicastOrMulticastIpv6Addr {
2636        UnicastOrMulticastIpv6Addr::Unicast(addr)
2637    }
2638}
2639
2640impl From<MulticastAddr<Ipv6Addr>> for UnicastOrMulticastIpv6Addr {
2641    fn from(addr: MulticastAddr<Ipv6Addr>) -> UnicastOrMulticastIpv6Addr {
2642        UnicastOrMulticastIpv6Addr::Multicast(addr)
2643    }
2644}
2645
2646impl TryFrom<Ipv6Addr> for UnicastOrMulticastIpv6Addr {
2647    type Error = ();
2648    fn try_from(addr: Ipv6Addr) -> Result<UnicastOrMulticastIpv6Addr, ()> {
2649        UnicastOrMulticastIpv6Addr::new(addr).ok_or(())
2650    }
2651}
2652
2653impl AsRef<Ipv6Addr> for UnicastOrMulticastIpv6Addr {
2654    fn as_ref(&self) -> &Ipv6Addr {
2655        match self {
2656            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr,
2657            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr,
2658        }
2659    }
2660}
2661
2662impl Deref for UnicastOrMulticastIpv6Addr {
2663    type Target = Ipv6Addr;
2664
2665    fn deref(&self) -> &Ipv6Addr {
2666        self.as_ref()
2667    }
2668}
2669
2670impl Display for UnicastOrMulticastIpv6Addr {
2671    #[inline]
2672    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2673        match self {
2674            UnicastOrMulticastIpv6Addr::Unicast(addr) => write!(f, "{}", addr),
2675            UnicastOrMulticastIpv6Addr::Multicast(addr) => write!(f, "{}", addr),
2676        }
2677    }
2678}
2679
2680impl Debug for UnicastOrMulticastIpv6Addr {
2681    #[inline]
2682    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2683        Display::fmt(self, f)
2684    }
2685}
2686
2687/// The error returned from [`Subnet::new`] and [`SubnetEither::new`].
2688#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2689pub enum SubnetError {
2690    /// The network prefix is longer than the number of bits in the address (32
2691    /// for IPv4/128 for IPv6).
2692    PrefixTooLong,
2693    /// The network address has some bits in the host part (past the network
2694    /// prefix) set to one.
2695    HostBitsSet,
2696}
2697
2698/// A prefix was provided which is longer than the number of bits in the address
2699/// (32 for IPv4/128 for IPv6).
2700#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2701pub struct PrefixTooLongError;
2702
2703/// An IP subnet.
2704///
2705/// `Subnet` is a combination of an IP network address and a prefix length.
2706#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2707pub struct Subnet<A> {
2708    // invariant: only contains prefix bits
2709    network: A,
2710    prefix: u8,
2711}
2712
2713impl<A: core::cmp::Ord> core::cmp::PartialOrd for Subnet<A> {
2714    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
2715        Some(self.cmp(other))
2716    }
2717}
2718
2719/// Subnet ordering always orders from least-specific to most-specific subnet.
2720impl<A: core::cmp::Ord> core::cmp::Ord for Subnet<A> {
2721    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
2722        let Self { network, prefix } = self;
2723        let Self { network: other_network, prefix: other_prefix } = other;
2724        match prefix.cmp(other_prefix) {
2725            core::cmp::Ordering::Equal => network.cmp(other_network),
2726            ord => ord,
2727        }
2728    }
2729}
2730
2731impl<A> Subnet<A> {
2732    /// Creates a new subnet without enforcing correctness.
2733    ///
2734    /// # Safety
2735    ///
2736    /// Unlike `new`, `new_unchecked` does not validate that `prefix` is in the
2737    /// proper range, and does not check that `network` has only the top
2738    /// `prefix` bits set. It is up to the caller to guarantee that `prefix` is
2739    /// in the proper range, and that none of the bits of `network` beyond the
2740    /// prefix are set.
2741    #[inline]
2742    pub const unsafe fn new_unchecked(network: A, prefix: u8) -> Subnet<A> {
2743        Subnet { network, prefix }
2744    }
2745}
2746
2747impl<A: IpAddress> Subnet<A> {
2748    /// Creates a new subnet.
2749    ///
2750    /// `new` creates a new subnet with the given network address and prefix
2751    /// length. It returns `Err` if `prefix` is longer than the number of bits
2752    /// in this type of IP address (32 for IPv4 and 128 for IPv6) or if any of
2753    /// the host bits (beyond the first `prefix` bits) are set in `network`.
2754    #[inline]
2755    pub fn new(network: A, prefix: u8) -> Result<Subnet<A>, SubnetError> {
2756        if prefix > A::BYTES * 8 {
2757            return Err(SubnetError::PrefixTooLong);
2758        }
2759        // TODO(joshlf): Is there a more efficient way we can perform this
2760        // check?
2761        if network != network.mask(prefix) {
2762            return Err(SubnetError::HostBitsSet);
2763        }
2764        Ok(Subnet { network, prefix })
2765    }
2766
2767    /// Creates a new subnet from the address of a host in that subnet.
2768    ///
2769    /// Unlike [`new`], the `host` address may have host bits set.
2770    ///
2771    /// [`new`]: Subnet::new
2772    #[inline]
2773    pub fn from_host(host: A, prefix: u8) -> Result<Subnet<A>, PrefixTooLongError> {
2774        if prefix > A::BYTES * 8 {
2775            return Err(PrefixTooLongError);
2776        }
2777        let network = host.mask(prefix);
2778        Ok(Subnet { network, prefix })
2779    }
2780
2781    /// Gets the network address component of this subnet.
2782    ///
2783    /// Any bits beyond the prefix will be zero.
2784    #[inline]
2785    pub fn network(&self) -> A {
2786        self.network
2787    }
2788
2789    /// Gets the prefix length component of this subnet.
2790    #[inline]
2791    pub fn prefix(&self) -> u8 {
2792        self.prefix
2793    }
2794
2795    /// Tests whether an address is in this subnet.
2796    ///
2797    /// Tests whether `addr` is in this subnet by testing whether the prefix
2798    /// bits match the prefix bits of the subnet's network address. This is
2799    /// equivalent to `sub.network() == addr.mask(sub.prefix())`.
2800    #[inline]
2801    pub fn contains(&self, addr: &A) -> bool {
2802        self.network == addr.mask(self.prefix)
2803    }
2804}
2805
2806impl Subnet<Ipv4Addr> {
2807    // TODO(joshlf): If we introduce a separate type for an address in a subnet
2808    // (with fewer requirements than `AddrSubnet` has now so that a broadcast
2809    // address is representable), then that type could implement
2810    // `BroadcastAddress`, and `broadcast` could return
2811    // `BroadcastAddr<Foo<Ipv4Addr>>`.
2812
2813    /// Gets the broadcast address in this IPv4 subnet.
2814    #[inline]
2815    pub fn broadcast(self) -> Ipv4Addr {
2816        if self.prefix == 32 {
2817            // shifting right by the size of the value is undefined
2818            self.network
2819        } else {
2820            let mask = <u32>::max_value() >> self.prefix;
2821            Ipv4Addr::new((u32::from_be_bytes(self.network.0) | mask).to_be_bytes())
2822        }
2823    }
2824}
2825
2826impl<A: IpAddress> Display for Subnet<A> {
2827    #[inline]
2828    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2829        write!(f, "{}/{}", self.network, self.prefix)
2830    }
2831}
2832
2833impl<A: IpAddress> Debug for Subnet<A> {
2834    #[inline]
2835    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
2836        write!(f, "{}/{}", self.network, self.prefix)
2837    }
2838}
2839
2840impl<A, I: Ip> GenericOverIp<I> for Subnet<A> {
2841    type Type = Subnet<I::Addr>;
2842}
2843
2844/// An IPv4 subnet or an IPv6 subnet.
2845///
2846/// `SubnetEither` is an enum of [`Subnet<Ipv4Addr>`] and `Subnet<Ipv6Addr>`.
2847///
2848/// [`Subnet<Ipv4Addr>`]: Subnet
2849#[allow(missing_docs)]
2850#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
2851pub enum SubnetEither {
2852    V4(Subnet<Ipv4Addr>),
2853    V6(Subnet<Ipv6Addr>),
2854}
2855
2856impl SubnetEither {
2857    /// Creates a new subnet.
2858    ///
2859    /// `new` creates a new subnet with the given network address and prefix
2860    /// length. It returns `Err` if `prefix` is longer than the number of bits
2861    /// in this type of IP address (32 for IPv4 and 128 for IPv6) or if any of
2862    /// the host bits (beyond the first `prefix` bits) are set in `network`.
2863    #[inline]
2864    pub fn new(network: IpAddr, prefix: u8) -> Result<SubnetEither, SubnetError> {
2865        Ok(match network {
2866            IpAddr::V4(network) => SubnetEither::V4(Subnet::new(network, prefix)?),
2867            IpAddr::V6(network) => SubnetEither::V6(Subnet::new(network, prefix)?),
2868        })
2869    }
2870
2871    /// Creates a new subnet from the address of a host in that subnet.
2872    ///
2873    /// Unlike [`new`], the `host` address may have host bits set.
2874    ///
2875    /// [`new`]: SubnetEither::new
2876    #[inline]
2877    pub fn from_host(host: IpAddr, prefix: u8) -> Result<SubnetEither, PrefixTooLongError> {
2878        Ok(match host {
2879            IpAddr::V4(host) => SubnetEither::V4(Subnet::from_host(host, prefix)?),
2880            IpAddr::V6(host) => SubnetEither::V6(Subnet::from_host(host, prefix)?),
2881        })
2882    }
2883
2884    /// Gets the network and prefix.
2885    #[inline]
2886    pub fn net_prefix(&self) -> (IpAddr, u8) {
2887        match self {
2888            SubnetEither::V4(v4) => (v4.network.into(), v4.prefix),
2889            SubnetEither::V6(v6) => (v6.network.into(), v6.prefix),
2890        }
2891    }
2892}
2893
2894impl<A: IpAddress> From<Subnet<A>> for SubnetEither {
2895    fn from(subnet: Subnet<A>) -> SubnetEither {
2896        A::subnet_into_either(subnet)
2897    }
2898}
2899
2900/// The error returned from [`AddrSubnet::new`] and [`AddrSubnetEither::new`].
2901#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2902pub enum AddrSubnetError {
2903    /// The network prefix is longer than the number of bits in the address (32
2904    /// for IPv4/128 for IPv6).
2905    PrefixTooLong,
2906    /// The address is not a unicast address in the given subnet (see
2907    /// [`IpAddress::is_unicast_in_subnet`]).
2908    NotUnicastInSubnet,
2909    /// The address does not satisfy the requirements of the witness type.
2910    InvalidWitness,
2911}
2912
2913// TODO(joshlf): Is the unicast restriction always necessary, or will some users
2914// want the AddrSubnet functionality without that restriction?
2915
2916/// An address and that address's subnet.
2917///
2918/// An `AddrSubnet` is a pair of an address and a subnet which maintains the
2919/// invariant that the address is guaranteed to be a unicast address in the
2920/// subnet. `S` is the type of address ([`Ipv4Addr`] or [`Ipv6Addr`]), and `A`
2921/// is the type of the address in the subnet, which is always a witness wrapper
2922/// around `S`. By default, it is `SpecifiedAddr<S>`.
2923#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
2924pub struct AddrSubnet<S: IpAddress, A: Witness<S> + Copy = SpecifiedAddr<S>> {
2925    // TODO(joshlf): Would it be more performant to store these as just an
2926    // address and subnet mask? It would make the object smaller and so cheaper
2927    // to pass around, but it would make certain operations more expensive.
2928    addr: A,
2929    subnet: Subnet<S>,
2930}
2931
2932impl<S: IpAddress, A: Witness<S> + Copy> AddrSubnet<S, A> {
2933    /// Creates a new `AddrSubnet`.
2934    ///
2935    /// `new` is like [`from_witness`], except that it also converts `addr` into
2936    /// the appropriate witness type, returning
2937    /// [`AddrSubnetError::InvalidWitness`] if the conversion fails.
2938    ///
2939    /// [`from_witness`]: Witness::from_witness
2940    #[inline]
2941    pub fn new(addr: S, prefix: u8) -> Result<AddrSubnet<S, A>, AddrSubnetError> {
2942        AddrSubnet::from_witness(A::new(addr).ok_or(AddrSubnetError::InvalidWitness)?, prefix)
2943    }
2944
2945    /// Creates a new `AddrSubnet` without checking for validity.
2946    ///
2947    /// # Safety
2948    ///
2949    /// Unlike [`new`], `new_unchecked` does not validate that `prefix` is in the
2950    /// proper range, and does not check that `addr` is a valid value for the
2951    /// witness type `A`. It is up to the caller to guarantee that `prefix` is
2952    /// in the proper range, and `A::new(addr)` is not `None`.
2953    ///
2954    /// [`new`]: AddrSubnet::new
2955    #[inline]
2956    pub unsafe fn new_unchecked(addr: S, prefix: u8) -> Self {
2957        let (subnet, addr) =
2958            unsafe { (Subnet::new_unchecked(addr.mask(prefix), prefix), A::new_unchecked(addr)) };
2959        AddrSubnet { addr, subnet }
2960    }
2961
2962    /// Creates a new `AddrSubnet` from an existing witness.
2963    ///
2964    /// `from_witness` creates a new `AddrSubnet` with the given address and
2965    /// prefix length. The network address of the subnet is taken to be the
2966    /// first `prefix` bits of the address. It returns `Err` if `prefix` is
2967    /// longer than the number of bits in this type of IP address (32 for IPv4
2968    /// and 128 for IPv6) or if `addr` is not a unicast address in the resulting
2969    /// subnet (see [`IpAddress::is_unicast_in_subnet`]).
2970    pub fn from_witness(addr: A, prefix: u8) -> Result<AddrSubnet<S, A>, AddrSubnetError> {
2971        if prefix > S::BYTES * 8 {
2972            return Err(AddrSubnetError::PrefixTooLong);
2973        }
2974        let subnet = Subnet { network: addr.as_ref().mask(prefix), prefix };
2975        if !addr.as_ref().is_unicast_in_subnet(&subnet) {
2976            return Err(AddrSubnetError::NotUnicastInSubnet);
2977        }
2978        Ok(AddrSubnet { addr, subnet })
2979    }
2980
2981    /// Gets the subnet.
2982    #[inline]
2983    pub fn subnet(&self) -> Subnet<S> {
2984        self.subnet
2985    }
2986
2987    /// Gets the address.
2988    #[inline]
2989    pub fn addr(&self) -> A {
2990        self.addr
2991    }
2992
2993    /// Gets the address and subnet.
2994    #[inline]
2995    pub fn addr_subnet(self) -> (A, Subnet<S>) {
2996        (self.addr, self.subnet)
2997    }
2998
2999    /// Constructs a new `AddrSubnet` of a different witness type.
3000    #[inline]
3001    pub fn to_witness<B: Witness<S> + Copy>(&self) -> AddrSubnet<S, B>
3002    where
3003        A: Into<B>,
3004    {
3005        AddrSubnet { addr: self.addr.into(), subnet: self.subnet }
3006    }
3007
3008    /// Wraps an additional witness onto this [`AddrSubnet`].
3009    #[inline]
3010    pub fn add_witness<B: Witness<A> + Witness<S> + Copy>(&self) -> Option<AddrSubnet<S, B>> {
3011        let addr = B::new(self.addr)?;
3012        Some(AddrSubnet { addr, subnet: self.subnet })
3013    }
3014
3015    /// Replaces the [`AddrSubnet`] witness.
3016    #[inline]
3017    pub fn replace_witness<B: Witness<S> + Copy>(&self) -> Option<AddrSubnet<S, B>> {
3018        let addr = B::new(self.addr.get())?;
3019        Some(AddrSubnet { addr, subnet: self.subnet })
3020    }
3021}
3022
3023impl<S: IpAddress, A: Witness<S> + Copy + Display> Display for AddrSubnet<S, A> {
3024    #[inline]
3025    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
3026        write!(f, "{}/{}", self.addr, self.subnet.prefix)
3027    }
3028}
3029
3030impl<A: Witness<Ipv6Addr> + Copy> AddrSubnet<Ipv6Addr, A> {
3031    /// Gets the address as a [`UnicastAddr`] witness.
3032    ///
3033    /// Since one of the invariants on an `AddrSubnet` is that its contained
3034    /// address is unicast in its subnet, `ipv6_unicast_addr` can infallibly
3035    /// convert its stored address to a `UnicastAddr`.
3036    pub fn ipv6_unicast_addr(&self) -> UnicastAddr<Ipv6Addr> {
3037        unsafe { UnicastAddr::new_unchecked(self.addr.get()) }
3038    }
3039
3040    /// Constructs a new `AddrSubnet` which stores a [`UnicastAddr`] witness.
3041    ///
3042    /// Since one of the invariants on an `AddrSubnet` is that its contained
3043    /// address is unicast in its subnet, `to_unicast` can infallibly convert
3044    /// its stored address to a `UnicastAddr`.
3045    pub fn to_unicast(&self) -> AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>> {
3046        let AddrSubnet { addr, subnet } = *self;
3047        let addr = unsafe { UnicastAddr::new_unchecked(addr.get()) };
3048        AddrSubnet { addr, subnet }
3049    }
3050}
3051
3052/// An IP prefix length.
3053#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, GenericOverIp)]
3054#[generic_over_ip(I, Ip)]
3055pub struct PrefixLength<I: Ip> {
3056    /// `inner` is guaranteed to be a valid prefix length for `I::Addr`.
3057    inner: u8,
3058    _ip: IpVersionMarker<I>,
3059}
3060
3061impl<I: Ip> PrefixLength<I> {
3062    /// Returns the prefix length.
3063    ///
3064    /// The returned length is guaranteed to be a valid prefix length for
3065    /// `I::Addr`.
3066    pub const fn get(self) -> u8 {
3067        let Self { inner, _ip } = self;
3068        inner
3069    }
3070
3071    /// Gets the subnet-mask representation of this prefix length.
3072    pub fn get_mask(self) -> I::Addr {
3073        I::map_ip(
3074            self,
3075            |prefix_len| Ipv4::LIMITED_BROADCAST_ADDRESS.mask(prefix_len.get()),
3076            |prefix_len| Ipv6Addr([u8::MAX; 16]).mask(prefix_len.get()),
3077        )
3078    }
3079
3080    /// Constructs a `PrefixLength` from a given prefix length without checking
3081    /// whether it is too long for the address type.
3082    ///
3083    /// # Safety
3084    /// `prefix_length` must be less than or equal to the number of bits in
3085    /// `I::Addr`. In other words, `prefix_length <= I::Addr::BYTES * 8`.
3086    pub const unsafe fn new_unchecked(prefix_length: u8) -> Self {
3087        Self { inner: prefix_length, _ip: I::VERSION_MARKER }
3088    }
3089
3090    /// Constructs a `PrefixLength` from a given unverified prefix length.
3091    ///
3092    /// Returns `Err(PrefixTooLongError)` if `prefix_length` is too long for the
3093    /// address type.
3094    pub const fn new(prefix_length: u8) -> Result<Self, PrefixTooLongError> {
3095        if prefix_length > I::Addr::BYTES * 8 {
3096            return Err(PrefixTooLongError);
3097        }
3098        Ok(Self { inner: prefix_length, _ip: I::VERSION_MARKER })
3099    }
3100
3101    /// Constructs a `PrefixLength` from an IP address representing a subnet mask.
3102    ///
3103    /// Returns `Err(NotSubnetMaskError)` if `subnet_mask` is not a valid subnet
3104    /// mask.
3105    pub fn try_from_subnet_mask(subnet_mask: I::Addr) -> Result<Self, NotSubnetMaskError> {
3106        let IpInvariant((count_ones, leading_ones)) = I::map_ip(
3107            subnet_mask,
3108            |subnet_mask| {
3109                let number = u32::from_be_bytes(subnet_mask.ipv4_bytes());
3110                IpInvariant((number.count_ones(), number.leading_ones()))
3111            },
3112            |subnet_mask| {
3113                let number = u128::from_be_bytes(subnet_mask.ipv6_bytes());
3114                IpInvariant((number.count_ones(), number.leading_ones()))
3115            },
3116        );
3117
3118        if leading_ones != count_ones {
3119            return Err(NotSubnetMaskError);
3120        }
3121
3122        Ok(Self {
3123            inner: u8::try_from(leading_ones)
3124                .expect("the number of bits in an IP address fits in u8"),
3125            _ip: IpVersionMarker::default(),
3126        })
3127    }
3128}
3129
3130impl<I: Ip> From<PrefixLength<I>> for u8 {
3131    fn from(value: PrefixLength<I>) -> Self {
3132        value.get()
3133    }
3134}
3135
3136/// An IP address was provided which is not a valid subnet mask (the address
3137/// has set bits after the first unset bit).
3138#[derive(Copy, Clone, Debug, Eq, PartialEq)]
3139pub struct NotSubnetMaskError;
3140
3141/// A type which is witness to some property about an [`IpAddress`], `A`.
3142///
3143/// `IpAddressWitness<A>` extends [`Witness`] of the `IpAddress` type `A` by
3144/// adding an associated type for the type-erased `IpAddr` version of the same
3145/// witness type. For example, the following implementation is provided for
3146/// `SpecifiedAddr<A>`:
3147///
3148/// ```rust,ignore
3149/// impl<A: IpAddress> IpAddressWitness<A> for SpecifiedAddr<A> {
3150///     type IpAddrWitness = SpecifiedAddr<IpAddr>;
3151/// }
3152/// ```
3153pub trait IpAddressWitness<A: IpAddress>: Witness<A> {
3154    /// The type-erased version of `Self`.
3155    ///
3156    /// For example, `SpecifiedAddr<Ipv4Addr>: IpAddressWitness<IpAddrWitness =
3157    /// SpecifiedAddr<IpAddr>>`.
3158    type IpAddrWitness: IpAddrWitness + From<Self>;
3159}
3160
3161macro_rules! impl_ip_address_witness {
3162    ($witness:ident) => {
3163        impl<A: IpAddress> IpAddressWitness<A> for $witness<A> {
3164            type IpAddrWitness = $witness<IpAddr>;
3165        }
3166    };
3167}
3168
3169impl_ip_address_witness!(SpecifiedAddr);
3170impl_ip_address_witness!(MulticastAddr);
3171impl_ip_address_witness!(LinkLocalAddr);
3172
3173/// A type which is a witness to some property about an [`IpAddress`].
3174///
3175/// `IpAddrWitness` extends [`Witness`] of [`IpAddr`] by adding associated types
3176/// for the IPv4- and IPv6-specific versions of the same witness type. For
3177/// example, the following implementation is provided for
3178/// `SpecifiedAddr<IpAddr>`:
3179///
3180/// ```rust,ignore
3181/// impl IpAddrWitness for SpecifiedAddr<IpAddr> {
3182///     type V4 = SpecifiedAddr<Ipv4Addr>;
3183///     type V6 = SpecifiedAddr<Ipv6Addr>;
3184/// }
3185/// ```
3186pub trait IpAddrWitness: Witness<IpAddr> + Into<IpAddr<Self::V4, Self::V6>> + Copy {
3187    /// The IPv4-specific version of `Self`.
3188    ///
3189    /// For example, `SpecifiedAddr<IpAddr>: IpAddrWitness<V4 =
3190    /// SpecifiedAddr<Ipv4Addr>>`.
3191    type V4: Witness<Ipv4Addr> + Into<Self> + Copy;
3192
3193    /// The IPv6-specific version of `Self`.
3194    ///
3195    /// For example, `SpecifiedAddr<IpAddr>: IpAddrWitness<V6 =
3196    /// SpecifiedAddr<Ipv6Addr>>`.
3197    type V6: Witness<Ipv6Addr> + Into<Self> + Copy;
3198
3199    // TODO(https://github.com/rust-lang/rust/issues/44491): Remove these
3200    // functions once implied where bounds make them unnecessary.
3201
3202    /// Converts an IPv4-specific witness into a general witness.
3203    fn from_v4(addr: Self::V4) -> Self {
3204        addr.into()
3205    }
3206
3207    /// Converts an IPv6-specific witness into a general witness.
3208    fn from_v6(addr: Self::V6) -> Self {
3209        addr.into()
3210    }
3211}
3212
3213macro_rules! impl_ip_addr_witness {
3214    ($witness:ident) => {
3215        impl IpAddrWitness for $witness<IpAddr> {
3216            type V4 = $witness<Ipv4Addr>;
3217            type V6 = $witness<Ipv6Addr>;
3218        }
3219    };
3220}
3221
3222impl_ip_addr_witness!(SpecifiedAddr);
3223impl_ip_addr_witness!(MulticastAddr);
3224impl_ip_addr_witness!(LinkLocalAddr);
3225
3226/// An address and that address's subnet, either IPv4 or IPv6.
3227///
3228/// `AddrSubnetEither` is an enum of [`AddrSubnet<Ipv4Addr>`] and
3229/// `AddrSubnet<Ipv6Addr>`.
3230///
3231/// [`AddrSubnet<Ipv4Addr>`]: AddrSubnet
3232#[allow(missing_docs)]
3233#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
3234pub enum AddrSubnetEither<A: IpAddrWitness = SpecifiedAddr<IpAddr>> {
3235    V4(AddrSubnet<Ipv4Addr, A::V4>),
3236    V6(AddrSubnet<Ipv6Addr, A::V6>),
3237}
3238
3239impl<A: IpAddrWitness> AddrSubnetEither<A> {
3240    /// Creates a new `AddrSubnetEither`.
3241    ///
3242    /// `new` creates a new `AddrSubnetEither` with the given address and prefix
3243    /// length. It returns `Err` under the same conditions as
3244    /// [`AddrSubnet::new`].
3245    #[inline]
3246    pub fn new(addr: IpAddr, prefix: u8) -> Result<AddrSubnetEither<A>, AddrSubnetError> {
3247        Ok(match addr {
3248            IpAddr::V4(addr) => AddrSubnetEither::V4(AddrSubnet::new(addr, prefix)?),
3249            IpAddr::V6(addr) => AddrSubnetEither::V6(AddrSubnet::new(addr, prefix)?),
3250        })
3251    }
3252
3253    /// Creates a new `AddrSubnetEither` from trusted inputs.
3254    ///
3255    /// # Safety
3256    ///
3257    /// Unlike [`new`], this assumes that the provided address satisfies the
3258    /// requirements of the witness type `A`, and that `prefix` is not too large
3259    /// for the IP version of the address in `addr`.
3260    ///
3261    /// [`new`]: AddrSubnetEither::new
3262    #[inline]
3263    pub unsafe fn new_unchecked(addr: IpAddr, prefix: u8) -> Self {
3264        match addr {
3265            IpAddr::V4(addr) => {
3266                AddrSubnetEither::V4(unsafe { AddrSubnet::new_unchecked(addr, prefix) })
3267            }
3268            IpAddr::V6(addr) => {
3269                AddrSubnetEither::V6(unsafe { AddrSubnet::new_unchecked(addr, prefix) })
3270            }
3271        }
3272    }
3273
3274    /// Gets the IP address.
3275    pub fn addr(&self) -> A {
3276        match self {
3277            AddrSubnetEither::V4(v4) => v4.addr.into(),
3278            AddrSubnetEither::V6(v6) => v6.addr.into(),
3279        }
3280    }
3281
3282    /// Gets the IP address and prefix.
3283    #[inline]
3284    pub fn addr_prefix(&self) -> (A, u8) {
3285        match self {
3286            AddrSubnetEither::V4(v4) => (v4.addr.into(), v4.subnet.prefix),
3287            AddrSubnetEither::V6(v6) => (v6.addr.into(), v6.subnet.prefix),
3288        }
3289    }
3290
3291    /// Gets the IP address and subnet.
3292    #[inline]
3293    pub fn addr_subnet(&self) -> (A, SubnetEither) {
3294        match self {
3295            AddrSubnetEither::V4(v4) => (v4.addr.into(), SubnetEither::V4(v4.subnet)),
3296            AddrSubnetEither::V6(v6) => (v6.addr.into(), SubnetEither::V6(v6.subnet)),
3297        }
3298    }
3299}
3300
3301impl<S: IpAddress, A: IpAddressWitness<S> + Copy> From<AddrSubnet<S, A>>
3302    for AddrSubnetEither<A::IpAddrWitness>
3303{
3304    #[inline]
3305    fn from(addr_sub: AddrSubnet<S, A>) -> AddrSubnetEither<A::IpAddrWitness> {
3306        let (addr, sub) = addr_sub.addr_subnet();
3307        // This unwrap is safe because:
3308        // - `addr_sub: AddrSubnet<S, A>`, so we know that `addr` and
3309        //   `sub.prefix` are valid arguments to `AddrSubnet::new` (which is
3310        //   what `AddrSubnetEither::new` calls under the hood).
3311        // - `A::IpAddrWitness` is the same witness type as `A`, but wrapping
3312        //   `IpAddr` instead of `Ipv4Addr` or `Ipv6Addr`. `addr: A` means that
3313        //   `addr` satisfies the property witnessed by the witness type `A`,
3314        //   which is the same property witnessed by `A::IpAddrWitness`. Thus,
3315        //   we're guaranteed that, when `AddrSubnetEither::new` tries to
3316        //   construct the witness, it will succeed.
3317        AddrSubnetEither::new(addr.get().to_ip_addr(), sub.prefix()).unwrap()
3318    }
3319}
3320
3321impl<A> Display for AddrSubnetEither<A>
3322where
3323    A: IpAddrWitness,
3324    A::V4: Display,
3325    A::V6: Display,
3326{
3327    #[inline]
3328    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
3329        match self {
3330            Self::V4(a) => write!(f, "{}", a),
3331            Self::V6(a) => write!(f, "{}", a),
3332        }
3333    }
3334}
3335
3336/// Marks types that are generic over IP version.
3337///
3338/// This should be implemented by types that contain a generic parameter
3339/// [`I: Ip`](Ip) or [`A: IpAddress`](IpAddress) to allow them to be used with
3340/// [`Ip::map_ip`].
3341///
3342/// Implementations of this trait should generally be themselves generic over
3343/// `Ip`. For example:
3344/// ```
3345/// struct AddrAndSubnet<I: Ip> {
3346///   addr: I::Addr,
3347///   subnet: Subnet<I::Addr>
3348/// }
3349///
3350/// impl <I: Ip, NewIp: Ip> GenericOverIp<NewIp> for AddrAndSubnet<I> {
3351///   type Type = AddrAndSubnet<NewIp>;
3352/// }
3353/// ```
3354pub trait GenericOverIp<NewIp: Ip> {
3355    /// The type of `Self` when its IP-generic parameter is replaced with the
3356    /// type `NewIp`.
3357    type Type;
3358}
3359
3360/// Wrapper type that implements [`GenericOverIp`] with `Type<I: Ip>=Self`.
3361///
3362/// This can be used to make a compound type implement `GenericOverIp` with
3363/// some portion that is invariant over IP version.
3364pub struct IpInvariant<T>(pub T);
3365
3366impl<T> IpInvariant<T> {
3367    /// Consumes the `IpInvariant` and returns the wrapped value.
3368    pub fn into_inner(self) -> T {
3369        self.0
3370    }
3371}
3372
3373impl<I: Ip, T> GenericOverIp<I> for IpInvariant<T> {
3374    type Type = Self;
3375}
3376
3377impl<I: Ip> GenericOverIp<I> for core::convert::Infallible {
3378    type Type = Self;
3379}
3380
3381/// A wrapper structure to add an IP version marker to an IP-invariant type.
3382#[derive(GenericOverIp, Default, Debug, PartialOrd, Ord, Eq, PartialEq, Hash)]
3383#[generic_over_ip(I, Ip)]
3384pub struct IpMarked<I: Ip, T> {
3385    inner: T,
3386    _marker: IpVersionMarker<I>,
3387}
3388
3389impl<I: Ip, T> Deref for IpMarked<I, T> {
3390    type Target = T;
3391
3392    fn deref(&self) -> &Self::Target {
3393        self.as_ref()
3394    }
3395}
3396
3397impl<I: Ip, T> DerefMut for IpMarked<I, T> {
3398    fn deref_mut(&mut self) -> &mut Self::Target {
3399        self.as_mut()
3400    }
3401}
3402impl<I: Ip, T> AsRef<T> for IpMarked<I, T> {
3403    fn as_ref(&self) -> &T {
3404        &self.inner
3405    }
3406}
3407
3408impl<I: Ip, T> AsMut<T> for IpMarked<I, T> {
3409    fn as_mut(&mut self) -> &mut T {
3410        &mut self.inner
3411    }
3412}
3413
3414impl<I: Ip, T> IpMarked<I, T> {
3415    /// Constructs a new `IpMarked` from the provided `T`.
3416    pub fn new(inner: T) -> Self {
3417        Self { inner, _marker: IpVersionMarker::<I>::new() }
3418    }
3419
3420    /// Consumes the `IpMarked` and returns the contained `T` by value.
3421    pub fn into_inner(self) -> T {
3422        let Self { inner, _marker } = self;
3423        inner
3424    }
3425
3426    /// Gets an immutable reference to the underlying `T`.
3427    pub fn get(&self) -> &T {
3428        self.as_ref()
3429    }
3430
3431    /// Gets an mutable reference to the underlying `T`.
3432    pub fn get_mut(&mut self) -> &mut T {
3433        self.as_mut()
3434    }
3435}
3436
3437/// Calls the provided macro with all suffixes of the input.
3438macro_rules! for_each_tuple_ {
3439        ( $m:ident !! ) => ( $m! { });
3440        ( $m:ident !! $h:ident, $($t:ident,)* ) => (
3441            $m! { $h $($t)* }
3442            for_each_tuple_! { $m !! $($t,)* }
3443        );
3444    }
3445
3446/// Calls the provided macro with 0-12 type parameters.
3447macro_rules! for_each_tuple {
3448    ($m:ident) => {
3449        for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, }
3450    };
3451}
3452
3453/// Implements GenericOverIp for a tuple with the provided generic parameters.
3454macro_rules! ip_generic_tuple {
3455        () => {
3456            impl<I: Ip> GenericOverIp<I> for () {
3457                type Type = Self;
3458            }
3459        };
3460        ( $name0:ident $($name:ident)* ) => (
3461            impl<P: Ip, $name0: GenericOverIp<P>, $($name: GenericOverIp<P>,)*>
3462            GenericOverIp<P> for ($name0, $($name,)*) {
3463                type Type = ($name0::Type, $($name::Type,)*);
3464            }
3465        );
3466    }
3467
3468for_each_tuple!(ip_generic_tuple);
3469
3470macro_rules! ip_generic {
3471    ( $type:ident < $($params:ident),* >) => {
3472        impl<IpType: Ip, $($params: GenericOverIp<IpType>),*>
3473        GenericOverIp<IpType> for $type<$($params),*> {
3474            type Type = $type<$($params::Type),*>;
3475        }
3476    };
3477    ( $type:ident) => {
3478        impl<IpType: Ip> GenericOverIp<IpType> for $type {
3479            type Type = Self;
3480        }
3481    }
3482}
3483
3484// Implement GenericOverIp for common types.
3485ip_generic!(bool);
3486ip_generic!(isize);
3487ip_generic!(i8);
3488ip_generic!(i16);
3489ip_generic!(i32);
3490ip_generic!(i64);
3491ip_generic!(usize);
3492ip_generic!(u8);
3493ip_generic!(u16);
3494ip_generic!(u32);
3495ip_generic!(u64);
3496ip_generic!(Option<T>);
3497ip_generic!(Result<R, E>);
3498#[cfg(feature = "std")]
3499ip_generic!(Vec<T>);
3500#[cfg(feature = "std")]
3501ip_generic!(Arc<T>);
3502
3503impl<'s, NewIp: Ip, T: GenericOverIp<NewIp>> GenericOverIp<NewIp> for &'s T
3504where
3505    T::Type: 's,
3506{
3507    type Type = &'s T::Type;
3508}
3509
3510impl<'s, NewIp: Ip, T: GenericOverIp<NewIp>> GenericOverIp<NewIp> for &'s mut T
3511where
3512    T::Type: 's,
3513{
3514    type Type = &'s mut T::Type;
3515}
3516
3517#[cfg(test)]
3518mod tests {
3519    use super::*;
3520    use test_case::test_case;
3521
3522    #[test]
3523    fn test_map_ip_associated_constant() {
3524        fn get_loopback_address<I: Ip>() -> SpecifiedAddr<I::Addr> {
3525            I::map_ip((), |()| Ipv4::LOOPBACK_ADDRESS, |()| Ipv6::LOOPBACK_ADDRESS)
3526        }
3527
3528        assert_eq!(get_loopback_address::<Ipv4>(), Ipv4::LOOPBACK_ADDRESS);
3529        assert_eq!(get_loopback_address::<Ipv6>(), Ipv6::LOOPBACK_ADDRESS);
3530    }
3531
3532    #[test]
3533    fn test_map_ip_different_behavior() {
3534        fn filter_v4<I: Ip>(addr: I::Addr) -> Option<I::Addr> {
3535            I::map_ip(addr, |addr| Some(addr), |_addr| None)
3536        }
3537
3538        assert_eq!(filter_v4::<Ipv4>(*Ipv4::LOOPBACK_ADDRESS), Some(*Ipv4::LOOPBACK_ADDRESS));
3539        assert_eq!(filter_v4::<Ipv6>(*Ipv6::LOOPBACK_ADDRESS), None);
3540    }
3541
3542    #[test]
3543    fn test_map_ip_extension_trait_fn() {
3544        trait FakeIpExt: Ip {
3545            fn reverse_addr_bytes(a: Self::Addr) -> Self::Addr;
3546        }
3547
3548        impl FakeIpExt for Ipv4 {
3549            fn reverse_addr_bytes(a: Self::Addr) -> Self::Addr {
3550                let Ipv4Addr(mut bytes) = a;
3551                bytes.reverse();
3552                Ipv4Addr(bytes)
3553            }
3554        }
3555        impl FakeIpExt for Ipv6 {
3556            fn reverse_addr_bytes(a: Self::Addr) -> Self::Addr {
3557                let Ipv6Addr(mut bytes) = a;
3558                bytes.reverse();
3559                Ipv6Addr(bytes)
3560            }
3561        }
3562
3563        fn reverse_bytes<A: IpAddress>(addr: A) -> A
3564        where
3565            A::Version: FakeIpExt,
3566        {
3567            A::Version::map_ip(addr, Ipv4::reverse_addr_bytes, Ipv6::reverse_addr_bytes)
3568        }
3569
3570        assert_eq!(reverse_bytes(Ipv4Addr([1, 2, 3, 4])), Ipv4Addr([4, 3, 2, 1]));
3571        assert_eq!(
3572            reverse_bytes(Ipv6Addr([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])),
3573            Ipv6Addr([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
3574        );
3575    }
3576
3577    #[test]
3578    fn test_map_ip_extension_trait_associated_type() {
3579        trait FakeIpExt: Ip {
3580            type PackedInt;
3581        }
3582        impl FakeIpExt for Ipv4 {
3583            type PackedInt = u32;
3584        }
3585        impl FakeIpExt for Ipv6 {
3586            type PackedInt = u128;
3587        }
3588
3589        #[derive(Debug, PartialEq)]
3590        struct Int<T>(T);
3591
3592        impl<T, I: FakeIpExt> GenericOverIp<I> for Int<T> {
3593            type Type = Int<I::PackedInt>;
3594        }
3595
3596        fn from_be_bytes<A: IpAddress>(addr: A) -> Int<<A::Version as FakeIpExt>::PackedInt>
3597        where
3598            A::Version: FakeIpExt,
3599        {
3600            A::Version::map_ip(
3601                addr,
3602                |Ipv4Addr(bytes)| Int(<Ipv4 as FakeIpExt>::PackedInt::from_be_bytes(bytes)),
3603                |Ipv6Addr(bytes)| Int(<Ipv6 as FakeIpExt>::PackedInt::from_be_bytes(bytes)),
3604            )
3605        }
3606
3607        assert_eq!(from_be_bytes(Ipv4::LOOPBACK_ADDRESS.get()), Int(0x7f000001u32));
3608        assert_eq!(from_be_bytes(Ipv6::LOOPBACK_ADDRESS.get()), Int(1u128));
3609    }
3610
3611    #[test]
3612    fn map_ip_twice() {
3613        struct FooV4 {
3614            field: Ipv4Addr,
3615        }
3616
3617        impl Default for FooV4 {
3618            fn default() -> Self {
3619                Self { field: Ipv4::UNSPECIFIED_ADDRESS }
3620            }
3621        }
3622
3623        struct FooV6 {
3624            field: Ipv6Addr,
3625        }
3626
3627        impl Default for FooV6 {
3628            fn default() -> Self {
3629                Self { field: Ipv6::UNSPECIFIED_ADDRESS }
3630            }
3631        }
3632
3633        trait IpExt {
3634            type Foo: Default;
3635        }
3636
3637        impl IpExt for Ipv4 {
3638            type Foo = FooV4;
3639        }
3640
3641        impl IpExt for Ipv6 {
3642            type Foo = FooV6;
3643        }
3644
3645        #[derive(GenericOverIp)]
3646        #[generic_over_ip(I, Ip)]
3647        struct Foo<I: IpExt>(I::Foo);
3648
3649        fn do_something<I: Ip + IpExt>(
3650            foo: Foo<I>,
3651            extra_foo: Foo<I>,
3652            captured_foo: Foo<I>,
3653        ) -> I::Addr {
3654            let addr: I::Addr = map_ip_twice!(I, foo, |Foo(foo)| { foo.field });
3655
3656            // Observe that we can use an associated item with `map_ip_twice!
3657            // too.
3658            let _: I::Addr =
3659                map_ip_twice!(<<I as Ip>::Addr as IpAddress>::Version, extra_foo, |Foo(foo)| {
3660                    // Since `captured_foo` is captured rather than fed through the
3661                    // generic-over-ip input, this wouldn't work if `I` was aliased
3662                    // concretely to `Ipv4` or `Ipv6`.
3663                    let _: &Foo<I> = &captured_foo;
3664                    foo.field
3665                });
3666
3667            addr
3668        }
3669
3670        assert_eq!(
3671            do_something(
3672                Foo::<Ipv4>(FooV4 { field: Ipv4::UNSPECIFIED_ADDRESS }),
3673                Foo::<Ipv4>(FooV4 { field: Ipv4::UNSPECIFIED_ADDRESS }),
3674                Foo::<Ipv4>(FooV4 { field: Ipv4::UNSPECIFIED_ADDRESS })
3675            ),
3676            Ipv4::UNSPECIFIED_ADDRESS
3677        );
3678        assert_eq!(
3679            do_something(
3680                Foo::<Ipv6>(FooV6 { field: Ipv6::UNSPECIFIED_ADDRESS }),
3681                Foo::<Ipv6>(FooV6 { field: Ipv6::UNSPECIFIED_ADDRESS }),
3682                Foo::<Ipv6>(FooV6 { field: Ipv6::UNSPECIFIED_ADDRESS })
3683            ),
3684            Ipv6::UNSPECIFIED_ADDRESS
3685        );
3686
3687        fn do_something_with_default_type_alias_shadowing<I: Ip>() -> (I::Addr, IpVersion) {
3688            let (field, IpInvariant(version)) = map_ip_twice!(I, (), |()| {
3689                // Note that there's no `IpExt` bound on `I`, so `I` wouldn't
3690                // work here unless it was automatically aliased to `Ipv4` or `Ipv6`.
3691                let foo: Foo<I> = Foo(<I as IpExt>::Foo::default());
3692                (foo.0.field, IpInvariant(I::VERSION))
3693            },);
3694            (field, version)
3695        }
3696
3697        fn do_something_with_type_alias<I: Ip>() -> (I::Addr, IpVersion) {
3698            // Show that the type alias inside the macro shadows
3699            // whatever it was bound to outside the macro.
3700            #[allow(dead_code)]
3701            type IpAlias = usize;
3702
3703            let (field, IpInvariant(version)) = map_ip_twice!(I as IpAlias, (), |()| {
3704                // Note that there's no `IpExt` bound on `I`, so `I` wouldn't
3705                // work here -- only `IpAlias`, since `IpAlias` is explicitly
3706                // an alias of `Ipv4` or `Ipv6`.
3707                let foo: Foo<IpAlias> = Foo(<IpAlias as IpExt>::Foo::default());
3708                (foo.0.field, IpInvariant(IpAlias::VERSION))
3709            },);
3710            (field, version)
3711        }
3712
3713        assert_eq!(
3714            do_something_with_default_type_alias_shadowing::<Ipv4>(),
3715            (Ipv4::UNSPECIFIED_ADDRESS, IpVersion::V4)
3716        );
3717        assert_eq!(
3718            do_something_with_default_type_alias_shadowing::<Ipv6>(),
3719            (Ipv6::UNSPECIFIED_ADDRESS, IpVersion::V6)
3720        );
3721        assert_eq!(
3722            do_something_with_type_alias::<Ipv4>(),
3723            (Ipv4::UNSPECIFIED_ADDRESS, IpVersion::V4)
3724        );
3725        assert_eq!(
3726            do_something_with_type_alias::<Ipv6>(),
3727            (Ipv6::UNSPECIFIED_ADDRESS, IpVersion::V6)
3728        );
3729    }
3730
3731    #[test]
3732    fn test_loopback_unicast() {
3733        // The loopback addresses are constructed as `SpecifiedAddr`s directly,
3734        // bypassing the actual check against `is_specified`. Test that that's
3735        // actually valid.
3736        assert!(Ipv4::LOOPBACK_ADDRESS.0.is_specified());
3737        assert!(Ipv6::LOOPBACK_ADDRESS.0.is_specified());
3738    }
3739
3740    #[test]
3741    fn test_specified() {
3742        // For types that implement SpecifiedAddress,
3743        // UnicastAddress::is_unicast, MulticastAddress::is_multicast, and
3744        // LinkLocalAddress::is_link_local all imply
3745        // SpecifiedAddress::is_specified. Test that that's true for both IPv4
3746        // and IPv6.
3747
3748        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_specified());
3749        assert!(!Ipv4::UNSPECIFIED_ADDRESS.is_specified());
3750
3751        // Unicast
3752
3753        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_unicast());
3754
3755        let unicast = Ipv6Addr([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
3756        assert!(unicast.is_unicast());
3757        assert!(unicast.is_specified());
3758
3759        // Multicast
3760
3761        assert!(!Ipv4::UNSPECIFIED_ADDRESS.is_multicast());
3762        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_multicast());
3763
3764        let multicast = Ipv4::MULTICAST_SUBNET.network;
3765        assert!(multicast.is_multicast());
3766        assert!(multicast.is_specified());
3767        let multicast = Ipv6::MULTICAST_SUBNET.network;
3768        assert!(multicast.is_multicast());
3769        assert!(multicast.is_specified());
3770
3771        // Link-local
3772
3773        assert!(!Ipv4::UNSPECIFIED_ADDRESS.is_link_local());
3774        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_link_local());
3775
3776        let link_local = Ipv4::LINK_LOCAL_UNICAST_SUBNET.network;
3777        assert!(link_local.is_link_local());
3778        assert!(link_local.is_specified());
3779        let link_local = Ipv4::LINK_LOCAL_MULTICAST_SUBNET.network;
3780        assert!(link_local.is_link_local());
3781        assert!(link_local.is_specified());
3782        let link_local = Ipv6::LINK_LOCAL_UNICAST_SUBNET.network;
3783        assert!(link_local.is_link_local());
3784        assert!(link_local.is_specified());
3785        let mut link_local = Ipv6::MULTICAST_SUBNET.network;
3786        link_local.0[1] = 0x02;
3787        assert!(link_local.is_link_local());
3788        assert!(link_local.is_specified());
3789        assert!(Ipv6::LOOPBACK_ADDRESS.is_link_local());
3790    }
3791
3792    #[test]
3793    fn test_link_local() {
3794        // IPv4
3795        assert!(Ipv4::LINK_LOCAL_UNICAST_SUBNET.network.is_link_local());
3796        assert!(Ipv4::LINK_LOCAL_MULTICAST_SUBNET.network.is_link_local());
3797
3798        // IPv6
3799        assert!(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network.is_link_local());
3800        assert!(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network.is_unicast_link_local());
3801        let mut addr = Ipv6::MULTICAST_SUBNET.network;
3802        for flags in 0..=0x0F {
3803            // Set the scope to link-local and the flags to `flags`.
3804            addr.0[1] = (flags << 4) | 0x02;
3805            // Test that a link-local multicast address is always considered
3806            // link-local regardless of which flags are set.
3807            assert!(addr.is_link_local());
3808            assert!(!addr.is_unicast_link_local());
3809        }
3810
3811        // Test that a non-multicast address (outside of the link-local subnet)
3812        // is never considered link-local even if the bits are set that, in a
3813        // multicast address, would put it in the link-local scope.
3814        let mut addr = Ipv6::LOOPBACK_ADDRESS.get();
3815        // Explicitly set the scope to link-local.
3816        addr.0[1] = 0x02;
3817        assert!(!addr.is_link_local());
3818    }
3819
3820    #[test]
3821    fn test_subnet_new() {
3822        assert_eq!(
3823            Subnet::new(Ipv4Addr::new([255, 255, 255, 255]), 32).unwrap(),
3824            Subnet { network: Ipv4Addr::new([255, 255, 255, 255]), prefix: 32 },
3825        );
3826        // Prefix exceeds 32 bits
3827        assert_eq!(
3828            Subnet::new(Ipv4Addr::new([255, 255, 0, 0]), 33),
3829            Err(SubnetError::PrefixTooLong)
3830        );
3831        assert_eq!(
3832            Subnet::from_host(Ipv4Addr::new([255, 255, 255, 255]), 33),
3833            Err(PrefixTooLongError)
3834        );
3835        // Network address has more than top 8 bits set
3836        assert_eq!(Subnet::new(Ipv4Addr::new([255, 255, 0, 0]), 8), Err(SubnetError::HostBitsSet));
3837        // Host address is allowed to have host bits set
3838        assert_eq!(
3839            Subnet::from_host(Ipv4Addr::new([255, 255, 0, 0]), 8),
3840            Ok(Subnet { network: Ipv4Addr::new([255, 0, 0, 0]), prefix: 8 })
3841        );
3842
3843        assert_eq!(
3844            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([1, 2, 3, 4]), 32).unwrap(),
3845            AddrSubnet {
3846                addr: SpecifiedAddr(Ipv4Addr::new([1, 2, 3, 4])),
3847                subnet: Subnet { network: Ipv4Addr::new([1, 2, 3, 4]), prefix: 32 }
3848            }
3849        );
3850        // The unspecified address will always fail because it is not valid for
3851        // the `SpecifiedAddr` witness (use assert, not assert_eq, because
3852        // AddrSubnet doesn't impl Debug).
3853        assert!(
3854            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4::UNSPECIFIED_ADDRESS, 16)
3855                == Err(AddrSubnetError::InvalidWitness)
3856        );
3857        assert!(
3858            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv6::UNSPECIFIED_ADDRESS, 64)
3859                == Err(AddrSubnetError::InvalidWitness)
3860        );
3861        // Prefix exceeds 32/128 bits
3862        assert!(
3863            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([1, 2, 3, 4]), 33)
3864                == Err(AddrSubnetError::PrefixTooLong)
3865        );
3866        assert!(
3867            AddrSubnet::<_, SpecifiedAddr<_>>::new(
3868                Ipv6Addr::from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
3869                129,
3870            ) == Err(AddrSubnetError::PrefixTooLong)
3871        );
3872        // Limited broadcast
3873        assert!(
3874            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4::LIMITED_BROADCAST_ADDRESS.get(), 16)
3875                == Err(AddrSubnetError::NotUnicastInSubnet)
3876        );
3877        // Subnet broadcast
3878        assert!(
3879            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([192, 168, 255, 255]), 16)
3880                == Err(AddrSubnetError::NotUnicastInSubnet)
3881        );
3882        // Multicast
3883        assert!(
3884            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([224, 0, 0, 1]), 16)
3885                == Err(AddrSubnetError::NotUnicastInSubnet)
3886        );
3887        assert!(
3888            AddrSubnet::<_, SpecifiedAddr<_>>::new(
3889                Ipv6Addr::from([0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]),
3890                64,
3891            ) == Err(AddrSubnetError::NotUnicastInSubnet)
3892        );
3893
3894        // If we use the `LinkLocalAddr` witness type, then non link-local
3895        // addresses are rejected. Note that this address was accepted above
3896        // when `SpecifiedAddr` was used.
3897        assert!(
3898            AddrSubnet::<_, LinkLocalAddr<Ipv4Addr>>::new(Ipv4Addr::new([1, 2, 3, 4]), 32)
3899                == Err(AddrSubnetError::InvalidWitness)
3900        );
3901    }
3902
3903    #[test]
3904    fn test_is_unicast_in_subnet() {
3905        // Valid unicast in subnet
3906        let subnet =
3907            Subnet::new(Ipv4Addr::new([1, 2, 0, 0]), 16).expect("1.2.0.0/16 is a valid subnet");
3908        assert!(Ipv4Addr::new([1, 2, 3, 4]).is_unicast_in_subnet(&subnet));
3909        assert!(!Ipv4Addr::new([2, 2, 3, 4]).is_unicast_in_subnet(&subnet));
3910
3911        let subnet =
3912            Subnet::new(Ipv6Addr::from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 64)
3913                .expect("1::/64 is a valid subnet");
3914        assert!(Ipv6Addr::from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
3915            .is_unicast_in_subnet(&subnet));
3916        assert!(!Ipv6Addr::from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
3917            .is_unicast_in_subnet(&subnet));
3918
3919        // Unspecified address
3920        assert!(!Ipv4::UNSPECIFIED_ADDRESS
3921            .is_unicast_in_subnet(&Subnet::new(Ipv4::UNSPECIFIED_ADDRESS, 16).unwrap()));
3922        assert!(!Ipv6::UNSPECIFIED_ADDRESS
3923            .is_unicast_in_subnet(&Subnet::new(Ipv6::UNSPECIFIED_ADDRESS, 64).unwrap()));
3924        // The "31- or 32-bit prefix" exception doesn't apply to the unspecified
3925        // address (IPv4 only).
3926        assert!(!Ipv4::UNSPECIFIED_ADDRESS
3927            .is_unicast_in_subnet(&Subnet::new(Ipv4::UNSPECIFIED_ADDRESS, 31).unwrap()));
3928        assert!(!Ipv4::UNSPECIFIED_ADDRESS
3929            .is_unicast_in_subnet(&Subnet::new(Ipv4::UNSPECIFIED_ADDRESS, 32).unwrap()));
3930        // All-zeroes host part (IPv4 only)
3931        assert!(!Ipv4Addr::new([1, 2, 0, 0])
3932            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 0, 0]), 16).unwrap()));
3933        // Exception: 31- or 32-bit prefix (IPv4 only)
3934        assert!(Ipv4Addr::new([1, 2, 3, 0])
3935            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 3, 0]), 31).unwrap()));
3936        assert!(Ipv4Addr::new([1, 2, 3, 0])
3937            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 3, 0]), 32).unwrap()));
3938        // Limited broadcast (IPv4 only)
3939        assert!(!Ipv4::LIMITED_BROADCAST_ADDRESS
3940            .get()
3941            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([128, 0, 0, 0]), 1).unwrap()));
3942        // Subnet broadcast (IPv4 only)
3943        assert!(!Ipv4Addr::new([1, 2, 255, 255])
3944            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 0, 0]), 16).unwrap()));
3945        // Exception: 31- or 32-bit prefix (IPv4 only)
3946        assert!(Ipv4Addr::new([1, 2, 255, 255])
3947            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 255, 254]), 31).unwrap()));
3948        assert!(Ipv4Addr::new([1, 2, 255, 255])
3949            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 255, 255]), 32).unwrap()));
3950        // Multicast
3951        assert!(!Ipv4Addr::new([224, 0, 0, 1]).is_unicast_in_subnet(&Ipv4::MULTICAST_SUBNET));
3952        assert!(!Ipv6Addr::from([0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
3953            .is_unicast_in_subnet(&Ipv6::MULTICAST_SUBNET));
3954        // Class E (IPv4 only)
3955        assert!(!Ipv4Addr::new([240, 0, 0, 1]).is_unicast_in_subnet(&Ipv4::CLASS_E_SUBNET));
3956    }
3957
3958    macro_rules! add_mask_test {
3959            ($name:ident, $addr:ident, $from_ip:expr => {
3960                $($mask:expr => $to_ip:expr),*
3961            }) => {
3962                #[test]
3963                fn $name() {
3964                    let from = $addr::from($from_ip);
3965                    $(assert_eq!(from.mask($mask), $addr::from($to_ip), "(`{}`.mask({}))", from, $mask);)*
3966                }
3967            };
3968            ($name:ident, $addr:ident, $from_ip:expr => {
3969                $($mask:expr => $to_ip:expr),*,
3970            }) => {
3971                add_mask_test!($name, $addr, $from_ip => { $($mask => $to_ip),* });
3972            };
3973        }
3974
3975    add_mask_test!(v4_full_mask, Ipv4Addr, [255, 254, 253, 252] => {
3976        32 => [255, 254, 253, 252],
3977        28 => [255, 254, 253, 240],
3978        24 => [255, 254, 253, 0],
3979        20 => [255, 254, 240, 0],
3980        16 => [255, 254, 0,   0],
3981        12 => [255, 240, 0,   0],
3982        8  => [255, 0,   0,   0],
3983        4  => [240, 0,   0,   0],
3984        0  => [0,   0,   0,   0],
3985    });
3986
3987    add_mask_test!(v6_full_mask, Ipv6Addr,
3988        [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0] => {
3989            128 => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0],
3990            112 => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0x00, 0x00],
3991            96  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0x00, 0x00, 0x00, 0x00],
3992            80  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
3993            64  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
3994            48  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
3995            32  => [0xFF, 0xFE, 0xFD, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
3996            16  => [0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
3997            8   => [0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
3998            0   => [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
3999        }
4000    );
4001
4002    #[test_case([255, 255, 255, 0] => Ok(24))]
4003    #[test_case([255, 255, 254, 0] => Ok(23))]
4004    #[test_case([255, 255, 253, 0] => Err(NotSubnetMaskError))]
4005    #[test_case([255, 255, 0, 255] => Err(NotSubnetMaskError))]
4006    #[test_case([255, 255, 255, 255] => Ok(32))]
4007    #[test_case([0, 0, 0, 0] => Ok(0))]
4008    #[test_case([0, 0, 0, 255] => Err(NotSubnetMaskError))]
4009    fn test_ipv4_prefix_len_try_from_subnet_mask(
4010        subnet_mask: [u8; 4],
4011    ) -> Result<u8, NotSubnetMaskError> {
4012        let subnet_mask = Ipv4Addr::from(subnet_mask);
4013        PrefixLength::<Ipv4>::try_from_subnet_mask(subnet_mask).map(|prefix_len| prefix_len.get())
4014    }
4015
4016    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(64))]
4017    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(63))]
4018    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0, 0, 0, 0, 0, 0, 0, 0] => Err(NotSubnetMaskError))]
4019    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0, 0, 0, 0, 0, 0, 0, 1] => Err(NotSubnetMaskError))]
4020    #[test_case([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(0))]
4021    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] => Ok(128))]
4022    #[test_case([0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0] => Err(NotSubnetMaskError))]
4023    fn test_ipv6_prefix_len_try_from_subnet_mask(
4024        subnet_mask: [u8; 16],
4025    ) -> Result<u8, NotSubnetMaskError> {
4026        let subnet_mask = Ipv6Addr::from(subnet_mask);
4027        PrefixLength::<Ipv6>::try_from_subnet_mask(subnet_mask).map(|prefix_len| prefix_len.get())
4028    }
4029
4030    #[test_case(0 => true)]
4031    #[test_case(1 => true)]
4032    #[test_case(32 => true)]
4033    #[test_case(33 => false)]
4034    #[test_case(128 => false)]
4035    #[test_case(129 => false)]
4036    #[test_case(255 => false)]
4037    fn test_ipv4_prefix_len_new(prefix_len: u8) -> bool {
4038        PrefixLength::<Ipv4>::new(prefix_len).is_ok()
4039    }
4040
4041    #[test_case(0 => true)]
4042    #[test_case(1 => true)]
4043    #[test_case(32 => true)]
4044    #[test_case(33 => true)]
4045    #[test_case(128 => true)]
4046    #[test_case(129 => false)]
4047    #[test_case(255 => false)]
4048    fn test_ipv6_prefix_len_new(prefix_len: u8) -> bool {
4049        PrefixLength::<Ipv6>::new(prefix_len).is_ok()
4050    }
4051
4052    #[test_case(0 => [0, 0, 0, 0])]
4053    #[test_case(6 => [252, 0, 0, 0])]
4054    #[test_case(16 => [255, 255, 0, 0])]
4055    #[test_case(25 => [255, 255, 255, 128])]
4056    #[test_case(32 => [255, 255, 255, 255])]
4057    fn test_ipv4_prefix_len_get_mask(prefix_len: u8) -> [u8; 4] {
4058        let Ipv4Addr(inner) = PrefixLength::<Ipv4>::new(prefix_len).unwrap().get_mask();
4059        inner
4060    }
4061
4062    #[test_case(0 => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
4063    #[test_case(6 => [0xFC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
4064    #[test_case(64 => [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0])]
4065    #[test_case(65 => [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0, 0, 0, 0, 0, 0, 0])]
4066    #[test_case(128 => [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
4067    fn test_ipv6_prefix_len_get_mask(prefix_len: u8) -> [u8; 16] {
4068        let Ipv6Addr(inner) = PrefixLength::<Ipv6>::new(prefix_len).unwrap().get_mask();
4069        inner
4070    }
4071
4072    #[test]
4073    fn test_ipv6_solicited_node() {
4074        let addr = Ipv6Addr::new([0xfe80, 0, 0, 0, 0x52e5, 0x49ff, 0xfeb5, 0x5aa0]);
4075        let solicited = Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0x01, 0xffb5, 0x5aa0]);
4076        assert_eq!(addr.to_solicited_node_address().get(), solicited);
4077    }
4078
4079    #[test]
4080    fn test_ipv6_address_types() {
4081        assert!(!Ipv6Addr::from([0; 16]).is_specified());
4082        assert!(Ipv6Addr::new([0, 0, 0, 0, 0, 0, 0, 1]).is_loopback());
4083        let link_local = Ipv6Addr::new([0xfe80, 0, 0, 0, 0x52e5, 0x49ff, 0xfeb5, 0x5aa0]);
4084        assert!(link_local.is_link_local());
4085        assert!(link_local.is_valid_unicast());
4086        assert!(link_local.to_solicited_node_address().is_multicast());
4087        let global_unicast = Ipv6Addr::new([0x80, 0, 0, 0, 0x52e5, 0x49ff, 0xfeb5, 0x5aa0]);
4088        assert!(global_unicast.is_valid_unicast());
4089        assert!(global_unicast.to_solicited_node_address().is_multicast());
4090
4091        let multi = Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0x01, 0xffb5, 0x5aa0]);
4092        assert!(multi.is_multicast());
4093        assert!(!multi.is_valid_unicast());
4094    }
4095
4096    #[test]
4097    fn test_const_witness() {
4098        // Test that all of the addresses that we initialize at compile time
4099        // using `new_unchecked` constructors are valid for their witness types.
4100        assert!(Ipv4::LOOPBACK_ADDRESS.0.is_specified());
4101        assert!(Ipv6::LOOPBACK_ADDRESS.0.is_specified());
4102        assert!(Ipv4::LIMITED_BROADCAST_ADDRESS.0.is_specified());
4103        assert!(Ipv4::ALL_ROUTERS_MULTICAST_ADDRESS.0.is_multicast());
4104        assert!(Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS.0.is_multicast());
4105        assert!(Ipv6::ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS.0.is_multicast());
4106    }
4107
4108    #[test]
4109    fn test_ipv6_scope() {
4110        use Ipv6ReservedScope::*;
4111        use Ipv6Scope::*;
4112        use Ipv6UnassignedScope::*;
4113
4114        // Test unicast scopes.
4115        assert_eq!(Ipv6::SITE_LOCAL_UNICAST_SUBNET.network.scope(), SiteLocal);
4116        assert_eq!(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network.scope(), LinkLocal);
4117        assert_eq!(Ipv6::UNSPECIFIED_ADDRESS.scope(), Global);
4118
4119        // Test multicast scopes.
4120        let assert_scope = |value, scope| {
4121            let mut addr = Ipv6::MULTICAST_SUBNET.network;
4122            // Set the "scop" field manually.
4123            addr.0[1] |= value;
4124            assert_eq!(addr.scope(), scope);
4125        };
4126        assert_scope(0, Reserved(Scope0));
4127        assert_scope(1, InterfaceLocal);
4128        assert_scope(2, LinkLocal);
4129        assert_scope(3, Reserved(Scope3));
4130        assert_scope(4, AdminLocal);
4131        assert_scope(5, SiteLocal);
4132        assert_scope(6, Unassigned(Scope6));
4133        assert_scope(7, Unassigned(Scope7));
4134        assert_scope(8, OrganizationLocal);
4135        assert_scope(9, Unassigned(Scope9));
4136        assert_scope(0xA, Unassigned(ScopeA));
4137        assert_scope(0xB, Unassigned(ScopeB));
4138        assert_scope(0xC, Unassigned(ScopeC));
4139        assert_scope(0xD, Unassigned(ScopeD));
4140        assert_scope(0xE, Global);
4141        assert_scope(0xF, Reserved(ScopeF));
4142    }
4143
4144    #[test]
4145    fn test_ipv6_multicast_scope_id() {
4146        const ALL_SCOPES: &[Ipv6Scope] = &[
4147            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope0),
4148            Ipv6Scope::InterfaceLocal,
4149            Ipv6Scope::LinkLocal,
4150            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope3),
4151            Ipv6Scope::AdminLocal,
4152            Ipv6Scope::SiteLocal,
4153            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope6),
4154            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope7),
4155            Ipv6Scope::OrganizationLocal,
4156            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope9),
4157            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeA),
4158            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeB),
4159            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeC),
4160            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeD),
4161            Ipv6Scope::Global,
4162            Ipv6Scope::Reserved(Ipv6ReservedScope::ScopeF),
4163        ];
4164        for (i, a) in ALL_SCOPES.iter().enumerate() {
4165            assert_eq!(a.multicast_scope_id(), i.try_into().unwrap());
4166        }
4167    }
4168
4169    #[test]
4170    fn test_ipv4_embedded() {
4171        // Test Ipv4Addr's to_ipv6_compatible and to_ipv6_mapped methods.
4172
4173        assert_eq!(
4174            Ipv4Addr::new([1, 2, 3, 4]).to_ipv6_compatible(),
4175            Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4])
4176        );
4177        assert_eq!(
4178            Ipv4Addr::new([1, 2, 3, 4]).to_ipv6_mapped().get(),
4179            Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 1, 2, 3, 4]),
4180        );
4181
4182        // Test Ipv6Addr's to_ipv4_compatible and to_ipv4_mapped methods.
4183
4184        let compatible = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4]);
4185        let mapped = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 1, 2, 3, 4]);
4186        let not_embedded = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 1, 2, 3, 4]);
4187        let v4 = Ipv4Addr::new([1, 2, 3, 4]);
4188
4189        assert_eq!(compatible.to_ipv4_compatible(), Some(v4));
4190        assert_eq!(compatible.to_ipv4_mapped(), None);
4191
4192        assert_eq!(mapped.to_ipv4_compatible(), None);
4193        assert_eq!(mapped.to_ipv4_mapped(), Some(v4));
4194
4195        assert_eq!(not_embedded.to_ipv4_compatible(), None);
4196        assert_eq!(not_embedded.to_ipv4_mapped(), None);
4197
4198        assert_eq!(
4199            NonMappedAddr::new(compatible),
4200            Some(unsafe { NonMappedAddr::new_unchecked(compatible) })
4201        );
4202        assert_eq!(NonMappedAddr::new(mapped), None);
4203        assert_eq!(
4204            NonMappedAddr::new(not_embedded),
4205            Some(unsafe { NonMappedAddr::new_unchecked(not_embedded) })
4206        );
4207        assert_eq!(NonMappedAddr::new(v4), Some(unsafe { NonMappedAddr::new_unchecked(v4) }));
4208    }
4209
4210    #[test]
4211    fn test_common_prefix_len_ipv6() {
4212        let ip1 = Ipv6Addr::from([0xFF, 0xFF, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
4213        let ip2 = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
4214        let ip3 = Ipv6Addr::from([0xFF, 0xFF, 0x80, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
4215        let ip4 = Ipv6Addr::from([0xFF, 0xFF, 0xC0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
4216        let compare_with_ip1 = |target, expect| {
4217            assert_eq!(ip1.common_prefix_len(&target), expect, "{} <=> {}", ip1, target);
4218        };
4219        compare_with_ip1(ip1, 128);
4220        compare_with_ip1(ip2, 0);
4221        compare_with_ip1(ip3, 24);
4222        compare_with_ip1(ip4, 17);
4223    }
4224
4225    #[test]
4226    fn test_common_prefix_len_ipv4() {
4227        let ip1 = Ipv4Addr::new([0xFF, 0xFF, 0x80, 0]);
4228        let ip2 = Ipv4Addr::new([0, 0, 0, 0]);
4229        let ip3 = Ipv4Addr::new([0xFF, 0xFF, 0x80, 0xFF]);
4230        let ip4 = Ipv4Addr::new([0xFF, 0xFF, 0xC0, 0x20]);
4231        let compare_with_ip1 = |target, expect| {
4232            assert_eq!(ip1.common_prefix_len(&target), expect, "{} <=> {}", ip1, target);
4233        };
4234        compare_with_ip1(ip1, 32);
4235        compare_with_ip1(ip2, 0);
4236        compare_with_ip1(ip3, 24);
4237        compare_with_ip1(ip4, 17);
4238    }
4239
4240    #[test]
4241    fn test_ipv6_display() {
4242        // Test that `addr` is formatted the same by our `Display` impl as by
4243        // the standard library's `Display` impl. Optionally test that it
4244        // matches a particular expected string.
4245        fn test_one(addr: Ipv6Addr, expect: Option<&str>) {
4246            let formatted = format!("{}", addr);
4247            if let Some(expect) = expect {
4248                assert_eq!(formatted, expect);
4249            }
4250
4251            // NOTE: We use `std` here even though we're not inside of the
4252            // `std_tests` module because we're using `std` to test
4253            // functionality that is present even when the `std` Cargo feature
4254            // is not used.
4255            //
4256            // Note that we use `std::net::Ipv6Addr::from(addr.segments())`
4257            // rather than `std::net::Ipv6Addr::from(addr)` because, when the
4258            // `std` Cargo feature is disabled, the `From<Ipv6Addr> for
4259            // std::net::Ipv6Addr` impl is not emitted.
4260            let formatted_std = format!("{}", std::net::Ipv6Addr::from(addr.segments()));
4261            assert_eq!(formatted, formatted_std);
4262        }
4263
4264        test_one(Ipv6::UNSPECIFIED_ADDRESS, Some("::"));
4265        test_one(*Ipv6::LOOPBACK_ADDRESS, Some("::1"));
4266        test_one(Ipv6::MULTICAST_SUBNET.network, Some("ff00::"));
4267        test_one(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network, Some("fe80::"));
4268        test_one(*Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS, Some("ff02::1"));
4269        test_one(*Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS, Some("ff02::1"));
4270        test_one(*Ipv6::ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS, Some("ff02::2"));
4271        test_one(Ipv6::SITE_LOCAL_UNICAST_SUBNET.network, Some("fec0::"));
4272        test_one(Ipv6Addr::new([1, 0, 0, 0, 0, 0, 0, 0]), Some("1::"));
4273        test_one(Ipv6Addr::new([0, 0, 0, 1, 2, 3, 4, 5]), Some("::1:2:3:4:5"));
4274
4275        // Treating each pair of bytes as a bit (either 0x0000 or 0x0001), cycle
4276        // through every possible IPv6 address. Since the formatting algorithm
4277        // is only sensitive to zero vs nonzero for any given byte pair, this
4278        // gives us effectively complete coverage of the input space.
4279        for byte in 0u8..=255 {
4280            test_one(
4281                Ipv6Addr::new([
4282                    u16::from(byte & 0b1),
4283                    u16::from((byte & 0b10) >> 1),
4284                    u16::from((byte & 0b100) >> 2),
4285                    u16::from((byte & 0b1000) >> 3),
4286                    u16::from((byte & 0b10000) >> 4),
4287                    u16::from((byte & 0b100000) >> 5),
4288                    u16::from((byte & 0b1000000) >> 6),
4289                    u16::from((byte & 0b10000000) >> 7),
4290                ]),
4291                None,
4292            );
4293        }
4294    }
4295
4296    #[test_case(Ipv4::UNSPECIFIED_ADDRESS, Ipv4AddressClass::A; "first_class_a")]
4297    #[test_case(Ipv4Addr::new([127, 255, 255, 255]), Ipv4AddressClass::A; "last_class_a")]
4298    #[test_case(Ipv4Addr::new([128, 0, 0, 0]), Ipv4AddressClass::B; "first_class_b")]
4299    #[test_case(Ipv4Addr::new([191, 255, 255, 255]), Ipv4AddressClass::B; "last_class_b")]
4300    #[test_case(Ipv4Addr::new([192, 0, 0, 0]), Ipv4AddressClass::C; "first_class_c")]
4301    #[test_case(Ipv4Addr::new([223, 255, 255, 255]), Ipv4AddressClass::C; "last_class_c")]
4302    #[test_case(Ipv4Addr::new([224, 0, 0, 0]), Ipv4AddressClass::D; "first_class_d")]
4303    #[test_case(Ipv4Addr::new([239, 255, 255, 255]), Ipv4AddressClass::D; "last_class_d")]
4304    #[test_case(Ipv4Addr::new([240, 0, 0, 0]), Ipv4AddressClass::E; "first_class_e")]
4305    #[test_case(Ipv4Addr::new([255, 255, 255, 255]), Ipv4AddressClass::E; "last_class_e")]
4306    fn ipv4addr_class(addr: Ipv4Addr, class: Ipv4AddressClass) {
4307        assert_eq!(addr.class(), class)
4308    }
4309
4310    #[test_case(
4311        Subnet::new(Ipv4Addr::new([192, 168, 1, 0]), 24).unwrap(),
4312        Subnet::new(Ipv4Addr::new([192, 168, 2, 0]), 24).unwrap()
4313    ; "ipv4_same_prefix")]
4314    #[test_case(
4315        Subnet::new(Ipv4Addr::new([192, 168, 2, 0]), 24).unwrap(),
4316        Subnet::new(Ipv4Addr::new([192, 168, 1, 0]), 32).unwrap()
4317    ; "ipv4_by_prefix")]
4318    #[test_case(
4319        Subnet::new(Ipv6Addr::new([1, 0, 0, 0, 0, 0, 0, 0]), 64).unwrap(),
4320        Subnet::new(Ipv6Addr::new([2, 0, 0, 0, 0, 0, 0, 0]), 64).unwrap()
4321    ; "ipv6_same_prefix")]
4322    #[test_case(
4323        Subnet::new(Ipv6Addr::new([2, 0, 0, 0, 0, 0, 0, 0]), 64).unwrap(),
4324        Subnet::new(Ipv6Addr::new([1, 0, 0, 0, 0, 0, 0, 0]), 128).unwrap()
4325    ; "ipv6_by_prefix")]
4326    fn subnet_ord<A: core::cmp::Ord>(a: Subnet<A>, b: Subnet<A>) {
4327        assert!(a < b);
4328    }
4329
4330    #[cfg(feature = "std")]
4331    mod std_tests {
4332        use super::*;
4333
4334        #[test]
4335        fn test_conversions() {
4336            let v4 = Ipv4Addr::new([127, 0, 0, 1]);
4337            let v6 = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
4338            let std_v4 = net::Ipv4Addr::new(127, 0, 0, 1);
4339            let std_v6 = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
4340
4341            let converted: IpAddr = net::IpAddr::V4(std_v4).into();
4342            assert_eq!(converted, IpAddr::V4(v4));
4343            let converted: IpAddr = net::IpAddr::V6(std_v6).into();
4344            assert_eq!(converted, IpAddr::V6(v6));
4345
4346            let converted: net::IpAddr = IpAddr::V4(v4).into();
4347            assert_eq!(converted, net::IpAddr::V4(std_v4));
4348            let converted: net::IpAddr = IpAddr::V6(v6).into();
4349            assert_eq!(converted, net::IpAddr::V6(std_v6));
4350
4351            let converted: Ipv4Addr = std_v4.into();
4352            assert_eq!(converted, v4);
4353            let converted: Ipv6Addr = std_v6.into();
4354            assert_eq!(converted, v6);
4355
4356            let converted: net::Ipv4Addr = v4.into();
4357            assert_eq!(converted, std_v4);
4358            let converted: net::Ipv6Addr = v6.into();
4359            assert_eq!(converted, std_v6);
4360        }
4361    }
4362}
4363
4364/// Tests of the [`GenericOverIp`] derive macro.
4365#[cfg(test)]
4366mod macro_test {
4367    use super::*;
4368
4369    /// No-op function that will only compile if `T::Type<I> = Other`.
4370    fn assert_ip_generic_is<T, I, Other>()
4371    where
4372        I: Ip,
4373        T: GenericOverIp<I, Type = Other>,
4374    {
4375        // Do nothing; this function just serves to assert that the argument
4376        // does in fact implement GenericOverIp.
4377    }
4378
4379    macro_rules! assert_ip_generic {
4380        ($name:ident, Ip $(,$($param:ident),*)?) => {
4381            assert_ip_generic_is::<$name<Ipv4 $(, $($param,)*)?>, Ipv4, $name<Ipv4 $(, $($param,)*)?>>();
4382            assert_ip_generic_is::<$name<Ipv4 $(, $($param,)*)?>, Ipv6, $name<Ipv6 $(, $($param,)*)?>>();
4383            assert_ip_generic_is::<$name<Ipv6 $(, $($param,)*)?>, Ipv4, $name<Ipv4 $(, $($param,)*)?>>();
4384            assert_ip_generic_is::<$name<Ipv6 $(, $($param,)*)?>, Ipv6, $name<Ipv6 $(, $($param,)*)?>>();
4385        };
4386        ($name:ident, IpAddress $(,$($param:ident),*)?) => {
4387            assert_ip_generic_is::<$name<Ipv4Addr $(, $($param,)*)?>, Ipv4, $name<Ipv4Addr $(, $($param,)*)?>>();
4388            assert_ip_generic_is::<$name<Ipv4Addr $(, $($param,)*)?>, Ipv6, $name<Ipv6Addr $(, $($param,)*)?>>();
4389            assert_ip_generic_is::<$name<Ipv6Addr $(, $($param,)*)?>, Ipv4, $name<Ipv4Addr $(, $($param,)*)?>>();
4390            assert_ip_generic_is::<$name<Ipv6Addr $(, $($param,)*)?>, Ipv6, $name<Ipv6Addr $(, $($param,)*)?>>();
4391        };
4392        ($name:ident $(,$($param:ident),*)?) => {
4393            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv4, $name<$($($param,)*)?>>();
4394            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv6, $name<$($($param,)*)?>>();
4395            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv4, $name<$($($param,)*)?>>();
4396            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv6, $name<$($($param,)*)?>>();
4397        };
4398    }
4399
4400    #[test]
4401    fn struct_with_ip_version_parameter() {
4402        #[allow(dead_code)]
4403        #[derive(GenericOverIp)]
4404        #[generic_over_ip(I, Ip)]
4405        struct Generic<I: Ip> {
4406            addr: I::Addr,
4407        }
4408
4409        assert_ip_generic!(Generic, Ip);
4410    }
4411
4412    #[test]
4413    fn struct_with_unbounded_ip_version_parameter() {
4414        #[allow(dead_code)]
4415        #[derive(GenericOverIp)]
4416        #[generic_over_ip(I, Ip)]
4417        struct Generic<I> {
4418            addr: core::marker::PhantomData<I>,
4419        }
4420
4421        assert_ip_generic!(Generic, Ip);
4422    }
4423
4424    #[test]
4425    fn struct_with_ip_address_parameter() {
4426        #[allow(dead_code)]
4427        #[derive(GenericOverIp)]
4428        #[generic_over_ip(A, IpAddress)]
4429        struct Generic<A: IpAddress> {
4430            addr: A,
4431        }
4432
4433        assert_ip_generic!(Generic, IpAddress);
4434    }
4435
4436    #[test]
4437    fn struct_with_unbounded_ip_address_parameter() {
4438        #[allow(dead_code)]
4439        #[derive(GenericOverIp)]
4440        #[generic_over_ip(A, IpAddress)]
4441        struct Generic<A> {
4442            addr: A,
4443        }
4444
4445        assert_ip_generic!(Generic, IpAddress);
4446    }
4447
4448    #[test]
4449    fn struct_with_generic_over_ip_parameter() {
4450        #[derive(GenericOverIp)]
4451        #[generic_over_ip(I, Ip)]
4452        struct InnerGeneric<I: Ip> {
4453            addr: I::Addr,
4454        }
4455
4456        #[derive(GenericOverIp)]
4457        #[generic_over_ip(T, GenericOverIp)]
4458        struct Generic<T> {
4459            foo: T,
4460        }
4461
4462        fn do_something<I: Ip>(g: Generic<InnerGeneric<I>>) {
4463            I::map_ip(
4464                g,
4465                |g| {
4466                    let _: Ipv4Addr = g.foo.addr;
4467                },
4468                |g| {
4469                    let _: Ipv6Addr = g.foo.addr;
4470                },
4471            )
4472        }
4473
4474        do_something::<Ipv4>(Generic { foo: InnerGeneric { addr: Ipv4::UNSPECIFIED_ADDRESS } });
4475
4476        do_something::<Ipv6>(Generic { foo: InnerGeneric { addr: Ipv6::UNSPECIFIED_ADDRESS } });
4477    }
4478
4479    #[test]
4480    fn enum_with_ip_version_parameter() {
4481        #[allow(dead_code)]
4482        #[derive(GenericOverIp)]
4483        #[generic_over_ip(I, Ip)]
4484        enum Generic<I: Ip> {
4485            A(I::Addr),
4486            B(I::Addr),
4487        }
4488
4489        assert_ip_generic!(Generic, Ip);
4490    }
4491
4492    #[test]
4493    fn enum_with_unbounded_ip_version_parameter() {
4494        #[allow(dead_code)]
4495        #[derive(GenericOverIp)]
4496        #[generic_over_ip(I, Ip)]
4497        enum Generic<I> {
4498            A(core::marker::PhantomData<I>),
4499            B(core::marker::PhantomData<I>),
4500        }
4501
4502        assert_ip_generic!(Generic, Ip);
4503    }
4504
4505    #[test]
4506    fn enum_with_ip_address_parameter() {
4507        #[allow(dead_code)]
4508        #[derive(GenericOverIp)]
4509        #[generic_over_ip(A, IpAddress)]
4510        enum Generic<A: IpAddress> {
4511            A(A),
4512            B(A),
4513        }
4514
4515        assert_ip_generic!(Generic, IpAddress);
4516    }
4517
4518    #[test]
4519    fn enum_with_unbounded_ip_address_parameter() {
4520        #[allow(dead_code)]
4521        #[derive(GenericOverIp)]
4522        #[generic_over_ip(A, IpAddress)]
4523        enum Generic<A> {
4524            A(A),
4525            B(A),
4526        }
4527
4528        assert_ip_generic!(Generic, IpAddress);
4529    }
4530
4531    #[test]
4532    fn struct_with_ip_version_and_other_parameters() {
4533        #[allow(dead_code)]
4534        #[derive(GenericOverIp)]
4535        #[generic_over_ip(I, Ip)]
4536        struct AddrAndDevice<I: Ip, D> {
4537            addr: I::Addr,
4538            device: D,
4539        }
4540        struct Device;
4541
4542        assert_ip_generic!(AddrAndDevice, Ip, Device);
4543    }
4544
4545    #[test]
4546    fn enum_with_ip_version_and_other_parameters() {
4547        #[allow(dead_code)]
4548        #[derive(GenericOverIp)]
4549        #[generic_over_ip(I, Ip)]
4550        enum AddrOrDevice<I: Ip, D> {
4551            Addr(I::Addr),
4552            Device(D),
4553        }
4554        struct Device;
4555
4556        assert_ip_generic!(AddrOrDevice, Ip, Device);
4557    }
4558
4559    #[test]
4560    fn struct_with_ip_address_and_other_parameters() {
4561        #[allow(dead_code)]
4562        #[derive(GenericOverIp)]
4563        #[generic_over_ip(A, IpAddress)]
4564        struct AddrAndDevice<A: IpAddress, D> {
4565            addr: A,
4566            device: D,
4567        }
4568        struct Device;
4569
4570        assert_ip_generic!(AddrAndDevice, IpAddress, Device);
4571    }
4572
4573    #[test]
4574    fn struct_with_unbounded_ip_address_and_other_parameters() {
4575        #[allow(dead_code)]
4576        #[derive(GenericOverIp)]
4577        #[generic_over_ip(A, IpAddress)]
4578        struct AddrAndDevice<A, D> {
4579            addr: A,
4580            device: D,
4581        }
4582        struct Device;
4583
4584        assert_ip_generic!(AddrAndDevice, IpAddress, Device);
4585    }
4586
4587    #[test]
4588    fn enum_with_ip_address_and_other_parameters() {
4589        #[allow(dead_code)]
4590        #[derive(GenericOverIp, Debug, PartialEq)]
4591        #[generic_over_ip(A, IpAddress)]
4592        enum AddrOrDevice<A: IpAddress, D> {
4593            Addr(A),
4594            Device(D),
4595        }
4596        struct Device;
4597
4598        assert_ip_generic!(AddrOrDevice, IpAddress, Device);
4599    }
4600
4601    #[test]
4602    fn struct_invariant_over_ip() {
4603        #[allow(dead_code)]
4604        #[derive(GenericOverIp)]
4605        #[generic_over_ip()]
4606        struct Invariant(usize);
4607
4608        assert_ip_generic!(Invariant);
4609    }
4610
4611    #[test]
4612    fn enum_invariant_over_ip() {
4613        #[allow(dead_code)]
4614        #[derive(GenericOverIp)]
4615        #[generic_over_ip()]
4616        enum Invariant {
4617            Usize(usize),
4618        }
4619
4620        assert_ip_generic!(Invariant);
4621    }
4622
4623    #[test]
4624    fn struct_invariant_over_ip_with_other_params() {
4625        #[allow(dead_code)]
4626        #[derive(GenericOverIp)]
4627        #[generic_over_ip()]
4628        struct Invariant<B, C, D>(B, C, D);
4629
4630        assert_ip_generic!(Invariant, usize, bool, char);
4631    }
4632
4633    #[test]
4634    fn enum_invariant_over_ip_with_other_params() {
4635        #[allow(dead_code)]
4636        #[derive(GenericOverIp)]
4637        #[generic_over_ip()]
4638        enum Invariant<A, B, C> {
4639            A(A),
4640            B(B),
4641            C(C),
4642        }
4643
4644        assert_ip_generic!(Invariant, usize, bool, char);
4645    }
4646
4647    #[test]
4648    fn struct_with_ip_version_extension_parameter() {
4649        trait FakeIpExt: Ip {
4650            type Associated;
4651        }
4652        impl FakeIpExt for Ipv4 {
4653            type Associated = u8;
4654        }
4655        impl FakeIpExt for Ipv6 {
4656            type Associated = u16;
4657        }
4658
4659        #[allow(dead_code)]
4660        #[derive(GenericOverIp)]
4661        #[generic_over_ip(I, Ip)]
4662        struct Generic<I: FakeIpExt> {
4663            field: I::Associated,
4664        }
4665
4666        assert_ip_generic!(Generic, Ip);
4667    }
4668
4669    #[test]
4670    fn struct_with_ip_version_extension_parameter_but_no_ip_bound() {
4671        trait FakeIpExt: Ip {
4672            type Associated;
4673        }
4674        impl FakeIpExt for Ipv4 {
4675            type Associated = u8;
4676        }
4677        impl FakeIpExt for Ipv6 {
4678            type Associated = u16;
4679        }
4680
4681        #[allow(dead_code)]
4682        #[derive(GenericOverIp)]
4683        #[generic_over_ip(I, Ip)]
4684        struct Generic<I: FakeIpExt> {
4685            field: I::Associated,
4686        }
4687
4688        assert_ip_generic!(Generic, Ip);
4689    }
4690
4691    #[test]
4692    fn struct_with_ip_address_extension_parameter() {
4693        trait FakeIpAddressExt: IpAddress {
4694            type Associated;
4695        }
4696        impl FakeIpAddressExt for Ipv4Addr {
4697            type Associated = u8;
4698        }
4699        impl FakeIpAddressExt for Ipv6Addr {
4700            type Associated = u16;
4701        }
4702
4703        #[allow(dead_code)]
4704        #[derive(GenericOverIp)]
4705        #[generic_over_ip(A, IpAddress)]
4706        struct Generic<A: IpAddress + FakeIpAddressExt> {
4707            field: A::Associated,
4708        }
4709
4710        assert_ip_generic!(Generic, IpAddress);
4711    }
4712
4713    #[test]
4714    fn type_with_lifetime_and_ip_parameter() {
4715        #[allow(dead_code)]
4716        #[derive(GenericOverIp)]
4717        #[generic_over_ip(I, Ip)]
4718        struct Generic<'a, I: Ip> {
4719            field: &'a I::Addr,
4720        }
4721
4722        assert_ip_generic_is::<Generic<'static, Ipv4>, Ipv4, Generic<'static, Ipv4>>();
4723        assert_ip_generic_is::<Generic<'static, Ipv4>, Ipv6, Generic<'static, Ipv6>>();
4724        assert_ip_generic_is::<Generic<'static, Ipv6>, Ipv4, Generic<'static, Ipv4>>();
4725        assert_ip_generic_is::<Generic<'static, Ipv6>, Ipv6, Generic<'static, Ipv6>>();
4726    }
4727
4728    #[test]
4729    fn type_with_lifetime_and_no_ip_parameter() {
4730        #[allow(dead_code)]
4731        #[derive(GenericOverIp)]
4732        #[generic_over_ip()]
4733        struct Generic<'a> {
4734            field: &'a (),
4735        }
4736
4737        assert_ip_generic_is::<Generic<'static>, Ipv4, Generic<'static>>();
4738        assert_ip_generic_is::<Generic<'static>, Ipv6, Generic<'static>>();
4739    }
4740
4741    #[test]
4742    fn type_with_params_list_with_trailing_comma() {
4743        trait IpExtensionTraitWithVeryLongName {}
4744        trait OtherIpExtensionTraitWithVeryLongName {}
4745        trait LongNameToForceFormatterToBreakLineAndAddTrailingComma {}
4746        // Regression test for https://fxbug.dev/42080215
4747        #[allow(dead_code)]
4748        #[derive(GenericOverIp)]
4749        #[generic_over_ip(I, Ip)]
4750        struct Generic<
4751            I: Ip
4752                + IpExtensionTraitWithVeryLongName
4753                + OtherIpExtensionTraitWithVeryLongName
4754                + LongNameToForceFormatterToBreakLineAndAddTrailingComma,
4755        > {
4756            field: I::Addr,
4757        }
4758    }
4759}