ui: Add ability to enable user (NAT) network backend

This commit is contained in:
Matt Borgerson 2020-05-30 17:42:09 -07:00 committed by mborgerson
parent 76107a4371
commit ca4d03cf89
4 changed files with 73 additions and 32 deletions

View File

@ -823,6 +823,7 @@ class NetworkWindow
{
public:
bool is_open;
int backend;
char remote_addr[64];
char local_addr[64];
@ -851,45 +852,56 @@ public:
strncpy(remote_addr, tmp, sizeof(remote_addr)-1);
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &tmp);
strncpy(local_addr, tmp, sizeof(local_addr)-1);
xemu_settings_get_enum(XEMU_SETTINGS_NETWORK_BACKEND, &backend);
}
ImGui::TextWrapped(
"xemu socket networking works by sending and receiving packets over "
"UDP which encapsulate the network traffic that the machine would "
"send or receive when connected to a Local Area Network (LAN)."
);
ImGui::Dummy(ImVec2(0.0f, ImGui::GetStyle().WindowPadding.y));
ImGui::Separator();
ImGui::Dummy(ImVec2(0.0f, ImGui::GetStyle().WindowPadding.y));
ImGui::Columns(2, "", false);
ImGui::SetColumnWidth(0, ImGui::GetWindowWidth()*0.33);
ImGuiInputTextFlags flg = 0;
bool is_enabled = xemu_net_is_enabled();
if (is_enabled) {
flg |= ImGuiInputTextFlags_ReadOnly;
}
ImGui::Text("Remote Host");
ImGui::SameLine(); HelpMarker("The remote <IP address>:<Port> to forward packets to (e.g. 1.2.3.4:9368)");
ImGui::Columns(2, "", false);
ImGui::SetColumnWidth(0, ImGui::GetWindowWidth()*0.33);
ImGui::Text("Attached To");
ImGui::SameLine(); HelpMarker("The network backend which the emulated NIC interacts with");
ImGui::NextColumn();
float w = ImGui::GetColumnWidth()-10*g_ui_scale;
ImGui::SetNextItemWidth(w);
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
ImGui::InputText("###remote_host", remote_addr, sizeof(remote_addr), flg);
int temp_backend = backend; // Temporary to make backend combo read-only (FIXME: surely there's a nicer way)
if (ImGui::Combo("##backend", is_enabled ? &temp_backend : &backend, "User (NAT)\0Socket\0") && !is_enabled) {
xemu_settings_set_enum(XEMU_SETTINGS_NETWORK_BACKEND, backend);
xemu_settings_save();
}
if (is_enabled) ImGui::PopStyleVar();
ImGui::SameLine();
if (backend == XEMU_NET_BACKEND_USER) {
HelpMarker("User-mode TCP/IP stack with a NAT'd network");
} else if (backend == XEMU_NET_BACKEND_SOCKET_UDP) {
HelpMarker("Encapsulates link-layer traffic in UDP packets");
}
ImGui::NextColumn();
ImGui::Text("Local Host");
ImGui::SameLine(); HelpMarker("The local <IP address>:<Port> to receive packets on (e.g. 0.0.0.0:9368)");
ImGui::NextColumn();
ImGui::SetNextItemWidth(w);
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
ImGui::InputText("###local_host", local_addr, sizeof(local_addr), flg);
if (is_enabled) ImGui::PopStyleVar();
ImGui::NextColumn();
if (backend == XEMU_NET_BACKEND_SOCKET_UDP) {
ImGui::Text("Remote Host");
ImGui::SameLine(); HelpMarker("The remote <IP address>:<Port> to forward packets to (e.g. 1.2.3.4:9368)");
ImGui::NextColumn();
float w = ImGui::GetColumnWidth()-10*g_ui_scale;
ImGui::SetNextItemWidth(w);
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
ImGui::InputText("###remote_host", remote_addr, sizeof(remote_addr), flg);
if (is_enabled) ImGui::PopStyleVar();
ImGui::NextColumn();
ImGui::Text("Local Host");
ImGui::SameLine(); HelpMarker("The local <IP address>:<Port> to receive packets on (e.g. 0.0.0.0:9368)");
ImGui::NextColumn();
ImGui::SetNextItemWidth(w);
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
ImGui::InputText("###local_host", local_addr, sizeof(local_addr), flg);
if (is_enabled) ImGui::PopStyleVar();
ImGui::NextColumn();
}
ImGui::Columns(1);

View File

@ -46,16 +46,29 @@ void xemu_net_enable(void)
return;
}
int backend;
const char *local_addr, *remote_addr;
xemu_settings_get_enum(XEMU_SETTINGS_NETWORK_BACKEND, &backend);
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, &remote_addr);
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &local_addr);
// Create the UDP netdev
QDict *qdict = qdict_new();
qdict_put_str(qdict, "id", id);
qdict_put_str(qdict, "type", "socket");
qdict_put_str(qdict, "udp", remote_addr);
qdict_put_str(qdict, "localaddr", local_addr);
// Create the netdev
QDict *qdict;
if (backend == XEMU_NET_BACKEND_USER) {
qdict = qdict_new();
qdict_put_str(qdict, "id", id);
qdict_put_str(qdict, "type", "user");
} else if (backend == XEMU_NET_BACKEND_SOCKET_UDP) {
qdict = qdict_new();
qdict_put_str(qdict, "id", id);
qdict_put_str(qdict, "type", "socket");
qdict_put_str(qdict, "udp", remote_addr);
qdict_put_str(qdict, "localaddr", local_addr);
} else {
// Unsupported backend type
return;
}
QemuOpts *opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &error_abort);
qobject_unref(qdict);
netdev_add(opts, &local_err);

View File

@ -56,6 +56,7 @@ struct xemu_settings {
// [network]
int net_enabled; // Boolean
int net_backend;
char *net_local_addr;
char *net_remote_addr;
};
@ -72,6 +73,12 @@ static const struct enum_str_map display_scale_map[DISPLAY_SCALE__COUNT+1] = {
{ 0, NULL },
};
static const struct enum_str_map net_backend_map[XEMU_NET_BACKEND__COUNT+1] = {
{ XEMU_NET_BACKEND_USER, "user" },
{ XEMU_NET_BACKEND_SOCKET_UDP, "udp" },
{ 0, NULL },
};
struct config_offset_table {
enum config_types type;
const char *section;
@ -102,6 +109,7 @@ struct config_offset_table {
[XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID] = { CONFIG_TYPE_STRING, "input", "controller_4_guid", offsetof(struct xemu_settings, controller_4_guid), { .default_str = "" } },
[XEMU_SETTINGS_NETWORK_ENABLED] = { CONFIG_TYPE_BOOL, "network", "enabled", offsetof(struct xemu_settings, net_enabled), { .default_bool = 0 } },
[XEMU_SETTINGS_NETWORK_BACKEND] = { CONFIG_TYPE_ENUM, "network", "backend", offsetof(struct xemu_settings, net_backend), { .default_int = XEMU_NET_BACKEND_USER }, net_backend_map },
[XEMU_SETTINGS_NETWORK_LOCAL_ADDR] = { CONFIG_TYPE_STRING, "network", "local_addr", offsetof(struct xemu_settings, net_local_addr), { .default_str = "0.0.0.0:9368" } },
[XEMU_SETTINGS_NETWORK_REMOTE_ADDR] = { CONFIG_TYPE_STRING, "network", "remote_addr", offsetof(struct xemu_settings, net_remote_addr), { .default_str = "1.2.3.4:9368" } },
};

View File

@ -43,6 +43,7 @@ enum xemu_settings_keys {
XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID,
XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID,
XEMU_SETTINGS_NETWORK_ENABLED,
XEMU_SETTINGS_NETWORK_BACKEND,
XEMU_SETTINGS_NETWORK_LOCAL_ADDR,
XEMU_SETTINGS_NETWORK_REMOTE_ADDR,
XEMU_SETTINGS__COUNT,
@ -58,6 +59,13 @@ enum DISPLAY_SCALE
DISPLAY_SCALE_INVALID = -1
};
enum xemu_net_backend {
XEMU_NET_BACKEND_USER,
XEMU_NET_BACKEND_SOCKET_UDP,
XEMU_NET_BACKEND__COUNT,
XEMU_NET_BACKEND_INVALID = -1
};
// Determine whether settings were loaded or not
int xemu_settings_did_fail_to_load(void);