include/boost/corosio/ipv6_address.hpp

100.0% Lines (7/7) 100.0% Functions (4/4)
include/boost/corosio/ipv6_address.hpp
Line Hits Source Code
1 //
2 // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_IPV6_ADDRESS_HPP
11 #define BOOST_COROSIO_IPV6_ADDRESS_HPP
12
13 #include <boost/corosio/detail/config.hpp>
14
15 #include <array>
16 #include <cstdint>
17 #include <iosfwd>
18 #include <string>
19 #include <string_view>
20 #include <system_error>
21
22 namespace boost::corosio {
23
24 class ipv4_address;
25
26 /** An IP version 6 style address.
27
28 Objects of this type are used to construct,
29 parse, and manipulate IP version 6 addresses.
30
31 @par BNF
32 @code
33 IPv6address = 6( h16 ":" ) ls32
34 / "::" 5( h16 ":" ) ls32
35 / [ h16 ] "::" 4( h16 ":" ) ls32
36 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
37 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
38 / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
39 / [ *4( h16 ":" ) h16 ] "::" ls32
40 / [ *5( h16 ":" ) h16 ] "::" h16
41 / [ *6( h16 ":" ) h16 ] "::"
42
43 ls32 = ( h16 ":" h16 ) / IPv4address
44 ; least-significant 32 bits of address
45
46 h16 = 1*4HEXDIG
47 ; 16 bits of address represented in hexadecimal
48 @endcode
49
50 @par Specification
51 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
52 >IP Version 6 Addressing Architecture (rfc4291)</a>
53 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
54 >3.2.2. Host (rfc3986)</a>
55
56 @see
57 @ref ipv4_address,
58 @ref parse_ipv6_address.
59 */
60 class BOOST_COROSIO_DECL ipv6_address
61 {
62 std::array<unsigned char, 16> addr_{};
63
64 public:
65 /** The number of characters in the longest possible IPv6 string.
66
67 The longest IPv6 address is:
68 @code
69 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
70 @endcode
71 or with IPv4-mapped:
72 @code
73 ::ffff:255.255.255.255
74 @endcode
75 */
76 static constexpr std::size_t max_str_len = 49;
77
78 /** The type used to represent an address as an array of bytes.
79
80 Octets are stored in network byte order.
81 */
82 using bytes_type = std::array<unsigned char, 16>;
83
84 /** Default constructor.
85
86 Constructs the unspecified address (::).
87
88 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2"
89 >2.5.2. The Unspecified Address</a>
90
91 @see
92 @ref is_unspecified
93 */
94 280251 ipv6_address() = default;
95
96 /** Copy constructor.
97 */
98 ipv6_address(ipv6_address const&) = default;
99
100 /** Copy assignment.
101
102 @return A reference to this object.
103 */
104 ipv6_address& operator=(ipv6_address const&) = default;
105
106 /** Construct from an array of bytes.
107
108 This function constructs an address
109 from the array in `bytes`, which is
110 interpreted in big-endian.
111
112 @param bytes The value to construct from.
113 */
114 explicit ipv6_address(bytes_type const& bytes) noexcept;
115
116 /** Construct from an IPv4 address.
117
118 This function constructs an IPv6 address
119 from the IPv4 address `addr`. The resulting
120 address is an IPv4-Mapped IPv6 Address.
121
122 @param addr The address to construct from.
123
124 @par Specification
125 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2"
126 >2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
127 */
128 explicit ipv6_address(ipv4_address const& addr) noexcept;
129
130 /** Construct from a string.
131
132 This function constructs an address from
133 the string `s`, which must contain a valid
134 IPv6 address string or else an exception
135 is thrown.
136
137 @note For a non-throwing parse function,
138 use @ref parse_ipv6_address.
139
140 @par Exception Safety
141 Exceptions thrown on invalid input.
142
143 @throw std::invalid_argument
144 The input failed to parse correctly.
145
146 @param s The string to parse.
147
148 @par Specification
149 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
150 >3.2.2. Host (rfc3986)</a>
151
152 @see
153 @ref parse_ipv6_address.
154 */
155 explicit ipv6_address(std::string_view s);
156
157 /** Return the address as bytes, in network byte order.
158
159 @return The address as an array of bytes.
160 */
161 2 bytes_type to_bytes() const noexcept
162 {
163 2 return addr_;
164 }
165
166 /** Return the address as a string.
167
168 The returned string does not
169 contain surrounding square brackets.
170
171 @par Example
172 @code
173 ipv6_address::bytes_type b = {{
174 0, 1, 0, 2, 0, 3, 0, 4,
175 0, 5, 0, 6, 0, 7, 0, 8 }};
176 ipv6_address a(b);
177 assert(a.to_string() == "1:2:3:4:5:6:7:8");
178 @endcode
179
180 @return The address as a string.
181
182 @par Specification
183 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
184 2.2. Text Representation of Addresses (rfc4291)</a>
185 */
186 std::string to_string() const;
187
188 /** Write a string representing the address to a buffer.
189
190 The resulting buffer is not null-terminated.
191
192 @throw std::length_error `dest_size < ipv6_address::max_str_len`
193
194 @return The formatted string view.
195
196 @param dest The buffer in which to write,
197 which must have at least `dest_size` space.
198
199 @param dest_size The size of the output buffer.
200 */
201 std::string_view to_buffer(char* dest, std::size_t dest_size) const;
202
203 /** Return true if the address is unspecified.
204
205 The address 0:0:0:0:0:0:0:0 is called the
206 unspecified address. It indicates the
207 absence of an address.
208
209 @return `true` if the address is unspecified.
210
211 @par Specification
212 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
213 2.5.2. The Unspecified Address (rfc4291)</a>
214 */
215 bool is_unspecified() const noexcept;
216
217 /** Return true if the address is a loopback address.
218
219 The unicast address 0:0:0:0:0:0:0:1 is called
220 the loopback address. It may be used by a node
221 to send an IPv6 packet to itself.
222
223 @return `true` if the address is a loopback address.
224
225 @par Specification
226 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
227 2.5.3. The Loopback Address (rfc4291)</a>
228 */
229 bool is_loopback() const noexcept;
230
231 /** Return true if the address is a mapped IPv4 address.
232
233 This address type is used to represent the
234 addresses of IPv4 nodes as IPv6 addresses.
235
236 @return `true` if the address is a mapped IPv4 address.
237
238 @par Specification
239 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
240 2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
241 */
242 bool is_v4_mapped() const noexcept;
243
244 /** Return true if two addresses are equal.
245
246 @return `true` if the addresses are equal.
247 */
248 friend bool
249 16 operator==(ipv6_address const& a1, ipv6_address const& a2) noexcept
250 {
251 16 return a1.addr_ == a2.addr_;
252 }
253
254 /** Return true if two addresses are not equal.
255
256 @return `true` if the addresses are not equal.
257 */
258 friend bool
259 2 operator!=(ipv6_address const& a1, ipv6_address const& a2) noexcept
260 {
261 2 return a1.addr_ != a2.addr_;
262 }
263
264 /** Return an address object that represents the loopback address.
265
266 The unicast address 0:0:0:0:0:0:0:1 is called
267 the loopback address. It may be used by a node
268 to send an IPv6 packet to itself.
269
270 @par Specification
271 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
272 2.5.3. The Loopback Address (rfc4291)</a>
273
274 @return The loopback address (::1).
275 */
276 static ipv6_address loopback() noexcept;
277
278 /** Format the address to an output stream.
279
280 This function writes the address to an
281 output stream using standard notation.
282
283 @return The output stream, for chaining.
284
285 @param os The output stream to write to.
286
287 @param addr The address to write.
288 */
289 friend BOOST_COROSIO_DECL std::ostream&
290 operator<<(std::ostream& os, ipv6_address const& addr);
291
292 private:
293 std::size_t print_impl(char* dest) const noexcept;
294 };
295
296
297 /** Parse a string containing an IPv6 address.
298
299 This function attempts to parse the string
300 as an IPv6 address and returns an error code
301 if the string does not contain a valid IPv6 address.
302
303 @par Exception Safety
304 Throws nothing.
305
306 @return An error code (empty on success).
307
308 @param s The string to parse.
309 @param addr The address to store the result.
310 */
311 [[nodiscard]] BOOST_COROSIO_DECL std::error_code
312 parse_ipv6_address(std::string_view s, ipv6_address& addr) noexcept;
313
314 } // namespace boost::corosio
315
316 #endif
317