1 | // |
2 | // ip/address_v4.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_V4_HPP |
12 | #define BOOST_ASIO_IP_ADDRESS_V4_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 | |
28 | #if !defined(BOOST_ASIO_NO_IOSTREAM) |
29 | # include <iosfwd> |
30 | #endif // !defined(BOOST_ASIO_NO_IOSTREAM) |
31 | |
32 | #include <boost/asio/detail/push_options.hpp> |
33 | |
34 | namespace boost { |
35 | namespace asio { |
36 | namespace ip { |
37 | |
38 | /// Implements IP version 4 style addresses. |
39 | /** |
40 | * The boost::asio::ip::address_v4 class provides the ability to use and |
41 | * manipulate IP version 4 addresses. |
42 | * |
43 | * @par Thread Safety |
44 | * @e Distinct @e objects: Safe.@n |
45 | * @e Shared @e objects: Unsafe. |
46 | */ |
47 | class address_v4 |
48 | { |
49 | public: |
50 | /// The type used to represent an address as an unsigned integer. |
51 | typedef uint_least32_t uint_type; |
52 | |
53 | /// The type used to represent an address as an array of bytes. |
54 | /** |
55 | * @note This type is defined in terms of the C++0x template @c std::array |
56 | * when it is available. Otherwise, it uses @c boost:array. |
57 | */ |
58 | #if defined(GENERATING_DOCUMENTATION) |
59 | typedef array<unsigned char, 4> bytes_type; |
60 | #else |
61 | typedef boost::asio::detail::array<unsigned char, 4> bytes_type; |
62 | #endif |
63 | |
64 | /// Default constructor. |
65 | /** |
66 | * Initialises the @c address_v4 object such that: |
67 | * @li <tt>to_bytes()</tt> yields <tt>{0, 0, 0, 0}</tt>; and |
68 | * @li <tt>to_uint() == 0</tt>. |
69 | */ |
70 | address_v4() noexcept |
71 | { |
72 | addr_.s_addr = 0; |
73 | } |
74 | |
75 | /// Construct an address from raw bytes. |
76 | /** |
77 | * Initialises the @c address_v4 object such that <tt>to_bytes() == |
78 | * bytes</tt>. |
79 | * |
80 | * @throws out_of_range Thrown if any element in @c bytes is not in the range |
81 | * <tt>0 - 0xFF</tt>. Note that no range checking is required for platforms |
82 | * where <tt>std::numeric_limits<unsigned char>::max()</tt> is <tt>0xFF</tt>. |
83 | */ |
84 | BOOST_ASIO_DECL explicit address_v4(const bytes_type& bytes); |
85 | |
86 | /// Construct an address from an unsigned integer in host byte order. |
87 | /** |
88 | * Initialises the @c address_v4 object such that <tt>to_uint() == addr</tt>. |
89 | */ |
90 | BOOST_ASIO_DECL explicit address_v4(uint_type addr); |
91 | |
92 | /// Copy constructor. |
93 | address_v4(const address_v4& other) noexcept |
94 | : addr_(other.addr_) |
95 | { |
96 | } |
97 | |
98 | /// Move constructor. |
99 | address_v4(address_v4&& other) noexcept |
100 | : addr_(other.addr_) |
101 | { |
102 | } |
103 | |
104 | /// Assign from another address. |
105 | address_v4& operator=(const address_v4& other) noexcept |
106 | { |
107 | addr_ = other.addr_; |
108 | return *this; |
109 | } |
110 | |
111 | /// Move-assign from another address. |
112 | address_v4& operator=(address_v4&& other) noexcept |
113 | { |
114 | addr_ = other.addr_; |
115 | return *this; |
116 | } |
117 | |
118 | /// Get the address in bytes, in network byte order. |
119 | BOOST_ASIO_DECL bytes_type to_bytes() const noexcept; |
120 | |
121 | /// Get the address as an unsigned integer in host byte order. |
122 | BOOST_ASIO_DECL uint_type to_uint() const noexcept; |
123 | |
124 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
125 | /// (Deprecated: Use to_uint().) Get the address as an unsigned long in host |
126 | /// byte order. |
127 | BOOST_ASIO_DECL unsigned long to_ulong() const; |
128 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
129 | |
130 | /// Get the address as a string in dotted decimal format. |
131 | BOOST_ASIO_DECL std::string to_string() const; |
132 | |
133 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
134 | /// (Deprecated: Use other overload.) Get the address as a string in dotted |
135 | /// decimal format. |
136 | BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const; |
137 | |
138 | /// (Deprecated: Use make_address_v4().) Create an address from an IP address |
139 | /// string in dotted decimal form. |
140 | static address_v4 from_string(const char* str); |
141 | |
142 | /// (Deprecated: Use make_address_v4().) Create an address from an IP address |
143 | /// string in dotted decimal form. |
144 | static address_v4 from_string( |
145 | const char* str, boost::system::error_code& ec); |
146 | |
147 | /// (Deprecated: Use make_address_v4().) Create an address from an IP address |
148 | /// string in dotted decimal form. |
149 | static address_v4 from_string(const std::string& str); |
150 | |
151 | /// (Deprecated: Use make_address_v4().) Create an address from an IP address |
152 | /// string in dotted decimal form. |
153 | static address_v4 from_string( |
154 | const std::string& str, boost::system::error_code& ec); |
155 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
156 | |
157 | /// Determine whether the address is a loopback address. |
158 | /** |
159 | * This function tests whether the address is in the address block |
160 | * <tt>127.0.0.0/8</tt>, which corresponds to the address range |
161 | * <tt>127.0.0.0 - 127.255.255.255</tt>. |
162 | * |
163 | * @returns <tt>(to_uint() & 0xFF000000) == 0x7F000000</tt>. |
164 | */ |
165 | BOOST_ASIO_DECL bool is_loopback() const noexcept; |
166 | |
167 | /// Determine whether the address is unspecified. |
168 | /** |
169 | * This function tests whether the address is the unspecified address |
170 | * <tt>0.0.0.0</tt>. |
171 | * |
172 | * @returns <tt>to_uint() == 0</tt>. |
173 | */ |
174 | BOOST_ASIO_DECL bool is_unspecified() const noexcept; |
175 | |
176 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
177 | /// (Deprecated: Use network_v4 class.) Determine whether the address is a |
178 | /// class A address. |
179 | BOOST_ASIO_DECL bool is_class_a() const; |
180 | |
181 | /// (Deprecated: Use network_v4 class.) Determine whether the address is a |
182 | /// class B address. |
183 | BOOST_ASIO_DECL bool is_class_b() const; |
184 | |
185 | /// (Deprecated: Use network_v4 class.) Determine whether the address is a |
186 | /// class C address. |
187 | BOOST_ASIO_DECL bool is_class_c() const; |
188 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
189 | |
190 | /// Determine whether the address is a multicast address. |
191 | /** |
192 | * This function tests whether the address is in the multicast address block |
193 | * <tt>224.0.0.0/4</tt>, which corresponds to the address range |
194 | * <tt>224.0.0.0 - 239.255.255.255</tt>. |
195 | * |
196 | * @returns <tt>(to_uint() & 0xF0000000) == 0xE0000000</tt>. |
197 | */ |
198 | BOOST_ASIO_DECL bool is_multicast() const noexcept; |
199 | |
200 | /// Compare two addresses for equality. |
201 | friend bool operator==(const address_v4& a1, |
202 | const address_v4& a2) noexcept |
203 | { |
204 | return a1.addr_.s_addr == a2.addr_.s_addr; |
205 | } |
206 | |
207 | /// Compare two addresses for inequality. |
208 | friend bool operator!=(const address_v4& a1, |
209 | const address_v4& a2) noexcept |
210 | { |
211 | return a1.addr_.s_addr != a2.addr_.s_addr; |
212 | } |
213 | |
214 | /// Compare addresses for ordering. |
215 | /** |
216 | * Compares two addresses in host byte order. |
217 | * |
218 | * @returns <tt>a1.to_uint() < a2.to_uint()</tt>. |
219 | */ |
220 | friend bool operator<(const address_v4& a1, |
221 | const address_v4& a2) noexcept |
222 | { |
223 | return a1.to_uint() < a2.to_uint(); |
224 | } |
225 | |
226 | /// Compare addresses for ordering. |
227 | /** |
228 | * Compares two addresses in host byte order. |
229 | * |
230 | * @returns <tt>a1.to_uint() > a2.to_uint()</tt>. |
231 | */ |
232 | friend bool operator>(const address_v4& a1, |
233 | const address_v4& a2) noexcept |
234 | { |
235 | return a1.to_uint() > a2.to_uint(); |
236 | } |
237 | |
238 | /// Compare addresses for ordering. |
239 | /** |
240 | * Compares two addresses in host byte order. |
241 | * |
242 | * @returns <tt>a1.to_uint() <= a2.to_uint()</tt>. |
243 | */ |
244 | friend bool operator<=(const address_v4& a1, |
245 | const address_v4& a2) noexcept |
246 | { |
247 | return a1.to_uint() <= a2.to_uint(); |
248 | } |
249 | |
250 | /// Compare addresses for ordering. |
251 | /** |
252 | * Compares two addresses in host byte order. |
253 | * |
254 | * @returns <tt>a1.to_uint() >= a2.to_uint()</tt>. |
255 | */ |
256 | friend bool operator>=(const address_v4& a1, |
257 | const address_v4& a2) noexcept |
258 | { |
259 | return a1.to_uint() >= a2.to_uint(); |
260 | } |
261 | |
262 | /// Obtain an address object that represents any address. |
263 | /** |
264 | * This functions returns an address that represents the "any" address |
265 | * <tt>0.0.0.0</tt>. |
266 | * |
267 | * @returns A default-constructed @c address_v4 object. |
268 | */ |
269 | static address_v4 any() noexcept |
270 | { |
271 | return address_v4(); |
272 | } |
273 | |
274 | /// Obtain an address object that represents the loopback address. |
275 | /** |
276 | * This function returns an address that represents the well-known loopback |
277 | * address <tt>127.0.0.1</tt>. |
278 | * |
279 | * @returns <tt>address_v4(0x7F000001)</tt>. |
280 | */ |
281 | static address_v4 loopback() noexcept |
282 | { |
283 | return address_v4(0x7F000001); |
284 | } |
285 | |
286 | /// Obtain an address object that represents the broadcast address. |
287 | /** |
288 | * This function returns an address that represents the broadcast address |
289 | * <tt>255.255.255.255</tt>. |
290 | * |
291 | * @returns <tt>address_v4(0xFFFFFFFF)</tt>. |
292 | */ |
293 | static address_v4 broadcast() noexcept |
294 | { |
295 | return address_v4(0xFFFFFFFF); |
296 | } |
297 | |
298 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
299 | /// (Deprecated: Use network_v4 class.) Obtain an address object that |
300 | /// represents the broadcast address that corresponds to the specified |
301 | /// address and netmask. |
302 | BOOST_ASIO_DECL static address_v4 broadcast( |
303 | const address_v4& addr, const address_v4& mask); |
304 | |
305 | /// (Deprecated: Use network_v4 class.) Obtain the netmask that corresponds |
306 | /// to the address, based on its address class. |
307 | BOOST_ASIO_DECL static address_v4 netmask(const address_v4& addr); |
308 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
309 | |
310 | private: |
311 | // The underlying IPv4 address. |
312 | boost::asio::detail::in4_addr_type addr_; |
313 | }; |
314 | |
315 | /// Create an IPv4 address from raw bytes in network order. |
316 | /** |
317 | * @relates address_v4 |
318 | */ |
319 | inline address_v4 make_address_v4(const address_v4::bytes_type& bytes) |
320 | { |
321 | return address_v4(bytes); |
322 | } |
323 | |
324 | /// Create an IPv4 address from an unsigned integer in host byte order. |
325 | /** |
326 | * @relates address_v4 |
327 | */ |
328 | inline address_v4 make_address_v4(address_v4::uint_type addr) |
329 | { |
330 | return address_v4(addr); |
331 | } |
332 | |
333 | /// Create an IPv4 address from an IP address string in dotted decimal form. |
334 | /** |
335 | * @relates address_v4 |
336 | */ |
337 | BOOST_ASIO_DECL address_v4 make_address_v4(const char* str); |
338 | |
339 | /// Create an IPv4 address from an IP address string in dotted decimal form. |
340 | /** |
341 | * @relates address_v4 |
342 | */ |
343 | BOOST_ASIO_DECL address_v4 make_address_v4(const char* str, |
344 | boost::system::error_code& ec) noexcept; |
345 | |
346 | /// Create an IPv4 address from an IP address string in dotted decimal form. |
347 | /** |
348 | * @relates address_v4 |
349 | */ |
350 | BOOST_ASIO_DECL address_v4 make_address_v4(const std::string& str); |
351 | |
352 | /// Create an IPv4 address from an IP address string in dotted decimal form. |
353 | /** |
354 | * @relates address_v4 |
355 | */ |
356 | BOOST_ASIO_DECL address_v4 make_address_v4(const std::string& str, |
357 | boost::system::error_code& ec) noexcept; |
358 | |
359 | #if defined(BOOST_ASIO_HAS_STRING_VIEW) \ |
360 | || defined(GENERATING_DOCUMENTATION) |
361 | |
362 | /// Create an IPv4 address from an IP address string in dotted decimal form. |
363 | /** |
364 | * @relates address_v4 |
365 | */ |
366 | BOOST_ASIO_DECL address_v4 make_address_v4(string_view str); |
367 | |
368 | /// Create an IPv4 address from an IP address string in dotted decimal form. |
369 | /** |
370 | * @relates address_v4 |
371 | */ |
372 | BOOST_ASIO_DECL address_v4 make_address_v4(string_view str, |
373 | boost::system::error_code& ec) noexcept; |
374 | |
375 | #endif // defined(BOOST_ASIO_HAS_STRING_VIEW) |
376 | // || defined(GENERATING_DOCUMENTATION) |
377 | |
378 | #if !defined(BOOST_ASIO_NO_IOSTREAM) |
379 | |
380 | /// Output an address as a string. |
381 | /** |
382 | * Used to output a human-readable string for a specified address. |
383 | * |
384 | * @param os The output stream to which the string will be written. |
385 | * |
386 | * @param addr The address to be written. |
387 | * |
388 | * @return The output stream. |
389 | * |
390 | * @relates boost::asio::ip::address_v4 |
391 | */ |
392 | template <typename Elem, typename Traits> |
393 | std::basic_ostream<Elem, Traits>& operator<<( |
394 | std::basic_ostream<Elem, Traits>& os, const address_v4& addr); |
395 | |
396 | #endif // !defined(BOOST_ASIO_NO_IOSTREAM) |
397 | |
398 | } // namespace ip |
399 | } // namespace asio |
400 | } // namespace boost |
401 | |
402 | namespace std { |
403 | |
404 | template <> |
405 | struct hash<boost::asio::ip::address_v4> |
406 | { |
407 | std::size_t operator()(const boost::asio::ip::address_v4& addr) |
408 | const noexcept |
409 | { |
410 | return std::hash<unsigned int>()(addr.to_uint()); |
411 | } |
412 | }; |
413 | |
414 | } // namespace std |
415 | |
416 | #include <boost/asio/detail/pop_options.hpp> |
417 | |
418 | #include <boost/asio/ip/impl/address_v4.hpp> |
419 | #if defined(BOOST_ASIO_HEADER_ONLY) |
420 | # include <boost/asio/ip/impl/address_v4.ipp> |
421 | #endif // defined(BOOST_ASIO_HEADER_ONLY) |
422 | |
423 | #endif // BOOST_ASIO_IP_ADDRESS_V4_HPP |
424 | |