33#include <ddk/ndisguid.h>
45#include <tap-windows.h>
79const char ADAPTER[] = ADAPTER_KEY;
80const char NETWORK_CONNECTIONS[] = NETWORK_CONNECTIONS_KEY;
84const char WINTUN_COMPONENT_ID[] =
"wintun";
85const char OVPNDCO_COMPONENT_ID[] =
"ovpn-dco";
88const char ROOT_WINTUN_COMPONENT_ID[] =
"root\\wintun";
89const char ROOT_OVPNDCO_COMPONENT_ID[] =
"root\\ovpn-dco";
91const char OVPNDCO_DEV_INTERFACE_REF_STRING[] =
"\\ovpn-dco";
104 std::vector<TapGuidLuid>
ret;
106 const char *component_id;
107 const char *root_component_id;
112 component_id = COMPONENT_ID;
113 root_component_id = ROOT_COMPONENT_ID;
116 component_id = WINTUN_COMPONENT_ID;
117 root_component_id = ROOT_WINTUN_COMPONENT_ID;
120 component_id = OVPNDCO_COMPONENT_ID;
121 root_component_id = ROOT_OVPNDCO_COMPONENT_ID;
124 OPENVPN_THROW(tun_win_util,
"tap_guids: unsupported TAP type");
129 status = ::RegOpenKeyExA(HKEY_LOCAL_MACHINE,
134 if (status != ERROR_SUCCESS)
137 OPENVPN_THROW(tun_win_util,
"tap_guids: error opening adapter registry key: " << ADAPTER <<
" : " << err.message());
140 for (
int i = 0;; ++i)
145 len =
sizeof(strbuf);
146 status = ::RegEnumKeyExA(adapter_key(),
154 if (status == ERROR_NO_MORE_ITEMS)
156 else if (status != ERROR_SUCCESS)
157 OPENVPN_THROW(tun_win_util,
"tap_guids: error enumerating registry subkeys of key: " << ADAPTER);
160 const std::string unit_string = std::string(ADAPTER)
162 + std::string(strbuf);
164 status = ::RegOpenKeyExA(HKEY_LOCAL_MACHINE,
170 if (status != ERROR_SUCCESS)
173 len =
sizeof(strbuf);
174 status = ::RegQueryValueExA(unit_key(),
181 if (status != ERROR_SUCCESS || data_type != REG_SZ)
190 len =
sizeof(strbuf);
191 status = ::RegQueryValueExA(unit_key(),
198 if (status == ERROR_SUCCESS && data_type == REG_SZ)
201 tgl.first = std::string(strbuf);
206 status = ::RegQueryValueExA(unit_key(),
213 if (status == ERROR_SUCCESS && data_type == REG_DWORD)
232 return index != DWORD(-1);
238 return to_string(
index);
239 else if (!
name.empty())
240 return '"' +
name +
'"';
242 OPENVPN_THROW(tun_win_util,
"TapNameGuidPair: TAP interface " <<
guid <<
" has no name or interface index");
265 std::vector<TapGuidLuid> guids =
tap_guids(tun_type);
266 for (
auto i = guids.begin(); i != guids.end(); i++)
269 pair.
guid = i->first;
275 const size_t len = 128;
277 _snwprintf(wbuf, len, L
"\\DEVICE\\TCPIP_%S", pair.
guid.c_str());
279 if (::GetAdapterIndex(wbuf, &aindex) == NO_ERROR)
294 status = ::RegOpenKeyExA(HKEY_LOCAL_MACHINE,
298 network_connections_key.
ref());
299 if (status != ERROR_SUCCESS)
302 OPENVPN_THROW(tun_win_util,
"TapNameGuidPairList: error opening network connections registry key: " << NETWORK_CONNECTIONS <<
" : " << err.message());
305 for (
int i = 0;; ++i)
310 len =
sizeof(strbuf);
311 status = ::RegEnumKeyExA(network_connections_key(),
319 if (status == ERROR_NO_MORE_ITEMS)
321 else if (status != ERROR_SUCCESS)
322 OPENVPN_THROW(tun_win_util,
"TapNameGuidPairList: error enumerating registry subkeys of key: " << NETWORK_CONNECTIONS);
325 const std::string guid = std::string(strbuf);
326 const std::string connection_string = std::string(NETWORK_CONNECTIONS) + std::string(
"\\") + guid + std::string(
"\\Connection");
328 status = ::RegOpenKeyExA(HKEY_LOCAL_MACHINE,
329 connection_string.c_str(),
332 connection_key.
ref());
333 if (status != ERROR_SUCCESS)
336 wchar_t wbuf[256] = L
"";
337 DWORD cbwbuf =
sizeof(wbuf);
338 status = ::RegQueryValueExW(connection_key(),
344 if (status != ERROR_SUCCESS || data_type != REG_SZ)
346 wbuf[(cbwbuf /
sizeof(wchar_t)) - 1] = L
'\0';
350 for (iterator j = begin(); j != end(); j++)
353 if (pair.
guid == guid)
354 pair.
name = wstring::to_utf8(wbuf);
363 std::ostringstream
os;
364 for (const_iterator i = begin(); i != end(); i++)
367 os <<
"guid='" << pair.
guid <<
'\'';
370 if (!pair.
name.empty())
371 os <<
" name='" << pair.
name <<
'\'';
379 for (const_iterator i = begin(); i != end(); i++)
382 if (pair.
guid == guid)
385 throw std::range_error{
"guid not found"};
390 for (const_iterator i = begin(); i != end(); i++)
393 if (pair.
name == name)
396 throw std::range_error{
"name not found"};
411 handle = SetupDiGetClassDevsEx(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
416 return handle != INVALID_HANDLE_VALUE;
428 SetupDiDestroyDeviceInfoList(
handle);
444 for (DWORD i = 0;; ++i)
446 SP_DEVINFO_DATA dev_info_data;
447 ZeroMemory(&dev_info_data,
sizeof(SP_DEVINFO_DATA));
448 dev_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
449 BOOL res = SetupDiEnumDeviceInfo(device_info_set, i, &dev_info_data);
452 if (GetLastError() == ERROR_NO_MORE_ITEMS)
459 *regkey.
ref() = SetupDiOpenDevRegKey(device_info_set, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
463 std::string str_net_cfg_instance_id;
466 LONG status = RegQueryValueExA(regkey(),
"NetCfgInstanceId", NULL, NULL, NULL, &size);
467 if (status != ERROR_SUCCESS)
471 status = RegQueryValueExA(regkey(),
"NetCfgInstanceId", NULL, NULL, (LPBYTE)buf_net_cfg_inst_id.
data(), &size);
472 if (status == ERROR_SUCCESS)
474 buf_net_cfg_inst_id.
data()[size - 1] =
'\0';
475 str_net_cfg_instance_id = std::string(buf_net_cfg_inst_id.
data());
480 res = SetupDiGetDeviceInstanceId(device_info_set, &dev_info_data, NULL, 0, &size);
481 if (res != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
485 if (!SetupDiGetDeviceInstanceId(device_info_set, &dev_info_data, buf_dev_inst_id.
data(), size, &size))
489 ULONG dev_interface_list_size = 0;
490 CONFIGRET cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
491 (LPGUID)&GUID_DEVINTERFACE_NET,
492 buf_dev_inst_id.
data(),
493 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
495 if (cr != CR_SUCCESS)
499 cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_NET,
500 buf_dev_inst_id.
data(),
501 buf_dev_iface_list.
data(),
502 dev_interface_list_size,
503 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
504 if (cr != CR_SUCCESS)
507 char *dev_if = buf_dev_iface_list.
data();
508 while (strlen(dev_if) > 0)
515 dev_if += strlen(dev_if) + 1;
524 return std::string(USERMODEDEVICEDIR) + tap.
guid + std::string(TAP_WIN_SUFFIX);
530 std::string &path_opened,
535 std::unique_ptr<DeviceInstanceIdInterfaceList> inst_id_interface_list;
540 for (TapNameGuidPairList::const_iterator i = guids.begin(); i != guids.end(); i++)
548 for (
const auto &inst_id_interface : *inst_id_interface_list)
550 if (inst_id_interface.net_cfg_instance_id != tap.
guid)
555 if (!
string::ends_with(inst_id_interface.device_interface, OVPNDCO_DEV_INTERFACE_REF_STRING))
558 path = inst_id_interface.device_interface;
567 if (path.length() > 0)
569 hand.
reset(::CreateFileA(path.c_str(),
570 GENERIC_READ | GENERIC_WRITE,
574 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
600 if (!::DeviceIoControl(th,
601 TAP_WIN_IOCTL_CONFIG_TUN,
609 throw tun_win_util(
"DeviceIoControl TAP_WIN_IOCTL_CONFIG_TUN failed");
624 if (!::DeviceIoControl(th,
625 TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT,
633 throw tun_win_util(
"DeviceIoControl TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT failed");
641 ULONG status = media_status ? TRUE : FALSE;
642 if (!::DeviceIoControl(th,
643 TAP_WIN_IOCTL_SET_MEDIA_STATUS,
651 throw tun_win_util(
"DeviceIoControl TAP_WIN_IOCTL_SET_MEDIA_STATUS failed");
659 const size_t size = 1024;
660 std::unique_ptr<char[]> line(
new char[size]);
663 while (::DeviceIoControl(th,
664 TAP_WIN_IOCTL_GET_LOG_LINE,
682 if (::GetInterfaceInfo(
nullptr, &size) != ERROR_INSUFFICIENT_BUFFER)
683 OPENVPN_THROW(tun_win_util,
"InterfaceInfoList: GetInterfaceInfo #1");
684 list.reset((IP_INTERFACE_INFO *)::operator
new(size));
685 if (::GetInterfaceInfo(
list.get(), &size) != NO_ERROR)
686 OPENVPN_THROW(tun_win_util,
"InterfaceInfoList: GetInterfaceInfo #2");
689 IP_ADAPTER_INDEX_MAP *
iface(
const DWORD index)
const
693 for (LONG i = 0; i <
list->NumAdapters; ++i)
695 IP_ADAPTER_INDEX_MAP *inter = &
list->Adapter[i];
696 if (index == inter->Index)
707 const DWORD adapter_index,
710 IP_ADAPTER_INDEX_MAP *iface = ii.
iface(adapter_index);
713 const DWORD status = ::IpReleaseAddress(iface);
714 if (status == NO_ERROR)
715 os <<
"TAP: DHCP release succeeded" << std::endl;
717 os <<
"TAP: DHCP release failed" << std::endl;
722 const DWORD adapter_index,
725 IP_ADAPTER_INDEX_MAP *iface = ii.
iface(adapter_index);
728 const DWORD status = ::IpRenewAddress(iface);
729 if (status == NO_ERROR)
730 os <<
"TAP: DHCP renew succeeded" << std::endl;
732 os <<
"TAP: DHCP renew failed" << std::endl;
739 const DWORD status = ::FlushIpNetTable2(AF_INET, adapter_index);
740 if (status == NO_ERROR)
741 os <<
"TAP: ARP flush succeeded" << std::endl;
743 os <<
"TAP: ARP flush failed" << std::endl;
770 catch (
const std::exception &)
777 catch (
const std::exception &)
802 if (::GetAdaptersInfo(
nullptr, &size) != ERROR_BUFFER_OVERFLOW)
803 OPENVPN_THROW(tun_win_util,
"IPAdaptersInfo: GetAdaptersInfo #1");
804 list.reset((IP_ADAPTER_INFO *)::operator
new(size));
805 if (::GetAdaptersInfo(
list.get(), &size) != NO_ERROR)
806 OPENVPN_THROW(tun_win_util,
"IPAdaptersInfo: GetAdaptersInfo #2");
809 const IP_ADAPTER_INFO *
adapter(
const DWORD index)
const
813 for (
const IP_ADAPTER_INFO *a =
list.get(); a !=
nullptr; a = a->Next)
815 if (index == a->Index)
824 const IP_ADAPTER_INFO *ai =
adapter(index);
827 for (
const IP_ADDR_STRING *iplist = &ai->IpAddressList; iplist !=
nullptr; iplist = iplist->Next)
838 const IP_ADAPTER_INFO *ai =
adapter(index);
839 return ai && ai->DhcpEnabled;
850 if (::GetPerAdapterInfo(index,
nullptr, &size) != ERROR_BUFFER_OVERFLOW)
852 adapt.reset((IP_PER_ADAPTER_INFO *)::operator
new(size));
853 if (::GetPerAdapterInfo(index,
adapt.get(), &size) != ERROR_SUCCESS)
868 if (::DeviceIoControl(th,
869 TAP_WIN_IOCTL_GET_VERSION,
883 std::ostringstream
os;
884 os <<
"TAP-Windows Driver Version ";
906 const std::string &tap_guid_arg)
918 const std::string reg_key_name =
"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\" +
tap_guid;
919 status = ::RegOpenKeyExA(HKEY_LOCAL_MACHINE,
920 reg_key_name.c_str(),
922 KEY_READ | KEY_WRITE,
924 if (status != ERROR_SUCCESS)
927 OPENVPN_THROW(tun_win_util,
"ActionSetAdapterDomainSuffix: error opening registry key: " << reg_key_name <<
" : " << err.message());
931 status = ::RegSetValueExW(key(),
935 reinterpret_cast<const BYTE *
>(dom.get()),
937 if (status != ERROR_SUCCESS)
938 OPENVPN_THROW(tun_win_util,
"ActionSetAdapterDomainSuffix: error writing Domain registry key: " << reg_key_name);
958 status = ::GetIpForwardTable(
nullptr, &size, TRUE);
959 if (status == ERROR_INSUFFICIENT_BUFFER)
961 rt.reset((MIB_IPFORWARDTABLE *)::operator
new(size));
962 status = ::GetIpForwardTable(rt.get(), &size, TRUE);
963 if (status != NO_ERROR)
965 OPENVPN_LOG(
"windows_routing_table: GetIpForwardTable failed");
976 MIB_IPFORWARD_TABLE2 *routes =
nullptr;
977 int res = ::GetIpForwardTable2(af, &routes);
993 [](
const MIB_IPFORWARD_TABLE2 *p)
994 { FreeMibTable((PVOID)p); });
1001 std::map<NET_IFINDEX, ULONG> metric_per_iface;
1002 ULONG gw_metric = 0;
1004 const MIB_IPFORWARD_ROW2 *gw =
nullptr;
1005 for (
size_t i = 0; i < rt2->NumEntries; ++i)
1007 const MIB_IPFORWARD_ROW2 *row = &rt2->Table[i];
1010 bool default_gw = dst.
all_zeros() && row->DestinationPrefix.PrefixLength == 0;
1014 if (default_gw && (!gw ||
metric < gw_metric))
1022 index = gw->InterfaceIndex;
1044 BestGateway(ADDRESS_FAMILY af,
const std::string &dest_str, DWORD vpn_interface_index)
1047 [](
const MIB_IPFORWARD_TABLE2 *p)
1048 { FreeMibTable((PVOID)p); });
1057 void *dst_addr = NULL;
1058 struct sockaddr_in sa4;
1059 struct sockaddr_in6 sa6;
1071 NET_IFINDEX best_interface = 0;
1072 DWORD res = ::GetBestInterfaceEx((sockaddr *)dst_addr, &best_interface);
1073 if (res != NO_ERROR)
1076 "GetBestInterfaceEx: error retrieving the best interface for " << dest
1081 MIB_IPFORWARD_ROW2 row{};
1082 SOCKADDR_INET best_source{};
1083 res = ::GetBestRoute2(NULL, best_interface, NULL, (
const SOCKADDR_INET *)dst_addr, 0, &row, &best_source);
1084 if (res != NO_ERROR)
1087 "GetBestGateway: error retrieving the best route for " << dest
1092 if (row.Protocol == RouteProtocolLocal)
1099 if (vpn_interface_index == DWORD(-1))
1106 const MIB_IPFORWARD_ROW2 *gw =
nullptr;
1107 std::map<NET_IFINDEX, ULONG> metric_per_iface;
1108 ULONG gw_metric = 0;
1109 for (
size_t i = 0; i < rt2->NumEntries; ++i)
1111 const MIB_IPFORWARD_ROW2 *row = &rt2->Table[i];
1116 if ((dest & mask) == dest_prefix)
1119 if ((vpn_interface_index != DWORD(-1)) && (row->InterfaceIndex == vpn_interface_index))
1123 <<
" on VPN interface " << vpn_interface_index);
1136 if ((row->DestinationPrefix.PrefixLength > gw->DestinationPrefix.PrefixLength) || ((row->DestinationPrefix.PrefixLength == gw->DestinationPrefix.PrefixLength) && (
metric < gw_metric)))
1152 return index != DWORD(-1) && !
addr.empty();
1177 index = row->InterfaceIndex;
1180 <<
"selected gateway " <<
addr
1181 <<
" on adapter " <<
index
1182 <<
" for destination " << dest);
1185 static ULONG
get_iface_metric(std::map<NET_IFINDEX, ULONG> &metric_per_iface, NET_IFINDEX iface, ADDRESS_FAMILY af)
1187 if (!metric_per_iface.contains(iface))
1189 MIB_IPINTERFACE_ROW ir{};
1190 ir.InterfaceIndex = iface;
1192 ::GetIpInterfaceEntry(&ir);
1193 metric_per_iface[iface] = ir.Metric;
1195 return metric_per_iface[iface];
1224 return "ActionDeleteAllRoutesOnInterface iface_index=" + std::to_string(
iface_index);
1233 for (
size_t i = 0; i < rt->dwNumEntries; ++i)
1235 const MIB_IPFORWARDROW *row = &rt->table[i];
1236 if (row->dwForwardIfIndex == index)
1240 const std::string net_str = net.
to_string();
1244 if (net_str ==
"224.0.0.0" && pl == 4)
1246 if (net_str ==
"255.255.255.255" && pl == 32)
1258 [](
const MIB_IPFORWARD_TABLE2 *p)
1259 { FreeMibTable((PVOID)p); });
1264 for (
size_t i = 0; i < rt2->NumEntries; ++i)
1266 const MIB_IPFORWARD_ROW2 *row = &rt2->Table[i];
1267 if (row->InterfaceIndex == index)
1269 const unsigned int pl = row->DestinationPrefix.PrefixLength;
1270 if (row->DestinationPrefix.Prefix.si_family == AF_INET6)
1273 const std::string net_str = net.
to_string();
1276 if (net_str ==
"ff00::" && pl == 8)
1278 if ((net & ll_mask) == ll_net && pl >= 64)
1301 return "netsh interface ip set address " + tap.
index_or_name() +
" dhcp";
1314 const std::string &iface_name,
1315 const std::string &gw_address,
1319 std::ostringstream
os;
1320 os <<
"netsh interface ip ";
1325 os <<
"route " << route_address <<
"/" << std::to_string(prefix_length) <<
" ";
1326 if (iface_index != DWORD(-1))
1330 os <<
" " << gw_address <<
" ";
1332 os <<
"metric=" << std::to_string(
metric) <<
" ";
1333 os <<
"store=active";
1352namespace TunIPHELPER {
1356 ZeroMemory(&sa,
sizeof(sa));
1357 sa.si_family = family;
1358 inet_pton(family, addr.c_str(), family == AF_INET ? &(sa.Ipv4.sin_addr) : (PVOID) & (sa.Ipv6.sin6_addr));
1364 auto wide_name = wstring::from_utf8(iface_name);
1365 return ConvertInterfaceAliasToLuid(wide_name.c_str(), luid);
1376 const std::string &iface_name,
1377 const std::string &gw_address,
1382 os_ <<
"IPHelper: ";
1387 os_ <<
"route " << route_address <<
"/" << std::to_string(prefix_length) <<
" ";
1388 if (iface_index != DWORD(-1))
1392 os_ <<
" " << gw_address <<
" metric=" << std::to_string(
metric);
1395 fwd_row.ValidLifetime = 0xffffffff;
1396 fwd_row.PreferredLifetime = 0xffffffff;
1397 fwd_row.Protocol = (NL_ROUTE_PROTOCOL)MIB_IPPROTO_NETMGMT;
1400 fwd_row.DestinationPrefix.PrefixLength = prefix_length;
1403 if (iface_index != DWORD(-1))
1404 fwd_row.InterfaceIndex = iface_index;
1405 else if (!iface_name.empty())
1410 OPENVPN_THROW(tun_win_util,
"Cannot convert interface name " << iface_name <<
" to LUID");
1417 os <<
os_.str() << std::endl;
1420 res = CreateIpForwardEntry2(&
fwd_row);
1422 res = DeleteIpForwardEntry2(&
fwd_row);
1424 os <<
"cannot modify route: error " << res << std::endl;
virtual std::unordered_set< std::string > execute(std::ostream &os)
Executes a sequence of actions and returns marks of failed actions.
T * data()
Get a mutable pointer to the start of the array.
void set_size(const size_t size)
After an external method, operating on the array as a mutable unsigned char buffer,...
static Addr from_string(const std::string &ipstr, const TITLE &title, const Version required_version)
static Addr from_sockaddr(const struct sockaddr *sa)
std::string to_string() const
const IPv4::Addr & to_ipv4() const
static Addr netmask_from_prefix_len(Version v, const unsigned int prefix_len)
const IPv6::Addr & to_ipv6() const
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
unsigned int prefix_len() const
static Addr from_in_addr(const in_addr *in4)
static Addr from_uint32(const base_type addr)
std::string to_string() const
std::uint32_t to_uint32() const
sockaddr_in to_sockaddr(const unsigned short port=0) const
static Addr from_string(const std::string &ipstr, const TITLE &title)
static Addr from_byte_string(const unsigned char *bytestr)
static Addr from_in6_addr(const in6_addr *in6)
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
std::string to_string() const
static Addr from_string(const std::string &ipstr, const TITLE &title)
sockaddr_in6 to_sockaddr(const unsigned short port=0) const
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
Route address class that may use non-canonical form.
unsigned char prefix_length
const RouteAddress * vpn_ipv4() const
Gets the IPv4 tunnel address.
ActionDeleteAllRoutesOnInterface(const DWORD iface_index_arg)
virtual std::string to_string() const override
virtual void execute(std::ostream &os) override
static void remove_all_ipv4_routes_on_iface(DWORD index, ActionList &actions)
static void remove_all_ipv6_routes_on_iface(DWORD index, ActionList &actions)
static std::string cmd(const TapNameGuidPair &tap)
ActionEnableDHCP(const TapNameGuidPair &tap)
virtual std::string to_string() const override
ActionSetAdapterDomainSuffix(const std::string &search_domain_arg, const std::string &tap_guid_arg)
const std::string tap_guid
virtual void execute(std::ostream &os) override
const std::string search_domain
const std::string & gateway_address() const
DWORD interface_index() const
BestGateway(ADDRESS_FAMILY af, const std::string &dest_str, DWORD vpn_interface_index)
BestGateway(ADDRESS_FAMILY af)
void fill_gw_details(const MIB_IPFORWARD_ROW2 *row, const std::string &dest)
static ULONG get_iface_metric(std::map< NET_IFINDEX, ULONG > &metric_per_iface, NET_IFINDEX iface, ADDRESS_FAMILY af)
TAPDriverVersion(HANDLE th)
void execute(std::ostream &os) override
AddRoute4Cmd(const std::string &route_address, int prefix_length, DWORD iface_index, const std::string &iface_name, const std::string &gw_address, int metric, bool add)
MIB_IPFORWARD_ROW2 fwd_row
RCPtr< AddRoute4Cmd > Ptr
std::string to_string() const override
AddRoute4Cmd(const std::string &route_address, int prefix_length, DWORD iface_index, const std::string &iface_name, const std::string &gw_address, int metric, bool add)
RCPtr< AddRoute4Cmd > Ptr
std::string to_string() const override
void execute(std::ostream &os) override
virtual void execute(std::ostream &os) override
virtual std::string to_string() const override
Wrapper class for a Registry key handle.
bool defined() const
Check for a valid key handle.
PHKEY ref()
Retrun a pointer to the Registry key handle.
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_THROW(exc, stuff)
#define OPENVPN_LOG(args)
constexpr BufferFlags CONSTRUCT_ZERO(1u<< 0)
if enabled, constructors/init will zero allocated space
static SOCKADDR_INET sockaddr_inet(short family, const std::string &addr)
static DWORD InterfaceLuid(const std::string &iface_name, PNET_LUID luid)
const MIB_IPFORWARD_TABLE2 * windows_routing_table2(ADDRESS_FAMILY af)
void flush_arp(const DWORD adapter_index, std::ostream &os)
void dhcp_release(const InterfaceInfoList &ii, const DWORD adapter_index, std::ostream &os)
std::string tap_path(const TapNameGuidPair &tap)
HANDLE tap_open(const Type tun_type, const TapNameGuidPairList &guids, std::string &path_opened, TapNameGuidPair &used)
const MIB_IPFORWARDTABLE * windows_routing_table()
void tap_configure_topology_subnet(HANDLE th, const IP::Addr &local, const unsigned int prefix_len)
void dhcp_renew(const InterfaceInfoList &ii, const DWORD adapter_index, std::ostream &os)
void tap_set_media_status(HANDLE th, bool media_status)
void tap_process_logging(HANDLE th)
std::vector< TapGuidLuid > tap_guids(const Type tun_type)
std::pair< std::string, DWORD > TapGuidLuid
void tap_configure_topology_net30(HANDLE th, const IP::Addr &local_addr, const IP::Addr &remote_addr)
DNS utilities for Windows.
std::unique_ptr< wchar_t[]> UTF16
size_t utf16_strlen(const wchar_t *str)
wchar_t * utf16(const std::string &str, int cp=CP_UTF8)
int strcasecmp(const char *s1, const char *s2)
bool ends_with(const STRING &str, const std::string &suffix)
std::string to_string(const T &t)
Convert a value to a string.
std::unique_ptr< T, std::function< void(T *)> > unique_ptr_del
std::unique_ptr< T, slab_deleter< T > > unique_ptr_slab
#define OPENVPN_STRINGIZE(x)
DeviceInstanceIdInterfaceList()
std::string device_interface
std::string net_cfg_instance_id
unique_ptr_slab< IP_ADAPTER_INFO > list
const IP_ADAPTER_INFO * adapter(const DWORD index) const
bool is_up(const DWORD index, const IPNetmask4 &vpn_addr) const
bool is_dhcp_enabled(const DWORD index) const
IPNetmask4(const IP_ADDR_STRING *ias)
bool operator==(const IPNetmask4 &rhs) const
bool operator!=(const IPNetmask4 &rhs) const
IPNetmask4(const TunBuilderCapture &pull, const char *title)
unique_ptr_slab< IP_PER_ADAPTER_INFO > adapt
IPPerAdapterInfo(const DWORD index)
unique_ptr_slab< IP_INTERFACE_INFO > list
IP_ADAPTER_INDEX_MAP * iface(const DWORD index) const
TapNameGuidPairList(const Type tun_type)
std::string to_string() const
std::string guid_from_name(const std::string &name) const
std::string name_from_guid(const std::string &guid) const
bool index_defined() const
std::string index_or_name() const
server addresses push_back({address, port})
int prefix_len(const IPv4::Addr::base_type mask)
static void add(const Time &t1, const Time::Duration &d1)