QHostAddress: add more classification functions
[ChangeLog][QtNetwork][QHostAddress] Added isGlobal(), isLinkLocal(), isSiteLocal(), isUniqueLocalUnicast(), and isBroadcast() classification functions to complement isLoopback() and isMulticast(). Change-Id: I3868166e5efc45538544fffd14d8fca6e9042c04 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
f93003e0c6
commit
cf7a97a658
@ -64,7 +64,6 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
class QHostAddressPrivate : public QSharedData
|
class QHostAddressPrivate : public QSharedData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -87,6 +86,8 @@ public:
|
|||||||
quint32 a; // IPv4 address
|
quint32 a; // IPv4 address
|
||||||
qint8 protocol;
|
qint8 protocol;
|
||||||
|
|
||||||
|
AddressClassification classify() const;
|
||||||
|
|
||||||
friend class QHostAddress;
|
friend class QHostAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -205,6 +206,75 @@ void QHostAddressPrivate::clear()
|
|||||||
memset(&a6, 0, sizeof(a6));
|
memset(&a6, 0, sizeof(a6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddressClassification QHostAddressPrivate::classify() const
|
||||||
|
{
|
||||||
|
if (a) {
|
||||||
|
// This is an IPv4 address or an IPv6 v4-mapped address includes all
|
||||||
|
// IPv6 v4-compat addresses, except for ::ffff:0.0.0.0 (because `a' is
|
||||||
|
// zero). See setAddress(quint8*) below, which calls convertToIpv4(),
|
||||||
|
// for details.
|
||||||
|
// Source: RFC 5735
|
||||||
|
if ((a & 0xff000000U) == 0x7f000000U) // 127.0.0.0/8
|
||||||
|
return LoopbackAddress;
|
||||||
|
if ((a & 0xf0000000U) == 0xe0000000U) // 224.0.0.0/4
|
||||||
|
return MulticastAddress;
|
||||||
|
if ((a & 0xffff0000U) == 0xa9fe0000U) // 169.254.0.0/16
|
||||||
|
return LinkLocalAddress;
|
||||||
|
if ((a & 0xff000000U) == 0) // 0.0.0.0/8 except 0.0.0.0 (handled below)
|
||||||
|
return LocalNetAddress;
|
||||||
|
if ((a & 0xf0000000U) == 0xf0000000U) { // 240.0.0.0/4
|
||||||
|
if (a == 0xffffffffU) // 255.255.255.255
|
||||||
|
return BroadcastAddress;
|
||||||
|
return UnknownAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not testing for PrivateNetworkAddress and TestNetworkAddress
|
||||||
|
// since we don't need them yet.
|
||||||
|
return GlobalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As `a' is zero, this address is either ::ffff:0.0.0.0 or a non-v4-mapped IPv6 address.
|
||||||
|
// Source: https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
|
||||||
|
if (a6_64.c[0]) {
|
||||||
|
quint32 high16 = qFromBigEndian(a6_32.c[0]) >> 16;
|
||||||
|
switch (high16 >> 8) {
|
||||||
|
case 0xff: // ff00::/8
|
||||||
|
return MulticastAddress;
|
||||||
|
case 0xfe:
|
||||||
|
switch (high16 & 0xffc0) {
|
||||||
|
case 0xfec0: // fec0::/10
|
||||||
|
return SiteLocalAddress;
|
||||||
|
|
||||||
|
case 0xfe80: // fe80::/10
|
||||||
|
return LinkLocalAddress;
|
||||||
|
|
||||||
|
default: // fe00::/9
|
||||||
|
return UnknownAddress;
|
||||||
|
}
|
||||||
|
case 0xfd: // fc00::/7
|
||||||
|
case 0xfc:
|
||||||
|
return UniqueLocalAddress;
|
||||||
|
default:
|
||||||
|
return GlobalAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 low64 = qFromBigEndian(a6_64.c[1]);
|
||||||
|
if (low64 == 1) // ::1
|
||||||
|
return LoopbackAddress;
|
||||||
|
if (low64 >> 32 == 0xffff) { // ::ffff:0.0.0.0/96
|
||||||
|
Q_ASSERT(quint32(low64) == 0);
|
||||||
|
return LocalNetAddress;
|
||||||
|
}
|
||||||
|
if (low64) // not ::
|
||||||
|
return GlobalAddress;
|
||||||
|
|
||||||
|
if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol)
|
||||||
|
return UnknownAddress;
|
||||||
|
|
||||||
|
// only :: and 0.0.0.0 remain now
|
||||||
|
return LocalNetAddress;
|
||||||
|
}
|
||||||
|
|
||||||
bool QNetmask::setAddress(const QHostAddress &address)
|
bool QNetmask::setAddress(const QHostAddress &address)
|
||||||
{
|
{
|
||||||
@ -1154,21 +1224,91 @@ QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet)
|
|||||||
*/
|
*/
|
||||||
bool QHostAddress::isLoopback() const
|
bool QHostAddress::isLoopback() const
|
||||||
{
|
{
|
||||||
if ((d->a & 0xFF000000) == 0x7F000000)
|
return d->classify() == LoopbackAddress;
|
||||||
return true; // v4 range (including IPv6 wrapped IPv4 addresses)
|
}
|
||||||
if (d->protocol == QAbstractSocket::IPv6Protocol) {
|
|
||||||
#ifdef __SSE2__
|
/*!
|
||||||
const __m128i loopback = _mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
|
\since 5.11
|
||||||
__m128i ipv6 = _mm_loadu_si128((const __m128i *)d->a6.c);
|
|
||||||
__m128i cmp = _mm_cmpeq_epi8(ipv6, loopback);
|
Returns \c true if the address is an IPv4 or IPv6 global address, \c false
|
||||||
return _mm_movemask_epi8(cmp) == 0xffff;
|
otherwise. A global address is an address that is not reserved for
|
||||||
#else
|
special purposes (like loopback or multicast) or future purposes.
|
||||||
if (d->a6_64.c[0] != 0 || qFromBigEndian(d->a6_64.c[1]) != 1)
|
|
||||||
return false;
|
Note that IPv6 unique local unicast addresses are considered global
|
||||||
#endif
|
addresses (see isUniqueLocalUnicast()), as are IPv4 addresses reserved for
|
||||||
return true;
|
local networks by \l {https://tools.ietf.org/html/rfc1918}{RFC 1918}.
|
||||||
}
|
|
||||||
return false;
|
Also note that IPv6 site-local addresses are deprecated and should be
|
||||||
|
considered as global in new applications. This function returns true for
|
||||||
|
site-local addresses too.
|
||||||
|
|
||||||
|
\sa isLoopback(), isSiteLocal(), isUniqueLocalUnicast()
|
||||||
|
*/
|
||||||
|
bool QHostAddress::isGlobal() const
|
||||||
|
{
|
||||||
|
return d->classify() & GlobalAddress; // GlobalAddress is a bit
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.11
|
||||||
|
|
||||||
|
Returns \c true if the address is an IPv4 or IPv6 link-local address, \c
|
||||||
|
false otherwise.
|
||||||
|
|
||||||
|
An IPv4 link-local address is an address in the network 169.254.0.0/16. An
|
||||||
|
IPv6 link-local address is one in the network fe80::/10. See the
|
||||||
|
\l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
|
||||||
|
IPv6 Address Space} registry for more information.
|
||||||
|
|
||||||
|
\sa isLoopback(), isGlobal(). isMulticast(), isSiteLocal(), isUniqueLocalUnicast()
|
||||||
|
*/
|
||||||
|
bool QHostAddress::isLinkLocal() const
|
||||||
|
{
|
||||||
|
return d->classify() == LinkLocalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.11
|
||||||
|
|
||||||
|
Returns \c true if the address is an IPv6 site-local address, \c
|
||||||
|
false otherwise.
|
||||||
|
|
||||||
|
An IPv6 site-local address is one in the network fec0::/10. See the
|
||||||
|
\l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
|
||||||
|
IPv6 Address Space} registry for more information.
|
||||||
|
|
||||||
|
IPv6 site-local addresses are deprecated and should not be depended upon in
|
||||||
|
new applications. New applications should not depend on this function and
|
||||||
|
should consider site-local addresses the same as global (which is why
|
||||||
|
isGlobal() also returns true). Site-local addresses were replaced by Unique
|
||||||
|
Local Addresses (ULA).
|
||||||
|
|
||||||
|
\sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
|
||||||
|
*/
|
||||||
|
bool QHostAddress::isSiteLocal() const
|
||||||
|
{
|
||||||
|
return d->classify() == SiteLocalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.11
|
||||||
|
|
||||||
|
Returns \c true if the address is an IPv6 unique local unicast address, \c
|
||||||
|
false otherwise.
|
||||||
|
|
||||||
|
An IPv6 unique local unicast address is one in the network fc00::/7. See the
|
||||||
|
\l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}
|
||||||
|
{IANA IPv6 Address Space} registry for more information.
|
||||||
|
|
||||||
|
Note that Unique local unicast addresses count as global addresses too. RFC
|
||||||
|
4193 says that, in practice, "applications may treat these addresses like
|
||||||
|
global scoped addresses." Only routers need care about the distinction.
|
||||||
|
|
||||||
|
\sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
|
||||||
|
*/
|
||||||
|
bool QHostAddress::isUniqueLocalUnicast() const
|
||||||
|
{
|
||||||
|
return d->classify() == UniqueLocalAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1176,14 +1316,29 @@ bool QHostAddress::isLoopback() const
|
|||||||
|
|
||||||
Returns \c true if the address is an IPv4 or IPv6 multicast address, \c
|
Returns \c true if the address is an IPv4 or IPv6 multicast address, \c
|
||||||
false otherwise.
|
false otherwise.
|
||||||
|
|
||||||
|
\sa isLoopback(), isGlobal(), isLinkLocal(), isSiteLocal(), isUniqueLocalUnicast()
|
||||||
*/
|
*/
|
||||||
bool QHostAddress::isMulticast() const
|
bool QHostAddress::isMulticast() const
|
||||||
{
|
{
|
||||||
if ((d->a & 0xF0000000) == 0xE0000000)
|
return d->classify() == MulticastAddress;
|
||||||
return true; // 224.0.0.0-239.255.255.255 (including v4-mapped IPv6 addresses)
|
}
|
||||||
if (d->protocol == QAbstractSocket::IPv6Protocol)
|
|
||||||
return d->a6.c[0] == 0xff;
|
/*!
|
||||||
return false;
|
\since 5.11
|
||||||
|
|
||||||
|
Returns \c true if the address is the IPv4 broadcast address, \c false
|
||||||
|
otherwise. The IPv4 broadcast address is 255.255.255.255.
|
||||||
|
|
||||||
|
Note that this function does not return true for an IPv4 network's local
|
||||||
|
broadcast address. For that, please use \l QNetworkInterface to obtain the
|
||||||
|
broadcast addresses of the local machine.
|
||||||
|
|
||||||
|
\sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
|
||||||
|
*/
|
||||||
|
bool QHostAddress::isBroadcast() const
|
||||||
|
{
|
||||||
|
return d->classify() == BroadcastAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
@ -148,7 +148,12 @@ public:
|
|||||||
bool isInSubnet(const QPair<QHostAddress, int> &subnet) const;
|
bool isInSubnet(const QPair<QHostAddress, int> &subnet) const;
|
||||||
|
|
||||||
bool isLoopback() const;
|
bool isLoopback() const;
|
||||||
|
bool isGlobal() const;
|
||||||
|
bool isLinkLocal() const;
|
||||||
|
bool isSiteLocal() const;
|
||||||
|
bool isUniqueLocalUnicast() const;
|
||||||
bool isMulticast() const;
|
bool isMulticast() const;
|
||||||
|
bool isBroadcast() const;
|
||||||
|
|
||||||
static QPair<QHostAddress, int> parseSubnet(const QString &subnet);
|
static QPair<QHostAddress, int> parseSubnet(const QString &subnet);
|
||||||
|
|
||||||
|
@ -57,6 +57,22 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
enum AddressClassification {
|
||||||
|
LoopbackAddress = 1,
|
||||||
|
LocalNetAddress, // RFC 1122
|
||||||
|
LinkLocalAddress, // RFC 4291 (v6), RFC 3927 (v4)
|
||||||
|
MulticastAddress, // RFC 4291 (v6), RFC 3171 (v4)
|
||||||
|
BroadcastAddress, // RFC 919, 922
|
||||||
|
|
||||||
|
GlobalAddress = 16,
|
||||||
|
TestNetworkAddress, // RFC 3849 (v6), RFC 5737 (v4),
|
||||||
|
PrivateNetworkAddress, // RFC 1918
|
||||||
|
UniqueLocalAddress, // RFC 4193
|
||||||
|
SiteLocalAddress, // RFC 4291 (deprecated by RFC 3879, should be treated as global)
|
||||||
|
|
||||||
|
UnknownAddress = 0 // unclassified or reserved
|
||||||
|
};
|
||||||
|
|
||||||
class QNetmask
|
class QNetmask
|
||||||
{
|
{
|
||||||
// stores 0-32 for IPv4, 0-128 for IPv6, or 255 for invalid
|
// stores 0-32 for IPv4, 0-128 for IPv6, or 255 for invalid
|
||||||
|
@ -2,7 +2,6 @@ CONFIG += testcase
|
|||||||
TARGET = tst_qhostaddress
|
TARGET = tst_qhostaddress
|
||||||
SOURCES += tst_qhostaddress.cpp
|
SOURCES += tst_qhostaddress.cpp
|
||||||
|
|
||||||
|
QT = core network-private testlib
|
||||||
QT = core network testlib
|
|
||||||
|
|
||||||
win32:LIBS += -lws2_32
|
win32:LIBS += -lws2_32
|
||||||
|
@ -27,9 +27,10 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <qhostaddress.h>
|
||||||
|
#include <private/qhostaddress_p.h>
|
||||||
#include <qcoreapplication.h>
|
#include <qcoreapplication.h>
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
#include <qhostaddress.h>
|
|
||||||
#include <qplatformdefs.h>
|
#include <qplatformdefs.h>
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <qhash.h>
|
#include <qhash.h>
|
||||||
@ -46,6 +47,7 @@
|
|||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(AddressClassification)
|
||||||
Q_DECLARE_METATYPE(QHostAddress::SpecialAddress)
|
Q_DECLARE_METATYPE(QHostAddress::SpecialAddress)
|
||||||
|
|
||||||
class tst_QHostAddress : public QObject
|
class tst_QHostAddress : public QObject
|
||||||
@ -75,10 +77,8 @@ private slots:
|
|||||||
void parseSubnet();
|
void parseSubnet();
|
||||||
void isInSubnet_data();
|
void isInSubnet_data();
|
||||||
void isInSubnet();
|
void isInSubnet();
|
||||||
void isLoopback_data();
|
void classification_data();
|
||||||
void isLoopback();
|
void classification();
|
||||||
void isMulticast_data();
|
|
||||||
void isMulticast();
|
|
||||||
void convertv4v6_data();
|
void convertv4v6_data();
|
||||||
void convertv4v6();
|
void convertv4v6();
|
||||||
};
|
};
|
||||||
@ -667,90 +667,88 @@ void tst_QHostAddress::isInSubnet()
|
|||||||
QTEST(address.isInSubnet(prefix, prefixLength), "result");
|
QTEST(address.isInSubnet(prefix, prefixLength), "result");
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QHostAddress::isLoopback_data()
|
void tst_QHostAddress::classification_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<QHostAddress>("address");
|
QTest::addColumn<QHostAddress>("address");
|
||||||
QTest::addColumn<bool>("result");
|
QTest::addColumn<AddressClassification>("result");
|
||||||
|
|
||||||
QTest::newRow("default") << QHostAddress() << false;
|
QTest::newRow("default") << QHostAddress() << UnknownAddress;
|
||||||
QTest::newRow("invalid") << QHostAddress("&&&") << false;
|
QTest::newRow("invalid") << QHostAddress("&&&") << UnknownAddress;
|
||||||
|
|
||||||
QTest::newRow("ipv6_loop") << QHostAddress(QHostAddress::LocalHostIPv6) << true;
|
QTest::newRow("Any") << QHostAddress(QHostAddress::Any) << LocalNetAddress;
|
||||||
QTest::newRow("::1") << QHostAddress("::1") << true;
|
QTest::newRow("Null") << QHostAddress(QHostAddress::Null) << UnknownAddress;
|
||||||
|
|
||||||
QTest::newRow("ipv4_loop") << QHostAddress(QHostAddress::LocalHost) << true;
|
// IPv6 address space
|
||||||
QTest::newRow("127.0.0.1") << QHostAddress("127.0.0.1") << true;
|
auto addV6 = [](const char *str, AddressClassification cl) {
|
||||||
QTest::newRow("127.0.0.2") << QHostAddress("127.0.0.2") << true;
|
QTest::newRow(str) << QHostAddress(str) << cl;
|
||||||
QTest::newRow("127.3.2.1") << QHostAddress("127.3.2.1") << true;
|
};
|
||||||
|
QTest::newRow("AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << LocalNetAddress;
|
||||||
QTest::newRow("1.2.3.4") << QHostAddress("1.2.3.4") << false;
|
QTest::newRow("ipv6_loop") << QHostAddress(QHostAddress::LocalHostIPv6) << LoopbackAddress;
|
||||||
QTest::newRow("10.0.0.4") << QHostAddress("10.0.0.4") << false;
|
addV6("::", LocalNetAddress);
|
||||||
QTest::newRow("192.168.3.4") << QHostAddress("192.168.3.4") << false;
|
addV6("::1", LoopbackAddress);
|
||||||
|
addV6("::2", GlobalAddress);
|
||||||
QTest::newRow("::") << QHostAddress("::") << false;
|
addV6("2000::", GlobalAddress);
|
||||||
QTest::newRow("Any") << QHostAddress(QHostAddress::Any) << false;
|
addV6("3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress);
|
||||||
QTest::newRow("AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << false;
|
addV6("fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress);
|
||||||
QTest::newRow("AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << false;
|
addV6("fc00::", UniqueLocalAddress);
|
||||||
QTest::newRow("Broadcast") << QHostAddress(QHostAddress::Broadcast) << false;
|
addV6("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UniqueLocalAddress);
|
||||||
QTest::newRow("Null") << QHostAddress(QHostAddress::Null) << false;
|
addV6("fe00::", UnknownAddress);
|
||||||
QTest::newRow("ipv6-all-ffff") << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") << false;
|
addV6("fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UnknownAddress);
|
||||||
|
addV6("fe80::", LinkLocalAddress);
|
||||||
QTest::newRow("::ffff:127.0.0.1") << QHostAddress("::ffff:127.0.0.1") << true;
|
addV6("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", LinkLocalAddress);
|
||||||
QTest::newRow("::ffff:127.0.0.2") << QHostAddress("::ffff:127.0.0.2") << true;
|
addV6("fec0::", SiteLocalAddress);
|
||||||
QTest::newRow("::ffff:127.3.2.1") << QHostAddress("::ffff:127.3.2.1") << true;
|
addV6("feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", SiteLocalAddress);
|
||||||
|
addV6("ff00::", MulticastAddress);
|
||||||
|
addV6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", MulticastAddress);
|
||||||
|
|
||||||
|
// IPv4 address space
|
||||||
|
auto addV4 = [](const char *str, AddressClassification cl) {
|
||||||
|
QTest::newRow(str) << QHostAddress(str) << cl;
|
||||||
|
QByteArray v6 = "::ffff:";
|
||||||
|
v6 += str;
|
||||||
|
QTest::newRow(v6.constData()) << QHostAddress(QString::fromLatin1(v6)) << cl;
|
||||||
|
};
|
||||||
|
QTest::newRow("AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << LocalNetAddress;
|
||||||
|
QTest::newRow("ipv4_loop") << QHostAddress(QHostAddress::LocalHost) << LoopbackAddress;
|
||||||
|
QTest::newRow("Broadcast") << QHostAddress(QHostAddress::Broadcast) << BroadcastAddress;
|
||||||
|
addV4("0.0.0.0", LocalNetAddress);
|
||||||
|
addV4("0.0.0.1", LocalNetAddress);
|
||||||
|
addV4("0.255.255.255", LocalNetAddress);
|
||||||
|
addV4("1.0.0.0", GlobalAddress);
|
||||||
|
addV4("1.2.3.4", GlobalAddress);
|
||||||
|
addV4("10.0.0.4", PrivateNetworkAddress);
|
||||||
|
addV4("127.0.0.1", LoopbackAddress);
|
||||||
|
addV4("127.0.0.2", LoopbackAddress);
|
||||||
|
addV4("127.255.255.255", LoopbackAddress);
|
||||||
|
addV4("192.168.3.4", PrivateNetworkAddress);
|
||||||
|
addV4("223.255.255.255", GlobalAddress);
|
||||||
|
addV4("224.0.0.0", MulticastAddress);
|
||||||
|
addV4("239.255.255.255", MulticastAddress);
|
||||||
|
addV4("240.0.0.0", UnknownAddress);
|
||||||
|
addV4("255.255.255.254", UnknownAddress);
|
||||||
|
addV4("255.255.255.255", BroadcastAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QHostAddress::isLoopback()
|
void tst_QHostAddress::classification()
|
||||||
{
|
{
|
||||||
QFETCH(QHostAddress, address);
|
QFETCH(QHostAddress, address);
|
||||||
QFETCH(bool, result);
|
QFETCH(AddressClassification, result);
|
||||||
|
|
||||||
QCOMPARE(address.isLoopback(), result);
|
bool isLoopback = (result == LoopbackAddress);
|
||||||
}
|
bool isGlobal = (result & GlobalAddress); // GlobalAddress is a bit
|
||||||
|
bool isLinkLocal = (result == LinkLocalAddress);
|
||||||
|
bool isSiteLocal = (result == SiteLocalAddress);
|
||||||
|
bool isUniqueLocalAddress = (result == UniqueLocalAddress);
|
||||||
|
bool isMulticast = (result == MulticastAddress);
|
||||||
|
bool isBroadcast = (result == BroadcastAddress);
|
||||||
|
|
||||||
void tst_QHostAddress::isMulticast_data()
|
QCOMPARE(address.isLoopback(), isLoopback);
|
||||||
{
|
QCOMPARE(address.isGlobal(), isGlobal);
|
||||||
QTest::addColumn<QHostAddress>("address");
|
QCOMPARE(address.isLinkLocal(), isLinkLocal);
|
||||||
QTest::addColumn<bool>("result");
|
QCOMPARE(address.isSiteLocal(), isSiteLocal);
|
||||||
|
QCOMPARE(address.isUniqueLocalUnicast(), isUniqueLocalAddress);
|
||||||
QTest::newRow("default") << QHostAddress() << false;
|
QCOMPARE(address.isMulticast(), isMulticast);
|
||||||
QTest::newRow("invalid") << QHostAddress("&&&") << false;
|
QCOMPARE(address.isBroadcast(), isBroadcast);
|
||||||
|
|
||||||
QTest::newRow("ipv6_loop") << QHostAddress(QHostAddress::LocalHostIPv6) << false;
|
|
||||||
QTest::newRow("::1") << QHostAddress("::1") << false;
|
|
||||||
QTest::newRow("ipv4_loop") << QHostAddress(QHostAddress::LocalHost) << false;
|
|
||||||
QTest::newRow("127.0.0.1") << QHostAddress("127.0.0.1") << false;
|
|
||||||
QTest::newRow("::") << QHostAddress("::") << false;
|
|
||||||
QTest::newRow("Any") << QHostAddress(QHostAddress::Any) << false;
|
|
||||||
QTest::newRow("AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << false;
|
|
||||||
QTest::newRow("AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << false;
|
|
||||||
QTest::newRow("Broadcast") << QHostAddress(QHostAddress::Broadcast) << false;
|
|
||||||
QTest::newRow("Null") << QHostAddress(QHostAddress::Null) << false;
|
|
||||||
|
|
||||||
QTest::newRow("223.255.255.255") << QHostAddress("223.255.255.255") << false;
|
|
||||||
QTest::newRow("224.0.0.0") << QHostAddress("224.0.0.0") << true;
|
|
||||||
QTest::newRow("239.255.255.255") << QHostAddress("239.255.255.255") << true;
|
|
||||||
QTest::newRow("240.0.0.0") << QHostAddress("240.0.0.0") << false;
|
|
||||||
|
|
||||||
QTest::newRow("::ffff:223.255.255.255") << QHostAddress("::ffff:223.255.255.255") << false;
|
|
||||||
QTest::newRow("::ffff:224.0.0.0") << QHostAddress("::ffff:224.0.0.0") << true;
|
|
||||||
QTest::newRow("::ffff:239.255.255.255") << QHostAddress("::ffff:239.255.255.255") << true;
|
|
||||||
QTest::newRow("::ffff:240.0.0.0") << QHostAddress("::ffff:240.0.0.0") << false;
|
|
||||||
|
|
||||||
QTest::newRow("fc00::") << QHostAddress("fc00::") << false;
|
|
||||||
QTest::newRow("fe80::") << QHostAddress("fe80::") << false;
|
|
||||||
QTest::newRow("fec0::") << QHostAddress("fec0::") << false;
|
|
||||||
QTest::newRow("ff00::") << QHostAddress("ff00::") << true;
|
|
||||||
QTest::newRow("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") << true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QHostAddress::isMulticast()
|
|
||||||
{
|
|
||||||
QFETCH(QHostAddress, address);
|
|
||||||
QFETCH(bool, result);
|
|
||||||
|
|
||||||
QCOMPARE(address.isMulticast(), result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QHostAddress::convertv4v6_data()
|
void tst_QHostAddress::convertv4v6_data()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user