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 134 : The input failed to parse correctly. 135 : 136 : @param s The string to parse. 137 : 138 : @par Specification 139 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" 140 : >3.2.2. Host (rfc3986)</a> 141 : 142 : @see 143 : @ref parse_ipv4_address. 144 : */ 145 : BOOST_URL_DECL 146 : explicit 147 : ipv4_address( 148 : core::string_view s); 149 : 150 : /** Return the address as bytes, in network byte order. 151 : */ 152 : BOOST_URL_DECL 153 : bytes_type 154 : to_bytes() const noexcept; 155 : 156 : /** Return the address as an unsigned integer. 157 : */ 158 : BOOST_URL_DECL 159 : uint_type 160 : to_uint() const noexcept; 161 : 162 : /** Return the address as a string in dotted decimal format 163 : 164 : When called with no arguments, the 165 : return type is `std::string`. 166 : Otherwise, the return type and style 167 : of output is determined by which string 168 : token is passed. 169 : 170 : @par Example 171 : @code 172 : assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" ); 173 : @endcode 174 : 175 : @par Complexity 176 : Constant. 177 : 178 : @par Exception Safety 179 : Strong guarantee. 180 : Calls to allocate may throw. 181 : String tokens may throw exceptions. 182 : 183 : @return The return type of the string token. 184 : If the token parameter is omitted, then 185 : a new `std::string` is returned. 186 : Otherwise, the function return type 187 : is the result type of the token. 188 : 189 : @param token An optional string token. 190 : 191 : @par Specification 192 : @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2"> 193 : 2.2. Text Representation of Addresses (rfc4291)</a> 194 : */ 195 : template<BOOST_URL_STRTOK_TPARAM> 196 : BOOST_URL_STRTOK_RETURN 197 2 : to_string( 198 : BOOST_URL_STRTOK_ARG(token)) const 199 : { 200 2 : to_string_impl(token); 201 2 : return token.result(); 202 : } 203 : 204 : /** Write a dotted decimal string representing the address to a buffer 205 : 206 : The resulting buffer is not null-terminated. 207 : 208 : @throw std::length_error `dest_size < ipv4_address::max_str_len` 209 : 210 : @return The formatted string 211 : 212 : @param dest The buffer in which to write, 213 : which must have at least `dest_size` space. 214 : 215 : @param dest_size The size of the output buffer. 216 : */ 217 : BOOST_URL_DECL 218 : core::string_view 219 : to_buffer( 220 : char* dest, 221 : std::size_t dest_size) const; 222 : 223 : /** Return true if the address is a loopback address 224 : */ 225 : BOOST_URL_DECL 226 : bool 227 : is_loopback() const noexcept; 228 : 229 : /** Return true if the address is unspecified 230 : */ 231 : BOOST_URL_DECL 232 : bool 233 : is_unspecified() const noexcept; 234 : 235 : /** Return true if the address is a multicast address 236 : */ 237 : BOOST_URL_DECL 238 : bool 239 : is_multicast() const noexcept; 240 : 241 : /** Return true if two addresses are equal 242 : */ 243 : friend 244 : bool 245 57 : operator==( 246 : ipv4_address const& a1, 247 : ipv4_address const& a2) noexcept 248 : { 249 57 : return a1.addr_ == a2.addr_; 250 : } 251 : 252 : /** Return true if two addresses are not equal 253 : */ 254 : friend 255 : bool 256 3 : operator!=( 257 : ipv4_address const& a1, 258 : ipv4_address const& a2) noexcept 259 : { 260 3 : return a1.addr_ != a2.addr_; 261 : } 262 : 263 : /** Return an address object that represents any address 264 : */ 265 : static 266 : ipv4_address 267 3 : any() noexcept 268 : { 269 3 : return ipv4_address(); 270 : } 271 : 272 : /** Return an address object that represents the loopback address 273 : */ 274 : static 275 : ipv4_address 276 3 : loopback() noexcept 277 : { 278 3 : return ipv4_address(0x7F000001); 279 : } 280 : 281 : /** Return an address object that represents the broadcast address 282 : */ 283 : static 284 : ipv4_address 285 3 : broadcast() noexcept 286 : { 287 3 : return ipv4_address(0xFFFFFFFF); 288 : } 289 : 290 : // hidden friend 291 : friend 292 : std::ostream& 293 1 : operator<<( 294 : std::ostream& os, 295 : ipv4_address const& addr) 296 : { 297 : char buf[ipv4_address::max_str_len]; 298 1 : os << addr.to_buffer(buf, sizeof(buf)); 299 1 : return os; 300 : } 301 : 302 : private: 303 : friend class ipv6_address; 304 : 305 : BOOST_URL_DECL 306 : std::size_t 307 : print_impl( 308 : char* dest) const noexcept; 309 : 310 : BOOST_URL_DECL 311 : void 312 : to_string_impl( 313 : string_token::arg& t) const; 314 : 315 : uint_type addr_ = 0; 316 : }; 317 : 318 : /** Format the address to an output stream. 319 : 320 : IPv4 addresses written to output streams 321 : are written in their dotted decimal format. 322 : 323 : @param os The output stream. 324 : 325 : @param addr The address to format. 326 : */ 327 : std::ostream& 328 : operator<<( 329 : std::ostream& os, 330 : ipv4_address const& addr); 331 : 332 : //------------------------------------------------ 333 : 334 : /** Return an IPv4 address from an IP address string in dotted decimal form 335 : */ 336 : BOOST_URL_DECL 337 : system::result<ipv4_address> 338 : parse_ipv4_address( 339 : core::string_view s) noexcept; 340 : 341 : } // urls 342 : } // boost 343 : 344 : #endif