diff options
Diffstat (limited to 'src/network/kernel/qnetworkinterface_unix.cpp')
-rw-r--r-- | src/network/kernel/qnetworkinterface_unix.cpp | 105 |
1 files changed, 37 insertions, 68 deletions
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index 5b34b99caa..c0a7d9e00d 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNetwork module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qbytearray.h" #include "qset.h" @@ -53,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 @@ -92,36 +52,49 @@ 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) - id = req.ifr_ifindex; + id = ifreq_index(req); qt_safe_close(socket); return id; #else + Q_UNUSED(name); return 0; #endif } 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); @@ -130,8 +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)); - req.ifr_ifindex = index; - + ifreq_index(req) = index; if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) { qt_safe_close(socket); return QString::fromLatin1(req.ifr_name); @@ -151,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; @@ -212,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 defined(Q_OS_HAIKU) - ifindex = req.ifr_index; -# else - ifindex = req.ifr_ifindex; -# endif + ifindex = ifreq_index(req); # else ifindex = if_nametoindex(req.ifr_name); # endif @@ -234,10 +202,11 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa break; } #else + Q_UNUSED(socket); // Search by name QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin(); for ( ; if_it != interfaces.end(); ++if_it) - if ((*if_it)->name == QLatin1String(req.ifr_name)) { + if ((*if_it)->name == QLatin1StringView(req.ifr_name)) { // existing interface iface = *if_it; break; @@ -267,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); @@ -278,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 { @@ -408,10 +379,7 @@ QT_BEGIN_INCLUDE_NAMESPACE # include <net/if_dl.h> #if defined(QT_PLATFORM_UIKIT) # include "qnetworkinterface_uikit_p.h" -#if !defined(QT_WATCHOS_OUTDATED_SDK_WORKAROUND) -// TODO: remove it as soon as SDK is updated on CI!!! # include <net/if_types.h> -#endif #else # include <net/if_media.h> # include <net/if_types.h> @@ -488,7 +456,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 @@ -617,7 +586,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing() interfaces = createInterfaces(interfaceListing); for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) { // Find the interface - QLatin1String name(ptr->ifa_name); + QLatin1StringView name(ptr->ifa_name); QNetworkInterfacePrivate *iface = nullptr; QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin(); for ( ; if_it != interfaces.end(); ++if_it) |