diff --git a/core/libs/prx/libSceNet/Export.cpp b/core/libs/prx/libSceNet/Export.cpp index 0775ad06b..d70156fea 100644 --- a/core/libs/prx/libSceNet/Export.cpp +++ b/core/libs/prx/libSceNet/Export.cpp @@ -369,6 +369,7 @@ std::int64_t message_length(const NetMsghdr* message) { extern "C" { extern const std::uint32_t sce_net_in6addr_any[4] = {}; +alignas(std::uint32_t) extern const std::uint8_t sce_net_in6addr_linklocal_allnodes[16] = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; int* APS5_VABI sceNetErrnoLoc(void) { return errno_slot(); diff --git a/core/libs/tests/GuestSceNet.cpp b/core/libs/tests/GuestSceNet.cpp index e71c5d65c..1579e6645 100644 --- a/core/libs/tests/GuestSceNet.cpp +++ b/core/libs/tests/GuestSceNet.cpp @@ -46,6 +46,7 @@ int APS5_VABI sceNetEpollWait(int, NetEpollEvent*, int, int); int APS5_VABI sceNetEpollDestroy(int); int APS5_VABI sceNetEpollAbort(int, int); extern const std::uint32_t sce_net_in6addr_any[4]; +extern const std::uint8_t sce_net_in6addr_linklocal_allnodes[16]; int APS5_VABI sceNetResolverCreate(const char*, int, int); int APS5_VABI sceNetResolverStartNtoa(int, const char*, void*, int, int, int); int APS5_VABI sceNetResolverStartNtoaMultipleRecordsEx(int, const char*, void*, int, int, int); @@ -255,6 +256,21 @@ static bool HostIpv6LoopbackUnavailable() { #endif } +static void CheckLinkLocalAllNodesIpv6() { + Require(reinterpret_cast(sce_net_in6addr_linklocal_allnodes) % alignof(std::uint32_t) == 0); + std::array address{}; + Require(sceNetInetPton(28, "ff02::1", address.data()) == 1); + Require(std::memcmp(sce_net_in6addr_linklocal_allnodes, address.data(), address.size()) == 0); + std::array text; + text.fill('x'); + Require(sceNetInetNtop(28, sce_net_in6addr_linklocal_allnodes, text.data(), 7) == nullptr && *sceNetErrnoLoc() == 28); + Require(sceNetInetNtop(28, sce_net_in6addr_linklocal_allnodes, text.data(), 8) == text.data()); + Require(std::strcmp(text.data(), "ff02::1") == 0 && text[8] == 'x'); + address.fill(0xa5); + Require(sceNetInetPton(28, text.data(), address.data()) == 1); + Require(std::memcmp(sce_net_in6addr_linklocal_allnodes, address.data(), address.size()) == 0); +} + static void CheckUnspecifiedIpv6() { std::array unspecified{}; Require(sceNetInetPton(28, "::", unspecified.data()) == 1); @@ -319,6 +335,7 @@ int main() { CheckAddressText(2, "255.255.255.255"); CheckAddressText(28, "::1"); CheckAddressText(28, "1234:5678:9abc:def0:1234:5678:9abc:def0"); + CheckLinkLocalAllNodesIpv6(); CheckUnspecifiedIpv6(); const int listener = sceNetSocket(nullptr, 2, 1, 6);