Botan 3.12.0
Crypto and TLS for C&
ipv6_address.h
Go to the documentation of this file.
1/*
2* (C) 2026 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_IPV6_ADDRESS_H_
8#define BOTAN_IPV6_ADDRESS_H_
9
10#include <botan/types.h>
11#include <array>
12#include <optional>
13#include <span>
14#include <string>
15#include <string_view>
16#include <vector>
17
18namespace Botan {
19
20class IPv4Address;
21
22/**
23* IPv6 Address
24*/
25class BOTAN_PUBLIC_API(3, 12) IPv6Address final {
26 public:
27 explicit IPv6Address(std::span<const uint8_t, 16> ip);
28
29 explicit IPv6Address(std::array<uint8_t, 16> ip) : m_ip(ip) {}
30
31 static std::optional<IPv6Address> from_string(std::string_view str);
32
33 /**
34 * Return an address with the leading @p bits set to one and the remainder
35 * zero. Throws Invalid_Argument if @p bits > 128.
36 */
37 static IPv6Address netmask(size_t bits);
38
39 static IPv6Address host_mask() { return netmask(128); }
40
41 IPv6Address operator&(const IPv6Address& other) const;
42
43 auto operator<=>(const IPv6Address&) const = default;
44
45 std::span<const uint8_t, 16> address() const { return m_ip; }
46
47 std::string to_string() const;
48
49 /**
50 * If this value is a netmask consisting of a run of one bits followed by
51 * a run of zero bits, return the number of one bits.
52 *
53 * Otherwise return nullopt.
54 */
55 std::optional<size_t> prefix_length() const;
56
57 /**
58 * If this IPv6 address is an IPv4-compatible IPv6 address (RFC 4291 2.5.5.1)
59 * or an IPv4-mapped IPv6 address (RFC 4291 2.5.5.2), return the embedded
60 * IPv4 address.
61 */
62 std::optional<IPv4Address> as_ipv4() const;
63
64 private:
65 std::array<uint8_t, 16> m_ip;
66};
67
68/**
69* An IPv6 subnet in CIDR form: a network address paired with a prefix length
70*/
71class BOTAN_PUBLIC_API(3, 12) IPv6Subnet final {
72 public:
73 /**
74 * Construct from a network address and a prefix length in [0, 128].
75 * Host bits of @p address are cleared.
76 *
77 * Throws Invalid_Argument if @p prefix_length > 128.
78 */
80
81 /**
82 * Construct from a network address and a 16-byte CIDR netmask.
83 * Returns nullopt if netmask is not a valid contiguous CIDR prefix.
84 */
85 static std::optional<IPv6Subnet> from_address_and_mask(std::span<const uint8_t, 32> addr_and_mask);
86
87 /**
88 * Parse the CIDR-style form "2001:db8::/32".
89 *
90 * The "/N" suffix is required: bare addresses should be parsed via
91 * IPv6Address::from_string and wrapped with IPv6Subnet::host if needed.
92 *
93 * Returns nullopt on parse failure or out-of-range prefix length.
94 */
95 static std::optional<IPv6Subnet> from_string(std::string_view str);
96
97 /**
98 * A single-host subnet (prefix length 128) covering exactly @p address.
99 */
101
102 /// The network address (host bits already zeroed).
103 const IPv6Address& address() const { return m_address; }
104
105 /// Prefix length in [0, 128].
106 size_t prefix_length() const { return m_prefix_length; }
107
108 /// True iff prefix_length() == 128.
109 bool is_host() const { return m_prefix_length == 128; }
110
111 /// True iff @p ip falls within this subnet.
112 bool contains(const IPv6Address& ip) const;
113
114 /// CIDR-style "2001:db8::/32".
115 std::string to_string() const;
116
117 /**
118 * Bytes for use in a DER-encoded GeneralName iPAddress field:
119 * - 16 bytes (the address) if is_host(); the SAN form per RFC 5280 4.2.1.6.
120 * - 32 bytes (address || netmask) otherwise; the name constraint form
121 * per RFC 5280 4.2.1.10.
122 */
123 std::vector<uint8_t> serialize() const;
124
125 friend bool operator==(const IPv6Subnet&, const IPv6Subnet&) = default;
126
127 private:
128 IPv6Address m_address;
129 uint8_t m_prefix_length;
130};
131
132} // namespace Botan
133
134#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
static IPv6Address host_mask()
auto operator<=>(const IPv6Address &) const =default
IPv6Address(std::span< const uint8_t, 16 > ip)
static IPv6Address netmask(size_t bits)
IPv6Address(std::array< uint8_t, 16 > ip)
std::span< const uint8_t, 16 > address() const
friend bool operator==(const IPv6Subnet &, const IPv6Subnet &)=default
size_t prefix_length() const
Prefix length in [0, 128].
static std::optional< IPv6Subnet > from_address_and_mask(std::span< const uint8_t, 32 > addr_and_mask)
const IPv6Address & address() const
The network address (host bits already zeroed).
static std::optional< IPv6Subnet > from_string(std::string_view str)
IPv6Subnet(IPv6Address address, size_t prefix_length)
bool is_host() const
True iff prefix_length() == 128.
static IPv6Subnet host(IPv6Address address)
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13
ECIES_Flags operator&(ECIES_Flags a, ECIES_Flags b)
Definition ecies.h:70