Make the is_loopback(), is_unspecified() and is_multicast() functions

consistent across all of the IP address classes.

Remove dependency on OS-provided macros for the well-known IPv4 and IPv6
addresses. This should eliminate the annoying "missing braces around
initializer" warnings.
This commit is contained in:
Christopher Kohlhoff 2011-02-08 15:40:26 +11:00
parent 855b96769c
commit b353d3eca2
9 changed files with 445 additions and 200 deletions

View File

@ -84,14 +84,6 @@ struct ipv6_mreq_emulation
unsigned int ipv6mr_interface;
};
#if !defined(IN6ADDR_ANY_INIT)
# define IN6ADDR_ANY_INIT { 0 }
#endif
#if !defined(IN6ADDR_LOOPBACK_INIT)
# define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
#endif
struct addrinfo_emulation
{
int ai_flags;
@ -200,122 +192,6 @@ struct addrinfo_emulation
# define IPV6_LEAVE_GROUP 13
#endif
inline int IN6_IS_ADDR_UNSPECIFIED(const in6_addr_emulation* a)
{
return ((a->s6_addr[0] == 0)
&& (a->s6_addr[1] == 0)
&& (a->s6_addr[2] == 0)
&& (a->s6_addr[3] == 0)
&& (a->s6_addr[4] == 0)
&& (a->s6_addr[5] == 0)
&& (a->s6_addr[6] == 0)
&& (a->s6_addr[7] == 0)
&& (a->s6_addr[8] == 0)
&& (a->s6_addr[9] == 0)
&& (a->s6_addr[10] == 0)
&& (a->s6_addr[11] == 0)
&& (a->s6_addr[12] == 0)
&& (a->s6_addr[13] == 0)
&& (a->s6_addr[14] == 0)
&& (a->s6_addr[15] == 0));
}
inline int IN6_IS_ADDR_LOOPBACK(const in6_addr_emulation* a)
{
return ((a->s6_addr[0] == 0)
&& (a->s6_addr[1] == 0)
&& (a->s6_addr[2] == 0)
&& (a->s6_addr[3] == 0)
&& (a->s6_addr[4] == 0)
&& (a->s6_addr[5] == 0)
&& (a->s6_addr[6] == 0)
&& (a->s6_addr[7] == 0)
&& (a->s6_addr[8] == 0)
&& (a->s6_addr[9] == 0)
&& (a->s6_addr[10] == 0)
&& (a->s6_addr[11] == 0)
&& (a->s6_addr[12] == 0)
&& (a->s6_addr[13] == 0)
&& (a->s6_addr[14] == 0)
&& (a->s6_addr[15] == 1));
}
inline int IN6_IS_ADDR_MULTICAST(const in6_addr_emulation* a)
{
return (a->s6_addr[0] == 0xff);
}
inline int IN6_IS_ADDR_LINKLOCAL(const in6_addr_emulation* a)
{
return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0x80));
}
inline int IN6_IS_ADDR_SITELOCAL(const in6_addr_emulation* a)
{
return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0xc0));
}
inline int IN6_IS_ADDR_V4MAPPED(const in6_addr_emulation* a)
{
return ((a->s6_addr[0] == 0)
&& (a->s6_addr[1] == 0)
&& (a->s6_addr[2] == 0)
&& (a->s6_addr[3] == 0)
&& (a->s6_addr[4] == 0)
&& (a->s6_addr[5] == 0)
&& (a->s6_addr[6] == 0)
&& (a->s6_addr[7] == 0)
&& (a->s6_addr[8] == 0)
&& (a->s6_addr[9] == 0)
&& (a->s6_addr[10] == 0xff)
&& (a->s6_addr[11] == 0xff));
}
inline int IN6_IS_ADDR_V4COMPAT(const in6_addr_emulation* a)
{
return ((a->s6_addr[0] == 0)
&& (a->s6_addr[1] == 0)
&& (a->s6_addr[2] == 0)
&& (a->s6_addr[3] == 0)
&& (a->s6_addr[4] == 0)
&& (a->s6_addr[5] == 0)
&& (a->s6_addr[6] == 0)
&& (a->s6_addr[7] == 0)
&& (a->s6_addr[8] == 0)
&& (a->s6_addr[9] == 0)
&& (a->s6_addr[10] == 0xff)
&& (a->s6_addr[11] == 0xff)
&& !((a->s6_addr[12] == 0)
&& (a->s6_addr[13] == 0)
&& (a->s6_addr[14] == 0)
&& ((a->s6_addr[15] == 0) || (a->s6_addr[15] == 1))));
}
inline int IN6_IS_ADDR_MC_NODELOCAL(const in6_addr_emulation* a)
{
return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 1);
}
inline int IN6_IS_ADDR_MC_LINKLOCAL(const in6_addr_emulation* a)
{
return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 2);
}
inline int IN6_IS_ADDR_MC_SITELOCAL(const in6_addr_emulation* a)
{
return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 5);
}
inline int IN6_IS_ADDR_MC_ORGLOCAL(const in6_addr_emulation* a)
{
return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 8);
}
inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a)
{
return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 0xe);
}
} // namespace detail
} // namespace asio

View File

@ -107,6 +107,15 @@ public:
ASIO_DECL static address from_string(
const std::string& str, asio::error_code& ec);
/// Determine whether the address is a loopback address.
ASIO_DECL bool is_loopback() const;
/// Determine whether the address is unspecified.
ASIO_DECL bool is_unspecified() const;
/// Determine whether the address is a multicast address.
ASIO_DECL bool is_multicast() const;
/// Compare two addresses for equality.
ASIO_DECL friend bool operator==(const address& a1, const address& a2);

View File

@ -97,6 +97,12 @@ public:
ASIO_DECL static address_v4 from_string(
const std::string& str, asio::error_code& ec);
/// Determine whether the address is a loopback address.
ASIO_DECL bool is_loopback() const;
/// Determine whether the address is unspecified.
ASIO_DECL bool is_unspecified() const;
/// Determine whether the address is a class A address.
ASIO_DECL bool is_class_a() const;
@ -148,19 +154,19 @@ public:
/// Obtain an address object that represents any address.
static address_v4 any()
{
return address_v4(static_cast<unsigned long>(INADDR_ANY));
return address_v4();
}
/// Obtain an address object that represents the loopback address.
static address_v4 loopback()
{
return address_v4(static_cast<unsigned long>(INADDR_LOOPBACK));
return address_v4(0x7F000001);
}
/// Obtain an address object that represents the broadcast address.
static address_v4 broadcast()
{
return address_v4(static_cast<unsigned long>(INADDR_BROADCAST));
return address_v4(0xFFFFFFFF);
}
/// Obtain an address object that represents the broadcast address that

View File

@ -384,31 +384,18 @@ class multicast_request
public:
// Default constructor.
multicast_request()
: ipv4_value_(), // Zero-initialisation gives the "any" address.
ipv6_value_() // Zero-initialisation gives the "any" address.
{
ipv4_value_.imr_multiaddr.s_addr =
asio::detail::socket_ops::host_to_network_long(
asio::ip::address_v4::any().to_ulong());
ipv4_value_.imr_interface.s_addr =
asio::detail::socket_ops::host_to_network_long(
asio::ip::address_v4::any().to_ulong());
asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
ipv6_value_.ipv6mr_multiaddr = tmp_addr;
ipv6_value_.ipv6mr_interface = 0;
}
// Construct with multicast address only.
explicit multicast_request(const asio::ip::address& multicast_address)
: ipv4_value_(), // Zero-initialisation gives the "any" address.
ipv6_value_() // Zero-initialisation gives the "any" address.
{
if (multicast_address.is_v6())
{
ipv4_value_.imr_multiaddr.s_addr =
asio::detail::socket_ops::host_to_network_long(
asio::ip::address_v4::any().to_ulong());
ipv4_value_.imr_interface.s_addr =
asio::detail::socket_ops::host_to_network_long(
asio::ip::address_v4::any().to_ulong());
using namespace std; // For memcpy.
asio::ip::address_v6 ipv6_address = multicast_address.to_v6();
asio::ip::address_v6::bytes_type bytes = ipv6_address.to_bytes();
@ -423,10 +410,6 @@ public:
ipv4_value_.imr_interface.s_addr =
asio::detail::socket_ops::host_to_network_long(
asio::ip::address_v4::any().to_ulong());
asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
ipv6_value_.ipv6mr_multiaddr = tmp_addr;
ipv6_value_.ipv6mr_interface = 0;
}
}
@ -435,6 +418,7 @@ public:
const asio::ip::address_v4& multicast_address,
const asio::ip::address_v4& network_interface
= asio::ip::address_v4::any())
: ipv6_value_() // Zero-initialisation gives the "any" address.
{
ipv4_value_.imr_multiaddr.s_addr =
asio::detail::socket_ops::host_to_network_long(
@ -442,24 +426,14 @@ public:
ipv4_value_.imr_interface.s_addr =
asio::detail::socket_ops::host_to_network_long(
network_interface.to_ulong());
asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
ipv6_value_.ipv6mr_multiaddr = tmp_addr;
ipv6_value_.ipv6mr_interface = 0;
}
// Construct with multicast address and IPv6 network interface index.
explicit multicast_request(
const asio::ip::address_v6& multicast_address,
unsigned long network_interface = 0)
: ipv4_value_() // Zero-initialisation gives the "any" address.
{
ipv4_value_.imr_multiaddr.s_addr =
asio::detail::socket_ops::host_to_network_long(
asio::ip::address_v4::any().to_ulong());
ipv4_value_.imr_interface.s_addr =
asio::detail::socket_ops::host_to_network_long(
asio::ip::address_v4::any().to_ulong());
using namespace std; // For memcpy.
asio::ip::address_v6::bytes_type bytes =
multicast_address.to_bytes();

View File

@ -158,6 +158,27 @@ address address::from_string(const std::string& str,
return from_string(str.c_str(), ec);
}
bool address::is_loopback() const
{
return (type_ == ipv4)
? ipv4_address_.is_loopback()
: ipv6_address_.is_loopback();
}
bool address::is_unspecified() const
{
return (type_ == ipv4)
? ipv4_address_.is_unspecified()
: ipv6_address_.is_unspecified();
}
bool address::is_multicast() const
{
return (type_ == ipv4)
? ipv4_address_.is_multicast()
: ipv6_address_.is_multicast();
}
bool operator==(const address& a1, const address& a2)
{
if (a1.type_ != a2.type_)

View File

@ -118,24 +118,34 @@ address_v4 address_v4::from_string(
return from_string(str.c_str(), ec);
}
bool address_v4::is_loopback() const
{
return (to_ulong() & 0xFF000000) == 0x7F000000;
}
bool address_v4::is_unspecified() const
{
return to_ulong() == 0;
}
bool address_v4::is_class_a() const
{
return IN_CLASSA(to_ulong());
return (to_ulong() & 0x80000000) == 0;
}
bool address_v4::is_class_b() const
{
return IN_CLASSB(to_ulong());
return (to_ulong() & 0xC0000000) == 0x80000000;
}
bool address_v4::is_class_c() const
{
return IN_CLASSC(to_ulong());
return (to_ulong() & 0xE0000000) == 0xC0000000;
}
bool address_v4::is_multicast() const
{
return IN_MULTICAST(to_ulong());
return (to_ulong() & 0xF0000000) == 0xE0000000;
}
address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask)

View File

@ -31,10 +31,9 @@ namespace asio {
namespace ip {
address_v6::address_v6()
: scope_id_(0)
: addr_(),
scope_id_(0)
{
asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
addr_ = tmp_addr;
}
address_v6::address_v6(const address_v6::bytes_type& bytes,
@ -140,7 +139,6 @@ address_v4 address_v6::to_v4() const
bool address_v6::is_loopback() const
{
#if defined(__BORLANDC__)
return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
&& (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
&& (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
@ -149,15 +147,10 @@ bool address_v6::is_loopback() const
&& (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
&& (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
&& (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
#else
using namespace asio::detail;
return IN6_IS_ADDR_LOOPBACK(&addr_) != 0;
#endif
}
bool address_v6::is_unspecified() const
{
#if defined(__BORLANDC__)
return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
&& (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
&& (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
@ -166,70 +159,70 @@ bool address_v6::is_unspecified() const
&& (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
&& (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
&& (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
#else
using namespace asio::detail;
return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0;
#endif
}
bool address_v6::is_link_local() const
{
using namespace asio::detail;
return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0;
return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80));
}
bool address_v6::is_site_local() const
{
using namespace asio::detail;
return IN6_IS_ADDR_SITELOCAL(&addr_) != 0;
return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0));
}
bool address_v6::is_v4_mapped() const
{
using namespace asio::detail;
return IN6_IS_ADDR_V4MAPPED(&addr_) != 0;
return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
&& (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
&& (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
&& (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
&& (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
&& (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff));
}
bool address_v6::is_v4_compatible() const
{
using namespace asio::detail;
return IN6_IS_ADDR_V4COMPAT(&addr_) != 0;
return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
&& (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
&& (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
&& (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
&& (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
&& (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
&& !((addr_.s6_addr[12] == 0)
&& (addr_.s6_addr[13] == 0)
&& (addr_.s6_addr[14] == 0)
&& ((addr_.s6_addr[15] == 0) || (addr_.s6_addr[15] == 1))));
}
bool address_v6::is_multicast() const
{
using namespace asio::detail;
return IN6_IS_ADDR_MULTICAST(&addr_) != 0;
return (addr_.s6_addr[0] == 0xff);
}
bool address_v6::is_multicast_global() const
{
using namespace asio::detail;
return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0;
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e));
}
bool address_v6::is_multicast_link_local() const
{
using namespace asio::detail;
return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0;
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02));
}
bool address_v6::is_multicast_node_local() const
{
using namespace asio::detail;
return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0;
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01));
}
bool address_v6::is_multicast_org_local() const
{
using namespace asio::detail;
return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0;
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08));
}
bool address_v6::is_multicast_site_local() const
{
using namespace asio::detail;
return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0;
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05));
}
bool operator==(const address_v6& a1, const address_v6& a2)
@ -255,8 +248,7 @@ bool operator<(const address_v6& a1, const address_v6& a2)
address_v6 address_v6::loopback()
{
address_v6 tmp;
asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT;
tmp.addr_ = tmp_addr;
tmp.addr_.s6_addr[15] = 1;
return tmp;
}

View File

@ -42,12 +42,18 @@ void test()
ip::address_v4 addr1;
const ip::address_v4::bytes_type const_bytes_value = { { 127, 0, 0, 1 } };
ip::address_v4 addr2(const_bytes_value);
const unsigned long const_ulong_value = 0x7F00001;
const unsigned long const_ulong_value = 0x7F000001;
ip::address_v4 addr3(const_ulong_value);
// address_v4 functions.
bool b = addr1.is_class_a();
bool b = addr1.is_loopback();
(void)b;
b = addr1.is_unspecified();
(void)b;
b = addr1.is_class_a();
(void)b;
b = addr1.is_class_b();
@ -124,9 +130,140 @@ void test()
//------------------------------------------------------------------------------
// ip_address_v4_runtime test
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
// The following test checks that the various public member functions meet the
// necessary postconditions.
namespace ip_address_v4_runtime {
void test()
{
using asio::ip::address_v4;
address_v4 a1;
BOOST_CHECK(a1.to_bytes()[0] == 0);
BOOST_CHECK(a1.to_bytes()[1] == 0);
BOOST_CHECK(a1.to_bytes()[2] == 0);
BOOST_CHECK(a1.to_bytes()[3] == 0);
BOOST_CHECK(a1.to_ulong() == 0);
address_v4::bytes_type b1 = {{ 1, 2, 3, 4 }};
address_v4 a2(b1);
BOOST_CHECK(a2.to_bytes()[0] == 1);
BOOST_CHECK(a2.to_bytes()[1] == 2);
BOOST_CHECK(a2.to_bytes()[2] == 3);
BOOST_CHECK(a2.to_bytes()[3] == 4);
BOOST_CHECK(((a2.to_ulong() >> 24) & 0xFF) == b1[0]);
BOOST_CHECK(((a2.to_ulong() >> 16) & 0xFF) == b1[1]);
BOOST_CHECK(((a2.to_ulong() >> 8) & 0xFF) == b1[2]);
BOOST_CHECK((a2.to_ulong() & 0xFF) == b1[3]);
address_v4 a3(0x01020304);
BOOST_CHECK(a3.to_bytes()[0] == 1);
BOOST_CHECK(a3.to_bytes()[1] == 2);
BOOST_CHECK(a3.to_bytes()[2] == 3);
BOOST_CHECK(a3.to_bytes()[3] == 4);
BOOST_CHECK(a3.to_ulong() == 0x01020304);
BOOST_CHECK(address_v4(0x7F000001).is_loopback());
BOOST_CHECK(address_v4(0x7F000002).is_loopback());
BOOST_CHECK(!address_v4(0x00000000).is_loopback());
BOOST_CHECK(!address_v4(0x01020304).is_loopback());
BOOST_CHECK(address_v4(0x00000000).is_unspecified());
BOOST_CHECK(!address_v4(0x7F000001).is_unspecified());
BOOST_CHECK(!address_v4(0x01020304).is_unspecified());
BOOST_CHECK(address_v4(0x01000000).is_class_a());
BOOST_CHECK(address_v4(0x7F000000).is_class_a());
BOOST_CHECK(!address_v4(0x80000000).is_class_a());
BOOST_CHECK(!address_v4(0xBFFF0000).is_class_a());
BOOST_CHECK(!address_v4(0xC0000000).is_class_a());
BOOST_CHECK(!address_v4(0xDFFFFF00).is_class_a());
BOOST_CHECK(!address_v4(0xE0000000).is_class_a());
BOOST_CHECK(!address_v4(0xEFFFFFFF).is_class_a());
BOOST_CHECK(!address_v4(0xF0000000).is_class_a());
BOOST_CHECK(!address_v4(0xFFFFFFFF).is_class_a());
BOOST_CHECK(!address_v4(0x01000000).is_class_b());
BOOST_CHECK(!address_v4(0x7F000000).is_class_b());
BOOST_CHECK(address_v4(0x80000000).is_class_b());
BOOST_CHECK(address_v4(0xBFFF0000).is_class_b());
BOOST_CHECK(!address_v4(0xC0000000).is_class_b());
BOOST_CHECK(!address_v4(0xDFFFFF00).is_class_b());
BOOST_CHECK(!address_v4(0xE0000000).is_class_b());
BOOST_CHECK(!address_v4(0xEFFFFFFF).is_class_b());
BOOST_CHECK(!address_v4(0xF0000000).is_class_b());
BOOST_CHECK(!address_v4(0xFFFFFFFF).is_class_b());
BOOST_CHECK(!address_v4(0x01000000).is_class_c());
BOOST_CHECK(!address_v4(0x7F000000).is_class_c());
BOOST_CHECK(!address_v4(0x80000000).is_class_c());
BOOST_CHECK(!address_v4(0xBFFF0000).is_class_c());
BOOST_CHECK(address_v4(0xC0000000).is_class_c());
BOOST_CHECK(address_v4(0xDFFFFF00).is_class_c());
BOOST_CHECK(!address_v4(0xE0000000).is_class_c());
BOOST_CHECK(!address_v4(0xEFFFFFFF).is_class_c());
BOOST_CHECK(!address_v4(0xF0000000).is_class_c());
BOOST_CHECK(!address_v4(0xFFFFFFFF).is_class_c());
BOOST_CHECK(!address_v4(0x01000000).is_multicast());
BOOST_CHECK(!address_v4(0x7F000000).is_multicast());
BOOST_CHECK(!address_v4(0x80000000).is_multicast());
BOOST_CHECK(!address_v4(0xBFFF0000).is_multicast());
BOOST_CHECK(!address_v4(0xC0000000).is_multicast());
BOOST_CHECK(!address_v4(0xDFFFFF00).is_multicast());
BOOST_CHECK(address_v4(0xE0000000).is_multicast());
BOOST_CHECK(address_v4(0xEFFFFFFF).is_multicast());
BOOST_CHECK(!address_v4(0xF0000000).is_multicast());
BOOST_CHECK(!address_v4(0xFFFFFFFF).is_multicast());
address_v4 a4 = address_v4::any();
BOOST_CHECK(a4.to_bytes()[0] == 0);
BOOST_CHECK(a4.to_bytes()[1] == 0);
BOOST_CHECK(a4.to_bytes()[2] == 0);
BOOST_CHECK(a4.to_bytes()[3] == 0);
BOOST_CHECK(a4.to_ulong() == 0);
address_v4 a5 = address_v4::loopback();
BOOST_CHECK(a5.to_bytes()[0] == 0x7F);
BOOST_CHECK(a5.to_bytes()[1] == 0);
BOOST_CHECK(a5.to_bytes()[2] == 0);
BOOST_CHECK(a5.to_bytes()[3] == 0x01);
BOOST_CHECK(a5.to_ulong() == 0x7F000001);
address_v4 a6 = address_v4::broadcast();
BOOST_CHECK(a6.to_bytes()[0] == 0xFF);
BOOST_CHECK(a6.to_bytes()[1] == 0xFF);
BOOST_CHECK(a6.to_bytes()[2] == 0xFF);
BOOST_CHECK(a6.to_bytes()[3] == 0xFF);
BOOST_CHECK(a6.to_ulong() == 0xFFFFFFFF);
address_v4 class_a_net(0xFF000000);
address_v4 class_b_net(0xFFFF0000);
address_v4 class_c_net(0xFFFFFF00);
address_v4 other_net(0xFFFFFFFF);
BOOST_CHECK(address_v4::netmask(address_v4(0x01000000)) == class_a_net);
BOOST_CHECK(address_v4::netmask(address_v4(0x7F000000)) == class_a_net);
BOOST_CHECK(address_v4::netmask(address_v4(0x80000000)) == class_b_net);
BOOST_CHECK(address_v4::netmask(address_v4(0xBFFF0000)) == class_b_net);
BOOST_CHECK(address_v4::netmask(address_v4(0xC0000000)) == class_c_net);
BOOST_CHECK(address_v4::netmask(address_v4(0xDFFFFF00)) == class_c_net);
BOOST_CHECK(address_v4::netmask(address_v4(0xE0000000)) == other_net);
BOOST_CHECK(address_v4::netmask(address_v4(0xEFFFFFFF)) == other_net);
BOOST_CHECK(address_v4::netmask(address_v4(0xF0000000)) == other_net);
BOOST_CHECK(address_v4::netmask(address_v4(0xFFFFFFFF)) == other_net);
}
} // namespace ip_address_v4_runtime
//------------------------------------------------------------------------------
test_suite* init_unit_test_suite(int, char*[])
{
test_suite* test = BOOST_TEST_SUITE("ip/address_v4");
test->add(BOOST_TEST_CASE(&ip_address_v4_compile::test));
test->add(BOOST_TEST_CASE(&ip_address_v4_runtime::test));
return test;
}

View File

@ -145,9 +145,229 @@ void test()
//------------------------------------------------------------------------------
// ip_address_v6_runtime test
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
// The following test checks that the various public member functions meet the
// necessary postconditions.
namespace ip_address_v6_runtime {
void test()
{
using asio::ip::address_v6;
address_v6 a1;
BOOST_CHECK(a1.is_unspecified());
BOOST_CHECK(a1.scope_id() == 0);
address_v6::bytes_type b1 = {{ 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }};
address_v6 a2(b1, 12345);
BOOST_CHECK(a2.to_bytes()[0] == 1);
BOOST_CHECK(a2.to_bytes()[1] == 2);
BOOST_CHECK(a2.to_bytes()[2] == 3);
BOOST_CHECK(a2.to_bytes()[3] == 4);
BOOST_CHECK(a2.to_bytes()[4] == 5);
BOOST_CHECK(a2.to_bytes()[5] == 6);
BOOST_CHECK(a2.to_bytes()[6] == 7);
BOOST_CHECK(a2.to_bytes()[7] == 8);
BOOST_CHECK(a2.to_bytes()[8] == 9);
BOOST_CHECK(a2.to_bytes()[9] == 10);
BOOST_CHECK(a2.to_bytes()[10] == 11);
BOOST_CHECK(a2.to_bytes()[11] == 12);
BOOST_CHECK(a2.to_bytes()[12] == 13);
BOOST_CHECK(a2.to_bytes()[13] == 14);
BOOST_CHECK(a2.to_bytes()[14] == 15);
BOOST_CHECK(a2.to_bytes()[15] == 16);
BOOST_CHECK(a2.scope_id() == 12345);
address_v6 a3;
a3.scope_id(12345);
BOOST_CHECK(a3.scope_id() == 12345);
address_v6 unspecified_address;
address_v6::bytes_type loopback_bytes = {{ 0 }};
loopback_bytes[15] = 1;
address_v6 loopback_address(loopback_bytes);
address_v6::bytes_type link_local_bytes = {{ 0xFE, 0x80, 1 }};
address_v6 link_local_address(link_local_bytes);
address_v6::bytes_type site_local_bytes = {{ 0xFE, 0xC0, 1 }};
address_v6 site_local_address(site_local_bytes);
address_v6::bytes_type v4_mapped_bytes = {{ 0 }};
v4_mapped_bytes[10] = 0xFF, v4_mapped_bytes[11] = 0xFF;
v4_mapped_bytes[12] = 1, v4_mapped_bytes[13] = 2;
v4_mapped_bytes[14] = 3, v4_mapped_bytes[15] = 4;
address_v6 v4_mapped_address(v4_mapped_bytes);
address_v6::bytes_type v4_compat_bytes = {{ 0 }};
v4_compat_bytes[12] = 1, v4_compat_bytes[13] = 2;
v4_compat_bytes[14] = 3, v4_compat_bytes[15] = 4;
address_v6 v4_compat_address(v4_compat_bytes);
address_v6::bytes_type mcast_global_bytes = {{ 0xFF, 0x0E, 1 }};
address_v6 mcast_global_address(mcast_global_bytes);
address_v6::bytes_type mcast_link_local_bytes = {{ 0xFF, 0x02, 1 }};
address_v6 mcast_link_local_address(mcast_link_local_bytes);
address_v6::bytes_type mcast_node_local_bytes = {{ 0xFF, 0x01, 1 }};
address_v6 mcast_node_local_address(mcast_node_local_bytes);
address_v6::bytes_type mcast_org_local_bytes = {{ 0xFF, 0x08, 1 }};
address_v6 mcast_org_local_address(mcast_org_local_bytes);
address_v6::bytes_type mcast_site_local_bytes = {{ 0xFF, 0x05, 1 }};
address_v6 mcast_site_local_address(mcast_site_local_bytes);
BOOST_CHECK(!unspecified_address.is_loopback());
BOOST_CHECK(loopback_address.is_loopback());
BOOST_CHECK(!link_local_address.is_loopback());
BOOST_CHECK(!site_local_address.is_loopback());
BOOST_CHECK(!v4_mapped_address.is_loopback());
BOOST_CHECK(!v4_compat_address.is_loopback());
BOOST_CHECK(!mcast_global_address.is_loopback());
BOOST_CHECK(!mcast_link_local_address.is_loopback());
BOOST_CHECK(!mcast_node_local_address.is_loopback());
BOOST_CHECK(!mcast_org_local_address.is_loopback());
BOOST_CHECK(!mcast_site_local_address.is_loopback());
BOOST_CHECK(unspecified_address.is_unspecified());
BOOST_CHECK(!loopback_address.is_unspecified());
BOOST_CHECK(!link_local_address.is_unspecified());
BOOST_CHECK(!site_local_address.is_unspecified());
BOOST_CHECK(!v4_mapped_address.is_unspecified());
BOOST_CHECK(!v4_compat_address.is_unspecified());
BOOST_CHECK(!mcast_global_address.is_unspecified());
BOOST_CHECK(!mcast_link_local_address.is_unspecified());
BOOST_CHECK(!mcast_node_local_address.is_unspecified());
BOOST_CHECK(!mcast_org_local_address.is_unspecified());
BOOST_CHECK(!mcast_site_local_address.is_unspecified());
BOOST_CHECK(!unspecified_address.is_link_local());
BOOST_CHECK(!loopback_address.is_link_local());
BOOST_CHECK(link_local_address.is_link_local());
BOOST_CHECK(!site_local_address.is_link_local());
BOOST_CHECK(!v4_mapped_address.is_link_local());
BOOST_CHECK(!v4_compat_address.is_link_local());
BOOST_CHECK(!mcast_global_address.is_link_local());
BOOST_CHECK(!mcast_link_local_address.is_link_local());
BOOST_CHECK(!mcast_node_local_address.is_link_local());
BOOST_CHECK(!mcast_org_local_address.is_link_local());
BOOST_CHECK(!mcast_site_local_address.is_link_local());
BOOST_CHECK(!unspecified_address.is_site_local());
BOOST_CHECK(!loopback_address.is_site_local());
BOOST_CHECK(!link_local_address.is_site_local());
BOOST_CHECK(site_local_address.is_site_local());
BOOST_CHECK(!v4_mapped_address.is_site_local());
BOOST_CHECK(!v4_compat_address.is_site_local());
BOOST_CHECK(!mcast_global_address.is_site_local());
BOOST_CHECK(!mcast_link_local_address.is_site_local());
BOOST_CHECK(!mcast_node_local_address.is_site_local());
BOOST_CHECK(!mcast_org_local_address.is_site_local());
BOOST_CHECK(!mcast_site_local_address.is_site_local());
BOOST_CHECK(!unspecified_address.is_v4_mapped());
BOOST_CHECK(!loopback_address.is_v4_mapped());
BOOST_CHECK(!link_local_address.is_v4_mapped());
BOOST_CHECK(!site_local_address.is_v4_mapped());
BOOST_CHECK(v4_mapped_address.is_v4_mapped());
BOOST_CHECK(!v4_compat_address.is_v4_mapped());
BOOST_CHECK(!mcast_global_address.is_v4_mapped());
BOOST_CHECK(!mcast_link_local_address.is_v4_mapped());
BOOST_CHECK(!mcast_node_local_address.is_v4_mapped());
BOOST_CHECK(!mcast_org_local_address.is_v4_mapped());
BOOST_CHECK(!mcast_site_local_address.is_v4_mapped());
BOOST_CHECK(!unspecified_address.is_v4_compatible());
BOOST_CHECK(!loopback_address.is_v4_compatible());
BOOST_CHECK(!link_local_address.is_v4_compatible());
BOOST_CHECK(!site_local_address.is_v4_compatible());
BOOST_CHECK(!v4_mapped_address.is_v4_compatible());
BOOST_CHECK(v4_compat_address.is_v4_compatible());
BOOST_CHECK(!mcast_global_address.is_v4_compatible());
BOOST_CHECK(!mcast_link_local_address.is_v4_compatible());
BOOST_CHECK(!mcast_node_local_address.is_v4_compatible());
BOOST_CHECK(!mcast_org_local_address.is_v4_compatible());
BOOST_CHECK(!mcast_site_local_address.is_v4_compatible());
BOOST_CHECK(!unspecified_address.is_multicast());
BOOST_CHECK(!loopback_address.is_multicast());
BOOST_CHECK(!link_local_address.is_multicast());
BOOST_CHECK(!site_local_address.is_multicast());
BOOST_CHECK(!v4_mapped_address.is_multicast());
BOOST_CHECK(!v4_compat_address.is_multicast());
BOOST_CHECK(mcast_global_address.is_multicast());
BOOST_CHECK(mcast_link_local_address.is_multicast());
BOOST_CHECK(mcast_node_local_address.is_multicast());
BOOST_CHECK(mcast_org_local_address.is_multicast());
BOOST_CHECK(mcast_site_local_address.is_multicast());
BOOST_CHECK(!unspecified_address.is_multicast_global());
BOOST_CHECK(!loopback_address.is_multicast_global());
BOOST_CHECK(!link_local_address.is_multicast_global());
BOOST_CHECK(!site_local_address.is_multicast_global());
BOOST_CHECK(!v4_mapped_address.is_multicast_global());
BOOST_CHECK(!v4_compat_address.is_multicast_global());
BOOST_CHECK(mcast_global_address.is_multicast_global());
BOOST_CHECK(!mcast_link_local_address.is_multicast_global());
BOOST_CHECK(!mcast_node_local_address.is_multicast_global());
BOOST_CHECK(!mcast_org_local_address.is_multicast_global());
BOOST_CHECK(!mcast_site_local_address.is_multicast_global());
BOOST_CHECK(!unspecified_address.is_multicast_link_local());
BOOST_CHECK(!loopback_address.is_multicast_link_local());
BOOST_CHECK(!link_local_address.is_multicast_link_local());
BOOST_CHECK(!site_local_address.is_multicast_link_local());
BOOST_CHECK(!v4_mapped_address.is_multicast_link_local());
BOOST_CHECK(!v4_compat_address.is_multicast_link_local());
BOOST_CHECK(!mcast_global_address.is_multicast_link_local());
BOOST_CHECK(mcast_link_local_address.is_multicast_link_local());
BOOST_CHECK(!mcast_node_local_address.is_multicast_link_local());
BOOST_CHECK(!mcast_org_local_address.is_multicast_link_local());
BOOST_CHECK(!mcast_site_local_address.is_multicast_link_local());
BOOST_CHECK(!unspecified_address.is_multicast_node_local());
BOOST_CHECK(!loopback_address.is_multicast_node_local());
BOOST_CHECK(!link_local_address.is_multicast_node_local());
BOOST_CHECK(!site_local_address.is_multicast_node_local());
BOOST_CHECK(!v4_mapped_address.is_multicast_node_local());
BOOST_CHECK(!v4_compat_address.is_multicast_node_local());
BOOST_CHECK(!mcast_global_address.is_multicast_node_local());
BOOST_CHECK(!mcast_link_local_address.is_multicast_node_local());
BOOST_CHECK(mcast_node_local_address.is_multicast_node_local());
BOOST_CHECK(!mcast_org_local_address.is_multicast_node_local());
BOOST_CHECK(!mcast_site_local_address.is_multicast_node_local());
BOOST_CHECK(!unspecified_address.is_multicast_org_local());
BOOST_CHECK(!loopback_address.is_multicast_org_local());
BOOST_CHECK(!link_local_address.is_multicast_org_local());
BOOST_CHECK(!site_local_address.is_multicast_org_local());
BOOST_CHECK(!v4_mapped_address.is_multicast_org_local());
BOOST_CHECK(!v4_compat_address.is_multicast_org_local());
BOOST_CHECK(!mcast_global_address.is_multicast_org_local());
BOOST_CHECK(!mcast_link_local_address.is_multicast_org_local());
BOOST_CHECK(!mcast_node_local_address.is_multicast_org_local());
BOOST_CHECK(mcast_org_local_address.is_multicast_org_local());
BOOST_CHECK(!mcast_site_local_address.is_multicast_org_local());
BOOST_CHECK(!unspecified_address.is_multicast_site_local());
BOOST_CHECK(!loopback_address.is_multicast_site_local());
BOOST_CHECK(!link_local_address.is_multicast_site_local());
BOOST_CHECK(!site_local_address.is_multicast_site_local());
BOOST_CHECK(!v4_mapped_address.is_multicast_site_local());
BOOST_CHECK(!v4_compat_address.is_multicast_site_local());
BOOST_CHECK(!mcast_global_address.is_multicast_site_local());
BOOST_CHECK(!mcast_link_local_address.is_multicast_site_local());
BOOST_CHECK(!mcast_node_local_address.is_multicast_site_local());
BOOST_CHECK(!mcast_org_local_address.is_multicast_site_local());
BOOST_CHECK(mcast_site_local_address.is_multicast_site_local());
BOOST_CHECK(address_v6::loopback().is_loopback());
}
} // namespace ip_address_v6_runtime
//------------------------------------------------------------------------------
test_suite* init_unit_test_suite(int, char*[])
{
test_suite* test = BOOST_TEST_SUITE("ip/address_v6");
test->add(BOOST_TEST_CASE(&ip_address_v6_compile::test));
test->add(BOOST_TEST_CASE(&ip_address_v6_runtime::test));
return test;
}