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