230 lines
6.2 KiB
C++
230 lines
6.2 KiB
C++
/*
|
|
* \brief Sculpt network management
|
|
* \author Norman Feske
|
|
* \date 2018-04-30
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2018 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
/* local includes */
|
|
#include <network.h>
|
|
|
|
|
|
void Sculpt::Network::_generate_nic_router_uplink(Xml_generator &xml,
|
|
char const *label)
|
|
{
|
|
xml.node("uplink", [&] () {
|
|
xml.attribute("label", label);
|
|
xml.attribute("domain", "uplink");
|
|
});
|
|
gen_named_node(xml, "domain", "uplink", [&] () {
|
|
xml.node("nat", [&] () {
|
|
xml.attribute("domain", "default");
|
|
xml.attribute("tcp-ports", "1000");
|
|
xml.attribute("udp-ports", "1000");
|
|
xml.attribute("icmp-ids", "1000");
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
void Sculpt::Network::handle_key_press(Codepoint code)
|
|
{
|
|
enum { BACKSPACE = 8, ENTER = 10 };
|
|
if (code.value == BACKSPACE)
|
|
wpa_passphrase.remove_last_character();
|
|
else if (code.value == ENTER)
|
|
wifi_connect(dialog.selected_ap());
|
|
else if (code.valid())
|
|
wpa_passphrase.append_character(code);
|
|
|
|
/*
|
|
* Keep updating the passphase when pressing keys after
|
|
* clicking the connect button once.
|
|
*/
|
|
if (_wifi_connection.state == Wifi_connection::CONNECTING)
|
|
wifi_connect(_wifi_connection.bssid);
|
|
|
|
_dialog_generator.generate_dialog();
|
|
}
|
|
|
|
|
|
void Sculpt::Network::_generate_nic_router_config()
|
|
{
|
|
if ((_nic_target.wired() && !_runtime_info.present_in_runtime("nic_drv"))
|
|
|| (_nic_target.wifi() && !_runtime_info.present_in_runtime("wifi_drv"))) {
|
|
|
|
/* defer NIC router reconfiguration until the needed uplink is present */
|
|
_nic_router_config_up_to_date = false;
|
|
return;
|
|
}
|
|
|
|
_nic_router_config_up_to_date = true;
|
|
|
|
if (_nic_router_config.try_generate_manually_managed())
|
|
return;
|
|
|
|
if (!_nic_target.nic_router_needed()) {
|
|
_nic_router_config.generate([&] (Xml_generator &xml) {
|
|
xml.attribute("verbose_domain_state", "yes"); });
|
|
return;
|
|
}
|
|
|
|
_nic_router_config.generate([&] (Xml_generator &xml) {
|
|
xml.attribute("verbose_domain_state", "yes");
|
|
|
|
xml.node("report", [&] () {
|
|
xml.attribute("interval_sec", "5");
|
|
xml.attribute("bytes", "yes");
|
|
xml.attribute("config", "yes");
|
|
xml.attribute("config_triggers", "yes");
|
|
});
|
|
|
|
xml.node("default-policy", [&] () {
|
|
xml.attribute("domain", "default"); });
|
|
|
|
bool uplink_exists = true;
|
|
switch (_nic_target.type()) {
|
|
case Nic_target::WIRED: _generate_nic_router_uplink(xml, "wired"); break;
|
|
case Nic_target::WIFI: _generate_nic_router_uplink(xml, "wifi"); break;
|
|
default: uplink_exists = false;
|
|
}
|
|
gen_named_node(xml, "domain", "default", [&] () {
|
|
xml.attribute("interface", "10.0.1.1/24");
|
|
|
|
xml.node("dhcp-server", [&] () {
|
|
xml.attribute("ip_first", "10.0.1.2");
|
|
xml.attribute("ip_last", "10.0.1.200");
|
|
if (_nic_target.type() != Nic_target::LOCAL) {
|
|
xml.attribute("dns_server_from", "uplink"); }
|
|
});
|
|
|
|
if (uplink_exists) {
|
|
xml.node("tcp", [&] () {
|
|
xml.attribute("dst", "0.0.0.0/0");
|
|
xml.node("permit-any", [&] () {
|
|
xml.attribute("domain", "uplink"); }); });
|
|
|
|
xml.node("udp", [&] () {
|
|
xml.attribute("dst", "0.0.0.0/0");
|
|
xml.node("permit-any", [&] () {
|
|
xml.attribute("domain", "uplink"); }); });
|
|
|
|
xml.node("icmp", [&] () {
|
|
xml.attribute("dst", "0.0.0.0/0");
|
|
xml.attribute("domain", "uplink"); });
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
void Sculpt::Network::_handle_wlan_accesspoints()
|
|
{
|
|
bool const initial_scan = !_wlan_accesspoints_rom.xml().has_sub_node("accesspoint");
|
|
|
|
_wlan_accesspoints_rom.update();
|
|
|
|
/* suppress updating the list while the access-point list is hovered */
|
|
if (!initial_scan && dialog.ap_list_hovered())
|
|
return;
|
|
|
|
Access_point_update_policy policy(_alloc);
|
|
_access_points.update_from_xml(policy, _wlan_accesspoints_rom.xml());
|
|
_dialog_generator.generate_dialog();
|
|
}
|
|
|
|
|
|
void Sculpt::Network::_handle_wlan_state()
|
|
{
|
|
_wlan_state_rom.update();
|
|
_wifi_connection = Wifi_connection::from_xml(_wlan_state_rom.xml());
|
|
_dialog_generator.generate_dialog();
|
|
}
|
|
|
|
|
|
void Sculpt::Network::_handle_nic_router_state()
|
|
{
|
|
_nic_router_state_rom.update();
|
|
|
|
Nic_state const old_nic_state = _nic_state;
|
|
_nic_state = Nic_state::from_xml(_nic_router_state_rom.xml());
|
|
|
|
if (_nic_state.ipv4 != old_nic_state.ipv4)
|
|
_dialog_generator.generate_dialog();
|
|
|
|
/* if the nic state becomes ready, consider spawning the update subsystem */
|
|
if (old_nic_state.ready() != _nic_state.ready())
|
|
_runtime_config_generator.generate_runtime_config();
|
|
}
|
|
|
|
|
|
void Sculpt::Network::_handle_nic_router_config(Xml_node config)
|
|
{
|
|
Nic_target::Type target = _nic_target.managed_type;
|
|
|
|
_nic_target.policy = config.has_type("empty")
|
|
? Nic_target::MANAGED : Nic_target::MANUAL;
|
|
|
|
if (_nic_target.manual()) {
|
|
|
|
/* obtain uplink information from configuration */
|
|
target = Nic_target::LOCAL;
|
|
|
|
if (!config.has_sub_node("domain"))
|
|
target = Nic_target::OFF;
|
|
|
|
struct Break : Exception { };
|
|
try {
|
|
config.for_each_sub_node("domain", [&] (Xml_node domain) {
|
|
|
|
/* skip domains that are not called "uplink" */
|
|
if (domain.attribute_value("name", String<16>()) != "uplink")
|
|
return;
|
|
|
|
config.for_each_sub_node("uplink", [&] (Xml_node uplink) {
|
|
|
|
/* skip uplinks not assigned to a domain called "uplink" */
|
|
if (uplink.attribute_value("domain", String<16>()) != "uplink")
|
|
return;
|
|
|
|
if (uplink.attribute_value("label", String<16>()) == "wired") {
|
|
target = Nic_target::WIRED;
|
|
throw Break();
|
|
}
|
|
if (uplink.attribute_value("label", String<16>()) == "wifi") {
|
|
target = Nic_target::WIFI;
|
|
throw Break();
|
|
}
|
|
});
|
|
});
|
|
} catch (Break) { }
|
|
_nic_target.manual_type = target;
|
|
}
|
|
|
|
nic_target(target);
|
|
_generate_nic_router_config();
|
|
_runtime_config_generator.generate_runtime_config();
|
|
_dialog_generator.generate_dialog();
|
|
}
|
|
|
|
|
|
void Sculpt::Network::gen_runtime_start_nodes(Xml_generator &xml) const
|
|
{
|
|
if (_use_nic_drv)
|
|
xml.node("start", [&] () { gen_nic_drv_start_content(xml); });
|
|
|
|
if (_use_wifi_drv)
|
|
xml.node("start", [&] () { gen_wifi_drv_start_content(xml); });
|
|
|
|
if (_nic_target.type() != Nic_target::OFF)
|
|
xml.node("start", [&] () {
|
|
gen_nic_router_start_content(xml, _nic_target,
|
|
_use_nic_drv, _use_wifi_drv); });
|
|
}
|