Botan 3.12.0
Crypto and TLS for C&
ipv4_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_IPV4_ADDRESS_H_
8#define BOTAN_IPV4_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
20/**
21* IPv4 Address
22*/
23class BOTAN_PUBLIC_API(3, 12) IPv4Address final {
24 public:
25 explicit IPv4Address(uint32_t ip) : m_ip(ip) {}
26
27 static std::optional<IPv4Address> from_string(std::string_view str);
28
29 /**
30 * Return an address with the leading @p bits set to one and the remainder
31 * zero. Throws Invalid_Argument if @p bits > 32.
32 */
33 static IPv4Address netmask(size_t bits);
34
35 static IPv4Address host_mask() { return netmask(32); }
36
37 IPv4Address operator&(const IPv4Address& other) const { return IPv4Address(m_ip & other.m_ip); }
38
39 auto operator<=>(const IPv4Address&) const = default;
40
41 /// The address as a 32-bit big-endian integer
42 uint32_t value() const { return m_ip; }
43
44 /// The address as four bytes, network-byte-order.
45 std::array<uint8_t, 4> to_bytes() const;
46
47 /// Dotted-decimal form, e.g. "10.0.0.1".
48 std::string to_string() const;
49
50 /**
51 * If this value is a netmask consisting of a run of one bits followed by
52 * a run of zero bits, return the number of one bits.
53 *
54 * Otherwise return nullopt.
55 */
56 std::optional<size_t> prefix_length() const;
57
58 private:
59 uint32_t m_ip;
60};
61
62/**
63* An IPv4 subnet in CIDR form: a network address paired with a prefix length
64*/
65class BOTAN_PUBLIC_API(3, 12) IPv4Subnet final {
66 public:
67 /**
68 * Construct from a network address and a prefix length in [0, 32].
69 * Host bits of @p address are cleared.
70 *
71 * Throws Invalid_Argument if @p prefix_length > 32.
72 */
74
75 /**
76 * Construct from a network address and a netmask (4 bytes each)
77 * Returns nullopt if netmask is not a valid contiguous CIDR prefix.
78 */
79 static std::optional<IPv4Subnet> from_address_and_mask(std::span<const uint8_t, 8> addr_and_mask);
80
81 /**
82 * Construct from a network address and a netmask (4 bytes each)
83 * Returns nullopt if netmask is not a valid contiguous CIDR prefix.
84 */
85 static std::optional<IPv4Subnet> from_address_and_mask(uint32_t addr, uint32_t mask);
86
87 /**
88 * Parse CIDR-style form "10.0.0.0/8".
89 *
90 * The "/N" suffix is required: bare addresses should be parsed via
91 * IPv4Address::from_string and wrapped with IPv4Subnet::host if needed.
92 *
93 * Returns nullopt on parse failure or out-of-range prefix length.
94 */
95 static std::optional<IPv4Subnet> from_string(std::string_view str);
96
97 /**
98 * A single-host subnet (prefix length 32) covering exactly @p address.
99 */
101
102 /// The network address (host bits already zeroed).
103 const IPv4Address& address() const { return m_address; }
104
105 /// Prefix length in [0, 32].
106 size_t prefix_length() const { return m_prefix_length; }
107
108 /// True iff prefix_length() == 32.
109 bool is_host() const { return m_prefix_length == 32; }
110
111 /// True iff @p ip falls within this subnet.
112 bool contains(const IPv4Address& ip) const;
113
114 /// CIDR-style "10.0.0.0/8".
115 std::string to_string() const;
116
117 /**
118 * Bytes for use in a DER-encoded GeneralName iPAddress field:
119 * - 4 bytes (the address) if is_host() — SAN form per RFC 5280 4.2.1.6.
120 * - 8 bytes (address || netmask) otherwise — name constraint form per RFC 5280 4.2.1.10.
121 */
122 std::vector<uint8_t> serialize() const;
123
124 friend bool operator==(const IPv4Subnet&, const IPv4Subnet&) = default;
125
126 private:
127 IPv4Address m_address;
128 uint8_t m_prefix_length;
129};
130
131} // namespace Botan
132
133#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
IPv4Address operator&(const IPv4Address &other) const
auto operator<=>(const IPv4Address &) const =default
uint32_t value() const
The address as a 32-bit big-endian integer.
static IPv4Address host_mask()
IPv4Address(uint32_t ip)
static IPv4Address netmask(size_t bits)
static std::optional< IPv4Subnet > from_address_and_mask(std::span< const uint8_t, 8 > addr_and_mask)
bool is_host() const
True iff prefix_length() == 32.
friend bool operator==(const IPv4Subnet &, const IPv4Subnet &)=default
IPv4Subnet(IPv4Address address, size_t prefix_length)
size_t prefix_length() const
Prefix length in [0, 32].
static IPv4Subnet host(IPv4Address address)
static std::optional< IPv4Subnet > from_string(std::string_view str)
const IPv4Address & address() const
The network address (host bits already zeroed).
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13