Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/boostorg/url
9 : //
10 :
11 : #ifndef BOOST_URL_IPV4_ADDRESS_HPP
12 : #define BOOST_URL_IPV4_ADDRESS_HPP
13 :
14 : #include <boost/url/detail/config.hpp>
15 : #include <boost/url/error.hpp>
16 : #include <boost/url/error_types.hpp>
17 : #include <boost/core/detail/string_view.hpp>
18 : #include <boost/url/grammar/string_token.hpp>
19 : #include <string>
20 : #include <array>
21 : #include <cstdint>
22 : #include <iosfwd>
23 :
24 : namespace boost {
25 : namespace urls {
26 :
27 : /** An IP version 4 style address.
28 :
29 : Objects of this type are used to construct,
30 : parse, and manipulate IP version 6 addresses.
31 :
32 : @par BNF
33 : @code
34 : IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
35 :
36 : dec-octet = DIGIT ; 0-9
37 : / %x31-39 DIGIT ; 10-99
38 : / "1" 2DIGIT ; 100-199
39 : / "2" %x30-34 DIGIT ; 200-249
40 : / "25" %x30-35 ; 250-255
41 : @endcode
42 :
43 : @par Specification
44 : @li <a href="https://en.wikipedia.org/wiki/IPv4"
45 : >IPv4 (Wikipedia)</a>
46 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
47 : >3.2.2. Host (rfc3986)</a>
48 :
49 : @see
50 : @ref parse_ipv4_address,
51 : @ref ipv6_address.
52 : */
53 : class ipv4_address
54 : {
55 : public:
56 : /** The number of characters in the longest possible IPv4 string.
57 :
58 : The longest ipv4 address string is "255.255.255.255".
59 : */
60 : static
61 : constexpr
62 : std::size_t max_str_len = 15;
63 :
64 : /** The type used to represent an address as an unsigned integer
65 : */
66 : using uint_type =
67 : std::uint_least32_t;
68 :
69 : /** The type used to represent an address as an array of bytes
70 : */
71 : using bytes_type =
72 : std::array<unsigned char, 4>;
73 :
74 : /** Constructor.
75 : */
76 77 : ipv4_address() = default;
77 :
78 : /** Constructor.
79 : */
80 : ipv4_address(
81 : ipv4_address const&) = default;
82 :
83 : /** Copy Assignment.
84 : */
85 : ipv4_address&
86 : operator=(
87 : ipv4_address const&) = default;
88 :
89 : //
90 : //---
91 : //
92 :
93 : /** Construct from an unsigned integer.
94 :
95 : This function constructs an address from
96 : the unsigned integer `u`, where the most
97 : significant byte forms the first octet
98 : of the resulting address.
99 :
100 : @param u The integer to construct from.
101 : */
102 : BOOST_URL_DECL
103 : explicit
104 : ipv4_address(
105 : uint_type u) noexcept;
106 :
107 : /** Construct from an array of bytes.
108 :
109 : This function constructs an address
110 : from the array in `bytes`, which is
111 : interpreted in big-endian.
112 :
113 : @param bytes The value to construct from.
114 : */
115 : BOOST_URL_DECL
116 : explicit
117 : ipv4_address(
118 : bytes_type const& bytes) noexcept;
119 :
120 : /** Construct from a string.
121 :
122 : This function constructs an address from
123 : the string `s`, which must contain a valid
124 : IPv4 address string or else an exception
125 : is thrown.
126 :
127 : @note For a non-throwing parse function,
128 : use @ref parse_ipv4_address.
129 :
130 : @par Exception Safety
131 : Exceptions thrown on invalid input.
132 :
133 : @throw system_error The input failed to parse correctly.
134 :
135 : @param s The string to parse.
136 :
137 : @par Specification
138 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
139 : >3.2.2. Host (rfc3986)</a>
140 :
141 : @see
142 : @ref parse_ipv4_address.
143 : */
144 : BOOST_URL_DECL
145 : explicit
146 : ipv4_address(
147 : core::string_view s);
148 :
149 : /** Return the address as bytes, in network byte order.
150 : */
151 : BOOST_URL_DECL
152 : bytes_type
153 : to_bytes() const noexcept;
154 :
155 : /** Return the address as an unsigned integer.
156 : */
157 : BOOST_URL_DECL
158 : uint_type
159 : to_uint() const noexcept;
160 :
161 : /** Return the address as a string in dotted decimal format
162 :
163 : When called with no arguments, the
164 : return type is `std::string`.
165 : Otherwise, the return type and style
166 : of output is determined by which string
167 : token is passed.
168 :
169 : @par Example
170 : @code
171 : assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
172 : @endcode
173 :
174 : @par Complexity
175 : Constant.
176 :
177 : @par Exception Safety
178 : Strong guarantee.
179 : Calls to allocate may throw.
180 : String tokens may throw exceptions.
181 :
182 : @return The return type of the string token.
183 : If the token parameter is omitted, then
184 : a new `std::string` is returned.
185 : Otherwise, the function return type
186 : is the result type of the token.
187 :
188 : @param token An optional string token.
189 :
190 : @par Specification
191 : @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
192 : 2.2. Text Representation of Addresses (rfc4291)</a>
193 : */
194 : template<BOOST_URL_STRTOK_TPARAM>
195 : BOOST_URL_STRTOK_RETURN
196 2 : to_string(StringToken&& token = {}) const
197 : {
198 2 : to_string_impl(token);
199 2 : return token.result();
200 : }
201 :
202 : /** Write a dotted decimal string representing the address to a buffer
203 :
204 : The resulting buffer is not null-terminated.
205 :
206 : @throw std::length_error `dest_size < ipv4_address::max_str_len`
207 :
208 : @return The formatted string
209 :
210 : @param dest The buffer in which to write,
211 : which must have at least `dest_size` space.
212 :
213 : @param dest_size The size of the output buffer.
214 : */
215 : BOOST_URL_DECL
216 : core::string_view
217 : to_buffer(
218 : char* dest,
219 : std::size_t dest_size) const;
220 :
221 : /** Return true if the address is a loopback address
222 : */
223 : BOOST_URL_DECL
224 : bool
225 : is_loopback() const noexcept;
226 :
227 : /** Return true if the address is unspecified
228 : */
229 : BOOST_URL_DECL
230 : bool
231 : is_unspecified() const noexcept;
232 :
233 : /** Return true if the address is a multicast address
234 : */
235 : BOOST_URL_DECL
236 : bool
237 : is_multicast() const noexcept;
238 :
239 : /** Return true if two addresses are equal
240 : */
241 : friend
242 : bool
243 57 : operator==(
244 : ipv4_address const& a1,
245 : ipv4_address const& a2) noexcept
246 : {
247 57 : return a1.addr_ == a2.addr_;
248 : }
249 :
250 : /** Return true if two addresses are not equal
251 : */
252 : friend
253 : bool
254 3 : operator!=(
255 : ipv4_address const& a1,
256 : ipv4_address const& a2) noexcept
257 : {
258 3 : return a1.addr_ != a2.addr_;
259 : }
260 :
261 : /** Return an address object that represents any address
262 : */
263 : static
264 : ipv4_address
265 3 : any() noexcept
266 : {
267 3 : return ipv4_address();
268 : }
269 :
270 : /** Return an address object that represents the loopback address
271 : */
272 : static
273 : ipv4_address
274 3 : loopback() noexcept
275 : {
276 3 : return ipv4_address(0x7F000001);
277 : }
278 :
279 : /** Return an address object that represents the broadcast address
280 : */
281 : static
282 : ipv4_address
283 3 : broadcast() noexcept
284 : {
285 3 : return ipv4_address(0xFFFFFFFF);
286 : }
287 :
288 : /** Format the address to an output stream.
289 :
290 : IPv4 addresses written to output streams
291 : are written in their dotted decimal format.
292 :
293 : @param os The output stream.
294 :
295 : @param addr The address to format.
296 : */
297 : friend
298 : std::ostream&
299 1 : operator<<(
300 : std::ostream& os,
301 : ipv4_address const& addr)
302 : {
303 : char buf[ipv4_address::max_str_len];
304 1 : os << addr.to_buffer(buf, sizeof(buf));
305 1 : return os;
306 : }
307 :
308 : private:
309 : friend class ipv6_address;
310 :
311 : BOOST_URL_DECL
312 : std::size_t
313 : print_impl(
314 : char* dest) const noexcept;
315 :
316 : BOOST_URL_DECL
317 : void
318 : to_string_impl(
319 : string_token::arg& t) const;
320 :
321 : uint_type addr_ = 0;
322 : };
323 :
324 : /** Format the address to an output stream.
325 :
326 : IPv4 addresses written to output streams
327 : are written in their dotted decimal format.
328 :
329 : @param os The output stream.
330 :
331 : @param addr The address to format.
332 : */
333 : std::ostream&
334 : operator<<(
335 : std::ostream& os,
336 : ipv4_address const& addr);
337 :
338 : //------------------------------------------------
339 :
340 : /** Return an IPv4 address from an IP address string in dotted decimal form
341 : */
342 : BOOST_URL_DECL
343 : system::result<ipv4_address>
344 : parse_ipv4_address(
345 : core::string_view s) noexcept;
346 :
347 : } // urls
348 : } // boost
349 :
350 : #endif
|