Skip to content

Commit

Permalink
[libasiotap/libfreelan] Adds an option to set DHCP for interface (Win…
Browse files Browse the repository at this point in the history
…dows only).
  • Loading branch information
s-vincent committed Dec 19, 2018
1 parent 42ffdf0 commit 30b6f8c
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 2 deletions.
8 changes: 8 additions & 0 deletions apps/freelan/config/freelan.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,14 @@ public_endpoint=0.0.0.0
#
ipv4_address_prefix_length=9.0.0.1/24

# The tap adapter interface DHCP status.
#
# If it is on the interface will send DHCP request to obtain IPv4 address from
# DHCP server (which must be installed on the FreeLAN overlay network).
#
# Note: this is only available for Windows!
ipv4_dhcp=false

# The tap adapter IPv6 address and prefix length to use.
#
# The network address must be in numeric format with a netmask suffix.
Expand Down
6 changes: 6 additions & 0 deletions apps/freelan/src/configuration_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ po::options_description get_tap_adapter_options()
("tap_adapter.mss_override", po::value<fl::mss_type>()->default_value(fl::mss_type()), "The MSS override.")
("tap_adapter.metric", po::value<fl::metric_type>()->default_value(fl::auto_metric_type()), "The metric of the tap adapter.")
("tap_adapter.ipv4_address_prefix_length", po::value<asiotap::ipv4_network_address>(), "The tap adapter IPv4 address and prefix length.")
("tap_adapter.ipv4_dhcp", po::value<bool>()->default_value(false), "The tap adapter IPv4 DHCP status.")
("tap_adapter.ipv6_address_prefix_length", po::value<asiotap::ipv6_network_address>(), "The tap adapter IPv6 address and prefix length.")
("tap_adapter.remote_ipv4_address", po::value<asiotap::ipv4_network_address>(), "The tap adapter IPv4 remote address.")
("tap_adapter.arp_proxy_enabled", po::value<bool>()->default_value(false), "Whether to enable the ARP proxy.")
Expand Down Expand Up @@ -538,6 +539,11 @@ void setup_configuration(const fscp::logger& logger, fl::configuration& configur
configuration.tap_adapter.ipv4_address_prefix_length = vm["tap_adapter.ipv4_address_prefix_length"].as<asiotap::ipv4_network_address>();
}

if (vm.count("tap_adapter.ipv4_dhcp"))
{
configuration.tap_adapter.ipv4_dhcp = vm["tap_adapter.ipv4_dhcp"].as<bool>();
}

if (vm.count("tap_adapter.ipv6_address_prefix_length"))
{
configuration.tap_adapter.ipv6_address_prefix_length = vm["tap_adapter.ipv6_address_prefix_length"].as<asiotap::ipv6_network_address>();
Expand Down
1 change: 1 addition & 0 deletions libs/asiotap/include/asiotap/tap_adapter_configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ namespace asiotap
{
boost::optional<ipv4_network_address> network_address;
boost::optional<boost::asio::ip::address_v4> remote_address;
bool dhcp;
};

struct ipv6_configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ namespace asiotap
{
}

void netsh_interface_ip_set_dhcp(const std::string& interface_name, bool persistent = false);
void netsh_interface_ip_set_address(const std::string& interface_name, const ip_network_address& address, bool persistent = false);

windows_route_manager::route_type get_route_for(const boost::asio::ip::address& host);
Expand Down
26 changes: 26 additions & 0 deletions libs/asiotap/src/windows/windows_route_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,32 @@ namespace asiotap
unregister_route(route_entry.interface, route_entry.route, route_entry.metric);
}

void windows_route_manager::netsh_interface_ip_set_dhcp(const std::string& interface_name, bool persistent)
{
std::vector<std::string> args {
"interface",
"ip",
"set",
"address",
"dhcp",
"name=" + interface_name,
persistent ? "store=persistent" : "store=active"
};

#ifdef UNICODE
std::vector<std::wstring> wargs;

for (auto&& arg : args)
{
wargs.push_back(multi_byte_to_wide_char(arg));
}

netsh(wargs);
#else
netsh(args);
#endif
}

void windows_route_manager::netsh_interface_ip_set_address(const std::string& interface_name, const ip_network_address& address, bool persistent)
{
std::vector<std::string> args;
Expand Down
19 changes: 17 additions & 2 deletions libs/asiotap/src/windows/windows_tap_adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,8 @@ namespace asiotap
DWORD len;

if (!::DeviceIoControl(descriptor().native_handle(), TAP_WIN_IOCTL_SET_MEDIA_STATUS,
&status, sizeof(status),
&status, sizeof(status), &len, NULL))
&status, sizeof(status),
&status, sizeof(status), &len, NULL))
{
throw boost::system::system_error(::GetLastError(), boost::system::system_category());
}
Expand Down Expand Up @@ -488,6 +488,21 @@ namespace asiotap
}
}

if (configuration.ipv4.dhcp)
{
try
{
m_route_manager.netsh_interface_ip_set_dhcp(display_name());
}
catch (const boost::system::system_error& ex)
{
if (ex.code() != executeplus::executeplus_error::external_process_failed)
{
throw;
}
}
}

if (configuration.ipv6.network_address)
{
try
Expand Down
5 changes: 5 additions & 0 deletions libs/freelan/include/freelan/configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@ namespace freelan
*/
asiotap::ipv4_network_address ipv4_address_prefix_length;

/**
* \brief The IPv4 tap adapter DHCP status.
*/
bool ipv4_dhcp;

/**
* \brief The IPv6 tap adapter address.
*/
Expand Down
3 changes: 3 additions & 0 deletions libs/freelan/src/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,9 @@ namespace freelan
m_logger(fscp::log_level::information) << "No IPv4 address configured.";
}

// IPv4 DHCP (for Windows)
tap_config.ipv4.dhcp = m_configuration.tap_adapter.ipv4_dhcp;

// IPv6 address
if (!m_configuration.tap_adapter.ipv6_address_prefix_length.is_null())
{
Expand Down

0 comments on commit 30b6f8c

Please sign in to comment.