1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2017 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:significant reason:default
5
6#include "qnetworkinterface.h"
7#include "qnetworkinterface_p.h"
8
9#include "qdebug.h"
10#include "qendian.h"
11#include "private/qtools_p.h"
12
13#ifndef QT_NO_NETWORKINTERFACE
14
15QT_BEGIN_NAMESPACE
16
17QT_IMPL_METATYPE_EXTERN(QNetworkAddressEntry)
18QT_IMPL_METATYPE_EXTERN(QNetworkInterface)
19
20static_assert(QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
21 && sizeof(QScopedPointer<QNetworkAddressEntryPrivate>) == sizeof(std::unique_ptr<QNetworkAddressEntryPrivate>));
22
23static QList<QNetworkInterfacePrivate *> postProcess(QList<QNetworkInterfacePrivate *> list)
24{
25 // Some platforms report a netmask but don't report a broadcast address
26 // Go through all available addresses and calculate the broadcast address
27 // from the IP and the netmask
28 //
29 // This is an IPv4-only thing -- IPv6 has no concept of broadcasts
30 // The math is:
31 // broadcast = IP | ~netmask
32
33 for (QNetworkInterfacePrivate *iface : list) {
34 for (QNetworkAddressEntry &address : iface->addressEntries) {
35 if (address.ip().protocol() != QAbstractSocket::IPv4Protocol)
36 continue;
37
38 if (!address.netmask().isNull() && address.broadcast().isNull()) {
39 QHostAddress bcast = address.ip();
40 bcast = QHostAddress(bcast.toIPv4Address() | ~address.netmask().toIPv4Address());
41 address.setBroadcast(bcast);
42 }
43 }
44 }
45
46 return list;
47}
48
49Q_GLOBAL_STATIC(QNetworkInterfaceManager, manager)
50
51QNetworkInterfaceManager::QNetworkInterfaceManager()
52{
53}
54
55QNetworkInterfaceManager::~QNetworkInterfaceManager()
56{
57}
58
59QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interfaceFromName(const QString &name)
60{
61 const auto interfaceList = allInterfaces();
62
63 bool ok;
64 uint index = name.toUInt(ok: &ok);
65
66 for (const auto &iface : interfaceList) {
67 if (ok && iface->index == int(index))
68 return iface;
69 else if (iface->name == name)
70 return iface;
71 }
72
73 return empty;
74}
75
76QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interfaceFromIndex(int index)
77{
78 const auto interfaceList = allInterfaces();
79 for (const auto &iface : interfaceList) {
80 if (iface->index == index)
81 return iface;
82 }
83
84 return empty;
85}
86
87QList<QSharedDataPointer<QNetworkInterfacePrivate> > QNetworkInterfaceManager::allInterfaces()
88{
89 const QList<QNetworkInterfacePrivate *> list = postProcess(list: scan());
90 QList<QSharedDataPointer<QNetworkInterfacePrivate> > result;
91 result.reserve(asize: list.size());
92
93 for (QNetworkInterfacePrivate *ptr : list) {
94 if ((ptr->flags & QNetworkInterface::IsUp) == 0) {
95 // if the network interface isn't UP, the addresses are ineligible for DNS
96 for (auto &addr : ptr->addressEntries)
97 addr.setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
98 }
99
100 result << QSharedDataPointer<QNetworkInterfacePrivate>(ptr);
101 }
102
103 return result;
104}
105
106QString QNetworkInterfacePrivate::makeHwAddress(int len, uchar *data)
107{
108 const int outLen = qMax(a: len * 2 + (len - 1) * 1, b: 0);
109 QString result(outLen, Qt::Uninitialized);
110 QChar *out = result.data();
111 for (int i = 0; i < len; ++i) {
112 if (i)
113 *out++ = u':';
114 *out++ = QLatin1Char(QtMiscUtils::toHexUpper(value: data[i] / 16));
115 *out++ = QLatin1Char(QtMiscUtils::toHexUpper(value: data[i] % 16));
116 }
117 return result;
118}
119
120/*!
121 \class QNetworkAddressEntry
122 \brief The QNetworkAddressEntry class stores one IP address
123 supported by a network interface, along with its associated
124 netmask and broadcast address.
125
126 \since 4.2
127 \reentrant
128 \ingroup network
129 \ingroup shared
130 \inmodule QtNetwork
131
132 Each network interface can contain zero or more IP addresses, which
133 in turn can be associated with a netmask and/or a broadcast
134 address (depending on support from the operating system).
135
136 This class represents one such group.
137*/
138
139/*!
140 \enum QNetworkAddressEntry::DnsEligibilityStatus
141 \since 5.11
142
143 This enum indicates whether a given host address is eligible to be
144 published in the Domain Name System (DNS) or other similar name resolution
145 mechanisms. In general, an address is suitable for publication if it is an
146 address this machine will be reached at for an indeterminate amount of
147 time, though it need not be permanent. For example, addresses obtained via
148 DHCP are often eligible, but cryptographically-generated temporary IPv6
149 addresses are not.
150
151 \value DnsEligibilityUnknown Qt and the operating system could not determine
152 whether this address should be published or not.
153 The application may need to apply further
154 heuristics if it cannot find any eligible
155 addresses.
156 \value DnsEligible This address is eligible for publication in DNS.
157 \value DnsIneligible This address should not be published in DNS and
158 should not be transmitted to other parties,
159 except maybe as the source address of an outgoing
160 packet.
161
162 \sa dnsEligibility(), setDnsEligibility()
163*/
164
165/*!
166 Constructs an empty QNetworkAddressEntry object.
167*/
168QNetworkAddressEntry::QNetworkAddressEntry()
169 : d(new QNetworkAddressEntryPrivate)
170{
171}
172
173/*!
174 Constructs a QNetworkAddressEntry object that is a copy of the
175 object \a other.
176*/
177QNetworkAddressEntry::QNetworkAddressEntry(const QNetworkAddressEntry &other)
178 : d(new QNetworkAddressEntryPrivate(*other.d.get()))
179{
180}
181
182/*!
183 Makes a copy of the QNetworkAddressEntry object \a other.
184*/
185QNetworkAddressEntry &QNetworkAddressEntry::operator=(const QNetworkAddressEntry &other)
186{
187 *d.get() = *other.d.get();
188 return *this;
189}
190
191/*!
192 \fn void QNetworkAddressEntry::swap(QNetworkAddressEntry &other)
193 \since 5.0
194 \memberswap{network address entry instance}
195*/
196
197/*!
198 Destroys this QNetworkAddressEntry object.
199*/
200QNetworkAddressEntry::~QNetworkAddressEntry()
201{
202}
203
204/*!
205 Returns \c true if this network address entry is the same as \a
206 other.
207*/
208bool QNetworkAddressEntry::operator==(const QNetworkAddressEntry &other) const
209{
210 if (d == other.d) return true;
211 if (!d || !other.d) return false;
212 return d->address == other.d->address &&
213 d->netmask == other.d->netmask &&
214 d->broadcast == other.d->broadcast;
215}
216
217/*!
218 \since 5.11
219
220 Returns whether this address is eligible for publication in the Domain Name
221 System (DNS) or similar name resolution mechanisms.
222
223 In general, an address is suitable for publication if it is an address this
224 machine will be reached at for an indeterminate amount of time, though it
225 need not be permanent. For example, addresses obtained via DHCP are often
226 eligible, but cryptographically-generated temporary IPv6 addresses are not.
227
228 On some systems, QNetworkInterface will need to heuristically determine
229 which addresses are eligible.
230
231 \sa isLifetimeKnown(), isPermanent(), setDnsEligibility()
232*/
233QNetworkAddressEntry::DnsEligibilityStatus QNetworkAddressEntry::dnsEligibility() const
234{
235 return d->dnsEligibility;
236}
237
238/*!
239 \since 5.11
240
241 Sets the DNS eligibility flag for this address to \a status.
242
243 \sa dnsEligibility()
244*/
245void QNetworkAddressEntry::setDnsEligibility(DnsEligibilityStatus status)
246{
247 d->dnsEligibility = status;
248}
249
250/*!
251 \fn bool QNetworkAddressEntry::operator!=(const QNetworkAddressEntry &other) const
252
253 Returns \c true if this network address entry is different from \a
254 other.
255*/
256
257/*!
258 This function returns one IPv4 or IPv6 address found, that was
259 found in a network interface.
260*/
261QHostAddress QNetworkAddressEntry::ip() const
262{
263 return d->address;
264}
265
266/*!
267 Sets the IP address the QNetworkAddressEntry object contains to \a
268 newIp.
269*/
270void QNetworkAddressEntry::setIp(const QHostAddress &newIp)
271{
272 d->address = newIp;
273}
274
275/*!
276 Returns the netmask associated with the IP address. The
277 netmask is expressed in the form of an IP address, such as
278 255.255.0.0.
279
280 For IPv6 addresses, the prefix length is converted to an address
281 where the number of bits set to 1 is equal to the prefix
282 length. For a prefix length of 64 bits (the most common value),
283 the netmask will be expressed as a QHostAddress holding the
284 address FFFF:FFFF:FFFF:FFFF::
285
286 \sa prefixLength()
287*/
288QHostAddress QNetworkAddressEntry::netmask() const
289{
290 return d->netmask.address(protocol: d->address.protocol());
291}
292
293/*!
294 Sets the netmask that this QNetworkAddressEntry object contains to
295 \a newNetmask. Setting the netmask also sets the prefix length to
296 match the new netmask.
297
298 \sa setPrefixLength()
299*/
300void QNetworkAddressEntry::setNetmask(const QHostAddress &newNetmask)
301{
302 if (newNetmask.protocol() != ip().protocol()) {
303 d->netmask = QNetmask();
304 return;
305 }
306
307 d->netmask.setAddress(newNetmask);
308}
309
310/*!
311 \since 4.5
312 Returns the prefix length of this IP address. The prefix length
313 matches the number of bits set to 1 in the netmask (see
314 netmask()). For IPv4 addresses, the value is between 0 and 32. For
315 IPv6 addresses, it's contained between 0 and 128 and is the
316 preferred form of representing addresses.
317
318 This function returns -1 if the prefix length could not be
319 determined (i.e., netmask() returns a null QHostAddress()).
320
321 \sa netmask()
322*/
323int QNetworkAddressEntry::prefixLength() const
324{
325 return d->netmask.prefixLength();
326}
327
328/*!
329 \since 4.5
330 Sets the prefix length of this IP address to \a length. The value
331 of \a length must be valid for this type of IP address: between 0
332 and 32 for IPv4 addresses, between 0 and 128 for IPv6
333 addresses. Setting to any invalid value is equivalent to setting
334 to -1, which means "no prefix length".
335
336 Setting the prefix length also sets the netmask (see netmask()).
337
338 \sa setNetmask()
339*/
340void QNetworkAddressEntry::setPrefixLength(int length)
341{
342 d->netmask.setPrefixLength(proto: d->address.protocol(), len: length);
343}
344
345/*!
346 Returns the broadcast address associated with the IPv4
347 address and netmask. It can usually be derived from those two by
348 setting to 1 the bits of the IP address where the netmask contains
349 a 0. (In other words, by bitwise-OR'ing the IP address with the
350 inverse of the netmask)
351
352 This member is always empty for IPv6 addresses, since the concept
353 of broadcast has been abandoned in that system in favor of
354 multicast. In particular, the group of hosts corresponding to all
355 the nodes in the local network can be reached by the "all-nodes"
356 special multicast group (address FF02::1).
357*/
358QHostAddress QNetworkAddressEntry::broadcast() const
359{
360 return d->broadcast;
361}
362
363/*!
364 Sets the broadcast IP address of this QNetworkAddressEntry object
365 to \a newBroadcast.
366*/
367void QNetworkAddressEntry::setBroadcast(const QHostAddress &newBroadcast)
368{
369 d->broadcast = newBroadcast;
370}
371
372/*!
373 \since 5.11
374
375 Returns \c true if the address lifetime is known, \c false if not. If the
376 lifetime is not known, both preferredLifetime() and validityLifetime() will
377 return QDeadlineTimer::Forever.
378
379 \sa preferredLifetime(), validityLifetime(), setAddressLifetime(), clearAddressLifetime()
380*/
381bool QNetworkAddressEntry::isLifetimeKnown() const
382{
383 return d->lifetimeKnown;
384}
385
386/*!
387 \since 5.11
388
389 Returns the deadline when this address becomes deprecated (no longer
390 preferred), if known. If the address lifetime is not known (see
391 isLifetimeKnown()), this function always returns QDeadlineTimer::Forever.
392
393 While an address is preferred, it may be used by the operating system as
394 the source address for new, outgoing packets. After it becomes deprecated,
395 it will remain valid for incoming packets for a while longer until finally
396 removed (see validityLifetime()).
397
398 \sa validityLifetime(), isLifetimeKnown(), setAddressLifetime(), clearAddressLifetime()
399*/
400QDeadlineTimer QNetworkAddressEntry::preferredLifetime() const
401{
402 return d->preferredLifetime;
403}
404
405/*!
406 \since 5.11
407
408 Returns the deadline when this address becomes invalid and will be removed
409 from the networking stack, if known. If the address lifetime is not known
410 (see isLifetimeKnown()), this function always returns
411 QDeadlineTimer::Forever.
412
413 While an address is valid, it will be accepted by the operating system as a
414 valid destination address for this machine. Whether it is used as a source
415 address for new, outgoing packets is controlled by, among other rules, the
416 preferred lifetime (see preferredLifetime()).
417
418 \sa preferredLifetime(), isLifetimeKnown(), setAddressLifetime(), clearAddressLifetime()
419*/
420QDeadlineTimer QNetworkAddressEntry::validityLifetime() const
421{
422 return d->validityLifetime;
423}
424
425/*!
426 \since 5.11
427
428 Sets both the preferred and valid lifetimes for this address to the \a
429 preferred and \a validity deadlines, respectively. After this call,
430 isLifetimeKnown() will return \c true, even if both parameters are
431 QDeadlineTimer::Forever.
432
433 \sa preferredLifetime(), validityLifetime(), isLifetimeKnown(), clearAddressLifetime()
434*/
435void QNetworkAddressEntry::setAddressLifetime(QDeadlineTimer preferred, QDeadlineTimer validity)
436{
437 d->preferredLifetime = preferred;
438 d->validityLifetime = validity;
439 d->lifetimeKnown = true;
440}
441
442/*!
443 \since 5.11
444
445 Resets both the preferred and valid lifetimes for this address. After this
446 call, isLifetimeKnown() will return \c false.
447
448 \sa preferredLifetime(), validityLifetime(), isLifetimeKnown(), setAddressLifetime()
449*/
450void QNetworkAddressEntry::clearAddressLifetime()
451{
452 d->preferredLifetime = QDeadlineTimer::Forever;
453 d->validityLifetime = QDeadlineTimer::Forever;
454 d->lifetimeKnown = false;
455}
456
457/*!
458 \since 5.11
459
460 Returns \c true if this address is permanent on this interface, \c false if
461 it's temporary. A permanent address is one which has no expiration time and
462 is often static (manually configured).
463
464 If this information could not be determined, this function returns \c true.
465
466 \note Depending on the operating system and the networking configuration
467 tool, it is possible for a temporary address to be interpreted as
468 permanent, if the tool did not inform the details correctly to the
469 operating system.
470
471 \sa isLifetimeKnown(), validityLifetime(), isTemporary()
472*/
473bool QNetworkAddressEntry::isPermanent() const
474{
475 return d->validityLifetime.isForever();
476}
477
478/*!
479 \fn bool QNetworkAddressEntry::isTemporary() const
480 \since 5.11
481
482 Returns \c true if this address is temporary on this interface, \c false if
483 it's permanent.
484
485 \sa isLifetimeKnown(), validityLifetime(), isPermanent()
486*/
487
488/*!
489 \class QNetworkInterface
490 \brief The QNetworkInterface class provides a listing of the host's IP
491 addresses and network interfaces.
492
493 \since 4.2
494 \reentrant
495 \ingroup network
496 \ingroup shared
497 \inmodule QtNetwork
498
499 QNetworkInterface represents one network interface attached to the
500 host where the program is being run. Each network interface may
501 contain zero or more IP addresses, each of which is optionally
502 associated with a netmask and/or a broadcast address. The list of
503 such trios can be obtained with addressEntries(). Alternatively,
504 when the netmask or the broadcast addresses or other information aren't
505 necessary, use the allAddresses() convenience function to obtain just the
506 IP addresses of the active interfaces.
507
508 QNetworkInterface also reports the interface's hardware address with
509 hardwareAddress().
510
511 Not all operating systems support reporting all features. Only the
512 IPv4 addresses are guaranteed to be listed by this class in all
513 platforms. In particular, IPv6 address listing is only supported
514 on Windows, Linux, \macos and the BSDs.
515
516 \sa QNetworkAddressEntry
517*/
518
519/*!
520 \enum QNetworkInterface::InterfaceFlag
521 Specifies the flags associated with this network interface. The
522 possible values are:
523
524 \value IsUp the network interface is "up" -
525 enabled by administrative action
526 \value IsRunning the network interface is operational:
527 configured "up" and (typically)
528 physically connected to a network
529 \value CanBroadcast the network interface works in
530 broadcast mode
531 \value IsLoopBack the network interface is a loopback
532 interface: that is, it's a virtual
533 interface whose destination is the
534 host computer itself
535 \value IsPointToPoint the network interface is a
536 point-to-point interface: that is,
537 there is one, single other address
538 that can be directly reached by it.
539 \value CanMulticast the network interface supports
540 multicasting
541
542 Note that one network interface cannot be both broadcast-based and
543 point-to-point.
544*/
545
546/*!
547 \enum QNetworkInterface::InterfaceType
548
549 Specifies the type of hardware (PHY layer, OSI level 1) this interface is,
550 if it could be determined. Interface types that are not among those listed
551 below will generally be listed as Unknown, though future versions of Qt may
552 add new enumeration values.
553
554 The possible values are:
555
556 \value Unknown The interface type could not be determined or is not
557 one of the other listed types.
558 \value Loopback The virtual loopback interface, which is assigned
559 the loopback IP addresses (127.0.0.1, ::1).
560 \value Virtual A type of interface determined to be virtual, but
561 not any of the other possible types. For example,
562 tunnel interfaces are (currently) detected as
563 virtual ones.
564 \value Ethernet IEEE 802.3 Ethernet interfaces, though on many
565 systems other types of IEEE 802 interfaces may also
566 be detected as Ethernet (especially Wi-Fi).
567 \value Wifi IEEE 802.11 Wi-Fi interfaces. Note that on some
568 systems, QNetworkInterface may be unable to
569 distinguish regular Ethernet from Wi-Fi and will
570 not return this enum value.
571 \value Ieee80211 An alias for WiFi.
572 \value CanBus ISO 11898 Controller Area Network bus interfaces,
573 usually found on automotive systems.
574 \value Fddi ANSI X3T12 Fiber Distributed Data Interface, a local area
575 network over optical fibers.
576 \value Ppp Point-to-Point Protocol interfaces, establishing a
577 direct connection between two nodes over a lower
578 transport layer (often serial over radio or physical
579 line).
580 \value Slip Serial Line Internet Protocol interfaces.
581 \value Phonet Interfaces using the Linux Phonet socket family, for
582 communication with cellular modems. See the
583 \l {https://www.kernel.org/doc/Documentation/networking/phonet.txt}{Linux kernel documentation}
584 for more information.
585 \value Ieee802154 IEEE 802.15.4 Personal Area Network interfaces, other
586 than 6LoWPAN (see below).
587 \value SixLoWPAN 6LoWPAN (IPv6 over Low-power Wireless Personal Area
588 Networks) interfaces, which operate on IEEE 802.15.4
589 PHY, but have specific header compression schemes
590 for IPv6 and UDP. This type of interface is often
591 used for mesh networking.
592 \value Ieee80216 IEEE 802.16 Wireless Metropolitan Area Network, also
593 known under the commercial name "WiMAX".
594 \value Ieee1394 IEEE 1394 interfaces (a.k.a. "FireWire").
595*/
596
597/*!
598 Constructs an empty network interface object.
599*/
600QNetworkInterface::QNetworkInterface()
601 : d(nullptr)
602{
603}
604
605/*!
606 Frees the resources associated with the QNetworkInterface object.
607*/
608QNetworkInterface::~QNetworkInterface()
609{
610}
611
612/*!
613 Creates a copy of the QNetworkInterface object contained in \a
614 other.
615*/
616QNetworkInterface::QNetworkInterface(const QNetworkInterface &other)
617 : d(other.d)
618{
619}
620
621/*!
622 Copies the contents of the QNetworkInterface object contained in \a
623 other into this one.
624*/
625QNetworkInterface &QNetworkInterface::operator=(const QNetworkInterface &other)
626{
627 d = other.d;
628 return *this;
629}
630
631/*!
632 \fn void QNetworkInterface::swap(QNetworkInterface &other)
633 \since 5.0
634 \memberswap{network interface instance}
635*/
636
637/*!
638 Returns \c true if this QNetworkInterface object contains valid
639 information about a network interface.
640*/
641bool QNetworkInterface::isValid() const
642{
643 return !name().isEmpty();
644}
645
646/*!
647 \since 4.5
648 Returns the interface system index, if known. This is an integer
649 assigned by the operating system to identify this interface and it
650 generally doesn't change. It matches the scope ID field in IPv6
651 addresses.
652
653 If the index isn't known, this function returns 0.
654*/
655int QNetworkInterface::index() const
656{
657 return d ? d->index : 0;
658}
659
660/*!
661 \since 5.11
662
663 Returns the maximum transmission unit on this interface, if known, or 0
664 otherwise.
665
666 The maximum transmission unit is the largest packet that may be sent on
667 this interface without incurring link-level fragmentation. Applications may
668 use this value to calculate the size of the payload that will fit an
669 unfragmented UDP datagram. Remember to subtract the sizes of headers used
670 in your communication over the interface, e.g. TCP (20 bytes) or UDP (12),
671 IPv4 (20) or IPv6 (40, absent some form of header compression), when
672 computing how big a payload you can transmit. Also note that the MTU along
673 the full path (the Path MTU) to the destination may be smaller than the
674 interface's MTU.
675
676 \sa QUdpSocket
677*/
678int QNetworkInterface::maximumTransmissionUnit() const
679{
680 return d ? d->mtu : 0;
681}
682
683/*!
684 Returns the name of this network interface. On Unix systems, this
685 is a string containing the type of the interface and optionally a
686 sequence number, such as "eth0", "lo" or "pcn0". On Windows, it's
687 an internal ID that cannot be changed by the user.
688*/
689QString QNetworkInterface::name() const
690{
691 return d ? d->name : QString();
692}
693
694/*!
695 \since 4.5
696
697 Returns the human-readable name of this network interface on
698 Windows, such as "Local Area Connection", if the name could be
699 determined. If it couldn't, this function returns the same as
700 name(). The human-readable name is a name that the user can modify
701 in the Windows Control Panel, so it may change during the
702 execution of the program.
703
704 On Unix, this function currently always returns the same as
705 name(), since Unix systems don't store a configuration for
706 human-readable names.
707*/
708QString QNetworkInterface::humanReadableName() const
709{
710 return d ? !d->friendlyName.isEmpty() ? d->friendlyName : name() : QString();
711}
712
713/*!
714 Returns the flags associated with this network interface.
715*/
716QNetworkInterface::InterfaceFlags QNetworkInterface::flags() const
717{
718 return d ? d->flags : InterfaceFlags{};
719}
720
721/*!
722 \since 5.11
723
724 Returns the type of this interface, if it could be determined. If it could
725 not be determined, this function returns QNetworkInterface::Unknown.
726
727 \sa hardwareAddress()
728*/
729QNetworkInterface::InterfaceType QNetworkInterface::type() const
730{
731 return d ? d->type : Unknown;
732}
733
734/*!
735 Returns the low-level hardware address for this interface. On
736 Ethernet interfaces, this will be a MAC address in string
737 representation, separated by colons.
738
739 Other interface types may have other types of hardware
740 addresses. Implementations should not depend on this function
741 returning a valid MAC address.
742
743 \sa type()
744*/
745QString QNetworkInterface::hardwareAddress() const
746{
747 return d ? d->hardwareAddress : QString();
748}
749
750/*!
751 Returns the list of IP addresses that this interface possesses
752 along with their associated netmasks and broadcast addresses.
753
754 If the netmask or broadcast address or other information is not necessary,
755 you can call the allAddresses() function to obtain just the IP addresses of
756 the active interfaces.
757*/
758QList<QNetworkAddressEntry> QNetworkInterface::addressEntries() const
759{
760 return d ? d->addressEntries : QList<QNetworkAddressEntry>();
761}
762
763/*!
764 \since 5.7
765
766 Returns the index of the interface whose name is \a name or 0 if there is
767 no interface with that name. This function should produce the same result
768 as the following code, but will probably execute faster.
769
770 \snippet code/src_network_kernel_qnetworkinterface.cpp 0
771
772 \sa interfaceFromName(), interfaceNameFromIndex(), QNetworkDatagram::interfaceIndex()
773*/
774int QNetworkInterface::interfaceIndexFromName(const QString &name)
775{
776 if (name.isEmpty())
777 return 0;
778
779 bool ok;
780 uint id = name.toUInt(ok: &ok);
781 if (!ok)
782 id = QNetworkInterfaceManager::interfaceIndexFromName(name);
783 return int(id);
784}
785
786/*!
787 Returns a QNetworkInterface object for the interface named \a
788 name. If no such interface exists, this function returns an
789 invalid QNetworkInterface object.
790
791 The string \a name may be either an actual interface name (such as "eth0"
792 or "en1") or an interface index in string form ("1", "2", etc.).
793
794 \sa name(), isValid()
795*/
796QNetworkInterface QNetworkInterface::interfaceFromName(const QString &name)
797{
798 QNetworkInterface result;
799 result.d = manager()->interfaceFromName(name);
800 return result;
801}
802
803/*!
804 Returns a QNetworkInterface object for the interface whose internal
805 ID is \a index. Network interfaces have a unique identifier called
806 the "interface index" to distinguish it from other interfaces on
807 the system. Often, this value is assigned progressively and
808 interfaces being removed and then added again get a different
809 value every time.
810
811 This index is also found in the IPv6 address' scope ID field.
812*/
813QNetworkInterface QNetworkInterface::interfaceFromIndex(int index)
814{
815 QNetworkInterface result;
816 result.d = manager()->interfaceFromIndex(index);
817 return result;
818}
819
820/*!
821 \since 5.7
822
823 Returns the name of the interface whose index is \a index or an empty
824 string if there is no interface with that index. This function should
825 produce the same result as the following code, but will probably execute
826 faster.
827
828 \snippet code/src_network_kernel_qnetworkinterface.cpp 1
829
830 \sa interfaceFromIndex(), interfaceIndexFromName(), QNetworkDatagram::interfaceIndex()
831*/
832QString QNetworkInterface::interfaceNameFromIndex(int index)
833{
834 if (!index)
835 return QString();
836 return QNetworkInterfaceManager::interfaceNameFromIndex(index);
837}
838
839/*!
840 Returns a listing of all the network interfaces found on the host
841 machine. In case of failure it returns a list with zero elements.
842*/
843QList<QNetworkInterface> QNetworkInterface::allInterfaces()
844{
845 const QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces();
846 QList<QNetworkInterface> result;
847 result.reserve(asize: privs.size());
848 for (const auto &p : privs) {
849 QNetworkInterface item;
850 item.d = p;
851 result << item;
852 }
853
854 return result;
855}
856
857/*!
858 This convenience function returns all IP addresses found on the host
859 machine. It is equivalent to calling addressEntries() on all the objects
860 returned by allInterfaces() that are in the QNetworkInterface::IsUp state
861 to obtain lists of QNetworkAddressEntry objects then calling
862 QNetworkAddressEntry::ip() on each of these.
863*/
864QList<QHostAddress> QNetworkInterface::allAddresses()
865{
866 const QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces();
867 QList<QHostAddress> result;
868 for (const auto &p : privs) {
869 // skip addresses if the interface isn't up
870 if ((p->flags & QNetworkInterface::IsUp) == 0)
871 continue;
872
873 for (const QNetworkAddressEntry &entry : std::as_const(t: p->addressEntries))
874 result += entry.ip();
875 }
876
877 return result;
878}
879
880#ifndef QT_NO_DEBUG_STREAM
881static inline QDebug flagsDebug(QDebug debug, QNetworkInterface::InterfaceFlags flags)
882{
883 if (flags & QNetworkInterface::IsUp)
884 debug << "IsUp ";
885 if (flags & QNetworkInterface::IsRunning)
886 debug << "IsRunning ";
887 if (flags & QNetworkInterface::CanBroadcast)
888 debug << "CanBroadcast ";
889 if (flags & QNetworkInterface::IsLoopBack)
890 debug << "IsLoopBack ";
891 if (flags & QNetworkInterface::IsPointToPoint)
892 debug << "IsPointToPoint ";
893 if (flags & QNetworkInterface::CanMulticast)
894 debug << "CanMulticast ";
895 return debug;
896}
897
898/*!
899 \since 6.2
900
901 Writes the QNetworkAddressEntry \a entry to the stream and
902 returns a reference to the \a debug stream.
903
904 \relates QNetworkAddressEntry
905 */
906QDebug operator<<(QDebug debug, const QNetworkAddressEntry &entry)
907{
908 QDebugStateSaver saver(debug);
909 debug.resetFormat().nospace();
910 debug << "address = " << entry.ip();
911 if (!entry.netmask().isNull())
912 debug << ", netmask = " << entry.netmask();
913 if (!entry.broadcast().isNull())
914 debug << ", broadcast = " << entry.broadcast();
915 return debug;
916}
917
918/*!
919 Writes the QNetworkInterface \a networkInterface to the stream and
920 returns a reference to the \a debug stream.
921
922 \relates QNetworkInterface
923 */
924QDebug operator<<(QDebug debug, const QNetworkInterface &networkInterface)
925{
926 QDebugStateSaver saver(debug);
927 debug.resetFormat().nospace();
928 debug << "QNetworkInterface(name = " << networkInterface.name()
929 << ", hardware address = " << networkInterface.hardwareAddress()
930 << ", flags = ";
931 flagsDebug(debug, flags: networkInterface.flags());
932 debug << ", entries = " << networkInterface.addressEntries()
933 << ")\n";
934 return debug;
935}
936#endif
937
938QT_END_NAMESPACE
939
940#include "moc_qnetworkinterface.cpp"
941
942#endif // QT_NO_NETWORKINTERFACE
943

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