include/boost/corosio/ipv6_address.hpp

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