From 1b33f14c8c9b0042c1e341b265d1f4dee4531400 Mon Sep 17 00:00:00 2001 From: Luis Gerardo Aguilar <100291529+LuisAguilarDev@users.noreply.github.com> Date: Thu, 15 Oct 2026 16:45:45 -0500 Subject: [PATCH] feat(netctl): add sceNetCtlGetInfoV6 argument and connection checks Titles import sceNetCtlGetInfoV6, and a missing import stops them at load. The checks that need no answer layout are implemented; every code throws when the host has IPv6, since the layout of the answer is not verified. --- core/libs/prx/libSceNetCtl/Export.cpp | 14 +++++++++----- core/libs/tests/GuestNetCtl.cpp | 7 +++++++ docs/dev/debt/libSceNetCtl.md | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/core/libs/prx/libSceNetCtl/Export.cpp b/core/libs/prx/libSceNetCtl/Export.cpp index dbc3d4c09a..fa0b264627 100644 --- a/core/libs/prx/libSceNetCtl/Export.cpp +++ b/core/libs/prx/libSceNetCtl/Export.cpp @@ -64,6 +64,8 @@ static constexpr int NET_CTL_INFO_SECONDARY_DNS = 18; static constexpr int NET_CTL_INFO_HTTP_PROXY_CONFIG = 19; static constexpr int NET_CTL_INFO_HTTP_PROXY_SERVER = 20; static constexpr int NET_CTL_INFO_HTTP_PROXY_PORT = 21; +static constexpr int NET_CTL_INFO_V6_IP_ADDRESS = 1; +static constexpr int NET_CTL_INFO_V6_SECONDARY_DNS = 5; static constexpr std::uint32_t NET_CTL_DEVICE_WIRED = 0; static constexpr std::uint32_t NET_CTL_LINK_CONNECTED = 1; static constexpr std::uint32_t NET_CTL_IP_DHCP = 0; @@ -456,11 +458,6 @@ int APS5_VABI sceNetCtlGetInfo(int code, NetCtlInfo* info) { return 0; } -int APS5_VABI sceNetCtlGetInfoV6() { - NotImplemented_nid_no_patch(__func__); - return 0; -} - int APS5_VABI sceNetCtlGetNatInfo(NetCtlNatInfo* nat_info) { if (!nat_info) return SCE_NET_CTL_ERROR_INVALID_ADDR; return SCE_NET_CTL_ERROR_NOT_CONNECTED; @@ -497,6 +494,13 @@ int APS5_VABI sceNetCtlRegisterCallbackV6(NetCtlCallback func, void* arg, int* c return RegisterCallback(g_callbacksV6, func, arg, cid); } +int APS5_VABI sceNetCtlGetInfoV6(int code, void* info) { + if (!info) return SCE_NET_CTL_ERROR_INVALID_ADDR; + if (code < NET_CTL_INFO_V6_IP_ADDRESS || code > NET_CTL_INFO_V6_SECONDARY_DNS) return SCE_NET_CTL_ERROR_INVALID_CODE; + if (!HostHasAddress(AF_INET6)) return SCE_NET_CTL_ERROR_NOT_CONNECTED; + throw std::runtime_error("sceNetCtlGetInfoV6: info code " + std::to_string(code) + " is not implemented"); +} + void APS5_VABI sceNetCtlTerm(void) { std::lock_guard lock(g_callbackLock); for (auto& slot : g_callbacks) slot = {}; diff --git a/core/libs/tests/GuestNetCtl.cpp b/core/libs/tests/GuestNetCtl.cpp index 5ee4c2a871..a74159ef72 100644 --- a/core/libs/tests/GuestNetCtl.cpp +++ b/core/libs/tests/GuestNetCtl.cpp @@ -37,6 +37,7 @@ int APS5_VABI sceNetCtlGetInfo(int, NetCtlInfo*); int APS5_VABI sceNetCtlGetNatInfo(NetCtlNatInfo*); int APS5_VABI sceNetCtlGetState(int*); int APS5_VABI sceNetCtlGetStateV6(int*); +int APS5_VABI sceNetCtlGetInfoV6(int, void*); int APS5_VABI sceNetCtlGetResult(int, int*); #ifdef __APPLE__ std::size_t NetCtlDefaultRoutes_nid_no_patch(const char*, std::size_t, NetCtlDefaultRoute*, std::size_t); @@ -275,6 +276,12 @@ int main() { Require(sceNetCtlGetInfo(22, &info) == kErrInvalidCode); Require(sceNetCtlGetInfo(14, nullptr) == kErrInvalidAddr); + std::uint8_t infoV6[256] = {}; + Require(sceNetCtlGetInfoV6(0, infoV6) == kErrInvalidCode); + Require(sceNetCtlGetInfoV6(6, infoV6) == kErrInvalidCode); + Require(sceNetCtlGetInfoV6(1, nullptr) == kErrInvalidAddr); + if (stateV6 != kStateIpObtained) Require(sceNetCtlGetInfoV6(1, infoV6) == kErrNotConnected); + const int result = sceNetCtlGetInfo(14, &info); if (result == kErrNotConnected) { std::puts("skipped, the host has no IPv4 address"); diff --git a/docs/dev/debt/libSceNetCtl.md b/docs/dev/debt/libSceNetCtl.md index 0df9af2742..ca13becdd0 100644 --- a/docs/dev/debt/libSceNetCtl.md +++ b/docs/dev/debt/libSceNetCtl.md @@ -6,7 +6,7 @@ ### Unknown function info -- [sceNetCtlGetInfoV6](../../../core/libs/prx/libSceNetCtl/Export.cpp) (libSceNetCtl, NID `Jy1EO5GdlcM`) - imported by PPSA08587, which fails to load without it, and not called before its loading screen; declared without parameters as a throwing stub, signature unknown. Name from the aerolib NID list +- [sceNetCtlGetInfoV6](../../../core/libs/prx/libSceNetCtl/Export.cpp) (libSceNetCtl, NID `Jy1EO5GdlcM`) - imported by PPSA08587. `(int code, SceNetCtlInfoV6* info)` with codes 1-5 (IP address, link-local address, default route, primary and secondary DNS) comes only from [SharpProspero](https://github.com/SvenGDK/SharpProspero), whose source is unknown; shadPS4 and fpPS4 only stub it. A null `info` answers `INVALID_ADDR`, a code outside 1-5 `INVALID_CODE`, and a host without an IPv6 address `NOT_CONNECTED`, as `sceNetCtlGetStateV6` reports it. The layout of each answer is unverified, so every code throws on a host with an IPv6 address - [sceNetCtlGetInfo](../../../core/libs/prx/libSceNetCtl/Export.cpp) (libSceNetCtl) - answers from the host interface that holds an IPv4 address, preferring the one that carries the default route: its address, netmask, gateway, MTU and first two IPv4 DNS servers. The device is reported as wired, the link as connected, the IP configuration as DHCP and the HTTP proxy as off, whatever the host uses, and the Ethernet address is the one `sceNetGetMacAddress` reports. A gateway or DNS server the interface does not have is reported as `0.0.0.0`; what a console reports then is unknown. The DHCP host name (12), the PPPoE user name (13), the HTTP proxy server (20) and the Wi-Fi BSSID and SSID (5, 6) are empty strings, as that configuration sets none of them; the remaining Wi-Fi codes (7-10) and the HTTP proxy port (21) report 0; this follows [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/network.cpp) and is not measured on hardware ### Functional