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