File indexing completed on 2025-03-16 12:58:24
0001 /* 0002 SPDX-FileCopyrightText: 2008, 2011 Will Stephenson <wstephenson@kde.org> 0003 SPDX-FileCopyrightText: 2013 Daniel Nicoletti <dantti12@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 0008 #include "ipconfig.h" 0009 0010 #include "manager.h" 0011 #include "manager_p.h" 0012 0013 #include <arpa/inet.h> 0014 0015 #include "dbus/ip4configinterface.h" 0016 #include "dbus/ip6configinterface.h" 0017 0018 namespace NetworkManager 0019 { 0020 class NetworkManager::IpConfig::Private 0021 { 0022 public: 0023 Private(const QList<IpAddress> &theAddresses, const QList<QHostAddress> &theNameservers, const QStringList &theDomains, const QList<IpRoute> &theRoutes) 0024 : addresses(theAddresses) 0025 , nameservers(theNameservers) 0026 , domains(theDomains) 0027 , routes(theRoutes) 0028 { 0029 } 0030 Private() 0031 { 0032 } 0033 IpAddresses addresses; 0034 QString gateway; 0035 QStringList searches; 0036 QList<QHostAddress> nameservers; 0037 QStringList domains; 0038 IpRoutes routes; 0039 QStringList dnsOptions; 0040 }; 0041 0042 } 0043 0044 NetworkManager::IpConfig::IpConfig(const IpAddresses &addresses, const QList<QHostAddress> &nameservers, const QStringList &domains, const IpRoutes &routes) 0045 : d(new Private(addresses, nameservers, domains, routes)) 0046 { 0047 } 0048 0049 NetworkManager::IpConfig::IpConfig() 0050 : d(new Private()) 0051 { 0052 } 0053 0054 NetworkManager::IpConfig::IpConfig(const IpConfig &other) 0055 : d(new Private) 0056 { 0057 *this = other; 0058 } 0059 0060 void NetworkManager::IpConfig::setIPv4Path(const QString &path) 0061 { 0062 OrgFreedesktopNetworkManagerIP4ConfigInterface iface(NetworkManagerPrivate::DBUS_SERVICE, 0063 path, 0064 #ifdef NMQT_STATIC 0065 QDBusConnection::sessionBus()); 0066 #else 0067 QDBusConnection::systemBus()); 0068 #endif 0069 // TODO - watch propertiesChanged signal 0070 0071 QList<NetworkManager::IpAddress> addressObjects; 0072 QList<NetworkManager::IpRoute> routeObjects; 0073 if (NetworkManager::checkVersion(1, 0, 0)) { 0074 const NMVariantMapList addresses = iface.addressData(); 0075 for (const QVariantMap &addressList : addresses) { 0076 if (addressList.contains(QLatin1String("address")) // 0077 && addressList.contains(QLatin1String("prefix"))) { 0078 NetworkManager::IpAddress address; 0079 address.setIp(QHostAddress(addressList.value(QLatin1String("address")).toString())); 0080 address.setPrefixLength(addressList.value(QLatin1String("prefix")).toUInt()); 0081 if (addressList.contains(QLatin1String("gateway"))) { 0082 address.setGateway(QHostAddress(addressList.value(QLatin1String("gateway")).toString())); 0083 } 0084 addressObjects << address; 0085 } 0086 } 0087 0088 const NMVariantMapList routes = iface.routeData(); 0089 for (const QVariantMap &routeList : routes) { 0090 if (routeList.contains(QLatin1String("address")) && routeList.contains(QLatin1String("prefix"))) { 0091 NetworkManager::IpRoute route; 0092 route.setIp(QHostAddress(routeList.value(QLatin1String("address")).toString())); 0093 route.setPrefixLength(routeList.value(QLatin1String("prefix")).toUInt()); 0094 if (routeList.contains(QLatin1String("next-hop"))) { 0095 route.setNextHop(QHostAddress(routeList.value(QLatin1String("next-hop")).toString())); 0096 } 0097 0098 if (routeList.contains(QLatin1String("metric"))) { 0099 route.setMetric(routeList.value(QLatin1String("metric")).toUInt()); 0100 } 0101 routeObjects << route; 0102 } 0103 } 0104 } else { 0105 // convert ipaddresses into object 0106 const UIntListList addresses = iface.addresses(); 0107 for (const UIntList &addressList : addresses) { 0108 if (addressList.count() == 3) { 0109 NetworkManager::IpAddress address; 0110 address.setIp(QHostAddress(ntohl(addressList[0]))); 0111 address.setPrefixLength(addressList[1]); 0112 address.setGateway(QHostAddress(ntohl(addressList[2]))); 0113 addressObjects << address; 0114 } 0115 } 0116 // convert routes into objects 0117 const UIntListList routes = iface.routes(); 0118 for (const UIntList &routeList : routes) { 0119 if (routeList.count() == 4) { 0120 NetworkManager::IpRoute route; 0121 route.setIp(QHostAddress(ntohl(routeList[0]))); 0122 route.setPrefixLength(routeList[1]); 0123 route.setNextHop(QHostAddress(ntohl(routeList[2]))); 0124 route.setMetric(ntohl(routeList[3])); 0125 routeObjects << route; 0126 } 0127 } 0128 } 0129 // nameservers' IP addresses are always in network byte order 0130 QList<QHostAddress> nameservers; 0131 const QList<uint> ifaceNameservers = iface.nameservers(); 0132 for (uint nameserver : ifaceNameservers) { 0133 nameservers << QHostAddress(ntohl(nameserver)); 0134 } 0135 0136 d->addresses = addressObjects; 0137 d->routes = routeObjects; 0138 d->nameservers = nameservers; 0139 d->gateway = iface.gateway(); 0140 d->searches = iface.searches(); 0141 d->domains = iface.domains(); 0142 if (NetworkManager::checkVersion(1, 2, 0)) { 0143 d->dnsOptions = iface.dnsOptions(); 0144 } 0145 } 0146 0147 void NetworkManager::IpConfig::setIPv6Path(const QString &path) 0148 { 0149 // ask the daemon for the details 0150 OrgFreedesktopNetworkManagerIP6ConfigInterface iface(NetworkManagerPrivate::DBUS_SERVICE, 0151 path, 0152 #ifdef NMQT_STATIC 0153 QDBusConnection::sessionBus()); 0154 #else 0155 QDBusConnection::systemBus()); 0156 #endif 0157 // TODO - watch propertiesChanged signal 0158 0159 QList<NetworkManager::IpAddress> addressObjects; 0160 QList<NetworkManager::IpRoute> routeObjects; 0161 if (NetworkManager::checkVersion(1, 0, 0)) { 0162 const NMVariantMapList addresses = iface.addressData(); 0163 for (const QVariantMap &addressList : addresses) { 0164 if (addressList.contains(QLatin1String("address")) // 0165 && addressList.contains(QLatin1String("prefix"))) { 0166 NetworkManager::IpAddress address; 0167 address.setIp(QHostAddress(addressList.value(QLatin1String("address")).toString())); 0168 address.setPrefixLength(addressList.value(QLatin1String("prefix")).toUInt()); 0169 if (addressList.contains(QLatin1String("gateway"))) { 0170 address.setGateway(QHostAddress(addressList.value(QLatin1String("gateway")).toString())); 0171 } 0172 addressObjects << address; 0173 } 0174 } 0175 0176 const NMVariantMapList routes = iface.routeData(); 0177 for (const QVariantMap &routeList : routes) { 0178 if (routeList.contains(QLatin1String("address")) && routeList.contains(QLatin1String("prefix"))) { 0179 NetworkManager::IpRoute route; 0180 route.setIp(QHostAddress(routeList.value(QLatin1String("address")).toString())); 0181 route.setPrefixLength(routeList.value(QLatin1String("prefix")).toUInt()); 0182 if (routeList.contains(QLatin1String("next-hop"))) { 0183 route.setNextHop(QHostAddress(routeList.value(QLatin1String("next-hop")).toString())); 0184 } 0185 0186 if (routeList.contains(QLatin1String("metric"))) { 0187 route.setMetric(routeList.value(QLatin1String("metric")).toUInt()); 0188 } 0189 routeObjects << route; 0190 } 0191 } 0192 } else { 0193 const IpV6DBusAddressList addresses = iface.addresses(); 0194 for (const IpV6DBusAddress &address : addresses) { 0195 Q_IPV6ADDR addr; 0196 Q_IPV6ADDR gateway; 0197 for (int i = 0; i < 16; i++) { 0198 addr[i] = address.address[i]; 0199 } 0200 for (int i = 0; i < 16; i++) { 0201 gateway[i] = address.gateway[i]; 0202 } 0203 NetworkManager::IpAddress addressEntry; 0204 addressEntry.setIp(QHostAddress(addr)); 0205 addressEntry.setPrefixLength(address.prefix); 0206 addressEntry.setGateway(QHostAddress(gateway)); 0207 addressObjects << addressEntry; 0208 } 0209 0210 const IpV6DBusRouteList routes = iface.routes(); 0211 for (const IpV6DBusRoute &route : routes) { 0212 Q_IPV6ADDR dest; 0213 Q_IPV6ADDR nexthop; 0214 for (int i = 0; i < 16; i++) { 0215 dest[i] = route.destination[i]; 0216 } 0217 for (int i = 0; i < 16; i++) { 0218 nexthop[i] = route.nexthop[i]; 0219 } 0220 NetworkManager::IpRoute routeEntry; 0221 routeEntry.setIp(QHostAddress(dest)); 0222 routeEntry.setPrefixLength(route.prefix); 0223 routeEntry.setNextHop(QHostAddress(nexthop)); 0224 routeEntry.setMetric(route.metric); 0225 routeObjects << routeEntry; 0226 } 0227 } 0228 0229 QList<QHostAddress> nameservers; 0230 const QList<QByteArray> ifaceNservers = iface.nameservers(); 0231 for (const QByteArray &nameserver : ifaceNservers) { 0232 Q_IPV6ADDR address; 0233 for (int i = 0; i < 16; i++) { 0234 address[i] = static_cast<quint8>(nameserver[i]); 0235 } 0236 nameservers << QHostAddress(address); 0237 } 0238 0239 d->addresses = addressObjects; 0240 d->routes = routeObjects; 0241 d->nameservers = nameservers; 0242 d->gateway = iface.gateway(); 0243 d->searches = iface.searches(); 0244 d->domains = iface.domains(); 0245 if (NetworkManager::checkVersion(1, 2, 0)) { 0246 d->dnsOptions = iface.dnsOptions(); 0247 } 0248 } 0249 0250 NetworkManager::IpConfig::~IpConfig() 0251 { 0252 delete d; 0253 } 0254 0255 NetworkManager::IpAddresses NetworkManager::IpConfig::addresses() const 0256 { 0257 return d->addresses; 0258 } 0259 0260 QString NetworkManager::IpConfig::gateway() const 0261 { 0262 return d->gateway; 0263 } 0264 0265 QList<QHostAddress> NetworkManager::IpConfig::nameservers() const 0266 { 0267 return d->nameservers; 0268 } 0269 0270 QStringList NetworkManager::IpConfig::domains() const 0271 { 0272 return d->domains; 0273 } 0274 0275 QList<NetworkManager::IpRoute> NetworkManager::IpConfig::routes() const 0276 { 0277 return d->routes; 0278 } 0279 0280 QStringList NetworkManager::IpConfig::searches() const 0281 { 0282 return d->searches; 0283 } 0284 0285 QStringList NetworkManager::IpConfig::dnsOptions() const 0286 { 0287 return d->dnsOptions; 0288 } 0289 0290 NetworkManager::IpConfig &NetworkManager::IpConfig::operator=(const IpConfig &other) 0291 { 0292 if (this == &other) { 0293 return *this; 0294 } 0295 0296 *d = *other.d; 0297 return *this; 0298 } 0299 0300 bool NetworkManager::IpConfig::isValid() const 0301 { 0302 return !d->addresses.isEmpty(); 0303 }