Files
GUI/src/device/networkmanager.cpp

318 lines
9.1 KiB
C++
Raw Normal View History

#include "networkmanager.h"
#include "json/jsonobject.h"
#include <QProcess>
#include <QDebug>
#include <QRegularExpression>
2023-09-20 10:09:57 +08:00
#include <QNetworkSession>
#include <QHostAddress>
#include <QNetworkInterface>
2023-09-20 10:09:57 +08:00
namespace
{
unsigned int ipToUInt(const std::string& ip) {
unsigned int result = 0;
int start = 0;
for (int i = 0; i < 4; ++i) {
int end = ip.find('.', start);
if (end == std::string::npos) end = ip.length();
int octet = stoi(ip.substr(start, end - start));
result = (result << 8) | octet;
start = end + 1;
}
return result;
}
QString cidrFromSubnet(const QString& subnet) {
unsigned int subnetMask = ipToUInt(subnet.toStdString());
int cidr = 0;
while (subnetMask != 0) {
subnetMask = (subnetMask << 1) & 0xFFFFFFFF;
cidr++;
}
return QString::number(cidr);
}
const QString NMCLI_CONNECTION_NAME = "usct";
2023-09-20 10:09:57 +08:00
}
2023-09-20 10:09:57 +08:00
NetworkManager* NetworkManager::getInstance()
{
static NetworkManager instance;
return &instance;
}
2023-09-20 10:09:57 +08:00
NetworkManager::NetworkManager(QObject* aParent)
: QObject(aParent)
, mIsDHCP()
, mIpAddress()
, mSubNetMask()
, mDeviceName()
2023-09-20 10:09:57 +08:00
{
initNetworkInfo();
}
2023-09-20 10:09:57 +08:00
void NetworkManager::initNetworkInfo()
{
mDeviceName = getDeviceName(NMCLI_CONNECTION_NAME);
2023-09-20 10:09:57 +08:00
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
for (const QNetworkInterface &interface : interfaces)
{
if (!(interface.flags() & QNetworkInterface::IsLoopBack))
{
QList<QNetworkAddressEntry> entries = interface.addressEntries();
for (const QNetworkAddressEntry &entry : entries)
{
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
{
mIsDHCP = !entry.isPermanent();
mIpAddress = entry.ip().toString();
mSubNetMask = entry.netmask().toString();
mGateway = JsonObject::Instance()->getDefaultIpAddr().gateway;
2023-09-20 10:09:57 +08:00
return;
}
}
}
}
}
QString NetworkManager::getDeviceName(const QString& aNmcliConName)
{
QProcess process;
process.start("nmcli", {"-t", "-f", "name,device", "connection", "show"});
process.waitForFinished();
QString output = process.readAllStandardOutput();
foreach (const QString &line, output.split('\n'))
{
if (line.contains(aNmcliConName))
{
return line.split(':').last();
}
}
return QString();
}
2021-12-28 18:23:02 +08:00
host NetworkManager::getLocalHost()
{
return JsonObject::Instance()->getServer(JsonObject::LOCAL);
}
2021-12-28 18:23:02 +08:00
bool NetworkManager::setLocalHost(const host& h)
{
JsonObject::Instance()->setServer(JsonObject::LOCAL, h);
return true;
}
QString NetworkManager::interfaceName()
{
return JsonObject::Instance()->interfaceName();
}
bool NetworkManager::isDHCP()
{
2023-09-20 10:09:57 +08:00
return mIsDHCP;
}
IpAddr NetworkManager::getDefaultIpAddr()
{
2024-04-25 14:37:38 +08:00
return IpAddr{mIsDHCP, mIpAddress, mSubNetMask, mGateway};
}
QList<QStringList> NetworkManager::getIpAddrList()
{
return JsonObject::Instance()->getIpAddrList();
}
QString NetworkManager::getDefaultGateway()
{
return JsonObject::Instance()->getDefaultGateway();
}
QList<QStringList> NetworkManager::getIpRouteList()
{
return JsonObject::Instance()->getIpRouteList();
}
2023-09-20 10:09:57 +08:00
bool NetworkManager::setDHCP()
{
2023-09-20 10:09:57 +08:00
QString pwd = JsonObject::Instance()->passWord();
qDebug()<< pwd;
QString dhcpCommand = QString("echo %1 | sudo -S nmcli con mod usct ipv4.method auto ipv4.address \"\" ipv4.gateway \"\"").arg(pwd);
QString networkUpdateCommand = QString("echo %1 | sudo -S nmcli con up usct").arg(pwd);
QProcess settingProcess;
settingProcess.start("/bin/bash" , QStringList() << "-c" << dhcpCommand);
settingProcess.waitForFinished();
if (settingProcess.exitStatus() != QProcess::NormalExit || settingProcess.exitCode() != 0)
{
return false;
}
QProcess restartProcess;
restartProcess.start("/bin/bash", QStringList() << "-c" << networkUpdateCommand);
restartProcess.waitForFinished();
if (restartProcess.exitStatus() != QProcess::NormalExit && restartProcess.exitCode() != 0)
{
return false;
}
mIsDHCP = true;
JsonObject::Instance()->autoDHCP(true);
return true;
}
2024-05-08 15:20:28 +08:00
bool NetworkManager::setIpAddr(const IpAddr& addr, QString& err_info)
{
2023-09-20 10:09:57 +08:00
QString pwd = JsonObject::Instance()->passWord();
QString ipaddr = NewExp(addr.ip, addr.mask);
2023-09-20 10:09:57 +08:00
QProcess settingProcess;
2024-05-08 15:20:28 +08:00
QString setIpCommand = QString("echo %1 | sudo -S nmcli con mod usct ipv4.method manual ipv4.address %2 ipv4.gateway %3").arg(pwd).arg(ipaddr).arg(addr.gateway);
QStringList args;
2023-09-20 10:09:57 +08:00
args << "-c" << setIpCommand;
settingProcess.start("/bin/sh", args);
settingProcess.waitForFinished();
if (settingProcess.exitStatus() != QProcess::NormalExit || settingProcess.exitCode() != 0)
{
return false;
}
QString networkUpdateCommand = QString("echo %1 | sudo -S nmcli con up usct").arg(pwd);
QProcess restartProcess;
restartProcess.start("/bin/bash", QStringList() << "-c" << networkUpdateCommand);
restartProcess.waitForFinished();
if (restartProcess.exitStatus() != QProcess::NormalExit && restartProcess.exitCode() != 0)
{
return false;
}
JsonObject::Instance()->setDefaultIpAddr(addr);
JsonObject::Instance()->autoDHCP(false);
return true;
}
bool NetworkManager::validate(const QString& addr)
{
QRegularExpression ipFormat("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
QRegularExpressionMatch mre = ipFormat.match(addr);
if (mre.hasMatch())
{
return true;
}
return false;
}
QString NetworkManager::NewExp(QString ip, QString mask)
{
QString temp = "";
2023-09-20 10:09:57 +08:00
temp.append(ip).append("/").append(cidrFromSubnet(mask));
return temp;
}
bool NetworkManager::setIpAddrList(const QList<QStringList>& list, QString& err_info)
{
QProcess* myProcess = new QProcess;
QString inface = JsonObject::Instance()->interfaceName();
QString pwd = JsonObject::Instance()->passWord();
QString cmd = QString("echo %1 | ").arg(pwd);
for (QStringList addr : list)
{
QString ipaddr = NewExp(addr[0], addr[1]);
cmd.append(QString("sudo -S ip addr add %1 dev %2;").arg(ipaddr).arg(inface));
}
QStringList args;
args << "-c" << cmd;
connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
myProcess->start("/bin/sh", args);
if (!myProcess->waitForFinished()) {
err_info.append("failed...\n");
return false;
}
if (myProcess->exitCode() == 0) {
JsonObject::Instance()->setIpAddrList(list);
err_info.append("success...\n");
return true;
}
else {
err_info.append(myProcess->readAllStandardError());
return false;
}
}
bool NetworkManager::setDefaultGateway(const QString& gw, QString& err_info)
{
QProcess* myProcess = new QProcess;
QString pwd = JsonObject::Instance()->passWord();
QString cmd = QString("echo %1 | sudo -S ip route replace default via %2").arg(pwd).arg(gw);
QStringList args;
args << "-c" << cmd;
connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
//qDebug()<<args;
myProcess->start("/bin/sh", args);
if (!myProcess->waitForFinished()) {
err_info.append("failed...\n");
return false;
}
if (myProcess->exitCode() == 0) {
JsonObject::Instance()->setDefaultGateway(gw);
err_info.append("success...\n");
return true;
}
else {
err_info.append(myProcess->readAllStandardError());
return false;
}
}
2021-12-28 18:23:02 +08:00
bool NetworkManager::checkPassWord(const QString& pwd, QString& err_info)
2021-12-28 10:43:59 +08:00
{
QProcess* myProcess = new QProcess;
2021-12-28 18:23:02 +08:00
//QString pwd = JsonObject::Instance()->passWord();
QString cmd = QString("echo %1 | sudo -S -k whoami").arg(pwd);
2021-12-28 10:43:59 +08:00
QStringList args;
args << "-c" << cmd;
connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
//qDebug()<<args;
myProcess->start("/bin/sh", args);
if (!myProcess->waitForFinished()) {
err_info.append("failed...\n");
return false;
}
if (myProcess->exitCode() == 0) {
err_info.append("success...\n");
return true;
}
else {
err_info.append(myProcess->readAllStandardError());
return false;
}
}
bool NetworkManager::setIpRouteList(const QList<QStringList>& list, QString& err_info)
{
QProcess* myProcess = new QProcess;
QString inface = JsonObject::Instance()->interfaceName();
QString pwd = JsonObject::Instance()->passWord();
QString cmd = QString("echo %1 | ").arg(pwd);
for (QStringList route : list)
{
QString ipaddr = NewExp(route[0], route[1]);
cmd.append(QString("sudo -S ip route replace %1 via %2 dev %3;").arg(ipaddr).arg(route[2]).arg(inface));
}
QStringList args;
args << "-c" << cmd;
connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
myProcess->start("/bin/sh", args);
if (!myProcess->waitForFinished()) {
err_info.append("failed...\n");
return false;
}
if (myProcess->exitCode() == 0) {
JsonObject::Instance()->setIpRouteList(list);
err_info.append("success...\n");
return true;
}
else {
err_info.append(cmd);
err_info.append("\n");
err_info.append(myProcess->readAllStandardError());
return false;
}
}