diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index d9164913dd0c..f6924c7c2a11 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -521,6 +521,12 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptrsa_family != SYS_NET_AF_INET) + { + sys_net.error("sys_net_bnet_connect(s=%d): unsupported sa_family (%d)", s, addr->sa_family); + return -SYS_NET_EAFNOSUPPORT; + } + if (!idm::check(s)) { return -SYS_NET_EBADF; 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 0cb0430e6818..03ace402522a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp @@ -164,6 +164,12 @@ std::optional lv2_socket_native::connect(const sys_net_sockaddr& addr) sys_net.notice("[Native] Attempting to connect on %s:%d", native_addr.sin_addr, std::bit_cast, u16>(native_addr.sin_port)); + auto& nph = g_fxo->get>(); + if (!nph.get_net_status() && is_ip_public_address(native_addr)) + { + return -SYS_NET_EADDRNOTAVAIL; + } + if (psa_in->sin_port == 53) { // Add socket to the dns hook list @@ -896,6 +902,12 @@ std::optional lv2_socket_native::sendto(s32 flags, const std::vector& b { native_addr = sys_net_addr_to_native_addr(*opt_sn_addr); sys_net.trace("[Native] Attempting to send to %s:%d", (*native_addr).sin_addr, std::bit_cast, u16>((*native_addr).sin_port)); + + auto& nph = g_fxo->get>(); + if (!nph.get_net_status() && is_ip_public_address(*native_addr)) + { + return -SYS_NET_EADDRNOTAVAIL; + } } sys_net_error result{}; @@ -915,13 +927,6 @@ std::optional lv2_socket_native::sendto(s32 flags, const std::vector& b { const s32 ret_analyzer = dnshook.analyze_dns_packet(lv2_id, reinterpret_cast(buf.data()), buf.size()); - // If we're offline return ENETDOWN for dns requests - auto& nph = g_fxo->get>(); - if (!nph.get_net_status()) - { - return -SYS_NET_ENETDOWN; - } - // Check if the packet is intercepted if (ret_analyzer >= 0) { diff --git a/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.cpp b/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.cpp index e2b2f3c924e9..73dd888722b6 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.cpp @@ -151,6 +151,21 @@ ::sockaddr_in sys_net_addr_to_native_addr(const sys_net_sockaddr& sn_addr) return native_addr; } +bool is_ip_public_address(const ::sockaddr_in& addr) +{ + const u8 *ip = reinterpret_cast(&addr.sin_addr.s_addr); + + if ((ip[0] == 10) || + (ip[0] == 127) || + (ip[0] == 172 && (ip[1] >= 16 && ip[1] <= 31)) || + (ip[0] == 192 && ip[1] == 168)) + { + return false; + } + + return true; +} + s32 network_clear_queue(ppu_thread& ppu) { s32 cleared = 0; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.h b/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.h index 28fcd6b7a042..26745d2b0dfe 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/sys_net_helpers.h @@ -21,6 +21,7 @@ int get_native_error(); sys_net_error get_last_error(bool is_blocking, int native_error = 0); sys_net_sockaddr native_addr_to_sys_net_addr(const ::sockaddr_storage& native_addr); ::sockaddr_in sys_net_addr_to_native_addr(const sys_net_sockaddr& sn_addr); +bool is_ip_public_address(const ::sockaddr_in& addr); s32 network_clear_queue(ppu_thread& ppu); #ifdef _WIN32