diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp index e069c34d61..dcea69a510 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp @@ -129,10 +129,18 @@ s32 lv2_socket_native::bind(const sys_net_sockaddr& addr) const auto* psa_in = reinterpret_cast(&addr); + auto& nph = g_fxo->get>(); + u32 saddr = nph.get_bind_ip(); + if (saddr == 0) + { + // If zero use the supplied address + saddr = std::bit_cast(psa_in->sin_addr); + } + ::sockaddr_in native_addr{}; native_addr.sin_family = AF_INET; native_addr.sin_port = std::bit_cast(psa_in->sin_port); - native_addr.sin_addr.s_addr = std::bit_cast(psa_in->sin_addr); + native_addr.sin_addr.s_addr = saddr; ::socklen_t native_addr_len = sizeof(native_addr); sys_net.warning("[Native] Trying to bind %s:%d", native_addr.sin_addr, std::bit_cast, u16>(native_addr.sin_port)); diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index cf9941f08e..548d95a331 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -371,6 +371,18 @@ namespace np { dns_ip = conv.s_addr; } + + // Convert bind address + conv = {}; + if (!inet_pton(AF_INET, g_cfg.net.bind_address.to_string().c_str(), &conv)) + { + // Do not set to disconnected on invalid IP just error and continue using default (0.0.0.0) + nph_log.error("Provided IP(%s) address for bind is invalid!", g_cfg.net.bind_address.to_string()); + } + else + { + bind_ip = conv.s_addr; + } } } @@ -585,6 +597,11 @@ namespace np return dns_ip; } + u32 np_handler::get_bind_ip() const + { + return bind_ip; + } + s32 np_handler::get_net_status() const { return is_connected ? CELL_NET_CTL_STATE_IPObtained : CELL_NET_CTL_STATE_Disconnected; diff --git a/rpcs3/Emu/NP/np_handler.h b/rpcs3/Emu/NP/np_handler.h index 8616a08aff..c26125e607 100644 --- a/rpcs3/Emu/NP/np_handler.h +++ b/rpcs3/Emu/NP/np_handler.h @@ -79,6 +79,7 @@ namespace np u32 get_local_ip_addr() const; u32 get_public_ip_addr() const; u32 get_dns_ip() const; + u32 get_bind_ip() const; s32 get_psn_status() const; s32 get_net_status() const; @@ -290,6 +291,7 @@ namespace np be_t local_ip_addr{}; be_t public_ip_addr{}; be_t dns_ip = 0x08080808; + be_t bind_ip = 0x00000000; // User infos SceNpId npid{}; diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 88fde3dcbb..c5df9d57e4 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -305,6 +305,7 @@ struct cfg_root : cfg::node cfg::_enum net_active{this, "Internet enabled", np_internet_status::disabled}; cfg::string ip_address{this, "IP address", "0.0.0.0"}; + cfg::string bind_address{this, "Bind address", "0.0.0.0"}; cfg::string dns{this, "DNS address", "8.8.8.8"}; cfg::string swap_list{this, "IP swap list", ""}; diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index e4b5d40eaa..988f8154be 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -170,6 +170,7 @@ enum class emu_settings_type DNSAddress, IpSwapList, PSNStatus, + BindAddress, // System LicenseArea, @@ -348,6 +349,7 @@ inline static const QMap settings_location = { emu_settings_type::DNSAddress, { "Net", "DNS address"}}, { emu_settings_type::IpSwapList, { "Net", "IP swap list"}}, { emu_settings_type::PSNStatus, { "Net", "PSN status"}}, + { emu_settings_type::BindAddress, { "Net", "Bind address"}}, // System { emu_settings_type::LicenseArea, { "System", "License Area"}}, diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 81c6b7e823..d0b99139dd 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -1281,6 +1281,9 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->EnhanceLineEdit(ui->edit_dns, emu_settings_type::DNSAddress); SubscribeTooltip(ui->gb_edit_dns, tooltips.settings.dns); + m_emu_settings->EnhanceLineEdit(ui->edit_bind, emu_settings_type::BindAddress); + SubscribeTooltip(ui->gb_edit_bind, tooltips.settings.bind); + m_emu_settings->EnhanceLineEdit(ui->edit_swaps, emu_settings_type::IpSwapList); SubscribeTooltip(ui->gb_edit_swaps, tooltips.settings.dns_swap); diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 4c47106b7e..96cedfac5a 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -2081,7 +2081,7 @@ Network Configuration - + @@ -2132,6 +2132,25 @@ + + + + Bind address + + + + + + + 0 + 0 + + + + + + + diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index 6e54041b8a..2a1b4dc79f 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -228,6 +228,7 @@ public: const QString psn_status = tr("If set to Simulated, RPCS3 will fake PSN connection as best as it can."); const QString dns = tr("DNS used to resolve hostnames by applications."); const QString dns_swap = tr("DNS Swap List."); + const QString bind = tr("Interface IP Address to bind to."); // system