1 // 2 // ip/impl/address_v4.ipp 3 // ~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 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 ASIO_IP_IMPL_ADDRESS_V4_IPP 12 #define ASIO_IP_IMPL_ADDRESS_V4_IPP 13 14 15 #include "asio/detail/config.hpp" 16 #include <climits> 17 #include <stdexcept> 18 #include "asio/error.hpp" 19 #include "asio/detail/socket_ops.hpp" 20 #include "asio/detail/throw_error.hpp" 21 #include "asio/detail/throw_exception.hpp" 22 #include "asio/ip/address_v4.hpp" 23 24 #include "asio/detail/push_options.hpp" 25 26 namespace asio { 27 namespace ip { 28 29 address_v4::address_v4(const address_v4::bytes_type& bytes) 30 { 31 #if UCHAR_MAX > 0xFF 32 if (bytes[0] > 0xFF || bytes[1] > 0xFF 33 || bytes[2] > 0xFF || bytes[3] > 0xFF) 34 { 35 std::out_of_range ex("address_v4 from bytes_type"); 36 asio::detail::throw_exception(ex); 37 } 38 #endif // UCHAR_MAX > 0xFF 39 40 using namespace std; // For memcpy. 41 memcpy(&addr_.s_addr, bytes.data(), 4); 42 } 43 44 address_v4::address_v4(unsigned long addr) 45 { 46 #if ULONG_MAX > 0xFFFFFFFF 47 if (addr > 0xFFFFFFFF) 48 { 49 std::out_of_range ex("address_v4 from unsigned long"); 50 asio::detail::throw_exception(ex); 51 } 52 #endif // ULONG_MAX > 0xFFFFFFFF 53 54 addr_.s_addr = asio::detail::socket_ops::host_to_network_long( 55 static_cast<asio::detail::u_long_type>(addr)); 56 } 57 58 address_v4::bytes_type address_v4::to_bytes() const 59 { 60 using namespace std; // For memcpy. 61 bytes_type bytes; 62 memcpy(bytes.data(), &addr_.s_addr, 4); 63 return bytes; 64 } 65 66 unsigned long address_v4::to_ulong() const 67 { 68 return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); 69 } 70 71 std::string address_v4::to_string() const 72 { 73 asio::error_code ec; 74 std::string addr = to_string(ec); 75 asio::detail::throw_error(ec); 76 return addr; 77 } 78 79 std::string address_v4::to_string(asio::error_code& ec) const 80 { 81 char addr_str[asio::detail::max_addr_v4_str_len]; 82 const char* addr = 83 asio::detail::socket_ops::inet_ntop( 84 ASIO_OS_DEF(AF_INET), &addr_, addr_str, 85 asio::detail::max_addr_v4_str_len, 0, ec); 86 if (addr == 0) 87 return std::string(); 88 return addr; 89 } 90 91 address_v4 address_v4::from_string(const char* str) 92 { 93 asio::error_code ec; 94 address_v4 addr = from_string(str, ec); 95 asio::detail::throw_error(ec); 96 return addr; 97 } 98 99 address_v4 address_v4::from_string( 100 const char* str, asio::error_code& ec) 101 { 102 address_v4 tmp; 103 if (asio::detail::socket_ops::inet_pton( 104 ASIO_OS_DEF(AF_INET), str, &tmp.addr_, 0, ec) <= 0) 105 return address_v4(); 106 return tmp; 107 } 108 109 address_v4 address_v4::from_string(const std::string& str) 110 { 111 return from_string(str.c_str()); 112 } 113 114 address_v4 address_v4::from_string( 115 const std::string& str, asio::error_code& ec) 116 { 117 return from_string(str.c_str(), ec); 118 } 119 120 bool address_v4::is_loopback() const 121 { 122 return (to_ulong() & 0xFF000000) == 0x7F000000; 123 } 124 125 bool address_v4::is_unspecified() const 126 { 127 return to_ulong() == 0; 128 } 129 130 bool address_v4::is_class_a() const 131 { 132 return (to_ulong() & 0x80000000) == 0; 133 } 134 135 bool address_v4::is_class_b() const 136 { 137 return (to_ulong() & 0xC0000000) == 0x80000000; 138 } 139 140 bool address_v4::is_class_c() const 141 { 142 return (to_ulong() & 0xE0000000) == 0xC0000000; 143 } 144 145 bool address_v4::is_multicast() const 146 { 147 return (to_ulong() & 0xF0000000) == 0xE0000000; 148 } 149 150 address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask) 151 { 152 return address_v4(addr.to_ulong() | (mask.to_ulong() ^ 0xFFFFFFFF)); 153 } 154 155 address_v4 address_v4::netmask(const address_v4& addr) 156 { 157 if (addr.is_class_a()) 158 return address_v4(0xFF000000); 159 if (addr.is_class_b()) 160 return address_v4(0xFFFF0000); 161 if (addr.is_class_c()) 162 return address_v4(0xFFFFFF00); 163 return address_v4(0xFFFFFFFF); 164 } 165 166 } // namespace ip 167 } // namespace asio 168 169 #include "asio/detail/pop_options.hpp" 170 171 #endif // ASIO_IP_IMPL_ADDRESS_V4_IPP 172