204 lines
6 KiB
C++
204 lines
6 KiB
C++
#include "router.h"
|
|
|
|
#ifdef Q_OS_WIN
|
|
#include "router_win.h"
|
|
#elif defined(Q_OS_MAC)
|
|
#include "router_mac.h"
|
|
#elif defined Q_OS_LINUX
|
|
#include "router_linux.h"
|
|
#endif
|
|
|
|
#ifdef Q_OS_WIN
|
|
#include <QNetworkInterface>
|
|
#include "windowsfirewall.h"
|
|
#include <cstring>
|
|
|
|
namespace
|
|
{
|
|
// TODO:FIXME try to get this constexpr variable from CORE code
|
|
constexpr char IKEV2[]{"AmneziaVPN IKEv2"};
|
|
constexpr char WG[]{"AmneziaVPN.WireGuard0"};
|
|
constexpr char OVPN[]{"TAP-Windows Adapter V9"};
|
|
|
|
bool is_eth_adapter_activated(char* ethName)
|
|
{
|
|
auto convert_wide_to_ansi = [](const std::wstring& widestring)->std::string{
|
|
auto nchars = WideCharToMultiByte(
|
|
CP_ACP,
|
|
0,
|
|
widestring.c_str(),
|
|
static_cast<int>(widestring.length() + 1),
|
|
nullptr,
|
|
0,
|
|
nullptr,
|
|
nullptr);
|
|
std::string converted_string{};
|
|
converted_string.resize(nchars);
|
|
WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
widestring.c_str(),
|
|
-1,
|
|
&converted_string[0],
|
|
static_cast<int>(widestring.length()),
|
|
nullptr,
|
|
nullptr);
|
|
return converted_string;
|
|
};
|
|
|
|
constexpr ULONG MAX_BUFFER_SIZE = 15000;
|
|
ULONG bufferSize = MAX_BUFFER_SIZE;
|
|
IP_ADAPTER_ADDRESSES *pAdapterAddresses = (IP_ADAPTER_ADDRESSES *)HeapAlloc(GetProcessHeap(), 0, bufferSize);
|
|
::GetAdaptersAddresses(AF_INET, 0, nullptr, pAdapterAddresses, &bufferSize);
|
|
do
|
|
{
|
|
const auto Descr = convert_wide_to_ansi(pAdapterAddresses->Description);
|
|
if (strcmp(ethName, Descr.data()) == 0) //the same
|
|
{
|
|
if (pAdapterAddresses->OperStatus == IfOperStatusUp){
|
|
return true;
|
|
}
|
|
}
|
|
if (pAdapterAddresses->Next != 0)
|
|
{
|
|
pAdapterAddresses = pAdapterAddresses->Next;
|
|
}
|
|
} while (pAdapterAddresses->Next != 0);
|
|
//::HeapFree(GetProcessHeap(), 0, pAdapterAddresses);
|
|
return false;
|
|
}
|
|
|
|
bool get_eth_name(const QString &adp_name)
|
|
{
|
|
IP_ADAPTER_INFO *pAdapterInfo{nullptr};
|
|
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
|
|
ULONG buflen = sizeof(IP_ADAPTER_INFO);
|
|
if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
|
|
{
|
|
free(pAdapterInfo);
|
|
pAdapterInfo = (IP_ADAPTER_INFO *)
|
|
malloc(buflen);
|
|
}
|
|
if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR)
|
|
{
|
|
IP_ADAPTER_INFO *pAdapter{pAdapterInfo};
|
|
if (pAdapter == nullptr)
|
|
return false;
|
|
while (pAdapter != nullptr)
|
|
{
|
|
const auto adp_acitvated = is_eth_adapter_activated(pAdapter->Description);
|
|
if (adp_name == pAdapter->Description && adp_acitvated){
|
|
qDebug() << "We will work with:";
|
|
qDebug() << "Adapter Name: " << pAdapter->AdapterName;
|
|
qDebug() << "Adapter Desc: " << pAdapter->Description;
|
|
qDebug() << "Adapter Index: " << pAdapter->Index;
|
|
qDebug() << "Adapter activated:"<<adp_acitvated;
|
|
free(pAdapterInfo);
|
|
return true;
|
|
}
|
|
pAdapter = pAdapter->Next;
|
|
}
|
|
}
|
|
free(pAdapterInfo);
|
|
return false;
|
|
}
|
|
|
|
void enable_killswitch()
|
|
{
|
|
auto VPN_LIST = []() -> int
|
|
{
|
|
const auto adapterList = QNetworkInterface::allInterfaces();
|
|
//qAsConst
|
|
for (const auto &adapter : adapterList)
|
|
{
|
|
bool finded{false};
|
|
finded = get_eth_name(OVPN);
|
|
if (adapter.humanReadableName().contains(IKEV2) ||
|
|
adapter.humanReadableName().contains(WG) ||
|
|
finded ||
|
|
adapter.humanReadableName().contains(OVPN))
|
|
{
|
|
qDebug() << "Network adapter for 'kill switch' option finded: " << adapter.humanReadableName();
|
|
return adapter.index();
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
const auto ¤t_vpn = VPN_LIST();
|
|
if (current_vpn != -1)
|
|
{
|
|
qInfo() << "KillSwitch option activated";
|
|
auto cf = WindowsFirewall::instance();
|
|
cf->enableKillSwitch(current_vpn);
|
|
}
|
|
else
|
|
{
|
|
// TODO::FIXME
|
|
qCritical().noquote() << "No any adapters was found, it's error";
|
|
}
|
|
}
|
|
} // end namespace
|
|
#endif
|
|
|
|
// TODO::FIXME when wireguard is activated, the adapter will alaviable
|
|
// after a couple of seconds
|
|
#include <thread>
|
|
|
|
int Router::routeAddList(const QString &gw, const QStringList &ips)
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
auto value = RouterWin::Instance().routeAddList(gw, ips);
|
|
// TODO::FIXME the next sleep is need only for wireguard
|
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
|
enable_killswitch();
|
|
return value;
|
|
// return RouterWin::Instance().routeAddList(gw, ips);
|
|
#elif defined(Q_OS_MAC)
|
|
return RouterMac::Instance().routeAddList(gw, ips);
|
|
#elif defined Q_OS_LINUX
|
|
return RouterLinux::Instance().routeAddList(gw, ips);
|
|
#endif
|
|
}
|
|
|
|
bool Router::clearSavedRoutes()
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
return RouterWin::Instance().clearSavedRoutes();
|
|
#elif defined(Q_OS_MAC)
|
|
return RouterMac::Instance().clearSavedRoutes();
|
|
#elif defined Q_OS_LINUX
|
|
return RouterLinux::Instance().clearSavedRoutes();
|
|
#endif
|
|
}
|
|
|
|
int Router::routeDeleteList(const QString &gw, const QStringList &ips)
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
return RouterWin::Instance().routeDeleteList(gw, ips);
|
|
#elif defined(Q_OS_MAC)
|
|
return RouterMac::Instance().routeDeleteList(gw, ips);
|
|
#elif defined Q_OS_LINUX
|
|
return RouterLinux::Instance().routeDeleteList(gw, ips);
|
|
#endif
|
|
}
|
|
|
|
void Router::flushDns()
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
RouterWin::Instance().flushDns();
|
|
#elif defined(Q_OS_MAC)
|
|
RouterMac::Instance().flushDns();
|
|
#elif defined Q_OS_LINUX
|
|
RouterLinux::Instance().flushDns();
|
|
#endif
|
|
}
|
|
|
|
void Router::resetIpStack()
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
RouterWin::Instance().resetIpStack();
|
|
#elif defined(Q_OS_MAC)
|
|
// todo fixme
|
|
#elif defined Q_OS_LINUX
|
|
// todo fixme
|
|
#endif
|
|
}
|