diff options
Diffstat (limited to 'src/network/kernel/qnetworkinterface_unix.cpp')
-rw-r--r-- | src/network/kernel/qnetworkinterface_unix.cpp | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index 51a266b2e3..39ff8dbb92 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -17,11 +17,7 @@ # include "qdatetime.h" #endif -#if defined(QT_LINUXBASE) -# define QT_NO_GETIFADDRS -#endif - -#ifndef QT_NO_GETIFADDRS +#if QT_CONFIG(getifaddrs) # include <ifaddrs.h> #endif @@ -56,30 +52,38 @@ static QHostAddress addressFromSockaddr(sockaddr *sa, int ifindex = 0, const QSt } } return address; +} +template <typename Req> [[maybe_unused]] +static auto &ifreq_index(Req &req, std::enable_if_t<sizeof(std::declval<Req>().ifr_index) != 0, int> = 0) +{ + return req.ifr_index; +} + +template <typename Req> [[maybe_unused]] +static auto &ifreq_index(Req &req, std::enable_if_t<sizeof(std::declval<Req>().ifr_ifindex) != 0, int> = 0) +{ + return req.ifr_ifindex; } uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name) { -#ifndef QT_NO_IPV6IFNAME - return ::if_nametoindex(name.toLatin1()); +#if QT_CONFIG(ipv6ifname) + return ::if_nametoindex(name.toLatin1().constData()); #elif defined(SIOCGIFINDEX) struct ifreq req; int socket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); if (socket < 0) return 0; - QByteArray name8bit = name.toLatin1(); + const QByteArray name8bit = name.toLatin1(); memset(&req, 0, sizeof(ifreq)); - memcpy(req.ifr_name, name8bit, qMin<int>(name8bit.length() + 1, sizeof(req.ifr_name) - 1)); + if (!name8bit.isNull()) + memcpy(req.ifr_name, name8bit.data(), qMin(size_t(name8bit.length()) + 1, sizeof(req.ifr_name) - 1)); uint id = 0; if (qt_safe_ioctl(socket, SIOCGIFINDEX, &req) >= 0) -# if QT_CONFIG(ifr_index) - id = req.ifr_index; -# else - id = req.ifr_ifindex; -# endif + id = ifreq_index(req); qt_safe_close(socket); return id; #else @@ -90,7 +94,7 @@ uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name) QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index) { -#ifndef QT_NO_IPV6IFNAME +#if QT_CONFIG(ipv6ifname) char buf[IF_NAMESIZE]; if (::if_indextoname(index, buf)) return QString::fromLatin1(buf); @@ -99,12 +103,7 @@ QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index) int socket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); if (socket >= 0) { memset(&req, 0, sizeof(ifreq)); -# if QT_CONFIG(ifr_index) - req.ifr_index = index; -# else - req.ifr_ifindex = index; -# endif - + ifreq_index(req) = index; if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) { qt_safe_close(socket); return QString::fromLatin1(req.ifr_name); @@ -124,13 +123,13 @@ static int getMtu(int socket, struct ifreq *req) return 0; } -#ifdef QT_NO_GETIFADDRS +#if !QT_CONFIG(getifaddrs) // getifaddrs not available static QSet<QByteArray> interfaceNames(int socket) { QSet<QByteArray> result; -#ifdef QT_NO_IPV6IFNAME +#if !QT_CONFIG(ipv6ifname) QByteArray storageBuffer; struct ifconf interfaceList; static const int STORAGEBUFFER_GROWTH = 256; @@ -185,15 +184,11 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa QNetworkInterfacePrivate *iface = nullptr; int ifindex = 0; -#if !defined(QT_NO_IPV6IFNAME) || defined(SIOCGIFINDEX) +#if QT_CONFIG(ipv6ifname) || defined(SIOCGIFINDEX) // Get the interface index # ifdef SIOCGIFINDEX if (qt_safe_ioctl(socket, SIOCGIFINDEX, &req) >= 0) -# if QT_CONFIG(ifr_index) - ifindex = req.ifr_index; -# else - ifindex = req.ifr_ifindex; -# endif + ifindex = ifreq_index(req); # else ifindex = if_nametoindex(req.ifr_name); # endif @@ -241,7 +236,8 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() for ( ; it != names.constEnd(); ++it) { ifreq req; memset(&req, 0, sizeof(ifreq)); - memcpy(req.ifr_name, *it, qMin<int>(it->length() + 1, sizeof(req.ifr_name) - 1)); + if (!it->isNull()) + memcpy(req.ifr_name, it->constData(), qMin(size_t(it->length()) + 1, sizeof(req.ifr_name) - 1)); QNetworkInterfacePrivate *iface = findInterface(socket, interfaces, req); @@ -252,7 +248,8 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() iface->name = QString::fromLatin1(req.ifr_name); // reset the name: - memcpy(req.ifr_name, oldName, qMin<int>(oldName.length() + 1, sizeof(req.ifr_name) - 1)); + if (!oldName.isNull()) + memcpy(req.ifr_name, oldName.constData(), qMin(size_t(oldName.length()) + 1, sizeof(req.ifr_name) - 1)); } else #endif { @@ -313,12 +310,20 @@ QT_BEGIN_INCLUDE_NAMESPACE QT_END_INCLUDE_NAMESPACE # endif +static int openSocket(int &socket) +{ + if (socket == -1) + socket = qt_safe_socket(AF_INET, SOCK_DGRAM, 0); + return socket; +} + # if defined(Q_OS_LINUX) && __GLIBC__ - 0 >= 2 && __GLIBC_MINOR__ - 0 >= 1 && !defined(QT_LINUXBASE) # include <netpacket/packet.h> static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList) { Q_UNUSED(getMtu); + Q_UNUSED(openSocket); QList<QNetworkInterfacePrivate *> interfaces; QDuplicateTracker<QString> seenInterfaces; QDuplicateTracker<int> seenIndexes; @@ -390,13 +395,6 @@ QT_BEGIN_INCLUDE_NAMESPACE #endif // QT_PLATFORM_UIKIT 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. @@ -459,7 +457,8 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList) // ensure both structs start with the name field, of size IFNAMESIZ static_assert(sizeof(mediareq.ifm_name) == sizeof(req.ifr_name)); - Q_ASSERT(&mediareq.ifm_name == &req.ifr_name); + static_assert(offsetof(struct ifmediareq, ifm_name) == 0); + static_assert(offsetof(struct ifreq, ifr_name) == 0); // on NetBSD we use AF_LINK and sockaddr_dl // scan the list for that family @@ -539,8 +538,8 @@ static void getAddressExtraInfo(QNetworkAddressEntry *entry, struct sockaddr *sa static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList) { - Q_UNUSED(getMtu); QList<QNetworkInterfacePrivate *> interfaces; + int socket = -1; // make sure there's one entry for each interface for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next) { @@ -561,9 +560,18 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList) iface->index = ifindex; iface->name = QString::fromLatin1(ptr->ifa_name); iface->flags = convertFlags(ptr->ifa_flags); + + if ((socket = openSocket(socket)) >= 0) { + struct ifreq ifr; + qstrncpy(ifr.ifr_name, ptr->ifa_name, sizeof(ifr.ifr_name)); + iface->mtu = getMtu(socket, &ifr); + } } } + if (socket != -1) + qt_safe_close(socket); + return interfaces; } |