File indexing completed on 2025-01-18 09:28:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP
0012 #define BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <cstring>
0020 #include <stdexcept>
0021 #include <typeinfo>
0022 #include <boost/asio/detail/socket_ops.hpp>
0023 #include <boost/asio/detail/throw_error.hpp>
0024 #include <boost/asio/detail/throw_exception.hpp>
0025 #include <boost/asio/error.hpp>
0026 #include <boost/asio/ip/address_v6.hpp>
0027 #include <boost/asio/ip/bad_address_cast.hpp>
0028
0029 #include <boost/asio/detail/push_options.hpp>
0030
0031 namespace boost {
0032 namespace asio {
0033 namespace ip {
0034
0035 address_v6::address_v6() noexcept
0036 : addr_(),
0037 scope_id_(0)
0038 {
0039 }
0040
0041 address_v6::address_v6(const address_v6::bytes_type& bytes,
0042 scope_id_type scope)
0043 : scope_id_(scope)
0044 {
0045 #if UCHAR_MAX > 0xFF
0046 for (std::size_t i = 0; i < bytes.size(); ++i)
0047 {
0048 if (bytes[i] > 0xFF)
0049 {
0050 std::out_of_range ex("address_v6 from bytes_type");
0051 boost::asio::detail::throw_exception(ex);
0052 }
0053 }
0054 #endif
0055
0056 using namespace std;
0057 memcpy(addr_.s6_addr, bytes.data(), 16);
0058 }
0059
0060 address_v6::address_v6(const address_v6& other) noexcept
0061 : addr_(other.addr_),
0062 scope_id_(other.scope_id_)
0063 {
0064 }
0065
0066 address_v6::address_v6(address_v6&& other) noexcept
0067 : addr_(other.addr_),
0068 scope_id_(other.scope_id_)
0069 {
0070 }
0071
0072 address_v6& address_v6::operator=(const address_v6& other) noexcept
0073 {
0074 addr_ = other.addr_;
0075 scope_id_ = other.scope_id_;
0076 return *this;
0077 }
0078
0079 address_v6& address_v6::operator=(address_v6&& other) noexcept
0080 {
0081 addr_ = other.addr_;
0082 scope_id_ = other.scope_id_;
0083 return *this;
0084 }
0085
0086 address_v6::bytes_type address_v6::to_bytes() const noexcept
0087 {
0088 using namespace std;
0089 bytes_type bytes;
0090 memcpy(bytes.data(), addr_.s6_addr, 16);
0091 return bytes;
0092 }
0093
0094 std::string address_v6::to_string() const
0095 {
0096 boost::system::error_code ec;
0097 char addr_str[boost::asio::detail::max_addr_v6_str_len];
0098 const char* addr =
0099 boost::asio::detail::socket_ops::inet_ntop(
0100 BOOST_ASIO_OS_DEF(AF_INET6), &addr_, addr_str,
0101 boost::asio::detail::max_addr_v6_str_len, scope_id_, ec);
0102 if (addr == 0)
0103 boost::asio::detail::throw_error(ec);
0104 return addr;
0105 }
0106
0107 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0108 std::string address_v6::to_string(boost::system::error_code& ec) const
0109 {
0110 char addr_str[boost::asio::detail::max_addr_v6_str_len];
0111 const char* addr =
0112 boost::asio::detail::socket_ops::inet_ntop(
0113 BOOST_ASIO_OS_DEF(AF_INET6), &addr_, addr_str,
0114 boost::asio::detail::max_addr_v6_str_len, scope_id_, ec);
0115 if (addr == 0)
0116 return std::string();
0117 return addr;
0118 }
0119
0120 address_v4 address_v6::to_v4() const
0121 {
0122 if (!is_v4_mapped() && !is_v4_compatible())
0123 {
0124 bad_address_cast ex;
0125 boost::asio::detail::throw_exception(ex);
0126 }
0127
0128 address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12],
0129 addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } };
0130 return address_v4(v4_bytes);
0131 }
0132 #endif
0133
0134 bool address_v6::is_loopback() const noexcept
0135 {
0136 return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
0137 && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
0138 && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
0139 && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
0140 && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
0141 && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
0142 && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
0143 && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
0144 }
0145
0146 bool address_v6::is_unspecified() const noexcept
0147 {
0148 return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
0149 && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
0150 && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
0151 && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
0152 && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
0153 && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
0154 && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
0155 && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
0156 }
0157
0158 bool address_v6::is_link_local() const noexcept
0159 {
0160 return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80));
0161 }
0162
0163 bool address_v6::is_site_local() const noexcept
0164 {
0165 return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0));
0166 }
0167
0168 bool address_v6::is_v4_mapped() const noexcept
0169 {
0170 return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
0171 && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
0172 && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
0173 && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
0174 && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
0175 && (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff));
0176 }
0177
0178 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0179 bool address_v6::is_v4_compatible() const
0180 {
0181 return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
0182 && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
0183 && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
0184 && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
0185 && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
0186 && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
0187 && !((addr_.s6_addr[12] == 0)
0188 && (addr_.s6_addr[13] == 0)
0189 && (addr_.s6_addr[14] == 0)
0190 && ((addr_.s6_addr[15] == 0) || (addr_.s6_addr[15] == 1))));
0191 }
0192 #endif
0193
0194 bool address_v6::is_multicast() const noexcept
0195 {
0196 return (addr_.s6_addr[0] == 0xff);
0197 }
0198
0199 bool address_v6::is_multicast_global() const noexcept
0200 {
0201 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e));
0202 }
0203
0204 bool address_v6::is_multicast_link_local() const noexcept
0205 {
0206 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02));
0207 }
0208
0209 bool address_v6::is_multicast_node_local() const noexcept
0210 {
0211 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01));
0212 }
0213
0214 bool address_v6::is_multicast_org_local() const noexcept
0215 {
0216 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08));
0217 }
0218
0219 bool address_v6::is_multicast_site_local() const noexcept
0220 {
0221 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05));
0222 }
0223
0224 bool operator==(const address_v6& a1, const address_v6& a2) noexcept
0225 {
0226 using namespace std;
0227 return memcmp(&a1.addr_, &a2.addr_,
0228 sizeof(boost::asio::detail::in6_addr_type)) == 0
0229 && a1.scope_id_ == a2.scope_id_;
0230 }
0231
0232 bool operator<(const address_v6& a1, const address_v6& a2) noexcept
0233 {
0234 using namespace std;
0235 int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
0236 sizeof(boost::asio::detail::in6_addr_type));
0237 if (memcmp_result < 0)
0238 return true;
0239 if (memcmp_result > 0)
0240 return false;
0241 return a1.scope_id_ < a2.scope_id_;
0242 }
0243
0244 address_v6 address_v6::loopback() noexcept
0245 {
0246 address_v6 tmp;
0247 tmp.addr_.s6_addr[15] = 1;
0248 return tmp;
0249 }
0250
0251 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0252 address_v6 address_v6::v4_mapped(const address_v4& addr)
0253 {
0254 address_v4::bytes_type v4_bytes = addr.to_bytes();
0255 bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF,
0256 v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
0257 return address_v6(v6_bytes);
0258 }
0259
0260 address_v6 address_v6::v4_compatible(const address_v4& addr)
0261 {
0262 address_v4::bytes_type v4_bytes = addr.to_bytes();
0263 bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0264 v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
0265 return address_v6(v6_bytes);
0266 }
0267 #endif
0268
0269 address_v6 make_address_v6(const char* str)
0270 {
0271 boost::system::error_code ec;
0272 address_v6 addr = make_address_v6(str, ec);
0273 boost::asio::detail::throw_error(ec);
0274 return addr;
0275 }
0276
0277 address_v6 make_address_v6(const char* str,
0278 boost::system::error_code& ec) noexcept
0279 {
0280 address_v6::bytes_type bytes;
0281 unsigned long scope_id = 0;
0282 if (boost::asio::detail::socket_ops::inet_pton(
0283 BOOST_ASIO_OS_DEF(AF_INET6), str, &bytes[0], &scope_id, ec) <= 0)
0284 return address_v6();
0285 return address_v6(bytes, scope_id);
0286 }
0287
0288 address_v6 make_address_v6(const std::string& str)
0289 {
0290 return make_address_v6(str.c_str());
0291 }
0292
0293 address_v6 make_address_v6(const std::string& str,
0294 boost::system::error_code& ec) noexcept
0295 {
0296 return make_address_v6(str.c_str(), ec);
0297 }
0298
0299 #if defined(BOOST_ASIO_HAS_STRING_VIEW)
0300
0301 address_v6 make_address_v6(string_view str)
0302 {
0303 return make_address_v6(static_cast<std::string>(str));
0304 }
0305
0306 address_v6 make_address_v6(string_view str,
0307 boost::system::error_code& ec) noexcept
0308 {
0309 return make_address_v6(static_cast<std::string>(str), ec);
0310 }
0311
0312 #endif
0313
0314 address_v4 make_address_v4(
0315 v4_mapped_t, const address_v6& v6_addr)
0316 {
0317 if (!v6_addr.is_v4_mapped())
0318 {
0319 bad_address_cast ex;
0320 boost::asio::detail::throw_exception(ex);
0321 }
0322
0323 address_v6::bytes_type v6_bytes = v6_addr.to_bytes();
0324 address_v4::bytes_type v4_bytes = { { v6_bytes[12],
0325 v6_bytes[13], v6_bytes[14], v6_bytes[15] } };
0326 return address_v4(v4_bytes);
0327 }
0328
0329 address_v6 make_address_v6(
0330 v4_mapped_t, const address_v4& v4_addr)
0331 {
0332 address_v4::bytes_type v4_bytes = v4_addr.to_bytes();
0333 address_v6::bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0334 0xFF, 0xFF, v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
0335 return address_v6(v6_bytes);
0336 }
0337
0338 }
0339 }
0340 }
0341
0342 #include <boost/asio/detail/pop_options.hpp>
0343
0344 #endif