|  |  | @@ -37,19 +37,33 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | const DEVPROPKEY devpkey_name = { { 0x65726957, 0x7547, 0x7261, { 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79 } }, DEVPROPID_FIRST_USABLE + 1 }; |  |  |  | const DEVPROPKEY devpkey_name = { { 0x65726957, 0x7547, 0x7261, { 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79 } }, DEVPROPID_FIRST_USABLE + 1 }; | 
			
		
	
		
		
			
				
					
					|  |  |  | #define IFNAMSIZ MAX_ADAPTER_NAME - 1 |  |  |  | #define IFNAMSIZ MAX_ADAPTER_NAME - 1 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Create Wireguard adapter | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_CREATE_ADAPTER_FUNC *WireGuardCreateAdapter; |  |  |  | static WIREGUARD_CREATE_ADAPTER_FUNC *WireGuardCreateAdapter; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Open Wireguard adapter by name if exists | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_OPEN_ADAPTER_FUNC *WireGuardOpenAdapter; |  |  |  | static WIREGUARD_OPEN_ADAPTER_FUNC *WireGuardOpenAdapter; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Close Wireguard adapter | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_CLOSE_ADAPTER_FUNC *WireGuardCloseAdapter; |  |  |  | static WIREGUARD_CLOSE_ADAPTER_FUNC *WireGuardCloseAdapter; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Get Wireguard adapter LUID | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_GET_ADAPTER_LUID_FUNC *WireGuardGetAdapterLUID; |  |  |  | static WIREGUARD_GET_ADAPTER_LUID_FUNC *WireGuardGetAdapterLUID; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Get running Wireguard driver version | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_GET_RUNNING_DRIVER_VERSION_FUNC *WireGuardGetRunningDriverVersion; |  |  |  | static WIREGUARD_GET_RUNNING_DRIVER_VERSION_FUNC *WireGuardGetRunningDriverVersion; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Delete Wireguard driver if non exists adapters | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_DELETE_DRIVER_FUNC *WireGuardDeleteDriver; |  |  |  | static WIREGUARD_DELETE_DRIVER_FUNC *WireGuardDeleteDriver; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Set logger for Wireguard adapter | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_SET_LOGGER_FUNC *WireGuardSetLogger; |  |  |  | static WIREGUARD_SET_LOGGER_FUNC *WireGuardSetLogger; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Set adapter logging for Wireguard adapter | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_SET_ADAPTER_LOGGING_FUNC *WireGuardSetAdapterLogging; |  |  |  | static WIREGUARD_SET_ADAPTER_LOGGING_FUNC *WireGuardSetAdapterLogging; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Get adapter state for Wireguard adapter | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_GET_ADAPTER_STATE_FUNC *WireGuardGetAdapterState; |  |  |  | static WIREGUARD_GET_ADAPTER_STATE_FUNC *WireGuardGetAdapterState; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Set adapter state for Wireguard adapter | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_SET_ADAPTER_STATE_FUNC *WireGuardSetAdapterState; |  |  |  | static WIREGUARD_SET_ADAPTER_STATE_FUNC *WireGuardSetAdapterState; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Get Wireguard adapter configuration | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_GET_CONFIGURATION_FUNC *WireGuardGetConfiguration; |  |  |  | static WIREGUARD_GET_CONFIGURATION_FUNC *WireGuardGetConfiguration; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Set Wireguard adapter configuration | 
			
		
	
		
		
			
				
					
					|  |  |  | static WIREGUARD_SET_CONFIGURATION_FUNC *WireGuardSetConfiguration; |  |  |  | static WIREGUARD_SET_CONFIGURATION_FUNC *WireGuardSetConfiguration; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | LPCWSTR WireguardAddonDescription = WireguardAddonDescription; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // Function to check if the current user has administrator privileges |  |  |  | // Function to check if the current user has administrator privileges | 
			
		
	
		
		
			
				
					
					|  |  |  | bool IsRunAsAdmin() { |  |  |  | bool IsRunAsAdmin() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   BOOL fRet = FALSE; |  |  |  |   BOOL fRet = FALSE; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -92,90 +106,6 @@ std::string parseEndpoint(SOCKADDR_INET *input) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   return std::string(saddr).append(":").append(std::to_string(htons(input->Ipv4.sin_port))); |  |  |  |   return std::string(saddr).append(":").append(std::to_string(htons(input->Ipv4.sin_port))); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | int parse_dns_retries() { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   unsigned long ret; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   char *retries = getenv("WG_ENDPOINT_RESOLUTION_RETRIES"), *end; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!retries) return 15; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!strcmp(retries, "infinity")) return -1; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   ret = strtoul(retries, &end, 10); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (*end || ret > INT_MAX) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     fprintf(stderr, "Unable to parse WG_ENDPOINT_RESOLUTION_RETRIES: `%s'\n", retries); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     exit(1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   return (int)ret; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void insertEndpoint(SOCKADDR_INET *endpoint, std::string value) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int ret, retries = parse_dns_retries(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *begin, *end; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   auto mmutable = strdup(value.c_str()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!mmutable) throw std::string("strdup"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!value.size()) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     free(mmutable); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     throw std::string("Unable to parse empty endpoint"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (mmutable[0] == '[') { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		begin = &mmutable[1]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		end = strchr(mmutable, ']'); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (!end) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       free(mmutable); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       throw std::string("Unable to find matching brace of endpoint: ").append(value); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		*end++ = '\0'; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (*end++ != ':' || !*end) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       free(mmutable); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       throw std::string("Unable to find port of endpoint: ").append(value); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		begin = mmutable; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		end = strrchr(mmutable, ':'); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (!end || !*(end + 1)) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       free(mmutable); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       throw std::string("Unable to find port of endpoint: ").append(value); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		*end++ = '\0'; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	ADDRINFOA *resolved; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	// #define min(a, b) ((a) < (b) ? (a) : (b)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	for (unsigned int timeout = 1000000;; timeout = ((20000000) < (timeout * 6 / 5) ? (20000000) : (timeout * 6 / 5))) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// ret = getaddrinfo(begin, end, &hints, &resolved); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ret = getaddrinfo(begin, end, NULL, &resolved); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (!ret) break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		/* The set of return codes that are "permanent failures". All other possibilities are potentially transient. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 * This is according to https://sourceware.org/glibc/wiki/NameResolver which states: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 *	"From the perspective of the application that calls getaddrinfo() it perhaps |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 *	 doesn't matter that much since EAI_FAIL, EAI_NONAME and EAI_NODATA are all |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 *	 permanent failure codes and the causes are all permanent failures in the |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 *	 sense that there is no point in retrying later." |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 * So this is what we do, except FreeBSD removed EAI_NODATA some time ago, so that's conditional. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		 */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (ret == EAI_NONAME || ret == EAI_FAIL || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			#ifdef EAI_NODATA |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				ret == EAI_NODATA || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			#endif |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				(retries >= 0 && !retries--)) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			free(mmutable); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			throw std::string("Error code: ").append(std::to_string(ret)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     std::this_thread::sleep_for(std::chrono::microseconds(timeout)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(SOCKADDR_IN))) memcpy(&endpoint->Ipv4, resolved->ai_addr, resolved->ai_addrlen); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   else if (resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(SOCKADDR_IN6)) memcpy(&endpoint->Ipv6, resolved->ai_addr, resolved->ai_addrlen); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		freeaddrinfo(resolved); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		throw std::string("Neither IPv4 nor IPv6 address found: ").append(value); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	freeaddrinfo(resolved); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   free(mmutable); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | std::string getErrorString(DWORD errorMessageID) { |  |  |  | std::string getErrorString(DWORD errorMessageID) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (errorMessageID == 0 || errorMessageID < 0) std::string("Error code: ").append(std::to_string(errorMessageID)); |  |  |  |   if (errorMessageID == 0 || errorMessageID < 0) std::string("Error code: ").append(std::to_string(errorMessageID)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   LPSTR messageBuffer = nullptr; |  |  |  |   LPSTR messageBuffer = nullptr; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -211,7 +141,9 @@ std::string driveLoad(std::map<std::string, std::string> load)  { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | std::string getWireguardVersion() { |  |  |  | std::string getWireguardVersion() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardCreateAdapter(L"getWgVersion", L"Wireguard-tools.js", NULL); |  |  |  |   // Create interface to get version | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardCreateAdapter(L"getWgVersion", WireguardAddonDescription, NULL); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   WireGuardCloseAdapter(Adapter); | 
			
		
	
		
		
			
				
					
					|  |  |  |   DWORD Version = WireGuardGetRunningDriverVersion(); |  |  |  |   DWORD Version = WireGuardGetRunningDriverVersion(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (Version == 0) { |  |  |  |   if (Version == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     auto statusErr = GetLastError(); |  |  |  |     auto statusErr = GetLastError(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -219,49 +151,25 @@ std::string getWireguardVersion() { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (statusErr == ERROR_FILE_NOT_FOUND) return "Driver not loaded"; |  |  |  |     if (statusErr == ERROR_FILE_NOT_FOUND) return "Driver not loaded"; | 
			
		
	
		
		
			
				
					
					|  |  |  |     return std::string("Cannot get version drive, ").append(getErrorString(GetLastError())); |  |  |  |     return std::string("Cannot get version drive, ").append(getErrorString(GetLastError())); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |   WireGuardCloseAdapter(Adapter); |  |  |  |   return std::string("WireGuardNT v").append(std::to_string((Version >> 16) & 0xff)).append(".").append(std::to_string((Version >> 0) & 0xff)).append(".").append(std::to_string((Version >> 8) & 0xff)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   return std::string("WireGuardNT v").append(std::to_string((Version >> 16) & 0xff)).append(".").append(std::to_string((Version >> 0) & 0xff)); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void WireguardDevices::getInterfaces() { |  |  |  | void WireguardDevices::getInterfaces() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   // std::vector<std::string> arrayPrefix; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // arrayPrefix.push_back("ProtectedPrefix\\Administrators\\WireGuard\\"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // arrayPrefix.push_back("WireGuard\\"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // WIN32_FIND_DATA find_data; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // HANDLE find_handle; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // for (auto &preit : arrayPrefix) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   int ret = 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   find_handle = FindFirstFile("\\\\.\\pipe\\*", &find_data); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   if (find_handle == INVALID_HANDLE_VALUE) continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   char *iface; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   do { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //     if (strncmp(preit.c_str(), find_data.cFileName, strlen(preit.c_str()))) continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //     iface = find_data.cFileName + strlen(preit.c_str()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //     this->push_back(std::string("\\\\.\\pipe\\").append(preit).append(iface)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   } while (FindNextFile(find_handle, &find_data)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   FindClose(find_handle); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //   if (ret < 0) throw std::string("Erro code: ").append(std::to_string(ret)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL); |  |  |  |   HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (dev_info == INVALID_HANDLE_VALUE) throw ("Cannot get devices"); |  |  |  |   if (dev_info == INVALID_HANDLE_VALUE) throw std::string("Cannot get devices"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   for (DWORD devIndex = 0;; ++devIndex) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   for (DWORD i = 0;; ++i) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DWORD buf_len; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     WCHAR adapter_name[MAX_ADAPTER_NAME]; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     SP_DEVINFO_DATA dev_info_data; |  |  |  |     SP_DEVINFO_DATA dev_info_data; | 
			
		
	
		
		
			
				
					
					|  |  |  |     dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); |  |  |  |     dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEVPROPTYPE prop_type; |  |  |  |     if (!SetupDiEnumDeviceInfo(dev_info, devIndex, &dev_info_data)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     ULONG status, problem_code; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     char *interface_name; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data)) { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       if (GetLastError() == ERROR_NO_MORE_ITEMS) break; |  |  |  |       if (GetLastError() == ERROR_NO_MORE_ITEMS) break; | 
			
		
	
		
		
			
				
					
					|  |  |  |       continue; |  |  |  |       continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     DWORD buf_len; ULONG status, problem_code; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     WCHAR adapter_name[MAX_ADAPTER_NAME]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     char *interface_name; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     DEVPROPTYPE prop_type; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name, &prop_type, (PBYTE)adapter_name, sizeof(adapter_name), NULL, 0) || prop_type != DEVPROP_TYPE_STRING) continue; |  |  |  |     if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name, &prop_type, (PBYTE)adapter_name, sizeof(adapter_name), NULL, 0) || prop_type != DEVPROP_TYPE_STRING) continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |     adapter_name[_countof(adapter_name) - 1] = L'0'; |  |  |  |     adapter_name[_countof(adapter_name) - 1] = L'0'; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!adapter_name[0]) continue; |  |  |  |     if (!adapter_name[0]) continue; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -281,28 +189,31 @@ void WireguardDevices::getInterfaces() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   SetupDiDestroyDeviceInfoList(dev_info); |  |  |  |   SetupDiDestroyDeviceInfoList(dev_info); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   Delete wireguard interface | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   Current bug from Addon: Set interface down and not delete wireguard interface | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | */ | 
			
		
	
		
		
			
				
					
					|  |  |  | void WireguardDevices::deleteInterface(std::string wgName) { |  |  |  | void WireguardDevices::deleteInterface(std::string wgName) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(wgName)); |  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(wgName)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!Adapter) throw std::string("This interface not exists in Wireguard-Tools.js addon!"); |  |  |  |   if (!Adapter) throw std::string("This interface not exists in Wireguard-Tools.js addon!"); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!(WireGuardSetAdapterState(Adapter, WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_DOWN))) throw std::string(std::string("Failed to set down interface, ").append(getErrorString(GetLastError()))); |  |  |  |   if (!(WireGuardSetAdapterState(Adapter, WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_DOWN))) throw std::string("Failed to set down interface, ").append(getErrorString(GetLastError())); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   WireGuardCloseAdapter(Adapter); |  |  |  |   WireGuardCloseAdapter(Adapter); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /** |  |  |  | /** | 
			
		
	
		
		
			
				
					
					|  |  |  |  * Change point from calloc or malloc |  |  |  |  * Change point from calloc or malloc, T: from, C: to | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |  * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  * T: to |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  * C: From |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | template <typename T, typename C> C* changePoint(T *x) { |  |  |  | template <typename T, typename C> C* changePoint(T *x) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   // reinterpret_cast<WIREGUARD_ALLOWED_IP*>(((char*)x) + sizeof(WIREGUARD_PEER)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // std::cout << "Sizeof: " << sizeof(C) << ", " << typeid(T).name() << " -> " << typeid(C).name() << std::endl; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   return reinterpret_cast<C*>(((char*)x) + sizeof(T)); |  |  |  |   return reinterpret_cast<C*>(((char*)x) + sizeof(T)); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void WireguardConfig::getWireguardConfig() { |  |  |  | void WireguardConfig::getWireguardConfig() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (this->name.length() == 0) throw std::string("Require interface name!"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   else if (!(WireguardDevices().exist(this->name))) throw std::string("This interface not exists in Wireguard-Tools.js addon!"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(this->name)); |  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(this->name)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!Adapter) throw ("This interface not exists in Wireguard-Tools.js addon!"); |  |  |  |   if (!Adapter) throw std::string("This interface not exists in Wireguard-Tools.js addon!"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   NET_LUID InterfaceLuid; |  |  |  |   NET_LUID InterfaceLuid; | 
			
		
	
		
		
			
				
					
					|  |  |  |   WireGuardGetAdapterLUID(Adapter, &InterfaceLuid); |  |  |  |   WireGuardGetAdapterLUID(Adapter, &InterfaceLuid); | 
			
		
	
		
		
			
				
					
					|  |  |  |   this->interfaceAddress.GetInInterface(this->name); |  |  |  |   this->interfaceAddress.GetInInterface(this->name); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -312,28 +223,27 @@ void WireguardConfig::getWireguardConfig() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   while (!(WireGuardGetConfiguration(Adapter, wg_iface, &buf_len))) { |  |  |  |   while (!(WireGuardGetConfiguration(Adapter, wg_iface, &buf_len))) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     free(wg_iface); |  |  |  |     free(wg_iface); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (GetLastError() != ERROR_MORE_DATA) throw ((std::string("Failed get interface config, code: ")).append(std::to_string(GetLastError()))); |  |  |  |     if (GetLastError() != ERROR_MORE_DATA) throw std::string("Failed get interface config, code: ").append(std::to_string(GetLastError())); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     wg_iface = (WIREGUARD_INTERFACE *)malloc(buf_len); |  |  |  |     wg_iface = (WIREGUARD_INTERFACE *)malloc(buf_len); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!wg_iface) throw std::string("Failed get interface config, ").append(std::to_string(-errno)); |  |  |  |     if (!wg_iface) throw std::string("Failed get interface config, ").append(std::to_string(-errno)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY) privateKey = wgKeys::toString(wg_iface->PrivateKey); |  |  |  |   if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY) this->privateKey = wgKeys::toString(wg_iface->PrivateKey); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PUBLIC_KEY) publicKey = wgKeys::toString(wg_iface->PublicKey); |  |  |  |   if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PUBLIC_KEY) this->publicKey = wgKeys::toString(wg_iface->PublicKey); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   portListen = 0; |  |  |  |   if (wg_iface->ListenPort > 0) this->portListen = wg_iface->ListenPort; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_LISTEN_PORT) portListen = wg_iface->ListenPort; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_PEER *wg_peer = changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface); |  |  |  |   WIREGUARD_PEER *wg_peer = changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface); | 
			
		
	
		
		
			
				
					
					|  |  |  |   for (DWORD i = 0; i < wg_iface->PeersCount; i++) { |  |  |  |   for (DWORD i = 0; i < wg_iface->PeersCount; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     auto pubKey = wgKeys::toString(wg_peer->PublicKey); |  |  |  |     auto pubKey = wgKeys::toString(wg_peer->PublicKey); | 
			
		
	
		
		
			
				
					
					|  |  |  |     Peer peerConfig; |  |  |  |     Peer peerConfig; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     peerConfig.txBytes = wg_peer->TxBytes; |  |  |  |     peerConfig.txBytes = wg_peer->TxBytes; | 
			
		
	
		
		
			
				
					
					|  |  |  |     peerConfig.rxBytes = wg_peer->RxBytes; |  |  |  |     peerConfig.rxBytes = wg_peer->RxBytes; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     peerConfig.lastHandshake = (wg_peer->LastHandshake - 116444736000000000LL) / (100 / 1000); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PRESHARED_KEY) peerConfig.presharedKey = wgKeys::toString(wg_peer->PresharedKey); |  |  |  |     if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PRESHARED_KEY) peerConfig.presharedKey = wgKeys::toString(wg_peer->PresharedKey); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT) peerConfig.endpoint = parseEndpoint(&wg_peer->Endpoint); |  |  |  |     if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT) peerConfig.endpoint = parseEndpoint(&wg_peer->Endpoint); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE) peerConfig.keepInterval = wg_peer->PersistentKeepalive; |  |  |  |     if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE) peerConfig.keepInterval = wg_peer->PersistentKeepalive; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (wg_peer->LastHandshake > 0) peerConfig.lastHandshake = (wg_peer->LastHandshake - 116444736000000000LL) / (100 / 1000); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     WIREGUARD_ALLOWED_IP* wg_aip = changePoint<WIREGUARD_PEER, WIREGUARD_ALLOWED_IP>(wg_peer); |  |  |  |     WIREGUARD_ALLOWED_IP* wg_aip = changePoint<WIREGUARD_PEER, WIREGUARD_ALLOWED_IP>(wg_peer); | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (DWORD __aip = 0; __aip < wg_peer->AllowedIPsCount; __aip++) { |  |  |  |     for (DWORD __aip = 0; __aip < wg_peer->AllowedIPsCount; __aip++) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -355,26 +265,28 @@ void WireguardConfig::getWireguardConfig() { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void WireguardConfig::setWireguardConfig() { |  |  |  | void WireguardConfig::setWireguardConfig() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (this->name.length() == 0) throw std::string("Require interface name!"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   else if (this->name.length() > IFNAMSIZ) throw std::string("Interface name too long"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   DWORD buf_len = sizeof(WIREGUARD_INTERFACE); |  |  |  |   DWORD buf_len = sizeof(WIREGUARD_INTERFACE); | 
			
		
	
		
		
			
				
					
					|  |  |  |   for (auto peer : this->Peers) { |  |  |  |   for (auto peer : this->Peers) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (DWORD_MAX - buf_len < sizeof(WIREGUARD_PEER)) throw ("Buffer overflow"); |  |  |  | 		if (DWORD_MAX - buf_len < sizeof(WIREGUARD_PEER)) throw std::string("Buffer overflow"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		buf_len += sizeof(WIREGUARD_PEER); |  |  |  | 		buf_len += sizeof(WIREGUARD_PEER); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		for (auto aip : peer.second.allowedIPs) { |  |  |  | 		for (auto aip : peer.second.allowedIPs) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (DWORD_MAX - buf_len < sizeof(WIREGUARD_ALLOWED_IP)) throw ("Buffer overflow"); |  |  |  | 			if (DWORD_MAX - buf_len < sizeof(WIREGUARD_ALLOWED_IP)) throw std::string("Buffer overflow"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			buf_len += sizeof(WIREGUARD_ALLOWED_IP); |  |  |  | 			buf_len += sizeof(WIREGUARD_ALLOWED_IP); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_INTERFACE *wg_iface = reinterpret_cast<WIREGUARD_INTERFACE*>(calloc(1, buf_len)); |  |  |  |   WIREGUARD_INTERFACE *wg_iface = reinterpret_cast<WIREGUARD_INTERFACE*>(calloc(1, buf_len)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!wg_iface) throw ("Cannot alloc buff"); |  |  |  |   if (!wg_iface) throw std::string("Cannot alloc buff"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   wg_iface->PeersCount = 0; |  |  |  |   wg_iface->PeersCount = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   wgKeys::stringToKey(wg_iface->PrivateKey, privateKey); |  |  |  |   wgKeys::stringToKey(wg_iface->PrivateKey, this->privateKey); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   wg_iface->Flags = WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY; |  |  |  |   wg_iface->Flags = WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   wg_iface->ListenPort = portListen; |  |  |  |   wg_iface->ListenPort = this->portListen; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (portListen >= 0 && 65535 <= portListen) wg_iface->Flags = (WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags|WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_LISTEN_PORT); |  |  |  |   if (this->portListen >= 0) wg_iface->Flags = (WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags|WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_LISTEN_PORT); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (this->replacePeers) wg_iface->Flags = (WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags|WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_REPLACE_PEERS); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (replacePeers) wg_iface->Flags = (WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags|WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_REPLACE_PEERS); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	WIREGUARD_ALLOWED_IP *wg_aip; |  |  |  | 	WIREGUARD_ALLOWED_IP *wg_aip; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	WIREGUARD_PEER *wg_peer = changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface); |  |  |  | 	WIREGUARD_PEER *wg_peer = changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -398,7 +310,75 @@ void WireguardConfig::setWireguardConfig() { | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (peerConfig.keepInterval >= 0) wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE); |  |  |  |       if (peerConfig.keepInterval >= 0) wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (peerConfig.endpoint.size() > 0) { |  |  |  |       if (peerConfig.endpoint.size() > 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         insertEndpoint(&wg_peer->Endpoint, peerConfig.endpoint.c_str()); |  |  |  |         int ret, retries = ([]() -> int { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           unsigned long ret; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           char *retries = getenv("WG_ENDPOINT_RESOLUTION_RETRIES"), *end; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (!retries) return 15; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (!strcmp(retries, "infinity")) return -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           ret = strtoul(retries, &end, 10); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (*end || ret > INT_MAX) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             fprintf(stderr, "Unable to parse WG_ENDPOINT_RESOLUTION_RETRIES: `%s'\n", retries); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             exit(1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           return (int)ret; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         })(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         char *begin, *end; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         auto mmutable = strdup(peerConfig.endpoint.c_str()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (!mmutable) throw std::string("strdup"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (!peerConfig.endpoint.size()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           free(mmutable); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           throw std::string("Unable to parse empty endpoint"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (mmutable[0] == '[') { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           begin = &mmutable[1]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           end = strchr(mmutable, ']'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (!end) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             free(mmutable); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw std::string("Unable to find matching brace of endpoint: ").append(peerConfig.endpoint); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           *end++ = '\0'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (*end++ != ':' || !*end) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             free(mmutable); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw std::string("Unable to find port of endpoint: ").append(peerConfig.endpoint); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           begin = mmutable; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           end = strrchr(mmutable, ':'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (!end || !*(end + 1)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             free(mmutable); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw std::string("Unable to find port of endpoint: ").append(peerConfig.endpoint); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           *end++ = '\0'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ADDRINFOA *resolved; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         for (unsigned int timeout = 1000000;; timeout = ((20000000) < (timeout * 6 / 5) ? (20000000) : (timeout * 6 / 5))) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           // ret = getaddrinfo(begin, end, &hints, &resolved); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           ret = getaddrinfo(begin, end, NULL, &resolved); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (!ret) break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           if (ret == EAI_NONAME || ret == EAI_FAIL || | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             #ifdef EAI_NODATA | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               ret == EAI_NODATA || | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               (retries >= 0 && !retries--)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             free(mmutable); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw std::string("Error code: ").append(std::to_string(ret)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           std::this_thread::sleep_for(std::chrono::microseconds(timeout)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(SOCKADDR_IN))) memcpy(&wg_peer->Endpoint.Ipv4, resolved->ai_addr, resolved->ai_addrlen); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         else if (resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(SOCKADDR_IN6)) memcpy(&wg_peer->Endpoint.Ipv6, resolved->ai_addr, resolved->ai_addrlen); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           freeaddrinfo(resolved); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           throw std::string("Neither IPv4 nor IPv6 address found: ").append(peerConfig.endpoint); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         freeaddrinfo(resolved); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         free(mmutable); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT); |  |  |  |         wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT); | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -420,38 +400,74 @@ void WireguardConfig::setWireguardConfig() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(this->name)); |  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(this->name)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!Adapter) Adapter = WireGuardCreateAdapter(toLpcwstr(this->name), L"Wireguard-tools.js", NULL); |  |  |  |   if (!Adapter) Adapter = WireGuardCreateAdapter(toLpcwstr(this->name), WireguardAddonDescription, NULL); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   if (!Adapter) throw std::string("Failed to create adapter, ").append(getErrorString(GetLastError())); |  |  |  |   if (!Adapter) throw std::string("Failed to create adapter, ").append(getErrorString(GetLastError())); | 
			
		
	
		
		
			
				
					
					|  |  |  |   else if (!WireGuardSetConfiguration(Adapter, reinterpret_cast<WIREGUARD_INTERFACE*>(wg_iface), buf_len)) { |  |  |  |  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   auto status = WireGuardSetConfiguration(Adapter, reinterpret_cast<WIREGUARD_INTERFACE*>(wg_iface), buf_len) && WireGuardSetAdapterState(Adapter, WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_UP); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   free(wg_iface); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (!status) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     auto status = GetLastError(); |  |  |  |     auto status = GetLastError(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     WireGuardCloseAdapter(Adapter); |  |  |  |     WireGuardCloseAdapter(Adapter); | 
			
		
	
		
		
			
				
					
					|  |  |  |     throw std::string("Failed to set interface config, ").append(getErrorString(status)); |  |  |  |     throw std::string("Failed to set interface config, ").append(getErrorString(status)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } else if (!WireGuardSetAdapterState(Adapter, WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_UP)) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     auto status = GetLastError(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     WireGuardCloseAdapter(Adapter); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     throw std::string("Failed to set interface up, ").append(getErrorString(status)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     this->interfaceAddress.SetInInterface(this->name); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |   free(wg_iface); |  |  |  |  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   this->interfaceAddress.SetInInterface(this->name); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void IpManeger::GetInInterface(std::string interfaceName) { |  |  |  | void IpManeger::GetInInterface(std::string interfaceName) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Define the InterfaceLuid of the network interface you want to query |  |  |  |   // Define the InterfaceLuid of the network interface you want to query | 
			
		
	
		
		
			
				
					
					|  |  |  |   NET_IFINDEX ind; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   NET_LUID InterfaceLuid; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(interfaceName)); |  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(interfaceName)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!Adapter) throw std::string("Cannot open wireguard adapter"); |  |  |  |   if (!Adapter) throw std::string("Cannot open wireguard adapter"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   NET_LUID InterfaceLuid; | 
			
		
	
		
		
			
				
					
					|  |  |  |   WireGuardGetAdapterLUID(Adapter, &InterfaceLuid); |  |  |  |   WireGuardGetAdapterLUID(Adapter, &InterfaceLuid); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (ConvertInterfaceLuidToIndex(&InterfaceLuid, &ind) != NO_ERROR) throw std::string("Cannot get interface index"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   ULONG bufferSize = 0; // Initial buffer size |  |  |  |   ULONG bufferSize = 0; // Initial buffer size | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Call GetAdaptersAddresses to get the required buffer size |  |  |  |   // Call GetAdaptersAddresses to get the required buffer size | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &bufferSize) == ERROR_BUFFER_OVERFLOW) { |  |  |  |   if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &bufferSize) == ERROR_BUFFER_OVERFLOW) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Allocate memory for the buffer |  |  |  |     // Allocate memory for the buffer | 
			
		
	
		
		
			
				
					
					|  |  |  |     PIP_ADAPTER_ADDRESSES addresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(bufferSize)); |  |  |  |     PIP_ADAPTER_ADDRESSES addresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(bufferSize)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Call GetAdaptersAddresses again with the allocated buffer | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, addresses, &bufferSize) == NO_ERROR) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       // Iterate through the list of adapters | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       for (PIP_ADAPTER_ADDRESSES adapter = addresses; adapter != nullptr; adapter = adapter->Next) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // Check if the adapter matches the specified InterfaceLuid | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (memcmp(&adapter->Luid, &InterfaceLuid, sizeof(NET_LUID)) == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           // Iterate through the list of IP addresses associated with the adapter | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           for (PIP_ADAPTER_UNICAST_ADDRESS address = adapter->FirstUnicastAddress; address != nullptr; address = address->Next) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // Access the IP address in the address structure | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             sockaddr* sa = address->Address.lpSockaddr; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             char ip[INET6_ADDRSTRLEN]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (sa->sa_family == AF_INET) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               inet_ntop(AF_INET, &reinterpret_cast<sockaddr_in*>(sa)->sin_addr, ip, sizeof(ip)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else if (sa->sa_family == AF_INET6) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               inet_ntop(AF_INET6, &reinterpret_cast<sockaddr_in6*>(sa)->sin6_addr, ip, sizeof(ip)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // Print or use the IP address as needed | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             this->addIPMask(std::string(ip).append("/").append(std::to_string(address->Address.iSockaddrLength))); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Free the allocated buffer | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     free(addresses); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-createunicastipaddressentry | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void IpManeger::SetInInterface(std::string interfaceName) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (this->size() == 0) return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(interfaceName)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (!Adapter) throw std::string("Cannot open wireguard adapter"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   NET_LUID InterfaceLuid; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   WireGuardGetAdapterLUID(Adapter, &InterfaceLuid); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   ULONG bufferSize = 0; // Initial buffer size | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   // Call GetAdaptersAddresses to get the required buffer size | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &bufferSize) == ERROR_BUFFER_OVERFLOW) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Allocate memory for the buffer | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     PIP_ADAPTER_ADDRESSES addresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(bufferSize)); | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Call GetAdaptersAddresses again with the allocated buffer |  |  |  |     // Call GetAdaptersAddresses again with the allocated buffer | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, addresses, &bufferSize) == NO_ERROR) { |  |  |  |     if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, addresses, &bufferSize) == NO_ERROR) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       // Iterate through the list of adapters |  |  |  |       // Iterate through the list of adapters | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -469,8 +485,19 @@ void IpManeger::GetInInterface(std::string interfaceName) { | 
			
		
	
		
		
			
				
					
					|  |  |  |               inet_ntop(AF_INET6, &reinterpret_cast<sockaddr_in6*>(sa)->sin6_addr, ip, sizeof(ip)); |  |  |  |               inet_ntop(AF_INET6, &reinterpret_cast<sockaddr_in6*>(sa)->sin6_addr, ip, sizeof(ip)); | 
			
		
	
		
		
			
				
					
					|  |  |  |             } else continue; |  |  |  |             } else continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // Print or use the IP address as needed |  |  |  |             // Delete the IP address | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             this->addIPMask(std::string(ip).append("/").append(std::to_string(address->Address.iSockaddrLength))); |  |  |  |             MIB_UNICASTIPADDRESS_ROW row; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             memset(&row, 0, sizeof(row)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             WireGuardGetAdapterLUID(Adapter, &row.InterfaceLuid); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (sa->sa_family == AF_INET) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               row.Address.si_family = AF_INET; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               inet_pton(AF_INET, ip, &row.Address.Ipv4.sin_addr); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else if (sa->sa_family == AF_INET6) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               row.Address.si_family = AF_INET6; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               inet_pton(AF_INET6, ip, &row.Address.Ipv6.sin6_addr); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (DeleteUnicastIpAddressEntry(&row) != NO_ERROR) throw std::string("Cannot delete IP address from interface"); | 
			
		
	
		
		
			
				
					
					|  |  |  |           } |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -479,14 +506,25 @@ void IpManeger::GetInInterface(std::string interfaceName) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Free the allocated buffer |  |  |  |     // Free the allocated buffer | 
			
		
	
		
		
			
				
					
					|  |  |  |     free(addresses); |  |  |  |     free(addresses); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void IpManeger::SetInInterface(std::string interfaceName) { |  |  |  |   for (auto ip : this->getIpParsed()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (this->size() == 0) return; |  |  |  |     MIB_UNICASTIPADDRESS_ROW row; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   NET_IFINDEX interfaceIndex; |  |  |  |     memset(&row, 0, sizeof(row)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   NET_LUID InterfaceLuid; |  |  |  |     memcpy(&row.InterfaceLuid, &InterfaceLuid, sizeof(NET_LUID)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(interfaceName)); |  |  |  |  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (!Adapter) throw std::string("Cannot open wireguard adapter"); |  |  |  |     row.DadState = NldsPreferred; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   WireGuardGetAdapterLUID(Adapter, &InterfaceLuid); |  |  |  |     row.ValidLifetime = 0xffffffff; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (ConvertInterfaceLuidToIndex(&InterfaceLuid, &interfaceIndex) != NO_ERROR) throw std::string("Cannot get interface index"); |  |  |  |     row.PreferredLifetime = 0xffffffff; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     row.OnLinkPrefixLength = ip.Mask; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (ip.Proto == 4) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       row.Address.si_family = AF_INET; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       inet_pton(AF_INET, ip.Address.c_str(), &row.Address.Ipv4.sin_addr); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } else if (ip.Proto == 6) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       row.Address.si_family = AF_INET6; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       inet_pton(AF_INET6, ip.Address.c_str(), &row.Address.Ipv6.sin6_addr); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } else continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (CreateUnicastIpAddressEntry(&row) != NO_ERROR) throw std::string("Cannot add IP address to interface"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } |