QNetworkInterface: Add type()
[ChangeLog][QtNetwork][QNetworkInterface] Added type(). Change-Id: I7de033f80b0e4431b7f1ffff13f9a5592b5776e1 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
4d31fc919b
commit
5193ab97f4
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 Intel Corporation.
|
||||
** Copyright (C) 2017 Intel Corporation.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||
@ -390,6 +390,57 @@ void QNetworkAddressEntry::setBroadcast(const QHostAddress &newBroadcast)
|
||||
point-to-point.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QNetworkInterface::InterfaceType
|
||||
|
||||
Specifies the type of hardware (PHY layer, OSI level 1) this interface is,
|
||||
if it could be determined. Interface types that are not among those listed
|
||||
below will generally be listed as Unknown, though future versions of Qt may
|
||||
add new enumeration values.
|
||||
|
||||
The possible values are:
|
||||
|
||||
\value Unknown The interface type could not be determined or is not
|
||||
one of the other listed types.
|
||||
\value Loopback The virtual loopback interface, which is assigned
|
||||
the loopback IP addresses (127.0.0.1, ::1).
|
||||
\value Virtual A type of interface determined to be virtual, but
|
||||
not any of the other possible types. For example,
|
||||
tunnel interfaces are (currently) detected as
|
||||
virtual ones.
|
||||
\value Ethernet IEEE 802.3 Ethernet interfaces, though on many
|
||||
systems other types of IEEE 802 interfaces may also
|
||||
be detected as Ethernet (especially Wi-Fi).
|
||||
\value WiFi IEEE 802.11 Wi-Fi interfaces. Note that on some
|
||||
systems, QNetworkInterface may be unable to
|
||||
distinguish regular Ethernet from Wi-Fi and will
|
||||
not return this enum value.
|
||||
\value Ieee80211 An alias for WiFi.
|
||||
\value CanBus ISO 11898 Controller Area Network bus interfaces,
|
||||
usually found on automotive systems.
|
||||
\value Fddi ANSI X3T12 Fiber Distributed Data Interface, a local area
|
||||
network over optical fibers.
|
||||
\value Ppp Point-to-Point Protocol interfaces, establishing a
|
||||
direct connection between two nodes over a lower
|
||||
transport layer (often serial over radio or physical
|
||||
line).
|
||||
\value Slip Serial Line Internet Protocol interfaces.
|
||||
\value Phonet Interfaces using the Linux Phonet socket family, for
|
||||
communication with cellular modems. See the
|
||||
\l {https://www.kernel.org/doc/Documentation/networking/phonet.txt}{Linux kernel documentation}
|
||||
for more information.
|
||||
\value Ieee802154 IEEE 802.15.4 Personal Area Network interfaces, other
|
||||
than 6LoWPAN (see below).
|
||||
\value SixLoWPAN 6LoWPAN (IPv6 over Low-power Wireless Personal Area
|
||||
Networks) interfaces, which operate on IEEE 802.15.4
|
||||
PHY, but have specific header compression schemes
|
||||
for IPv6 and UDP. This type of interface is often
|
||||
used for mesh networking.
|
||||
\value Ieee80216 IEEE 802.16 Wireless Metropolitan Area Network, also
|
||||
known under the commercial name "WiMAX".
|
||||
\value Ieee1394 IEEE 1394 interfaces (a.k.a. "FireWire").
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an empty network interface object.
|
||||
*/
|
||||
@ -493,6 +544,19 @@ QNetworkInterface::InterfaceFlags QNetworkInterface::flags() const
|
||||
return d ? d->flags : InterfaceFlags(0);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.11
|
||||
|
||||
Returns the type of this interface, if it could be determined. If it could
|
||||
not be determined, this function returns QNetworkInterface::Unknown.
|
||||
|
||||
\sa hardwareAddress()
|
||||
*/
|
||||
QNetworkInterface::InterfaceType QNetworkInterface::type() const
|
||||
{
|
||||
return d ? d->type : Unknown;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the low-level hardware address for this interface. On
|
||||
Ethernet interfaces, this will be a MAC address in string
|
||||
@ -501,6 +565,8 @@ QNetworkInterface::InterfaceFlags QNetworkInterface::flags() const
|
||||
Other interface types may have other types of hardware
|
||||
addresses. Implementations should not depend on this function
|
||||
returning a valid MAC address.
|
||||
|
||||
\sa type()
|
||||
*/
|
||||
QString QNetworkInterface::hardwareAddress() const
|
||||
{
|
||||
@ -686,4 +752,6 @@ QDebug operator<<(QDebug debug, const QNetworkInterface &networkInterface)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qnetworkinterface.cpp"
|
||||
|
||||
#endif // QT_NO_NETWORKINTERFACE
|
||||
|
@ -90,6 +90,7 @@ Q_DECLARE_SHARED(QNetworkAddressEntry)
|
||||
class QNetworkInterfacePrivate;
|
||||
class Q_NETWORK_EXPORT QNetworkInterface
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
enum InterfaceFlag {
|
||||
IsUp = 0x1,
|
||||
@ -100,6 +101,27 @@ public:
|
||||
CanMulticast = 0x20
|
||||
};
|
||||
Q_DECLARE_FLAGS(InterfaceFlags, InterfaceFlag)
|
||||
Q_FLAG(InterfaceFlags)
|
||||
|
||||
enum InterfaceType {
|
||||
Loopback = 1,
|
||||
Virtual,
|
||||
Ethernet,
|
||||
Slip,
|
||||
CanBus,
|
||||
Ppp,
|
||||
Fddi,
|
||||
Wifi,
|
||||
Ieee80211 = Wifi, // alias
|
||||
Phonet,
|
||||
Ieee802154,
|
||||
SixLoWPAN, // 6LoWPAN, but we can't start with a digit
|
||||
Ieee80216,
|
||||
Ieee1394,
|
||||
|
||||
Unknown = 0
|
||||
};
|
||||
Q_ENUM(InterfaceType)
|
||||
|
||||
QNetworkInterface();
|
||||
QNetworkInterface(const QNetworkInterface &other);
|
||||
@ -117,6 +139,7 @@ public:
|
||||
QString name() const;
|
||||
QString humanReadableName() const;
|
||||
InterfaceFlags flags() const;
|
||||
InterfaceType type() const;
|
||||
QString hardwareAddress() const;
|
||||
QList<QNetworkAddressEntry> addressEntries() const;
|
||||
|
||||
|
@ -48,16 +48,76 @@
|
||||
// accordding to rtnetlink(7)
|
||||
#include <asm/types.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* in case these aren't defined in linux/if_arp.h (added since 2.6.28) */
|
||||
#define ARPHRD_PHONET 820 /* v2.6.29: PhoNet media type */
|
||||
#define ARPHRD_PHONET_PIPE 821 /* v2.6.29: PhoNet pipe header */
|
||||
#define ARPHRD_IEEE802154 804 /* v2.6.31 */
|
||||
#define ARPHRD_6LOWPAN 825 /* v3.14: IPv6 over LoWPAN */
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum {
|
||||
BufferSize = 8192
|
||||
};
|
||||
|
||||
static QNetworkInterface::InterfaceType probeIfType(int socket, struct ifreq *req, short arptype)
|
||||
{
|
||||
switch (ushort(arptype)) {
|
||||
case ARPHRD_LOOPBACK:
|
||||
return QNetworkInterface::Loopback;
|
||||
|
||||
case ARPHRD_ETHER:
|
||||
// check if it's a WiFi interface
|
||||
if (qt_safe_ioctl(socket, SIOCGIWMODE, req) >= 0)
|
||||
return QNetworkInterface::Wifi;
|
||||
return QNetworkInterface::Ethernet;
|
||||
|
||||
case ARPHRD_SLIP:
|
||||
case ARPHRD_CSLIP:
|
||||
case ARPHRD_SLIP6:
|
||||
case ARPHRD_CSLIP6:
|
||||
return QNetworkInterface::Slip;
|
||||
|
||||
case ARPHRD_CAN:
|
||||
return QNetworkInterface::CanBus;
|
||||
|
||||
case ARPHRD_PPP:
|
||||
return QNetworkInterface::Ppp;
|
||||
|
||||
case ARPHRD_FDDI:
|
||||
return QNetworkInterface::Fddi;
|
||||
|
||||
case ARPHRD_IEEE80211:
|
||||
case ARPHRD_IEEE80211_PRISM:
|
||||
case ARPHRD_IEEE80211_RADIOTAP:
|
||||
return QNetworkInterface::Ieee80211;
|
||||
|
||||
case ARPHRD_IEEE802154:
|
||||
return QNetworkInterface::Ieee802154;
|
||||
|
||||
case ARPHRD_PHONET:
|
||||
case ARPHRD_PHONET_PIPE:
|
||||
return QNetworkInterface::Phonet;
|
||||
|
||||
case ARPHRD_6LOWPAN:
|
||||
return QNetworkInterface::SixLoWPAN;
|
||||
|
||||
case ARPHRD_TUNNEL:
|
||||
case ARPHRD_TUNNEL6:
|
||||
case ARPHRD_NONE:
|
||||
case ARPHRD_VOID:
|
||||
return QNetworkInterface::Virtual;
|
||||
}
|
||||
return QNetworkInterface::Unknown;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
struct NetlinkSocket
|
||||
{
|
||||
@ -195,6 +255,7 @@ QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
|
||||
static QList<QNetworkInterfacePrivate *> getInterfaces(int sock, char *buf)
|
||||
{
|
||||
QList<QNetworkInterfacePrivate *> result;
|
||||
struct ifreq req;
|
||||
|
||||
// request all links
|
||||
struct {
|
||||
@ -227,6 +288,8 @@ static QList<QNetworkInterfacePrivate *> getInterfaces(int sock, char *buf)
|
||||
break;
|
||||
|
||||
case IFLA_IFNAME: // interface name
|
||||
Q_ASSERT(payloadLen <= int(sizeof(req.ifr_name)));
|
||||
memcpy(req.ifr_name, payloadPtr, payloadLen); // including terminating NUL
|
||||
iface->name = QString::fromLatin1(payloadPtr, payloadLen - 1);
|
||||
break;
|
||||
|
||||
@ -245,6 +308,7 @@ static QList<QNetworkInterfacePrivate *> getInterfaces(int sock, char *buf)
|
||||
qWarning("QNetworkInterface: found interface %d with no name", iface->index);
|
||||
delete iface;
|
||||
} else {
|
||||
iface->type = probeIfType(sock, &req, ifi->ifi_type);
|
||||
result.append(iface);
|
||||
}
|
||||
});
|
||||
|
@ -52,6 +52,7 @@
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/qnetworkinterface.h>
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qreadwritelock.h>
|
||||
@ -82,6 +83,7 @@ public:
|
||||
|
||||
int index; // interface index, if know
|
||||
QNetworkInterface::InterfaceFlags flags;
|
||||
QNetworkInterface::InterfaceType type = QNetworkInterface::Unknown;
|
||||
|
||||
QString name;
|
||||
QString friendlyName;
|
||||
|
@ -384,11 +384,70 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
|
||||
# elif defined(Q_OS_BSD4)
|
||||
QT_BEGIN_INCLUDE_NAMESPACE
|
||||
# include <net/if_dl.h>
|
||||
# include <net/if_media.h>
|
||||
# include <net/if_types.h>
|
||||
QT_END_INCLUDE_NAMESPACE
|
||||
|
||||
static int openSocket(int &socket)
|
||||
{
|
||||
if (socket == -1)
|
||||
socket = qt_safe_socket(AF_INET, SOCK_DGRAM, 0);
|
||||
return socket;
|
||||
}
|
||||
|
||||
static QNetworkInterface::InterfaceType probeIfType(int socket, int iftype, struct ifmediareq *req)
|
||||
{
|
||||
// Determine the interface type.
|
||||
|
||||
// On Darwin, these are #defines, but on FreeBSD they're just an
|
||||
// enum, so we can't #ifdef them. Use the authoritative list from
|
||||
// https://www.iana.org/assignments/smi-numbers/smi-numbers.xhtml#smi-numbers-5
|
||||
switch (iftype) {
|
||||
case IFT_PPP:
|
||||
return QNetworkInterface::Ppp;
|
||||
|
||||
case IFT_LOOP:
|
||||
return QNetworkInterface::Loopback;
|
||||
|
||||
case IFT_SLIP:
|
||||
return QNetworkInterface::Slip;
|
||||
|
||||
case 0x47: // IFT_IEEE80211
|
||||
return QNetworkInterface::Ieee80211;
|
||||
|
||||
case IFT_IEEE1394:
|
||||
return QNetworkInterface::Ieee1394;
|
||||
|
||||
case IFT_GIF:
|
||||
case IFT_STF:
|
||||
return QNetworkInterface::Virtual;
|
||||
}
|
||||
|
||||
// For the remainder (including Ethernet), let's try SIOGIFMEDIA
|
||||
req->ifm_count = 0;
|
||||
if (qt_safe_ioctl(socket, SIOCGIFMEDIA, req) == 0) {
|
||||
// see https://man.openbsd.org/ifmedia.4
|
||||
|
||||
switch (IFM_TYPE(req->ifm_current)) {
|
||||
case IFM_ETHER:
|
||||
return QNetworkInterface::Ethernet;
|
||||
|
||||
case IFM_FDDI:
|
||||
return QNetworkInterface::Fddi;
|
||||
|
||||
case IFM_IEEE80211:
|
||||
return QNetworkInterface::Ieee80211;
|
||||
}
|
||||
}
|
||||
|
||||
return QNetworkInterface::Unknown;
|
||||
}
|
||||
|
||||
static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
|
||||
{
|
||||
QList<QNetworkInterfacePrivate *> interfaces;
|
||||
struct ifmediareq mediareq;
|
||||
int socket = -1;
|
||||
|
||||
// on NetBSD we use AF_LINK and sockaddr_dl
|
||||
// scan the list for that family
|
||||
@ -402,8 +461,13 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
|
||||
iface->name = QString::fromLatin1(ptr->ifa_name);
|
||||
iface->flags = convertFlags(ptr->ifa_flags);
|
||||
iface->hardwareAddress = iface->makeHwAddress(sdl->sdl_alen, (uchar*)LLADDR(sdl));
|
||||
|
||||
strlcpy(mediareq.ifm_name, ptr->ifa_name, sizeof(mediareq.ifm_name));
|
||||
iface->type = probeIfType(openSocket(socket), sdl->sdl_type, &mediareq);
|
||||
}
|
||||
|
||||
if (socket != -1)
|
||||
qt_safe_close(socket);
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,10 @@
|
||||
|
||||
#include <qt_windows.h>
|
||||
|
||||
// In case these aren't defined
|
||||
#define IF_TYPE_IEEE80216_WMAN 237
|
||||
#define IF_TYPE_IEEE802154 259
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static QHostAddress addressFromSockaddr(sockaddr *sa)
|
||||
@ -155,6 +159,45 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
|
||||
if (ptr->IfType == IF_TYPE_PPP)
|
||||
iface->flags |= QNetworkInterface::IsPointToPoint;
|
||||
|
||||
switch (ptr->IfType) {
|
||||
case IF_TYPE_ETHERNET_CSMACD:
|
||||
iface->type = QNetworkInterface::Ethernet;
|
||||
break;
|
||||
|
||||
case IF_TYPE_FDDI:
|
||||
iface->type = QNetworkInterface::Fddi;
|
||||
break;
|
||||
|
||||
case IF_TYPE_PPP:
|
||||
iface->type = QNetworkInterface::Ppp;
|
||||
break;
|
||||
|
||||
case IF_TYPE_SLIP:
|
||||
iface->type = QNetworkInterface::Slip;
|
||||
break;
|
||||
|
||||
case IF_TYPE_SOFTWARE_LOOPBACK:
|
||||
iface->type = QNetworkInterface::Loopback;
|
||||
iface->flags |= QNetworkInterface::IsLoopBack;
|
||||
break;
|
||||
|
||||
case IF_TYPE_IEEE80211:
|
||||
iface->type = QNetworkInterface::Ieee80211;
|
||||
break;
|
||||
|
||||
case IF_TYPE_IEEE1394:
|
||||
iface->type = QNetworkInterface::Ieee1394;
|
||||
break;
|
||||
|
||||
case IF_TYPE_IEEE80216_WMAN:
|
||||
iface->type = QNetworkInterface::Ieee80216;
|
||||
break;
|
||||
|
||||
case IF_TYPE_IEEE802154:
|
||||
iface->type = QNetworkInterface::Ieee802154;
|
||||
break;
|
||||
}
|
||||
|
||||
// use ConvertInterfaceLuidToNameW because that returns a friendlier name, though not
|
||||
// as "friendly" as FriendlyName below
|
||||
WCHAR buf[IF_MAX_STRING_SIZE + 1];
|
||||
@ -167,9 +210,6 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
|
||||
if (ptr->PhysicalAddressLength)
|
||||
iface->hardwareAddress = iface->makeHwAddress(ptr->PhysicalAddressLength,
|
||||
ptr->PhysicalAddress);
|
||||
else
|
||||
// loopback if it has no address
|
||||
iface->flags |= QNetworkInterface::IsLoopBack;
|
||||
|
||||
// parse the IP (unicast) addresses
|
||||
for (PIP_ADAPTER_UNICAST_ADDRESS addr = ptr->FirstUnicastAddress; addr; addr = addr->Next) {
|
||||
|
@ -138,6 +138,7 @@ void tst_QNetworkInterface::dump()
|
||||
|
||||
qDebug() << " index: " << i.index();
|
||||
qDebug() << " flags: " << qPrintable(flags);
|
||||
qDebug() << " type: " << i.type();
|
||||
qDebug() << " hw address:" << qPrintable(i.hardwareAddress());
|
||||
|
||||
int count = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user