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

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