Compare commits

5 Commits

Author SHA1 Message Date
e101f5ddd6 Merge branch 'beta' - Version 1.0.0 2026-01-01 17:21:28 +01:00
e1118ccafe Merge branch 'dev' into beta 2026-01-01 17:21:15 +01:00
ccbacd1180 interface on win32 - v1 2026-01-01 17:15:58 +01:00
cf3ec30492 interface on win32 - v1 2026-01-01 17:11:02 +01:00
1d34953f25 interface on win32 - v1 2026-01-01 17:08:35 +01:00
2 changed files with 60 additions and 29 deletions

View File

@@ -36,6 +36,12 @@
#include <locale> #include <locale>
#include <codecvt> #include <codecvt>
#include <wintun/wintun.h> #include <wintun/wintun.h>
#include <iphlpapi.h>
#include <netioapi.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
#endif #endif
namespace ColumnLynx::Net { namespace ColumnLynx::Net {

View File

@@ -433,41 +433,66 @@ namespace ColumnLynx::Net {
uint16_t mtu) uint16_t mtu)
{ {
#ifdef _WIN32 #ifdef _WIN32
std::string ip = ipv4ToString(clientIP); // Interface alias → LUID → Index
std::string gw = ipv4ToString(serverIP); std::wstring ifAlias(mIfName.begin(), mIfName.end());
std::string mask;
// Convert prefixLen → subnet mask NET_LUID luid;
uint32_t maskInt = (prefixLen == 0) ? 0 : (0xFFFFFFFF << (32 - prefixLen)); if (ConvertInterfaceAliasToLuid(ifAlias.c_str(), &luid) != NO_ERROR)
mask = ipv4ToString(maskInt); return false;
// Calculate network address from IP and mask NET_IFINDEX ifIndex;
uint32_t networkInt = (clientIP & maskInt); if (ConvertInterfaceLuidToIndex(&luid, &ifIndex) != NO_ERROR)
std::string network = ipv4ToString(networkInt); return false;
char cmd[512]; // ssign IPv4 address + prefix
MIB_UNICASTIPADDRESS_ROW addr;
InitializeUnicastIpAddressEntry(&addr);
// 1. Set the static IP + mask + gateway addr.InterfaceIndex = ifIndex;
snprintf(cmd, sizeof(cmd), addr.Address.si_family = AF_INET;
"netsh interface ip set address name=\"%s\" static %s %s %s", addr.Address.Ipv4.sin_addr.s_addr = htonl(clientIP);
mIfName.c_str(), ip.c_str(), mask.c_str(), gw.c_str() addr.OnLinkPrefixLength = prefixLen;
); addr.DadState = IpDadStatePreferred;
system(cmd);
// 2. Set MTU (separate command) if (CreateUnicastIpAddressEntry(&addr) != NO_ERROR)
snprintf(cmd, sizeof(cmd), return false;
"netsh interface ipv4 set subinterface \"%s\" mtu=%u store=persistent",
mIfName.c_str(), mtu
);
system(cmd);
// 3. Add route for the VPN network to go through the TUN interface // Set MTU
// This is critical: tells Windows to send packets destined for the server/network through the TUN interface MIB_IFROW ifRow;
snprintf(cmd, sizeof(cmd), ifRow.dwIndex = ifIndex;
"netsh routing ip add persistentroute dest=%s/%d name=\"%s\" nexthopcfg=%s",
network.c_str(), prefixLen, mIfName.c_str(), gw.c_str() if (GetIfEntry(&ifRow) != NO_ERROR)
); return false;
system(cmd);
ifRow.dwMtu = mtu;
if (SetIfEntry(&ifRow) != NO_ERROR)
return false;
// Add persistent route for VPN network via this interface
uint32_t mask =
(prefixLen == 0) ? 0 : (0xFFFFFFFFu << (32 - prefixLen));
uint32_t network = clientIP & mask;
MIB_IPFORWARD_ROW2 route;
InitializeIpForwardEntry(&route);
route.InterfaceIndex = ifIndex;
route.DestinationPrefix.Prefix.si_family = AF_INET;
route.DestinationPrefix.Prefix.Ipv4.sin_addr.s_addr = htonl(network);
route.DestinationPrefix.PrefixLength = prefixLen;
route.NextHop.si_family = AF_INET;
route.NextHop.Ipv4.sin_addr.s_addr = 0;
route.Metric = 1;
route.Protocol = static_cast<NL_ROUTE_PROTOCOL>(MIB_IPPROTO_NETMGMT);
route.ValidLifetime = 0xFFFFFFFF;
route.PreferredLifetime = 0xFFFFFFFF;
DWORD r = CreateIpForwardEntry2(&route);
if (r != NO_ERROR && r != ERROR_OBJECT_ALREADY_EXISTS)
return false;
return true; return true;
#else #else