Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:29:49

0001 //
0002 // ip/impl/address_v6.ipp
0003 // ~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // defined(_MSC_VER) && (_MSC_VER >= 1200)
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 // UCHAR_MAX > 0xFF
0055 
0056   using namespace std; // For memcpy.
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; // For memcpy.
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; // For memcmp.
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; // For memcmp.
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 // defined(BOOST_ASIO_HAS_STRING_VIEW)
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 } // namespace ip
0278 } // namespace asio
0279 } // namespace boost
0280 
0281 #include <boost/asio/detail/pop_options.hpp>
0282 
0283 #endif // BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP