1/****************************************************************************
2**
3** Copyright (C) 2017 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 QtNetwork module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
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 Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qhostaddress.h"
42#include "qhostaddress_p.h"
43#include "private/qipaddress_p.h"
44#include "qdebug.h"
45#if defined(Q_OS_WIN)
46# include <winsock2.h>
47# include <ws2tcpip.h>
48#else
49# include <netinet/in.h>
50#endif
51#include "qplatformdefs.h"
52#include "qstringlist.h"
53#include "qendian.h"
54#ifndef QT_NO_DATASTREAM
55#include <qdatastream.h>
56#endif
57#ifdef __SSE2__
58# include <private/qsimd_p.h>
59#endif
60
61#ifdef QT_LINUXBASE
62# include <arpa/inet.h>
63#endif
64
65QT_BEGIN_NAMESPACE
66
67QHostAddressPrivate::QHostAddressPrivate()
68 : a(0), protocol(QAbstractSocket::UnknownNetworkLayerProtocol)
69{
70 memset(s: &a6, c: 0, n: sizeof(a6));
71}
72
73void QHostAddressPrivate::setAddress(quint32 a_)
74{
75 a = a_;
76 protocol = QAbstractSocket::IPv4Protocol;
77
78 //create mapped address, except for a_ == 0 (any)
79 a6_64.c[0] = 0;
80 if (a) {
81 a6_32.c[2] = qToBigEndian(source: 0xffff);
82 a6_32.c[3] = qToBigEndian(source: a);
83 } else {
84 a6_64.c[1] = 0;
85 }
86}
87
88/// parses v4-mapped addresses or the AnyIPv6 address and stores in \a a;
89/// returns true if the address was one of those
90static bool convertToIpv4(quint32& a, const Q_IPV6ADDR &a6, const QHostAddress::ConversionMode mode)
91{
92 if (mode == QHostAddress::StrictConversion)
93 return false;
94
95 const uchar *ptr = a6.c;
96 if (qFromUnaligned<quint64>(src: ptr) != 0)
97 return false;
98
99 const quint32 mid = qFromBigEndian<quint32>(src: ptr + 8);
100 if ((mid == 0xffff) && (mode & QHostAddress::ConvertV4MappedToIPv4)) {
101 a = qFromBigEndian<quint32>(src: ptr + 12);
102 return true;
103 }
104 if (mid != 0)
105 return false;
106
107 const quint32 low = qFromBigEndian<quint32>(src: ptr + 12);
108 if ((low == 0) && (mode & QHostAddress::ConvertUnspecifiedAddress)) {
109 a = 0;
110 return true;
111 }
112 if ((low == 1) && (mode & QHostAddress::ConvertLocalHost)) {
113 a = INADDR_LOOPBACK;
114 return true;
115 }
116 if ((low != 1) && (mode & QHostAddress::ConvertV4CompatToIPv4)) {
117 a = low;
118 return true;
119 }
120 return false;
121}
122
123void QHostAddressPrivate::setAddress(const quint8 *a_)
124{
125 protocol = QAbstractSocket::IPv6Protocol;
126 memcpy(dest: a6.c, src: a_, n: sizeof(a6));
127 a = 0;
128 convertToIpv4(a, a6: a6, mode: (QHostAddress::ConvertV4MappedToIPv4
129 | QHostAddress::ConvertUnspecifiedAddress));
130}
131
132void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_)
133{
134 setAddress(a_.c);
135}
136
137static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr, QString *scopeId)
138{
139 QStringRef tmp(&address);
140 int scopeIdPos = tmp.lastIndexOf(ch: QLatin1Char('%'));
141 if (scopeIdPos != -1) {
142 *scopeId = tmp.mid(pos: scopeIdPos + 1).toString();
143 tmp.chop(n: tmp.size() - scopeIdPos);
144 } else {
145 scopeId->clear();
146 }
147 return QIPAddressUtils::parseIp6(address&: addr, begin: tmp.constBegin(), end: tmp.constEnd()) == nullptr;
148}
149
150bool QHostAddressPrivate::parse(const QString &ipString)
151{
152 protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
153 QString a = ipString.simplified();
154 if (a.isEmpty())
155 return false;
156
157 // All IPv6 addresses contain a ':', and may contain a '.'.
158 if (a.contains(c: QLatin1Char(':'))) {
159 quint8 maybeIp6[16];
160 if (parseIp6(address: a, addr&: maybeIp6, scopeId: &scopeId)) {
161 setAddress(maybeIp6);
162 return true;
163 }
164 }
165
166 quint32 maybeIp4 = 0;
167 if (QIPAddressUtils::parseIp4(address&: maybeIp4, begin: a.constBegin(), end: a.constEnd())) {
168 setAddress(maybeIp4);
169 return true;
170 }
171
172 return false;
173}
174
175void QHostAddressPrivate::clear()
176{
177 a = 0;
178 protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
179 memset(s: &a6, c: 0, n: sizeof(a6));
180}
181
182AddressClassification QHostAddressPrivate::classify() const
183{
184 if (a) {
185 // This is an IPv4 address or an IPv6 v4-mapped address includes all
186 // IPv6 v4-compat addresses, except for ::ffff:0.0.0.0 (because `a' is
187 // zero). See setAddress(quint8*) below, which calls convertToIpv4(),
188 // for details.
189 // Source: RFC 5735
190 if ((a & 0xff000000U) == 0x7f000000U) // 127.0.0.0/8
191 return LoopbackAddress;
192 if ((a & 0xf0000000U) == 0xe0000000U) // 224.0.0.0/4
193 return MulticastAddress;
194 if ((a & 0xffff0000U) == 0xa9fe0000U) // 169.254.0.0/16
195 return LinkLocalAddress;
196 if ((a & 0xff000000U) == 0) // 0.0.0.0/8 except 0.0.0.0 (handled below)
197 return LocalNetAddress;
198 if ((a & 0xf0000000U) == 0xf0000000U) { // 240.0.0.0/4
199 if (a == 0xffffffffU) // 255.255.255.255
200 return BroadcastAddress;
201 return UnknownAddress;
202 }
203
204 // Not testing for PrivateNetworkAddress and TestNetworkAddress
205 // since we don't need them yet.
206 return GlobalAddress;
207 }
208
209 // As `a' is zero, this address is either ::ffff:0.0.0.0 or a non-v4-mapped IPv6 address.
210 // Source: https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
211 if (a6_64.c[0]) {
212 quint32 high16 = qFromBigEndian(source: a6_32.c[0]) >> 16;
213 switch (high16 >> 8) {
214 case 0xff: // ff00::/8
215 return MulticastAddress;
216 case 0xfe:
217 switch (high16 & 0xffc0) {
218 case 0xfec0: // fec0::/10
219 return SiteLocalAddress;
220
221 case 0xfe80: // fe80::/10
222 return LinkLocalAddress;
223
224 default: // fe00::/9
225 return UnknownAddress;
226 }
227 case 0xfd: // fc00::/7
228 case 0xfc:
229 return UniqueLocalAddress;
230 default:
231 return GlobalAddress;
232 }
233 }
234
235 quint64 low64 = qFromBigEndian(source: a6_64.c[1]);
236 if (low64 == 1) // ::1
237 return LoopbackAddress;
238 if (low64 >> 32 == 0xffff) { // ::ffff:0.0.0.0/96
239 Q_ASSERT(quint32(low64) == 0);
240 return LocalNetAddress;
241 }
242 if (low64) // not ::
243 return GlobalAddress;
244
245 if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol)
246 return UnknownAddress;
247
248 // only :: and 0.0.0.0 remain now
249 return LocalNetAddress;
250}
251
252bool QNetmask::setAddress(const QHostAddress &address)
253{
254 static const quint8 zeroes[16] = { 0 };
255 union {
256 quint32 v4;
257 quint8 v6[16];
258 } ip;
259
260 int netmask = 0;
261 quint8 *ptr = ip.v6;
262 quint8 *end;
263 length = 255;
264
265 if (address.protocol() == QAbstractSocket::IPv4Protocol) {
266 ip.v4 = qToBigEndian(source: address.toIPv4Address());
267 end = ptr + 4;
268 } else if (address.protocol() == QAbstractSocket::IPv6Protocol) {
269 memcpy(dest: ip.v6, src: address.toIPv6Address().c, n: 16);
270 end = ptr + 16;
271 } else {
272 return false;
273 }
274
275 while (ptr < end) {
276 switch (*ptr) {
277 case 255:
278 netmask += 8;
279 ++ptr;
280 continue;
281
282 default:
283 return false; // invalid IP-style netmask
284
285 case 254:
286 ++netmask;
287 Q_FALLTHROUGH();
288 case 252:
289 ++netmask;
290 Q_FALLTHROUGH();
291 case 248:
292 ++netmask;
293 Q_FALLTHROUGH();
294 case 240:
295 ++netmask;
296 Q_FALLTHROUGH();
297 case 224:
298 ++netmask;
299 Q_FALLTHROUGH();
300 case 192:
301 ++netmask;
302 Q_FALLTHROUGH();
303 case 128:
304 ++netmask;
305 Q_FALLTHROUGH();
306 case 0:
307 break;
308 }
309 break;
310 }
311
312 // confirm that the rest is only zeroes
313 if (ptr < end && memcmp(s1: ptr + 1, s2: zeroes, n: end - ptr - 1) != 0)
314 return false;
315
316 length = netmask;
317 return true;
318}
319
320static void clearBits(quint8 *where, int start, int end)
321{
322 Q_ASSERT(end == 32 || end == 128);
323 if (start == end)
324 return;
325
326 // for the byte where 'start' is, clear the lower bits only
327 quint8 bytemask = 256 - (1 << (8 - (start & 7)));
328 where[start / 8] &= bytemask;
329
330 // for the tail part, clear everything
331 memset(s: where + (start + 7) / 8, c: 0, n: end / 8 - (start + 7) / 8);
332}
333
334QHostAddress QNetmask::address(QAbstractSocket::NetworkLayerProtocol protocol) const
335{
336 if (length == 255 || protocol == QAbstractSocket::AnyIPProtocol ||
337 protocol == QAbstractSocket::UnknownNetworkLayerProtocol) {
338 return QHostAddress();
339 } else if (protocol == QAbstractSocket::IPv4Protocol) {
340 quint32 a;
341 if (length == 0)
342 a = 0;
343 else if (length == 32)
344 a = quint32(0xffffffff);
345 else
346 a = quint32(0xffffffff) >> (32 - length) << (32 - length);
347 return QHostAddress(a);
348 } else {
349 Q_IPV6ADDR a6;
350 memset(s: a6.c, c: 0xFF, n: sizeof(a6));
351 clearBits(where: a6.c, start: length, end: 128);
352 return QHostAddress(a6);
353 }
354}
355
356/*!
357 \class QHostAddress
358 \brief The QHostAddress class provides an IP address.
359 \ingroup network
360 \ingroup shared
361 \inmodule QtNetwork
362
363 This class holds an IPv4 or IPv6 address in a platform- and
364 protocol-independent manner.
365
366 QHostAddress is normally used with the QTcpSocket, QTcpServer,
367 and QUdpSocket to connect to a host or to set up a server.
368
369 A host address is set with setAddress(), and retrieved with
370 toIPv4Address(), toIPv6Address(), or toString(). You can check the
371 type with protocol().
372
373 \note Please note that QHostAddress does not do DNS lookups.
374 QHostInfo is needed for that.
375
376 The class also supports common predefined addresses: \l Null, \l
377 LocalHost, \l LocalHostIPv6, \l Broadcast, and \l Any.
378
379 \sa QHostInfo, QTcpSocket, QTcpServer, QUdpSocket
380*/
381
382/*! \enum QHostAddress::SpecialAddress
383
384 \value Null The null address object. Equivalent to QHostAddress(). See also QHostAddress::isNull().
385 \value LocalHost The IPv4 localhost address. Equivalent to QHostAddress("127.0.0.1").
386 \value LocalHostIPv6 The IPv6 localhost address. Equivalent to QHostAddress("::1").
387 \value Broadcast The IPv4 broadcast address. Equivalent to QHostAddress("255.255.255.255").
388 \value AnyIPv4 The IPv4 any-address. Equivalent to QHostAddress("0.0.0.0"). A socket bound with this address will listen only on IPv4 interfaces.
389 \value AnyIPv6 The IPv6 any-address. Equivalent to QHostAddress("::"). A socket bound with this address will listen only on IPv6 interfaces.
390 \value Any The dual stack any-address. A socket bound with this address will listen on both IPv4 and IPv6 interfaces.
391*/
392
393/*! \enum QHostAddress::ConversionModeFlag
394
395 \since 5.8
396
397 \value StrictConversion Don't convert IPv6 addresses to IPv4 when comparing two QHostAddress objects of different protocols, so they will always be considered different.
398 \value ConvertV4MappedToIPv4 Convert IPv4-mapped IPv6 addresses (RFC 4291 sect. 2.5.5.2) when comparing. Therefore QHostAddress("::ffff:192.168.1.1") will compare equal to QHostAddress("192.168.1.1").
399 \value ConvertV4CompatToIPv4 Convert IPv4-compatible IPv6 addresses (RFC 4291 sect. 2.5.5.1) when comparing. Therefore QHostAddress("::192.168.1.1") will compare equal to QHostAddress("192.168.1.1").
400 \value ConvertLocalHost Convert the IPv6 loopback addresses to its IPv4 equivalent when comparing. Therefore e.g. QHostAddress("::1") will compare equal to QHostAddress("127.0.0.1").
401 \value ConvertUnspecifiedAddress All unspecified addresses will compare equal, namely AnyIPv4, AnyIPv6 and Any.
402 \value TolerantConversion Sets all three preceding flags.
403
404 \sa isEqual()
405 */
406
407/*! Constructs a null host address object, i.e. an address which is not valid for any host or interface.
408
409 \sa clear()
410*/
411QHostAddress::QHostAddress()
412 : d(new QHostAddressPrivate)
413{
414}
415
416/*!
417 Constructs a host address object with the IPv4 address \a ip4Addr.
418*/
419QHostAddress::QHostAddress(quint32 ip4Addr)
420 : d(new QHostAddressPrivate)
421{
422 setAddress(ip4Addr);
423}
424
425/*!
426 Constructs a host address object with the IPv6 address \a ip6Addr.
427
428 \a ip6Addr must be a 16-byte array in network byte order (big
429 endian).
430*/
431QHostAddress::QHostAddress(quint8 *ip6Addr)
432 : d(new QHostAddressPrivate)
433{
434 setAddress(ip6Addr);
435}
436
437/*!
438 \since 5.5
439 Constructs a host address object with the IPv6 address \a ip6Addr.
440
441 \a ip6Addr must be a 16-byte array in network byte order (big
442 endian).
443*/
444QHostAddress::QHostAddress(const quint8 *ip6Addr)
445 : d(new QHostAddressPrivate)
446{
447 setAddress(ip6Addr);
448}
449
450/*!
451 Constructs a host address object with the IPv6 address \a ip6Addr.
452*/
453QHostAddress::QHostAddress(const Q_IPV6ADDR &ip6Addr)
454 : d(new QHostAddressPrivate)
455{
456 setAddress(ip6Addr);
457}
458
459/*!
460 Constructs an IPv4 or IPv6 address based on the string \a address
461 (e.g., "127.0.0.1").
462
463 \sa setAddress()
464*/
465QHostAddress::QHostAddress(const QString &address)
466 : d(new QHostAddressPrivate)
467{
468 d->parse(ipString: address);
469}
470
471/*!
472 \fn QHostAddress::QHostAddress(const sockaddr *sockaddr)
473
474 Constructs an IPv4 or IPv6 address using the address specified by
475 the native structure \a sockaddr.
476
477 \sa setAddress()
478*/
479QHostAddress::QHostAddress(const struct sockaddr *sockaddr)
480 : d(new QHostAddressPrivate)
481{
482#ifndef Q_OS_WINRT
483 if (sockaddr->sa_family == AF_INET)
484 setAddress(htonl(hostlong: ((const sockaddr_in *)sockaddr)->sin_addr.s_addr));
485 else if (sockaddr->sa_family == AF_INET6)
486 setAddress(((const sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr);
487#else
488 Q_UNUSED(sockaddr)
489#endif
490}
491
492/*!
493 Constructs a copy of the given \a address.
494*/
495QHostAddress::QHostAddress(const QHostAddress &address)
496 : d(address.d)
497{
498}
499
500/*!
501 Constructs a QHostAddress object for \a address.
502*/
503QHostAddress::QHostAddress(SpecialAddress address)
504 : d(new QHostAddressPrivate)
505{
506 setAddress(address);
507}
508
509/*!
510 Destroys the host address object.
511*/
512QHostAddress::~QHostAddress()
513{
514}
515
516/*!
517 Assigns another host \a address to this object, and returns a reference
518 to this object.
519*/
520QHostAddress &QHostAddress::operator=(const QHostAddress &address)
521{
522 d = address.d;
523 return *this;
524}
525
526#if QT_DEPRECATED_SINCE(5, 8)
527/*!
528 Assigns the host address \a address to this object, and returns a
529 reference to this object.
530
531 \sa setAddress()
532*/
533QHostAddress &QHostAddress::operator=(const QString &address)
534{
535 setAddress(address);
536 return *this;
537}
538#endif
539
540/*!
541 \since 5.8
542 Assigns the special address \a address to this object, and returns a
543 reference to this object.
544
545 \sa setAddress()
546*/
547QHostAddress &QHostAddress::operator=(SpecialAddress address)
548{
549 setAddress(address);
550 return *this;
551}
552
553/*!
554 \fn void QHostAddress::swap(QHostAddress &other)
555 \since 5.6
556
557 Swaps this host address with \a other. This operation is very fast
558 and never fails.
559*/
560
561/*!
562 \fn bool QHostAddress::operator!=(const QHostAddress &other) const
563 \since 4.2
564
565 Returns \c true if this host address is not the same as the \a other
566 address given; otherwise returns \c false.
567*/
568
569/*!
570 \fn bool QHostAddress::operator!=(SpecialAddress other) const
571
572 Returns \c true if this host address is not the same as the \a other
573 address given; otherwise returns \c false.
574*/
575
576/*!
577 Sets the host address to null and sets the protocol to
578 QAbstractSocket::UnknownNetworkLayerProtocol.
579
580 \sa QHostAddress::Null
581*/
582void QHostAddress::clear()
583{
584 d.detach();
585 d->clear();
586}
587
588/*!
589 Set the IPv4 address specified by \a ip4Addr.
590*/
591void QHostAddress::setAddress(quint32 ip4Addr)
592{
593 d.detach();
594 d->setAddress(ip4Addr);
595}
596
597/*!
598 \overload
599
600 Set the IPv6 address specified by \a ip6Addr.
601
602 \a ip6Addr must be an array of 16 bytes in network byte order
603 (high-order byte first).
604*/
605void QHostAddress::setAddress(quint8 *ip6Addr)
606{
607 d.detach();
608 d->setAddress(ip6Addr);
609}
610
611/*!
612 \overload
613 \since 5.5
614
615 Set the IPv6 address specified by \a ip6Addr.
616
617 \a ip6Addr must be an array of 16 bytes in network byte order
618 (high-order byte first).
619*/
620void QHostAddress::setAddress(const quint8 *ip6Addr)
621{
622 d.detach();
623 d->setAddress(ip6Addr);
624}
625
626/*!
627 \overload
628
629 Set the IPv6 address specified by \a ip6Addr.
630*/
631void QHostAddress::setAddress(const Q_IPV6ADDR &ip6Addr)
632{
633 d.detach();
634 d->setAddress(ip6Addr);
635}
636
637/*!
638 \overload
639
640 Sets the IPv4 or IPv6 address specified by the string
641 representation specified by \a address (e.g. "127.0.0.1").
642 Returns \c true and sets the address if the address was successfully
643 parsed; otherwise returns \c false.
644*/
645bool QHostAddress::setAddress(const QString &address)
646{
647 d.detach();
648 return d->parse(ipString: address);
649}
650
651/*!
652 \fn void QHostAddress::setAddress(const sockaddr *sockaddr)
653 \overload
654
655 Sets the IPv4 or IPv6 address specified by the native structure \a
656 sockaddr. Returns \c true and sets the address if the address was
657 successfully parsed; otherwise returns \c false.
658*/
659void QHostAddress::setAddress(const struct sockaddr *sockaddr)
660{
661 d.detach();
662#ifndef Q_OS_WINRT
663 clear();
664 if (sockaddr->sa_family == AF_INET)
665 setAddress(htonl(hostlong: ((const sockaddr_in *)sockaddr)->sin_addr.s_addr));
666 else if (sockaddr->sa_family == AF_INET6)
667 setAddress(((const sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr);
668#else
669 Q_UNUSED(sockaddr)
670#endif
671}
672
673/*!
674 \overload
675 \since 5.8
676
677 Sets the special address specified by \a address.
678*/
679void QHostAddress::setAddress(SpecialAddress address)
680{
681 clear();
682
683 Q_IPV6ADDR ip6;
684 memset(s: &ip6, c: 0, n: sizeof ip6);
685 quint32 ip4 = INADDR_ANY;
686
687 switch (address) {
688 case Null:
689 return;
690
691 case Broadcast:
692 ip4 = INADDR_BROADCAST;
693 break;
694 case LocalHost:
695 ip4 = INADDR_LOOPBACK;
696 break;
697 case AnyIPv4:
698 break;
699
700 case LocalHostIPv6:
701 ip6[15] = 1;
702 Q_FALLTHROUGH();
703 case AnyIPv6:
704 d->setAddress(ip6);
705 return;
706
707 case Any:
708 d->protocol = QAbstractSocket::AnyIPProtocol;
709 return;
710 }
711
712 // common IPv4 part
713 d->setAddress(ip4);
714}
715
716/*!
717 Returns the IPv4 address as a number.
718
719 For example, if the address is 127.0.0.1, the returned value is
720 2130706433 (i.e. 0x7f000001).
721
722 This value is valid if the protocol() is
723 \l{QAbstractSocket::}{IPv4Protocol},
724 or if the protocol is
725 \l{QAbstractSocket::}{IPv6Protocol},
726 and the IPv6 address is an IPv4 mapped address. (RFC4291)
727
728 \sa toString()
729*/
730quint32 QHostAddress::toIPv4Address() const
731{
732 return toIPv4Address(ok: nullptr);
733}
734
735/*!
736 Returns the IPv4 address as a number.
737
738 For example, if the address is 127.0.0.1, the returned value is
739 2130706433 (i.e. 0x7f000001).
740
741 This value is valid if the protocol() is
742 \l{QAbstractSocket::}{IPv4Protocol},
743 or if the protocol is
744 \l{QAbstractSocket::}{IPv6Protocol},
745 and the IPv6 address is an IPv4 mapped address. (RFC4291). In those
746 cases, \a ok will be set to true. Otherwise, it will be set to false.
747
748 \sa toString()
749*/
750quint32 QHostAddress::toIPv4Address(bool *ok) const
751{
752 quint32 dummy;
753 if (ok)
754 *ok = d->protocol == QAbstractSocket::IPv4Protocol || d->protocol == QAbstractSocket::AnyIPProtocol
755 || (d->protocol == QAbstractSocket::IPv6Protocol
756 && convertToIpv4(a&: dummy, a6: d->a6, mode: ConversionMode(QHostAddress::ConvertV4MappedToIPv4
757 | QHostAddress::ConvertUnspecifiedAddress)));
758 return d->a;
759}
760
761/*!
762 Returns the network layer protocol of the host address.
763*/
764QAbstractSocket::NetworkLayerProtocol QHostAddress::protocol() const
765{
766 return QAbstractSocket::NetworkLayerProtocol(d->protocol);
767}
768
769/*!
770 Returns the IPv6 address as a Q_IPV6ADDR structure. The structure
771 consists of 16 unsigned characters.
772
773 \snippet code/src_network_kernel_qhostaddress.cpp 0
774
775 This value is valid if the protocol() is
776 \l{QAbstractSocket::}{IPv6Protocol}.
777 If the protocol is
778 \l{QAbstractSocket::}{IPv4Protocol},
779 then the address is returned an an IPv4 mapped IPv6 address. (RFC4291)
780
781 \sa toString()
782*/
783Q_IPV6ADDR QHostAddress::toIPv6Address() const
784{
785 return d->a6;
786}
787
788/*!
789 Returns the address as a string.
790
791 For example, if the address is the IPv4 address 127.0.0.1, the
792 returned string is "127.0.0.1". For IPv6 the string format will
793 follow the RFC5952 recommendation.
794 For QHostAddress::Any, its IPv4 address will be returned ("0.0.0.0")
795
796 \sa toIPv4Address()
797*/
798QString QHostAddress::toString() const
799{
800 QString s;
801 if (d->protocol == QAbstractSocket::IPv4Protocol
802 || d->protocol == QAbstractSocket::AnyIPProtocol) {
803 quint32 i = toIPv4Address();
804 QIPAddressUtils::toString(appendTo&: s, address: i);
805 } else if (d->protocol == QAbstractSocket::IPv6Protocol) {
806 QIPAddressUtils::toString(appendTo&: s, address: d->a6.c);
807 if (!d->scopeId.isEmpty())
808 s.append(s: QLatin1Char('%') + d->scopeId);
809 }
810 return s;
811}
812
813/*!
814 \since 4.1
815
816 Returns the scope ID of an IPv6 address. For IPv4 addresses, or if the
817 address does not contain a scope ID, an empty QString is returned.
818
819 The IPv6 scope ID specifies the scope of \e reachability for non-global
820 IPv6 addresses, limiting the area in which the address can be used. All
821 IPv6 addresses are associated with such a reachability scope. The scope ID
822 is used to disambiguate addresses that are not guaranteed to be globally
823 unique.
824
825 IPv6 specifies the following four levels of reachability:
826
827 \list
828
829 \li Node-local: Addresses that are only used for communicating with
830 services on the same interface (e.g., the loopback interface "::1").
831
832 \li Link-local: Addresses that are local to the network interface
833 (\e{link}). There is always one link-local address for each IPv6 interface
834 on your host. Link-local addresses ("fe80...") are generated from the MAC
835 address of the local network adaptor, and are not guaranteed to be unique.
836
837 \li Global: For globally routable addresses, such as public servers on the
838 Internet.
839
840 \endlist
841
842 When using a link-local or site-local address for IPv6 connections, you
843 must specify the scope ID. The scope ID for a link-local address is
844 usually the same as the interface name (e.g., "eth0", "en1") or number
845 (e.g., "1", "2").
846
847 \sa setScopeId(), QNetworkInterface, QNetworkInterface::interfaceFromName
848*/
849QString QHostAddress::scopeId() const
850{
851 return (d->protocol == QAbstractSocket::IPv6Protocol) ? d->scopeId : QString();
852}
853
854/*!
855 \since 4.1
856
857 Sets the IPv6 scope ID of the address to \a id. If the address protocol is
858 not IPv6, this function does nothing. The scope ID may be set as an
859 interface name (such as "eth0" or "en1") or as an integer representing the
860 interface index. If \a id is an interface name, QtNetwork will convert to
861 an interface index using QNetworkInterface::interfaceIndexFromName() before
862 calling the operating system networking functions.
863
864 \sa scopeId(), QNetworkInterface, QNetworkInterface::interfaceFromName
865*/
866void QHostAddress::setScopeId(const QString &id)
867{
868 d.detach();
869 if (d->protocol == QAbstractSocket::IPv6Protocol)
870 d->scopeId = id;
871}
872
873/*!
874 Returns \c true if this host address is the same as the \a other address
875 given; otherwise returns \c false. This operator just calls isEqual(other, StrictConversion).
876
877 \sa isEqual()
878*/
879bool QHostAddress::operator==(const QHostAddress &other) const
880{
881 return d == other.d || isEqual(address: other, mode: StrictConversion);
882}
883
884/*!
885 \since 5.8
886
887 Returns \c true if this host address is the same as the \a other address
888 given; otherwise returns \c false.
889
890 The parameter \a mode controls which conversions are preformed between addresses
891 of differing protocols. If no \a mode is given, \c TolerantConversion is performed
892 by default.
893
894 \sa ConversionMode, operator==()
895 */
896bool QHostAddress::isEqual(const QHostAddress &other, ConversionMode mode) const
897{
898 if (d == other.d)
899 return true;
900
901 if (d->protocol == QAbstractSocket::IPv4Protocol) {
902 switch (other.d->protocol) {
903 case QAbstractSocket::IPv4Protocol:
904 return d->a == other.d->a;
905 case QAbstractSocket::IPv6Protocol:
906 quint32 a4;
907 return convertToIpv4(a&: a4, a6: other.d->a6, mode) && (a4 == d->a);
908 case QAbstractSocket::AnyIPProtocol:
909 return (mode & QHostAddress::ConvertUnspecifiedAddress) && d->a == 0;
910 case QAbstractSocket::UnknownNetworkLayerProtocol:
911 return false;
912 }
913 }
914
915 if (d->protocol == QAbstractSocket::IPv6Protocol) {
916 switch (other.d->protocol) {
917 case QAbstractSocket::IPv4Protocol:
918 quint32 a4;
919 return convertToIpv4(a&: a4, a6: d->a6, mode) && (a4 == other.d->a);
920 case QAbstractSocket::IPv6Protocol:
921 return memcmp(s1: &d->a6, s2: &other.d->a6, n: sizeof(Q_IPV6ADDR)) == 0;
922 case QAbstractSocket::AnyIPProtocol:
923 return (mode & QHostAddress::ConvertUnspecifiedAddress)
924 && (other.d->a6_64.c[0] == 0) && (other.d->a6_64.c[1] == 0);
925 case QAbstractSocket::UnknownNetworkLayerProtocol:
926 return false;
927 }
928 }
929
930 if ((d->protocol == QAbstractSocket::AnyIPProtocol)
931 && (mode & QHostAddress::ConvertUnspecifiedAddress)) {
932 switch (other.d->protocol) {
933 case QAbstractSocket::IPv4Protocol:
934 return other.d->a == 0;
935 case QAbstractSocket::IPv6Protocol:
936 return (other.d->a6_64.c[0] == 0) && (other.d->a6_64.c[1] == 0);
937 default:
938 break;
939 }
940 }
941
942 return d->protocol == other.d->protocol;
943}
944
945/*!
946 Returns \c true if this host address is the same as the \a other
947 address given; otherwise returns \c false.
948*/
949bool QHostAddress::operator ==(SpecialAddress other) const
950{
951 quint32 ip4 = INADDR_ANY;
952 switch (other) {
953 case Null:
954 return d->protocol == QAbstractSocket::UnknownNetworkLayerProtocol;
955
956 case Broadcast:
957 ip4 = INADDR_BROADCAST;
958 break;
959
960 case LocalHost:
961 ip4 = INADDR_LOOPBACK;
962 break;
963
964 case Any:
965 return d->protocol == QAbstractSocket::AnyIPProtocol;
966
967 case AnyIPv4:
968 break;
969
970 case LocalHostIPv6:
971 case AnyIPv6:
972 if (d->protocol == QAbstractSocket::IPv6Protocol) {
973 quint64 second = quint8(other == LocalHostIPv6); // 1 for localhost, 0 for any
974 return d->a6_64.c[0] == 0 && d->a6_64.c[1] == qToBigEndian(source: second);
975 }
976 return false;
977 }
978
979 // common IPv4 part
980 return d->protocol == QAbstractSocket::IPv4Protocol && d->a == ip4;
981}
982
983/*!
984 Returns \c true if this host address is not valid for any host or interface.
985
986 The default constructor creates a null address.
987
988 \sa QHostAddress::Null
989*/
990bool QHostAddress::isNull() const
991{
992 return d->protocol == QAbstractSocket::UnknownNetworkLayerProtocol;
993}
994
995/*!
996 \since 4.5
997
998 Returns \c true if this IP is in the subnet described by the network
999 prefix \a subnet and netmask \a netmask.
1000
1001 An IP is considered to belong to a subnet if it is contained
1002 between the lowest and the highest address in that subnet. In the
1003 case of IP version 4, the lowest address is the network address,
1004 while the highest address is the broadcast address.
1005
1006 The \a subnet argument does not have to be the actual network
1007 address (the lowest address in the subnet). It can be any valid IP
1008 belonging to that subnet. In particular, if it is equal to the IP
1009 address held by this object, this function will always return true
1010 (provided the netmask is a valid value).
1011
1012 \sa parseSubnet()
1013*/
1014bool QHostAddress::isInSubnet(const QHostAddress &subnet, int netmask) const
1015{
1016 if (subnet.protocol() != d->protocol || netmask < 0)
1017 return false;
1018
1019 union {
1020 quint32 ip;
1021 quint8 data[4];
1022 } ip4, net4;
1023 const quint8 *ip;
1024 const quint8 *net;
1025 if (d->protocol == QAbstractSocket::IPv4Protocol) {
1026 if (netmask > 32)
1027 netmask = 32;
1028 ip4.ip = qToBigEndian(source: d->a);
1029 net4.ip = qToBigEndian(source: subnet.d->a);
1030 ip = ip4.data;
1031 net = net4.data;
1032 } else if (d->protocol == QAbstractSocket::IPv6Protocol) {
1033 if (netmask > 128)
1034 netmask = 128;
1035 ip = d->a6.c;
1036 net = subnet.d->a6.c;
1037 } else {
1038 return false;
1039 }
1040
1041 if (netmask >= 8 && memcmp(s1: ip, s2: net, n: netmask / 8) != 0)
1042 return false;
1043 if ((netmask & 7) == 0)
1044 return true;
1045
1046 // compare the last octet now
1047 quint8 bytemask = 256 - (1 << (8 - (netmask & 7)));
1048 quint8 ipbyte = ip[netmask / 8];
1049 quint8 netbyte = net[netmask / 8];
1050 return (ipbyte & bytemask) == (netbyte & bytemask);
1051}
1052
1053/*!
1054 \since 4.5
1055 \overload
1056
1057 Returns \c true if this IP is in the subnet described by \a
1058 subnet. The QHostAddress member of \a subnet contains the network
1059 prefix and the int (second) member contains the netmask (prefix
1060 length).
1061*/
1062bool QHostAddress::isInSubnet(const QPair<QHostAddress, int> &subnet) const
1063{
1064 return isInSubnet(subnet: subnet.first, netmask: subnet.second);
1065}
1066
1067
1068/*!
1069 \since 4.5
1070
1071 Parses the IP and subnet information contained in \a subnet and
1072 returns the network prefix for that network and its prefix length.
1073
1074 The IP address and the netmask must be separated by a slash
1075 (/).
1076
1077 This function supports arguments in the form:
1078 \list
1079 \li 123.123.123.123/n where n is any value between 0 and 32
1080 \li 123.123.123.123/255.255.255.255
1081 \li <ipv6-address>/n where n is any value between 0 and 128
1082 \endlist
1083
1084 For IP version 4, this function accepts as well missing trailing
1085 components (i.e., less than 4 octets, like "192.168.1"), followed
1086 or not by a dot. If the netmask is also missing in that case, it
1087 is set to the number of octets actually passed (in the example
1088 above, it would be 24, for 3 octets).
1089
1090 \sa isInSubnet()
1091*/
1092QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet)
1093{
1094 // We support subnets in the form:
1095 // ddd.ddd.ddd.ddd/nn
1096 // ddd.ddd.ddd/nn
1097 // ddd.ddd/nn
1098 // ddd/nn
1099 // ddd.ddd.ddd.
1100 // ddd.ddd.ddd
1101 // ddd.ddd.
1102 // ddd.ddd
1103 // ddd.
1104 // ddd
1105 // <ipv6-address>/nn
1106 //
1107 // where nn can be an IPv4-style netmask for the IPv4 forms
1108
1109 const QPair<QHostAddress, int> invalid = qMakePair(x: QHostAddress(), y: -1);
1110 if (subnet.isEmpty())
1111 return invalid;
1112
1113 int slash = subnet.indexOf(c: QLatin1Char('/'));
1114 QStringRef netStr(&subnet);
1115 if (slash != -1)
1116 netStr.truncate(pos: slash);
1117
1118 int netmask = -1;
1119 bool isIpv6 = netStr.contains(c: QLatin1Char(':'));
1120
1121 if (slash != -1) {
1122 // is the netmask given in IP-form or in bit-count form?
1123 if (!isIpv6 && subnet.indexOf(c: QLatin1Char('.'), from: slash + 1) != -1) {
1124 // IP-style, convert it to bit-count form
1125 QHostAddress mask;
1126 QNetmask parser;
1127 if (!mask.setAddress(subnet.mid(position: slash + 1)))
1128 return invalid;
1129 if (!parser.setAddress(mask))
1130 return invalid;
1131 netmask = parser.prefixLength();
1132 } else {
1133 bool ok;
1134 netmask = subnet.midRef(position: slash + 1).toUInt(ok: &ok);
1135 if (!ok)
1136 return invalid; // failed to parse the subnet
1137 }
1138 }
1139
1140 if (isIpv6) {
1141 // looks like it's an IPv6 address
1142 if (netmask > 128)
1143 return invalid; // invalid netmask
1144 if (netmask < 0)
1145 netmask = 128;
1146
1147 QHostAddress net;
1148 if (!net.setAddress(netStr.toString()))
1149 return invalid; // failed to parse the IP
1150
1151 clearBits(where: net.d->a6.c, start: netmask, end: 128);
1152 return qMakePair(x: net, y: netmask);
1153 }
1154
1155 if (netmask > 32)
1156 return invalid; // invalid netmask
1157
1158 // parse the address manually
1159 auto parts = netStr.split(sep: QLatin1Char('.'));
1160 if (parts.isEmpty() || parts.count() > 4)
1161 return invalid; // invalid IPv4 address
1162
1163 if (parts.constLast().isEmpty())
1164 parts.removeLast();
1165
1166 quint32 addr = 0;
1167 for (int i = 0; i < parts.count(); ++i) {
1168 bool ok;
1169 uint byteValue = parts.at(i).toUInt(ok: &ok);
1170 if (!ok || byteValue > 255)
1171 return invalid; // invalid IPv4 address
1172
1173 addr <<= 8;
1174 addr += byteValue;
1175 }
1176 addr <<= 8 * (4 - parts.count());
1177 if (netmask == -1) {
1178 netmask = 8 * parts.count();
1179 } else if (netmask == 0) {
1180 // special case here
1181 // x86's instructions "shr" and "shl" do not operate when
1182 // their argument is 32, so the code below doesn't work as expected
1183 addr = 0;
1184 } else if (netmask != 32) {
1185 // clear remaining bits
1186 quint32 mask = quint32(0xffffffff) >> (32 - netmask) << (32 - netmask);
1187 addr &= mask;
1188 }
1189
1190 return qMakePair(x: QHostAddress(addr), y: netmask);
1191}
1192
1193/*!
1194 \since 5.0
1195
1196 returns \c true if the address is the IPv6 loopback address, or any
1197 of the IPv4 loopback addresses.
1198*/
1199bool QHostAddress::isLoopback() const
1200{
1201 return d->classify() == LoopbackAddress;
1202}
1203
1204/*!
1205 \since 5.11
1206
1207 Returns \c true if the address is an IPv4 or IPv6 global address, \c false
1208 otherwise. A global address is an address that is not reserved for
1209 special purposes (like loopback or multicast) or future purposes.
1210
1211 Note that IPv6 unique local unicast addresses are considered global
1212 addresses (see isUniqueLocalUnicast()), as are IPv4 addresses reserved for
1213 local networks by \l {https://tools.ietf.org/html/rfc1918}{RFC 1918}.
1214
1215 Also note that IPv6 site-local addresses are deprecated and should be
1216 considered as global in new applications. This function returns true for
1217 site-local addresses too.
1218
1219 \sa isLoopback(), isSiteLocal(), isUniqueLocalUnicast()
1220*/
1221bool QHostAddress::isGlobal() const
1222{
1223 return d->classify() & GlobalAddress; // GlobalAddress is a bit
1224}
1225
1226/*!
1227 \since 5.11
1228
1229 Returns \c true if the address is an IPv4 or IPv6 link-local address, \c
1230 false otherwise.
1231
1232 An IPv4 link-local address is an address in the network 169.254.0.0/16. An
1233 IPv6 link-local address is one in the network fe80::/10. See the
1234 \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
1235 IPv6 Address Space} registry for more information.
1236
1237 \sa isLoopback(), isGlobal(), isMulticast(), isSiteLocal(), isUniqueLocalUnicast()
1238*/
1239bool QHostAddress::isLinkLocal() const
1240{
1241 return d->classify() == LinkLocalAddress;
1242}
1243
1244/*!
1245 \since 5.11
1246
1247 Returns \c true if the address is an IPv6 site-local address, \c
1248 false otherwise.
1249
1250 An IPv6 site-local address is one in the network fec0::/10. See the
1251 \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
1252 IPv6 Address Space} registry for more information.
1253
1254 IPv6 site-local addresses are deprecated and should not be depended upon in
1255 new applications. New applications should not depend on this function and
1256 should consider site-local addresses the same as global (which is why
1257 isGlobal() also returns true). Site-local addresses were replaced by Unique
1258 Local Addresses (ULA).
1259
1260 \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
1261*/
1262bool QHostAddress::isSiteLocal() const
1263{
1264 return d->classify() == SiteLocalAddress;
1265}
1266
1267/*!
1268 \since 5.11
1269
1270 Returns \c true if the address is an IPv6 unique local unicast address, \c
1271 false otherwise.
1272
1273 An IPv6 unique local unicast address is one in the network fc00::/7. See the
1274 \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}
1275 {IANA IPv6 Address Space} registry for more information.
1276
1277 Note that Unique local unicast addresses count as global addresses too. RFC
1278 4193 says that, in practice, "applications may treat these addresses like
1279 global scoped addresses." Only routers need care about the distinction.
1280
1281 \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
1282*/
1283bool QHostAddress::isUniqueLocalUnicast() const
1284{
1285 return d->classify() == UniqueLocalAddress;
1286}
1287
1288/*!
1289 \since 5.6
1290
1291 Returns \c true if the address is an IPv4 or IPv6 multicast address, \c
1292 false otherwise.
1293
1294 \sa isLoopback(), isGlobal(), isLinkLocal(), isSiteLocal(), isUniqueLocalUnicast()
1295*/
1296bool QHostAddress::isMulticast() const
1297{
1298 return d->classify() == MulticastAddress;
1299}
1300
1301/*!
1302 \since 5.11
1303
1304 Returns \c true if the address is the IPv4 broadcast address, \c false
1305 otherwise. The IPv4 broadcast address is 255.255.255.255.
1306
1307 Note that this function does not return true for an IPv4 network's local
1308 broadcast address. For that, please use \l QNetworkInterface to obtain the
1309 broadcast addresses of the local machine.
1310
1311 \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
1312*/
1313bool QHostAddress::isBroadcast() const
1314{
1315 return d->classify() == BroadcastAddress;
1316}
1317
1318#ifndef QT_NO_DEBUG_STREAM
1319QDebug operator<<(QDebug d, const QHostAddress &address)
1320{
1321 QDebugStateSaver saver(d);
1322 d.resetFormat().nospace();
1323 if (address == QHostAddress::Any)
1324 d << "QHostAddress(QHostAddress::Any)";
1325 else
1326 d << "QHostAddress(" << address.toString() << ')';
1327 return d;
1328}
1329#endif
1330
1331/*!
1332 \since 5.0
1333 \relates QHostAddress
1334 Returns a hash of the host address \a key, using \a seed to seed the calculation.
1335*/
1336uint qHash(const QHostAddress &key, uint seed) noexcept
1337{
1338 return qHashBits(p: key.d->a6.c, size: 16, seed);
1339}
1340
1341/*!
1342 \fn bool operator==(QHostAddress::SpecialAddress lhs, const QHostAddress &rhs)
1343 \relates QHostAddress
1344
1345 Returns \c true if special address \a lhs is the same as host address \a rhs;
1346 otherwise returns \c false.
1347
1348 \sa isEqual()
1349*/
1350
1351/*!
1352 \fn bool operator!=(QHostAddress::SpecialAddress lhs, const QHostAddress &rhs)
1353 \relates QHostAddress
1354 \since 5.9
1355
1356 Returns \c false if special address \a lhs is the same as host address \a rhs;
1357 otherwise returns \c true.
1358
1359 \sa isEqual()
1360*/
1361
1362#ifndef QT_NO_DATASTREAM
1363
1364/*! \relates QHostAddress
1365
1366 Writes host address \a address to the stream \a out and returns a reference
1367 to the stream.
1368
1369 \sa {Serializing Qt Data Types}
1370*/
1371QDataStream &operator<<(QDataStream &out, const QHostAddress &address)
1372{
1373 qint8 prot;
1374 prot = qint8(address.protocol());
1375 out << prot;
1376 switch (address.protocol()) {
1377 case QAbstractSocket::UnknownNetworkLayerProtocol:
1378 case QAbstractSocket::AnyIPProtocol:
1379 break;
1380 case QAbstractSocket::IPv4Protocol:
1381 out << address.toIPv4Address();
1382 break;
1383 case QAbstractSocket::IPv6Protocol:
1384 {
1385 Q_IPV6ADDR ipv6 = address.toIPv6Address();
1386 for (int i = 0; i < 16; ++i)
1387 out << ipv6[i];
1388 out << address.scopeId();
1389 }
1390 break;
1391 }
1392 return out;
1393}
1394
1395/*! \relates QHostAddress
1396
1397 Reads a host address into \a address from the stream \a in and returns a
1398 reference to the stream.
1399
1400 \sa {Serializing Qt Data Types}
1401*/
1402QDataStream &operator>>(QDataStream &in, QHostAddress &address)
1403{
1404 qint8 prot;
1405 in >> prot;
1406 switch (QAbstractSocket::NetworkLayerProtocol(prot)) {
1407 case QAbstractSocket::UnknownNetworkLayerProtocol:
1408 address.clear();
1409 break;
1410 case QAbstractSocket::IPv4Protocol:
1411 {
1412 quint32 ipv4;
1413 in >> ipv4;
1414 address.setAddress(ipv4);
1415 }
1416 break;
1417 case QAbstractSocket::IPv6Protocol:
1418 {
1419 Q_IPV6ADDR ipv6;
1420 for (int i = 0; i < 16; ++i)
1421 in >> ipv6[i];
1422 address.setAddress(ipv6);
1423
1424 QString scope;
1425 in >> scope;
1426 address.setScopeId(scope);
1427 }
1428 break;
1429 case QAbstractSocket::AnyIPProtocol:
1430 address = QHostAddress::Any;
1431 break;
1432 default:
1433 address.clear();
1434 in.setStatus(QDataStream::ReadCorruptData);
1435 }
1436 return in;
1437}
1438
1439#endif //QT_NO_DATASTREAM
1440
1441QT_END_NAMESPACE
1442

source code of qtbase/src/network/kernel/qhostaddress.cpp