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