1/*
2 SPDX-FileCopyrightText: 2008, 2011 Will Stephenson <wstephenson@kde.org>
3 SPDX-FileCopyrightText: 2013 Daniel Nicoletti <dantti12@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "ipconfig.h"
9
10#include "manager.h"
11#include "manager_p.h"
12
13#include <arpa/inet.h>
14
15#include "dbus/ip4configinterface.h"
16#include "dbus/ip6configinterface.h"
17
18namespace NetworkManager
19{
20class NetworkManager::IpConfig::Private
21{
22public:
23 Private(const QList<IpAddress> &theAddresses, const QList<QHostAddress> &theNameservers, const QStringList &theDomains, const QList<IpRoute> &theRoutes)
24 : addresses(theAddresses)
25 , nameservers(theNameservers)
26 , domains(theDomains)
27 , routes(theRoutes)
28 {
29 }
30 Private()
31 {
32 }
33 IpAddresses addresses;
34 QString gateway;
35 QStringList searches;
36 QList<QHostAddress> nameservers;
37 QStringList domains;
38 IpRoutes routes;
39 QStringList dnsOptions;
40};
41
42}
43
44NetworkManager::IpConfig::IpConfig(const IpAddresses &addresses, const QList<QHostAddress> &nameservers, const QStringList &domains, const IpRoutes &routes)
45 : d(new Private(addresses, nameservers, domains, routes))
46{
47}
48
49NetworkManager::IpConfig::IpConfig()
50 : d(new Private())
51{
52}
53
54NetworkManager::IpConfig::IpConfig(const IpConfig &other)
55 : d(new Private)
56{
57 *this = other;
58}
59
60void NetworkManager::IpConfig::setIPv4Path(const QString &path)
61{
62 OrgFreedesktopNetworkManagerIP4ConfigInterface iface(NetworkManagerPrivate::DBUS_SERVICE,
63 path,
64#ifdef NMQT_STATIC
65 QDBusConnection::sessionBus());
66#else
67 QDBusConnection::systemBus());
68#endif
69 // TODO - watch propertiesChanged signal
70
71 QList<NetworkManager::IpAddress> addressObjects;
72 QList<NetworkManager::IpRoute> routeObjects;
73 if (NetworkManager::checkVersion(x: 1, y: 0, z: 0)) {
74 const NMVariantMapList addresses = iface.addressData();
75 for (const QVariantMap &addressList : addresses) {
76 if (addressList.contains(key: QLatin1String("address")) //
77 && addressList.contains(key: QLatin1String("prefix"))) {
78 NetworkManager::IpAddress address;
79 address.setIp(QHostAddress(addressList.value(key: QLatin1String("address")).toString()));
80 address.setPrefixLength(addressList.value(key: QLatin1String("prefix")).toUInt());
81 if (addressList.contains(key: QLatin1String("gateway"))) {
82 address.setGateway(QHostAddress(addressList.value(key: QLatin1String("gateway")).toString()));
83 }
84 addressObjects << address;
85 }
86 }
87
88 const NMVariantMapList routes = iface.routeData();
89 for (const QVariantMap &routeList : routes) {
90 if (routeList.contains(key: QLatin1String("address")) && routeList.contains(key: QLatin1String("prefix"))) {
91 NetworkManager::IpRoute route;
92 route.setIp(QHostAddress(routeList.value(key: QLatin1String("address")).toString()));
93 route.setPrefixLength(routeList.value(key: QLatin1String("prefix")).toUInt());
94 if (routeList.contains(key: QLatin1String("next-hop"))) {
95 route.setNextHop(QHostAddress(routeList.value(key: QLatin1String("next-hop")).toString()));
96 }
97
98 if (routeList.contains(key: QLatin1String("metric"))) {
99 route.setMetric(routeList.value(key: QLatin1String("metric")).toUInt());
100 }
101 routeObjects << route;
102 }
103 }
104 } else {
105 // convert ipaddresses into object
106 const UIntListList addresses = iface.addresses();
107 for (const UIntList &addressList : addresses) {
108 if (addressList.count() == 3) {
109 NetworkManager::IpAddress address;
110 address.setIp(QHostAddress(ntohl(netlong: addressList[0])));
111 address.setPrefixLength(addressList[1]);
112 address.setGateway(QHostAddress(ntohl(netlong: addressList[2])));
113 addressObjects << address;
114 }
115 }
116 // convert routes into objects
117 const UIntListList routes = iface.routes();
118 for (const UIntList &routeList : routes) {
119 if (routeList.count() == 4) {
120 NetworkManager::IpRoute route;
121 route.setIp(QHostAddress(ntohl(netlong: routeList[0])));
122 route.setPrefixLength(routeList[1]);
123 route.setNextHop(QHostAddress(ntohl(netlong: routeList[2])));
124 route.setMetric(ntohl(netlong: routeList[3]));
125 routeObjects << route;
126 }
127 }
128 }
129 // nameservers' IP addresses are always in network byte order
130 QList<QHostAddress> nameservers;
131 const QList<uint> ifaceNameservers = iface.nameservers();
132 for (uint nameserver : ifaceNameservers) {
133 nameservers << QHostAddress(ntohl(netlong: nameserver));
134 }
135
136 d->addresses = addressObjects;
137 d->routes = routeObjects;
138 d->nameservers = nameservers;
139 d->gateway = iface.gateway();
140 d->searches = iface.searches();
141 d->domains = iface.domains();
142 if (NetworkManager::checkVersion(x: 1, y: 2, z: 0)) {
143 d->dnsOptions = iface.dnsOptions();
144 }
145}
146
147void NetworkManager::IpConfig::setIPv6Path(const QString &path)
148{
149 // ask the daemon for the details
150 OrgFreedesktopNetworkManagerIP6ConfigInterface iface(NetworkManagerPrivate::DBUS_SERVICE,
151 path,
152#ifdef NMQT_STATIC
153 QDBusConnection::sessionBus());
154#else
155 QDBusConnection::systemBus());
156#endif
157 // TODO - watch propertiesChanged signal
158
159 QList<NetworkManager::IpAddress> addressObjects;
160 QList<NetworkManager::IpRoute> routeObjects;
161 if (NetworkManager::checkVersion(x: 1, y: 0, z: 0)) {
162 const NMVariantMapList addresses = iface.addressData();
163 for (const QVariantMap &addressList : addresses) {
164 if (addressList.contains(key: QLatin1String("address")) //
165 && addressList.contains(key: QLatin1String("prefix"))) {
166 NetworkManager::IpAddress address;
167 address.setIp(QHostAddress(addressList.value(key: QLatin1String("address")).toString()));
168 address.setPrefixLength(addressList.value(key: QLatin1String("prefix")).toUInt());
169 if (addressList.contains(key: QLatin1String("gateway"))) {
170 address.setGateway(QHostAddress(addressList.value(key: QLatin1String("gateway")).toString()));
171 }
172 addressObjects << address;
173 }
174 }
175
176 const NMVariantMapList routes = iface.routeData();
177 for (const QVariantMap &routeList : routes) {
178 if (routeList.contains(key: QLatin1String("address")) && routeList.contains(key: QLatin1String("prefix"))) {
179 NetworkManager::IpRoute route;
180 route.setIp(QHostAddress(routeList.value(key: QLatin1String("address")).toString()));
181 route.setPrefixLength(routeList.value(key: QLatin1String("prefix")).toUInt());
182 if (routeList.contains(key: QLatin1String("next-hop"))) {
183 route.setNextHop(QHostAddress(routeList.value(key: QLatin1String("next-hop")).toString()));
184 }
185
186 if (routeList.contains(key: QLatin1String("metric"))) {
187 route.setMetric(routeList.value(key: QLatin1String("metric")).toUInt());
188 }
189 routeObjects << route;
190 }
191 }
192 } else {
193 const IpV6DBusAddressList addresses = iface.addresses();
194 for (const IpV6DBusAddress &address : addresses) {
195 Q_IPV6ADDR addr;
196 Q_IPV6ADDR gateway;
197 for (int i = 0; i < 16; i++) {
198 addr[i] = address.address[i];
199 }
200 for (int i = 0; i < 16; i++) {
201 gateway[i] = address.gateway[i];
202 }
203 NetworkManager::IpAddress addressEntry;
204 addressEntry.setIp(QHostAddress(addr));
205 addressEntry.setPrefixLength(address.prefix);
206 addressEntry.setGateway(QHostAddress(gateway));
207 addressObjects << addressEntry;
208 }
209
210 const IpV6DBusRouteList routes = iface.routes();
211 for (const IpV6DBusRoute &route : routes) {
212 Q_IPV6ADDR dest;
213 Q_IPV6ADDR nexthop;
214 for (int i = 0; i < 16; i++) {
215 dest[i] = route.destination[i];
216 }
217 for (int i = 0; i < 16; i++) {
218 nexthop[i] = route.nexthop[i];
219 }
220 NetworkManager::IpRoute routeEntry;
221 routeEntry.setIp(QHostAddress(dest));
222 routeEntry.setPrefixLength(route.prefix);
223 routeEntry.setNextHop(QHostAddress(nexthop));
224 routeEntry.setMetric(route.metric);
225 routeObjects << routeEntry;
226 }
227 }
228
229 QList<QHostAddress> nameservers;
230 const QList<QByteArray> ifaceNservers = iface.nameservers();
231 for (const QByteArray &nameserver : ifaceNservers) {
232 Q_IPV6ADDR address;
233 for (int i = 0; i < 16; i++) {
234 address[i] = static_cast<quint8>(nameserver[i]);
235 }
236 nameservers << QHostAddress(address);
237 }
238
239 d->addresses = addressObjects;
240 d->routes = routeObjects;
241 d->nameservers = nameservers;
242 d->gateway = iface.gateway();
243 d->searches = iface.searches();
244 d->domains = iface.domains();
245 if (NetworkManager::checkVersion(x: 1, y: 2, z: 0)) {
246 d->dnsOptions = iface.dnsOptions();
247 }
248}
249
250NetworkManager::IpConfig::~IpConfig()
251{
252 delete d;
253}
254
255NetworkManager::IpAddresses NetworkManager::IpConfig::addresses() const
256{
257 return d->addresses;
258}
259
260QString NetworkManager::IpConfig::gateway() const
261{
262 return d->gateway;
263}
264
265QList<QHostAddress> NetworkManager::IpConfig::nameservers() const
266{
267 return d->nameservers;
268}
269
270QStringList NetworkManager::IpConfig::domains() const
271{
272 return d->domains;
273}
274
275QList<NetworkManager::IpRoute> NetworkManager::IpConfig::routes() const
276{
277 return d->routes;
278}
279
280QStringList NetworkManager::IpConfig::searches() const
281{
282 return d->searches;
283}
284
285QStringList NetworkManager::IpConfig::dnsOptions() const
286{
287 return d->dnsOptions;
288}
289
290NetworkManager::IpConfig &NetworkManager::IpConfig::operator=(const IpConfig &other)
291{
292 if (this == &other) {
293 return *this;
294 }
295
296 *d = *other.d;
297 return *this;
298}
299
300bool NetworkManager::IpConfig::isValid() const
301{
302 return !d->addresses.isEmpty();
303}
304

source code of networkmanager-qt/src/ipconfig.cpp