1//
2// ip/address_v6.hpp
3// ~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_IP_ADDRESS_V6_HPP
12#define BOOST_ASIO_IP_ADDRESS_V6_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19#include <functional>
20#include <string>
21#include <boost/asio/detail/array.hpp>
22#include <boost/asio/detail/cstdint.hpp>
23#include <boost/asio/detail/socket_types.hpp>
24#include <boost/asio/detail/string_view.hpp>
25#include <boost/asio/detail/winsock_init.hpp>
26#include <boost/system/error_code.hpp>
27#include <boost/asio/ip/address_v4.hpp>
28
29#if !defined(BOOST_ASIO_NO_IOSTREAM)
30# include <iosfwd>
31#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
32
33#include <boost/asio/detail/push_options.hpp>
34
35namespace boost {
36namespace asio {
37namespace ip {
38
39template <typename> class basic_address_iterator;
40
41/// Type used for storing IPv6 scope IDs.
42typedef uint_least32_t scope_id_type;
43
44/// Implements IP version 6 style addresses.
45/**
46 * The boost::asio::ip::address_v6 class provides the ability to use and
47 * manipulate IP version 6 addresses.
48 *
49 * @par Thread Safety
50 * @e Distinct @e objects: Safe.@n
51 * @e Shared @e objects: Unsafe.
52 */
53class address_v6
54{
55public:
56 /// The type used to represent an address as an array of bytes.
57 /**
58 * @note This type is defined in terms of the C++0x template @c std::array
59 * when it is available. Otherwise, it uses @c boost:array.
60 */
61#if defined(GENERATING_DOCUMENTATION)
62 typedef array<unsigned char, 16> bytes_type;
63#else
64 typedef boost::asio::detail::array<unsigned char, 16> bytes_type;
65#endif
66
67 /// Default constructor.
68 /**
69 * Initialises the @c address_v6 object such that:
70 * @li <tt>to_bytes()</tt> yields <tt>{0, 0, ..., 0}</tt>; and
71 * @li <tt>scope_id() == 0</tt>.
72 */
73 BOOST_ASIO_DECL address_v6() noexcept;
74
75 /// Construct an address from raw bytes and scope ID.
76 /**
77 * Initialises the @c address_v6 object such that:
78 * @li <tt>to_bytes() == bytes</tt>; and
79 * @li <tt>this->scope_id() == scope_id</tt>.
80 *
81 * @throws out_of_range Thrown if any element in @c bytes is not in the range
82 * <tt>0 - 0xFF</tt>. Note that no range checking is required for platforms
83 * where <tt>std::numeric_limits<unsigned char>::max()</tt> is <tt>0xFF</tt>.
84 */
85 BOOST_ASIO_DECL explicit address_v6(const bytes_type& bytes,
86 scope_id_type scope_id = 0);
87
88 /// Copy constructor.
89 BOOST_ASIO_DECL address_v6(const address_v6& other) noexcept;
90
91 /// Move constructor.
92 BOOST_ASIO_DECL address_v6(address_v6&& other) noexcept;
93
94 /// Assign from another address.
95 BOOST_ASIO_DECL address_v6& operator=(
96 const address_v6& other) noexcept;
97
98 /// Move-assign from another address.
99 BOOST_ASIO_DECL address_v6& operator=(address_v6&& other) noexcept;
100
101 /// The scope ID of the address.
102 /**
103 * Returns the scope ID associated with the IPv6 address.
104 */
105 scope_id_type scope_id() const noexcept
106 {
107 return scope_id_;
108 }
109
110 /// The scope ID of the address.
111 /**
112 * Modifies the scope ID associated with the IPv6 address.
113 *
114 * @param id The new scope ID.
115 */
116 void scope_id(scope_id_type id) noexcept
117 {
118 scope_id_ = id;
119 }
120
121 /// Get the address in bytes, in network byte order.
122 BOOST_ASIO_DECL bytes_type to_bytes() const noexcept;
123
124 /// Get the address as a string.
125 BOOST_ASIO_DECL std::string to_string() const;
126
127#if !defined(BOOST_ASIO_NO_DEPRECATED)
128 /// (Deprecated: Use other overload.) Get the address as a string.
129 BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const;
130
131 /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
132 /// address string.
133 static address_v6 from_string(const char* str);
134
135 /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
136 /// address string.
137 static address_v6 from_string(
138 const char* str, boost::system::error_code& ec);
139
140 /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
141 /// address string.
142 static address_v6 from_string(const std::string& str);
143
144 /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP
145 /// address string.
146 static address_v6 from_string(
147 const std::string& str, boost::system::error_code& ec);
148
149 /// (Deprecated: Use make_address_v4().) Converts an IPv4-mapped or
150 /// IPv4-compatible address to an IPv4 address.
151 BOOST_ASIO_DECL address_v4 to_v4() const;
152#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
153
154 /// Determine whether the address is a loopback address.
155 /**
156 * This function tests whether the address is the loopback address
157 * <tt>::1</tt>.
158 */
159 BOOST_ASIO_DECL bool is_loopback() const noexcept;
160
161 /// Determine whether the address is unspecified.
162 /**
163 * This function tests whether the address is the loopback address
164 * <tt>::</tt>.
165 */
166 BOOST_ASIO_DECL bool is_unspecified() const noexcept;
167
168 /// Determine whether the address is link local.
169 BOOST_ASIO_DECL bool is_link_local() const noexcept;
170
171 /// Determine whether the address is site local.
172 BOOST_ASIO_DECL bool is_site_local() const noexcept;
173
174 /// Determine whether the address is a mapped IPv4 address.
175 BOOST_ASIO_DECL bool is_v4_mapped() const noexcept;
176
177#if !defined(BOOST_ASIO_NO_DEPRECATED)
178 /// (Deprecated: No replacement.) Determine whether the address is an
179 /// IPv4-compatible address.
180 BOOST_ASIO_DECL bool is_v4_compatible() const;
181#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
182
183 /// Determine whether the address is a multicast address.
184 BOOST_ASIO_DECL bool is_multicast() const noexcept;
185
186 /// Determine whether the address is a global multicast address.
187 BOOST_ASIO_DECL bool is_multicast_global() const noexcept;
188
189 /// Determine whether the address is a link-local multicast address.
190 BOOST_ASIO_DECL bool is_multicast_link_local() const noexcept;
191
192 /// Determine whether the address is a node-local multicast address.
193 BOOST_ASIO_DECL bool is_multicast_node_local() const noexcept;
194
195 /// Determine whether the address is a org-local multicast address.
196 BOOST_ASIO_DECL bool is_multicast_org_local() const noexcept;
197
198 /// Determine whether the address is a site-local multicast address.
199 BOOST_ASIO_DECL bool is_multicast_site_local() const noexcept;
200
201 /// Compare two addresses for equality.
202 BOOST_ASIO_DECL friend bool operator==(const address_v6& a1,
203 const address_v6& a2) noexcept;
204
205 /// Compare two addresses for inequality.
206 friend bool operator!=(const address_v6& a1,
207 const address_v6& a2) noexcept
208 {
209 return !(a1 == a2);
210 }
211
212 /// Compare addresses for ordering.
213 BOOST_ASIO_DECL friend bool operator<(const address_v6& a1,
214 const address_v6& a2) noexcept;
215
216 /// Compare addresses for ordering.
217 friend bool operator>(const address_v6& a1,
218 const address_v6& a2) noexcept
219 {
220 return a2 < a1;
221 }
222
223 /// Compare addresses for ordering.
224 friend bool operator<=(const address_v6& a1,
225 const address_v6& a2) noexcept
226 {
227 return !(a2 < a1);
228 }
229
230 /// Compare addresses for ordering.
231 friend bool operator>=(const address_v6& a1,
232 const address_v6& a2) noexcept
233 {
234 return !(a1 < a2);
235 }
236
237 /// Obtain an address object that represents any address.
238 /**
239 * This functions returns an address that represents the "any" address
240 * <tt>::</tt>.
241 *
242 * @returns A default-constructed @c address_v6 object.
243 */
244 static address_v6 any() noexcept
245 {
246 return address_v6();
247 }
248
249 /// Obtain an address object that represents the loopback address.
250 /**
251 * This function returns an address that represents the well-known loopback
252 * address <tt>::1</tt>.
253 */
254 BOOST_ASIO_DECL static address_v6 loopback() noexcept;
255
256#if !defined(BOOST_ASIO_NO_DEPRECATED)
257 /// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address.
258 BOOST_ASIO_DECL static address_v6 v4_mapped(const address_v4& addr);
259
260 /// (Deprecated: No replacement.) Create an IPv4-compatible IPv6 address.
261 BOOST_ASIO_DECL static address_v6 v4_compatible(const address_v4& addr);
262#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
263
264private:
265 friend class basic_address_iterator<address_v6>;
266
267 // The underlying IPv6 address.
268 boost::asio::detail::in6_addr_type addr_;
269
270 // The scope ID associated with the address.
271 scope_id_type scope_id_;
272};
273
274/// Create an IPv6 address from raw bytes and scope ID.
275/**
276 * @relates address_v6
277 */
278inline address_v6 make_address_v6(const address_v6::bytes_type& bytes,
279 scope_id_type scope_id = 0)
280{
281 return address_v6(bytes, scope_id);
282}
283
284/// Create an IPv6 address from an IP address string.
285/**
286 * @relates address_v6
287 */
288BOOST_ASIO_DECL address_v6 make_address_v6(const char* str);
289
290/// Create an IPv6 address from an IP address string.
291/**
292 * @relates address_v6
293 */
294BOOST_ASIO_DECL address_v6 make_address_v6(const char* str,
295 boost::system::error_code& ec) noexcept;
296
297/// Createan IPv6 address from an IP address string.
298/**
299 * @relates address_v6
300 */
301BOOST_ASIO_DECL address_v6 make_address_v6(const std::string& str);
302
303/// Create an IPv6 address from an IP address string.
304/**
305 * @relates address_v6
306 */
307BOOST_ASIO_DECL address_v6 make_address_v6(const std::string& str,
308 boost::system::error_code& ec) noexcept;
309
310#if defined(BOOST_ASIO_HAS_STRING_VIEW) \
311 || defined(GENERATING_DOCUMENTATION)
312
313/// Create an IPv6 address from an IP address string.
314/**
315 * @relates address_v6
316 */
317BOOST_ASIO_DECL address_v6 make_address_v6(string_view str);
318
319/// Create an IPv6 address from an IP address string.
320/**
321 * @relates address_v6
322 */
323BOOST_ASIO_DECL address_v6 make_address_v6(string_view str,
324 boost::system::error_code& ec) noexcept;
325
326#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
327 // || defined(GENERATING_DOCUMENTATION)
328
329/// Tag type used for distinguishing overloads that deal in IPv4-mapped IPv6
330/// addresses.
331enum v4_mapped_t { v4_mapped };
332
333/// Create an IPv4 address from a IPv4-mapped IPv6 address.
334/**
335 * @relates address_v4
336 */
337BOOST_ASIO_DECL address_v4 make_address_v4(
338 v4_mapped_t, const address_v6& v6_addr);
339
340/// Create an IPv4-mapped IPv6 address from an IPv4 address.
341/**
342 * @relates address_v6
343 */
344BOOST_ASIO_DECL address_v6 make_address_v6(
345 v4_mapped_t, const address_v4& v4_addr);
346
347#if !defined(BOOST_ASIO_NO_IOSTREAM)
348
349/// Output an address as a string.
350/**
351 * Used to output a human-readable string for a specified address.
352 *
353 * @param os The output stream to which the string will be written.
354 *
355 * @param addr The address to be written.
356 *
357 * @return The output stream.
358 *
359 * @relates boost::asio::ip::address_v6
360 */
361template <typename Elem, typename Traits>
362std::basic_ostream<Elem, Traits>& operator<<(
363 std::basic_ostream<Elem, Traits>& os, const address_v6& addr);
364
365#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
366
367} // namespace ip
368} // namespace asio
369} // namespace boost
370
371namespace std {
372
373template <>
374struct hash<boost::asio::ip::address_v6>
375{
376 std::size_t operator()(const boost::asio::ip::address_v6& addr)
377 const noexcept
378 {
379 const boost::asio::ip::address_v6::bytes_type bytes = addr.to_bytes();
380 std::size_t result = static_cast<std::size_t>(addr.scope_id());
381 combine_4_bytes(seed&: result, bytes: &bytes[0]);
382 combine_4_bytes(seed&: result, bytes: &bytes[4]);
383 combine_4_bytes(seed&: result, bytes: &bytes[8]);
384 combine_4_bytes(seed&: result, bytes: &bytes[12]);
385 return result;
386 }
387
388private:
389 static void combine_4_bytes(std::size_t& seed, const unsigned char* bytes)
390 {
391 const std::size_t bytes_hash =
392 (static_cast<std::size_t>(bytes[0]) << 24) |
393 (static_cast<std::size_t>(bytes[1]) << 16) |
394 (static_cast<std::size_t>(bytes[2]) << 8) |
395 (static_cast<std::size_t>(bytes[3]));
396 seed ^= bytes_hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
397 }
398};
399
400} // namespace std
401
402#include <boost/asio/detail/pop_options.hpp>
403
404#include <boost/asio/ip/impl/address_v6.hpp>
405#if defined(BOOST_ASIO_HEADER_ONLY)
406# include <boost/asio/ip/impl/address_v6.ipp>
407#endif // defined(BOOST_ASIO_HEADER_ONLY)
408
409#endif // BOOST_ASIO_IP_ADDRESS_V6_HPP
410

source code of boost/libs/asio/include/boost/asio/ip/address_v6.hpp