Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:59

0001 //
0002 // ip/impl/address_v6.ipp
0003 // ~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 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 #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 // !defined(BOOST_ASIO_NO_DEPRECATED)
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 // !defined(BOOST_ASIO_NO_DEPRECATED)
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; // For memcmp.
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; // For memcmp.
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 // !defined(BOOST_ASIO_NO_DEPRECATED)
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 // defined(BOOST_ASIO_HAS_STRING_VIEW)
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 } // namespace ip
0339 } // namespace asio
0340 } // namespace boost
0341 
0342 #include <boost/asio/detail/pop_options.hpp>
0343 
0344 #endif // BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP