1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the test suite of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <qhostaddress.h>
31#include <private/qhostaddress_p.h>
32#include <qcoreapplication.h>
33#include <QtTest/QtTest>
34#include <qplatformdefs.h>
35#include <qdebug.h>
36#include <qhash.h>
37#include <qbytearray.h>
38#include <qdatastream.h>
39#ifdef Q_OS_WIN
40# include <qt_windows.h>
41# if defined(Q_OS_WINRT)
42# include <winsock2.h>
43# endif
44#endif
45
46#ifdef Q_OS_ANDROID
47# include <netinet/in.h>
48#endif
49
50Q_DECLARE_METATYPE(AddressClassification)
51Q_DECLARE_METATYPE(QHostAddress::SpecialAddress)
52
53class tst_QHostAddress : public QObject
54{
55 Q_OBJECT
56
57public:
58 tst_QHostAddress();
59
60private slots:
61 void constructor_QString_data();
62 void constructor_QString();
63 void setAddress_QString_data();
64 void setAddress_QString();
65 void specialAddresses_data();
66 void specialAddresses();
67 void compare_data();
68 void compare();
69 void isEqual_data();
70 void isEqual();
71 void assignment();
72 void scopeId();
73 void hashKey();
74 void streaming_data();
75 void streaming();
76 void parseSubnet_data();
77 void parseSubnet();
78 void isInSubnet_data();
79 void isInSubnet();
80 void classification_data();
81 void classification();
82 void convertv4v6_data();
83 void convertv4v6();
84};
85
86Q_DECLARE_METATYPE(QHostAddress)
87
88tst_QHostAddress::tst_QHostAddress()
89{
90 qRegisterMetaType<QHostAddress>(typeName: "QHostAddress");
91}
92
93void tst_QHostAddress::constructor_QString_data()
94{
95 setAddress_QString_data();
96}
97
98void tst_QHostAddress::constructor_QString()
99{
100 QFETCH(QString, address);
101 QFETCH(bool, ok);
102 QFETCH(int, protocol);
103
104 QHostAddress hostAddr(address);
105
106 if (address == "0.0.0.0" || address == "::") {
107 QVERIFY(ok);
108 } else {
109 QVERIFY(hostAddr.isNull() != ok);
110 }
111
112 if (ok)
113 QTEST(hostAddr.toString(), "resAddr");
114
115 if ( protocol == 4 ) {
116 QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv4Protocol || hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol );
117 QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv6Protocol );
118 } else if ( protocol == 6 ) {
119 QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv4Protocol && hostAddr.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol );
120 QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv6Protocol );
121 } else {
122 QVERIFY( hostAddr.isNull() );
123 QVERIFY( hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol );
124 }
125}
126
127void tst_QHostAddress::setAddress_QString_data()
128{
129 QTest::addColumn<QString>(name: "address");
130 QTest::addColumn<bool>(name: "ok");
131 QTest::addColumn<QString>(name: "resAddr");
132 QTest::addColumn<int>(name: "protocol"); // 4: IPv4, 6: IPv6, other: undefined
133
134 //next we fill it with data
135 QTest::newRow(dataTag: "ip4_00") << QString("127.0.0.1") << true << QString("127.0.0.1") << 4;
136 QTest::newRow(dataTag: "ip4_01") << QString("255.3.2.1") << true << QString("255.3.2.1") << 4;
137 QTest::newRow(dataTag: "ip4_03") << QString(" 255.3.2.1") << true << QString("255.3.2.1") << 4;
138 QTest::newRow(dataTag: "ip4_04") << QString("255.3.2.1\r ") << true << QString("255.3.2.1") << 4;
139 QTest::newRow(dataTag: "ip4_05") << QString("0.0.0.0") << true << QString("0.0.0.0") << 4;
140 QTest::newRow(dataTag: "ip4_06") << QString("123.0.0") << true << QString("123.0.0.0") << 4;
141
142 // for the format of IPv6 addresses see also RFC 5952
143 // rule 4.1: Leading zeros MUST be suppressed
144 // rule 4.2.1: Shorten as Much as Possible
145 // rule 4.2.2: The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field.
146 // rule 4.2.3: the longest run of consecutive 16-bit 0 fields MUST be shortened
147 // When the length of the consecutive 16-bit 0 fields, the first sequence
148 // of zero bits MUST be shortened
149 // rule 4.3: The characters "a", "b", "c", "d", "e", and "f" in an IPv6 address
150 // MUST be represented in lowercase
151 QTest::newRow(dataTag: "ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << true << QString("fedc:ba98:7654:3210:fedc:ba98:7654:3210") << 6; // 4.3
152 QTest::newRow(dataTag: "ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; // 4.1, 4.2.1
153 QTest::newRow(dataTag: "ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6;
154 QTest::newRow(dataTag: "ip6_03") << QString("1080::8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6;
155 QTest::newRow(dataTag: "ip6_04") << QString("FF01::43") << true << QString("ff01::43") << 6;
156 QTest::newRow(dataTag: "ip6_05") << QString("::1") << true << QString("::1") << 6;
157 QTest::newRow(dataTag: "ip6_06") << QString("1::") << true << QString("1::") << 6;
158 QTest::newRow(dataTag: "ip6_07") << QString("::") << true << QString("::") << 6;
159 QTest::newRow(dataTag: "ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << true << QString("::13.1.68.3") << 6;
160 QTest::newRow(dataTag: "ip6_09") << QString("::13.1.68.3") << true << QString("::13.1.68.3") << 6;
161 QTest::newRow(dataTag: "ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << true << QString("::ffff:129.144.52.38") << 6;
162 QTest::newRow(dataTag: "ip6_11") << QString("::FFFF:129.144.52.38") << true << QString("::ffff:129.144.52.38") << 6;
163 QTest::newRow(dataTag: "ip6_12") << QString("1::FFFF:129.144.52.38") << true << QString("1::ffff:8190:3426") << 6;
164 QTest::newRow(dataTag: "ip6_13") << QString("A:B::D:E") << true << QString("a:b::d:e") << 6;
165 QTest::newRow(dataTag: "ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << true << QString("1080:0:1:0:8:800:200c:417a") << 6; // 4.2.2
166 QTest::newRow(dataTag: "ip6_15") << QString("1080:0:1:0:8:800:200C:0") << true << QString("1080:0:1:0:8:800:200c:0") << 6;
167 QTest::newRow(dataTag: "ip6_16") << QString("1080:0:1:0:8:800:0:0") << true << QString("1080:0:1:0:8:800::") << 6;
168 QTest::newRow(dataTag: "ip6_17a") << QString("1080:0:0:8:800:0:0:0") << true << QString("1080:0:0:8:800::") << 6; // 4.2.3a
169 QTest::newRow(dataTag: "ip6_17b") << QString("1080:0:0:0:8:0:0:0") << true << QString("1080::8:0:0:0") << 6; // 4.2.3b
170 QTest::newRow(dataTag: "ip6_18") << QString("0:1:1:1:8:800:0:0") << true << QString("0:1:1:1:8:800::") << 6;
171 QTest::newRow(dataTag: "ip6_19") << QString("0:1:1:1:8:800:0:1") << true << QString("0:1:1:1:8:800:0:1") << 6;
172
173 QTest::newRow(dataTag: "error_00") << QString("foobarcom") << false << QString() << 0;
174 QTest::newRow(dataTag: "error_01") << QString("foo.bar.com") << false << QString() << 0;
175 QTest::newRow(dataTag: "error_02") << QString("") << false << QString() << 0;
176 QTest::newRow(dataTag: "error_03") << QString() << false << QString() << 0;
177 QTest::newRow(dataTag: "error_04") << QString(" \t\r") << false << QString() << 0;
178
179 QTest::newRow(dataTag: "error_ip4_00") << QString("256.9.9.9") << false << QString() << 0;
180 QTest::newRow(dataTag: "error_ip4_01") << QString("-1.9.9.9") << false << QString() << 0;
181 //QTest::newRow("error_ip4_02") << QString("123.0.0") << false << QString() << 0; // no longer invalid in Qt5
182 QTest::newRow(dataTag: "error_ip4_02") << QString("123.0.0.") << false << QString() << 0;
183 QTest::newRow(dataTag: "error_ip4_03") << QString("123.0.0.0.0") << false << QString() << 0;
184 QTest::newRow(dataTag: "error_ip4_04") << QString("255.2 3.2.1") << false << QString() << 0;
185
186 QTest::newRow(dataTag: "error_ip6_00") << QString(":") << false << QString() << 0;
187 QTest::newRow(dataTag: "error_ip6_01") << QString(":::") << false << QString() << 0;
188 QTest::newRow(dataTag: "error_ip6_02") << QString("::AAAA:") << false << QString() << 0;
189 QTest::newRow(dataTag: "error_ip6_03") << QString(":AAAA::") << false << QString() << 0;
190 QTest::newRow(dataTag: "error_ip6_04") << QString("FFFF:::129.144.52.38") << false << QString() << 0;
191 QTest::newRow(dataTag: "error_ip6_05") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210:1234") << false << QString() << 0;
192 QTest::newRow(dataTag: "error_ip6_06") << QString("129.144.52.38::") << false << QString() << 0;
193 QTest::newRow(dataTag: "error_ip6_07") << QString("::129.144.52.38:129.144.52.38") << false << QString() << 0;
194 QTest::newRow(dataTag: "error_ip6_08") << QString(":::129.144.52.38") << false << QString() << 0;
195 QTest::newRow(dataTag: "error_ip6_09") << QString("1FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << false << QString() << 0;
196 QTest::newRow(dataTag: "error_ip6_10") << QString("::FFFFFFFF") << false << QString() << 0;
197 QTest::newRow(dataTag: "error_ip6_11") << QString("::EFGH") << false << QString() << 0;
198 QTest::newRow(dataTag: "error_ip6_12") << QString("ABCD:ABCD:ABCD") << false << QString() << 0;
199 QTest::newRow(dataTag: "error_ip6_13") << QString("::ABCD:ABCD::") << false << QString() << 0;
200 QTest::newRow(dataTag: "error_ip6_14") << QString("1::2::3") << false << QString() << 0;
201 QTest::newRow(dataTag: "error_ip6_15") << QString("1:2:::") << false << QString() << 0;
202 QTest::newRow(dataTag: "error_ip6_16") << QString(":::1:2") << false << QString() << 0;
203 QTest::newRow(dataTag: "error_ip6_17") << QString("1:::2") << false << QString() << 0;
204 QTest::newRow(dataTag: "error_ip6_18") << QString("FEDC::7654:3210:FEDC:BA98::3210") << false << QString() << 0;
205 QTest::newRow(dataTag: "error_ip6_19") << QString("ABCD:ABCD:ABCD:1.2.3.4") << false << QString() << 0;
206 QTest::newRow(dataTag: "error_ip6_20") << QString("ABCD::ABCD::ABCD:1.2.3.4") << false << QString() << 0;
207
208}
209
210void tst_QHostAddress::setAddress_QString()
211{
212 QFETCH(QString, address);
213 QFETCH(bool, ok);
214 QFETCH(int, protocol);
215
216 QHostAddress hostAddr;
217 QCOMPARE(hostAddr.setAddress(address), ok);
218
219 if (ok)
220 QTEST(hostAddr.toString(), "resAddr");
221
222 if ( protocol == 4 ) {
223 QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv4Protocol || hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol );
224 QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv6Protocol );
225 } else if ( protocol == 6 ) {
226 QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv4Protocol && hostAddr.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol );
227 QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv6Protocol );
228 } else {
229 QVERIFY( hostAddr.isNull() );
230 QVERIFY( hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol );
231 }
232}
233
234void tst_QHostAddress::specialAddresses_data()
235{
236 QTest::addColumn<QString>(name: "text");
237 QTest::addColumn<QHostAddress::SpecialAddress>(name: "address");
238 QTest::addColumn<bool>(name: "result");
239
240 QTest::newRow(dataTag: "localhost_1") << QString("127.0.0.1") << QHostAddress::LocalHost << true;
241 QTest::newRow(dataTag: "localhost_2") << QString("127.0.0.2") << QHostAddress::LocalHost << false;
242 QTest::newRow(dataTag: "localhost_3") << QString("127.0.0.2") << QHostAddress::LocalHostIPv6 << false;
243
244 QTest::newRow(dataTag: "localhost_ipv6_4") << QString("::1") << QHostAddress::LocalHostIPv6 << true;
245 QTest::newRow(dataTag: "localhost_ipv6_5") << QString("::2") << QHostAddress::LocalHostIPv6 << false;
246 QTest::newRow(dataTag: "localhost_ipv6_6") << QString("::1") << QHostAddress::LocalHost << false;
247
248 QTest::newRow(dataTag: "null_1") << QString("") << QHostAddress::Null << true;
249 QTest::newRow(dataTag: "null_2") << QString("bjarne") << QHostAddress::Null << true;
250
251 QTest::newRow(dataTag: "compare_from_null") << QString("") << QHostAddress::Broadcast << false;
252
253 QTest::newRow(dataTag: "broadcast_1") << QString("255.255.255.255") << QHostAddress::Any << false;
254 QTest::newRow(dataTag: "broadcast_2") << QString("255.255.255.255") << QHostAddress::Broadcast << true;
255
256 QTest::newRow(dataTag: "any_ipv6") << QString("::") << QHostAddress::AnyIPv6 << true;
257 QTest::newRow(dataTag: "any_ipv4") << QString("0.0.0.0") << QHostAddress::AnyIPv4 << true;
258
259 QTest::newRow(dataTag: "dual_not_ipv6") << QString("::") << QHostAddress::Any << false;
260 QTest::newRow(dataTag: "dual_not_ipv4") << QString("0.0.0.0") << QHostAddress::Any << false;
261}
262
263
264void tst_QHostAddress::specialAddresses()
265{
266 QFETCH(QString, text);
267 QFETCH(QHostAddress::SpecialAddress, address);
268 QFETCH(bool, result);
269 QCOMPARE(QHostAddress(text) == address, result);
270
271 //check special address equal to itself (QTBUG-22898), note two overloads of operator==
272 QVERIFY(QHostAddress(address) == QHostAddress(address));
273 QVERIFY(QHostAddress(address) == address);
274 QVERIFY(address == QHostAddress(address));
275 QVERIFY(!(QHostAddress(address) != QHostAddress(address)));
276 QVERIFY(!(QHostAddress(address) != address));
277 QVERIFY(!(address != QHostAddress(address)));
278
279 {
280 QHostAddress ha;
281 ha.setAddress(address);
282 QVERIFY(ha == address);
283 }
284
285 QHostAddress setter;
286 setter.setAddress(text);
287 QCOMPARE(setter == address, result);
288}
289
290
291void tst_QHostAddress::compare_data()
292{
293 QTest::addColumn<QHostAddress>(name: "first");
294 QTest::addColumn<QHostAddress>(name: "second");
295 QTest::addColumn<bool>(name: "result");
296
297 QTest::newRow(dataTag: "1") << QHostAddress() << QHostAddress() << true;
298 QTest::newRow(dataTag: "2") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::Any) << true;
299 QTest::newRow(dataTag: "3") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6) << true;
300 QTest::newRow(dataTag: "4") << QHostAddress(QHostAddress::Broadcast) << QHostAddress(QHostAddress::Broadcast) << true;
301 QTest::newRow(dataTag: "5") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::Broadcast) << false;
302 QTest::newRow(dataTag: "6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << false;
303 QTest::newRow(dataTag: "7") << QHostAddress() << QHostAddress(QHostAddress::LocalHostIPv6) << false;
304 QTest::newRow(dataTag: "any4-any6") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::AnyIPv6) << false;
305
306 Q_IPV6ADDR localhostv4mapped = { .c: { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1 } };
307 QTest::newRow(dataTag: "v4-v4mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("::ffff:127.0.0.1") << false;
308 QTest::newRow(dataTag: "v4-v4mapped-2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(localhostv4mapped) << false;
309}
310
311void tst_QHostAddress::compare()
312{
313 QFETCH(QHostAddress, first);
314 QFETCH(QHostAddress, second);
315 QFETCH(bool, result);
316
317 QCOMPARE(first == second, result);
318 QCOMPARE(second == first, result);
319 if (result == true)
320 QCOMPARE(qHash(first), qHash(second));
321}
322
323void tst_QHostAddress::isEqual_data()
324{
325 QTest::addColumn<QHostAddress>(name: "first");
326 QTest::addColumn<QHostAddress>(name: "second");
327 QTest::addColumn<int>(name: "flags");
328 QTest::addColumn<bool>(name: "result");
329
330 // QHostAddress::StrictConversion is already tested in compare()
331 QTest::newRow(dataTag: "localhost4to6-local") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertLocalHost << true;
332 QTest::newRow(dataTag: "localhost4to6-compat") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4CompatToIPv4 << false;
333 QTest::newRow(dataTag: "localhost4to6-mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
334 QTest::newRow(dataTag: "localhost4to6-unspec") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << false;
335 QTest::newRow(dataTag: "0.0.0.1-::1-local") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertLocalHost << false;
336 QTest::newRow(dataTag: "v4-v4compat-local") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertLocalHost << false;
337 QTest::newRow(dataTag: "v4-v4mapped-local") << QHostAddress("192.168.1.1") << QHostAddress("::ffff:192.168.1.1") << (int)QHostAddress::ConvertLocalHost << false;
338 QTest::newRow(dataTag: "0.0.0.1-::1-unspec") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << false;
339 QTest::newRow(dataTag: "v4-v4compat-unspec") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertUnspecifiedAddress << false;
340 QTest::newRow(dataTag: "v4-v4mapped-unspec") << QHostAddress("192.168.1.1") << QHostAddress("::ffff:192.168.1.1") << (int)QHostAddress::ConvertUnspecifiedAddress << false;
341 QTest::newRow(dataTag: "0.0.0.1-::1-compat") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4CompatToIPv4 << false;
342 QTest::newRow(dataTag: "v4-v4compat-compat") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertV4CompatToIPv4 << true;
343 QTest::newRow(dataTag: "v4-v4mapped-compat") << QHostAddress("192.168.1.1") << QHostAddress("::ffff:192.168.1.1") << (int)QHostAddress::ConvertV4CompatToIPv4 << false;
344 QTest::newRow(dataTag: "0.0.0.1-::1-mapped") << QHostAddress("0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
345 QTest::newRow(dataTag: "v4-v4compat-mapped") << QHostAddress("192.168.1.1") << QHostAddress("::192.168.1.1") << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
346 QTest::newRow(dataTag: "v4-v4mapped-mapped") << QHostAddress("192.168.1.1") << QHostAddress("::FFFF:192.168.1.1") << (int)QHostAddress::ConvertV4MappedToIPv4 << true;
347 QTest::newRow(dataTag: "undef-any-local") << QHostAddress() << QHostAddress(QHostAddress::Any) << (int)QHostAddress::ConvertLocalHost << false;
348 QTest::newRow(dataTag: "undef-any-unspec") << QHostAddress() << QHostAddress(QHostAddress::Any) << (int)QHostAddress::ConvertUnspecifiedAddress << false;
349 QTest::newRow(dataTag: "anyv6-anyv4-compat") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertV4CompatToIPv4 << true;
350 QTest::newRow(dataTag: "anyv6-anyv4-mapped") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertV4MappedToIPv4 << false;
351 QTest::newRow(dataTag: "anyv6-anyv4-unspec") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertUnspecifiedAddress << true;
352 QTest::newRow(dataTag: "any-anyv4-unspec") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertUnspecifiedAddress << true;
353 QTest::newRow(dataTag: "any-anyv6-unspec") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << true;
354 QTest::newRow(dataTag: "anyv6-anyv4-local") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false;
355 QTest::newRow(dataTag: "any-anyv4-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false;
356 QTest::newRow(dataTag: "any-anyv6-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::ConvertLocalHost << false;
357}
358
359void tst_QHostAddress::isEqual()
360{
361 QFETCH(QHostAddress, first);
362 QFETCH(QHostAddress, second);
363 QFETCH(int, flags);
364 QFETCH(bool, result);
365
366 QCOMPARE(first.isEqual(second, QHostAddress::ConversionModeFlag(flags)), result);
367 QCOMPARE(second.isEqual(first, QHostAddress::ConversionModeFlag(flags)), result);
368}
369
370QT_WARNING_PUSH
371#ifdef QT_WARNING_DISABLE_DEPRECATED
372QT_WARNING_DISABLE_DEPRECATED
373#endif
374
375void tst_QHostAddress::assignment()
376{
377 QHostAddress address;
378
379#if QT_DEPRECATED_SINCE(5, 8)
380 address = "127.0.0.1";
381 QCOMPARE(address, QHostAddress("127.0.0.1"));
382
383 address = "::1";
384 QCOMPARE(address, QHostAddress("::1"));
385#endif
386
387 // WinRT does not support sockaddr_in
388#ifndef Q_OS_WINRT
389 QHostAddress addr("4.2.2.1");
390 sockaddr_in sockAddr;
391 sockAddr.sin_family = AF_INET;
392 sockAddr.sin_addr.s_addr = htonl(hostlong: addr.toIPv4Address());
393 address.setAddress((sockaddr *)&sockAddr);
394 QCOMPARE(address, addr);
395#endif // !Q_OS_WINRT
396}
397
398QT_WARNING_POP
399
400void tst_QHostAddress::scopeId()
401{
402 QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0");
403 QCOMPARE(address.scopeId(), QString("eth0"));
404 QCOMPARE(address.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0"));
405
406 QHostAddress address2("fe80::2e0:4cff:fefb:662a");
407 QCOMPARE(address2.scopeId(), QString());
408 address2.setScopeId(QString("en0"));
409 QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%en0"));
410
411 address2 = address;
412 QCOMPARE(address2.scopeId(), QString("eth0"));
413 QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0"));
414}
415
416void tst_QHostAddress::hashKey()
417{
418 QHash<QHostAddress, QString> hostHash;
419 hostHash.insert(akey: QHostAddress(), avalue: "ole");
420}
421
422void tst_QHostAddress::streaming_data()
423{
424 QTest::addColumn<QHostAddress>(name: "address");
425 QTest::newRow(dataTag: "1") << QHostAddress();
426 QTest::newRow(dataTag: "2") << QHostAddress(0xDEADBEEF);
427 QTest::newRow(dataTag: "3") << QHostAddress("127.128.129.130");
428 QTest::newRow(dataTag: "4") << QHostAddress("1080:0000:0000:0000:0008:0800:200C:417A");
429 QTest::newRow(dataTag: "5") << QHostAddress("fe80::2e0:4cff:fefb:662a%eth0");
430 QTest::newRow(dataTag: "6") << QHostAddress(QHostAddress::Null);
431 QTest::newRow(dataTag: "7") << QHostAddress(QHostAddress::LocalHost);
432 QTest::newRow(dataTag: "8") << QHostAddress(QHostAddress::LocalHostIPv6);
433 QTest::newRow(dataTag: "9") << QHostAddress(QHostAddress::Broadcast);
434 QTest::newRow(dataTag: "10") << QHostAddress(QHostAddress::Any);
435 QTest::newRow(dataTag: "11") << QHostAddress(QHostAddress::AnyIPv4);
436 QTest::newRow(dataTag: "12") << QHostAddress(QHostAddress::AnyIPv6);
437 QTest::newRow(dataTag: "13") << QHostAddress("foo.bar.com");
438}
439
440void tst_QHostAddress::streaming()
441{
442 QFETCH(QHostAddress, address);
443 QByteArray ba;
444 QDataStream ds1(&ba, QIODevice::WriteOnly);
445 ds1 << address;
446 QCOMPARE(ds1.status(), QDataStream::Ok);
447 QDataStream ds2(&ba, QIODevice::ReadOnly);
448 QHostAddress address2;
449 ds2 >> address2;
450 QCOMPARE(ds2.status(), QDataStream::Ok);
451 QCOMPARE(address, address2);
452}
453
454void tst_QHostAddress::parseSubnet_data()
455{
456 QTest::addColumn<QString>(name: "subnet");
457 QTest::addColumn<QHostAddress>(name: "prefix");
458 QTest::addColumn<int>(name: "prefixLength");
459
460 // invalid/error values
461 QTest::newRow(dataTag: "empty") << QString() << QHostAddress() << -1;
462 QTest::newRow(dataTag: "invalid_01") << "foobar" << QHostAddress() << -1;
463 QTest::newRow(dataTag: "invalid_02") << " " << QHostAddress() << -1;
464 QTest::newRow(dataTag: "invalid_03") << "1.2.3.a" << QHostAddress() << -1;
465 QTest::newRow(dataTag: "invalid_04") << "1.2.3.4.5" << QHostAddress() << -1;
466 QTest::newRow(dataTag: "invalid_05") << "1.2.3.4:80" << QHostAddress() << -1;
467 QTest::newRow(dataTag: "invalid_06") << "1.2.3.4/33" << QHostAddress() << -1;
468 QTest::newRow(dataTag: "invalid_07") << "1.2.3.4/-1" << QHostAddress() << -1;
469 QTest::newRow(dataTag: "invalid_08") << "1.2.3.4/256.0.0.0" << QHostAddress() << -1;
470 QTest::newRow(dataTag: "invalid_09") << "1.2.3.4/255.253.0.0" << QHostAddress() << -1;
471 QTest::newRow(dataTag: "invalid_10") << "1.2.3.4/255.0.0.255" << QHostAddress() << -1;
472 QTest::newRow(dataTag: "invalid_11") << "1.2.3.4." << QHostAddress() << -1;
473 QTest::newRow(dataTag: "invalid_20") << "ffff::/-1" << QHostAddress() << -1;
474 QTest::newRow(dataTag: "invalid_21") << "ffff::/129" << QHostAddress() << -1;
475 QTest::newRow(dataTag: "invalid_22") << "ffff::/255.255.0.0" << QHostAddress() << -1;
476 QTest::newRow(dataTag: "invalid_23") << "ffff::/ff00::" << QHostAddress() << -1;
477
478 // correct IPv4 with netmask
479 QTest::newRow(dataTag: "netmask_0") << "0.0.0.0/0.0.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 0;
480 QTest::newRow(dataTag: "netmask_1") << "0.0.0.0/255.128.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 9;
481 QTest::newRow(dataTag: "netmask_2") << "0.0.0.0/255.192.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 10;
482 QTest::newRow(dataTag: "netmask_3") << "0.0.0.0/255.224.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 11;
483 QTest::newRow(dataTag: "netmask_4") << "0.0.0.0/255.240.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 12;
484 QTest::newRow(dataTag: "netmask_5") << "0.0.0.0/255.248.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 13;
485 QTest::newRow(dataTag: "netmask_6") << "0.0.0.0/255.252.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 14;
486 QTest::newRow(dataTag: "netmask_7") << "0.0.0.0/255.254.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 15;
487 QTest::newRow(dataTag: "netmask_8") << "0.0.0.0/255.255.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 16;
488 QTest::newRow(dataTag: "netmask_16") << "0.0.0.0/255.255.0.0" << QHostAddress(QHostAddress::AnyIPv4) << 16;
489 QTest::newRow(dataTag: "netmask_24") << "0.0.0.0/255.255.255.0" << QHostAddress(QHostAddress::AnyIPv4) << 24;
490 QTest::newRow(dataTag: "netmask_31") << "0.0.0.0/255.255.255.254" << QHostAddress(QHostAddress::AnyIPv4) << 31;
491 QTest::newRow(dataTag: "netmask_32") << "0.0.0.0/255.255.255.255" << QHostAddress(QHostAddress::AnyIPv4) << 32;
492
493 // correct IPv4 with prefix
494 QTest::newRow(dataTag: "prefix_0") << "0.0.0.0/0" << QHostAddress(QHostAddress::AnyIPv4) << 0;
495 QTest::newRow(dataTag: "prefix_1") << "0.0.0.0/1" << QHostAddress(QHostAddress::AnyIPv4) << 1;
496 QTest::newRow(dataTag: "prefix_9") << "0.0.0.0/9" << QHostAddress(QHostAddress::AnyIPv4) << 9;
497 QTest::newRow(dataTag: "prefix_31") << "0.0.0.0/31" << QHostAddress(QHostAddress::AnyIPv4) << 31;
498 QTest::newRow(dataTag: "prefix_32") << "0.0.0.0/32" << QHostAddress(QHostAddress::AnyIPv4) << 32;
499
500 // correct IPv4 without prefix or netmask
501 QTest::newRow(dataTag: "classA") << "10" << QHostAddress("10.0.0.0") << 8;
502 QTest::newRow(dataTag: "classA+dot") << "10." << QHostAddress("10.0.0.0") << 8;
503 QTest::newRow(dataTag: "classB") << "172.16" << QHostAddress("172.16.0.0") << 16;
504 QTest::newRow(dataTag: "classB+dot") << "172.16." << QHostAddress("172.16.0.0") << 16;
505 QTest::newRow(dataTag: "classC") << "192.168.0" << QHostAddress("192.168.0.0") << 24;
506 QTest::newRow(dataTag: "classC+dot") << "192.168.0" << QHostAddress("192.168.0.0") << 24;
507 QTest::newRow(dataTag: "full-ipv4") << "192.168.0.1" << QHostAddress("192.168.0.1") << 32;
508
509 // correct IPv6 with prefix
510 QTest::newRow(dataTag: "ipv6_01") << "::/0" << QHostAddress(QHostAddress::AnyIPv6) << 0;
511 QTest::newRow(dataTag: "ipv6_03") << "::/3" << QHostAddress(QHostAddress::AnyIPv6) << 3;
512 QTest::newRow(dataTag: "ipv6_16") << "::/16" << QHostAddress(QHostAddress::AnyIPv6) << 16;
513 QTest::newRow(dataTag: "ipv6_48") << "::/48" << QHostAddress(QHostAddress::AnyIPv6) << 48;
514 QTest::newRow(dataTag: "ipv6_127") << "::/127" << QHostAddress(QHostAddress::AnyIPv6) << 127;
515 QTest::newRow(dataTag: "ipv6_128") << "::/128" << QHostAddress(QHostAddress::AnyIPv6) << 128;
516
517 // tail bit clearing:
518 QTest::newRow(dataTag: "clear_01") << "255.255.255.255/31" << QHostAddress("255.255.255.254") << 31;
519 QTest::newRow(dataTag: "clear_08") << "255.255.255.255/24" << QHostAddress("255.255.255.0") << 24;
520 QTest::newRow(dataTag: "clear_09") << "255.255.255.255/23" << QHostAddress("255.255.254.0") << 23;
521 QTest::newRow(dataTag: "clear_10") << "255.255.255.255/22" << QHostAddress("255.255.252.0") << 22;
522 QTest::newRow(dataTag: "clear_11") << "255.255.255.255/21" << QHostAddress("255.255.248.0") << 21;
523 QTest::newRow(dataTag: "clear_12") << "255.255.255.255/20" << QHostAddress("255.255.240.0") << 20;
524 QTest::newRow(dataTag: "clear_13") << "255.255.255.255/19" << QHostAddress("255.255.224.0") << 19;
525 QTest::newRow(dataTag: "clear_14") << "255.255.255.255/18" << QHostAddress("255.255.192.0") << 18;
526 QTest::newRow(dataTag: "clear_15") << "255.255.255.255/17" << QHostAddress("255.255.128.0") << 17;
527 QTest::newRow(dataTag: "clear_16") << "255.255.255.255/16" << QHostAddress("255.255.0.0") << 16;
528 QTest::newRow(dataTag: "clear_24") << "255.255.255.255/8" << QHostAddress("255.0.0.0") << 8;
529 QTest::newRow(dataTag: "clear_31") << "255.255.255.255/1" << QHostAddress("128.0.0.0") << 1;
530 QTest::newRow(dataTag: "clear_32") << "255.255.255.255/0" << QHostAddress("0.0.0.0") << 0;
531
532 // same for IPv6:
533 QTest::newRow(dataTag: "ipv6_clear_01") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/127"
534 << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe")
535 << 127;
536 QTest::newRow(dataTag: "ipv6_clear_07") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/121"
537 << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80")
538 << 121;
539 QTest::newRow(dataTag: "ipv6_clear_08") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/120"
540 << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00")
541 << 120;
542 QTest::newRow(dataTag: "ipv6_clear_16") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/112"
543 << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0")
544 << 112;
545 QTest::newRow(dataTag: "ipv6_clear_80") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/48"
546 << QHostAddress("ffff:ffff:ffff::")
547 << 48;
548 QTest::newRow(dataTag: "ipv6_clear_81") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/47"
549 << QHostAddress("ffff:ffff:fffe::")
550 << 47;
551 QTest::newRow(dataTag: "ipv6_clear_82") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/46"
552 << QHostAddress("ffff:ffff:fffc::")
553 << 46;
554 QTest::newRow(dataTag: "ipv6_clear_83") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/45"
555 << QHostAddress("ffff:ffff:fff8::")
556 << 45;
557 QTest::newRow(dataTag: "ipv6_clear_84") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/44"
558 << QHostAddress("ffff:ffff:fff0::")
559 << 44;
560 QTest::newRow(dataTag: "ipv6_clear_85") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/43"
561 << QHostAddress("ffff:ffff:ffe0::")
562 << 43;
563 QTest::newRow(dataTag: "ipv6_clear_86") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/42"
564 << QHostAddress("ffff:ffff:ffc0::")
565 << 42;
566 QTest::newRow(dataTag: "ipv6_clear_87") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/41"
567 << QHostAddress("ffff:ffff:ff80::")
568 << 41;
569 QTest::newRow(dataTag: "ipv6_clear_88") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/40"
570 << QHostAddress("ffff:ffff:ff00::")
571 << 40;
572 QTest::newRow(dataTag: "ipv6_clear_125") << "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/3"
573 << QHostAddress("2000::")
574 << 3;
575 QTest::newRow(dataTag: "ipv6_clear_127") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/1"
576 << QHostAddress("8000::")
577 << 1;
578 QTest::newRow(dataTag: "ipv6_clear_128") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0"
579 << QHostAddress(QHostAddress::AnyIPv6)
580 << 0;
581}
582
583void tst_QHostAddress::parseSubnet()
584{
585 QFETCH(QString, subnet);
586 QFETCH(QHostAddress, prefix);
587 QFETCH(int, prefixLength);
588
589 QPair<QHostAddress, int> result = QHostAddress::parseSubnet(subnet);
590 QCOMPARE(result.first, prefix);
591 QCOMPARE(result.second, prefixLength);
592}
593
594void tst_QHostAddress::isInSubnet_data()
595{
596 QTest::addColumn<QHostAddress>(name: "address");
597 QTest::addColumn<QHostAddress>(name: "prefix");
598 QTest::addColumn<int>(name: "prefixLength");
599 QTest::addColumn<bool>(name: "result");
600
601 // invalid QHostAddresses are never in any subnets
602 QTest::newRow(dataTag: "invalid_01") << QHostAddress() << QHostAddress() << 32 << false;
603 QTest::newRow(dataTag: "invalid_02") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 32 << false;
604 QTest::newRow(dataTag: "invalid_03") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 8 << false;
605 QTest::newRow(dataTag: "invalid_04") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 0 << false;
606 QTest::newRow(dataTag: "invalid_05") << QHostAddress() << QHostAddress("255.255.255.0") << 24 << false;
607 QTest::newRow(dataTag: "invalid_06") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 0 << false;
608 QTest::newRow(dataTag: "invalid_07") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 32 << false;
609 QTest::newRow(dataTag: "invalid_08") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 128<< false;
610
611 // and no host address can be in a subnet whose prefix is invalid
612 QTest::newRow(dataTag: "invalid_20") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress() << 16 << false;
613 QTest::newRow(dataTag: "invalid_21") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress() << 16 << false;
614 QTest::newRow(dataTag: "invalid_22") << QHostAddress(QHostAddress::LocalHost) << QHostAddress() << 16 << false;
615 QTest::newRow(dataTag: "invalid_23") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress() << 16 << false;
616
617 // negative netmasks don't make sense:
618 QTest::newRow(dataTag: "invalid_30") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::Any) << -1 << false;
619 QTest::newRow(dataTag: "invalid_31") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6) << -1 << false;
620
621 // we don't support IPv4 belonging in an IPv6 netmask and vice-versa
622 QTest::newRow(dataTag: "v4-in-v6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv6) << 0 << false;
623 QTest::newRow(dataTag: "v6-in-v4") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::Any) << 0 << false;
624 QTest::newRow(dataTag: "v4-in-v6mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:255.0.0.0") << 113 << false;
625 QTest::newRow(dataTag: "v4-in-v6mapped2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("::ffff:255.0.0.0") << 113 << false;
626
627 // IPv4 correct ones
628 QTest::newRow(dataTag: "netmask_0") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << 0 << true;
629 QTest::newRow(dataTag: "netmask_0bis") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("255.255.0.0") << 0 << true;
630 QTest::newRow(dataTag: "netmask_0ter") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("1.2.3.4") << 0 << true;
631 QTest::newRow(dataTag: "netmask_1") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << 1 << true;
632 QTest::newRow(dataTag: "~netmask_1") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("128.0.0.0") << 1 << false;
633 QTest::newRow(dataTag: "netmask_1bis") << QHostAddress("224.0.0.1") << QHostAddress("128.0.0.0") << 1 << true;
634 QTest::newRow(dataTag: "~netmask_1bis") << QHostAddress("224.0.0.1") << QHostAddress("0.0.0.0") << 1 << false;
635 QTest::newRow(dataTag: "netmask_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("127.0.0.0") << 8 << true;
636 QTest::newRow(dataTag: "~netmask_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("126.0.0.0") << 8 << false;
637 QTest::newRow(dataTag: "netmask_15") << QHostAddress("10.0.1.255") << QHostAddress("10.0.0.0") << 15 << true;
638 QTest::newRow(dataTag: "netmask_16") << QHostAddress("172.16.0.1") << QHostAddress("172.16.0.0") << 16 << true;
639
640 // the address is always in the subnet containing its address, regardless of length:
641 QTest::newRow(dataTag: "same_01") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 1 << true;
642 QTest::newRow(dataTag: "same_07") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 7 << true;
643 QTest::newRow(dataTag: "same_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 8 << true;
644 QTest::newRow(dataTag: "same_24") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 23 << true;
645 QTest::newRow(dataTag: "same_31") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 31 << true;
646 QTest::newRow(dataTag: "same_32") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 32 << true;
647
648 // IPv6 correct ones:
649 QTest::newRow(dataTag: "ipv6_netmask_0") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << 0 << true;
650 QTest::newRow(dataTag: "ipv6_netmask_0bis") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::LocalHostIPv6) << 0 << true;
651 QTest::newRow(dataTag: "ipv6_netmask_0ter") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress("ffff::") << 0 << true;
652 QTest::newRow(dataTag: "ipv6_netmask_1") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << 1 << true;
653 QTest::newRow(dataTag: "ipv6_netmask_1bis") << QHostAddress("fec0::1") << QHostAddress("8000::") << 1 << true;
654 QTest::newRow(dataTag: "~ipv6_netmask_1") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress("8000::") << 1 << false;
655 QTest::newRow(dataTag: "~ipv6_netmask_1bis") << QHostAddress("fec0::1") << QHostAddress("::") << 1 << false;
656 QTest::newRow(dataTag: "ipv6_netmask_47") << QHostAddress("2:3:5::1") << QHostAddress("2:3:4::") << 47 << true;
657 QTest::newRow(dataTag: "ipv6_netmask_48") << QHostAddress("2:3:4::1") << QHostAddress("2:3:4::") << 48 << true;
658 QTest::newRow(dataTag: "~ipv6_netmask_48") << QHostAddress("2:3:5::1") << QHostAddress("2:3:4::") << 48 << false;
659 QTest::newRow(dataTag: "ipv6_netmask_127") << QHostAddress("2:3:4:5::1") << QHostAddress("2:3:4:5::") << 127 << true;
660 QTest::newRow(dataTag: "ipv6_netmask_128") << QHostAddress("2:3:4:5::1") << QHostAddress("2:3:4:5::1") << 128 << true;
661 QTest::newRow(dataTag: "~ipv6_netmask_128") << QHostAddress("2:3:4:5::1") << QHostAddress("2:3:4:5::0") << 128 << false;
662}
663
664void tst_QHostAddress::isInSubnet()
665{
666 QFETCH(QHostAddress, address);
667 QFETCH(QHostAddress, prefix);
668 QFETCH(int, prefixLength);
669
670 QTEST(address.isInSubnet(prefix, prefixLength), "result");
671}
672
673void tst_QHostAddress::classification_data()
674{
675 QTest::addColumn<QHostAddress>(name: "address");
676 QTest::addColumn<AddressClassification>(name: "result");
677
678 QTest::newRow(dataTag: "default") << QHostAddress() << UnknownAddress;
679 QTest::newRow(dataTag: "invalid") << QHostAddress("&&&") << UnknownAddress;
680
681 QTest::newRow(dataTag: "Any") << QHostAddress(QHostAddress::Any) << LocalNetAddress;
682 QTest::newRow(dataTag: "Null") << QHostAddress(QHostAddress::Null) << UnknownAddress;
683
684 // IPv6 address space
685 auto addV6 = [](const char *str, AddressClassification cl) {
686 QTest::newRow(dataTag: str) << QHostAddress(str) << cl;
687 };
688 QTest::newRow(dataTag: "AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << LocalNetAddress;
689 QTest::newRow(dataTag: "ipv6_loop") << QHostAddress(QHostAddress::LocalHostIPv6) << LoopbackAddress;
690 addV6("::", LocalNetAddress);
691 addV6("::1", LoopbackAddress);
692 addV6("::2", GlobalAddress);
693 addV6("2000::", GlobalAddress);
694 addV6("3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress);
695 addV6("fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress);
696 addV6("fc00::", UniqueLocalAddress);
697 addV6("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UniqueLocalAddress);
698 addV6("fe00::", UnknownAddress);
699 addV6("fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UnknownAddress);
700 addV6("fe80::", LinkLocalAddress);
701 addV6("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", LinkLocalAddress);
702 addV6("fec0::", SiteLocalAddress);
703 addV6("feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", SiteLocalAddress);
704 addV6("ff00::", MulticastAddress);
705 addV6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", MulticastAddress);
706
707 // IPv4 address space
708 auto addV4 = [](const char *str, AddressClassification cl) {
709 QTest::newRow(dataTag: str) << QHostAddress(str) << cl;
710 QByteArray v6 = "::ffff:";
711 v6 += str;
712 QTest::newRow(dataTag: v6.constData()) << QHostAddress(QString::fromLatin1(str: v6)) << cl;
713 };
714 QTest::newRow(dataTag: "AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << LocalNetAddress;
715 QTest::newRow(dataTag: "ipv4_loop") << QHostAddress(QHostAddress::LocalHost) << LoopbackAddress;
716 QTest::newRow(dataTag: "Broadcast") << QHostAddress(QHostAddress::Broadcast) << BroadcastAddress;
717 addV4("0.0.0.0", LocalNetAddress);
718 addV4("0.0.0.1", LocalNetAddress);
719 addV4("0.255.255.255", LocalNetAddress);
720 addV4("1.0.0.0", GlobalAddress);
721 addV4("1.2.3.4", GlobalAddress);
722 addV4("10.0.0.4", PrivateNetworkAddress);
723 addV4("127.0.0.1", LoopbackAddress);
724 addV4("127.0.0.2", LoopbackAddress);
725 addV4("127.255.255.255", LoopbackAddress);
726 addV4("192.168.3.4", PrivateNetworkAddress);
727 addV4("223.255.255.255", GlobalAddress);
728 addV4("224.0.0.0", MulticastAddress);
729 addV4("239.255.255.255", MulticastAddress);
730 addV4("240.0.0.0", UnknownAddress);
731 addV4("255.255.255.254", UnknownAddress);
732 addV4("255.255.255.255", BroadcastAddress);
733}
734
735void tst_QHostAddress::classification()
736{
737 QFETCH(QHostAddress, address);
738 QFETCH(AddressClassification, result);
739
740 bool isLoopback = (result == LoopbackAddress);
741 bool isGlobal = (result & GlobalAddress); // GlobalAddress is a bit
742 bool isLinkLocal = (result == LinkLocalAddress);
743 bool isSiteLocal = (result == SiteLocalAddress);
744 bool isUniqueLocalAddress = (result == UniqueLocalAddress);
745 bool isMulticast = (result == MulticastAddress);
746 bool isBroadcast = (result == BroadcastAddress);
747
748 QCOMPARE(address.isLoopback(), isLoopback);
749 QCOMPARE(address.isGlobal(), isGlobal);
750 QCOMPARE(address.isLinkLocal(), isLinkLocal);
751 QCOMPARE(address.isSiteLocal(), isSiteLocal);
752 QCOMPARE(address.isUniqueLocalUnicast(), isUniqueLocalAddress);
753 QCOMPARE(address.isMulticast(), isMulticast);
754 QCOMPARE(address.isBroadcast(), isBroadcast);
755}
756
757void tst_QHostAddress::convertv4v6_data()
758{
759 QTest::addColumn<QHostAddress>(name: "source");
760 QTest::addColumn<int>(name: "protocol");
761 QTest::addColumn<QHostAddress>(name: "result");
762
763 QTest::newRow(dataTag: "any-to-v4") << QHostAddress(QHostAddress::Any) << 4 << QHostAddress(QHostAddress::AnyIPv4);
764 QTest::newRow(dataTag: "any-to-v6") << QHostAddress(QHostAddress::Any) << 6 << QHostAddress(QHostAddress::AnyIPv6);
765 QTest::newRow(dataTag: "anyv4-to-v6") << QHostAddress(QHostAddress::AnyIPv4) << 6 << QHostAddress(QHostAddress::AnyIPv6);
766 QTest::newRow(dataTag: "anyv6-to-v4") << QHostAddress(QHostAddress::AnyIPv6) << 4 << QHostAddress(QHostAddress::AnyIPv4);
767
768 QTest::newRow(dataTag: "v4mapped-to-v4") << QHostAddress("::ffff:192.0.2.1") << 4 << QHostAddress("192.0.2.1");
769 QTest::newRow(dataTag: "v4-to-v4mapped") << QHostAddress("192.0.2.1") << 6 << QHostAddress("::ffff:192.0.2.1");
770
771 // we won't convert 127.0.0.1 to ::1 or vice-versa:
772 // you can connect to a v4 server socket with ::ffff:127.0.0.1, but not with ::1
773 QTest::newRow(dataTag: "localhost-to-v4mapped") << QHostAddress(QHostAddress::LocalHost) << 6 << QHostAddress("::ffff:127.0.0.1");
774 QTest::newRow(dataTag: "v4mapped-to-localhost") << QHostAddress("::ffff:127.0.0.1") << 4 << QHostAddress(QHostAddress::LocalHost);
775
776 // in turn, that means localhost6 doesn't convert to v4
777 QTest::newRow(dataTag: "localhost6-to-v4") << QHostAddress(QHostAddress::LocalHostIPv6) << 4 << QHostAddress();
778
779 // some other v6 addresses that won't convert to v4
780 QTest::newRow(dataTag: "v4compat-to-v4") << QHostAddress("::192.0.2.1") << 4 << QHostAddress();
781 QTest::newRow(dataTag: "localhostv4compat-to-v4") << QHostAddress("::127.0.0.1") << 4 << QHostAddress();
782 QTest::newRow(dataTag: "v6global-to-v4") << QHostAddress("2001:db8::1") << 4 << QHostAddress();
783 QTest::newRow(dataTag: "v6multicast-to-v4") << QHostAddress("ff02::1") << 4 << QHostAddress();
784}
785
786void tst_QHostAddress::convertv4v6()
787{
788 QFETCH(QHostAddress, source);
789 QFETCH(int, protocol);
790 QFETCH(QHostAddress, result);
791
792 if (protocol == 4) {
793 bool ok;
794 quint32 v4 = source.toIPv4Address(ok: &ok);
795 QCOMPARE(ok, result.protocol() == QAbstractSocket::IPv4Protocol);
796 if (ok)
797 QCOMPARE(QHostAddress(v4), result);
798 } else if (protocol == 6) {
799 QCOMPARE(QHostAddress(source.toIPv6Address()), result);
800 }
801}
802
803QTEST_MAIN(tst_QHostAddress)
804#include "tst_qhostaddress.moc"
805

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp