include/boost/corosio/ipv6_address.hpp

100.0% Lines (9/9) 100.0% List of functions (5/5)
f(x) Functions (5)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Vinnie Falco ([email protected])
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 332513x 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 34x bytes_type to_bytes() const noexcept
161 {
162 34x 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 the address is a multicast address.
244
245 IPv6 multicast addresses have the prefix ff00::/8.
246
247 @return `true` if the address is a multicast address.
248
249 @par Specification
250 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.7">
251 2.7. Multicast Addresses (rfc4291)</a>
252 */
253 bool is_multicast() const noexcept;
254
255 /** Return true if two addresses are equal.
256
257 @return `true` if the addresses are equal.
258 */
259 friend bool
260 17x operator==(ipv6_address const& a1, ipv6_address const& a2) noexcept
261 {
262 17x return a1.addr_ == a2.addr_;
263 }
264
265 /** Return true if two addresses are not equal.
266
267 @return `true` if the addresses are not equal.
268 */
269 friend bool
270 2x operator!=(ipv6_address const& a1, ipv6_address const& a2) noexcept
271 {
272 2x return a1.addr_ != a2.addr_;
273 }
274
275 /** Return an address object that represents the unspecified address.
276
277 The address 0:0:0:0:0:0:0:0 (::) may be used to bind a socket
278 to all available interfaces.
279
280 @return The unspecified address (::).
281 */
282 6x static ipv6_address any() noexcept
283 {
284 6x return ipv6_address();
285 }
286
287 /** Return an address object that represents the loopback address.
288
289 The unicast address 0:0:0:0:0:0:0:1 is called
290 the loopback address. It may be used by a node
291 to send an IPv6 packet to itself.
292
293 @par Specification
294 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
295 2.5.3. The Loopback Address (rfc4291)</a>
296
297 @return The loopback address (::1).
298 */
299 static ipv6_address loopback() noexcept;
300
301 /** Format the address to an output stream.
302
303 This function writes the address to an
304 output stream using standard notation.
305
306 @return The output stream, for chaining.
307
308 @param os The output stream to write to.
309
310 @param addr The address to write.
311 */
312 friend BOOST_COROSIO_DECL std::ostream&
313 operator<<(std::ostream& os, ipv6_address const& addr);
314
315 private:
316 std::size_t print_impl(char* dest) const noexcept;
317 };
318
319 /** Parse a string containing an IPv6 address.
320
321 This function attempts to parse the string
322 as an IPv6 address and returns an error code
323 if the string does not contain a valid IPv6 address.
324
325 @par Exception Safety
326 Throws nothing.
327
328 @return An error code (empty on success).
329
330 @param s The string to parse.
331 @param addr The address to store the result.
332 */
333 [[nodiscard]] BOOST_COROSIO_DECL std::error_code
334 parse_ipv6_address(std::string_view s, ipv6_address& addr) noexcept;
335
336 } // namespace boost::corosio
337
338 #endif
339