File indexing completed on 2025-09-15 08:29:49
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 bool address_v6::is_loopback() const noexcept
0108 {
0109 return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
0110 && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
0111 && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
0112 && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
0113 && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
0114 && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
0115 && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
0116 && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
0117 }
0118
0119 bool address_v6::is_unspecified() const noexcept
0120 {
0121 return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
0122 && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
0123 && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
0124 && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
0125 && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
0126 && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
0127 && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
0128 && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
0129 }
0130
0131 bool address_v6::is_link_local() const noexcept
0132 {
0133 return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80));
0134 }
0135
0136 bool address_v6::is_site_local() const noexcept
0137 {
0138 return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0));
0139 }
0140
0141 bool address_v6::is_v4_mapped() const noexcept
0142 {
0143 return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
0144 && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
0145 && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
0146 && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
0147 && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
0148 && (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff));
0149 }
0150
0151 bool address_v6::is_multicast() const noexcept
0152 {
0153 return (addr_.s6_addr[0] == 0xff);
0154 }
0155
0156 bool address_v6::is_multicast_global() const noexcept
0157 {
0158 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e));
0159 }
0160
0161 bool address_v6::is_multicast_link_local() const noexcept
0162 {
0163 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02));
0164 }
0165
0166 bool address_v6::is_multicast_node_local() const noexcept
0167 {
0168 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01));
0169 }
0170
0171 bool address_v6::is_multicast_org_local() const noexcept
0172 {
0173 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08));
0174 }
0175
0176 bool address_v6::is_multicast_site_local() const noexcept
0177 {
0178 return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05));
0179 }
0180
0181 bool operator==(const address_v6& a1, const address_v6& a2) noexcept
0182 {
0183 using namespace std;
0184 return memcmp(&a1.addr_, &a2.addr_,
0185 sizeof(boost::asio::detail::in6_addr_type)) == 0
0186 && a1.scope_id_ == a2.scope_id_;
0187 }
0188
0189 bool operator<(const address_v6& a1, const address_v6& a2) noexcept
0190 {
0191 using namespace std;
0192 int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
0193 sizeof(boost::asio::detail::in6_addr_type));
0194 if (memcmp_result < 0)
0195 return true;
0196 if (memcmp_result > 0)
0197 return false;
0198 return a1.scope_id_ < a2.scope_id_;
0199 }
0200
0201 address_v6 address_v6::loopback() noexcept
0202 {
0203 address_v6 tmp;
0204 tmp.addr_.s6_addr[15] = 1;
0205 return tmp;
0206 }
0207
0208 address_v6 make_address_v6(const char* str)
0209 {
0210 boost::system::error_code ec;
0211 address_v6 addr = make_address_v6(str, ec);
0212 boost::asio::detail::throw_error(ec);
0213 return addr;
0214 }
0215
0216 address_v6 make_address_v6(const char* str,
0217 boost::system::error_code& ec) noexcept
0218 {
0219 address_v6::bytes_type bytes;
0220 unsigned long scope_id = 0;
0221 if (boost::asio::detail::socket_ops::inet_pton(
0222 BOOST_ASIO_OS_DEF(AF_INET6), str, &bytes[0], &scope_id, ec) <= 0)
0223 return address_v6();
0224 return address_v6(bytes, static_cast<scope_id_type>(scope_id));
0225 }
0226
0227 address_v6 make_address_v6(const std::string& str)
0228 {
0229 return make_address_v6(str.c_str());
0230 }
0231
0232 address_v6 make_address_v6(const std::string& str,
0233 boost::system::error_code& ec) noexcept
0234 {
0235 return make_address_v6(str.c_str(), ec);
0236 }
0237
0238 #if defined(BOOST_ASIO_HAS_STRING_VIEW)
0239
0240 address_v6 make_address_v6(string_view str)
0241 {
0242 return make_address_v6(static_cast<std::string>(str));
0243 }
0244
0245 address_v6 make_address_v6(string_view str,
0246 boost::system::error_code& ec) noexcept
0247 {
0248 return make_address_v6(static_cast<std::string>(str), ec);
0249 }
0250
0251 #endif
0252
0253 address_v4 make_address_v4(
0254 v4_mapped_t, const address_v6& v6_addr)
0255 {
0256 if (!v6_addr.is_v4_mapped())
0257 {
0258 bad_address_cast ex;
0259 boost::asio::detail::throw_exception(ex);
0260 }
0261
0262 address_v6::bytes_type v6_bytes = v6_addr.to_bytes();
0263 address_v4::bytes_type v4_bytes = { { v6_bytes[12],
0264 v6_bytes[13], v6_bytes[14], v6_bytes[15] } };
0265 return address_v4(v4_bytes);
0266 }
0267
0268 address_v6 make_address_v6(
0269 v4_mapped_t, const address_v4& v4_addr)
0270 {
0271 address_v4::bytes_type v4_bytes = v4_addr.to_bytes();
0272 address_v6::bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0273 0xFF, 0xFF, v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
0274 return address_v6(v6_bytes);
0275 }
0276
0277 }
0278 }
0279 }
0280
0281 #include <boost/asio/detail/pop_options.hpp>
0282
0283 #endif