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