1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qnetworkmanagernetworkinformationbackend.h"
6
7#include <QtCore/qglobal.h>
8#include <QtCore/private/qobject_p.h>
9
10#include <QtDBus/qdbusmessage.h>
11
12QT_BEGIN_NAMESPACE
13Q_DECLARE_LOGGING_CATEGORY(lcNetInfoNLM)
14Q_LOGGING_CATEGORY(lcNetInfoNM, "qt.network.info.networkmanager");
15
16namespace {
17QNetworkInformation::Reachability reachabilityFromNMState(QNetworkManagerInterface::NMState state)
18{
19 switch (state) {
20 case QNetworkManagerInterface::NM_STATE_UNKNOWN:
21 case QNetworkManagerInterface::NM_STATE_ASLEEP:
22 case QNetworkManagerInterface::NM_STATE_CONNECTING:
23 return QNetworkInformation::Reachability::Unknown;
24 case QNetworkManagerInterface::NM_STATE_DISCONNECTING: // No point in starting new connections:
25 case QNetworkManagerInterface::NM_STATE_DISCONNECTED:
26 return QNetworkInformation::Reachability::Disconnected;
27 case QNetworkManagerInterface::NM_STATE_CONNECTED_LOCAL:
28 return QNetworkInformation::Reachability::Local;
29 case QNetworkManagerInterface::NM_STATE_CONNECTED_SITE:
30 return QNetworkInformation::Reachability::Site;
31 case QNetworkManagerInterface::NM_STATE_CONNECTED_GLOBAL:
32 return QNetworkInformation::Reachability::Online;
33 }
34 return QNetworkInformation::Reachability::Unknown;
35}
36
37QNetworkInformation::TransportMedium
38transportMediumFromDeviceType(QNetworkManagerInterface::NMDeviceType type)
39{
40 switch (type) {
41 case QNetworkManagerInterface::NM_DEVICE_TYPE_ETHERNET:
42 return QNetworkInformation::TransportMedium::Ethernet;
43 case QNetworkManagerInterface::NM_DEVICE_TYPE_WIFI:
44 return QNetworkInformation::TransportMedium::WiFi;
45 case QNetworkManagerInterface::NM_DEVICE_TYPE_BT:
46 return QNetworkInformation::TransportMedium::Bluetooth;
47 case QNetworkManagerInterface::NM_DEVICE_TYPE_MODEM:
48 return QNetworkInformation::TransportMedium::Cellular;
49
50 case QNetworkManagerInterface::NM_DEVICE_TYPE_UNKNOWN:
51 case QNetworkManagerInterface::NM_DEVICE_TYPE_GENERIC:
52 case QNetworkManagerInterface::NM_DEVICE_TYPE_UNUSED1:
53 case QNetworkManagerInterface::NM_DEVICE_TYPE_UNUSED2:
54 case QNetworkManagerInterface::NM_DEVICE_TYPE_OLPC_MESH:
55 case QNetworkManagerInterface::NM_DEVICE_TYPE_WIMAX:
56 case QNetworkManagerInterface::NM_DEVICE_TYPE_INFINIBAND:
57 case QNetworkManagerInterface::NM_DEVICE_TYPE_BOND:
58 case QNetworkManagerInterface::NM_DEVICE_TYPE_VLAN:
59 case QNetworkManagerInterface::NM_DEVICE_TYPE_ADSL:
60 case QNetworkManagerInterface::NM_DEVICE_TYPE_BRIDGE:
61 case QNetworkManagerInterface::NM_DEVICE_TYPE_TEAM:
62 case QNetworkManagerInterface::NM_DEVICE_TYPE_TUN:
63 case QNetworkManagerInterface::NM_DEVICE_TYPE_IP_TUNNEL:
64 case QNetworkManagerInterface::NM_DEVICE_TYPE_MACVLAN:
65 case QNetworkManagerInterface::NM_DEVICE_TYPE_VXLAN:
66 case QNetworkManagerInterface::NM_DEVICE_TYPE_VETH:
67 case QNetworkManagerInterface::NM_DEVICE_TYPE_MACSEC:
68 case QNetworkManagerInterface::NM_DEVICE_TYPE_DUMMY:
69 case QNetworkManagerInterface::NM_DEVICE_TYPE_PPP:
70 case QNetworkManagerInterface::NM_DEVICE_TYPE_OVS_INTERFACE:
71 case QNetworkManagerInterface::NM_DEVICE_TYPE_OVS_PORT:
72 case QNetworkManagerInterface::NM_DEVICE_TYPE_OVS_BRIDGE:
73 case QNetworkManagerInterface::NM_DEVICE_TYPE_WPAN:
74 case QNetworkManagerInterface::NM_DEVICE_TYPE_6LOWPAN:
75 case QNetworkManagerInterface::NM_DEVICE_TYPE_WIREGUARD:
76 case QNetworkManagerInterface::NM_DEVICE_TYPE_WIFI_P2P:
77 case QNetworkManagerInterface::NM_DEVICE_TYPE_VRF:
78 break;
79 }
80 // While the list is exhaustive of the enum there can be additional
81 // entries added in NetworkManager that isn't listed here
82 return QNetworkInformation::TransportMedium::Unknown;
83}
84
85bool isMeteredFromNMMetered(QNetworkManagerInterface::NMMetered metered)
86{
87 switch (metered) {
88 case QNetworkManagerInterface::NM_METERED_YES:
89 case QNetworkManagerInterface::NM_METERED_GUESS_YES:
90 return true;
91 case QNetworkManagerInterface::NM_METERED_NO:
92 case QNetworkManagerInterface::NM_METERED_GUESS_NO:
93 case QNetworkManagerInterface::NM_METERED_UNKNOWN:
94 return false;
95 }
96 Q_UNREACHABLE_RETURN(false);
97}
98} // unnamed namespace
99
100static QString backendName()
101{
102 return QStringView(QNetworkInformationBackend::PluginNames
103 [QNetworkInformationBackend::PluginNamesLinuxIndex]).toString();
104}
105
106QString QNetworkManagerNetworkInformationBackend::name() const
107{
108 return backendName();
109}
110
111class QNetworkManagerNetworkInformationBackendFactory : public QNetworkInformationBackendFactory
112{
113 Q_OBJECT
114 Q_PLUGIN_METADATA(IID QNetworkInformationBackendFactory_iid)
115 Q_INTERFACES(QNetworkInformationBackendFactory)
116public:
117 QNetworkManagerNetworkInformationBackendFactory() = default;
118 ~QNetworkManagerNetworkInformationBackendFactory() = default;
119 QString name() const override { return backendName(); }
120 QNetworkInformation::Features featuresSupported() const override
121 {
122 if (!QNetworkManagerInterfaceBase::networkManagerAvailable())
123 return {};
124 return QNetworkManagerNetworkInformationBackend::featuresSupportedStatic();
125 }
126
127 QNetworkInformationBackend *create(QNetworkInformation::Features requiredFeatures) const override
128 {
129 if ((requiredFeatures & featuresSupported()) != requiredFeatures)
130 return nullptr;
131 if (!QNetworkManagerInterfaceBase::networkManagerAvailable())
132 return nullptr;
133 auto backend = new QNetworkManagerNetworkInformationBackend();
134 if (!backend->isValid())
135 delete std::exchange(obj&: backend, new_val: nullptr);
136 return backend;
137 }
138private:
139 Q_DISABLE_COPY_MOVE(QNetworkManagerNetworkInformationBackendFactory)
140};
141
142QNetworkManagerNetworkInformationBackend::QNetworkManagerNetworkInformationBackend()
143{
144 if (!iface.isValid())
145 return;
146 iface.setBackend(this);
147 onStateChanged(state: iface.state());
148 onConnectivityChanged(connectivityState: iface.connectivityState());
149 onDeviceTypeChanged(deviceType: iface.deviceType());
150 onMeteredChanged(metered: iface.meteredState());
151}
152
153void QNetworkManagerNetworkInformationBackend::onStateChanged(
154 QNetworkManagerInterface::NMState newState)
155{
156 setReachability(reachabilityFromNMState(state: newState));
157}
158
159void QNetworkManagerNetworkInformationBackend::onConnectivityChanged(
160 QNetworkManagerInterface::NMConnectivityState connectivityState)
161{
162 const bool behindPortal =
163 (connectivityState == QNetworkManagerInterface::NM_CONNECTIVITY_PORTAL);
164 setBehindCaptivePortal(behindPortal);
165}
166
167void QNetworkManagerNetworkInformationBackend::onDeviceTypeChanged(
168 QNetworkManagerInterface::NMDeviceType newDevice)
169{
170 setTransportMedium(transportMediumFromDeviceType(type: newDevice));
171}
172
173void QNetworkManagerNetworkInformationBackend::onMeteredChanged(
174 QNetworkManagerInterface::NMMetered metered)
175{
176 setMetered(isMeteredFromNMMetered(metered));
177};
178
179QT_END_NAMESPACE
180
181#include "qnetworkmanagernetworkinformationbackend.moc"
182#include "moc_qnetworkmanagernetworkinformationbackend.cpp"
183

source code of qtbase/src/plugins/networkinformation/networkmanager/qnetworkmanagernetworkinformationbackend.cpp