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;
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.detach();
530 d->clear();
531}
532
533/*!
534 Set the IPv4 address specified by \a ip4Addr.
535*/
536void QHostAddress::setAddress(quint32 ip4Addr)
537{
538 d.detach();
539 d->setAddress(ip4Addr);
540}
541
542/*!
543 \overload
544 \since 5.5
545
546 Set the IPv6 address specified by \a ip6Addr.
547
548 \a ip6Addr must be an array of 16 bytes in network byte order
549 (high-order byte first).
550*/
551void QHostAddress::setAddress(const quint8 *ip6Addr)
552{
553 d.detach();
554 d->setAddress(ip6Addr);
555}
556
557/*!
558 \overload
559
560 Set the IPv6 address specified by \a ip6Addr.
561*/
562void QHostAddress::setAddress(const Q_IPV6ADDR &ip6Addr)
563{
564 d.detach();
565 d->setAddress(ip6Addr);
566}
567
568/*!
569 \overload
570
571 Sets the IPv4 or IPv6 address specified by the string
572 representation specified by \a address (e.g. "127.0.0.1").
573 Returns \c true and sets the address if the address was successfully
574 parsed; otherwise returns \c false.
575*/
576bool QHostAddress::setAddress(const QString &address)
577{
578 d.detach();
579 return d->parse(address);
580}
581
582/*!
583 \fn void QHostAddress::setAddress(const sockaddr *sockaddr)
584 \overload
585
586 Sets the IPv4 or IPv6 address specified by the native structure \a
587 sockaddr. Returns \c true and sets the address if the address was
588 successfully parsed; otherwise returns \c false.
589*/
590void QHostAddress::setAddress(const struct sockaddr *sockaddr)
591{
592 d.detach();
593 clear();
594 if (sockaddr->sa_family == AF_INET)
595 setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr));
596 else if (sockaddr->sa_family == AF_INET6)
597 setAddress(((const sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr);
598}
599
600/*!
601 \overload
602 \since 5.8
603
604 Sets the special address specified by \a address.
605*/
606void QHostAddress::setAddress(SpecialAddress address)
607{
608 clear();
609
610 Q_IPV6ADDR ip6;
611 memset(&ip6, 0, sizeof ip6);
612 quint32 ip4 = INADDR_ANY;
613
614 switch (address) {
615 case Null:
616 return;
617
618 case Broadcast:
619 ip4 = INADDR_BROADCAST;
620 break;
621 case LocalHost:
622 ip4 = INADDR_LOOPBACK;
623 break;
624 case AnyIPv4:
625 break;
626
627 case LocalHostIPv6:
628 ip6[15] = 1;
629 Q_FALLTHROUGH();
630 case AnyIPv6:
631 d->setAddress(ip6);
632 return;
633
634 case Any:
635 d->protocol = QHostAddress::AnyIPProtocol;
636 return;
637 }
638
639 // common IPv4 part
640 d->setAddress(ip4);
641}
642
643/*!
644 Returns the IPv4 address as a number.
645
646 For example, if the address is 127.0.0.1, the returned value is
647 2130706433 (i.e. 0x7f000001).
648
649 This value is valid if the protocol() is
650 \l{QAbstractSocket::}{IPv4Protocol},
651 or if the protocol is
652 \l{QAbstractSocket::}{IPv6Protocol},
653 and the IPv6 address is an IPv4 mapped address (RFC4291). In those
654 cases, \a ok will be set to true. Otherwise, it will be set to false.
655
656 \sa toString()
657*/
658quint32 QHostAddress::toIPv4Address(bool *ok) const
659{
660 quint32 dummy;
661 if (ok)
662 *ok = d->protocol == QHostAddress::IPv4Protocol || d->protocol == QHostAddress::AnyIPProtocol
663 || (d->protocol == QHostAddress::IPv6Protocol
664 && convertToIpv4(dummy, d->a6, ConversionMode(QHostAddress::ConvertV4MappedToIPv4
665 | QHostAddress::ConvertUnspecifiedAddress)));
666 return d->a;
667}
668
669/*!
670 Returns the network layer protocol of the host address.
671*/
672QHostAddress::NetworkLayerProtocol QHostAddress::protocol() const
673{
674 return QHostAddress::NetworkLayerProtocol(d->protocol);
675}
676
677/*!
678 Returns the IPv6 address as a Q_IPV6ADDR structure. The structure
679 consists of 16 unsigned characters.
680
681 \snippet code/src_network_kernel_qhostaddress.cpp 0
682
683 This value is valid if the protocol() is
684 \l{QAbstractSocket::}{IPv6Protocol}.
685 If the protocol is
686 \l{QAbstractSocket::}{IPv4Protocol},
687 then the address is returned as an IPv4 mapped IPv6 address. (RFC4291)
688
689 \sa toString()
690*/
691Q_IPV6ADDR QHostAddress::toIPv6Address() const
692{
693 return d->a6;
694}
695
696/*!
697 Returns the address as a string.
698
699 For example, if the address is the IPv4 address 127.0.0.1, the
700 returned string is "127.0.0.1". For IPv6 the string format will
701 follow the RFC5952 recommendation.
702 For QHostAddress::Any, its IPv4 address will be returned ("0.0.0.0")
703
704 \sa toIPv4Address()
705*/
706QString QHostAddress::toString() const
707{
708 QString s;
709 if (d->protocol == QHostAddress::IPv4Protocol
710 || d->protocol == QHostAddress::AnyIPProtocol) {
711 quint32 i = toIPv4Address();
712 QIPAddressUtils::toString(s, i);
713 } else if (d->protocol == QHostAddress::IPv6Protocol) {
714 QIPAddressUtils::toString(s, d->a6.c);
715 if (!d->scopeId.isEmpty())
716 s += u'%' + d->scopeId;
717 }
718 return s;
719}
720
721/*!
722 \since 4.1
723
724 Returns the scope ID of an IPv6 address. For IPv4 addresses, or if the
725 address does not contain a scope ID, an empty QString is returned.
726
727 The IPv6 scope ID specifies the scope of \e reachability for non-global
728 IPv6 addresses, limiting the area in which the address can be used. All
729 IPv6 addresses are associated with such a reachability scope. The scope ID
730 is used to disambiguate addresses that are not guaranteed to be globally
731 unique.
732
733 IPv6 specifies the following four levels of reachability:
734
735 \list
736
737 \li Node-local: Addresses that are only used for communicating with
738 services on the same interface (e.g., the loopback interface "::1").
739
740 \li Link-local: Addresses that are local to the network interface
741 (\e{link}). There is always one link-local address for each IPv6 interface
742 on your host. Link-local addresses ("fe80...") are generated from the MAC
743 address of the local network adaptor, and are not guaranteed to be unique.
744
745 \li Global: For globally routable addresses, such as public servers on the
746 Internet.
747
748 \endlist
749
750 When using a link-local or site-local address for IPv6 connections, you
751 must specify the scope ID. The scope ID for a link-local address is
752 usually the same as the interface name (e.g., "eth0", "en1") or number
753 (e.g., "1", "2").
754
755 \sa setScopeId(), QNetworkInterface, QNetworkInterface::interfaceFromName
756*/
757QString QHostAddress::scopeId() const
758{
759 return (d->protocol == QHostAddress::IPv6Protocol) ? d->scopeId : QString();
760}
761
762/*!
763 \since 4.1
764
765 Sets the IPv6 scope ID of the address to \a id. If the address protocol is
766 not IPv6, this function does nothing. The scope ID may be set as an
767 interface name (such as "eth0" or "en1") or as an integer representing the
768 interface index. If \a id is an interface name, QtNetwork will convert to
769 an interface index using QNetworkInterface::interfaceIndexFromName() before
770 calling the operating system networking functions.
771
772 \sa scopeId(), QNetworkInterface, QNetworkInterface::interfaceFromName
773*/
774void QHostAddress::setScopeId(const QString &id)
775{
776 d.detach();
777 if (d->protocol == QHostAddress::IPv6Protocol)
778 d->scopeId = id;
779}
780
781/*!
782 Returns \c true if this host address is the same as the \a other address
783 given; otherwise returns \c false. This operator just calls isEqual(other, StrictConversion).
784
785 \sa isEqual()
786*/
787bool QHostAddress::operator==(const QHostAddress &other) const
788{
789 return d == other.d || isEqual(other, StrictConversion);
790}
791
792/*!
793 \since 5.8
794
795 Returns \c true if this host address is the same as the \a other address
796 given; otherwise returns \c false.
797
798 The parameter \a mode controls which conversions are performed between addresses
799 of differing protocols. If no \a mode is given, \c TolerantConversion is performed
800 by default.
801
802 \sa ConversionMode, operator==()
803 */
804bool QHostAddress::isEqual(const QHostAddress &other, ConversionMode mode) const
805{
806 if (d == other.d)
807 return true;
808
809 if (d->protocol == QHostAddress::IPv4Protocol) {
810 switch (other.d->protocol) {
811 case QHostAddress::IPv4Protocol:
812 return d->a == other.d->a;
813 case QHostAddress::IPv6Protocol:
814 quint32 a4;
815 return convertToIpv4(a4, other.d->a6, mode) && (a4 == d->a);
816 case QHostAddress::AnyIPProtocol:
817 return (mode & QHostAddress::ConvertUnspecifiedAddress) && d->a == 0;
818 case QHostAddress::UnknownNetworkLayerProtocol:
819 return false;
820 }
821 }
822
823 if (d->protocol == QHostAddress::IPv6Protocol) {
824 switch (other.d->protocol) {
825 case QHostAddress::IPv4Protocol:
826 quint32 a4;
827 return convertToIpv4(a4, d->a6, mode) && (a4 == other.d->a);
828 case QHostAddress::IPv6Protocol:
829 return memcmp(&d->a6, &other.d->a6, sizeof(Q_IPV6ADDR)) == 0;
830 case QHostAddress::AnyIPProtocol:
831 return (mode & QHostAddress::ConvertUnspecifiedAddress)
832 && (d->a6_64.c[0] == 0) && (d->a6_64.c[1] == 0);
833 case QHostAddress::UnknownNetworkLayerProtocol:
834 return false;
835 }
836 }
837
838 if ((d->protocol == QHostAddress::AnyIPProtocol)
839 && (mode & QHostAddress::ConvertUnspecifiedAddress)) {
840 switch (other.d->protocol) {
841 case QHostAddress::IPv4Protocol:
842 return other.d->a == 0;
843 case QHostAddress::IPv6Protocol:
844 return (other.d->a6_64.c[0] == 0) && (other.d->a6_64.c[1] == 0);
845 default:
846 break;
847 }
848 }
849
850 return d->protocol == other.d->protocol;
851}
852
853/*!
854 Returns \c true if this host address is the same as the \a other
855 address given; otherwise returns \c false.
856*/
857bool QHostAddress::operator ==(SpecialAddress other) const
858{
859 quint32 ip4 = INADDR_ANY;
860 switch (other) {
861 case Null:
862 return d->protocol == QHostAddress::UnknownNetworkLayerProtocol;
863
864 case Broadcast:
865 ip4 = INADDR_BROADCAST;
866 break;
867
868 case LocalHost:
869 ip4 = INADDR_LOOPBACK;
870 break;
871
872 case Any:
873 return d->protocol == QHostAddress::AnyIPProtocol;
874
875 case AnyIPv4:
876 break;
877
878 case LocalHostIPv6:
879 case AnyIPv6:
880 if (d->protocol == QHostAddress::IPv6Protocol) {
881 quint64 second = quint8(other == LocalHostIPv6); // 1 for localhost, 0 for any
882 return d->a6_64.c[0] == 0 && d->a6_64.c[1] == qToBigEndian(second);
883 }
884 return false;
885 }
886
887 // common IPv4 part
888 return d->protocol == QHostAddress::IPv4Protocol && d->a == ip4;
889}
890
891/*!
892 Returns \c true if this host address is not valid for any host or interface.
893
894 The default constructor creates a null address.
895
896 \sa QHostAddress::Null
897*/
898bool QHostAddress::isNull() const
899{
900 return d->protocol == QHostAddress::UnknownNetworkLayerProtocol;
901}
902
903/*!
904 \since 4.5
905
906 Returns \c true if this IP is in the subnet described by the network
907 prefix \a subnet and netmask \a netmask.
908
909 The \a netmask parameter is the prefix length - the number of leading
910 bits used to identify the network portion of the address. For IPv4,
911 valid values range from 0 to 32; for IPv6, from 0 to 128.
912
913 An IP is considered to belong to a subnet if it is contained
914 between the lowest and the highest address in that subnet. In the
915 case of IP version 4, the lowest address is the network address,
916 while the highest address is the broadcast address.
917
918 The \a subnet argument does not have to be the actual network
919 address (the lowest address in the subnet). It can be any valid IP
920 belonging to that subnet. In particular, if it is equal to the IP
921 address held by this object, this function will always return true
922 (provided the prefix length is a valid value).
923
924 \sa parseSubnet()
925*/
926bool QHostAddress::isInSubnet(const QHostAddress &subnet, int netmask) const
927{
928 if (subnet.protocol() != d->protocol || netmask < 0)
929 return false;
930
931 union {
932 quint32 ip;
933 quint8 data[4];
934 } ip4, net4;
935 const quint8 *ip;
936 const quint8 *net;
937 if (d->protocol == QHostAddress::IPv4Protocol) {
938 if (netmask > 32)
939 netmask = 32;
940 ip4.ip = qToBigEndian(d->a);
941 net4.ip = qToBigEndian(subnet.d->a);
942 ip = ip4.data;
943 net = net4.data;
944 } else if (d->protocol == QHostAddress::IPv6Protocol) {
945 if (netmask > 128)
946 netmask = 128;
947 ip = d->a6.c;
948 net = subnet.d->a6.c;
949 } else {
950 return false;
951 }
952
953 if (netmask >= 8 && memcmp(ip, net, netmask / 8) != 0)
954 return false;
955 if ((netmask & 7) == 0)
956 return true;
957
958 // compare the last octet now
959 quint8 bytemask = 256 - (1 << (8 - (netmask & 7)));
960 quint8 ipbyte = ip[netmask / 8];
961 quint8 netbyte = net[netmask / 8];
962 return (ipbyte & bytemask) == (netbyte & bytemask);
963}
964
965/*!
966 \since 4.5
967 \overload
968
969 Returns \c true if this IP is in the subnet described by \a
970 subnet. The QHostAddress member of \a subnet contains the network
971 prefix and the int (second) member contains the netmask (prefix
972 length).
973*/
974bool QHostAddress::isInSubnet(const std::pair<QHostAddress, int> &subnet) const
975{
976 return isInSubnet(subnet.first, subnet.second);
977}
978
979
980/*!
981 \since 4.5
982
983 Parses the IP and subnet information contained in \a subnet and
984 returns the network prefix for that network and its prefix length.
985
986 The IP address and the netmask must be separated by a slash
987 (/).
988
989 This function supports arguments in the form:
990 \list
991 \li 123.123.123.123/n where n is any value between 0 and 32
992 \li 123.123.123.123/255.255.255.255
993 \li <ipv6-address>/n where n is any value between 0 and 128
994 \endlist
995
996 For IP version 4, this function accepts as well missing trailing
997 components (i.e., less than 4 octets, like "192.168.1"), followed
998 or not by a dot. If the netmask is also missing in that case, it
999 is set to the number of octets actually passed (in the example
1000 above, it would be 24, for 3 octets).
1001
1002 \sa isInSubnet()
1003*/
1004std::pair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet)
1005{
1006 // We support subnets in the form:
1007 // ddd.ddd.ddd.ddd/nn
1008 // ddd.ddd.ddd/nn
1009 // ddd.ddd/nn
1010 // ddd/nn
1011 // ddd.ddd.ddd.
1012 // ddd.ddd.ddd
1013 // ddd.ddd.
1014 // ddd.ddd
1015 // ddd.
1016 // ddd
1017 // <ipv6-address>/nn
1018 //
1019 // where nn can be an IPv4-style netmask for the IPv4 forms
1020
1021 const std::pair<QHostAddress, int> invalid = std::pair(QHostAddress(), -1);
1022 if (subnet.isEmpty())
1023 return invalid;
1024
1025 qsizetype slash = subnet.indexOf(u'/');
1026 QStringView netStr(subnet);
1027 if (slash != -1)
1028 netStr.truncate(slash);
1029
1030 int netmask = -1;
1031 bool isIpv6 = netStr.contains(u':');
1032
1033 if (slash != -1) {
1034 // is the netmask given in IP-form or in bit-count form?
1035 if (!isIpv6 && subnet.indexOf(u'.', slash + 1) != -1) {
1036 // IP-style, convert it to bit-count form
1037 QHostAddress mask;
1038 QNetmask parser;
1039 if (!mask.setAddress(subnet.mid(slash + 1)))
1040 return invalid;
1041 if (!parser.setAddress(mask))
1042 return invalid;
1043 netmask = parser.prefixLength();
1044 } else {
1045 bool ok;
1046 netmask = QStringView{subnet}.mid(slash + 1).toUInt(&ok);
1047 if (!ok)
1048 return invalid; // failed to parse the subnet
1049 }
1050 }
1051
1052 if (isIpv6) {
1053 // looks like it's an IPv6 address
1054 if (netmask > 128)
1055 return invalid; // invalid netmask
1056 if (netmask < 0)
1057 netmask = 128;
1058
1059 QHostAddress net;
1060 if (!net.setAddress(netStr.toString()))
1061 return invalid; // failed to parse the IP
1062
1063 clearBits(net.d->a6.c, netmask, 128);
1064 return std::pair(net, netmask);
1065 }
1066
1067 if (netmask > 32)
1068 return invalid; // invalid netmask
1069
1070 // parse the address manually
1071 auto parts = netStr.split(u'.');
1072 if (parts.isEmpty() || parts.size() > 4)
1073 return invalid; // invalid IPv4 address
1074
1075 if (parts.constLast().isEmpty())
1076 parts.removeLast();
1077
1078 quint32 addr = 0;
1079 for (int i = 0; i < parts.size(); ++i) {
1080 bool ok;
1081 uint byteValue = parts.at(i).toUInt(&ok);
1082 if (!ok || byteValue > 255)
1083 return invalid; // invalid IPv4 address
1084
1085 addr <<= 8;
1086 addr += byteValue;
1087 }
1088 addr <<= 8 * (4 - parts.size());
1089 if (netmask == -1) {
1090 netmask = 8 * parts.size();
1091 } else if (netmask == 0) {
1092 // special case here
1093 // x86's instructions "shr" and "shl" do not operate when
1094 // their argument is 32, so the code below doesn't work as expected
1095 addr = 0;
1096 } else if (netmask != 32) {
1097 // clear remaining bits
1098 quint32 mask = quint32(0xffffffff) >> (32 - netmask) << (32 - netmask);
1099 addr &= mask;
1100 }
1101
1102 return std::pair(QHostAddress(addr), netmask);
1103}
1104
1105/*!
1106 \since 5.0
1107
1108 returns \c true if the address is the IPv6 loopback address, or any
1109 of the IPv4 loopback addresses.
1110*/
1111bool QHostAddress::isLoopback() const
1112{
1113 return d->classify() == LoopbackAddress;
1114}
1115
1116/*!
1117 \since 5.11
1118
1119 Returns \c true if the address is an IPv4 or IPv6 global address, \c false
1120 otherwise. A global address is an address that is not reserved for
1121 special purposes (like loopback or multicast) or future purposes.
1122
1123 Note that IPv6 unique local unicast addresses are considered global
1124 addresses (see isUniqueLocalUnicast()), as are IPv4 addresses reserved for
1125 local networks by \l {RFC 1918}.
1126
1127 Also note that IPv6 site-local addresses are deprecated and should be
1128 considered as global in new applications. This function returns true for
1129 site-local addresses too.
1130
1131 \sa isLoopback(), isSiteLocal(), isUniqueLocalUnicast(), isPrivateUse()
1132*/
1133bool QHostAddress::isGlobal() const
1134{
1135 return d->classify() & GlobalAddress; // GlobalAddress is a bit
1136}
1137
1138/*!
1139 \since 5.11
1140
1141 Returns \c true if the address is an IPv4 or IPv6 link-local address, \c
1142 false otherwise.
1143
1144 An IPv4 link-local address is an address in the network 169.254.0.0/16. An
1145 IPv6 link-local address is one in the network fe80::/10. See the
1146 \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
1147 IPv6 Address Space} registry for more information.
1148
1149 \sa isLoopback(), isGlobal(), isMulticast(), isSiteLocal(), isUniqueLocalUnicast(), isPrivateUse()
1150*/
1151bool QHostAddress::isLinkLocal() const
1152{
1153 return d->classify() == LinkLocalAddress;
1154}
1155
1156/*!
1157 \since 5.11
1158
1159 Returns \c true if the address is an IPv6 site-local address, \c
1160 false otherwise.
1161
1162 An IPv6 site-local address is one in the network fec0::/10. See the
1163 \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
1164 IPv6 Address Space} registry for more information.
1165
1166 IPv6 site-local addresses are deprecated and should not be depended upon in
1167 new applications. New applications should not depend on this function and
1168 should consider site-local addresses the same as global (which is why
1169 isGlobal() also returns true). Site-local addresses were replaced by Unique
1170 Local Addresses (ULA).
1171
1172 \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isPrivateUse()
1173*/
1174bool QHostAddress::isSiteLocal() const
1175{
1176 return d->classify() == SiteLocalAddress;
1177}
1178
1179/*!
1180 \since 5.11
1181
1182 Returns \c true if the address is an IPv6 unique local unicast address, \c
1183 false otherwise.
1184
1185 An IPv6 unique local unicast address is one in the network fc00::/7. See the
1186 \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}
1187 {IANA IPv6 Address Space} registry for more information.
1188
1189 Note that Unique local unicast addresses count as global addresses too. RFC
1190 4193 says that, in practice, "applications may treat these addresses like
1191 global scoped addresses." Only routers need care about the distinction.
1192
1193 \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isPrivateUse()
1194*/
1195bool QHostAddress::isUniqueLocalUnicast() const
1196{
1197 return d->classify() == UniqueLocalAddress;
1198}
1199
1200/*!
1201 \since 5.6
1202
1203 Returns \c true if the address is an IPv4 or IPv6 multicast address, \c
1204 false otherwise.
1205
1206 \sa isLoopback(), isGlobal(), isLinkLocal(), isSiteLocal(), isUniqueLocalUnicast(), isPrivateUse()
1207*/
1208bool QHostAddress::isMulticast() const
1209{
1210 return d->classify() == MulticastAddress;
1211}
1212
1213/*!
1214 \since 5.11
1215
1216 Returns \c true if the address is the IPv4 broadcast address, \c false
1217 otherwise. The IPv4 broadcast address is 255.255.255.255.
1218
1219 Note that this function does not return true for an IPv4 network's local
1220 broadcast address. For that, please use \l QNetworkInterface to obtain the
1221 broadcast addresses of the local machine.
1222
1223 \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isPrivateUse()
1224*/
1225bool QHostAddress::isBroadcast() const
1226{
1227 return d->classify() == BroadcastAddress;
1228}
1229
1230/*!
1231 \since 6.6
1232
1233 Returns \c true if the address is an IPv6 unique local unicast address or
1234 IPv4 address reserved for local networks by \l {RFC 1918}, \c false otherwise.
1235
1236 \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isBroadcast()
1237*/
1238bool QHostAddress::isPrivateUse() const
1239{
1240 const AddressClassification classification = d->classify();
1241 return (classification == PrivateNetworkAddress) || (classification == UniqueLocalAddress);
1242}
1243
1244#ifndef QT_NO_DEBUG_STREAM
1245QDebug operator<<(QDebug d, const QHostAddress &address)
1246{
1247 QDebugStateSaver saver(d);
1248 d.resetFormat().nospace();
1249 if (address == QHostAddress::Any)
1250 d << "QHostAddress(QHostAddress::Any)";
1251 else
1252 d << "QHostAddress(" << address.toString() << ')';
1253 return d;
1254}
1255#endif
1256
1257/*!
1258 \since 5.0
1259 \qhashold{QHostAddress}
1260*/
1261size_t qHash(const QHostAddress &key, size_t seed) noexcept
1262{
1263 return qHashBits(key.d->a6.c, 16, seed);
1264}
1265
1266/*!
1267 \fn bool QHostAddress::operator==(QHostAddress::SpecialAddress lhs, const QHostAddress &rhs)
1268
1269 Returns \c true if special address \a lhs is the same as host address \a rhs;
1270 otherwise returns \c false.
1271
1272 \sa isEqual()
1273*/
1274
1275/*!
1276 \fn bool QHostAddress::operator!=(QHostAddress::SpecialAddress lhs, const QHostAddress &rhs)
1277 \since 5.9
1278
1279 Returns \c false if special address \a lhs is the same as host address \a rhs;
1280 otherwise returns \c true.
1281
1282 \sa isEqual()
1283*/
1284
1285#ifndef QT_NO_DATASTREAM
1286
1287/*! \relates QHostAddress
1288
1289 Writes host address \a address to the stream \a out and returns a reference
1290 to the stream.
1291
1292 \sa {Serializing Qt Data Types}
1293*/
1294QDataStream &operator<<(QDataStream &out, const QHostAddress &address)
1295{
1296 qint8 prot;
1297 prot = qint8(address.protocol());
1298 out << prot;
1299 switch (address.protocol()) {
1300 case QHostAddress::UnknownNetworkLayerProtocol:
1301 case QHostAddress::AnyIPProtocol:
1302 break;
1303 case QHostAddress::IPv4Protocol:
1304 out << address.toIPv4Address();
1305 break;
1306 case QHostAddress::IPv6Protocol:
1307 {
1308 Q_IPV6ADDR ipv6 = address.toIPv6Address();
1309 for (int i = 0; i < 16; ++i)
1310 out << ipv6[i];
1311 out << address.scopeId();
1312 }
1313 break;
1314 }
1315 return out;
1316}
1317
1318/*! \relates QHostAddress
1319
1320 Reads a host address into \a address from the stream \a in and returns a
1321 reference to the stream.
1322
1323 \sa {Serializing Qt Data Types}
1324*/
1325QDataStream &operator>>(QDataStream &in, QHostAddress &address)
1326{
1327 qint8 prot;
1328 in >> prot;
1329 switch (QHostAddress::NetworkLayerProtocol(prot)) {
1330 case QHostAddress::UnknownNetworkLayerProtocol:
1331 address.clear();
1332 break;
1333 case QHostAddress::IPv4Protocol:
1334 {
1335 quint32 ipv4;
1336 in >> ipv4;
1337 address.setAddress(ipv4);
1338 }
1339 break;
1340 case QHostAddress::IPv6Protocol:
1341 {
1342 Q_IPV6ADDR ipv6;
1343 for (int i = 0; i < 16; ++i)
1344 in >> ipv6[i];
1345 address.setAddress(ipv6);
1346
1347 QString scope;
1348 in >> scope;
1349 address.setScopeId(scope);
1350 }
1351 break;
1352 case QHostAddress::AnyIPProtocol:
1353 address = QHostAddress::Any;
1354 break;
1355 default:
1356 address.clear();
1357 in.setStatus(QDataStream::ReadCorruptData);
1358 }
1359 return in;
1360}
1361
1362#endif //QT_NO_DATASTREAM
1363
1364QT_END_NAMESPACE
1365
1366#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